Fix handling of Note renames

We often use the note's filePath as a unique identifier, however that
can change, and we need to update the caches accordingly.

Fixes #97
This commit is contained in:
Vishesh Handa
2020-04-10 13:45:19 +02:00
parent d16b4e9eb9
commit 14d734bf08
4 changed files with 93 additions and 1 deletions

View File

@ -213,6 +213,7 @@ class Note with NotesNotifier {
newName += '.md';
}
var oldFilePath = filePath;
var parentDirName = p.dirname(filePath);
var newFilePath = p.join(parentDirName, newName);
if (_loadState != NoteLoadState.None) {
@ -221,6 +222,7 @@ class Note with NotesNotifier {
}
_filePath = newFilePath;
notifyRenameListeners(this, oldFilePath);
_notifyModified();
}

View File

@ -4,9 +4,11 @@ import 'package:flutter/foundation.dart';
import 'note.dart';
typedef NoteModificationCallback = void Function(Note note);
typedef NoteRenameCallback = void Function(Note note, String oldPath);
class NotesNotifier implements ChangeNotifier {
var _modListeners = ObserverList<NoteModificationCallback>();
var _renameListeners = ObserverList<NoteRenameCallback>();
void addModifiedListener(NoteModificationCallback listener) {
_modListeners.add(listener);
@ -16,11 +18,20 @@ class NotesNotifier implements ChangeNotifier {
_modListeners.remove(listener);
}
void addRenameListener(NoteRenameCallback listener) {
_renameListeners.add(listener);
}
void removeRenameListener(NoteRenameCallback listener) {
_renameListeners.remove(listener);
}
@mustCallSuper
@override
void dispose() {
assert(_debugAssertNotDisposed());
_modListeners = null;
_renameListeners = null;
_listeners = null;
}
@ -151,7 +162,7 @@ class NotesNotifier implements ChangeNotifier {
assert(_debugAssertNotDisposed());
if (_modListeners != null) {
final localListeners = List<NoteModificationCallback>.from(_modListeners);
for (NoteModificationCallback listener in localListeners) {
for (var listener in localListeners) {
try {
if (_modListeners.contains(listener)) {
listener(note);
@ -175,4 +186,33 @@ class NotesNotifier implements ChangeNotifier {
}
}
}
void notifyRenameListeners(Note note, String oldPath) {
assert(_debugAssertNotDisposed());
if (_renameListeners != null) {
final localListeners = List<NoteRenameCallback>.from(_renameListeners);
for (var listener in localListeners) {
try {
if (_renameListeners.contains(listener)) {
listener(note, oldPath);
}
} catch (exception, stack) {
FlutterError.reportError(FlutterErrorDetails(
exception: exception,
stack: stack,
library: 'foundation library',
context: ErrorDescription(
'while dispatching notifications for $runtimeType'),
informationCollector: () sync* {
yield DiagnosticsProperty<ChangeNotifier>(
'The $runtimeType sending notification was',
this,
style: DiagnosticsTreeStyle.errorProperty,
);
},
));
}
}
}
}
}

View File

@ -45,6 +45,12 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
notifyNoteModified(-1, note);
}
void _noteRenamed(Note note, String oldPath) {
assert(_entityMap.containsKey(oldPath));
_entityMap.remove(oldPath);
_entityMap[note.filePath] = note;
}
void reset(String folderPath) {
_folderPath = folderPath;
@ -194,6 +200,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
}
//Log.d("Found file ${fsEntity.path}");
note.addModifiedListener(_noteModified);
note.addRenameListener(_noteRenamed);
_notes.add(note);
_entityMap[fsEntity.path] = note;
@ -254,6 +261,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
void remove(Note note) {
assert(note.parent == this);
note.removeModifiedListener(_noteModified);
note.removeRenameListener(_noteRenamed);
assert(_notes.indexWhere((n) => n.filePath == note.filePath) != -1);
assert(_entityMap.containsKey(note.filePath));

View File

@ -7,6 +7,8 @@ import 'notes_folder.dart';
typedef FolderNotificationCallback = void Function(
int index, NotesFolder folder);
typedef NoteNotificationCallback = void Function(int index, Note note);
typedef NoteRenamedCallback = void Function(
int index, Note note, String oldPath);
class NotesFolderNotifier implements ChangeNotifier {
var _folderAddedListeners = ObserverList<FolderNotificationCallback>();
@ -15,6 +17,7 @@ class NotesFolderNotifier implements ChangeNotifier {
var _noteAddedListeners = ObserverList<NoteNotificationCallback>();
var _noteRemovedListeners = ObserverList<NoteNotificationCallback>();
var _noteModifiedListeners = ObserverList<NoteNotificationCallback>();
var _noteRenameListeners = ObserverList<NoteRenamedCallback>();
void addFolderRemovedListener(FolderNotificationCallback listener) {
_folderRemovedListeners.add(listener);
@ -56,6 +59,14 @@ class NotesFolderNotifier implements ChangeNotifier {
_noteModifiedListeners.remove(listener);
}
void addNoteRenameListener(NoteRenamedCallback listener) {
_noteRenameListeners.add(listener);
}
void removeNoteRenameListener(NoteRenamedCallback listener) {
_noteRenameListeners.remove(listener);
}
@mustCallSuper
@override
void dispose() {
@ -64,6 +75,7 @@ class NotesFolderNotifier implements ChangeNotifier {
_noteAddedListeners = null;
_noteRemovedListeners = null;
_noteModifiedListeners = null;
_noteRenameListeners = null;
assert(_debugAssertNotDisposed());
_listeners = null;
@ -157,6 +169,36 @@ class NotesFolderNotifier implements ChangeNotifier {
_notifyNoteCallback(_noteModifiedListeners, index, note);
}
void notifyNoteRenamed(int index, Note note, String oldPath) {
if (_listeners == null) {
return;
}
final localListeners = List<NoteRenamedCallback>.from(_noteRenameListeners);
for (var listener in localListeners) {
try {
if (_listeners.contains(listener)) {
listener(index, note, 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();
}
//
// ChangeNotifier implementation - How to not duplicate this?
//