Long-pressing a note in the list opens it in view mode with the scroll
position at the bottom of the file. Switching to edit mode the first
time positions the cursor at the end of the text and scrolls there too,
so the user can immediately append content.
Implementation:
- NoteEditorScreen gains a scrollToEnd parameter (default false)
- A ScrollController is attached to the view/edit SingleChildScrollView
- After content loads with scrollToEnd=true, two post-frame callbacks
fire (first renders the content, second has a stable maxScrollExtent)
then jumpTo(maxScrollExtent)
- _cursorAtEnd flag is consumed on the first Mode Edit switch: sets
selection to text.length, requests focus, and scrolls to bottom
- NoteListScreen ListTile gets onLongPress that navigates with
scrollToEnd: true and reloads on return
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
_filterNotes was calling note.readAsStringSync() and _extractTags() for
every note on every keystroke, plus recomputing path.relative() each
time. For large collections with many subdirectories this is O(n * disk).
Fix: build three maps during _loadNotes (which already reads every file
once) and use them in _filterNotes instead of touching the filesystem:
- _noteRelativePaths: pre-lowercased relative path per note
- _noteContentLower: pre-lowercased content for full-text search
- noteTags: already existed, now actually used in filter
_filterNotes now does only in-memory map lookups and string.contains
checks — no file reads, no regex, no path computation per keystroke.
Also fix _createNewNote: the Navigator.push was not awaited so
_loadNotes() was never called on return, leaving stale caches after
editing a freshly created note. Now awaits the push and reloads on
return, mirroring the existing-note tap behaviour.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
_filterNotes lowercases the query so searchTags contains e.g. '#work',
but _extractTags preserves original case from file content ('#Work').
The startsWith comparison was case-sensitive, causing all tag searches
to fail whenever the file used any uppercase in tag names.
Fix: toLowerCase() on the noteTag side before comparing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- filter notes by relative path instead of bare filename so searching
"/subdir" or "subdir" matches notes inside that subdirectory
- strip leading "/" from search text before matching so both forms work
- tighten tag regex in _extractTags and _formatTags: require a letter
after the symbol and a non-word boundary before it ((?<!\S)) to avoid
matching phone numbers (+44…) and email-local-part suffixes
- fix subdir/notename creation: use contains('/') instead of
startsWith('/') so names without a leading slash are split correctly
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Introduce NoteMode enum { view, edit, preview } replacing the old bool
- Default mode when opening a note is view (syntax-highlighted, read-only)
- Menu now shows all three modes with a checkmark on the active one
- Save and autosave menu items disabled outside edit mode
- New notes open in edit mode with cursor positioned after the header
and keyboard focused, ready to type
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>