diff --git a/assets/langs/en.yaml b/assets/langs/en.yaml index dc28d03f..22d5b870 100644 --- a/assets/langs/en.yaml +++ b/assets/langs/en.yaml @@ -389,6 +389,7 @@ feature: title: Localization subtitle: Allow GitJournal to be translated inlineTags: Inline Tags + singleJournalEntry: Single Journal Entry File per day feature_timeline: title: Feature Timeline diff --git a/changelog.yml b/changelog.yml index 29d409a1..5142b8c7 100644 --- a/changelog.yml +++ b/changelog.yml @@ -5,6 +5,9 @@ - text: "Implement Basic Search highlighting #14" - text: Implement basic note selection image: note_select_delete.gif + - title: Single Journal entry Per Day + text: Some users prefer all the journal entries for a single day be in the same file. This matches with how Obsidian and Foam handle daily notes. + image: single_journal_entry.jpeg improvements: - title: Purchase Screen text: Make it prettier for smaller screen sizes diff --git a/lib/editors/checklist_editor.dart b/lib/editors/checklist_editor.dart index 3d61270f..fd10fc31 100644 --- a/lib/editors/checklist_editor.dart +++ b/lib/editors/checklist_editor.dart @@ -31,7 +31,7 @@ class ChecklistEditor extends StatefulWidget implements Editor { @override final NoteCallback discardChangesSelected; - final bool isNewNote; + final bool editMode; ChecklistEditor({ Key key, @@ -44,7 +44,7 @@ class ChecklistEditor extends StatefulWidget implements Editor { @required this.editTagsSelected, @required this.moveNoteToFolderSelected, @required this.discardChangesSelected, - @required this.isNewNote, + @required this.editMode, }) : super(key: key); @override @@ -127,7 +127,7 @@ class ChecklistEditorState extends State var itemTiles = []; for (var i = 0; i < checklist.items.length; i++) { var item = checklist.items[i]; - var autofocus = widget.isNewNote && (i == checklist.items.length - 1); + var autofocus = widget.editMode && (i == checklist.items.length - 1); itemTiles.add(_buildTile(item, i, autofocus)); } itemTiles.add(AddItemButton( @@ -174,7 +174,7 @@ class ChecklistEditorState extends State editor: widget, editorState: this, noteModified: _noteModified, - isNewNote: widget.isNewNote, + editMode: widget.editMode, parentFolder: widget.note.parent, body: Column( children: [ diff --git a/lib/editors/journal_editor.dart b/lib/editors/journal_editor.dart index 77c80bd1..b8476107 100644 --- a/lib/editors/journal_editor.dart +++ b/lib/editors/journal_editor.dart @@ -28,7 +28,7 @@ class JournalEditor extends StatefulWidget implements Editor { @override final NoteCallback discardChangesSelected; - final bool isNewNote; + final bool editMode; JournalEditor({ Key key, @@ -41,7 +41,7 @@ class JournalEditor extends StatefulWidget implements Editor { @required this.editTagsSelected, @required this.moveNoteToFolderSelected, @required this.discardChangesSelected, - this.isNewNote = false, + this.editMode = false, }) : super(key: key); @override @@ -92,7 +92,7 @@ class JournalEditorState extends State JournalEditorHeader(note), NoteBodyEditor( textController: _textController, - autofocus: widget.isNewNote, + autofocus: widget.editMode, onChanged: _noteTextChanged, ), ], @@ -103,7 +103,7 @@ class JournalEditorState extends State editor: widget, editorState: this, noteModified: _noteModified, - isNewNote: widget.isNewNote, + editMode: widget.editMode, parentFolder: note.parent, body: editor, ); @@ -117,12 +117,12 @@ class JournalEditorState extends State } void _noteTextChanged() { - if (_noteModified && !widget.isNewNote) { + if (_noteModified && !widget.editMode) { notifyListeners(); return; } - var newState = !(widget.isNewNote && _textController.text.trim().isEmpty); + var newState = !(widget.editMode && _textController.text.trim().isEmpty); if (newState != _noteModified) { setState(() { _noteModified = newState; diff --git a/lib/editors/markdown_editor.dart b/lib/editors/markdown_editor.dart index b4e1b437..6666e099 100644 --- a/lib/editors/markdown_editor.dart +++ b/lib/editors/markdown_editor.dart @@ -33,7 +33,7 @@ class MarkdownEditor extends StatefulWidget implements Editor { @override final NoteCallback discardChangesSelected; - final bool isNewNote; + final bool editMode; MarkdownEditor({ Key key, @@ -47,7 +47,7 @@ class MarkdownEditor extends StatefulWidget implements Editor { @required this.editTagsSelected, @required this.moveNoteToFolderSelected, @required this.discardChangesSelected, - @required this.isNewNote, + @required this.editMode, }) : super(key: key); @override @@ -108,7 +108,7 @@ class MarkdownEditorState extends State ), NoteBodyEditor( textController: _textController, - autofocus: widget.isNewNote, + autofocus: widget.editMode, onChanged: _noteTextChanged, ), ], @@ -137,7 +137,7 @@ class MarkdownEditorState extends State editor: widget, editorState: this, noteModified: _noteModified, - isNewNote: widget.isNewNote, + editMode: widget.editMode, parentFolder: note.parent, body: editor, ); @@ -162,9 +162,9 @@ class MarkdownEditorState extends State Log.e("EditorHeuristics: $e"); logExceptionWarning(e, stackTrace); } - if (_noteModified && !widget.isNewNote) return; + if (_noteModified && !widget.editMode) return; - var newState = !(widget.isNewNote && _textController.text.trim().isEmpty); + var newState = !(widget.editMode && _textController.text.trim().isEmpty); if (newState != _noteModified) { setState(() { _noteModified = newState; diff --git a/lib/editors/raw_editor.dart b/lib/editors/raw_editor.dart index 05e42d52..9850a77b 100644 --- a/lib/editors/raw_editor.dart +++ b/lib/editors/raw_editor.dart @@ -29,7 +29,7 @@ class RawEditor extends StatefulWidget implements Editor { @override final NoteCallback discardChangesSelected; - final bool isNewNote; + final bool editMode; RawEditor({ Key key, @@ -42,7 +42,7 @@ class RawEditor extends StatefulWidget implements Editor { @required this.editTagsSelected, @required this.moveNoteToFolderSelected, @required this.discardChangesSelected, - @required this.isNewNote, + @required this.editMode, }) : super(key: key); @override @@ -92,7 +92,7 @@ class RawEditorState extends State var editor = EditorScrollView( child: _NoteEditor( textController: _textController, - autofocus: widget.isNewNote, + autofocus: widget.editMode, onChanged: _noteTextChanged, ), ); @@ -101,7 +101,7 @@ class RawEditorState extends State editor: widget, editorState: this, noteModified: _noteModified, - isNewNote: widget.isNewNote, + editMode: widget.editMode, parentFolder: note.parent, body: editor, ); diff --git a/lib/editors/scaffold.dart b/lib/editors/scaffold.dart index e8acbc08..9d8a059f 100644 --- a/lib/editors/scaffold.dart +++ b/lib/editors/scaffold.dart @@ -12,7 +12,7 @@ class EditorScaffold extends StatefulWidget { final Editor editor; final EditorState editorState; final bool noteModified; - final bool isNewNote; + final bool editMode; final IconButton extraButton; final Widget body; final NotesFolderFS parentFolder; @@ -21,7 +21,7 @@ class EditorScaffold extends StatefulWidget { @required this.editor, @required this.editorState, @required this.noteModified, - @required this.isNewNote, + @required this.editMode, @required this.body, @required this.parentFolder, this.extraButton, @@ -53,7 +53,7 @@ class _EditorScaffoldState extends State { settings.markdownDefaultView == SettingsMarkdownDefaultView.Edit; } - if (widget.isNewNote) { + if (widget.editMode) { editingMode = true; } diff --git a/lib/features.dart b/lib/features.dart index f0a55301..35fa7bed 100644 --- a/lib/features.dart +++ b/lib/features.dart @@ -38,6 +38,7 @@ class Features { Feature.customMetaData, Feature.localization, Feature.inlineTags, + Feature.singleJournalEntry, ]; static final inProgress = [ @@ -328,6 +329,14 @@ class Feature { "", true, ); + + static final singleJournalEntry = Feature( + "singleJournalEntry", + DateTime(2020, 09, 16), + tr("feature.singleJournalEntry"), + "", + true, + ); } // Feature Adding checklist diff --git a/lib/folder_views/common.dart b/lib/folder_views/common.dart index 9eb2bb56..ec15911d 100644 --- a/lib/folder_views/common.dart +++ b/lib/folder_views/common.dart @@ -79,10 +79,11 @@ Widget buildFolderView({ void openNoteEditor( BuildContext context, Note note, - NotesFolder parentFolder, -) async { + NotesFolder parentFolder, { + bool editMode = false, +}) async { var route = MaterialPageRoute( - builder: (context) => NoteEditor.fromNote(note, parentFolder), + builder: (context) => NoteEditor.fromNote(note, parentFolder, editMode: editMode), settings: const RouteSettings(name: '/note/'), ); var showUndoSnackBar = await Navigator.of(context).push(route); diff --git a/lib/screens/folder_view.dart b/lib/screens/folder_view.dart index 97f79210..7ce960f7 100644 --- a/lib/screens/folder_view.dart +++ b/lib/screens/folder_view.dart @@ -169,10 +169,22 @@ class _FolderViewState extends State { fsFolder = getFolderForEditor(settings, rootFolder, editorType); } + var settings = Provider.of(context); + + if (editorType == EditorType.Journal) { + if (settings.journalEditorSingleNote) { + var note = await getTodayJournalEntry(fsFolder.rootFolder); + return openNoteEditor( + context, + note, + widget.notesFolder, + editMode: true, + ); + } + } var routeType = SettingsEditorType.fromEditorType(editorType).toInternalString(); - var settings = Provider.of(context); var extraProps = Map.from(widget.newNoteExtraProps); if (settings.customMetaData.isNotEmpty) { var map = MarkdownYAMLCodec.parseYamlText(settings.customMetaData); diff --git a/lib/screens/note_editor.dart b/lib/screens/note_editor.dart index bfe4d7c9..c60a2fce 100644 --- a/lib/screens/note_editor.dart +++ b/lib/screens/note_editor.dart @@ -37,9 +37,13 @@ class NoteEditor extends StatefulWidget { final List existingImages; final Map newNoteExtraProps; + final bool editMode; - NoteEditor.fromNote(this.note, this.parentFolderView) - : notesFolder = note.parent, + NoteEditor.fromNote( + this.note, + this.parentFolderView, { + this.editMode = false, + }) : notesFolder = note.parent, defaultEditorType = null, existingText = null, existingImages = null, @@ -52,7 +56,8 @@ class NoteEditor extends StatefulWidget { this.existingText, this.existingImages, this.newNoteExtraProps = const {}, - }) : note = null; + }) : note = null, + editMode = true; @override NoteEditorState createState() { @@ -164,7 +169,7 @@ class NoteEditorState extends State { editTagsSelected: _editTagsSelected, moveNoteToFolderSelected: _moveNoteToFolderSelected, discardChangesSelected: _discardChangesSelected, - isNewNote: _isNewNote, + editMode: widget.editMode ); case EditorType.Raw: return RawEditor( @@ -178,7 +183,7 @@ class NoteEditorState extends State { editTagsSelected: _editTagsSelected, moveNoteToFolderSelected: _moveNoteToFolderSelected, discardChangesSelected: _discardChangesSelected, - isNewNote: _isNewNote, + editMode: widget.editMode ); case EditorType.Checklist: return ChecklistEditor( @@ -192,7 +197,7 @@ class NoteEditorState extends State { editTagsSelected: _editTagsSelected, moveNoteToFolderSelected: _moveNoteToFolderSelected, discardChangesSelected: _discardChangesSelected, - isNewNote: _isNewNote, + editMode: widget.editMode ); case EditorType.Journal: return JournalEditor( @@ -206,7 +211,7 @@ class NoteEditorState extends State { editTagsSelected: _editTagsSelected, moveNoteToFolderSelected: _moveNoteToFolderSelected, discardChangesSelected: _discardChangesSelected, - isNewNote: _isNewNote, + editMode: widget.editMode ); } return null; diff --git a/lib/screens/settings_editors.dart b/lib/screens/settings_editors.dart index ddc66ea5..77f53095 100644 --- a/lib/screens/settings_editors.dart +++ b/lib/screens/settings_editors.dart @@ -81,6 +81,18 @@ class SettingsEditorsScreenState extends State { }, ), ), + ProOverlay( + feature: Feature.singleJournalEntry, + child: SwitchListTile( + title: Text(tr("feature.singleJournalEntry")), + value: settings.journalEditorSingleNote, + onChanged: (bool newVal) { + settings.journalEditorSingleNote = newVal; + settings.save(); + setState(() {}); + }, + ), + ), ]); return Scaffold( diff --git a/lib/settings.dart b/lib/settings.dart index 1a98c587..bfca15e7 100644 --- a/lib/settings.dart +++ b/lib/settings.dart @@ -35,6 +35,7 @@ class Settings extends ChangeNotifier { bool yamlHeaderEnabled = true; String defaultNewNoteFolderSpec = ""; String journalEditordefaultNewNoteFolderSpec = ""; + bool journalEditorSingleNote = false; RemoteSyncFrequency remoteSyncFrequency = RemoteSyncFrequency.Default; SortingField sortingField = SortingField.Default; @@ -99,6 +100,8 @@ class Settings extends ChangeNotifier { journalEditordefaultNewNoteFolderSpec = pref.getString("journalEditordefaultNewNoteFolderSpec") ?? journalEditordefaultNewNoteFolderSpec; + journalEditorSingleNote = + pref.getBool("journalEditorSingleNote") ?? journalEditorSingleNote; remoteSyncFrequency = RemoteSyncFrequency.fromInternalString( pref.getString("remoteSyncFrequency")); @@ -191,6 +194,8 @@ class Settings extends ChangeNotifier { "journalEditordefaultNewNoteFolderSpec", journalEditordefaultNewNoteFolderSpec, defaultSet.journalEditordefaultNewNoteFolderSpec); + _setBool(pref, "journalEditorSingleNote", journalEditorSingleNote, + defaultSet.journalEditorSingleNote); _setString( pref, "remoteSyncFrequency", @@ -300,6 +305,7 @@ class Settings extends ChangeNotifier { "defaultNewNoteFolderSpec": defaultNewNoteFolderSpec, "journalEditordefaultNewNoteFolderSpec": journalEditordefaultNewNoteFolderSpec, + 'journalEditorSingleNote': journalEditorSingleNote.toString(), "defaultEditor": defaultEditor.toInternalString(), "defaultView": defaultView.toInternalString(), "sortingField": sortingField.toInternalString(), diff --git a/lib/utils.dart b/lib/utils.dart index 01ec9f27..3a047bf4 100644 --- a/lib/utils.dart +++ b/lib/utils.dart @@ -93,3 +93,15 @@ String toCurlCommand(String url, Map headers) { Future shareNote(Note note) async { return Share.share(note.body); } + +Future getTodayJournalEntry(NotesFolderFS rootFolder) async { + var today = DateTime.now(); + var matches = await rootFolder.matchNotes((n) async { + var dt = n.created; + return dt.year == today.year && + dt.month == today.month && + dt.day == today.day; + }); + + return matches.isNotEmpty ? matches[0] : null; +}