aboutsummaryrefslogtreecommitdiffstats
path: root/desktop
diff options
context:
space:
mode:
Diffstat (limited to 'desktop')
-rw-r--r--desktop/modules/notes/NotesModule.qml45
-rw-r--r--desktop/modules/notes/NotesPage.qml25
-rw-r--r--desktop/modules/notes/README.md15
3 files changed, 54 insertions, 31 deletions
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
diff --git a/desktop/modules/notes/NotesPage.qml b/desktop/modules/notes/NotesPage.qml
index 585fcfb..1a82254 100644
--- a/desktop/modules/notes/NotesPage.qml
+++ b/desktop/modules/notes/NotesPage.qml
@@ -19,9 +19,11 @@ import "Notes.js" as Notes
//
// Save is two clicks and each click does one thing. The first writes the note
// and, when that has finished, arms the button as "Commit & push?"; the second
-// commits and pushes and returns to the list. Arming the second click only
-// after the write completes is what stops a quick second click from committing
-// a note the first click has not written yet.
+// writes whatever the editor holds now, then commits and pushes, then returns
+// to the list. The second click writes as well because the editor stays
+// editable in between: pushing without writing would throw away an edit made
+// after the first click. Arming only after the first write completes is what
+// stops a quick second click from committing a note that is not written yet.
//
// Nothing is remembered between visits: leaving the editor with text that was
// not saved drops it, which is the clipboard page's own rule.
@@ -78,12 +80,19 @@ Item {
// The note is already on disk and only the push is owed, so this click
// pushes rather than writing a second note.
if (page.awaiting !== "") {
- const id = page.awaiting === "create" ? page.owner.lastCreatedId : page.editing.id;
+ // The editor stays editable after the first click, so whatever was
+ // typed since is written before it is pushed: the push alone would
+ // leave that edit behind.
+ const kind = page.awaiting;
+ const id = kind === "create" ? page.owner.lastCreatedId : page.editing.id;
page.busy = true;
- page.owner.commitPush(page.awaiting, id, (ok, msg) => {
- page.busy = false;
- if (!ok) { page.owner.lastError = msg; return; }
- page.toList();
+ page.owner.update(id, titleField.text, bodyEdit.text, (ok, msg) => {
+ if (!ok) { page.busy = false; page.owner.lastError = msg; return; }
+ page.owner.commitPush(kind, id, (ok2, msg2) => {
+ page.busy = false;
+ if (!ok2) { page.owner.lastError = msg2; return; }
+ page.toList();
+ });
});
return;
}
diff --git a/desktop/modules/notes/README.md b/desktop/modules/notes/README.md
index 0f642b8..42f989f 100644
--- a/desktop/modules/notes/README.md
+++ b/desktop/modules/notes/README.md
@@ -14,9 +14,9 @@ per note, named by its creation time in epoch seconds.
lists, links, inline code and quotes render; tables and fenced-code
highlighting do not.
- **Save** is two clicks: the first writes the note, the second reads
- **Commit & push?** and pushes it. **Delete** asks first, then removes the
- note and pushes the removal. With git off there is no second half, so Save
- writes and returns in one.
+ **Commit & push?**, writes whatever you have typed since, and pushes it.
+ **Delete** asks first, then removes the note and pushes the removal. With git
+ off there is no second half, so Save writes and returns in one.
- Leaving the editor with **Cancel**, the back arrow, Escape or a click
outside drops unsaved text. The save is the explicit act.
- **Update list** runs `git pull` and stamps `git.lastpull`.
@@ -38,9 +38,12 @@ git to resolve instead. A change made on two machines at once conflicts here
for the same reason it conflicts for `notes.sh`: every machine appends to the
one `db.json`.
-A write that fails is reported rather than assumed: the writes block, so a
-refused or failing `setText` is known when it returns, and a failed commit or
-push shows git's own message.
+A write that fails is reported rather than assumed. A body is written by a
+`Process` running `cat > <file>` with the text on stdin, not by a `FileView`:
+`setText` with an empty string, on a path that view has not loaded, creates no
+file and reports no error, which once put an empty note into `db.json` with no
+file beside it. `cat` takes any content at any length, including none, and its
+exit code is the outcome; a failed commit or push shows git's own message.
**Git order.** `notes.sh` pulls before it writes and commits after, and the
page keeps that order: creating a note pulls first, then writes on what the