From 77e67fca11b1f96452a66bbd5e807aa32151ee11 Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Mon, 20 Apr 2020 02:10:10 +0200 Subject: [PATCH] Rename Folders properly 1. Actually rename the folder instead of calling rename with the oldPath 2. Inform the parentFolder that a sub-folder has been renamed so it can accordingly update its mapping. Fixes #108 --- lib/core/note_notifier.dart | 2 + lib/core/notes_folder_fs.dart | 59 +++++++++++++++++++++-------- lib/core/notes_folder_notifier.dart | 53 ++++++++++++++++++++++++-- lib/state_container.dart | 1 + 4 files changed, 96 insertions(+), 19 deletions(-) diff --git a/lib/core/note_notifier.dart b/lib/core/note_notifier.dart index 81039f56..3792d7e3 100644 --- a/lib/core/note_notifier.dart +++ b/lib/core/note_notifier.dart @@ -15,6 +15,7 @@ class NotesNotifier implements ChangeNotifier { } void removeModifiedListener(NoteModificationCallback listener) { + assert(_modListeners.contains(listener)); _modListeners.remove(listener); } @@ -23,6 +24,7 @@ class NotesNotifier implements ChangeNotifier { } void removeRenameListener(NoteRenameCallback listener) { + assert(_renameListeners.contains(listener)); _renameListeners.remove(listener); } diff --git a/lib/core/notes_folder_fs.dart b/lib/core/notes_folder_fs.dart index faa2148b..ac4e7ebb 100644 --- a/lib/core/notes_folder_fs.dart +++ b/lib/core/notes_folder_fs.dart @@ -49,6 +49,14 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder { assert(_entityMap.containsKey(oldPath)); _entityMap.remove(oldPath); _entityMap[note.filePath] = note; + + notifyNoteRenamed(-1, note, oldPath); + } + + void _subFolderRenamed(NotesFolderFS folder, String oldPath) { + assert(_entityMap.containsKey(oldPath)); + _entityMap.remove(oldPath); + _entityMap[folder.folderPath] = folder; } void reset(String folderPath) { @@ -183,7 +191,8 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder { if (subFolder.name.startsWith('.')) { continue; } - subFolder.addListener(_entityChanged); + //Log.d("Found folder ${fsEntity.path}"); + _addFolderListeners(subFolder); _folders.add(subFolder); _entityMap[fsEntity.path] = subFolder; @@ -199,8 +208,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder { continue; } //Log.d("Found file ${fsEntity.path}"); - note.addModifiedListener(_noteModified); - note.addRenameListener(_noteRenamed); + _addNoteListeners(note); _notes.add(note); _entityMap[fsEntity.path] = note; @@ -219,7 +227,8 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder { if (e is Note) { Log.d("File $path was no longer found"); - e.removeModifiedListener(_noteModified); + _removeNoteListeners(e); + var i = _notes.indexWhere((n) => n.filePath == path); assert(i != -1); var note = _notes[i]; @@ -227,7 +236,8 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder { notifyNoteRemoved(i, note); } else { Log.d("Folder $path was no longer found"); - e.removeListener(_entityChanged); + _removeFolderListeners(e); + var i = _folders.indexWhere((f) => f.folderPath == path); assert(i != -1); var folder = _folders[i]; @@ -239,7 +249,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder { void add(Note note) { assert(note.parent == this); - note.addModifiedListener(_noteModified); + _addNoteListeners(note); _notes.add(note); _entityMap[note.filePath] = note; @@ -249,8 +259,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder { void remove(Note note) { assert(note.parent == this); - note.removeModifiedListener(_noteModified); - note.removeRenameListener(_noteRenamed); + _removeNoteListeners(note); assert(_notes.indexWhere((n) => n.filePath == note.filePath) != -1); assert(_entityMap.containsKey(note.filePath)); @@ -263,6 +272,16 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder { notifyNoteRemoved(index, note); } + void _addNoteListeners(Note note) { + note.addModifiedListener(_noteModified); + note.addRenameListener(_noteRenamed); + } + + void _removeNoteListeners(Note note) { + note.removeModifiedListener(_noteModified); + note.removeRenameListener(_noteRenamed); + } + void create() { // Git doesn't track Directories, only files, so we create an empty .gitignore file // in the directory instead. @@ -276,7 +295,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder { void addFolder(NotesFolderFS folder) { assert(folder.parent == this); - folder.addListener(_entityChanged); + _addFolderListeners(folder); _folders.add(folder); _entityMap[folder.folderPath] = folder; @@ -285,7 +304,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder { } void removeFolder(NotesFolderFS folder) { - folder.removeListener(_entityChanged); + _removeFolderListeners(folder); assert(_folders.indexWhere((f) => f.folderPath == folder.folderPath) != -1); assert(_entityMap.containsKey(folder.folderPath)); @@ -299,12 +318,22 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder { } void rename(String newName) { - var dir = Directory(folderPath); - var parentDirName = dirname(folderPath); - dir.renameSync(folderPath); - _folderPath = p.join(parentDirName, newName); + var oldPath = _folderPath; + var dir = Directory(_folderPath); + _folderPath = p.join(dirname(_folderPath), newName); + dir.renameSync(_folderPath); - notifyListeners(); + notifyThisFolderRenamed(this, oldPath); + } + + void _addFolderListeners(NotesFolderFS folder) { + folder.addListener(_entityChanged); + folder.addThisFolderRenamedListener(_subFolderRenamed); + } + + void _removeFolderListeners(NotesFolderFS folder) { + folder.removeListener(_entityChanged); + folder.removeThisFolderRenamedListener(_subFolderRenamed); } @override diff --git a/lib/core/notes_folder_notifier.dart b/lib/core/notes_folder_notifier.dart index 3ff6888a..dfdcc32f 100644 --- a/lib/core/notes_folder_notifier.dart +++ b/lib/core/notes_folder_notifier.dart @@ -1,11 +1,14 @@ import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; +import 'package:gitjournal/core/notes_folder_fs.dart'; import 'note.dart'; import 'notes_folder.dart'; typedef FolderNotificationCallback = void Function( int index, NotesFolder folder); +typedef FolderRenamedCallback = void Function( + NotesFolderFS folder, String oldPath); typedef NoteNotificationCallback = void Function(int index, Note note); typedef NoteRenamedCallback = void Function( int index, Note note, String oldPath); @@ -13,6 +16,7 @@ typedef NoteRenamedCallback = void Function( class NotesFolderNotifier implements ChangeNotifier { var _folderAddedListeners = ObserverList(); var _folderRemovedListeners = ObserverList(); + var _thisFolderRenamedListeners = ObserverList(); var _noteAddedListeners = ObserverList(); var _noteRemovedListeners = ObserverList(); @@ -24,6 +28,7 @@ class NotesFolderNotifier implements ChangeNotifier { } void removeFolderRemovedListener(FolderNotificationCallback listener) { + assert(_folderRemovedListeners.contains(listener)); _folderRemovedListeners.remove(listener); } @@ -32,14 +37,25 @@ class NotesFolderNotifier implements ChangeNotifier { } void removeFolderAddedListener(FolderNotificationCallback listener) { + assert(_folderAddedListeners.contains(listener)); _folderAddedListeners.remove(listener); } + void addThisFolderRenamedListener(FolderRenamedCallback listener) { + _thisFolderRenamedListeners.add(listener); + } + + void removeThisFolderRenamedListener(FolderRenamedCallback listener) { + assert(_thisFolderRenamedListeners.contains(listener)); + _thisFolderRenamedListeners.remove(listener); + } + void addNoteAddedListener(NoteNotificationCallback listener) { _noteAddedListeners.add(listener); } void removeNoteAddedListener(NoteNotificationCallback listener) { + assert(_noteAddedListeners.contains(listener)); _noteAddedListeners.remove(listener); } @@ -48,6 +64,7 @@ class NotesFolderNotifier implements ChangeNotifier { } void removeNoteRemovedListener(NoteNotificationCallback listener) { + assert(_noteRemovedListeners.contains(listener)); _noteRemovedListeners.remove(listener); } @@ -56,6 +73,7 @@ class NotesFolderNotifier implements ChangeNotifier { } void removeNoteModifiedListener(NoteNotificationCallback listener) { + assert(_noteModifiedListeners.contains(listener)); _noteModifiedListeners.remove(listener); } @@ -64,6 +82,7 @@ class NotesFolderNotifier implements ChangeNotifier { } void removeNoteRenameListener(NoteRenamedCallback listener) { + assert(_noteRenameListeners.contains(listener)); _noteRenameListeners.remove(listener); } @@ -72,6 +91,7 @@ class NotesFolderNotifier implements ChangeNotifier { void dispose() { _folderAddedListeners = null; _folderRemovedListeners = null; + _thisFolderRenamedListeners = null; _noteAddedListeners = null; _noteRemovedListeners = null; _noteModifiedListeners = null; @@ -123,6 +143,34 @@ class NotesFolderNotifier implements ChangeNotifier { _notifyFolderCallback(_folderRemovedListeners, index, folder); } + void notifyThisFolderRenamed(NotesFolderFS folder, String oldPath) { + final localListeners = + List.from(_thisFolderRenamedListeners); + for (var listener in localListeners) { + try { + if (_thisFolderRenamedListeners.contains(listener)) { + listener(folder, oldPath); + } + } catch (exception, stack) { + FlutterError.reportError(FlutterErrorDetails( + exception: exception, + stack: stack, + library: 'GitJournal', + context: ErrorDescription( + 'while dispatching notifications for $runtimeType'), + informationCollector: () sync* { + yield DiagnosticsProperty( + 'The $runtimeType sending notification was', + this, + style: DiagnosticsTreeStyle.errorProperty, + ); + }, + )); + } + } + notifyListeners(); + } + void _notifyNoteCallback( ObserverList _listeners, int index, @@ -170,13 +218,10 @@ class NotesFolderNotifier implements ChangeNotifier { } void notifyNoteRenamed(int index, Note note, String oldPath) { - if (_listeners == null) { - return; - } final localListeners = List.from(_noteRenameListeners); for (var listener in localListeners) { try { - if (_listeners.contains(listener)) { + if (_noteRenameListeners.contains(listener)) { listener(index, note, oldPath); } } catch (exception, stack) { diff --git a/lib/state_container.dart b/lib/state_container.dart index 3ad373f9..ccd1d1e5 100644 --- a/lib/state_container.dart +++ b/lib/state_container.dart @@ -162,6 +162,7 @@ class StateContainer with ChangeNotifier { void renameFolder(NotesFolderFS folder, String newFolderName) async { return _opLock.synchronized(() async { var oldFolderPath = folder.folderPath; + print("Renaming Folder from $oldFolderPath -> $newFolderName"); folder.rename(newFolderName); _gitRepo