From e9eba510dae0b60045fb9335e240e408f67b3cff Mon Sep 17 00:00:00 2001 From: rish07 Date: Wed, 10 Feb 2021 14:42:06 +0530 Subject: [PATCH 1/2] Bottom toolbar bug fix --- lib/widgets/editor.dart | 14 +++++------- lib/widgets/text_line.dart | 2 +- lib/widgets/text_selection.dart | 16 +++++++------- lib/widgets/toolbar.dart | 8 ++++++- pubspec.lock | 38 ++++++++++++++++----------------- 5 files changed, 40 insertions(+), 38 deletions(-) diff --git a/lib/widgets/editor.dart b/lib/widgets/editor.dart index 75ee0e52..b02f97eb 100644 --- a/lib/widgets/editor.dart +++ b/lib/widgets/editor.dart @@ -11,7 +11,7 @@ import 'package:flutter_quill/models/documents/document.dart'; import 'package:flutter_quill/models/documents/nodes/container.dart' as containerNode; import 'package:flutter_quill/models/documents/nodes/embed.dart'; -import 'package:flutter_quill/models/documents/nodes/leaf.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/widgets/image.dart'; @@ -73,20 +73,16 @@ abstract class RenderAbstractEditor { void selectPosition(SelectionChangedCause cause); } -Widget _defaultEmbedBuilder(BuildContext context, Embed node) { +Widget _defaultEmbedBuilder(BuildContext context, leaf.Embed node) { switch (node.value.type) { - case 'divider': + case 'image': final style = QuillStyles.getStyles(context, true); return Divider( height: style.paragraph.style.fontSize * style.paragraph.style.height, thickness: 2, color: Colors.grey.shade200, ); - case 'image': - String imageUrl = node.value.data; - return imageUrl.startsWith('http') - ? Image.network(imageUrl) - : Image.asset(imageUrl); + default: throw UnimplementedError( 'Embeddable type "${node.value.type}" is not supported by default embed ' @@ -348,7 +344,7 @@ class _QuillEditorSelectionGestureDetectorBuilder } return false; } - Leaf segment = segmentResult.node as Leaf; + leaf.Leaf segment = segmentResult.node as leaf.Leaf; if (segment.style.containsKey(Attribute.link.key)) { var launchUrl = getEditor().widget.onLaunchUrl; if (launchUrl == null) { diff --git a/lib/widgets/text_line.dart b/lib/widgets/text_line.dart index a90a6883..53bb07f8 100644 --- a/lib/widgets/text_line.dart +++ b/lib/widgets/text_line.dart @@ -60,7 +60,7 @@ class TextLine extends StatelessWidget { textAlign, textDirection, 1.0, - Localizations.localeOf(context, nullOk: true), + Localizations.localeOf(context), strutStyle, TextWidthBasis.parent, null); diff --git a/lib/widgets/text_selection.dart b/lib/widgets/text_selection.dart index 64534c0c..e74318ac 100644 --- a/lib/widgets/text_selection.dart +++ b/lib/widgets/text_selection.dart @@ -199,14 +199,14 @@ class EditorTextSelectionOverlay { showWhenUnlinked: false, offset: -editingRegion.topLeft, child: selectionCtrls.buildToolbar( - context, - editingRegion, - baseLineHeight, - midpoint, - endpoints, - selectionDelegate, - clipboardStatus, - ), + context, + editingRegion, + baseLineHeight, + midpoint, + endpoints, + selectionDelegate, + clipboardStatus, + Offset(0, 0)), ), ); } diff --git a/lib/widgets/toolbar.dart b/lib/widgets/toolbar.dart index 6818803a..1f54bd79 100644 --- a/lib/widgets/toolbar.dart +++ b/lib/widgets/toolbar.dart @@ -446,7 +446,13 @@ Widget _selectHeadingStyleButtonBuilder( height: iconSize * 1.77, fillColor: Theme.of(context).canvasColor, child: Text( - _valueToText[value], + _valueToText[value.key == "header" + ? Attribute.header + : (value.key == "h1") + ? Attribute.h1 + : (value.key == "h2") + ? Attribute.h2 + : Attribute.h3], style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600), ), initialValue: value, diff --git a/pubspec.lock b/pubspec.lock index 02cc03c0..10c6a87a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,49 +7,49 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0-nullsafety.3" + version: "2.5.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.5" + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0" collection: dependency: "direct main" description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0-nullsafety.5" + version: "1.15.0" fake_async: dependency: transitive description: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0" flutter: dependency: "direct main" description: flutter @@ -113,28 +113,28 @@ packages: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.3-nullsafety.3" + version: "0.6.3" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10-nullsafety.3" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.6" + version: "1.3.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.3" + version: "1.8.0" pedantic: dependency: transitive description: @@ -188,42 +188,42 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.4" + version: "1.8.0" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.6" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19-nullsafety.6" + version: "0.2.19" tuple: dependency: "direct main" description: @@ -237,7 +237,7 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.5" + version: "1.3.0" url_launcher: dependency: "direct main" description: @@ -286,7 +286,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.5" + version: "2.1.0" sdks: dart: ">=2.12.0-0.0 <3.0.0" flutter: ">=1.22.0" From e287043b5df40ca2287dcfd138e0ed61b54a4e2a Mon Sep 17 00:00:00 2001 From: rish07 Date: Wed, 10 Feb 2021 16:27:07 +0530 Subject: [PATCH 2/2] Added keyboard shortcut with ctrl+b --- README.md | 64 ++++++++++++++++++++---------------- app/lib/pages/home_page.dart | 21 +++++++++++- lib/widgets/editor.dart | 15 +++++---- lib/widgets/toolbar.dart | 17 ++++++---- 4 files changed, 75 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index ca463e9e..e123d18e 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,37 @@ - -# FlutterQuill - -Rich text editor and a [Quill] component for [Flutter]. - -https://pub.dev/packages/flutter_quill - -This library is a WYSIWYG editor built for the modern mobile platform only and web is not supported. -For web development, [ReactQuill] is recommended to use for compatibility. - ---- - -1 -1 -1 -1 - -One client and affiliated collaborator of **[FlutterQuill]** is Bullet Journal App: https://bulletjournal.us/home/index.html - -You can also join [Slack Group] for discussion. - -[Quill]: https://quilljs.com -[Flutter]: https://github.com/flutter/flutter -[FlutterQuill]: https://pub.dev/packages/flutter_quill -[ReactQuill]: https://github.com/zenoamaro/react-quill -[Slack Group]: https://join.slack.com/t/bulletjournal1024/shared_invite/zt-fys7t9hi-ITVU5PGDen1rNRyCjdcQ2g + + +# FlutterQuill + +Rich text editor and a [Quill] component for [Flutter]. + +https://pub.dev/packages/flutter_quill + +This library is a WYSIWYG editor built for the modern mobile platform only and web is under development. + +To run the app on web do the following: +1) Change flutter channel to master using `flutter channel master`, followed by `flutter upgrade`. +2) Enable web using `flutter config --enable-web` and restart the IDE. +3) Upon successful execution of step 1 and 2 you should see `Chrome` as one of the devices which you run `flutter devices`. +4) Run the app. + +For web development, [ReactQuill] is recommended to use for compatibility. + +--- + +1 +1 +1 +1 + +One client and affiliated collaborator of **[FlutterQuill]** is Bullet Journal App: https://bulletjournal.us/home/index.html + +You can also join [Slack Group] for discussion. + +[Quill]: https://quilljs.com +[Flutter]: https://github.com/flutter/flutter +[FlutterQuill]: https://pub.dev/packages/flutter_quill +[ReactQuill]: https://github.com/zenoamaro/react-quill +[Slack Group]: https://join.slack.com/t/bulletjournal1024/shared_invite/zt-fys7t9hi-ITVU5PGDen1rNRyCjdcQ2g \ No newline at end of file diff --git a/app/lib/pages/home_page.dart b/app/lib/pages/home_page.dart index f251e7b8..3663543f 100644 --- a/app/lib/pages/home_page.dart +++ b/app/lib/pages/home_page.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_quill/models/documents/attribute.dart'; import 'package:flutter_quill/models/documents/document.dart'; import 'package:flutter_quill/widgets/controller.dart'; import 'package:flutter_quill/widgets/default_styles.dart'; @@ -65,7 +66,25 @@ class _HomePageState extends State { color: Colors.grey.shade800, child: _buildMenuBar(context), ), - body: _buildWelcomeEditor(context), + body: RawKeyboardListener( + focusNode: FocusNode(), + onKey: (RawKeyEvent event) { + if (event.data.isControlPressed && event.character == 'b') { + if (_controller + .getSelectionStyle() + .attributes + .keys + .contains("bold")) { + _controller + .formatSelection(Attribute.clone(Attribute.bold, null)); + } else { + _controller.formatSelection(Attribute.bold); + print("not bold"); + } + } + }, + child: _buildWelcomeEditor(context), + ), ); } diff --git a/lib/widgets/editor.dart b/lib/widgets/editor.dart index b02f97eb..dd9784d2 100644 --- a/lib/widgets/editor.dart +++ b/lib/widgets/editor.dart @@ -76,12 +76,15 @@ abstract class RenderAbstractEditor { Widget _defaultEmbedBuilder(BuildContext context, leaf.Embed node) { switch (node.value.type) { case 'image': - final style = QuillStyles.getStyles(context, true); - return Divider( - height: style.paragraph.style.fontSize * style.paragraph.style.height, - thickness: 2, - color: Colors.grey.shade200, - ); + if (kIsWeb) { + return SizedBox.shrink(); + } else { + String imageUrl = node.value.data; + return imageUrl.startsWith('http') + ? Image.network(imageUrl) + : Image.asset(imageUrl); + } + break; default: throw UnimplementedError( diff --git a/lib/widgets/toolbar.dart b/lib/widgets/toolbar.dart index 1f54bd79..69de725a 100644 --- a/lib/widgets/toolbar.dart +++ b/lib/widgets/toolbar.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_colorpicker/flutter_colorpicker.dart'; import 'package:flutter_quill/models/documents/attribute.dart'; @@ -446,13 +447,15 @@ Widget _selectHeadingStyleButtonBuilder( height: iconSize * 1.77, fillColor: Theme.of(context).canvasColor, child: Text( - _valueToText[value.key == "header" - ? Attribute.header - : (value.key == "h1") - ? Attribute.h1 - : (value.key == "h2") - ? Attribute.h2 - : Attribute.h3], + !kIsWeb + ? _valueToText[value] + : _valueToText[value.key == "header" + ? Attribute.header + : (value.key == "h1") + ? Attribute.h1 + : (value.key == "h2") + ? Attribute.h2 + : Attribute.h3], style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600), ), initialValue: value,