Add the first draft of a TodoEditor

It's a small proof of concept and still needs a lot of work.
This commit is contained in:
Vishesh Handa
2020-01-30 18:41:27 +01:00
parent ddb7303fea
commit 7c2cde03b7
2 changed files with 211 additions and 1 deletions

View File

@ -0,0 +1,187 @@
import 'package:flutter/material.dart';
import 'package:gitjournal/core/note.dart';
import 'package:gitjournal/editors/common.dart';
class TodoEditor extends StatefulWidget implements Editor {
final Note note;
@override
final NoteCallback noteDeletionSelected;
@override
final NoteCallback noteEditorChooserSelected;
@override
final NoteCallback exitEditorSelected;
@override
final NoteCallback renameNoteSelected;
@override
final NoteCallback moveNoteToFolderSelected;
TodoEditor({
Key key,
@required this.note,
@required this.noteDeletionSelected,
@required this.noteEditorChooserSelected,
@required this.exitEditorSelected,
@required this.renameNoteSelected,
@required this.moveNoteToFolderSelected,
}) : super(key: key);
@override
TodoEditorState createState() {
return TodoEditorState(note);
}
}
class TodoEditorState extends State<TodoEditor> implements EditorState {
Note note;
List<TodoItem> todos;
TextEditingController _titleTextController = TextEditingController();
TodoEditorState(this.note) {
_titleTextController = TextEditingController(text: note.title);
todos = [
TodoItem(false, "First Item"),
TodoItem(true, "Second Item"),
TodoItem(false, "Third Item"),
];
}
@override
void dispose() {
_titleTextController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
var todoItemTiles = <TodoItemTile>[];
todos.forEach((TodoItem todo) {
todoItemTiles.add(_buildTile(todo));
});
print("Building " + todos.toString());
var todoList = ListView(
children: todoItemTiles,
);
// FIXME: The body needs to be scrollable
var titleEditor = Padding(
padding: const EdgeInsets.all(16.0),
child: _NoteTitleEditor(_titleTextController),
);
return Scaffold(
appBar: buildEditorAppBar(widget, this),
floatingActionButton: buildFAB(widget, this),
body: Column(
children: <Widget>[titleEditor, Expanded(child: todoList)],
),
);
}
@override
Note getNote() {
note.title = _titleTextController.text.trim();
return note;
}
TodoItemTile _buildTile(TodoItem todo) {
return TodoItemTile(
todo: todo,
statusChanged: (val) {
setState(() {
todo.checked = val;
});
},
);
}
}
class _NoteTitleEditor extends StatelessWidget {
final TextEditingController textController;
_NoteTitleEditor(this.textController);
@override
Widget build(BuildContext context) {
var style = Theme.of(context).textTheme.title;
return TextField(
keyboardType: TextInputType.text,
maxLines: 1,
style: style,
decoration: const InputDecoration(
hintText: 'Title',
border: InputBorder.none,
isDense: true,
),
controller: textController,
textCapitalization: TextCapitalization.sentences,
);
}
}
class TodoItem {
bool checked;
String body;
TodoItem(this.checked, this.body);
@override
String toString() {
return 'TodoItem($checked, "$body")';
}
}
class TodoItemTile extends StatefulWidget {
final TodoItem todo;
final Function statusChanged;
TodoItemTile({@required this.todo, @required this.statusChanged});
@override
_TodoItemTileState createState() => _TodoItemTileState();
}
class _TodoItemTileState extends State<TodoItemTile> {
TextEditingController _textController;
@override
void initState() {
super.initState();
_textController = TextEditingController(text: widget.todo.body);
}
@override
Widget build(BuildContext context) {
var style = Theme.of(context).textTheme.subhead;
var editor = TextField(
keyboardType: TextInputType.text,
maxLines: 1,
style: style,
textCapitalization: TextCapitalization.sentences,
controller: _textController,
decoration: const InputDecoration(
border: InputBorder.none,
isDense: true,
),
);
return ListTile(
leading: Checkbox(
value: widget.todo.checked,
onChanged: widget.statusChanged,
),
title: editor,
trailing: IconButton(
icon: Icon(Icons.cancel),
onPressed: () {},
),
dense: true,
);
}
}

View File

@ -5,12 +5,15 @@ import 'package:gitjournal/core/note.dart';
import 'package:gitjournal/core/notes_folder.dart';
import 'package:gitjournal/editors/markdown_editor.dart';
import 'package:gitjournal/editors/raw_editor.dart';
import 'package:gitjournal/editors/todo_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';
final todoEditorEnabled = false;
class NoteEditor extends StatefulWidget {
final Note note;
final NotesFolder notesFolder;
@ -28,7 +31,7 @@ class NoteEditor extends StatefulWidget {
}
}
enum EditorType { Markdown, Raw }
enum EditorType { Markdown, Raw, Todo }
class NoteEditorState extends State<NoteEditor> {
Note note;
@ -37,6 +40,7 @@ class NoteEditorState extends State<NoteEditor> {
final _rawEditorKey = GlobalKey<RawEditorState>();
final _markdownEditorKey = GlobalKey<MarkdownEditorState>();
final _todoEditorKey = GlobalKey<TodoEditorState>();
bool get _isNewNote {
return widget.note == null;
@ -85,6 +89,16 @@ class NoteEditorState extends State<NoteEditor> {
renameNoteSelected: _renameNoteSelected,
moveNoteToFolderSelected: _moveNoteToFolderSelected,
);
case EditorType.Todo:
return TodoEditor(
key: _todoEditorKey,
note: note,
noteDeletionSelected: _noteDeletionSelected,
noteEditorChooserSelected: _noteEditorChooserSelected,
exitEditorSelected: _exitEditorSelected,
renameNoteSelected: _renameNoteSelected,
moveNoteToFolderSelected: _moveNoteToFolderSelected,
);
}
return null;
}
@ -106,6 +120,13 @@ class NoteEditorState extends State<NoteEditor> {
groupValue: editorType,
onChanged: (EditorType et) => Navigator.of(context).pop(et),
),
if (todoEditorEnabled)
RadioListTile<EditorType>(
title: const Text("Todo Editor"),
value: EditorType.Todo,
groupValue: editorType,
onChanged: (EditorType et) => Navigator.of(context).pop(et),
),
];
return AlertDialog(
@ -225,6 +246,8 @@ class NoteEditorState extends State<NoteEditor> {
return _markdownEditorKey.currentState.getNote();
case EditorType.Raw:
return _rawEditorKey.currentState.getNote();
case EditorType.Todo:
return _todoEditorKey.currentState.getNote();
}
return null;
}