mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-29 10:17:16 +08:00
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>[
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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(
|
||||
|
@ -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(),
|
||||
|
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user