diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-17 11:34:07 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-17 11:34:07 +0200 |
| commit | 080d3d9aaffa8848d6de8546511f096d8e7c30f5 (patch) | |
| tree | 2663bd5c774d8db7fa024e82546f6cfa04c07e29 /desktop/modules/assistant/PresetsModule.qml | |
| parent | b8c0f01f058c87db5924067dbb475aa241c71b46 (diff) | |
| download | quickshell-080d3d9aaffa8848d6de8546511f096d8e7c30f5.tar.gz quickshell-080d3d9aaffa8848d6de8546511f096d8e7c30f5.zip | |
settings: pages edit a draft, and Save writes it
The qtmaildir, Assistant and Ask presets pages wrote a field on Enter,
and a switch or chip the moment it was clicked, so a half-finished
change reached the file and a slip could not be taken back. They now
edit a draft as fields are typed, and a Save and Discard pair in the
page header (SaveBar, through Page.actions) writes or drops it. Save
waits while a field holds a value that cannot be written, and a draft
over a file that changed on disk meanwhile is refused at Save rather
than written over it. A dot in the sidebar marks a page with unsaved
edits; drafts survive moving between pages. The four Mail pages share
one draft, since they are one file. Tool switches are staged too and
renamed on Save; model Load, Prefer and Restart stay immediate, being
actions rather than settings.
Live editing needed two rules. A field is no longer bound to its value,
which would reset the cursor and eat a typed trailing space; it follows
the value only when the draft moves under it. And a Repeater's model is
now the set of row keys (or a count), assigned only when that set
changes: an array rebuilt from the draft on each keystroke recreates
every row, including the one being typed in, which loses its focus.
Git, autostart's rows, HyprSunset, HyprIdle and User keep their own
buttons.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop/modules/assistant/PresetsModule.qml')
| -rw-r--r-- | desktop/modules/assistant/PresetsModule.qml | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/desktop/modules/assistant/PresetsModule.qml b/desktop/modules/assistant/PresetsModule.qml index 8617b02..1c62f73 100644 --- a/desktop/modules/assistant/PresetsModule.qml +++ b/desktop/modules/assistant/PresetsModule.qml @@ -15,8 +15,10 @@ import "../../assistant/Presets.js" as Presets // The assistant canvas's Ask row: the canned questions offered for the // staged files. They live in Prefs and the canvas reads them live, so -// unlike the daemon's settings these need no restart. +// unlike the daemon's settings these need no restart. The page edits a +// draft here; Save hands it to Prefs. Module { + id: pm name: "presets" label: "Ask presets" // nf-fa-lightbulb_o, present in Inconsolata Nerd Font. @@ -24,12 +26,34 @@ Module { settings: true group: "Assistant" keywords: ["assistant", "canvas", "ask", "question", "prompt", "summarize", "files"] - searchItems: Presets.list(Prefs.presets).map((p, i) => ({ text: p.label + ": " + p.prompt, key: "preset:" + i })) + searchItems: pm.shown.map((p, i) => ({ text: p.label + ": " + p.prompt, key: "preset:" + i })) + + // null while there are no edits: the page then shows Prefs' list. + property var draft: null + // Reset to defaults was pressed: Save drops the saved list rather than + // saving a copy of the defaults, so later default changes still arrive. + property bool resetting: false + readonly property var shown: pm.draft ?? Presets.list(Prefs.presets) + // Presets with an empty label or question, by index; Save waits. + readonly property bool valid: pm.shown.every(p => p.label.trim() !== "" && p.prompt.trim() !== "") + dirty: pm.draft !== null + + function edit(list) { pm.draft = list; pm.resetting = false; } + function reset() { pm.draft = Presets.list(null).map(p => Object.assign({}, p, { kinds: p.kinds.slice() })); pm.resetting = true; } + function save() { + if (pm.resetting) Prefs.resetPresets(); else Prefs.setPresets(pm.draft); + pm.discard(); + } + function discard() { pm.draft = null; pm.resetting = false; } page: Component { Page { title: "Ask presets" - PresetsPage { width: parent.width } + actions: Component { + SaveBar { dirty: pm.dirty; valid: pm.valid; note: "every preset needs a label and a question" + onSave: pm.save(); onDiscard: pm.discard() } + } + PresetsPage { width: parent.width; owner: pm } } } } |
