diff --git a/lib/core/notes_folder.dart b/lib/core/notes_folder.dart index c756bfdf..b1ce7864 100644 --- a/lib/core/notes_folder.dart +++ b/lib/core/notes_folder.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:path/path.dart' as p; import 'package:path/path.dart'; import 'note.dart'; @@ -107,4 +108,19 @@ class NotesFolder { entities.removeAt(i); } + + void create() { + // Git doesn't track Directories, only files, so we create an empty .gitignore file + // in the directory instead. + var gitIgnoreFilePath = p.join(folderPath, ".gitignore"); + var file = File(gitIgnoreFilePath); + if (!file.existsSync()) { + file.createSync(recursive: true); + } + } + + void addFolder(NotesFolder folder) { + assert(folder.parent == this); + entities.add(NoteFSEntity(folder: folder)); + } } diff --git a/lib/screens/folder_listing.dart b/lib/screens/folder_listing.dart index c1b812a2..4e791048 100644 --- a/lib/screens/folder_listing.dart +++ b/lib/screens/folder_listing.dart @@ -33,6 +33,79 @@ class FolderListingScreen extends StatelessWidget { ), body: treeView, drawer: AppDrawer(), + floatingActionButton: CreateFolderButton(), + ); + } +} + +class CreateFolderButton extends StatefulWidget { + @override + _CreateFolderButtonState createState() => _CreateFolderButtonState(); +} + +class _CreateFolderButtonState extends State { + final TextEditingController _textController = TextEditingController(); + + @override + Widget build(BuildContext context) { + return FloatingActionButton( + key: const ValueKey("FAB"), + onPressed: () async { + var folderName = + await showDialog(context: context, builder: _buildAlert); + if (folderName is String) { + final container = StateContainer.of(context); + final appState = container.appState; + + container.createFolder(appState.notesFolder, folderName); + } + }, + child: Icon(Icons.add), + ); + } + + @override + void dispose() { + _textController.dispose(); + super.dispose(); + } + + Widget _buildAlert(BuildContext context) { + var form = Form( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextFormField( + decoration: const InputDecoration(labelText: 'Folder Name'), + validator: (value) { + if (value.isEmpty) return 'Please enter a name'; + return ""; + }, + autofocus: true, + keyboardType: TextInputType.text, + textCapitalization: TextCapitalization.words, + controller: _textController, + ), + ], + ), + ); + + return AlertDialog( + title: const Text("Create new Folder"), + actions: [ + FlatButton( + onPressed: () => Navigator.of(context).pop(false), + child: const Text("Discard"), + ), + FlatButton( + onPressed: () { + var newFolderName = _textController.text; + return Navigator.of(context).pop(newFolderName); + }, + child: const Text("Create"), + ), + ], + content: form, ); } } diff --git a/lib/state_container.dart b/lib/state_container.dart index ee25ff7a..50430c06 100644 --- a/lib/state_container.dart +++ b/lib/state_container.dart @@ -144,6 +144,22 @@ class StateContainerState extends State { }); } + void createFolder(NotesFolder parent, String folderName) async { + var newFolderPath = p.join(parent.folderPath, folderName); + var newFolder = NotesFolder(parent, newFolderPath); + newFolder.create(); + + Fimber.d("Created New Folder: " + newFolderPath); + parent.addFolder(newFolder); + + setState(() { + // Update the git repo + noteRepo.addFolder(newFolder).then((NoteRepoResult _) { + _syncNotes(); + }); + }); + } + void addNote(Note note) { insertNote(0, note); } diff --git a/lib/storage/git_storage.dart b/lib/storage/git_storage.dart index 900a5180..1f2bd0fc 100644 --- a/lib/storage/git_storage.dart +++ b/lib/storage/git_storage.dart @@ -4,6 +4,7 @@ import 'package:fimber/fimber.dart'; import 'package:flutter/foundation.dart'; import 'package:gitjournal/apis/git.dart'; import 'package:gitjournal/core/note.dart'; +import 'package:gitjournal/core/notes_folder.dart'; import 'package:gitjournal/settings.dart'; import 'package:path/path.dart' as p; @@ -50,6 +51,15 @@ class GitNoteRepository { return NoteRepoResult(noteFilePath: note.filePath, error: false); } + Future addFolder(NotesFolder folder) async { + await _gitRepo.add("."); + await _gitRepo.commit( + message: "Created new folder", + ); + + return NoteRepoResult(noteFilePath: folder.folderPath, error: false); + } + Future removeNote(String noteFilePath) async { var gitDir = p.join(baseDirectory, dirName); var pathSpec = noteFilePath.replaceFirst(gitDir, "").substring(1);