From 62b5761ec417c790a04518312a41952b1b4c04d0 Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Wed, 6 May 2020 15:14:41 +0200 Subject: [PATCH] Editors: Do not use BottomAppBar in the scaffold property The BottomAppBar when given in the Scaffold gets hidden when the keyboard is visible. We had hacked around that by translating its position, however that resulted in the cursor at the bottom being hidden when we were typing a long note. It is not just part of the body of the scaffold. Also converted many functions into widgets. --- lib/editors/checklist_editor.dart | 11 +- lib/editors/common.dart | 271 ++++++++++++++++++------------ lib/editors/journal_editor.dart | 11 +- lib/editors/markdown_editor.dart | 18 +- lib/editors/raw_editor.dart | 11 +- 5 files changed, 190 insertions(+), 132 deletions(-) diff --git a/lib/editors/checklist_editor.dart b/lib/editors/checklist_editor.dart index 2f4c6f0e..3e2343fa 100644 --- a/lib/editors/checklist_editor.dart +++ b/lib/editors/checklist_editor.dart @@ -152,18 +152,17 @@ class ChecklistEditorState extends State child: NoteTitleEditor(_titleTextController, _noteTextChanged), ); - return Scaffold( - appBar: buildEditorAppBar(widget, this, noteModified: _noteModified), + return EditorScaffold( + editor: widget, + editorState: this, + noteModified: _noteModified, + parentFolder: widget.note.parent, body: Column( children: [ if (widget.note.canHaveMetadata) titleEditor, Expanded(child: FocusScope(child: checklistWidget)), ], ), - bottomNavigationBar: Builder( - builder: (context) => - buildEditorBottonBar(context, widget, this, widget.note.parent), - ), ); } diff --git a/lib/editors/common.dart b/lib/editors/common.dart index 77c20a6d..84e3a0af 100644 --- a/lib/editors/common.dart +++ b/lib/editors/common.dart @@ -26,104 +26,134 @@ abstract class EditorState { enum DropDownChoices { Rename, DiscardChanges, Share } -AppBar buildEditorAppBar( - Editor editor, - EditorState editorState, { - @required bool noteModified, - List extraButtons, -}) { - return AppBar( - leading: IconButton( - key: const ValueKey("NewEntry"), - icon: Icon(noteModified ? Icons.check : Icons.close), - onPressed: () { - editor.exitEditorSelected(editorState.getNote()); - }, - ), - actions: [ - ...?extraButtons, - IconButton( - key: const ValueKey("EditorSelector"), - icon: const Icon(Icons.library_books), - onPressed: () { - var note = editorState.getNote(); - editor.noteEditorChooserSelected(note); - }, - ), - IconButton( - icon: const Icon(Icons.delete), - onPressed: () { - var note = editorState.getNote(); - editor.noteDeletionSelected(note); - }, - ), - PopupMenuButton( - onSelected: (DropDownChoices choice) { - switch (choice) { - case DropDownChoices.Rename: - var note = editorState.getNote(); - editor.renameNoteSelected(note); - return; +class EditorAppBar extends StatelessWidget implements PreferredSizeWidget { + final Editor editor; + final EditorState editorState; + final bool noteModified; + final IconButton extraButton; - case DropDownChoices.DiscardChanges: - var note = editorState.getNote(); - editor.discardChangesSelected(note); - return; + EditorAppBar({ + Key key, + @required this.editor, + @required this.editorState, + @required this.noteModified, + this.extraButton, + }) : preferredSize = Size.fromHeight(kToolbarHeight), + super(key: key); - case DropDownChoices.Share: - var note = editorState.getNote(); - Share.share(note.body); - return; - } + @override + final Size preferredSize; + + @override + Widget build(BuildContext context) { + return AppBar( + leading: IconButton( + key: const ValueKey("NewEntry"), + icon: Icon(noteModified ? Icons.check : Icons.close), + onPressed: () { + editor.exitEditorSelected(editorState.getNote()); }, - itemBuilder: (BuildContext context) => - >[ - const PopupMenuItem( - value: DropDownChoices.Rename, - child: Text('Edit File Name'), - ), - const PopupMenuItem( - value: DropDownChoices.DiscardChanges, - child: Text('Discard Changes'), - ), - const PopupMenuItem( - value: DropDownChoices.Share, - child: Text('Share Note'), - ), - ], ), - ], - ); + actions: [ + if (extraButton != null) extraButton, + IconButton( + key: const ValueKey("EditorSelector"), + icon: const Icon(Icons.library_books), + onPressed: () { + var note = editorState.getNote(); + editor.noteEditorChooserSelected(note); + }, + ), + IconButton( + icon: const Icon(Icons.delete), + onPressed: () { + var note = editorState.getNote(); + editor.noteDeletionSelected(note); + }, + ), + PopupMenuButton( + onSelected: (DropDownChoices choice) { + switch (choice) { + case DropDownChoices.Rename: + var note = editorState.getNote(); + editor.renameNoteSelected(note); + return; + + case DropDownChoices.DiscardChanges: + var note = editorState.getNote(); + editor.discardChangesSelected(note); + return; + + case DropDownChoices.Share: + var note = editorState.getNote(); + Share.share(note.body); + return; + } + }, + itemBuilder: (BuildContext context) => + >[ + const PopupMenuItem( + value: DropDownChoices.Rename, + child: Text('Edit File Name'), + ), + const PopupMenuItem( + value: DropDownChoices.DiscardChanges, + child: Text('Discard Changes'), + ), + const PopupMenuItem( + value: DropDownChoices.Share, + child: Text('Share Note'), + ), + ], + ), + ], + ); + } } -Widget buildEditorBottonBar( - BuildContext context, - Editor editor, - EditorState editorState, - NotesFolderFS parentFolder, -) { - var folderName = parentFolder.pathSpec(); - if (folderName.isEmpty) { - folderName = "Root Folder"; - } +class EditorBottomBar extends StatelessWidget { + final Editor editor; + final EditorState editorState; + final NotesFolderFS parentFolder; + final bool allowEdits; - var s = Scaffold.of(context); - print("s $s"); - return StickyBottomAppBar( - child: BottomAppBar( + EditorBottomBar({ + @required this.editor, + @required this.editorState, + @required this.parentFolder, + @required this.allowEdits, + }); + + @override + Widget build(BuildContext context) { + var folderName = parentFolder.pathSpec(); + if (folderName.isEmpty) { + folderName = "Root Folder"; + } + + var addIcon = IconButton( + icon: Icon(Icons.add), + onPressed: () { + showModalBottomSheet( + context: context, + builder: (c) => _buildAddBottomSheet(c, editor, editorState), + elevation: 0, + ); + }, + ); + + return BottomAppBar( elevation: 0.0, color: Theme.of(context).scaffoldBackgroundColor, child: Row( children: [ - IconButton( - icon: Icon(Icons.add), - onPressed: () { - showModalBottomSheet( - context: context, - builder: (c) => _buildAddBottomSheet(c, editor, editorState), - elevation: 0, - ); - }, + Visibility( + child: addIcon, + visible: allowEdits, + maintainSize: true, + maintainAnimation: true, + maintainState: true, + maintainInteractivity: false, ), Expanded( child: FlatButton.icon( @@ -135,26 +165,18 @@ Widget buildEditorBottonBar( }, ), ), - const SizedBox( - height: 32.0, - width: 32.0, + // Just so there is equal padding on the right side + Visibility( + child: addIcon, + visible: false, + maintainSize: true, + maintainAnimation: true, + maintainState: true, + maintainInteractivity: false, ), ], mainAxisAlignment: MainAxisAlignment.center, ), - ), - ); -} - -class StickyBottomAppBar extends StatelessWidget { - final BottomAppBar child; - StickyBottomAppBar({@required this.child}); - - @override - Widget build(BuildContext context) { - return Transform.translate( - offset: Offset(0.0, -1 * MediaQuery.of(context).viewInsets.bottom), - child: child, ); } } @@ -208,3 +230,46 @@ Widget _buildAddBottomSheet( ), ); } + +class EditorScaffold extends StatelessWidget { + final Editor editor; + final EditorState editorState; + final bool noteModified; + final IconButton extraButton; + final Widget body; + final NotesFolderFS parentFolder; + final bool allowEdits; + + EditorScaffold({ + @required this.editor, + @required this.editorState, + @required this.noteModified, + @required this.body, + @required this.parentFolder, + this.extraButton, + this.allowEdits = true, + }); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: EditorAppBar( + editor: editor, + editorState: editorState, + noteModified: noteModified, + extraButton: extraButton, + ), + body: Column( + children: [ + Expanded(child: body), + EditorBottomBar( + editor: editor, + editorState: editorState, + parentFolder: parentFolder, + allowEdits: allowEdits, + ), + ], + ), + ); + } +} diff --git a/lib/editors/journal_editor.dart b/lib/editors/journal_editor.dart index 51482715..04e9ab85 100644 --- a/lib/editors/journal_editor.dart +++ b/lib/editors/journal_editor.dart @@ -80,13 +80,12 @@ class JournalEditorState extends State implements EditorState { ), ); - return Scaffold( - appBar: buildEditorAppBar(widget, this, noteModified: _noteModified), + return EditorScaffold( + editor: widget, + editorState: this, + noteModified: _noteModified, + parentFolder: note.parent, body: editor, - bottomNavigationBar: Builder( - builder: (context) => - buildEditorBottonBar(context, widget, this, note.parent), - ), ); } diff --git a/lib/editors/markdown_editor.dart b/lib/editors/markdown_editor.dart index afbd5d79..c3e5f9a0 100644 --- a/lib/editors/markdown_editor.dart +++ b/lib/editors/markdown_editor.dart @@ -106,18 +106,14 @@ class MarkdownEditorState extends State implements EditorState { onPressed: _switchMode, ); - return Scaffold( - appBar: buildEditorAppBar( - widget, - this, - noteModified: _noteModified, - extraButtons: [extraButton], - ), + return EditorScaffold( + editor: widget, + editorState: this, + extraButton: extraButton, + noteModified: _noteModified, + parentFolder: note.parent, + allowEdits: editingMode, body: body, - bottomNavigationBar: Builder( - builder: (context) => - buildEditorBottonBar(context, widget, this, note.parent), - ), ); } diff --git a/lib/editors/raw_editor.dart b/lib/editors/raw_editor.dart index 35d04ac2..0de385d9 100644 --- a/lib/editors/raw_editor.dart +++ b/lib/editors/raw_editor.dart @@ -77,13 +77,12 @@ class RawEditorState extends State implements EditorState { ), ); - return Scaffold( - appBar: buildEditorAppBar(widget, this, noteModified: _noteModified), + return EditorScaffold( + editor: widget, + editorState: this, + noteModified: _noteModified, + parentFolder: note.parent, body: editor, - bottomNavigationBar: Builder( - builder: (context) => - buildEditorBottonBar(context, widget, this, note.parent), - ), ); }