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/note.dart';
|
||||||
import 'package:gitjournal/core/md_yaml_doc.dart';
|
import 'package:gitjournal/core/md_yaml_doc.dart';
|
||||||
import 'package:gitjournal/core/notes_folder.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/markdown_editor.dart';
|
||||||
import 'package:gitjournal/editors/raw_editor.dart';
|
import 'package:gitjournal/editors/raw_editor.dart';
|
||||||
import 'package:gitjournal/editors/checklist_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> {
|
class NoteEditorState extends State<NoteEditor> {
|
||||||
Note note;
|
Note note;
|
||||||
@ -41,6 +42,7 @@ class NoteEditorState extends State<NoteEditor> {
|
|||||||
final _rawEditorKey = GlobalKey<RawEditorState>();
|
final _rawEditorKey = GlobalKey<RawEditorState>();
|
||||||
final _markdownEditorKey = GlobalKey<MarkdownEditorState>();
|
final _markdownEditorKey = GlobalKey<MarkdownEditorState>();
|
||||||
final _checklistEditorKey = GlobalKey<ChecklistEditorState>();
|
final _checklistEditorKey = GlobalKey<ChecklistEditorState>();
|
||||||
|
final _journalEditorKey = GlobalKey<JournalEditorState>();
|
||||||
|
|
||||||
bool get _isNewNote {
|
bool get _isNewNote {
|
||||||
return widget.note == null;
|
return widget.note == null;
|
||||||
@ -117,11 +119,25 @@ class NoteEditorState extends State<NoteEditor> {
|
|||||||
discardChangesSelected: _discardChangesSelected,
|
discardChangesSelected: _discardChangesSelected,
|
||||||
autofocusOnEditor: _isNewNote,
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _noteEditorChooserSelected(Note _note) async {
|
void _noteEditorChooserSelected(Note _note) async {
|
||||||
|
var onEditorChange = (EditorType et) => Navigator.of(context).pop(et);
|
||||||
|
|
||||||
var newEditorType = await showDialog<EditorType>(
|
var newEditorType = await showDialog<EditorType>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
@ -130,19 +146,25 @@ class NoteEditorState extends State<NoteEditor> {
|
|||||||
title: const Text("Markdown Editor"),
|
title: const Text("Markdown Editor"),
|
||||||
value: EditorType.Markdown,
|
value: EditorType.Markdown,
|
||||||
groupValue: editorType,
|
groupValue: editorType,
|
||||||
onChanged: (EditorType et) => Navigator.of(context).pop(et),
|
onChanged: onEditorChange,
|
||||||
),
|
),
|
||||||
RadioListTile<EditorType>(
|
RadioListTile<EditorType>(
|
||||||
title: const Text("Raw Editor"),
|
title: const Text("Raw Editor"),
|
||||||
value: EditorType.Raw,
|
value: EditorType.Raw,
|
||||||
groupValue: editorType,
|
groupValue: editorType,
|
||||||
onChanged: (EditorType et) => Navigator.of(context).pop(et),
|
onChanged: onEditorChange,
|
||||||
),
|
),
|
||||||
RadioListTile<EditorType>(
|
RadioListTile<EditorType>(
|
||||||
title: const Text("Checklist Editor"),
|
title: const Text("Checklist Editor"),
|
||||||
value: EditorType.Checklist,
|
value: EditorType.Checklist,
|
||||||
groupValue: editorType,
|
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();
|
return _rawEditorKey.currentState.getNote();
|
||||||
case EditorType.Checklist:
|
case EditorType.Checklist:
|
||||||
return _checklistEditorKey.currentState.getNote();
|
return _checklistEditorKey.currentState.getNote();
|
||||||
|
case EditorType.Journal:
|
||||||
|
return _journalEditorKey.currentState.getNote();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user