Add a lock between all git operations

This way in between a git add + git commit, no other git operation will
run. This rarely occurs but it was a posibility depending on the speed
of the users actions.
This commit is contained in:
Vishesh Handa
2020-03-21 00:44:14 +01:00
parent 86ae88bae0
commit eb7d7dc2e7

View File

@ -14,10 +14,13 @@ import 'package:gitjournal/settings.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_crashlytics/flutter_crashlytics.dart'; import 'package:flutter_crashlytics/flutter_crashlytics.dart';
import 'package:synchronized/synchronized.dart';
class StateContainer with ChangeNotifier { class StateContainer with ChangeNotifier {
final AppState appState; final AppState appState;
final _opLock = Lock();
// FIXME: The gitRepo should never be changed once it has been setup // FIXME: The gitRepo should never be changed once it has been setup
// We should always just be modifying the 'git remotes' // We should always just be modifying the 'git remotes'
// With that, the StateContainer can be a StatelessWidget // With that, the StateContainer can be a StatelessWidget
@ -118,93 +121,111 @@ class StateContainer with ChangeNotifier {
} }
void createFolder(NotesFolderFS parent, String folderName) async { void createFolder(NotesFolderFS parent, String folderName) async {
var newFolderPath = p.join(parent.folderPath, folderName); return _opLock.synchronized(() async {
var newFolder = NotesFolderFS(parent, newFolderPath); var newFolderPath = p.join(parent.folderPath, folderName);
newFolder.create(); var newFolder = NotesFolderFS(parent, newFolderPath);
newFolder.create();
Fimber.d("Created New Folder: " + newFolderPath); Fimber.d("Created New Folder: " + newFolderPath);
parent.addFolder(newFolder); parent.addFolder(newFolder);
_gitRepo.addFolder(newFolder).then((NoteRepoResult _) { _gitRepo.addFolder(newFolder).then((NoteRepoResult _) {
_syncNotes(); _syncNotes();
});
}); });
} }
void removeFolder(NotesFolderFS folder) { void removeFolder(NotesFolderFS folder) async {
Fimber.d("Removing Folder: " + folder.folderPath); return _opLock.synchronized(() async {
Fimber.d("Removing Folder: " + folder.folderPath);
folder.parentFS.removeFolder(folder); folder.parentFS.removeFolder(folder);
_gitRepo.removeFolder(folder.folderPath).then((NoteRepoResult _) { _gitRepo.removeFolder(folder.folderPath).then((NoteRepoResult _) {
_syncNotes(); _syncNotes();
});
}); });
} }
void renameFolder(NotesFolderFS folder, String newFolderName) { void renameFolder(NotesFolderFS folder, String newFolderName) async {
var oldFolderPath = folder.folderPath; return _opLock.synchronized(() async {
folder.rename(newFolderName); var oldFolderPath = folder.folderPath;
folder.rename(newFolderName);
_gitRepo _gitRepo
.renameFolder(oldFolderPath, folder.folderPath) .renameFolder(oldFolderPath, folder.folderPath)
.then((NoteRepoResult _) { .then((NoteRepoResult _) {
_syncNotes(); _syncNotes();
});
}); });
} }
void renameNote(Note note, String newFileName) { void renameNote(Note note, String newFileName) async {
var oldNotePath = note.filePath; return _opLock.synchronized(() async {
note.rename(newFileName); var oldNotePath = note.filePath;
note.rename(newFileName);
_gitRepo.renameNote(oldNotePath, note.filePath).then((NoteRepoResult _) { _gitRepo.renameNote(oldNotePath, note.filePath).then((NoteRepoResult _) {
_syncNotes(); _syncNotes();
});
}); });
} }
void moveNote(Note note, NotesFolderFS destFolder) { void moveNote(Note note, NotesFolderFS destFolder) async {
if (destFolder.folderPath == note.parent.folderPath) { if (destFolder.folderPath == note.parent.folderPath) {
return; return;
} }
var oldNotePath = note.filePath; return _opLock.synchronized(() async {
note.move(destFolder); var oldNotePath = note.filePath;
note.move(destFolder);
_gitRepo.moveNote(oldNotePath, note.filePath).then((NoteRepoResult _) { _gitRepo.moveNote(oldNotePath, note.filePath).then((NoteRepoResult _) {
_syncNotes(); _syncNotes();
});
}); });
} }
void addNote(Note note) { void addNote(Note note) async {
Fimber.d("State Container addNote"); return _opLock.synchronized(() async {
note.parent.insert(0, note); Fimber.d("State Container addNote");
note.updateModified(); note.parent.insert(0, note);
_gitRepo.addNote(note).then((NoteRepoResult _) { note.updateModified();
_syncNotes(); _gitRepo.addNote(note).then((NoteRepoResult _) {
_syncNotes();
});
}); });
} }
void removeNote(Note note) { void removeNote(Note note) async {
// FIXME: What if the Note hasn't yet been saved? return _opLock.synchronized(() async {
note.parent.remove(note); // FIXME: What if the Note hasn't yet been saved?
_gitRepo.removeNote(note.filePath).then((NoteRepoResult _) async { note.parent.remove(note);
// FIXME: Is there a way of figuring this amount dynamically? _gitRepo.removeNote(note.filePath).then((NoteRepoResult _) async {
// The '4 seconds' is taken from snack_bar.dart -> _kSnackBarDisplayDuration // FIXME: Is there a way of figuring this amount dynamically?
// We wait an aritfical amount of time, so that the user has a change to undo // The '4 seconds' is taken from snack_bar.dart -> _kSnackBarDisplayDuration
// their delete operation, and that commit is not synced with the server, till then. // We wait an aritfical amount of time, so that the user has a change to undo
await Future.delayed(const Duration(seconds: 4)); // their delete operation, and that commit is not synced with the server, till then.
_syncNotes(); await Future.delayed(const Duration(seconds: 4));
_syncNotes();
});
}); });
} }
void undoRemoveNote(Note note) { void undoRemoveNote(Note note) async {
note.parent.insert(0, note); return _opLock.synchronized(() async {
_gitRepo.resetLastCommit().then((NoteRepoResult _) { note.parent.insert(0, note);
_syncNotes(); _gitRepo.resetLastCommit().then((NoteRepoResult _) {
_syncNotes();
});
}); });
} }
void updateNote(Note note) { void updateNote(Note note) async {
Fimber.d("State Container updateNote"); return _opLock.synchronized(() async {
note.updateModified(); Fimber.d("State Container updateNote");
_gitRepo.updateNote(note).then((NoteRepoResult _) { note.updateModified();
_syncNotes(); _gitRepo.updateNote(note).then((NoteRepoResult _) {
_syncNotes();
});
}); });
} }