aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/notes/Notes.js
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-16 20:46:50 +0200
committerDanilo M. <danix@danix.xyz>2026-10-16 20:46:50 +0200
commit53a6051c1d74e48d9a065ce0765dc49a75c9d711 (patch)
treedd95954a5328b7d5bcc97c1722ff96366b8b545b /desktop/modules/notes/Notes.js
parentfe7dcb389e0df86aadbe481646ca9202dfcca9dc (diff)
downloadquickshell-53a6051c1d74e48d9a065ce0765dc49a75c9d711.tar.gz
quickshell-53a6051c1d74e48d9a065ce0765dc49a75c9d711.zip
notes: in-drawer editor with commit-on-save and git pull
The editor, and the write and git path behind it. Save is two clicks and each does one thing: the first writes the note and only then arms the button as 'Commit & push?', so a quick second click cannot commit a note the first has not written yet. The write path refuses when db.json cannot be read as the index. That is not hypothetical: git pull --rebase --autostash resolves a remote db.json change against a local uncommitted one, the stash pop conflicts, git still exits 0, and the file is left full of merge markers. Reading that as 'no notes' and writing it back deleted every title in a probe; Notes.valid now distinguishes it from an empty store and the write reports instead. parse stays tolerant for display. Stamping lastpull also only follows a pull that worked, and only when git is on at all. Db reads that a write is based on go through reload() plus waitForJob(): blockLoading does not make reload() blocking, contrary to the note in AGENTS.md, and reading text() straight after reload() returns the old contents. A body is written with a plain setText, which needs no prior load; only reading text() before a load would.
Diffstat (limited to 'desktop/modules/notes/Notes.js')
-rw-r--r--desktop/modules/notes/Notes.js23
1 files changed, 17 insertions, 6 deletions
diff --git a/desktop/modules/notes/Notes.js b/desktop/modules/notes/Notes.js
index 76c8f95..6bc8c88 100644
--- a/desktop/modules/notes/Notes.js
+++ b/desktop/modules/notes/Notes.js
@@ -22,17 +22,28 @@ function notesOf(db) {
return (db && Array.isArray(db.notes)) ? db.notes : [];
}
-// db.json, whole. Anything that is not an object carrying a notes array reads
-// as an empty store, so a truncated or hand-edited file shows "no notes"
-// rather than failing to load the page.
-function parse(text) {
+// The db object, or null when the text cannot be read as one. An empty or
+// missing file is an empty store, not an error. Anything else that does not
+// parse, or parses to something without a notes array, is null: a writer must
+// refuse on null rather than replace a file it did not understand, which is
+// what a conflicted db.json (merge markers from an autostash pop) is.
+function valid(text) {
+ const t = String(text === undefined || text === null ? "" : text);
+ if (t.trim() === "") return { notes: [] };
let v = null;
- try { v = JSON.parse(text); } catch (e) { v = null; }
+ try { v = JSON.parse(t); } catch (e) { v = null; }
if (!v || typeof v !== "object" || Array.isArray(v) || !Array.isArray(v.notes))
- return { notes: [] };
+ return null;
return v;
}
+// db.json for display: the object, or an empty store when nothing readable is
+// there, so a truncated or hand-edited file shows "no notes" rather than
+// failing to load the page.
+function parse(text) {
+ return valid(text) || { notes: [] };
+}
+
// Pretty, 2-space, trailing newline. notes.sh reads db.json through jq, which
// does not care about the layout.
function stringify(db) {