add view mode as default, open new notes in edit mode with cursor ready

- 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>
This commit is contained in:
randogoth 2026-06-19 17:21:00 +03:00
parent 6b11515aa2
commit bf214afe72
2 changed files with 57 additions and 14 deletions

View file

@ -17,28 +17,35 @@ class NoteEditorScreen extends StatefulWidget {
final String? notesDirectoryPath; // Add this final String? notesDirectoryPath; // Add this
final bool isDarkMode; final bool isDarkMode;
final NoteMode initialMode;
const NoteEditorScreen({ const NoteEditorScreen({
super.key, super.key,
required this.note, required this.note,
required this.isDarkMode, required this.isDarkMode,
required this.notesDirectoryPath, required this.notesDirectoryPath,
this.initialMode = NoteMode.view,
}); });
@override @override
State<NoteEditorScreen> createState() => _NoteEditorScreenState(); State<NoteEditorScreen> createState() => _NoteEditorScreenState();
} }
enum NoteMode { view, edit, preview }
class _NoteEditorScreenState extends State<NoteEditorScreen> { class _NoteEditorScreenState extends State<NoteEditorScreen> {
late CodeController _controller; late CodeController _controller;
late String _initialContent; late String _initialContent;
bool _isPreviewMode = false; late NoteMode _mode;
final FocusNode _editorFocusNode = FocusNode();
bool _isLoading = true; bool _isLoading = true;
bool _autoSaveEnabled = false; // Controlled by user toggle bool _autoSaveEnabled = false;
double _fontSize = 16.0; double _fontSize = 16.0;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_mode = widget.initialMode;
_loadPreferences(); _loadPreferences();
_loadNoteContent(); _loadNoteContent();
} }
@ -74,10 +81,18 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
_controller.addListener(_onTextChanged); _controller.addListener(_onTextChanged);
_isLoading = false; _isLoading = false;
}); });
if (widget.initialMode == NoteMode.edit) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_controller.selection =
TextSelection.collapsed(offset: _controller.text.length);
_editorFocusNode.requestFocus();
});
}
} }
void _onTextChanged() { void _onTextChanged() {
if (_autoSaveEnabled && _controller.text != _initialContent) { if (_mode == NoteMode.edit && _autoSaveEnabled && _controller.text != _initialContent) {
_saveNote(); _saveNote();
} }
} }
@ -105,7 +120,7 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
} }
Future<bool> _onWillPop() async { Future<bool> _onWillPop() async {
if (_controller.text == _initialContent) return true; // No changes, exit if (_mode != NoteMode.edit || _controller.text == _initialContent) return true;
return await showDialog( return await showDialog(
context: context, context: context,
@ -144,6 +159,7 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
void dispose() { void dispose() {
_controller.removeListener(_onTextChanged); _controller.removeListener(_onTextChanged);
_controller.dispose(); _controller.dispose();
_editorFocusNode.dispose();
super.dispose(); super.dispose();
} }
@ -187,10 +203,14 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
case 'Toggle Autosave': case 'Toggle Autosave':
_setAutoSaveEnabled(!_autoSaveEnabled); _setAutoSaveEnabled(!_autoSaveEnabled);
break; break;
case 'Toggle Preview': case 'Mode View':
setState(() { setState(() { _mode = NoteMode.view; });
_isPreviewMode = !_isPreviewMode; break;
}); case 'Mode Edit':
setState(() { _mode = NoteMode.edit; });
break;
case 'Mode Preview':
setState(() { _mode = NoteMode.preview; });
break; break;
} }
}, },
@ -205,6 +225,7 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
PopupMenuDivider(), PopupMenuDivider(),
PopupMenuItem<String>( PopupMenuItem<String>(
value: 'Save', value: 'Save',
enabled: _mode == NoteMode.edit,
child: ListTile( child: ListTile(
leading: Icon(Icons.save_outlined), leading: Icon(Icons.save_outlined),
title: Text("Save"), title: Text("Save"),
@ -212,6 +233,7 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
), ),
PopupMenuItem<String>( PopupMenuItem<String>(
value: 'Toggle Autosave', value: 'Toggle Autosave',
enabled: _mode == NoteMode.edit,
child: ListTile( child: ListTile(
leading: Icon(_autoSaveEnabled leading: Icon(_autoSaveEnabled
? Icons.alarm_off ? Icons.alarm_off
@ -250,12 +272,30 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
), ),
PopupMenuDivider(), PopupMenuDivider(),
PopupMenuItem<String>( PopupMenuItem<String>(
value: 'Toggle Preview', value: 'Mode View',
child: ListTile( child: ListTile(
leading: leading: Icon(_mode == NoteMode.view
Icon(_isPreviewMode ? Icons.edit_note_outlined : Icons.visibility_outlined), ? Icons.check
title: : Icons.book_outlined),
Text(_isPreviewMode ? "Edit Mode" : "Preview Mode"), title: Text("View Mode"),
),
),
PopupMenuItem<String>(
value: 'Mode Edit',
child: ListTile(
leading: Icon(_mode == NoteMode.edit
? Icons.check
: Icons.edit_note_outlined),
title: Text("Edit Mode"),
),
),
PopupMenuItem<String>(
value: 'Mode Preview',
child: ListTile(
leading: Icon(_mode == NoteMode.preview
? Icons.check
: Icons.visibility_outlined),
title: Text("Preview Mode"),
), ),
), ),
], ],
@ -265,7 +305,7 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
), ),
body: _isLoading body: _isLoading
? Center(child: CircularProgressIndicator()) ? Center(child: CircularProgressIndicator())
: _isPreviewMode : _mode == NoteMode.preview
? Padding( ? Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView( child: SingleChildScrollView(
@ -325,6 +365,8 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
child: WrappedCodeField( child: WrappedCodeField(
wrap: true, wrap: true,
controller: _controller, controller: _controller,
readOnly: _mode == NoteMode.view,
focusNode: _editorFocusNode,
textStyle: TextStyle( textStyle: TextStyle(
fontSize: _fontSize, fontSize: _fontSize,
), ),

View file

@ -449,6 +449,7 @@ Happy note taking! ✨
note: newNote, note: newNote,
isDarkMode: widget.isDarkMode, isDarkMode: widget.isDarkMode,
notesDirectoryPath: notesDirectoryPath, notesDirectoryPath: notesDirectoryPath,
initialMode: NoteMode.edit,
), ),
), ),
); );