diff --git a/lib/core/git_repo.dart b/lib/core/git_repo.dart index c7a2b941..f758d359 100644 --- a/lib/core/git_repo.dart +++ b/lib/core/git_repo.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'package:fimber/fimber.dart'; import 'package:flutter/foundation.dart'; @@ -86,6 +87,20 @@ class GitNoteRepository { return NoteRepoResult(noteFilePath: noteFilePath, error: false); } + Future removeFolder(String folderPath) async { + var gitDir = p.join(baseDirectory, dirName); + var pathSpec = folderPath.replaceFirst(gitDir, "").substring(1); + + await _gitRepo.rm(pathSpec); + await _gitRepo.commit( + message: "Removed Folder " + pathSpec, + ); + + await Directory(folderPath).delete(recursive: true); + + return NoteRepoResult(noteFilePath: folderPath, error: false); + } + Future resetLastCommit() async { await _gitRepo.resetLast(); return NoteRepoResult(error: false); diff --git a/lib/core/notes_folder.dart b/lib/core/notes_folder.dart index 2872ca1d..849a5894 100644 --- a/lib/core/notes_folder.dart +++ b/lib/core/notes_folder.dart @@ -48,6 +48,23 @@ class NotesFolder with ChangeNotifier { return _entities.firstWhere((e) => e.isNote, orElse: () => null) != null; } + bool get hasNotesRecursive { + bool has = hasNotes; + if (has) return true; + + for (var i = 0; i < _entities.length; i++) { + var e = _entities[i]; + if (e.isNote) continue; + + has = has || e.folder.hasNotes; + if (has) { + return true; + } + } + + return has; + } + int get numberOfNotes { int i = 0; _entities.forEach((e) { @@ -231,6 +248,21 @@ class NotesFolder with ChangeNotifier { notifyListeners(); } + void removeFolder(NotesFolder folder) { + folder.removeListener(_entityChanged); + + var i = _entities.indexWhere((e) { + if (e.isNote) return false; + return e.folder.folderPath == folder.folderPath; + }); + assert(i != -1); + + _entities.removeAt(i); + _entityMap.remove(folder.folderPath); + + notifyListeners(); + } + void rename(String newName) { var dir = Directory(folderPath); var parentDirName = dirname(folderPath); diff --git a/lib/screens/folder_listing.dart b/lib/screens/folder_listing.dart index 6f279677..9d2a8d16 100644 --- a/lib/screens/folder_listing.dart +++ b/lib/screens/folder_listing.dart @@ -57,7 +57,11 @@ class _FolderListingScreenState extends State { const PopupMenuItem( child: Text("Create Sub-Folder"), value: "Create", - ) + ), + const PopupMenuItem( + child: Text("Delete Folder"), + value: "Delete", + ), ]; }, onSelected: (String value) async { @@ -79,6 +83,16 @@ class _FolderListingScreenState extends State { final container = StateContainer.of(context); container.createFolder(selectedFolder, folderName); } + } else if (value == "Delete") { + if (selectedFolder.hasNotesRecursive) { + await showDialog( + context: context, + builder: (_) => FolderErrorDialog(), + ); + } else { + final container = StateContainer.of(context); + container.removeFolder(selectedFolder); + } } _folderTreeViewKey.currentState.resetSelection(); @@ -254,3 +268,19 @@ class _RenameFolderDialogState extends State { super.dispose(); } } + +class FolderErrorDialog extends StatelessWidget { + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text("Error"), + content: const Text("Cannot delete a Folder which contains notes"), + actions: [ + FlatButton( + child: const Text("Ok"), + onPressed: () => Navigator.of(context).pop(), + ), + ], + ); + } +} diff --git a/lib/state_container.dart b/lib/state_container.dart index 0bea952f..a3b113e3 100644 --- a/lib/state_container.dart +++ b/lib/state_container.dart @@ -111,6 +111,15 @@ class StateContainerState extends State { }); } + void removeFolder(NotesFolder folder) { + Fimber.d("Removing Folder: " + folder.folderPath); + + folder.parent.removeFolder(folder); + _gitRepo.removeFolder(folder.folderPath).then((NoteRepoResult _) { + syncNotes(); + }); + } + void renameFolder(NotesFolder folder, String newFolderName) async { var oldFolderPath = folder.folderPath; folder.rename(newFolderName);