Repository navigation
fix: improve offline editor save safety - #80
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bf94f1cef8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| try { | ||
| if (_titleCtrl.text != _note.title) { | ||
| await state.updateNoteTitle(_note.id, _titleCtrl.text); | ||
| _note = _note.copyWith(title: _titleCtrl.text); |
There was a problem hiding this comment.
Snapshot the submitted title before awaiting
If the user changes the title again while updateNoteTitle is in flight, this reads the newer controller value even though the request contained the older value. _note.title then incorrectly records the newer title as saved, so subsequent body saves skip updating it and reopening the note restores the stale server title. Capture the submitted title before the await and use that same snapshot for both the request and local note update.
Useful? React with 👍 / 👎.
| } | ||
|
|
||
| Future<void> _switchToInk() async { | ||
| await _flushTextBeforeModeSwitch(); |
There was a problem hiding this comment.
Avoid awaiting an unbounded save before switching modes
With a configured backend and pending edits, tapping Draw cannot update _showInk until the full title/text persistence chain completes. ApiClient.savePageText uses a raw http.put without a timeout, so a slow or unresponsive self-hosted server can leave the editor stuck in Text mode for an OS-level network timeout. Persist a captured snapshot without gating the visual mode change, or apply a bounded timeout.
Useful? React with 👍 / 👎.
| _note = _note.copyWith(title: _titleCtrl.text); | ||
| } | ||
| if (!_showInk) await state.savePageText(_note.id, 1, _contentCtrl.text); | ||
| await state.savePageText(_note.id, 1, _contentCtrl.text); |
There was a problem hiding this comment.
Save the body only when it is dirty
While the note is in Draw mode, a title edit sets _hasChanges and this unconditional call PUTs the body snapshot loaded when the editor opened. If another client has updated that page in the meantime, the title-only save overwrites the newer server body because the text endpoint directly replaces typed_content; the previous Draw-mode path skipped this write. Track title and body dirtiness separately so pending pre-switch text is flushed without resubmitting unchanged cached content.
Useful? React with 👍 / 👎.
| _saveTimer?.cancel(); | ||
| if (!_hasChanges) return; | ||
| if (mounted) setState(() => _isSaving = true); | ||
| final ok = await _persist(); |
There was a problem hiding this comment.
Serialize the mode-switch save with the active autosave
If the two-second autosave has already started, the user can type a newer body and tap Draw before that request finishes; _hasChanges is still true, so this starts a second _persist concurrently after canceling only the newer timer. The old and new bodies are then PUT independently, and if the older request completes last it overwrites the newer text while both completion paths clear the dirty flag. Queue the latest revision behind an active save rather than launching parallel persistence.
Useful? React with 👍 / 👎.
Summary
This PR makes a focused stability pass on NexaNote before more UI work:
Note.copyWithhelper for the API DTO so the editor can update its local title snapshot after a successful save.metadata/com.nexanote.app.ymlwith the currentapp/pubspec.yamlversion1.1.4+9.Manual test checklist
NexaNote-Android.apk.Notes
This is intentionally not a giant redesign PR. The next PR should do deeper Settings UI polish and canvas gesture work, especially two-finger pan/zoom vs drawing behavior.