From 2bf7b8b585a040bf0769ec443d501546ade14d26 Mon Sep 17 00:00:00 2001 From: Xin Yao Date: Sun, 28 Mar 2021 22:21:17 -0700 Subject: [PATCH 1/7] Enable "Select", "Select All" and "Copy" in read-only mode --- CHANGELOG.md | 3 +++ lib/widgets/editor.dart | 4 ++-- lib/widgets/raw_editor.dart | 4 ---- pubspec.yaml | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96d611ee..84dcc862 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [1.1.5] +* Enable "Select", "Select All" and "Copy" in read-only mode. + ## [1.1.4] * Fix text selection issue. diff --git a/lib/widgets/editor.dart b/lib/widgets/editor.dart index 5bab5fb4..56b41641 100644 --- a/lib/widgets/editor.dart +++ b/lib/widgets/editor.dart @@ -277,10 +277,10 @@ class _QuillEditorState extends State widget.placeholder, widget.onLaunchUrl, ToolbarOptions( - copy: widget.enableInteractiveSelection, + copy: true, cut: widget.enableInteractiveSelection, paste: widget.enableInteractiveSelection, - selectAll: widget.enableInteractiveSelection, + selectAll: true, ), theme.platform == TargetPlatform.iOS || theme.platform == TargetPlatform.android, diff --git a/lib/widgets/raw_editor.dart b/lib/widgets/raw_editor.dart index d48fea6b..c4b15c88 100644 --- a/lib/widgets/raw_editor.dart +++ b/lib/widgets/raw_editor.dart @@ -371,10 +371,6 @@ class RawEditorState extends EditorState _textInputConnection != null && _textInputConnection!.attached; void openConnectionIfNeeded() { - if (!shouldCreateInputConnection) { - return; - } - if (!hasConnection) { _lastKnownRemoteTextEditingValue = textEditingValue; _textInputConnection = TextInput.attach( diff --git a/pubspec.yaml b/pubspec.yaml index 69bb7a14..a06bd297 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor supporting mobile and web (Demo App @ bulletjournal.us) -version: 1.1.4 +version: 1.1.5 #author: bulletjournal homepage: https://bulletjournal.us/home/index.html repository: https://github.com/singerdmx/flutter-quill From 03e587b970ab51612d07adf7aefab7345ec558dd Mon Sep 17 00:00:00 2001 From: Xin Yao Date: Sun, 28 Mar 2021 23:02:55 -0700 Subject: [PATCH 2/7] Upgrade universal_html --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index a06bd297..99a201aa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,7 +23,7 @@ dependencies: quiver: ^3.0.0 string_validator: ^0.3.0 tuple: ^2.0.0 - universal_html: ^2.0.4 + universal_html: ^2.0.7 url_launcher: ^6.0.2 pedantic: ^1.11.0 From 63a616e7ebea3d6a8b5aa8386fd7341cefe6f33a Mon Sep 17 00:00:00 2001 From: Xin Yao Date: Mon, 29 Mar 2021 01:20:00 -0700 Subject: [PATCH 3/7] Remove universal_html dependency --- example/lib/pages/home_page.dart | 88 +++++++---- example/lib/pages/read_only_page.dart | 33 ++-- .../lib}/universal_ui/fake_ui.dart | 0 .../lib}/universal_ui/real_ui.dart | 0 example/lib/universal_ui/universal_ui.dart | 57 +++++++ example/lib/widgets/field.dart | 142 ------------------ example/pubspec.yaml | 2 +- lib/utils/universal_ui/universal_ui.dart | 21 --- lib/widgets/editor.dart | 38 +---- pubspec.yaml | 1 - 10 files changed, 142 insertions(+), 240 deletions(-) rename {lib/utils => example/lib}/universal_ui/fake_ui.dart (100%) rename {lib/utils => example/lib}/universal_ui/real_ui.dart (100%) create mode 100644 example/lib/universal_ui/universal_ui.dart delete mode 100644 example/lib/widgets/field.dart delete mode 100644 lib/utils/universal_ui/universal_ui.dart diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 9e91cde4..65c2f165 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'package:app/universal_ui/universal_ui.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -38,13 +39,13 @@ class _HomePageState extends State { final doc = Document.fromJson(jsonDecode(result)); setState(() { _controller = QuillController( - document: doc, selection: TextSelection.collapsed(offset: 0)); + document: doc, selection: const TextSelection.collapsed(offset: 0)); }); } catch (error) { final doc = Document()..insert(0, 'Empty asset'); setState(() { _controller = QuillController( - document: doc, selection: TextSelection.collapsed(offset: 0)); + document: doc, selection: const TextSelection.collapsed(offset: 0)); }); } } @@ -52,7 +53,7 @@ class _HomePageState extends State { @override Widget build(BuildContext context) { if (_controller == null) { - return Scaffold(body: Center(child: Text('Loading...'))); + return const Scaffold(body: Center(child: Text('Loading...'))); } return Scaffold( @@ -60,7 +61,7 @@ class _HomePageState extends State { backgroundColor: Colors.grey.shade800, elevation: 0, centerTitle: false, - title: Text( + title: const Text( 'Flutter Quill', ), actions: [], @@ -93,6 +94,55 @@ class _HomePageState extends State { } Widget _buildWelcomeEditor(BuildContext context) { + var quillEditor = QuillEditor( + controller: _controller!, + scrollController: ScrollController(), + scrollable: true, + focusNode: _focusNode, + autoFocus: false, + readOnly: false, + placeholder: 'Add content', + expands: false, + padding: EdgeInsets.zero, + customStyles: DefaultStyles( + h1: DefaultTextBlockStyle( + const TextStyle( + fontSize: 32.0, + color: Colors.black, + height: 1.15, + fontWeight: FontWeight.w300, + ), + const Tuple2(16.0, 0.0), + const Tuple2(0.0, 0.0), + null), + sizeSmall: const TextStyle(fontSize: 9.0), + )); + if (kIsWeb) { + quillEditor = QuillEditor( + controller: _controller!, + scrollController: ScrollController(), + scrollable: true, + focusNode: _focusNode, + autoFocus: false, + readOnly: false, + placeholder: 'Add content', + expands: false, + padding: EdgeInsets.zero, + customStyles: DefaultStyles( + h1: DefaultTextBlockStyle( + const TextStyle( + fontSize: 32.0, + color: Colors.black, + height: 1.15, + fontWeight: FontWeight.w300, + ), + const Tuple2(16.0, 0.0), + const Tuple2(0.0, 0.0), + null), + sizeSmall: const TextStyle(fontSize: 9.0), + ), + embedBuilder: defaultEmbedBuilderWeb); + } return SafeArea( child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -102,36 +152,14 @@ class _HomePageState extends State { child: Container( color: Colors.white, padding: const EdgeInsets.only(left: 16.0, right: 16.0), - child: QuillEditor( - controller: _controller!, - scrollController: ScrollController(), - scrollable: true, - focusNode: _focusNode, - autoFocus: false, - readOnly: false, - placeholder: 'Add content', - expands: false, - padding: EdgeInsets.zero, - customStyles: DefaultStyles( - h1: DefaultTextBlockStyle( - TextStyle( - fontSize: 32.0, - color: Colors.black, - height: 1.15, - fontWeight: FontWeight.w300, - ), - Tuple2(16.0, 0.0), - Tuple2(0.0, 0.0), - null), - sizeSmall: TextStyle(fontSize: 9.0), - ), - ), + child: quillEditor, ), ), kIsWeb ? Expanded( child: Container( - padding: EdgeInsets.symmetric(vertical: 16, horizontal: 8), + padding: + const EdgeInsets.symmetric(vertical: 16, horizontal: 8), child: QuillToolbar.basic( controller: _controller!, onImagePickCallback: _onImagePickCallback), @@ -158,7 +186,7 @@ class _HomePageState extends State { Widget _buildMenuBar(BuildContext context) { Size size = MediaQuery.of(context).size; - final itemStyle = TextStyle( + final itemStyle = const TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, diff --git a/example/lib/pages/read_only_page.dart b/example/lib/pages/read_only_page.dart index 6e2ec0e0..e87e4f8f 100644 --- a/example/lib/pages/read_only_page.dart +++ b/example/lib/pages/read_only_page.dart @@ -1,3 +1,5 @@ +import 'package:app/universal_ui/universal_ui.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_quill/widgets/controller.dart'; import 'package:flutter_quill/widgets/editor.dart'; @@ -28,15 +30,19 @@ class _ReadOnlyPageState extends State { } Widget _buildContent(BuildContext context, QuillController? controller) { - return Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.grey.shade200), - ), - child: QuillEditor( - controller: controller!, + var quillEditor = QuillEditor( + controller: controller!, + scrollController: ScrollController(), + scrollable: true, + focusNode: _focusNode, + autoFocus: true, + readOnly: !_edit, + expands: false, + padding: EdgeInsets.zero, + ); + if (kIsWeb) { + quillEditor = QuillEditor( + controller: controller, scrollController: ScrollController(), scrollable: true, focusNode: _focusNode, @@ -44,7 +50,16 @@ class _ReadOnlyPageState extends State { readOnly: !_edit, expands: false, padding: EdgeInsets.zero, + embedBuilder: defaultEmbedBuilderWeb); + } + return Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.grey.shade200), ), + child: quillEditor, ), ); } diff --git a/lib/utils/universal_ui/fake_ui.dart b/example/lib/universal_ui/fake_ui.dart similarity index 100% rename from lib/utils/universal_ui/fake_ui.dart rename to example/lib/universal_ui/fake_ui.dart diff --git a/lib/utils/universal_ui/real_ui.dart b/example/lib/universal_ui/real_ui.dart similarity index 100% rename from lib/utils/universal_ui/real_ui.dart rename to example/lib/universal_ui/real_ui.dart diff --git a/example/lib/universal_ui/universal_ui.dart b/example/lib/universal_ui/universal_ui.dart new file mode 100644 index 00000000..15eeb9f8 --- /dev/null +++ b/example/lib/universal_ui/universal_ui.dart @@ -0,0 +1,57 @@ +library universal_ui; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_quill/models/documents/nodes/leaf.dart' as leaf; +import 'package:flutter_quill/widgets/responsive_widget.dart'; +import 'package:universal_html/html.dart' as html; + +import 'fake_ui.dart' if (dart.library.html) 'real_ui.dart' as ui_instance; + +class PlatformViewRegistryFix { + void registerViewFactory(dynamic x, dynamic y) { + if (kIsWeb) { + ui_instance.PlatformViewRegistry.registerViewFactory( + x, + y, + ); + } + } +} + +class UniversalUI { + PlatformViewRegistryFix platformViewRegistry = PlatformViewRegistryFix(); +} + +var ui = UniversalUI(); + +Widget defaultEmbedBuilderWeb(BuildContext context, leaf.Embed node) { + switch (node.value.type) { + case 'image': + String imageUrl = node.value.data; + Size size = MediaQuery.of(context).size; + UniversalUI().platformViewRegistry.registerViewFactory( + imageUrl, (int viewId) => html.ImageElement()..src = imageUrl); + return Padding( + padding: EdgeInsets.only( + right: ResponsiveWidget.isMediumScreen(context) + ? size.width * 0.5 + : (ResponsiveWidget.isLargeScreen(context)) + ? size.width * 0.75 + : size.width * 0.2, + ), + child: SizedBox( + height: MediaQuery.of(context).size.height * 0.45, + child: HtmlElementView( + viewType: imageUrl, + ), + ), + ); + + default: + throw UnimplementedError( + 'Embeddable type "${node.value.type}" is not supported by default embed ' + 'builder of QuillEditor. You must pass your own builder function to ' + 'embedBuilder property of QuillEditor or QuillField widgets.'); + } +} diff --git a/example/lib/widgets/field.dart b/example/lib/widgets/field.dart deleted file mode 100644 index 5a6badfe..00000000 --- a/example/lib/widgets/field.dart +++ /dev/null @@ -1,142 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_quill/widgets/controller.dart'; -import 'package:flutter_quill/widgets/delegate.dart'; -import 'package:flutter_quill/widgets/editor.dart'; - -class QuillField extends StatefulWidget { - final QuillController controller; - final FocusNode? focusNode; - final ScrollController? scrollController; - final bool scrollable; - final EdgeInsetsGeometry padding; - final bool autofocus; - final bool showCursor; - final bool readOnly; - final bool enableInteractiveSelection; - final double? minHeight; - final double? maxHeight; - final bool expands; - final TextCapitalization textCapitalization; - final Brightness keyboardAppearance; - final ScrollPhysics? scrollPhysics; - final ValueChanged? onLaunchUrl; - final InputDecoration? decoration; - final Widget? toolbar; - final EmbedBuilder? embedBuilder; - - QuillField({ - Key? key, - required this.controller, - this.focusNode, - this.scrollController, - this.scrollable = true, - this.padding = EdgeInsets.zero, - this.autofocus = false, - this.showCursor = true, - this.readOnly = false, - this.enableInteractiveSelection = true, - this.minHeight, - this.maxHeight, - this.expands = false, - this.textCapitalization = TextCapitalization.sentences, - this.keyboardAppearance = Brightness.light, - this.scrollPhysics, - this.onLaunchUrl, - this.decoration, - this.toolbar, - this.embedBuilder, - }) : super(key: key); - - @override - _QuillFieldState createState() => _QuillFieldState(); -} - -class _QuillFieldState extends State { - late bool _focused; - - void _editorFocusChanged() { - setState(() { - _focused = widget.focusNode!.hasFocus; - }); - } - - @override - void initState() { - super.initState(); - _focused = widget.focusNode!.hasFocus; - widget.focusNode!.addListener(_editorFocusChanged); - } - - @override - void didUpdateWidget(covariant QuillField oldWidget) { - super.didUpdateWidget(oldWidget); - if (widget.focusNode != oldWidget.focusNode) { - oldWidget.focusNode!.removeListener(_editorFocusChanged); - widget.focusNode!.addListener(_editorFocusChanged); - _focused = widget.focusNode!.hasFocus; - } - } - - @override - Widget build(BuildContext context) { - Widget child = QuillEditor( - controller: widget.controller, - focusNode: widget.focusNode!, - scrollController: widget.scrollController!, - scrollable: widget.scrollable, - padding: widget.padding, - autoFocus: widget.autofocus, - showCursor: widget.showCursor, - readOnly: widget.readOnly, - enableInteractiveSelection: widget.enableInteractiveSelection, - minHeight: widget.minHeight, - maxHeight: widget.maxHeight, - expands: widget.expands, - textCapitalization: widget.textCapitalization, - keyboardAppearance: widget.keyboardAppearance, - scrollPhysics: widget.scrollPhysics, - onLaunchUrl: widget.onLaunchUrl, - embedBuilder: widget.embedBuilder!, - ); - - if (widget.toolbar != null) { - child = Column( - children: [ - child, - Visibility( - visible: _focused, - maintainSize: true, - maintainAnimation: true, - maintainState: true, - child: widget.toolbar!, - ), - ], - ); - } - - return AnimatedBuilder( - animation: - Listenable.merge([widget.focusNode, widget.controller]), - builder: (BuildContext context, Widget? child) { - return InputDecorator( - decoration: _getEffectiveDecoration(), - isFocused: widget.focusNode!.hasFocus, - // TODO: Document should be considered empty of it has single empty line with no styles applied - isEmpty: widget.controller.document.length == 1, - child: child, - ); - }, - child: child, - ); - } - - InputDecoration _getEffectiveDecoration() { - return (widget.decoration ?? const InputDecoration()) - .applyDefaults(Theme.of(context).inputDecorationTheme) - .copyWith( - enabled: !widget.readOnly, - hintMaxLines: widget.decoration?.hintMaxLines, - ); - } -} diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 3a31d347..e1bd45f5 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -23,7 +23,7 @@ environment: dependencies: flutter: sdk: flutter - + universal_html: ^2.0.7 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. diff --git a/lib/utils/universal_ui/universal_ui.dart b/lib/utils/universal_ui/universal_ui.dart deleted file mode 100644 index 5fe7c428..00000000 --- a/lib/utils/universal_ui/universal_ui.dart +++ /dev/null @@ -1,21 +0,0 @@ -library universal_ui; - -import 'package:flutter/foundation.dart'; -import 'fake_ui.dart' if (dart.library.html) 'real_ui.dart' as ui_instance; - -class PlatformViewRegistryFix { - void registerViewFactory(dynamic x, dynamic y) { - if (kIsWeb) { - ui_instance.PlatformViewRegistry.registerViewFactory( - x, - y, - ); - } - } -} - -class UniversalUI { - PlatformViewRegistryFix platformViewRegistry = PlatformViewRegistryFix(); -} - -var ui = UniversalUI(); diff --git a/lib/widgets/editor.dart b/lib/widgets/editor.dart index 56b41641..df74e2e7 100644 --- a/lib/widgets/editor.dart +++ b/lib/widgets/editor.dart @@ -16,13 +16,10 @@ import 'package:flutter_quill/models/documents/nodes/embed.dart'; import 'package:flutter_quill/models/documents/nodes/leaf.dart' as leaf; import 'package:flutter_quill/models/documents/nodes/line.dart'; import 'package:flutter_quill/models/documents/nodes/node.dart'; -import 'package:flutter_quill/utils/universal_ui/universal_ui.dart'; import 'package:flutter_quill/widgets/image.dart'; import 'package:flutter_quill/widgets/raw_editor.dart'; -import 'package:flutter_quill/widgets/responsive_widget.dart'; import 'package:flutter_quill/widgets/text_selection.dart'; import 'package:string_validator/string_validator.dart'; -import 'package:universal_html/html.dart' as html; import 'package:url_launcher/url_launcher.dart'; import 'box.dart'; @@ -101,6 +98,7 @@ String _standardizeImageUrl(String url) { } Widget _defaultEmbedBuilder(BuildContext context, leaf.Embed node) { + assert(!kIsWeb, 'Please provide EmbedBuilder for Web'); switch (node.value.type) { case 'image': String imageUrl = _standardizeImageUrl(node.value.data); @@ -117,37 +115,6 @@ Widget _defaultEmbedBuilder(BuildContext context, leaf.Embed node) { } } -Widget _defaultEmbedBuilderWeb(BuildContext context, leaf.Embed node) { - switch (node.value.type) { - case 'image': - String imageUrl = node.value.data; - Size size = MediaQuery.of(context).size; - UniversalUI().platformViewRegistry.registerViewFactory( - imageUrl, (int viewId) => html.ImageElement()..src = imageUrl); - return Padding( - padding: EdgeInsets.only( - right: ResponsiveWidget.isMediumScreen(context) - ? size.width * 0.5 - : (ResponsiveWidget.isLargeScreen(context)) - ? size.width * 0.75 - : size.width * 0.2, - ), - child: SizedBox( - height: MediaQuery.of(context).size.height * 0.45, - child: HtmlElementView( - viewType: imageUrl, - ), - ), - ); - - default: - throw UnimplementedError( - 'Embeddable type "${node.value.type}" is not supported by default embed ' - 'builder of QuillEditor. You must pass your own builder function to ' - 'embedBuilder property of QuillEditor or QuillField widgets.'); - } -} - class QuillEditor extends StatefulWidget { final QuillController controller; final FocusNode focusNode; @@ -188,8 +155,7 @@ class QuillEditor extends StatefulWidget { this.keyboardAppearance = Brightness.light, this.scrollPhysics, this.onLaunchUrl, - this.embedBuilder = - kIsWeb ? _defaultEmbedBuilderWeb : _defaultEmbedBuilder}); + this.embedBuilder = _defaultEmbedBuilder}); factory QuillEditor.basic( {required QuillController controller, required bool readOnly}) { diff --git a/pubspec.yaml b/pubspec.yaml index 99a201aa..41f9fb06 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,7 +23,6 @@ dependencies: quiver: ^3.0.0 string_validator: ^0.3.0 tuple: ^2.0.0 - universal_html: ^2.0.7 url_launcher: ^6.0.2 pedantic: ^1.11.0 From 96cb7effc66471a06b9e25dcaa4492cfa38b25b7 Mon Sep 17 00:00:00 2001 From: Xin Yao Date: Mon, 29 Mar 2021 01:25:49 -0700 Subject: [PATCH 4/7] Update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 18172233..b7c1a247 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,8 @@ The `QuillToolbar` class lets you customise which formatting options are availab For web development, use `flutter config --enable-web` for flutter and use [ReactQuill] for React. +It is required to provide EmbedBuilder, e.g. [defaultEmbedBuilderWeb](https://github.com/singerdmx/flutter-quill/blob/master/example/lib/universal_ui/universal_ui.dart#L28). + ## Migrate Zefyr Data Check out [code](https://github.com/jwehrle/zefyr_quill_convert) and [doc](https://docs.google.com/document/d/1FUSrpbarHnilb7uDN5J5DDahaI0v1RMXBjj4fFSpSuY/edit?usp=sharing). From 30bd6342ead137c6d810a18c97c3b6cf60858a8a Mon Sep 17 00:00:00 2001 From: Xin Yao Date: Mon, 29 Mar 2021 01:37:20 -0700 Subject: [PATCH 5/7] Upgrade to 1.1.6 --- CHANGELOG.md | 3 +++ pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84dcc862..bee97937 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [1.1.6] +* Remove universal_html dependency. + ## [1.1.5] * Enable "Select", "Select All" and "Copy" in read-only mode. diff --git a/pubspec.yaml b/pubspec.yaml index 41f9fb06..040d3d33 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor supporting mobile and web (Demo App @ bulletjournal.us) -version: 1.1.5 +version: 1.1.6 #author: bulletjournal homepage: https://bulletjournal.us/home/index.html repository: https://github.com/singerdmx/flutter-quill From 5b9fb5280446cf7fe0fb5391ea270461f864396e Mon Sep 17 00:00:00 2001 From: Xin Yao Date: Mon, 29 Mar 2021 01:47:23 -0700 Subject: [PATCH 6/7] Make showCursor default to true --- lib/widgets/raw_editor.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/raw_editor.dart b/lib/widgets/raw_editor.dart index c4b15c88..b5139bc5 100644 --- a/lib/widgets/raw_editor.dart +++ b/lib/widgets/raw_editor.dart @@ -85,7 +85,7 @@ class RawEditor extends StatefulWidget { assert(minHeight == null || minHeight >= 0, 'minHeight cannot be null'), assert(maxHeight == null || minHeight == null || maxHeight >= minHeight, 'maxHeight cannot be null'), - showCursor = showCursor ?? !readOnly, + showCursor = showCursor ?? true, super(key: key); @override From f0dcca00d90cd75d7165c0daf803523c81559743 Mon Sep 17 00:00:00 2001 From: Xin Yao Date: Mon, 29 Mar 2021 02:02:48 -0700 Subject: [PATCH 7/7] Readonly mode - temporary hack to dismiss keyboard --- lib/widgets/raw_editor.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/widgets/raw_editor.dart b/lib/widgets/raw_editor.dart index b5139bc5..9d2a5fe4 100644 --- a/lib/widgets/raw_editor.dart +++ b/lib/widgets/raw_editor.dart @@ -379,6 +379,7 @@ class RawEditorState extends EditorState inputType: TextInputType.multiline, readOnly: widget.readOnly, inputAction: TextInputAction.newline, + enableSuggestions: !widget.readOnly, keyboardAppearance: widget.keyboardAppearance, textCapitalization: widget.textCapitalization, ), @@ -388,6 +389,10 @@ class RawEditorState extends EditorState // _sentRemoteValues.add(_lastKnownRemoteTextEditingValue); } _textInputConnection!.show(); + if (widget.readOnly) { + // temporary hack to dismiss keyboard + SystemChannels.textInput.invokeMethod('TextInput.hide'); + } } void closeConnectionIfNeeded() {