Generate one journal entry per day

Fixes #243
This commit is contained in:
Vishesh Handa
2020-09-16 11:01:38 +02:00
parent 0b7448e535
commit 265e253584
14 changed files with 95 additions and 34 deletions

View File

@ -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

View File

@ -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

View File

@ -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<ChecklistEditor>
var itemTiles = <Widget>[];
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<ChecklistEditor>
editor: widget,
editorState: this,
noteModified: _noteModified,
isNewNote: widget.isNewNote,
editMode: widget.editMode,
parentFolder: widget.note.parent,
body: Column(
children: <Widget>[

View File

@ -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<JournalEditor>
JournalEditorHeader(note),
NoteBodyEditor(
textController: _textController,
autofocus: widget.isNewNote,
autofocus: widget.editMode,
onChanged: _noteTextChanged,
),
],
@ -103,7 +103,7 @@ class JournalEditorState extends State<JournalEditor>
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<JournalEditor>
}
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;

View File

@ -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<MarkdownEditor>
),
NoteBodyEditor(
textController: _textController,
autofocus: widget.isNewNote,
autofocus: widget.editMode,
onChanged: _noteTextChanged,
),
],
@ -137,7 +137,7 @@ class MarkdownEditorState extends State<MarkdownEditor>
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<MarkdownEditor>
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;

View File

@ -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<RawEditor>
var editor = EditorScrollView(
child: _NoteEditor(
textController: _textController,
autofocus: widget.isNewNote,
autofocus: widget.editMode,
onChanged: _noteTextChanged,
),
);
@ -101,7 +101,7 @@ class RawEditorState extends State<RawEditor>
editor: widget,
editorState: this,
noteModified: _noteModified,
isNewNote: widget.isNewNote,
editMode: widget.editMode,
parentFolder: note.parent,
body: editor,
);

View File

@ -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<EditorScaffold> {
settings.markdownDefaultView == SettingsMarkdownDefaultView.Edit;
}
if (widget.isNewNote) {
if (widget.editMode) {
editingMode = true;
}

View File

@ -38,6 +38,7 @@ class Features {
Feature.customMetaData,
Feature.localization,
Feature.inlineTags,
Feature.singleJournalEntry,
];
static final inProgress = <String>[
@ -328,6 +329,14 @@ class Feature {
"",
true,
);
static final singleJournalEntry = Feature(
"singleJournalEntry",
DateTime(2020, 09, 16),
tr("feature.singleJournalEntry"),
"",
true,
);
}
// Feature Adding checklist

View File

@ -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);

View File

@ -169,10 +169,22 @@ class _FolderViewState extends State<FolderView> {
fsFolder = getFolderForEditor(settings, rootFolder, editorType);
}
var settings = Provider.of<Settings>(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<Settings>(context);
var extraProps = Map<String, dynamic>.from(widget.newNoteExtraProps);
if (settings.customMetaData.isNotEmpty) {
var map = MarkdownYAMLCodec.parseYamlText(settings.customMetaData);

View File

@ -37,9 +37,13 @@ class NoteEditor extends StatefulWidget {
final List<String> existingImages;
final Map<String, dynamic> 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<NoteEditor> {
editTagsSelected: _editTagsSelected,
moveNoteToFolderSelected: _moveNoteToFolderSelected,
discardChangesSelected: _discardChangesSelected,
isNewNote: _isNewNote,
editMode: widget.editMode
);
case EditorType.Raw:
return RawEditor(
@ -178,7 +183,7 @@ class NoteEditorState extends State<NoteEditor> {
editTagsSelected: _editTagsSelected,
moveNoteToFolderSelected: _moveNoteToFolderSelected,
discardChangesSelected: _discardChangesSelected,
isNewNote: _isNewNote,
editMode: widget.editMode
);
case EditorType.Checklist:
return ChecklistEditor(
@ -192,7 +197,7 @@ class NoteEditorState extends State<NoteEditor> {
editTagsSelected: _editTagsSelected,
moveNoteToFolderSelected: _moveNoteToFolderSelected,
discardChangesSelected: _discardChangesSelected,
isNewNote: _isNewNote,
editMode: widget.editMode
);
case EditorType.Journal:
return JournalEditor(
@ -206,7 +211,7 @@ class NoteEditorState extends State<NoteEditor> {
editTagsSelected: _editTagsSelected,
moveNoteToFolderSelected: _moveNoteToFolderSelected,
discardChangesSelected: _discardChangesSelected,
isNewNote: _isNewNote,
editMode: widget.editMode
);
}
return null;

View File

@ -81,6 +81,18 @@ class SettingsEditorsScreenState extends State<SettingsEditorsScreen> {
},
),
),
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(

View File

@ -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(),

View File

@ -93,3 +93,15 @@ String toCurlCommand(String url, Map<String, String> headers) {
Future<void> shareNote(Note note) async {
return Share.share(note.body);
}
Future<Note> 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;
}