1
0
mirror of https://github.com/GitJournal/GitJournal.git synced 2025-07-21 07:03:25 +08:00

OrgEditor

This commit is contained in:
Alen Šiljak
2021-03-23 09:48:08 +01:00
committed by Vishesh Handa
parent 746c374d48
commit 93cf6433d6
6 changed files with 228 additions and 7 deletions

@ -159,6 +159,7 @@ settings:
journalEditor: Journal Editor
defaultFolder: Default Folder
checklistEditor: Checklist Editor
orgEditor: Org Editor
rawEditor: Raw Editor
choose: Choose Editor
sortingField:

@ -46,11 +46,7 @@ enum NoteLoadState {
Error,
}
enum NoteType {
Unknown,
Checklist,
Journal,
}
enum NoteType { Unknown, Checklist, Journal, Org }
class NoteFileFormatInfo {
static List<String> allowedExtensions = ['.md', '.org', '.txt'];

197
lib/editors/org_editor.dart Normal file

@ -0,0 +1,197 @@
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/editors/undo_redo.dart';
import 'package:gitjournal/widgets/editor_scroll_view.dart';
class OrgEditor 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 editMode;
OrgEditor({
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.editMode,
}) : super(key: key);
@override
OrgEditorState createState() {
return OrgEditorState(note);
}
}
class OrgEditorState extends State<OrgEditor>
with DisposableChangeNotifier
implements EditorState {
Note note;
bool _noteModified;
TextEditingController _textController;
UndoRedoStack _undoRedoStack;
final serializer = MarkdownYAMLCodec();
OrgEditorState(this.note) {
_textController = TextEditingController(text: serializer.encode(note.data));
_undoRedoStack = UndoRedoStack();
}
@override
void initState() {
super.initState();
_noteModified = widget.noteModified;
}
@override
void dispose() {
_textController.dispose();
super.disposeListenables();
super.dispose();
}
@override
void didUpdateWidget(OrgEditor 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.editMode,
onChanged: _noteTextChanged,
),
);
return EditorScaffold(
editor: widget,
editorState: this,
noteModified: _noteModified,
editMode: widget.editMode,
parentFolder: note.parent,
body: editor,
onUndoSelected: _undo,
onRedoSelected: _redo,
undoAllowed: _undoRedoStack.undoPossible,
redoAllowed: _undoRedoStack.redoPossible,
);
}
@override
Note getNote() {
note.data = serializer.decode(_textController.text);
return note;
}
void _noteTextChanged() {
notifyListeners();
var editState = TextEditorState.fromValue(_textController.value);
var redraw = _undoRedoStack.textChanged(editState);
if (redraw) {
setState(() {});
}
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;
Future<void> _undo() async {
var es = _undoRedoStack.undo();
_textController.value = es.toValue();
setState(() {
// To Redraw the undo/redo button state
});
}
Future<void> _redo() async {
var es = _undoRedoStack.redo();
_textController.value = es.toValue();
setState(() {
// To Redraw the undo/redo button state
});
}
}
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(),
);
}
}

@ -5,6 +5,7 @@ import 'package:flutter/services.dart';
import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:gitjournal/editors/org_editor.dart';
import 'package:provider/provider.dart';
import 'package:gitjournal/core/md_yaml_doc.dart';
@ -79,7 +80,7 @@ class NoteEditor extends StatefulWidget {
}
}
enum EditorType { Markdown, Raw, Checklist, Journal }
enum EditorType { Markdown, Raw, Checklist, Journal, Org }
class NoteEditorState extends State<NoteEditor> with WidgetsBindingObserver {
Note note;
@ -90,6 +91,7 @@ class NoteEditorState extends State<NoteEditor> with WidgetsBindingObserver {
final _markdownEditorKey = GlobalKey<MarkdownEditorState>();
final _checklistEditorKey = GlobalKey<ChecklistEditorState>();
final _journalEditorKey = GlobalKey<JournalEditorState>();
final _orgEditorKey = GlobalKey<OrgEditorState>();
bool get _isNewNote {
return widget.note == null;
@ -138,6 +140,9 @@ class NoteEditorState extends State<NoteEditor> with WidgetsBindingObserver {
case NoteType.Checklist:
editorType = EditorType.Checklist;
break;
case NoteType.Org:
editorType = EditorType.Org;
break;
case NoteType.Unknown:
editorType = widget.notesFolder.config.defaultEditor;
break;
@ -147,7 +152,7 @@ class NoteEditorState extends State<NoteEditor> with WidgetsBindingObserver {
// Org files
if (note.fileFormat == NoteFileFormat.OrgMode &&
editorType == EditorType.Markdown) {
editorType = EditorType.Raw;
editorType = EditorType.Org;
}
// Txt files
@ -166,6 +171,7 @@ class NoteEditorState extends State<NoteEditor> with WidgetsBindingObserver {
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
Log.i("Note Edit State: $state");
if (state != AppLifecycleState.resumed) {
var note = _getNoteFromEditor();
if (!_noteModified(note)) return;
@ -245,6 +251,20 @@ class NoteEditorState extends State<NoteEditor> with WidgetsBindingObserver {
discardChangesSelected: _discardChangesSelected,
editMode: widget.editMode,
);
case EditorType.Org:
return OrgEditor(
key: _orgEditorKey,
note: note,
noteModified: _noteModified(note),
noteDeletionSelected: _noteDeletionSelected,
noteEditorChooserSelected: _noteEditorChooserSelected,
exitEditorSelected: _exitEditorSelected,
renameNoteSelected: _renameNoteSelected,
editTagsSelected: _editTagsSelected,
moveNoteToFolderSelected: _moveNoteToFolderSelected,
discardChangesSelected: _discardChangesSelected,
editMode: widget.editMode,
);
}
return null;
}
@ -388,6 +408,8 @@ class NoteEditorState extends State<NoteEditor> with WidgetsBindingObserver {
return _checklistEditorKey.currentState.getNote();
case EditorType.Journal:
return _journalEditorKey.currentState.getNote();
case EditorType.Org:
return _orgEditorKey.currentState.getNote();
}
return null;
}

@ -661,6 +661,7 @@ class SettingsEditorType {
SettingsEditorType('settings.editors.journalEditor', "Journal");
static const Checklist =
SettingsEditorType('settings.editors.checklistEditor', "Checklist");
static const Org = SettingsEditorType('settings.editors.orgEditor', "Org");
static const Default = Markdown;
final String _str;
@ -700,6 +701,8 @@ class SettingsEditorType {
return SettingsEditorType.Markdown;
case EditorType.Journal:
return SettingsEditorType.Journal;
case EditorType.Org:
return SettingsEditorType.Org;
}
return SettingsEditorType.Default;
}

@ -57,6 +57,8 @@ class NoteEditorSelector extends StatelessWidget {
tr('settings.editors.journalEditor'),
FontAwesomeIcons.book,
),
_buildTile(context, EditorType.Org, tr('settings.editors.orgEditor'),
FontAwesomeIcons.horseHead)
],
mainAxisSize: MainAxisSize.min,
);