From cf99dde4805f1792d6a56156b6a0338aa684005c Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Fri, 16 Oct 2026 21:08:04 +0200 Subject: notes: an empty note body gets a file, and the second click writes Reported from use: a note created with only a title then saved left a db.json entry with no file beside it, and reopening it said the file was missing. Cause: FileView.setText("") on a path that view has not loaded creates no file at all and reports no error. The index write (always non-empty JSON) was fine, so only the body was lost, which is why it looked like a missing file rather than a failed save. Bodies are now written by a Process running cat > with the text on stdin: verified against empty and non-empty payloads, consecutive writes on one Process, and a store with no db.json at all. The exit code is the real outcome, so a refused write reports it. Second report in the same flow: the editor stays editable after the first click, so typing more and then pressing Commit & push dropped the edit, the push carrying only what the first click wrote. The second click now writes the current title and body before it commits and pushes. --- desktop/modules/notes/NotesModule.qml | 45 ++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'desktop/modules/notes/NotesModule.qml') diff --git a/desktop/modules/notes/NotesModule.qml b/desktop/modules/notes/NotesModule.qml index 082f02c..992cbfa 100644 --- a/desktop/modules/notes/NotesModule.qml +++ b/desktop/modules/notes/NotesModule.qml @@ -150,27 +150,38 @@ Module { if (done) done(ok, ok ? "" : mod.dbView.saveError); } - // A note body. notes.sh keeps the title out of the file, so this is the - // body and nothing else. setText writes the path directly and needs no - // prior load; reading the file back is what would need one, and nothing - // here reads it back. - property FileView bodyView: FileView { - blockWrites: true - printErrors: false - property string saveError: "" - onSaved: saveError = "" - onSaveFailed: error => { - console.warn("notes: note body write failed:", error); - saveError = "the note's file could not be written"; + // A note body, written through a Process rather than a FileView. + // FileView.setText() with EMPTY text on a path that view has not loaded + // writes no file at all and reports no error, which is how a note created + // with an empty body ended up in db.json with no file beside it. cat reads + // stdin, so any content and any length works, including none, and the exit + // code is the real outcome. Clearing stdinEnabled after the write is what + // gives cat its EOF. + property Process bodyWriter: Process { + stdinEnabled: true + property string data: "" + property var done: null + property string err: "" + onStarted: { + mod.bodyWriter.write(mod.bodyWriter.data); + mod.bodyWriter.stdinEnabled = false; + } + onExited: code => { + const d = mod.bodyWriter.done; + mod.bodyWriter.done = null; + if (d) d(code === 0, code === 0 ? "" : (mod.bodyWriter.err || "the note's file could not be written")); } + stderr: StdioCollector { onStreamFinished: mod.bodyWriter.err = this.text } } function writeBody(path, text, done) { - mod.bodyView.path = path; - mod.bodyView.saveError = ""; - mod.bodyView.setText(text); - const ok = mod.bodyView.saveError === ""; - if (done) done(ok, ok ? "" : mod.bodyView.saveError); + mod.bodyWriter.done = done; + mod.bodyWriter.data = text; + mod.bodyWriter.err = ""; + mod.bodyWriter.command = ["sh", "-c", 'cat > "$1"', "sh", path]; + mod.bodyWriter.stdinEnabled = true; + mod.bodyWriter.running = false; + mod.bodyWriter.running = true; } // The path of a note's body, "" when the entry's file is not a plain -- cgit v1.2.3