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.
This commit is contained in:
Vishesh Handa
2019-12-04 15:14:17 +01:00
parent 10d65cd6fb
commit 5b8fc6342a
9 changed files with 48 additions and 56 deletions

View File

@ -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<Note> notes = [];
NotesFolder noteFolder;
NotesFolder notesFolder;
AppState(SharedPreferences pref) {
localGitRepoConfigured = pref.getBool("localGitRepoConfigured") ?? false;

View File

@ -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<Note> {
NotesFolder parent;
String filePath = "";
DateTime _created;
NoteData _data = NoteData();
@ -20,7 +24,7 @@ class Note implements Comparable<Note> {
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);
}

View File

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

View File

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

View File

@ -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<JournalEditor> {
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();
}

View File

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

View File

@ -57,7 +57,7 @@ class StateContainerState extends State<StateContainer> {
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<StateContainer> {
}
}
Future<List<Note>> _loadNotes() async {
await appState.noteFolder.loadRecursively();
var notes = appState.noteFolder.getAllNotes();
notes.sort((a, b) => b.compareTo(a));
return notes;
Future<void> _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: <String, dynamic>{
'count': loadedNotes.length,
},
);
});
}).catchError((err, stack) {
@ -124,9 +115,9 @@ class StateContainerState extends State<StateContainer> {
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<StateContainer> {
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<StateContainer> {
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<StateContainer> {
}
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<StateContainer> {
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<StateContainer> {
baseDirectory: appState.gitBaseDirectory,
dirName: appState.remoteGitRepoFolderName,
);
appState.noteFolder = NotesFolder(noteRepo.notesBasePath);
appState.notesFolder = NotesFolder(null, noteRepo.notesBasePath);
await _persistConfig();
_loadNotesFromDisk();

View File

@ -50,9 +50,9 @@ class GitNoteRepository {
return NoteRepoResult(noteFilePath: note.filePath, error: false);
}
Future<NoteRepoResult> removeNote(Note note) async {
Future<NoteRepoResult> 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<NoteRepoResult> resetLastCommit() async {

View File

@ -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 = <Note>[];
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);