Files
GitJournal/lib/editors/raw_editor.dart
Vishesh Handa 7e7503ca2f Editors: Expose the preview markdown button on all editors
It's nice to sometimes use the RawEditor to edit something and then
later you want to see what it looks, and having to switch to the
Markdown Editor for that is very annoying.
2020-08-20 11:47:31 +02:00

169 lines
4.0 KiB
Dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:gitjournal/core/md_yaml_doc_codec.dart';
import 'package:gitjournal/core/note.dart';
import 'package:gitjournal/editors/common.dart';
import 'package:gitjournal/editors/disposable_change_notifier.dart';
import 'package:gitjournal/widgets/editor_scroll_view.dart';
class RawEditor extends StatefulWidget implements Editor {
final Note note;
final bool noteModified;
@override
final NoteCallback noteDeletionSelected;
@override
final NoteCallback noteEditorChooserSelected;
@override
final NoteCallback exitEditorSelected;
@override
final NoteCallback renameNoteSelected;
@override
final NoteCallback editTagsSelected;
@override
final NoteCallback moveNoteToFolderSelected;
@override
final NoteCallback discardChangesSelected;
final bool isNewNote;
RawEditor({
Key key,
@required this.note,
@required this.noteModified,
@required this.noteDeletionSelected,
@required this.noteEditorChooserSelected,
@required this.exitEditorSelected,
@required this.renameNoteSelected,
@required this.editTagsSelected,
@required this.moveNoteToFolderSelected,
@required this.discardChangesSelected,
@required this.isNewNote,
}) : super(key: key);
@override
RawEditorState createState() {
return RawEditorState(note);
}
}
class RawEditorState extends State<RawEditor>
with DisposableChangeNotifier
implements EditorState {
Note note;
bool _noteModified;
TextEditingController _textController = TextEditingController();
final serializer = MarkdownYAMLCodec();
RawEditorState(this.note) {
_textController = TextEditingController(text: serializer.encode(note.data));
}
@override
void initState() {
super.initState();
_noteModified = widget.noteModified;
}
@override
void dispose() {
_textController.dispose();
super.disposeListenables();
super.dispose();
}
@override
void didUpdateWidget(RawEditor oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.noteModified != widget.noteModified) {
_noteModified = widget.noteModified;
}
}
@override
Widget build(BuildContext context) {
var editor = EditorScrollView(
child: _NoteEditor(
textController: _textController,
autofocus: widget.isNewNote,
onChanged: _noteTextChanged,
),
);
return EditorScaffold(
editor: widget,
editorState: this,
noteModified: _noteModified,
isNewNote: widget.isNewNote,
parentFolder: note.parent,
body: editor,
);
}
@override
Note getNote() {
note.data = serializer.decode(_textController.text);
return note;
}
void _noteTextChanged() {
notifyListeners();
if (_noteModified) return;
setState(() {
_noteModified = true;
});
}
@override
Future<void> addImage(File file) async {
await getNote().addImage(file);
setState(() {
_textController.text = note.body;
_noteModified = true;
});
}
@override
bool get noteModified => _noteModified;
}
class _NoteEditor extends StatelessWidget {
final TextEditingController textController;
final bool autofocus;
final Function onChanged;
_NoteEditor({this.textController, this.autofocus, this.onChanged});
@override
Widget build(BuildContext context) {
var style = Theme.of(context)
.textTheme
.subtitle1
.copyWith(fontFamily: "Roboto Mono");
return TextField(
autofocus: autofocus,
keyboardType: TextInputType.multiline,
maxLines: null,
style: style,
decoration: InputDecoration(
hintText: tr('editors.common.defaultBodyHint'),
border: InputBorder.none,
isDense: true,
),
controller: textController,
textCapitalization: TextCapitalization.sentences,
scrollPadding: const EdgeInsets.all(0.0),
onChanged: (_) => onChanged(),
);
}
}