aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/assistant/PresetsPage.qml
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/modules/assistant/PresetsPage.qml')
-rw-r--r--desktop/modules/assistant/PresetsPage.qml60
1 files changed, 31 insertions, 29 deletions
diff --git a/desktop/modules/assistant/PresetsPage.qml b/desktop/modules/assistant/PresetsPage.qml
index ec103cf..56d507c 100644
--- a/desktop/modules/assistant/PresetsPage.qml
+++ b/desktop/modules/assistant/PresetsPage.qml
@@ -13,14 +13,17 @@ import QtQuick
import "../.."
import "../../assistant/Presets.js" as Presets
-// One card per preset: its label and question, saved on Enter, and the file
-// kinds it is offered for. Every change saves the whole list to Prefs; Reset
-// drops the saved list, which brings the built-in one back.
+// One card per preset: its label and question and the file kinds it is
+// offered for. Every change edits the module's draft; the header's Save
+// hands the list to Prefs. Reset fills the draft with the built-in list.
Column {
id: page
spacing: 10
- readonly property var list: Presets.list(Prefs.presets)
+ // The module, holding the draft. Not named pm, its id (it would bind to
+ // itself, AGENTS.md).
+ required property QtObject owner
+ readonly property var list: owner.shown
// The kinds a preset can name: the four the canvas chats about, and
// "many", offered whenever two or more files are staged.
readonly property var kinds: ["pdf", "text", "code", "image", "many"]
@@ -38,13 +41,13 @@ Column {
if (r) out.push(r);
});
page.error = "";
- page.confirming = -1;
- Prefs.setPresets(out);
+ if (fn === null || out.length !== page.list.length) page.confirming = -1;
+ page.owner.edit(out);
}
function add() {
- Prefs.setPresets(page.list.concat([{ label: "New preset", icon: Presets.FALLBACK,
- kinds: ["text"], prompt: "Summarize this." }]));
+ page.owner.edit(page.list.concat([{ label: "New preset", icon: Presets.FALLBACK,
+ kinds: ["text"], prompt: "Summarize this." }]));
}
component Small: Text {
@@ -52,27 +55,30 @@ Column {
font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 }
}
+ // Reports every keystroke into the draft. Not bound to value, which
+ // would reset the cursor; it follows the value only when the draft moves
+ // under it (Discard, Reset). Empty is outlined, since Save refuses it.
component Field: Rectangle {
id: field
property string value: ""
property string placeholder: ""
- signal commit(string text)
+ signal edited(string text)
height: 32
radius: 8
color: Qt.alpha(Theme.base, 0.6)
+ border.width: ti.text.trim() === "" ? 1 : 0
+ border.color: Theme.red
+ onValueChanged: if (ti.text !== field.value) ti.text = field.value
TextInput {
+ id: ti
anchors { fill: parent; leftMargin: 10; rightMargin: 10 }
verticalAlignment: TextInput.AlignVCenter
clip: true
selectByMouse: true
color: Theme.text
font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 3 }
- text: field.value
- onAccepted: if (text !== field.value) field.commit(text)
- Keys.onEscapePressed: event => {
- if (text !== field.value) text = field.value;
- else event.accepted = false;
- }
+ Component.onCompleted: text = field.value
+ onTextEdited: field.edited(text)
Text {
anchors.verticalCenter: parent.verticalCenter
visible: parent.text === ""
@@ -87,8 +93,8 @@ Column {
width: page.width
wrapMode: Text.Wrap
text: "Offered on the assistant canvas for the staged files: a preset shows when every staged file is "
- + "one of its kinds, or, with \"many\", when two or more are staged. Enter saves a field; "
- + "changes apply at once."
+ + "one of its kinds, or, with \"many\", when two or more are staged. Save applies the "
+ + "changes, which the canvas picks up at once."
}
Text {
@@ -101,12 +107,14 @@ Column {
}
Repeater {
- model: page.list
+ // A count, not the list: a new list on every keystroke would rebuild
+ // every card and drop the focus of the field being typed in.
+ model: page.list.length
delegate: Rectangle {
id: card
- required property var modelData
required property int index
+ readonly property var modelData: page.list[index] ?? { label: "", prompt: "", kinds: [], icon: "" }
objectName: "preset:" + index
width: page.width
height: body.implicitHeight + 20
@@ -133,10 +141,7 @@ Column {
anchors { left: glyph.right; leftMargin: 6; right: del.left; rightMargin: 8; top: parent.top; bottom: parent.bottom }
value: card.modelData.label
placeholder: "label"
- onCommit: t => {
- if (t.trim() === "") { page.error = "A preset needs a label."; return; }
- page.edit(card.index, c => Object.assign(c, { label: t.trim() }));
- }
+ onEdited: t => page.edit(card.index, c => Object.assign(c, { label: t }))
}
Button {
id: del
@@ -154,10 +159,7 @@ Column {
width: parent.width
value: card.modelData.prompt
placeholder: "the question asked"
- onCommit: t => {
- if (t.trim() === "") { page.error = "A preset needs a question."; return; }
- page.edit(card.index, c => Object.assign(c, { prompt: t.trim() }));
- }
+ onEdited: t => page.edit(card.index, c => Object.assign(c, { prompt: t }))
}
// A kind toggles on click; the last one cannot be cleared,
@@ -208,8 +210,8 @@ Column {
Button {
text: "Reset to defaults"
danger: true
- enabled: Prefs.presets !== null
- onClicked: Prefs.resetPresets()
+ enabled: !page.owner.resetting && (Prefs.presets !== null || page.owner.dirty)
+ onClicked: page.owner.reset()
}
}
}