From 5b8fc6342adeb29fc9c015fbdfbea2bae41db67e Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Wed, 4 Dec 2019 15:14:17 +0100 Subject: [PATCH] Connect the AppState to the Folders Now when adding/editing/removing a note, it gets modified from the directory it was present in. There is no longer a just a plain list of all notes, but always a tree of notes, which are inside Folders. --- lib/appstate.dart | 6 ++-- lib/core/note.dart | 6 +++- lib/core/note_fs_entity.dart | 5 +--- lib/screens/folder_listing.dart | 4 +-- lib/screens/journal_editor.dart | 13 +++++---- lib/screens/journal_listing.dart | 11 +++++--- lib/state_container.dart | 47 ++++++++++++-------------------- lib/storage/git_storage.dart | 6 ++-- test/note_storage_test.dart | 6 ++-- 9 files changed, 48 insertions(+), 56 deletions(-) diff --git a/lib/appstate.dart b/lib/appstate.dart index c866ba83..9cd5aee6 100644 --- a/lib/appstate.dart +++ b/lib/appstate.dart @@ -1,6 +1,5 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:fimber/fimber.dart'; -import 'package:gitjournal/core/note.dart'; import 'package:gitjournal/core/notes_folder.dart'; class AppState { @@ -24,11 +23,10 @@ class AppState { String gitBaseDirectory = ""; bool get hasJournalEntries { - return notes.isNotEmpty; + return notesFolder.hasNotes; } - List notes = []; - NotesFolder noteFolder; + NotesFolder notesFolder; AppState(SharedPreferences pref) { localGitRepoConfigured = pref.getBool("localGitRepoConfigured") ?? false; diff --git a/lib/core/note.dart b/lib/core/note.dart index 6110e3ea..033db480 100644 --- a/lib/core/note.dart +++ b/lib/core/note.dart @@ -3,6 +3,8 @@ import 'dart:io'; import 'package:gitjournal/storage/serializers.dart'; import 'package:gitjournal/utils/datetime.dart'; +import 'notes_folder.dart'; + enum NoteLoadState { None, Loading, @@ -11,7 +13,9 @@ enum NoteLoadState { } class Note implements Comparable { + NotesFolder parent; String filePath = ""; + DateTime _created; NoteData _data = NoteData(); @@ -20,7 +24,7 @@ class Note implements Comparable { var _loadState = NoteLoadState.None; var _serializer = MarkdownYAMLSerializer(); - Note([this.filePath]) { + Note(this.parent, [this.filePath]) { _created = _created ?? DateTime(0, 0, 0, 0, 0, 0, 0, 0); } diff --git a/lib/core/note_fs_entity.dart b/lib/core/note_fs_entity.dart index c3740b2e..be9862a4 100644 --- a/lib/core/note_fs_entity.dart +++ b/lib/core/note_fs_entity.dart @@ -1,14 +1,11 @@ import 'note.dart'; import 'notes_folder.dart'; -// FIXME: Maybe the parent should be a part of the Note, and the NoteFolder -// or maybe also a part of the NoteFolder class NoteFSEntity { - NotesFolder parent; NotesFolder folder; Note note; - NoteFSEntity(this.parent, {this.folder, this.note}) { + NoteFSEntity({this.folder, this.note}) { assert(folder != null || note != null); } diff --git a/lib/screens/folder_listing.dart b/lib/screens/folder_listing.dart index 5a6a7e03..c1b812a2 100644 --- a/lib/screens/folder_listing.dart +++ b/lib/screens/folder_listing.dart @@ -15,11 +15,11 @@ class FolderListingScreen extends StatelessWidget { final appState = container.appState; var treeView = FolderTreeView( - rootFolder: appState.noteFolder, + rootFolder: appState.notesFolder, onFolderSelected: (NotesFolder folder) { var route = MaterialPageRoute( builder: (context) => JournalListingScreen( - noteFolder: folder, + notesFolder: folder, ), ); Navigator.of(context).push(route); diff --git a/lib/screens/journal_editor.dart b/lib/screens/journal_editor.dart index 56f8d34c..12773184 100644 --- a/lib/screens/journal_editor.dart +++ b/lib/screens/journal_editor.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:gitjournal/core/note.dart'; +import 'package:gitjournal/core/notes_folder.dart'; import 'package:gitjournal/state_container.dart'; import 'package:gitjournal/widgets/journal_editor_header.dart'; import 'package:gitjournal/storage/serializers.dart'; @@ -8,14 +9,15 @@ enum NoteEditorDropDownChoices { Discard, SwitchEditor } class JournalEditor extends StatefulWidget { final Note note; + final NotesFolder notesFolder; - JournalEditor() : note = null; - JournalEditor.fromNote(this.note); + JournalEditor.fromNote(this.note) : notesFolder = null; + JournalEditor.newNote(this.notesFolder) : note = null; @override JournalEditorState createState() { if (note == null) { - return JournalEditorState(); + return JournalEditorState.newNote(notesFolder); } else { return JournalEditorState.fromNote(note); } @@ -23,13 +25,14 @@ class JournalEditor extends StatefulWidget { } class JournalEditorState extends State { - Note note = Note(); + Note note; final bool newNote; TextEditingController _textController = TextEditingController(); bool rawEditor = false; final serializer = MarkdownYAMLSerializer(); - JournalEditorState() : newNote = true { + JournalEditorState.newNote(NotesFolder folder) : newNote = true { + note = Note(folder); note.created = DateTime.now(); } diff --git a/lib/screens/journal_listing.dart b/lib/screens/journal_listing.dart index 44ba51dc..2d680a1c 100644 --- a/lib/screens/journal_listing.dart +++ b/lib/screens/journal_listing.dart @@ -12,10 +12,10 @@ import 'package:gitjournal/widgets/journal_list.dart'; import 'package:gitjournal/themes.dart'; class JournalListingScreen extends StatelessWidget { - final NotesFolder noteFolder; + final NotesFolder notesFolder; final bool recursive; - JournalListingScreen({@required this.noteFolder, this.recursive = false}); + JournalListingScreen({@required this.notesFolder, this.recursive = false}); @override Widget build(BuildContext context) { @@ -27,7 +27,9 @@ class JournalListingScreen extends StatelessWidget { child: Icon(Icons.add), ); - var allNotes = recursive ? noteFolder.getAllNotes() : noteFolder.getNotes(); + var allNotes = + recursive ? notesFolder.getAllNotes() : notesFolder.getNotes(); + allNotes.sort((a, b) => b.compareTo(a)); Widget journalList = JournalList( notes: allNotes, @@ -76,7 +78,8 @@ class JournalListingScreen extends StatelessWidget { } void _newPost(BuildContext context) { - var route = MaterialPageRoute(builder: (context) => JournalEditor()); + var route = MaterialPageRoute( + builder: (context) => JournalEditor.newNote(notesFolder)); Navigator.of(context).push(route); } } diff --git a/lib/state_container.dart b/lib/state_container.dart index a8f38f53..ee25ff7a 100644 --- a/lib/state_container.dart +++ b/lib/state_container.dart @@ -57,7 +57,7 @@ class StateContainerState extends State { dirName: appState.localGitRepoPath, ); } - appState.noteFolder = NotesFolder(noteRepo.notesBasePath); + appState.notesFolder = NotesFolder(null, noteRepo.notesBasePath); // Just a fail safe if (!appState.remoteGitRepoConfigured) { @@ -79,25 +79,16 @@ class StateContainerState extends State { } } - Future> _loadNotes() async { - await appState.noteFolder.loadRecursively(); - var notes = appState.noteFolder.getAllNotes(); - notes.sort((a, b) => b.compareTo(a)); - - return notes; + Future _loadNotes() async { + await appState.notesFolder.loadRecursively(); } void _loadNotesFromDisk() { Fimber.d("Loading Notes From Disk"); - _loadNotes().then((loadedNotes) { + _loadNotes().then((void _) { setState(() { - appState.notes = loadedNotes; - getAnalytics().logEvent( name: "notes_loaded", - parameters: { - 'count': loadedNotes.length, - }, ); }); }).catchError((err, stack) { @@ -124,9 +115,9 @@ class StateContainerState extends State { await noteRepo.sync(); try { - var loadedNotes = await _loadNotes(); + await _loadNotes(); setState(() { - appState.notes = loadedNotes; + // TODO: Inform exactly what notes have changed? }); } catch (err, stack) { setState(() { @@ -159,8 +150,8 @@ class StateContainerState extends State { void removeNote(Note note) { setState(() { - appState.notes.remove(note); - noteRepo.removeNote(note).then((NoteRepoResult _) async { + note.parent.remove(note); + noteRepo.removeNote(note.filePath).then((NoteRepoResult _) async { // FIXME: Is there a way of figuring this amount dynamically? // The '4 seconds' is taken from snack_bar.dart -> _kSnackBarDisplayDuration // We wait an aritfical amount of time, so that the user has a change to undo @@ -173,7 +164,7 @@ class StateContainerState extends State { void undoRemoveNote(Note note, int index) { setState(() { - appState.notes.insert(index, note); + note.parent.insert(index, note); noteRepo.resetLastCommit().then((NoteRepoResult _) { _syncNotes(); }); @@ -181,12 +172,15 @@ class StateContainerState extends State { } void insertNote(int index, Note note) { - Fimber.d("State Container insertNote"); + Fimber.d("State Container insertNote " + index.toString()); setState(() { if (note.filePath == null || note.filePath.isEmpty) { - note.filePath = p.join(noteRepo.notesBasePath, getFileName(note)); + var parentPath = note.parent != null + ? note.parent.folderPath + : noteRepo.notesBasePath; + note.filePath = p.join(parentPath, getFileName(note)); } - appState.notes.insert(index, note); + note.parent.insert(index, note); noteRepo.addNote(note).then((NoteRepoResult _) { _syncNotes(); }); @@ -196,14 +190,7 @@ class StateContainerState extends State { void updateNote(Note note) { Fimber.d("State Container updateNote"); setState(() { - // Update that specific note - for (var i = 0; i < appState.notes.length; i++) { - var n = appState.notes[i]; - if (n.filePath == note.filePath) { - appState.notes[i] = note; - } - } - + // Update the git repo noteRepo.updateNote(note).then((NoteRepoResult _) { _syncNotes(); }); @@ -225,7 +212,7 @@ class StateContainerState extends State { baseDirectory: appState.gitBaseDirectory, dirName: appState.remoteGitRepoFolderName, ); - appState.noteFolder = NotesFolder(noteRepo.notesBasePath); + appState.notesFolder = NotesFolder(null, noteRepo.notesBasePath); await _persistConfig(); _loadNotesFromDisk(); diff --git a/lib/storage/git_storage.dart b/lib/storage/git_storage.dart index 9158aaf2..900a5180 100644 --- a/lib/storage/git_storage.dart +++ b/lib/storage/git_storage.dart @@ -50,9 +50,9 @@ class GitNoteRepository { return NoteRepoResult(noteFilePath: note.filePath, error: false); } - Future removeNote(Note note) async { + Future removeNote(String noteFilePath) async { var gitDir = p.join(baseDirectory, dirName); - var pathSpec = note.filePath.replaceFirst(gitDir, "").substring(1); + var pathSpec = noteFilePath.replaceFirst(gitDir, "").substring(1); // We are not calling note.remove() as gitRm will also remove the file await _gitRepo.rm(pathSpec); @@ -60,7 +60,7 @@ class GitNoteRepository { message: "Removed Journal entry", ); - return NoteRepoResult(noteFilePath: note.filePath, error: false); + return NoteRepoResult(noteFilePath: noteFilePath, error: false); } Future resetLastCommit() async { diff --git a/test/note_storage_test.dart b/test/note_storage_test.dart index 1d80f572..ab2441b2 100644 --- a/test/note_storage_test.dart +++ b/test/note_storage_test.dart @@ -25,11 +25,11 @@ void main() { n1Path = p.join(tempDir.path, "1.md"); n2Path = p.join(tempDir.path, "2.md"); - var n1 = Note(n1Path); + var n1 = Note(null, n1Path); n1.body = "test"; n1.created = dt; - var n2 = Note(n2Path); + var n2 = Note(null, n2Path); n2.data = NoteData("test2", props); notes = [n1, n2]; @@ -49,7 +49,7 @@ void main() { var loadedNotes = []; await Future.forEach(notes, (origNote) async { - var note = Note(origNote.filePath); + var note = Note(null, origNote.filePath); var r = await note.load(); expect(r, NoteLoadState.Loaded);