Add support for moving a Note to another folder

The Folder selection dialog needs a lot of work, but it's a start.
This commit is contained in:
Vishesh Handa
2020-01-29 16:51:57 +01:00
parent d48461a4cc
commit 43281bd2bb
8 changed files with 128 additions and 12 deletions

View File

@ -81,6 +81,19 @@ class GitNoteRepository {
return NoteRepoResult(noteFilePath: newFullPath, error: false);
}
Future<NoteRepoResult> moveNote(
String oldFullPath,
String newFullPath,
) async {
// FIXME: This is a hacky way of adding the changes, ideally we should be calling rm + add or something
await _gitRepo.add(".");
await _gitRepo.commit(
message: "Note Moved",
);
return NoteRepoResult(noteFilePath: newFullPath, error: false);
}
Future<NoteRepoResult> removeNote(String noteFilePath) async {
var pathSpec = noteFilePath.replaceFirst(gitDirPath, "").substring(1);

View File

@ -172,6 +172,22 @@ class Note with ChangeNotifier implements Comparable<Note> {
notifyListeners();
}
bool move(NotesFolder destFolder) {
var destPath = p.join(destFolder.folderPath, fileName);
if (File(destPath).existsSync()) {
return false;
}
File(filePath).renameSync(destPath);
parent.remove(this);
parent = destFolder;
destFolder.add(this);
notifyListeners();
return true;
}
@override
int get hashCode => _filePath.hashCode;

View File

@ -4,7 +4,7 @@ import 'package:gitjournal/core/note.dart';
import 'package:gitjournal/widgets/note_viewer.dart';
typedef NoteCallback = void Function(Note);
enum DropDownChoices { Rename }
enum DropDownChoices { Rename, MoveToFolder }
class MarkdownEditor extends StatefulWidget {
final Note note;
@ -12,6 +12,7 @@ class MarkdownEditor extends StatefulWidget {
final NoteCallback noteEditorChooserSelected;
final NoteCallback exitEditorSelected;
final NoteCallback renameNoteSelected;
final NoteCallback moveNoteToFolderSelected;
final bool autofocusOnEditor;
MarkdownEditor({
@ -21,6 +22,7 @@ class MarkdownEditor extends StatefulWidget {
@required this.noteEditorChooserSelected,
@required this.exitEditorSelected,
@required this.renameNoteSelected,
@required this.moveNoteToFolderSelected,
this.autofocusOnEditor = false,
}) : super(key: key);
@ -108,8 +110,17 @@ class MarkdownEditorState extends State<MarkdownEditor> {
),
PopupMenuButton<DropDownChoices>(
onSelected: (DropDownChoices choice) {
_updateNote();
widget.renameNoteSelected(note);
switch (choice) {
case DropDownChoices.Rename:
_updateNote();
widget.renameNoteSelected(note);
return;
case DropDownChoices.MoveToFolder:
_updateNote();
widget.moveNoteToFolderSelected(note);
return;
}
},
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<DropDownChoices>>[
@ -117,6 +128,10 @@ class MarkdownEditorState extends State<MarkdownEditor> {
value: DropDownChoices.Rename,
child: Text('Edit File Name'),
),
const PopupMenuItem<DropDownChoices>(
value: DropDownChoices.MoveToFolder,
child: Text('Move to Folder'),
),
],
),
],

View File

@ -4,7 +4,7 @@ import 'package:gitjournal/core/note.dart';
import 'package:gitjournal/core/note_data_serializers.dart';
typedef NoteCallback = void Function(Note);
enum DropDownChoices { Rename }
enum DropDownChoices { Rename, MoveToFolder }
class RawEditor extends StatefulWidget {
final Note note;
@ -12,6 +12,7 @@ class RawEditor extends StatefulWidget {
final NoteCallback noteEditorChooserSelected;
final NoteCallback exitEditorSelected;
final NoteCallback renameNoteSelected;
final NoteCallback moveNoteToFolderSelected;
RawEditor({
Key key,
@ -20,6 +21,7 @@ class RawEditor extends StatefulWidget {
@required this.noteEditorChooserSelected,
@required this.exitEditorSelected,
@required this.renameNoteSelected,
@required this.moveNoteToFolderSelected,
}) : super(key: key);
@override
@ -88,8 +90,17 @@ class RawEditorState extends State<RawEditor> {
),
PopupMenuButton<DropDownChoices>(
onSelected: (DropDownChoices choice) {
_updateNote();
widget.renameNoteSelected(note);
switch (choice) {
case DropDownChoices.Rename:
_updateNote();
widget.renameNoteSelected(note);
return;
case DropDownChoices.MoveToFolder:
_updateNote();
widget.moveNoteToFolderSelected(note);
return;
}
},
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<DropDownChoices>>[
@ -97,6 +108,10 @@ class RawEditorState extends State<RawEditor> {
value: DropDownChoices.Rename,
child: Text('Edit File Name'),
),
const PopupMenuItem<DropDownChoices>(
value: DropDownChoices.MoveToFolder,
child: Text('Move to Folder'),
),
],
),
],

View File

@ -8,10 +8,9 @@ import 'package:gitjournal/editors/raw_editor.dart';
import 'package:gitjournal/state_container.dart';
import 'package:gitjournal/core/note_data_serializers.dart';
import 'package:gitjournal/utils.dart';
import 'package:gitjournal/widgets/folder_selection_dialog.dart';
import 'package:gitjournal/widgets/rename_dialog.dart';
enum NoteEditorDropDownChoices { Discard, SwitchEditor }
class NoteEditor extends StatefulWidget {
final Note note;
final NotesFolder notesFolder;
@ -73,6 +72,7 @@ class NoteEditorState extends State<NoteEditor> {
noteEditorChooserSelected: _noteEditorChooserSelected,
exitEditorSelected: _exitEditorSelected,
renameNoteSelected: _renameNoteSelected,
moveNoteToFolderSelected: _moveNoteToFolderSelected,
autofocusOnEditor: _isNewNote,
);
case EditorType.Raw:
@ -83,6 +83,7 @@ class NoteEditorState extends State<NoteEditor> {
noteEditorChooserSelected: _noteEditorChooserSelected,
exitEditorSelected: _exitEditorSelected,
renameNoteSelected: _renameNoteSelected,
moveNoteToFolderSelected: _moveNoteToFolderSelected,
);
}
return null;
@ -227,4 +228,15 @@ class NoteEditorState extends State<NoteEditor> {
}
return null;
}
void _moveNoteToFolderSelected(Note note) async {
var destFolder = await showDialog<NotesFolder>(
context: context,
builder: (context) => FolderSelectionDialog(),
);
if (destFolder != null) {
final stateContainer = StateContainer.of(context);
stateContainer.moveNote(note, destFolder);
}
}
}

View File

@ -139,7 +139,7 @@ class StateContainerState extends State<StateContainer> {
});
}
void renameFolder(NotesFolder folder, String newFolderName) async {
void renameFolder(NotesFolder folder, String newFolderName) {
var oldFolderPath = folder.folderPath;
folder.rename(newFolderName);
@ -150,7 +150,7 @@ class StateContainerState extends State<StateContainer> {
});
}
void renameNote(Note note, String newFileName) async {
void renameNote(Note note, String newFileName) {
var oldNotePath = note.filePath;
note.rename(newFileName);
@ -159,6 +159,15 @@ class StateContainerState extends State<StateContainer> {
});
}
void moveNote(Note note, NotesFolder destFolder) {
var oldNotePath = note.filePath;
note.move(destFolder);
_gitRepo.moveNote(oldNotePath, note.filePath).then((NoteRepoResult _) {
syncNotes();
});
}
void addNote(Note note) {
insertNote(0, note);
}

View File

@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
import 'package:gitjournal/core/notes_folder.dart';
import 'package:gitjournal/widgets/folder_tree_view.dart';
import 'package:provider/provider.dart';
typedef NoteFolderCallback = void Function(NotesFolder);
class FolderSelectionDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
final notesFolder = Provider.of<NotesFolder>(context);
var body = Container(
width: double.maxFinite,
child: FolderTreeView(
rootFolder: notesFolder,
onFolderEntered: (NotesFolder destFolder) {
Navigator.of(context).pop(destFolder);
},
longPressAllowed: false,
),
);
return AlertDialog(
title: const Text('Select a Folder'),
content: body,
);
}
}
// FIXME: Add the previously as a radio button selected Folder

View File

@ -10,17 +10,21 @@ class FolderTreeView extends StatefulWidget {
final FolderSelectedCallback onFolderSelected;
final Function onFolderUnselected;
final FolderSelectedCallback onFolderEntered;
final bool longPressAllowed;
FolderTreeView({
Key key,
@required this.rootFolder,
@required this.onFolderSelected,
@required this.onFolderUnselected,
@required this.onFolderEntered,
this.onFolderSelected = _doNothing,
this.onFolderUnselected = _doNothing,
this.longPressAllowed = true,
}) : super(key: key);
@override
FolderTreeViewState createState() => FolderTreeViewState();
static void _doNothing(NotesFolder f) {}
}
class FolderTreeViewState extends State<FolderTreeView> {
@ -43,6 +47,7 @@ class FolderTreeViewState extends State<FolderTreeView> {
}
},
onLongPress: (folder) {
if (!widget.longPressAllowed) return;
setState(() {
inSelectionMode = true;
selectedFolder = folder;