mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-29 02:07:39 +08:00
Add experimental Journal Editor
It removes the title and displays the journal header. This provides a much better experience for writing a journal.
This commit is contained in:
117
lib/editors/journal_editor.dart
Normal file
117
lib/editors/journal_editor.dart
Normal file
@ -0,0 +1,117 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:gitjournal/core/note.dart';
|
||||
import 'package:gitjournal/editors/common.dart';
|
||||
import 'package:gitjournal/widgets/journal_editor_header.dart';
|
||||
|
||||
class JournalEditor 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;
|
||||
@override
|
||||
final NoteCallback discardChangesSelected;
|
||||
|
||||
final bool autofocusOnEditor;
|
||||
|
||||
JournalEditor({
|
||||
Key key,
|
||||
@required this.note,
|
||||
@required this.noteDeletionSelected,
|
||||
@required this.noteEditorChooserSelected,
|
||||
@required this.exitEditorSelected,
|
||||
@required this.renameNoteSelected,
|
||||
@required this.moveNoteToFolderSelected,
|
||||
@required this.discardChangesSelected,
|
||||
this.autofocusOnEditor = false,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
JournalEditorState createState() {
|
||||
return JournalEditorState(note);
|
||||
}
|
||||
}
|
||||
|
||||
class JournalEditorState extends State<JournalEditor> implements EditorState {
|
||||
Note note;
|
||||
TextEditingController _textController = TextEditingController();
|
||||
|
||||
JournalEditorState(this.note) {
|
||||
_textController = TextEditingController(text: note.body);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_textController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var editor = Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
JournalEditorHeader(note),
|
||||
_NoteBodyEditor(
|
||||
_textController,
|
||||
autofocus: widget.autofocusOnEditor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: buildEditorAppBar(widget, this),
|
||||
body: editor,
|
||||
);
|
||||
}
|
||||
|
||||
void _updateNote() {
|
||||
note.body = _textController.text.trim();
|
||||
}
|
||||
|
||||
@override
|
||||
Note getNote() {
|
||||
_updateNote();
|
||||
return note;
|
||||
}
|
||||
}
|
||||
|
||||
class _NoteBodyEditor extends StatelessWidget {
|
||||
final TextEditingController textController;
|
||||
final bool autofocus;
|
||||
|
||||
_NoteBodyEditor(this.textController, {this.autofocus = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var style = Theme.of(context).textTheme.subhead;
|
||||
|
||||
return TextField(
|
||||
autofocus: autofocus,
|
||||
autocorrect: false,
|
||||
keyboardType: TextInputType.multiline,
|
||||
maxLines: null,
|
||||
style: style,
|
||||
decoration: const InputDecoration(
|
||||
hintText: 'Write here',
|
||||
border: InputBorder.none,
|
||||
isDense: true,
|
||||
),
|
||||
controller: textController,
|
||||
textCapitalization: TextCapitalization.sentences,
|
||||
scrollPadding: const EdgeInsets.all(0.0),
|
||||
);
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:gitjournal/core/note.dart';
|
||||
import 'package:gitjournal/core/md_yaml_doc.dart';
|
||||
import 'package:gitjournal/core/notes_folder.dart';
|
||||
import 'package:gitjournal/editors/journal_editor.dart';
|
||||
import 'package:gitjournal/editors/markdown_editor.dart';
|
||||
import 'package:gitjournal/editors/raw_editor.dart';
|
||||
import 'package:gitjournal/editors/checklist_editor.dart';
|
||||
@ -31,7 +32,7 @@ class NoteEditor extends StatefulWidget {
|
||||
}
|
||||
}
|
||||
|
||||
enum EditorType { Markdown, Raw, Checklist }
|
||||
enum EditorType { Markdown, Raw, Checklist, Journal }
|
||||
|
||||
class NoteEditorState extends State<NoteEditor> {
|
||||
Note note;
|
||||
@ -41,6 +42,7 @@ class NoteEditorState extends State<NoteEditor> {
|
||||
final _rawEditorKey = GlobalKey<RawEditorState>();
|
||||
final _markdownEditorKey = GlobalKey<MarkdownEditorState>();
|
||||
final _checklistEditorKey = GlobalKey<ChecklistEditorState>();
|
||||
final _journalEditorKey = GlobalKey<JournalEditorState>();
|
||||
|
||||
bool get _isNewNote {
|
||||
return widget.note == null;
|
||||
@ -117,11 +119,25 @@ class NoteEditorState extends State<NoteEditor> {
|
||||
discardChangesSelected: _discardChangesSelected,
|
||||
autofocusOnEditor: _isNewNote,
|
||||
);
|
||||
case EditorType.Journal:
|
||||
return JournalEditor(
|
||||
key: _journalEditorKey,
|
||||
note: note,
|
||||
noteDeletionSelected: _noteDeletionSelected,
|
||||
noteEditorChooserSelected: _noteEditorChooserSelected,
|
||||
exitEditorSelected: _exitEditorSelected,
|
||||
renameNoteSelected: _renameNoteSelected,
|
||||
moveNoteToFolderSelected: _moveNoteToFolderSelected,
|
||||
discardChangesSelected: _discardChangesSelected,
|
||||
autofocusOnEditor: _isNewNote,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void _noteEditorChooserSelected(Note _note) async {
|
||||
var onEditorChange = (EditorType et) => Navigator.of(context).pop(et);
|
||||
|
||||
var newEditorType = await showDialog<EditorType>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
@ -130,19 +146,25 @@ class NoteEditorState extends State<NoteEditor> {
|
||||
title: const Text("Markdown Editor"),
|
||||
value: EditorType.Markdown,
|
||||
groupValue: editorType,
|
||||
onChanged: (EditorType et) => Navigator.of(context).pop(et),
|
||||
onChanged: onEditorChange,
|
||||
),
|
||||
RadioListTile<EditorType>(
|
||||
title: const Text("Raw Editor"),
|
||||
value: EditorType.Raw,
|
||||
groupValue: editorType,
|
||||
onChanged: (EditorType et) => Navigator.of(context).pop(et),
|
||||
onChanged: onEditorChange,
|
||||
),
|
||||
RadioListTile<EditorType>(
|
||||
title: const Text("Checklist Editor"),
|
||||
value: EditorType.Checklist,
|
||||
groupValue: editorType,
|
||||
onChanged: (EditorType et) => Navigator.of(context).pop(et),
|
||||
onChanged: onEditorChange,
|
||||
),
|
||||
RadioListTile<EditorType>(
|
||||
title: const Text("Journal Editor"),
|
||||
value: EditorType.Journal,
|
||||
groupValue: editorType,
|
||||
onChanged: onEditorChange,
|
||||
),
|
||||
];
|
||||
|
||||
@ -264,6 +286,8 @@ class NoteEditorState extends State<NoteEditor> {
|
||||
return _rawEditorKey.currentState.getNote();
|
||||
case EditorType.Checklist:
|
||||
return _checklistEditorKey.currentState.getNote();
|
||||
case EditorType.Journal:
|
||||
return _journalEditorKey.currentState.getNote();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
Reference in New Issue
Block a user