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
This commit is contained in:
Vishesh Handa
2020-04-20 02:10:10 +02:00
parent 5784399ac6
commit 77e67fca11
4 changed files with 96 additions and 19 deletions

View File

@ -15,6 +15,7 @@ class NotesNotifier implements ChangeNotifier {
} }
void removeModifiedListener(NoteModificationCallback listener) { void removeModifiedListener(NoteModificationCallback listener) {
assert(_modListeners.contains(listener));
_modListeners.remove(listener); _modListeners.remove(listener);
} }
@ -23,6 +24,7 @@ class NotesNotifier implements ChangeNotifier {
} }
void removeRenameListener(NoteRenameCallback listener) { void removeRenameListener(NoteRenameCallback listener) {
assert(_renameListeners.contains(listener));
_renameListeners.remove(listener); _renameListeners.remove(listener);
} }

View File

@ -49,6 +49,14 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
assert(_entityMap.containsKey(oldPath)); assert(_entityMap.containsKey(oldPath));
_entityMap.remove(oldPath); _entityMap.remove(oldPath);
_entityMap[note.filePath] = note; _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) { void reset(String folderPath) {
@ -183,7 +191,8 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
if (subFolder.name.startsWith('.')) { if (subFolder.name.startsWith('.')) {
continue; continue;
} }
subFolder.addListener(_entityChanged); //Log.d("Found folder ${fsEntity.path}");
_addFolderListeners(subFolder);
_folders.add(subFolder); _folders.add(subFolder);
_entityMap[fsEntity.path] = subFolder; _entityMap[fsEntity.path] = subFolder;
@ -199,8 +208,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
continue; continue;
} }
//Log.d("Found file ${fsEntity.path}"); //Log.d("Found file ${fsEntity.path}");
note.addModifiedListener(_noteModified); _addNoteListeners(note);
note.addRenameListener(_noteRenamed);
_notes.add(note); _notes.add(note);
_entityMap[fsEntity.path] = note; _entityMap[fsEntity.path] = note;
@ -219,7 +227,8 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
if (e is Note) { if (e is Note) {
Log.d("File $path was no longer found"); Log.d("File $path was no longer found");
e.removeModifiedListener(_noteModified); _removeNoteListeners(e);
var i = _notes.indexWhere((n) => n.filePath == path); var i = _notes.indexWhere((n) => n.filePath == path);
assert(i != -1); assert(i != -1);
var note = _notes[i]; var note = _notes[i];
@ -227,7 +236,8 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
notifyNoteRemoved(i, note); notifyNoteRemoved(i, note);
} else { } else {
Log.d("Folder $path was no longer found"); Log.d("Folder $path was no longer found");
e.removeListener(_entityChanged); _removeFolderListeners(e);
var i = _folders.indexWhere((f) => f.folderPath == path); var i = _folders.indexWhere((f) => f.folderPath == path);
assert(i != -1); assert(i != -1);
var folder = _folders[i]; var folder = _folders[i];
@ -239,7 +249,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
void add(Note note) { void add(Note note) {
assert(note.parent == this); assert(note.parent == this);
note.addModifiedListener(_noteModified); _addNoteListeners(note);
_notes.add(note); _notes.add(note);
_entityMap[note.filePath] = note; _entityMap[note.filePath] = note;
@ -249,8 +259,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
void remove(Note note) { void remove(Note note) {
assert(note.parent == this); assert(note.parent == this);
note.removeModifiedListener(_noteModified); _removeNoteListeners(note);
note.removeRenameListener(_noteRenamed);
assert(_notes.indexWhere((n) => n.filePath == note.filePath) != -1); assert(_notes.indexWhere((n) => n.filePath == note.filePath) != -1);
assert(_entityMap.containsKey(note.filePath)); assert(_entityMap.containsKey(note.filePath));
@ -263,6 +272,16 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
notifyNoteRemoved(index, note); 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() { void create() {
// Git doesn't track Directories, only files, so we create an empty .gitignore file // Git doesn't track Directories, only files, so we create an empty .gitignore file
// in the directory instead. // in the directory instead.
@ -276,7 +295,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
void addFolder(NotesFolderFS folder) { void addFolder(NotesFolderFS folder) {
assert(folder.parent == this); assert(folder.parent == this);
folder.addListener(_entityChanged); _addFolderListeners(folder);
_folders.add(folder); _folders.add(folder);
_entityMap[folder.folderPath] = folder; _entityMap[folder.folderPath] = folder;
@ -285,7 +304,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
} }
void removeFolder(NotesFolderFS folder) { void removeFolder(NotesFolderFS folder) {
folder.removeListener(_entityChanged); _removeFolderListeners(folder);
assert(_folders.indexWhere((f) => f.folderPath == folder.folderPath) != -1); assert(_folders.indexWhere((f) => f.folderPath == folder.folderPath) != -1);
assert(_entityMap.containsKey(folder.folderPath)); assert(_entityMap.containsKey(folder.folderPath));
@ -299,12 +318,22 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
} }
void rename(String newName) { void rename(String newName) {
var dir = Directory(folderPath); var oldPath = _folderPath;
var parentDirName = dirname(folderPath); var dir = Directory(_folderPath);
dir.renameSync(folderPath); _folderPath = p.join(dirname(_folderPath), newName);
_folderPath = p.join(parentDirName, 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 @override

View File

@ -1,11 +1,14 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:gitjournal/core/notes_folder_fs.dart';
import 'note.dart'; import 'note.dart';
import 'notes_folder.dart'; import 'notes_folder.dart';
typedef FolderNotificationCallback = void Function( typedef FolderNotificationCallback = void Function(
int index, NotesFolder folder); int index, NotesFolder folder);
typedef FolderRenamedCallback = void Function(
NotesFolderFS folder, String oldPath);
typedef NoteNotificationCallback = void Function(int index, Note note); typedef NoteNotificationCallback = void Function(int index, Note note);
typedef NoteRenamedCallback = void Function( typedef NoteRenamedCallback = void Function(
int index, Note note, String oldPath); int index, Note note, String oldPath);
@ -13,6 +16,7 @@ typedef NoteRenamedCallback = void Function(
class NotesFolderNotifier implements ChangeNotifier { class NotesFolderNotifier implements ChangeNotifier {
var _folderAddedListeners = ObserverList<FolderNotificationCallback>(); var _folderAddedListeners = ObserverList<FolderNotificationCallback>();
var _folderRemovedListeners = ObserverList<FolderNotificationCallback>(); var _folderRemovedListeners = ObserverList<FolderNotificationCallback>();
var _thisFolderRenamedListeners = ObserverList<FolderRenamedCallback>();
var _noteAddedListeners = ObserverList<NoteNotificationCallback>(); var _noteAddedListeners = ObserverList<NoteNotificationCallback>();
var _noteRemovedListeners = ObserverList<NoteNotificationCallback>(); var _noteRemovedListeners = ObserverList<NoteNotificationCallback>();
@ -24,6 +28,7 @@ class NotesFolderNotifier implements ChangeNotifier {
} }
void removeFolderRemovedListener(FolderNotificationCallback listener) { void removeFolderRemovedListener(FolderNotificationCallback listener) {
assert(_folderRemovedListeners.contains(listener));
_folderRemovedListeners.remove(listener); _folderRemovedListeners.remove(listener);
} }
@ -32,14 +37,25 @@ class NotesFolderNotifier implements ChangeNotifier {
} }
void removeFolderAddedListener(FolderNotificationCallback listener) { void removeFolderAddedListener(FolderNotificationCallback listener) {
assert(_folderAddedListeners.contains(listener));
_folderAddedListeners.remove(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) { void addNoteAddedListener(NoteNotificationCallback listener) {
_noteAddedListeners.add(listener); _noteAddedListeners.add(listener);
} }
void removeNoteAddedListener(NoteNotificationCallback listener) { void removeNoteAddedListener(NoteNotificationCallback listener) {
assert(_noteAddedListeners.contains(listener));
_noteAddedListeners.remove(listener); _noteAddedListeners.remove(listener);
} }
@ -48,6 +64,7 @@ class NotesFolderNotifier implements ChangeNotifier {
} }
void removeNoteRemovedListener(NoteNotificationCallback listener) { void removeNoteRemovedListener(NoteNotificationCallback listener) {
assert(_noteRemovedListeners.contains(listener));
_noteRemovedListeners.remove(listener); _noteRemovedListeners.remove(listener);
} }
@ -56,6 +73,7 @@ class NotesFolderNotifier implements ChangeNotifier {
} }
void removeNoteModifiedListener(NoteNotificationCallback listener) { void removeNoteModifiedListener(NoteNotificationCallback listener) {
assert(_noteModifiedListeners.contains(listener));
_noteModifiedListeners.remove(listener); _noteModifiedListeners.remove(listener);
} }
@ -64,6 +82,7 @@ class NotesFolderNotifier implements ChangeNotifier {
} }
void removeNoteRenameListener(NoteRenamedCallback listener) { void removeNoteRenameListener(NoteRenamedCallback listener) {
assert(_noteRenameListeners.contains(listener));
_noteRenameListeners.remove(listener); _noteRenameListeners.remove(listener);
} }
@ -72,6 +91,7 @@ class NotesFolderNotifier implements ChangeNotifier {
void dispose() { void dispose() {
_folderAddedListeners = null; _folderAddedListeners = null;
_folderRemovedListeners = null; _folderRemovedListeners = null;
_thisFolderRenamedListeners = null;
_noteAddedListeners = null; _noteAddedListeners = null;
_noteRemovedListeners = null; _noteRemovedListeners = null;
_noteModifiedListeners = null; _noteModifiedListeners = null;
@ -123,6 +143,34 @@ class NotesFolderNotifier implements ChangeNotifier {
_notifyFolderCallback(_folderRemovedListeners, index, folder); _notifyFolderCallback(_folderRemovedListeners, index, folder);
} }
void notifyThisFolderRenamed(NotesFolderFS folder, String oldPath) {
final localListeners =
List<FolderRenamedCallback>.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<ChangeNotifier>(
'The $runtimeType sending notification was',
this,
style: DiagnosticsTreeStyle.errorProperty,
);
},
));
}
}
notifyListeners();
}
void _notifyNoteCallback( void _notifyNoteCallback(
ObserverList<NoteNotificationCallback> _listeners, ObserverList<NoteNotificationCallback> _listeners,
int index, int index,
@ -170,13 +218,10 @@ class NotesFolderNotifier implements ChangeNotifier {
} }
void notifyNoteRenamed(int index, Note note, String oldPath) { void notifyNoteRenamed(int index, Note note, String oldPath) {
if (_listeners == null) {
return;
}
final localListeners = List<NoteRenamedCallback>.from(_noteRenameListeners); final localListeners = List<NoteRenamedCallback>.from(_noteRenameListeners);
for (var listener in localListeners) { for (var listener in localListeners) {
try { try {
if (_listeners.contains(listener)) { if (_noteRenameListeners.contains(listener)) {
listener(index, note, oldPath); listener(index, note, oldPath);
} }
} catch (exception, stack) { } catch (exception, stack) {

View File

@ -162,6 +162,7 @@ class StateContainer with ChangeNotifier {
void renameFolder(NotesFolderFS folder, String newFolderName) async { void renameFolder(NotesFolderFS folder, String newFolderName) async {
return _opLock.synchronized(() async { return _opLock.synchronized(() async {
var oldFolderPath = folder.folderPath; var oldFolderPath = folder.folderPath;
print("Renaming Folder from $oldFolderPath -> $newFolderName");
folder.rename(newFolderName); folder.rename(newFolderName);
_gitRepo _gitRepo