diff options
Diffstat (limited to 'desktop/modules/assistant/PresetsPage.qml')
| -rw-r--r-- | desktop/modules/assistant/PresetsPage.qml | 60 |
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() } } } |
