mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-27 01:02:14 +08:00
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:
187
lib/editors/todo_editor.dart
Normal file
187
lib/editors/todo_editor.dart
Normal 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,
|
||||
);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user