From 3e9ab4bd4d56a5599c7cd07e3e4fd108e4034eee Mon Sep 17 00:00:00 2001 From: X Code Date: Sun, 29 Oct 2023 13:21:35 -0700 Subject: [PATCH 001/210] Create publish.yml --- .github/workflows/publish.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..b51a07c7 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,12 @@ +name: Publish to pub.dev + +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+*' + +jobs: + publish: + uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 + # with: + # working-directory: path/to/package/within/repository From f7528d30a016ab30c1be74275ac4bf720e7820b7 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Tue, 31 Oct 2023 21:55:40 +0300 Subject: [PATCH 002/210] Code cleanup and fixes (#1486) --- .github/ISSUE_TEMPLATE/issue-template.md | 10 +- CHANGELOG.md | 6 + lib/src/models/config/others/animations.dart | 6 +- .../config/toolbar/buttons/link_style2.dart | 63 ++++++ .../toolbar/buttons/select_alignment.dart | 2 + .../toolbar/buttons/select_header_style.dart | 17 +- .../models/config/toolbar/configurations.dart | 12 +- lib/src/models/documents/nodes/block.dart | 2 +- lib/src/models/documents/nodes/container.dart | 2 +- lib/src/models/documents/nodes/leaf.dart | 6 +- lib/src/models/documents/nodes/line.dart | 2 +- lib/src/models/documents/nodes/node.dart | 4 +- lib/src/models/rules/insert.dart | 14 +- lib/src/test/widget_tester_extension.dart | 8 +- lib/src/utils/delta.dart | 15 +- lib/src/utils/experimental.dart | 7 - lib/src/utils/string.dart | 14 -- lib/src/widgets/controller.dart | 22 ++- lib/src/widgets/cursor.dart | 6 +- lib/src/widgets/default_styles.dart | 129 +++++++----- lib/src/widgets/delegate.dart | 53 ++--- lib/src/widgets/editor/editor.dart | 7 +- lib/src/widgets/embeds.dart | 9 +- lib/src/widgets/keyboard_listener.dart | 5 +- lib/src/widgets/proxy.dart | 8 +- .../quill_single_child_scroll_view.dart | 9 +- lib/src/widgets/raw_editor/raw_editor.dart | 15 +- .../widgets/style_widgets/bullet_point.dart | 4 +- .../widgets/style_widgets/checkbox_point.dart | 9 +- .../widgets/style_widgets/number_point.dart | 8 +- lib/src/widgets/text_block.dart | 84 +++++--- lib/src/widgets/text_line.dart | 160 +++++++++------ lib/src/widgets/text_selection.dart | 6 +- .../toolbar/buttons/arrow_indicated_list.dart | 4 +- .../widgets/toolbar/buttons/link_style.dart | 18 +- .../widgets/toolbar/buttons/link_style2.dart | 186 ++++++++++-------- .../toolbar/buttons/select_alignment.dart | 64 +++--- .../toolbar/buttons/select_header_style.dart | 52 +++-- lib/src/widgets/toolbar/toolbar.dart | 162 ++++++++++----- pubspec.yaml | 6 +- test/bug_fix_test.dart | 2 +- 41 files changed, 772 insertions(+), 446 deletions(-) create mode 100644 lib/src/models/config/toolbar/buttons/link_style2.dart delete mode 100644 lib/src/utils/experimental.dart diff --git a/.github/ISSUE_TEMPLATE/issue-template.md b/.github/ISSUE_TEMPLATE/issue-template.md index c8a389aa..cd6b26f9 100644 --- a/.github/ISSUE_TEMPLATE/issue-template.md +++ b/.github/ISSUE_TEMPLATE/issue-template.md @@ -1,20 +1,16 @@ --- name: Issue template about: Common things to fill -title: "[Web] or [Mobile] or [Desktop]" +title: "Issue in [Mobile, Desktop, Web]" labels: '' assignees: '' --- -My issue is about [Web] -My issue is about [Mobile] -My issue is about [Desktop] - -I have tried running `example` directory successfully before creating an issue here. - Please note that we are using latest flutter version in stable channel on branch master. If you are using beta or master channel, or you are not using latest flutter version in stable channel, you may experience error. + + diff --git a/CHANGELOG.md b/CHANGELOG.md index 5776f039..f406c647 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [8.1.2] +- Fix bug that is related to the regexp of the insert link dialog +- Require dart 3 as minimum +- Code cleanup +- Add spacer widget between each button in the `QuillToolbar` + ## [8.1.1] - Fix null error in line.dart [#1487](https://github.com/singerdmx/flutter-quill/issues/1487) diff --git a/lib/src/models/config/others/animations.dart b/lib/src/models/config/others/animations.dart index 829442c5..ce6bcb0c 100644 --- a/lib/src/models/config/others/animations.dart +++ b/lib/src/models/config/others/animations.dart @@ -1,10 +1,8 @@ import 'package:equatable/equatable.dart'; -import 'package:flutter/foundation.dart' show immutable; - -import '../../../utils/experimental.dart'; +import 'package:meta/meta.dart' show experimental, immutable; @immutable -@Experimental('This class might removed') +@experimental class QuillAnimationConfigurations extends Equatable { const QuillAnimationConfigurations({ required this.checkBoxPointItem, diff --git a/lib/src/models/config/toolbar/buttons/link_style2.dart b/lib/src/models/config/toolbar/buttons/link_style2.dart new file mode 100644 index 00000000..d42eec96 --- /dev/null +++ b/lib/src/models/config/toolbar/buttons/link_style2.dart @@ -0,0 +1,63 @@ +import 'package:flutter/widgets.dart'; + +import '../../../themes/quill_dialog_theme.dart'; +import 'base.dart'; + +class QuillToolbarLinkStyleButton2ExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarLinkStyleButton2ExtraOptions({ + required super.controller, + required super.context, + required super.onPressed, + }); +} + +class QuillToolbarLinkStyleButton2Options extends QuillToolbarBaseButtonOptions< + QuillToolbarLinkStyleButton2Options, + QuillToolbarLinkStyleButton2ExtraOptions> { + const QuillToolbarLinkStyleButton2Options({ + this.iconSize, + this.dialogTheme, + this.constraints, + this.addLinkLabel, + this.editLinkLabel, + this.linkColor, + this.validationMessage, + this.buttonSize, + this.dialogBarrierColor, + this.childrenSpacing = 16.0, + this.autovalidateMode = AutovalidateMode.disabled, + super.iconData, + super.afterButtonPressed, + super.tooltip, + super.iconTheme, + super.childBuilder, + super.controller, + }); + + final double? iconSize; + final QuillDialogTheme? dialogTheme; + + /// The constrains for dialog. + final BoxConstraints? constraints; + + /// The text of label in link add mode. + final String? addLinkLabel; + + /// The text of label in link edit mode. + final String? editLinkLabel; + + /// The color of URL. + final Color? linkColor; + + /// The margin between child widgets in the dialog. + final double childrenSpacing; + + final AutovalidateMode autovalidateMode; + final String? validationMessage; + + /// The size of dialog buttons. + final Size? buttonSize; + + final Color? dialogBarrierColor; +} diff --git a/lib/src/models/config/toolbar/buttons/select_alignment.dart b/lib/src/models/config/toolbar/buttons/select_alignment.dart index 3bbef892..19bb21bd 100644 --- a/lib/src/models/config/toolbar/buttons/select_alignment.dart +++ b/lib/src/models/config/toolbar/buttons/select_alignment.dart @@ -19,6 +19,8 @@ class QuillToolbarSelectAlignmentButtonOptions this.tooltips, this.iconSize, super.afterButtonPressed, + + /// This will called on every select alignment button super.childBuilder, super.controller, super.iconTheme, diff --git a/lib/src/models/config/toolbar/buttons/select_header_style.dart b/lib/src/models/config/toolbar/buttons/select_header_style.dart index 1145afaf..fd4298b7 100644 --- a/lib/src/models/config/toolbar/buttons/select_header_style.dart +++ b/lib/src/models/config/toolbar/buttons/select_header_style.dart @@ -20,20 +20,21 @@ class QuillToolbarSelectHeaderStyleButtonsOptions super.afterButtonPressed, super.childBuilder, super.controller, - super.iconData, super.iconTheme, super.tooltip, this.axis, - this.attributes = const [ - Attribute.header, - Attribute.h1, - Attribute.h2, - Attribute.h3, - ], + this.attributes, this.iconSize, }); - final List attributes; + /// Default value: + /// const [ + /// Attribute.header, + /// Attribute.h1, + /// Attribute.h2, + /// Attribute.h3, + /// ] + final List? attributes; /// By default we will the toolbar axis from [QuillToolbarConfigurations] final Axis? axis; diff --git a/lib/src/models/config/toolbar/configurations.dart b/lib/src/models/config/toolbar/configurations.dart index 533ac8fb..00412042 100644 --- a/lib/src/models/config/toolbar/configurations.dart +++ b/lib/src/models/config/toolbar/configurations.dart @@ -1,7 +1,7 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' - show Axis, Color, Decoration, WrapAlignment, WrapCrossAlignment; + show Axis, Color, Decoration, Widget, WrapAlignment, WrapCrossAlignment; import '../../../widgets/embeds.dart'; import '../../structs/link_dialog_action.dart'; @@ -107,6 +107,7 @@ class QuillToolbarConfigurations extends Equatable { this.color, this.sectionDividerColor, this.sectionDividerSpace, + this.spacerWidget, /// By default it will calculated based on the [globalIconSize] from /// [base] in [QuillToolbarButtonOptions] @@ -130,6 +131,15 @@ class QuillToolbarConfigurations extends Equatable { /// If you want change spesefic buttons or all of them /// then you came to the right place final QuillToolbarButtonOptions buttonOptions; + + /// A widget that will placed between each button in the toolbar + /// can be used as a spacer + /// it will not used before the first button + /// it will not used after the last button + /// it will also not used in the toolbar dividers + /// Default value will be [SizedBox.shrink()] + /// some widgets like the header styles will be considered as one widget + final Widget? spacerWidget; final bool multiRowsDisplay; /// By default it will be diff --git a/lib/src/models/documents/nodes/block.dart b/lib/src/models/documents/nodes/block.dart index ed5a4c75..886ad392 100644 --- a/lib/src/models/documents/nodes/block.dart +++ b/lib/src/models/documents/nodes/block.dart @@ -13,7 +13,7 @@ import 'node.dart'; /// - Text Alignment /// - Text Direction /// - Code Block -class Block extends Container { +base class Block extends Container { /// Creates new unmounted [Block]. @override Node newInstance() => Block(); diff --git a/lib/src/models/documents/nodes/container.dart b/lib/src/models/documents/nodes/container.dart index f061a4ca..47bc37e4 100644 --- a/lib/src/models/documents/nodes/container.dart +++ b/lib/src/models/documents/nodes/container.dart @@ -14,7 +14,7 @@ import 'node.dart'; /// /// Most of the operation handling logic is implemented by [Line] /// and [QuillText]. -abstract class Container extends Node { +abstract base class Container extends Node { final LinkedList _children = LinkedList(); /// List of children. diff --git a/lib/src/models/documents/nodes/leaf.dart b/lib/src/models/documents/nodes/leaf.dart index 8bf78462..8ae3be36 100644 --- a/lib/src/models/documents/nodes/leaf.dart +++ b/lib/src/models/documents/nodes/leaf.dart @@ -8,7 +8,7 @@ import 'line.dart'; import 'node.dart'; /// A leaf in Quill document tree. -abstract class Leaf extends Node { +abstract base class Leaf extends Node { /// Creates a new [Leaf] with specified [data]. factory Leaf(Object data) { if (data is Embeddable) { @@ -216,7 +216,7 @@ abstract class Leaf extends Node { /// The reason we are renamed quill Text to [QuillText] so it doesn't /// conflict with the one from the widgets, material or cupertino library /// -class QuillText extends Leaf { +base class QuillText extends Leaf { QuillText([String text = '']) : assert(!text.contains('\n')), super.val(text); @@ -249,7 +249,7 @@ class QuillText extends Leaf { /// necessarily mean the embed will look according to that style. For instance, /// applying "bold" style to an image gives no effect, while adding a "link" to /// an image actually makes the image react to user's action. -class Embed extends Leaf { +base class Embed extends Leaf { Embed(Embeddable data) : super.val(data); // Refer to https://www.fileformat.info/info/unicode/char/fffc/index.htm diff --git a/lib/src/models/documents/nodes/line.dart b/lib/src/models/documents/nodes/line.dart index 58ba9cc6..4a0c8c71 100644 --- a/lib/src/models/documents/nodes/line.dart +++ b/lib/src/models/documents/nodes/line.dart @@ -19,7 +19,7 @@ import 'node.dart'; /// /// When a line contains an embed, it fully occupies the line, no other embeds /// or text nodes are allowed. -class Line extends Container { +base class Line extends Container { @override Leaf get defaultChild => QuillText(); diff --git a/lib/src/models/documents/nodes/node.dart b/lib/src/models/documents/nodes/node.dart index 098f1241..bb6a1c59 100644 --- a/lib/src/models/documents/nodes/node.dart +++ b/lib/src/models/documents/nodes/node.dart @@ -17,7 +17,7 @@ import 'line.dart'; /// /// The current parent node is exposed by the [parent] property. A node is /// considered [mounted] when the [parent] property is not `null`. -abstract class Node extends LinkedListEntry { +abstract base class Node extends LinkedListEntry { /// Current parent of this node. May be null if this node is not mounted. Container? parent; @@ -127,7 +127,7 @@ abstract class Node extends LinkedListEntry { } /// Root node of document tree. -class Root extends Container> { +base class Root extends Container> { @override Node newInstance() => Root(); diff --git a/lib/src/models/rules/insert.dart b/lib/src/models/rules/insert.dart index 92fc461e..8f1c1dea 100644 --- a/lib/src/models/rules/insert.dart +++ b/lib/src/models/rules/insert.dart @@ -358,14 +358,14 @@ class AutoFormatMultipleLinksRule extends InsertRule { // TODO: You might want to rename those but everywhere even in // flutter_quill_extensions - static const _oneLinePattern = + static const _oneLineLinkPattern = r'^https?:\/\/[\w\-]+(\.[\w\-]+)*(:\d+)?(\/.*)?$'; static const _detectLinkPattern = r'https?:\/\/[\w\-]+(\.[\w\-]+)*(:\d+)?(\/[^\s]*)?'; /// It requires a valid link in one link - static final oneLineRegExp = RegExp( - _oneLinePattern, + static final oneLineLinkRegExp = RegExp( + _oneLineLinkPattern, caseSensitive: false, ); @@ -375,10 +375,10 @@ class AutoFormatMultipleLinksRule extends InsertRule { _detectLinkPattern, caseSensitive: false, ); - @Deprecated( - 'Please use [linkRegExp1] or [linkRegExp2]', - ) - static final linkRegExp = oneLineRegExp; + // @Deprecated( + // 'Please use [linkRegExp1] or [linkRegExp2]', + // ) + static final linkRegExp = oneLineLinkRegExp; @override Delta? applyRule( diff --git a/lib/src/test/widget_tester_extension.dart b/lib/src/test/widget_tester_extension.dart index 85cc4500..ab811fdc 100644 --- a/lib/src/test/widget_tester_extension.dart +++ b/lib/src/test/widget_tester_extension.dart @@ -11,10 +11,10 @@ extension QuillEnterText on WidgetTester { return TestAsyncUtils.guard(() async { final editor = state( find.descendant( - of: finder, - matching: - find.byType(QuillEditor, skipOffstage: finder.skipOffstage), - matchRoot: true), + of: finder, + matching: find.byType(QuillEditor, skipOffstage: finder.skipOffstage), + matchRoot: true, + ), ); editor.widget.focusNode.requestFocus(); await pump(); diff --git a/lib/src/utils/delta.dart b/lib/src/utils/delta.dart index c737e1ac..7ef44a2d 100644 --- a/lib/src/utils/delta.dart +++ b/lib/src/utils/delta.dart @@ -1,13 +1,20 @@ import 'dart:math' as math; import 'dart:ui'; +import 'package:meta/meta.dart' show immutable; + import '../models/documents/attribute.dart'; import '../models/documents/nodes/node.dart'; import '../models/quill_delta.dart'; // Diff between two texts - old text and new text +@immutable class Diff { - Diff(this.start, this.deleted, this.inserted); + const Diff({ + required this.start, + required this.deleted, + required this.inserted, + }); // Start index in old text at which changes begin. final int start; @@ -37,7 +44,11 @@ Diff getDiff(String oldText, String newText, int cursorPosition) { start++) {} final deleted = (start >= end) ? '' : oldText.substring(start, end); final inserted = newText.substring(start, end + delta); - return Diff(start, deleted, inserted); + return Diff( + start: start, + deleted: deleted, + inserted: inserted, + ); } int getPositionDelta(Delta user, Delta actual) { diff --git a/lib/src/utils/experimental.dart b/lib/src/utils/experimental.dart deleted file mode 100644 index 8f24e87e..00000000 --- a/lib/src/utils/experimental.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter/foundation.dart' show immutable; - -@immutable -class Experimental { - const Experimental([this.reason = 'Experimental feature']); - final String reason; -} diff --git a/lib/src/utils/string.dart b/lib/src/utils/string.dart index f639c716..3de84e65 100644 --- a/lib/src/utils/string.dart +++ b/lib/src/utils/string.dart @@ -19,20 +19,6 @@ Map parseKeyValuePairs(String s, Set targetKeys) { return result; } -@Deprecated('Use replaceStyleStringWithSize instead') -String replaceStyleString( - String s, - double width, - double height, -) { - return replaceStyleStringWithSize( - s, - width: width, - height: height, - isMobile: true, - ); -} - String replaceStyleStringWithSize( String s, { required double width, diff --git a/lib/src/widgets/controller.dart b/lib/src/widgets/controller.dart index 242faa55..fbfc77f0 100644 --- a/lib/src/widgets/controller.dart +++ b/lib/src/widgets/controller.dart @@ -333,18 +333,23 @@ class QuillController extends ChangeNotifier { void moveCursorToStart() { updateSelection( - const TextSelection.collapsed(offset: 0), ChangeSource.LOCAL); + const TextSelection.collapsed(offset: 0), + ChangeSource.LOCAL, + ); } void moveCursorToPosition(int position) { updateSelection( - TextSelection.collapsed(offset: position), ChangeSource.LOCAL); + TextSelection.collapsed(offset: position), + ChangeSource.LOCAL, + ); } void moveCursorToEnd() { updateSelection( - TextSelection.collapsed(offset: plainTextEditingValue.text.length), - ChangeSource.LOCAL); + TextSelection.collapsed(offset: plainTextEditingValue.text.length), + ChangeSource.LOCAL, + ); } void updateSelection(TextSelection textSelection, ChangeSource source) { @@ -358,9 +363,12 @@ class QuillController extends ChangeNotifier { } textSelection = selection.copyWith( - baseOffset: delta.transformPosition(selection.baseOffset, force: false), - extentOffset: - delta.transformPosition(selection.extentOffset, force: false)); + baseOffset: delta.transformPosition(selection.baseOffset, force: false), + extentOffset: delta.transformPosition( + selection.extentOffset, + force: false, + ), + ); if (selection != textSelection) { _updateSelection(textSelection, source); } diff --git a/lib/src/widgets/cursor.dart b/lib/src/widgets/cursor.dart index de2dbb5f..293b2ec6 100644 --- a/lib/src/widgets/cursor.dart +++ b/lib/src/widgets/cursor.dart @@ -257,7 +257,11 @@ class CursorPainter { /// [offset] is global top left (x, y) of text line /// [position] is relative (x) in text line void paint( - Canvas canvas, Offset offset, TextPosition position, bool lineHasEmbed) { + Canvas canvas, + Offset offset, + TextPosition position, + bool lineHasEmbed, + ) { // relative (x, y) to global offset var relativeCaretOffset = editable!.getOffsetForCaret(position, prototype); if (lineHasEmbed && relativeCaretOffset == Offset.zero) { diff --git a/lib/src/widgets/default_styles.dart b/lib/src/widgets/default_styles.dart index d600b71d..dded6d08 100644 --- a/lib/src/widgets/default_styles.dart +++ b/lib/src/widgets/default_styles.dart @@ -240,22 +240,30 @@ class DefaultStyles { const VerticalSpacing(0, 0), null), h3: DefaultTextBlockStyle( - defaultTextStyle.style.copyWith( - fontSize: 20, - color: defaultTextStyle.style.color!.withOpacity(0.70), - height: 1.25, - fontWeight: FontWeight.w500, - decoration: TextDecoration.none, - ), - const VerticalSpacing(8, 0), - const VerticalSpacing(0, 0), - null), + defaultTextStyle.style.copyWith( + fontSize: 20, + color: defaultTextStyle.style.color!.withOpacity(0.70), + height: 1.25, + fontWeight: FontWeight.w500, + decoration: TextDecoration.none, + ), + const VerticalSpacing(8, 0), + const VerticalSpacing(0, 0), + null, + ), paragraph: DefaultTextBlockStyle(baseStyle, const VerticalSpacing(0, 0), const VerticalSpacing(0, 0), null), bold: const TextStyle(fontWeight: FontWeight.bold), - subscript: const TextStyle(fontFeatures: [FontFeature.subscripts()]), - superscript: - const TextStyle(fontFeatures: [FontFeature.superscripts()]), + subscript: const TextStyle( + fontFeatures: [ + FontFeature.subscripts(), + ], + ), + superscript: const TextStyle( + fontFeatures: [ + FontFeature.superscripts(), + ], + ), italic: const TextStyle(fontStyle: FontStyle.italic), small: const TextStyle(fontSize: 12), underline: const TextStyle(decoration: TextDecoration.underline), @@ -288,16 +296,22 @@ class DefaultStyles { const VerticalSpacing(0, 0), null), lists: DefaultListBlockStyle( - baseStyle, baseSpacing, const VerticalSpacing(0, 6), null, null), + baseStyle, + baseSpacing, + const VerticalSpacing(0, 6), + null, + null, + ), quote: DefaultTextBlockStyle( - TextStyle(color: baseStyle.color!.withOpacity(0.6)), - baseSpacing, - const VerticalSpacing(6, 2), - BoxDecoration( - border: Border( - left: BorderSide(width: 4, color: Colors.grey.shade300), - ), - )), + TextStyle(color: baseStyle.color!.withOpacity(0.6)), + baseSpacing, + const VerticalSpacing(6, 2), + BoxDecoration( + border: Border( + left: BorderSide(width: 4, color: Colors.grey.shade300), + ), + ), + ), code: DefaultTextBlockStyle( TextStyle( color: Colors.blue.shade900.withOpacity(0.9), @@ -312,11 +326,23 @@ class DefaultStyles { borderRadius: BorderRadius.circular(2), )), indent: DefaultTextBlockStyle( - baseStyle, baseSpacing, const VerticalSpacing(0, 6), null), - align: DefaultTextBlockStyle(baseStyle, const VerticalSpacing(0, 0), - const VerticalSpacing(0, 0), null), - leading: DefaultTextBlockStyle(baseStyle, const VerticalSpacing(0, 0), - const VerticalSpacing(0, 0), null), + baseStyle, + baseSpacing, + const VerticalSpacing(0, 6), + null, + ), + align: DefaultTextBlockStyle( + baseStyle, + const VerticalSpacing(0, 0), + const VerticalSpacing(0, 0), + null, + ), + leading: DefaultTextBlockStyle( + baseStyle, + const VerticalSpacing(0, 0), + const VerticalSpacing(0, 0), + null, + ), sizeSmall: const TextStyle(fontSize: 10), sizeLarge: const TextStyle(fontSize: 18), sizeHuge: const TextStyle(fontSize: 22)); @@ -324,29 +350,30 @@ class DefaultStyles { DefaultStyles merge(DefaultStyles other) { return DefaultStyles( - h1: other.h1 ?? h1, - h2: other.h2 ?? h2, - h3: other.h3 ?? h3, - paragraph: other.paragraph ?? paragraph, - bold: other.bold ?? bold, - subscript: other.subscript ?? subscript, - superscript: other.superscript ?? superscript, - italic: other.italic ?? italic, - small: other.small ?? small, - underline: other.underline ?? underline, - strikeThrough: other.strikeThrough ?? strikeThrough, - inlineCode: other.inlineCode ?? inlineCode, - link: other.link ?? link, - color: other.color ?? color, - placeHolder: other.placeHolder ?? placeHolder, - lists: other.lists ?? lists, - quote: other.quote ?? quote, - code: other.code ?? code, - indent: other.indent ?? indent, - align: other.align ?? align, - leading: other.leading ?? leading, - sizeSmall: other.sizeSmall ?? sizeSmall, - sizeLarge: other.sizeLarge ?? sizeLarge, - sizeHuge: other.sizeHuge ?? sizeHuge); + h1: other.h1 ?? h1, + h2: other.h2 ?? h2, + h3: other.h3 ?? h3, + paragraph: other.paragraph ?? paragraph, + bold: other.bold ?? bold, + subscript: other.subscript ?? subscript, + superscript: other.superscript ?? superscript, + italic: other.italic ?? italic, + small: other.small ?? small, + underline: other.underline ?? underline, + strikeThrough: other.strikeThrough ?? strikeThrough, + inlineCode: other.inlineCode ?? inlineCode, + link: other.link ?? link, + color: other.color ?? color, + placeHolder: other.placeHolder ?? placeHolder, + lists: other.lists ?? lists, + quote: other.quote ?? quote, + code: other.code ?? code, + indent: other.indent ?? indent, + align: other.align ?? align, + leading: other.leading ?? leading, + sizeSmall: other.sizeSmall ?? sizeSmall, + sizeLarge: other.sizeLarge ?? sizeLarge, + sizeHuge: other.sizeHuge ?? sizeHuge, + ); } } diff --git a/lib/src/widgets/delegate.dart b/lib/src/widgets/delegate.dart index c196a5d3..f595beff 100644 --- a/lib/src/widgets/delegate.dart +++ b/lib/src/widgets/delegate.dart @@ -314,8 +314,10 @@ class EditorTextSelectionGestureDetectorBuilder { void onDragSelectionUpdate( //DragStartDetails startDetails, DragUpdateDetails updateDetails) { - renderEditor!.extendSelection(updateDetails.globalPosition, - cause: SelectionChangedCause.drag); + renderEditor!.extendSelection( + updateDetails.globalPosition, + cause: SelectionChangedCause.drag, + ); } /// Handler for [EditorTextSelectionGestureDetector.onDragSelectionEnd]. @@ -341,29 +343,30 @@ class EditorTextSelectionGestureDetectorBuilder { /// the handlers provided by this builder. /// /// The [child] or its subtree should contain [EditableText]. - Widget build( - {required HitTestBehavior behavior, - required Widget child, - Key? key, - bool detectWordBoundary = true}) { + Widget build({ + required HitTestBehavior behavior, + required Widget child, + Key? key, + bool detectWordBoundary = true, + }) { return EditorTextSelectionGestureDetector( - key: key, - onTapDown: onTapDown, - onForcePressStart: - delegate.forcePressEnabled ? onForcePressStart : null, - onForcePressEnd: delegate.forcePressEnabled ? onForcePressEnd : null, - onSingleTapUp: onSingleTapUp, - onSingleTapCancel: onSingleTapCancel, - onSingleLongTapStart: onSingleLongTapStart, - onSingleLongTapMoveUpdate: onSingleLongTapMoveUpdate, - onSingleLongTapEnd: onSingleLongTapEnd, - onDoubleTapDown: onDoubleTapDown, - onSecondarySingleTapUp: onSecondarySingleTapUp, - onDragSelectionStart: onDragSelectionStart, - onDragSelectionUpdate: onDragSelectionUpdate, - onDragSelectionEnd: onDragSelectionEnd, - behavior: behavior, - detectWordBoundary: detectWordBoundary, - child: child); + key: key, + onTapDown: onTapDown, + onForcePressStart: delegate.forcePressEnabled ? onForcePressStart : null, + onForcePressEnd: delegate.forcePressEnabled ? onForcePressEnd : null, + onSingleTapUp: onSingleTapUp, + onSingleTapCancel: onSingleTapCancel, + onSingleLongTapStart: onSingleLongTapStart, + onSingleLongTapMoveUpdate: onSingleLongTapMoveUpdate, + onSingleLongTapEnd: onSingleLongTapEnd, + onDoubleTapDown: onDoubleTapDown, + onSecondarySingleTapUp: onSecondarySingleTapUp, + onDragSelectionStart: onDragSelectionStart, + onDragSelectionUpdate: onDragSelectionUpdate, + onDragSelectionEnd: onDragSelectionEnd, + behavior: behavior, + detectWordBoundary: detectWordBoundary, + child: child, + ); } } diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index 766ad8aa..3c25cdb4 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -1,10 +1,5 @@ import 'dart:math' as math; -// ignore: unnecessary_import -// import 'dart:typed_data'; -// The project maanged to compiled successfully without the import -// do we still need this import (dart:typed_data)?? - import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; @@ -1495,7 +1490,7 @@ class RenderEditor extends RenderEditableContainerBox } } -class QuillVerticalCaretMovementRun extends Iterator { +class QuillVerticalCaretMovementRun implements Iterator { QuillVerticalCaretMovementRun._( this._editor, this._currentTextPosition, diff --git a/lib/src/widgets/embeds.dart b/lib/src/widgets/embeds.dart index 11d34b87..87511204 100644 --- a/lib/src/widgets/embeds.dart +++ b/lib/src/widgets/embeds.dart @@ -29,7 +29,8 @@ abstract class EmbedBuilder { } typedef EmbedButtonBuilder = Widget Function( - QuillController controller, - double toolbarIconSize, - QuillIconTheme? iconTheme, - QuillDialogTheme? dialogTheme); + QuillController controller, + double toolbarIconSize, + QuillIconTheme? iconTheme, + QuillDialogTheme? dialogTheme, +); diff --git a/lib/src/widgets/keyboard_listener.dart b/lib/src/widgets/keyboard_listener.dart index 47cb9555..ee1e3d11 100644 --- a/lib/src/widgets/keyboard_listener.dart +++ b/lib/src/widgets/keyboard_listener.dart @@ -44,8 +44,9 @@ class QuillKeyboardListenerState extends State { final QuillPressedKeys _pressedKeys = QuillPressedKeys(); bool _keyEvent(KeyEvent event) { - _pressedKeys - ._updatePressedKeys(HardwareKeyboard.instance.logicalKeysPressed); + _pressedKeys._updatePressedKeys( + HardwareKeyboard.instance.logicalKeysPressed, + ); return false; } diff --git a/lib/src/widgets/proxy.dart b/lib/src/widgets/proxy.dart index 155e620a..2379c883 100644 --- a/lib/src/widgets/proxy.dart +++ b/lib/src/widgets/proxy.dart @@ -6,8 +6,12 @@ import 'package:flutter/widgets.dart'; import 'box.dart'; class BaselineProxy extends SingleChildRenderObjectWidget { - const BaselineProxy({Key? key, Widget? child, this.textStyle, this.padding}) - : super(key: key, child: child); + const BaselineProxy({ + Key? key, + Widget? child, + this.textStyle, + this.padding, + }) : super(key: key, child: child); final TextStyle? textStyle; final EdgeInsets? padding; diff --git a/lib/src/widgets/quill_single_child_scroll_view.dart b/lib/src/widgets/quill_single_child_scroll_view.dart index 40971b06..ba6c0371 100644 --- a/lib/src/widgets/quill_single_child_scroll_view.dart +++ b/lib/src/widgets/quill_single_child_scroll_view.dart @@ -14,10 +14,10 @@ class QuillSingleChildScrollView extends StatelessWidget { const QuillSingleChildScrollView({ required this.controller, required this.viewportBuilder, - Key? key, + super.key, this.physics, this.restorationId, - }) : super(key: key); + }); /// An object that can be used to control the position to which this scroll /// view is scrolled. @@ -48,7 +48,10 @@ class QuillSingleChildScrollView extends StatelessWidget { AxisDirection _getDirection(BuildContext context) { return getAxisDirectionFromAxisReverseAndDirectionality( - context, Axis.vertical, false); + context, + Axis.vertical, + false, + ); } @override diff --git a/lib/src/widgets/raw_editor/raw_editor.dart b/lib/src/widgets/raw_editor/raw_editor.dart index 8e5090f0..28d6c342 100644 --- a/lib/src/widgets/raw_editor/raw_editor.dart +++ b/lib/src/widgets/raw_editor/raw_editor.dart @@ -437,9 +437,6 @@ class RawEditorState extends EditorState // in the web browser, but we do unfocus for all other kinds of events. switch (event.kind) { case ui.PointerDeviceKind.touch: - // if (isWeb()) { - // widget.focusNode.unfocus(); - // } break; case ui.PointerDeviceKind.mouse: case ui.PointerDeviceKind.stylus: @@ -449,7 +446,7 @@ class RawEditorState extends EditorState break; case ui.PointerDeviceKind.trackpad: throw UnimplementedError( - 'Unexpected pointer down event for trackpad', + 'Unexpected pointer down event for trackpad.', ); } break; @@ -461,7 +458,7 @@ class RawEditorState extends EditorState default: throw UnsupportedError( 'The platform ${defaultTargetPlatform.name} is not supported in the' - ' _defaultOnTapOutside', + ' _defaultOnTapOutside()', ); } } @@ -474,8 +471,11 @@ class RawEditorState extends EditorState var _doc = controller.document; if (_doc.isEmpty() && widget.placeholder != null) { final raw = widget.placeholder?.replaceAll(r'"', '\\"'); - _doc = Document.fromJson(jsonDecode( - '[{"attributes":{"placeholder":true},"insert":"$raw\\n"}]')); + _doc = Document.fromJson( + jsonDecode( + '[{"attributes":{"placeholder":true},"insert":"$raw\\n"}]', + ), + ); } Widget child = CompositedTransformTarget( @@ -1435,7 +1435,6 @@ class RawEditorState extends EditorState @override void requestKeyboard() { if (controller.skipRequestKeyboard) { - // TODO: There is a bug, requestKeyboard is being called 2-4 times! // and that just by one simple change controller.skipRequestKeyboard = false; return; diff --git a/lib/src/widgets/style_widgets/bullet_point.dart b/lib/src/widgets/style_widgets/bullet_point.dart index 8b5fce70..f760c992 100644 --- a/lib/src/widgets/style_widgets/bullet_point.dart +++ b/lib/src/widgets/style_widgets/bullet_point.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -class QuillBulletPoint extends StatelessWidget { - const QuillBulletPoint({ +class QuillEditorBulletPoint extends StatelessWidget { + const QuillEditorBulletPoint({ required this.style, required this.width, this.padding = 0, diff --git a/lib/src/widgets/style_widgets/checkbox_point.dart b/lib/src/widgets/style_widgets/checkbox_point.dart index 1276a152..4d87df16 100644 --- a/lib/src/widgets/style_widgets/checkbox_point.dart +++ b/lib/src/widgets/style_widgets/checkbox_point.dart @@ -3,8 +3,8 @@ import 'package:flutter_animate/flutter_animate.dart'; import '../../utils/extensions/build_context.dart'; -class CheckboxPoint extends StatefulWidget { - const CheckboxPoint({ +class QuillEditorCheckboxPoint extends StatefulWidget { + const QuillEditorCheckboxPoint({ required this.size, required this.value, required this.enabled, @@ -20,10 +20,11 @@ class CheckboxPoint extends StatefulWidget { final QuillCheckboxBuilder? uiBuilder; @override - _CheckboxPointState createState() => _CheckboxPointState(); + _QuillEditorCheckboxPointState createState() => + _QuillEditorCheckboxPointState(); } -class _CheckboxPointState extends State { +class _QuillEditorCheckboxPointState extends State { @override Widget build(BuildContext context) { final uiBuilder = widget.uiBuilder; diff --git a/lib/src/widgets/style_widgets/number_point.dart b/lib/src/widgets/style_widgets/number_point.dart index 54d5ebc9..30b5590e 100644 --- a/lib/src/widgets/style_widgets/number_point.dart +++ b/lib/src/widgets/style_widgets/number_point.dart @@ -3,8 +3,8 @@ import 'package:flutter/material.dart'; import '../../models/documents/attribute.dart'; import '../text_block.dart'; -class QuillNumberPoint extends StatelessWidget { - const QuillNumberPoint({ +class QuillEditorNumberPoint extends StatelessWidget { + const QuillEditorNumberPoint({ required this.index, required this.indentLevelCounts, required this.count, @@ -13,8 +13,8 @@ class QuillNumberPoint extends StatelessWidget { required this.attrs, this.withDot = true, this.padding = 0.0, - Key? key, - }) : super(key: key); + super.key, + }); final int index; final Map indentLevelCounts; diff --git a/lib/src/widgets/text_block.dart b/lib/src/widgets/text_block.dart index d10596fe..f99ccbb0 100644 --- a/lib/src/widgets/text_block.dart +++ b/lib/src/widgets/text_block.dart @@ -146,7 +146,13 @@ class EditableTextBlock extends StatelessWidget { index++; final editableTextLine = EditableTextLine( line, - _buildLeading(context, line, index, indentLevelCounts, count), + _buildLeading( + context: context, + line: line, + index: index, + indentLevelCounts: indentLevelCounts, + count: count, + ), TextLine( line: line, textDirection: textDirection, @@ -194,14 +200,19 @@ class EditableTextBlock extends StatelessWidget { } } - Widget? _buildLeading(BuildContext context, Line line, int index, - Map indentLevelCounts, int count) { + Widget? _buildLeading({ + required BuildContext context, + required Line line, + required int index, + required Map indentLevelCounts, + required int count, + }) { final defaultStyles = QuillStyles.getStyles(context, false)!; final fontSize = defaultStyles.paragraph?.style.fontSize ?? 16; final attrs = line.style.attributes; if (attrs[Attribute.list.key] == Attribute.ol) { - return QuillNumberPoint( + return QuillEditorNumberPoint( index: index, indentLevelCounts: indentLevelCounts, count: count, @@ -213,7 +224,7 @@ class EditableTextBlock extends StatelessWidget { } if (attrs[Attribute.list.key] == Attribute.ul) { - return QuillBulletPoint( + return QuillEditorBulletPoint( style: defaultStyles.leading!.style.copyWith(fontWeight: FontWeight.bold), width: fontSize * 2, @@ -223,7 +234,7 @@ class EditableTextBlock extends StatelessWidget { if (attrs[Attribute.list.key] == Attribute.checked || attrs[Attribute.list.key] == Attribute.unchecked) { - return CheckboxPoint( + return QuillEditorCheckboxPoint( size: fontSize, value: attrs[Attribute.list.key] == Attribute.checked, enabled: !readOnly, @@ -233,7 +244,7 @@ class EditableTextBlock extends StatelessWidget { } if (attrs.containsKey(Attribute.codeBlock.key) && context.requireQuillEditorElementOptions.codeBlock.enableLineNumbers) { - return QuillNumberPoint( + return QuillEditorNumberPoint( index: index, indentLevelCounts: indentLevelCounts, count: count, @@ -278,7 +289,11 @@ class EditableTextBlock extends StatelessWidget { } VerticalSpacing _getSpacingForLine( - Line node, int index, int count, DefaultStyles? defaultStyles) { + Line node, + int index, + int count, + DefaultStyles? defaultStyles, + ) { var top = 0.0, bottom = 0.0; final attrs = block.style.attributes; @@ -301,7 +316,7 @@ class EditableTextBlock extends StatelessWidget { throw 'Invalid level $level'; } } else { - late VerticalSpacing lineSpacing; + final VerticalSpacing lineSpacing; if (attrs.containsKey(Attribute.blockQuote.key)) { lineSpacing = defaultStyles!.quote!.lineSpacing; } else if (attrs.containsKey(Attribute.indent.key)) { @@ -500,12 +515,18 @@ class RenderEditableTextBlock extends RenderEditableContainerBox TextSelectionPoint getBaseEndpointForSelection(TextSelection selection) { if (selection.isCollapsed) { return TextSelectionPoint( - Offset(0, preferredLineHeight(selection.extent)) + - getOffsetForCaret(selection.extent), - null); + Offset(0, preferredLineHeight(selection.extent)) + + getOffsetForCaret(selection.extent), + null, + ); } - final baseNode = container.queryChild(selection.start, false).node; + final baseNode = container + .queryChild( + selection.start, + false, + ) + .node; var baseChild = firstChild; while (baseChild != null) { if (baseChild.container == baseNode) { @@ -516,19 +537,26 @@ class RenderEditableTextBlock extends RenderEditableContainerBox assert(baseChild != null); final basePoint = baseChild!.getBaseEndpointForSelection( - localSelection(baseChild.container, selection, true)); + localSelection( + baseChild.container, + selection, + true, + ), + ); return TextSelectionPoint( - basePoint.point + (baseChild.parentData as BoxParentData).offset, - basePoint.direction); + basePoint.point + (baseChild.parentData as BoxParentData).offset, + basePoint.direction, + ); } @override TextSelectionPoint getExtentEndpointForSelection(TextSelection selection) { if (selection.isCollapsed) { return TextSelectionPoint( - Offset(0, preferredLineHeight(selection.extent)) + - getOffsetForCaret(selection.extent), - null); + Offset(0, preferredLineHeight(selection.extent)) + + getOffsetForCaret(selection.extent), + null, + ); } final extentNode = container.queryChild(selection.end, false).node; @@ -543,10 +571,16 @@ class RenderEditableTextBlock extends RenderEditableContainerBox assert(extentChild != null); final extentPoint = extentChild!.getExtentEndpointForSelection( - localSelection(extentChild.container, selection, true)); + localSelection( + extentChild.container, + selection, + true, + ), + ); return TextSelectionPoint( - extentPoint.point + (extentChild.parentData as BoxParentData).offset, - extentPoint.direction); + extentPoint.point + (extentChild.parentData as BoxParentData).offset, + extentPoint.direction, + ); } @override @@ -576,8 +610,10 @@ class RenderEditableTextBlock extends RenderEditableContainerBox offset.translate(decorationPadding.left, decorationPadding.top); _painter!.paint(context.canvas, decorationOffset, filledConfiguration); if (debugSaveCount != context.canvas.getSaveCount()) { - throw '${_decoration.runtimeType} painter had mismatching save and ' - 'restore calls.'; + throw StateError( + '${_decoration.runtimeType} painter had mismatching save and ' + 'restore calls.', + ); } if (decoration.isComplex) { context.setIsComplexHint(); diff --git a/lib/src/widgets/text_line.dart b/lib/src/widgets/text_line.dart index 6dd4f793..8aa88ccb 100644 --- a/lib/src/widgets/text_line.dart +++ b/lib/src/widgets/text_line.dart @@ -43,8 +43,8 @@ class TextLine extends StatefulWidget { this.customStyleBuilder, this.customRecognizerBuilder, this.customLinkPrefixes = const [], - Key? key, - }) : super(key: key); + super.key, + }); final Line line; final TextDirection? textDirection; @@ -88,8 +88,8 @@ class _TextLineState extends State { // In editing mode it depends on the platform: - // Desktop platforms (macos, linux, windows): - // only allow Meta(Control)+Click combinations + // Desktop platforms (macOS, Linux, Windows): + // only allow Meta (Control) + Click combinations if (isDesktop()) { return _metaOrControlPressed; } @@ -581,21 +581,22 @@ class EditableTextLine extends RenderObjectWidget { } } -enum TextLineSlot { LEADING, BODY } +enum TextLineSlot { leading, body } class RenderEditableTextLine extends RenderEditableBox { /// Creates new editable paragraph render box. RenderEditableTextLine( - this.line, - this.textDirection, - this.textSelection, - this.enableInteractiveSelection, - this.hasFocus, - this.devicePixelRatio, - this.padding, - this.color, - this.cursorCont, - this.inlineCodeStyle); + this.line, + this.textDirection, + this.textSelection, + this.enableInteractiveSelection, + this.hasFocus, + this.devicePixelRatio, + this.padding, + this.color, + this.cursorCont, + this.inlineCodeStyle, + ); RenderBox? _leading; RenderContentProxyBox? _body; @@ -715,11 +716,11 @@ class RenderEditableTextLine extends RenderEditableBox { } void setLeading(RenderBox? l) { - _leading = _updateChild(_leading, l, TextLineSlot.LEADING); + _leading = _updateChild(_leading, l, TextLineSlot.leading); } void setBody(RenderContentProxyBox? b) { - _body = _updateChild(_body, b, TextLineSlot.BODY) as RenderContentProxyBox?; + _body = _updateChild(_body, b, TextLineSlot.body) as RenderContentProxyBox?; } void setInlineCodeStyle(InlineCodeStyle newStyle) { @@ -744,7 +745,10 @@ class RenderEditableTextLine extends RenderEditableBox { } RenderBox? _updateChild( - RenderBox? old, RenderBox? newChild, TextLineSlot slot) { + RenderBox? old, + RenderBox? newChild, + TextLineSlot slot, + ) { if (old != null) { dropChild(old); children.remove(slot); @@ -800,8 +804,9 @@ class RenderEditableTextLine extends RenderEditableBox { assert(boxes.isNotEmpty); final targetBox = first ? boxes.first : boxes.last; return TextSelectionPoint( - Offset(first ? targetBox.start : targetBox.end, targetBox.bottom), - targetBox.direction); + Offset(first ? targetBox.start : targetBox.end, targetBox.bottom), + targetBox.direction, + ); } @override @@ -814,9 +819,12 @@ class RenderEditableTextLine extends RenderEditableBox { .where((element) => element.top < lineDy && element.bottom > lineDy) .toList(growable: false); return TextRange( - start: - getPositionForOffset(Offset(lineBoxes.first.left, lineDy)).offset, - end: getPositionForOffset(Offset(lineBoxes.last.right, lineDy)).offset); + start: getPositionForOffset( + Offset(lineBoxes.first.left, lineDy), + ).offset, + end: getPositionForOffset( + Offset(lineBoxes.last.right, lineDy), + ).offset); } @override @@ -886,7 +894,9 @@ class RenderEditableTextLine extends RenderEditableBox { /// of the cursor for iOS is approximate and obtained through an eyeball /// comparison. void _computeCaretPrototype() { - if (isAppleOS()) { + // If the cursor is taller only on iOS and not AppleOS then we should check + // only for iOS instead of AppleOS (macOS for example) + if (isIOS()) { _caretPrototype = Rect.fromLTWH(0, 0, cursorWidth, cursorHeight + 2); } else { _caretPrototype = Rect.fromLTWH(0, 2, cursorWidth, cursorHeight - 4.0); @@ -1090,8 +1100,13 @@ class RenderEditableTextLine extends RenderEditableBox { } else { final parentData = _leading!.parentData as BoxParentData; final effectiveOffset = offset + parentData.offset; - context.paintChild(_leading!, - Offset(size.width - _leading!.size.width, effectiveOffset.dy)); + context.paintChild( + _leading!, + Offset( + size.width - _leading!.size.width, + effectiveOffset.dy, + ), + ); } } @@ -1106,18 +1121,29 @@ class RenderEditableTextLine extends RenderEditableBox { continue; } final textRange = TextSelection( - baseOffset: item.offset, extentOffset: item.offset + item.length); + baseOffset: item.offset, + extentOffset: item.offset + item.length, + ); final rects = _body!.getBoxesForSelection(textRange); final paint = Paint()..color = inlineCodeStyle.backgroundColor!; for (final box in rects) { final rect = box.toRect().translate(0, 1).shift(effectiveOffset); if (inlineCodeStyle.radius == null) { final paintRect = Rect.fromLTRB( - rect.left - 2, rect.top, rect.right + 2, rect.bottom); + rect.left - 2, + rect.top, + rect.right + 2, + rect.bottom, + ); context.canvas.drawRect(paintRect, paint); } else { - final paintRect = RRect.fromLTRBR(rect.left - 2, rect.top, - rect.right + 2, rect.bottom, inlineCodeStyle.radius!); + final paintRect = RRect.fromLTRBR( + rect.left - 2, + rect.top, + rect.right + 2, + rect.bottom, + inlineCodeStyle.radius!, + ); context.canvas.drawRRect(paintRect, paint); } } @@ -1154,10 +1180,20 @@ class RenderEditableTextLine extends RenderEditableBox { if (line.isEmpty && textSelection.baseOffset <= line.offset && textSelection.extentOffset > line.offset) { - final lineHeight = - preferredLineHeight(TextPosition(offset: line.offset)); - _selectedRects - ?.add(TextBox.fromLTRBD(0, 0, 3, lineHeight, textDirection)); + final lineHeight = preferredLineHeight( + TextPosition( + offset: line.offset, + ), + ); + _selectedRects?.add( + TextBox.fromLTRBD( + 0, + 0, + 3, + lineHeight, + textDirection, + ), + ); } _paintSelection(context, effectiveOffset); @@ -1179,12 +1215,18 @@ class RenderEditableTextLine extends RenderEditableBox { ? TextPosition( offset: cursorCont.floatingCursorTextPosition.value!.offset - line.documentOffset, - affinity: cursorCont.floatingCursorTextPosition.value!.affinity) + affinity: cursorCont.floatingCursorTextPosition.value!.affinity, + ) : TextPosition( offset: textSelection.extentOffset - line.documentOffset, - affinity: textSelection.base.affinity); + affinity: textSelection.base.affinity, + ); _cursorPainter.paint( - context.canvas, effectiveOffset, position, lineHasEmbed); + context.canvas, + effectiveOffset, + position, + lineHasEmbed, + ); } @override @@ -1192,29 +1234,35 @@ class RenderEditableTextLine extends RenderEditableBox { if (_leading != null) { final childParentData = _leading!.parentData as BoxParentData; final isHit = result.addWithPaintOffset( - offset: childParentData.offset, - position: position, - hitTest: (result, transformed) { - assert(transformed == position - childParentData.offset); - return _leading!.hitTest(result, position: transformed); - }); + offset: childParentData.offset, + position: position, + hitTest: (result, transformed) { + assert(transformed == position - childParentData.offset); + return _leading!.hitTest(result, position: transformed); + }, + ); if (isHit) return true; } if (_body == null) return false; final parentData = _body!.parentData as BoxParentData; return result.addWithPaintOffset( - offset: parentData.offset, - position: position, - hitTest: (result, position) { - return _body!.hitTest(result, position: position); - }); + offset: parentData.offset, + position: position, + hitTest: (result, position) { + return _body!.hitTest(result, position: position); + }, + ); } @override Rect getLocalRectForCaret(TextPosition position) { final caretOffset = getOffsetForCaret(position); - var rect = - Rect.fromLTWH(0, 0, cursorWidth, cursorHeight).shift(caretOffset); + var rect = Rect.fromLTWH( + 0, + 0, + cursorWidth, + cursorHeight, + ).shift(caretOffset); final cursorOffset = cursorCont.style.offset; // Add additional cursor offset (generally only if on iOS). if (cursorOffset != null) rect = rect.shift(cursorOffset); @@ -1272,16 +1320,16 @@ class _TextLineElement extends RenderObjectElement { @override void mount(Element? parent, dynamic newSlot) { super.mount(parent, newSlot); - _mountChild(widget.leading, TextLineSlot.LEADING); - _mountChild(widget.body, TextLineSlot.BODY); + _mountChild(widget.leading, TextLineSlot.leading); + _mountChild(widget.body, TextLineSlot.body); } @override void update(EditableTextLine newWidget) { super.update(newWidget); assert(widget == newWidget); - _updateChild(widget.leading, TextLineSlot.LEADING); - _updateChild(widget.body, TextLineSlot.BODY); + _updateChild(widget.leading, TextLineSlot.leading); + _updateChild(widget.body, TextLineSlot.body); } @override @@ -1318,10 +1366,10 @@ class _TextLineElement extends RenderObjectElement { void _updateRenderObject(RenderBox? child, TextLineSlot? slot) { switch (slot) { - case TextLineSlot.LEADING: + case TextLineSlot.leading: renderObject.setLeading(child); break; - case TextLineSlot.BODY: + case TextLineSlot.body: renderObject.setBody(child as RenderContentProxyBox?); break; default: diff --git a/lib/src/widgets/text_selection.dart b/lib/src/widgets/text_selection.dart index c13f9952..07cbdeb8 100644 --- a/lib/src/widgets/text_selection.dart +++ b/lib/src/widgets/text_selection.dart @@ -842,8 +842,10 @@ class _EditorTextSelectionGestureDetectorState void _handleDragUpdate(DragUpdateDetails details) { _lastDragUpdateDetails = details; - _dragUpdateThrottleTimer ??= - Timer(const Duration(milliseconds: 50), _handleDragUpdateThrottled); + _dragUpdateThrottleTimer ??= Timer( + const Duration(milliseconds: 50), + _handleDragUpdateThrottled, + ); } /// Drag updates are being throttled to avoid excessive text layouts in text diff --git a/lib/src/widgets/toolbar/buttons/arrow_indicated_list.dart b/lib/src/widgets/toolbar/buttons/arrow_indicated_list.dart index 146fcc95..f90b9b4d 100644 --- a/lib/src/widgets/toolbar/buttons/arrow_indicated_list.dart +++ b/lib/src/widgets/toolbar/buttons/arrow_indicated_list.dart @@ -10,8 +10,8 @@ class QuillToolbarArrowIndicatedButtonList extends StatefulWidget { const QuillToolbarArrowIndicatedButtonList({ required this.axis, required this.buttons, - Key? key, - }) : super(key: key); + super.key, + }); final Axis axis; final List buttons; diff --git a/lib/src/widgets/toolbar/buttons/link_style.dart b/lib/src/widgets/toolbar/buttons/link_style.dart index 15cd5af1..b7bf91c0 100644 --- a/lib/src/widgets/toolbar/buttons/link_style.dart +++ b/lib/src/widgets/toolbar/buttons/link_style.dart @@ -95,14 +95,13 @@ class _QuillToolbarLinkStyleButtonState context.requireQuillSharedConfigurations.dialogBarrierColor; } - RegExp get linkRegExp { - return options.linkRegExp ?? RegExp(r'https?://\S+'); + RegExp? get linkRegExp { + return options.linkRegExp; } @override Widget build(BuildContext context) { final isToggled = _getLinkAttributeValue() != null; - final pressedHandler = () => _openLinkDialog(context); final childBuilder = options.childBuilder ?? baseButtonExtraOptions.childBuilder; @@ -124,7 +123,7 @@ class _QuillToolbarLinkStyleButtonState context: context, controller: controller, onPressed: () { - pressedHandler(); + _openLinkDialog(context); afterButtonPressed?.call(); }, ), @@ -144,10 +143,10 @@ class _QuillToolbarLinkStyleButtonState : (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color), ), fillColor: isToggled - ? (iconTheme?.iconSelectedFillColor ?? Theme.of(context).primaryColor) + ? (iconTheme?.iconSelectedFillColor ?? theme.primaryColor) : (iconTheme?.iconUnselectedFillColor ?? theme.canvasColor), borderRadius: iconTheme?.borderRadius ?? 2, - onPressed: pressedHandler, + onPressed: () => _openLinkDialog(context), afterPressed: afterButtonPressed, ); } @@ -236,7 +235,11 @@ class _LinkDialog extends StatefulWidget { class _LinkDialogState extends State<_LinkDialog> { late String _link; late String _text; - late RegExp linkRegExp; + + RegExp get linkRegExp { + return widget.linkRegExp ?? AutoFormatMultipleLinksRule.oneLineLinkRegExp; + } + late TextEditingController _linkController; late TextEditingController _textController; @@ -245,7 +248,6 @@ class _LinkDialogState extends State<_LinkDialog> { super.initState(); _link = widget.link ?? ''; _text = widget.text ?? ''; - linkRegExp = widget.linkRegExp ?? AutoFormatMultipleLinksRule.oneLineRegExp; _linkController = TextEditingController(text: _link); _textController = TextEditingController(text: _text); } diff --git a/lib/src/widgets/toolbar/buttons/link_style2.dart b/lib/src/widgets/toolbar/buttons/link_style2.dart index d2ecbddd..57e0bcf1 100644 --- a/lib/src/widgets/toolbar/buttons/link_style2.dart +++ b/lib/src/widgets/toolbar/buttons/link_style2.dart @@ -5,9 +5,11 @@ import 'package:url_launcher/link.dart'; import '../../../../extensions.dart' show UtilityWidgets, AutoFormatMultipleLinksRule; import '../../../../translations.dart'; +import '../../../models/config/toolbar/buttons/link_style2.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/themes/quill_dialog_theme.dart'; import '../../../models/themes/quill_icon_theme.dart'; +import '../../../utils/extensions/build_context.dart'; import '../../controller.dart'; import '../../link.dart'; import '../base_toolbar.dart'; @@ -16,60 +18,20 @@ import '../base_toolbar.dart'; /// customization /// and uses dialog similar to one which is used on [http://quilljs.com]. class QuillToolbarLinkStyleButton2 extends StatefulWidget { - const QuillToolbarLinkStyleButton2({ + QuillToolbarLinkStyleButton2({ required this.controller, - this.icon, - this.iconSize = kDefaultIconSize, - this.iconTheme, - this.dialogTheme, - this.afterButtonPressed, - this.tooltip, - this.constraints, - this.addLinkLabel, - this.editLinkLabel, - this.linkColor, - this.childrenSpacing = 16.0, - this.autovalidateMode = AutovalidateMode.disabled, - this.validationMessage, - this.buttonSize, - this.dialogBarrierColor = Colors.black54, - Key? key, - }) : assert(addLinkLabel == null || addLinkLabel.length > 0), - assert(editLinkLabel == null || editLinkLabel.length > 0), - assert(childrenSpacing > 0), - assert(validationMessage == null || validationMessage.length > 0), - super(key: key); + required this.options, + super.key, + }) : assert(options.addLinkLabel == null || + (options.addLinkLabel?.isNotEmpty ?? true)), + assert(options.editLinkLabel == null || + (options.editLinkLabel?.isNotEmpty ?? true)), + assert(options.childrenSpacing > 0), + assert(options.validationMessage == null || + (options.validationMessage?.isNotEmpty ?? true)); final QuillController controller; - final IconData? icon; - final double iconSize; - final QuillIconTheme? iconTheme; - final QuillDialogTheme? dialogTheme; - final VoidCallback? afterButtonPressed; - final String? tooltip; - - /// The constrains for dialog. - final BoxConstraints? constraints; - - /// The text of label in link add mode. - final String? addLinkLabel; - - /// The text of label in link edit mode. - final String? editLinkLabel; - - /// The color of URL. - final Color? linkColor; - - /// The margin between child widgets in the dialog. - final double childrenSpacing; - - final AutovalidateMode autovalidateMode; - final String? validationMessage; - - /// The size of dialog buttons. - final Size? buttonSize; - - final Color dialogBarrierColor; + final QuillToolbarLinkStyleButton2Options options; @override State createState() => @@ -99,30 +61,101 @@ class _QuillToolbarLinkStyleButton2State } } + QuillController get controller { + return widget.controller; + } + + QuillToolbarLinkStyleButton2Options get options { + return widget.options; + } + + double get iconSize { + final baseFontSize = baseButtonExtraOptions.globalIconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize; + } + + VoidCallback? get afterButtonPressed { + return options.afterButtonPressed ?? + baseButtonExtraOptions.afterButtonPressed; + } + + QuillIconTheme? get iconTheme { + return options.iconTheme ?? baseButtonExtraOptions.iconTheme; + } + + QuillToolbarBaseButtonOptions get baseButtonExtraOptions { + return context.requireQuillToolbarBaseButtonOptions; + } + + String get tooltip { + return options.tooltip ?? + baseButtonExtraOptions.tooltip ?? + 'Insert URL'.i18n; + } + + IconData get iconData { + return options.iconData ?? baseButtonExtraOptions.iconData ?? Icons.link; + } + + Color get dialogBarrierColor { + return options.dialogBarrierColor ?? + context.requireQuillSharedConfigurations.dialogBarrierColor; + } + @override Widget build(BuildContext context) { + final childBuilder = + options.childBuilder ?? baseButtonExtraOptions.childBuilder; + if (childBuilder != null) { + return childBuilder( + QuillToolbarLinkStyleButton2Options( + iconData: iconData, + addLinkLabel: options.addLinkLabel, + afterButtonPressed: options.afterButtonPressed, + autovalidateMode: options.autovalidateMode, + buttonSize: options.buttonSize, + childrenSpacing: options.childrenSpacing, + dialogBarrierColor: dialogBarrierColor, + dialogTheme: options.dialogTheme, + iconSize: iconSize, + constraints: options.constraints, + tooltip: tooltip, + iconTheme: iconTheme, + editLinkLabel: options.editLinkLabel, + validationMessage: options.validationMessage, + linkColor: options.linkColor, + ), + QuillToolbarLinkStyleButton2ExtraOptions( + controller: controller, + context: context, + onPressed: () { + _openLinkDialog(); + afterButtonPressed?.call(); + }, + ), + ); + } final theme = Theme.of(context); final isToggled = _getLinkAttributeValue() != null; return QuillToolbarIconButton( - tooltip: widget.tooltip, + tooltip: tooltip, highlightElevation: 0, hoverElevation: 0, - size: widget.iconSize * kIconButtonFactor, + size: iconSize * kIconButtonFactor, icon: Icon( - widget.icon ?? Icons.link, - size: widget.iconSize, + iconData, + size: iconSize, color: isToggled - ? (widget.iconTheme?.iconSelectedColor ?? - theme.primaryIconTheme.color) - : (widget.iconTheme?.iconUnselectedColor ?? theme.iconTheme.color), + ? (iconTheme?.iconSelectedColor ?? theme.primaryIconTheme.color) + : (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color), ), fillColor: isToggled - ? (widget.iconTheme?.iconSelectedFillColor ?? - Theme.of(context).primaryColor) - : (widget.iconTheme?.iconUnselectedFillColor ?? theme.canvasColor), - borderRadius: widget.iconTheme?.borderRadius ?? 2, + ? (iconTheme?.iconSelectedFillColor ?? theme.primaryColor) + : (iconTheme?.iconUnselectedFillColor ?? theme.canvasColor), + borderRadius: iconTheme?.borderRadius ?? 2, onPressed: _openLinkDialog, - afterPressed: widget.afterButtonPressed, + afterPressed: afterButtonPressed, ); } @@ -131,19 +164,19 @@ class _QuillToolbarLinkStyleButton2State final textLink = await showDialog( context: context, - barrierColor: widget.dialogBarrierColor, + barrierColor: dialogBarrierColor, builder: (_) => LinkStyleDialog( - dialogTheme: widget.dialogTheme, + dialogTheme: options.dialogTheme, text: initialTextLink.text, link: initialTextLink.link, - constraints: widget.constraints, - addLinkLabel: widget.addLinkLabel, - editLinkLabel: widget.editLinkLabel, - linkColor: widget.linkColor, - childrenSpacing: widget.childrenSpacing, - autovalidateMode: widget.autovalidateMode, - validationMessage: widget.validationMessage, - buttonSize: widget.buttonSize, + constraints: options.constraints, + addLinkLabel: options.addLinkLabel, + editLinkLabel: options.editLinkLabel, + linkColor: options.linkColor, + childrenSpacing: options.childrenSpacing, + autovalidateMode: options.autovalidateMode, + validationMessage: options.validationMessage, + buttonSize: options.buttonSize, ), ); @@ -166,7 +199,7 @@ class _QuillToolbarLinkStyleButton2State class LinkStyleDialog extends StatefulWidget { const LinkStyleDialog({ - Key? key, + super.key, this.text, this.link, this.dialogTheme, @@ -183,8 +216,7 @@ class LinkStyleDialog extends StatefulWidget { }) : assert(addLinkLabel == null || addLinkLabel.length > 0), assert(editLinkLabel == null || editLinkLabel.length > 0), assert(childrenSpacing > 0), - assert(validationMessage == null || validationMessage.length > 0), - super(key: key); + assert(validationMessage == null || validationMessage.length > 0); final String? text; final String? link; @@ -387,7 +419,7 @@ class _LinkStyleDialogState extends State { String? _validateLink(String? value) { if ((value?.isEmpty ?? false) || - !AutoFormatMultipleLinksRule.oneLineRegExp.hasMatch(value!)) { + !AutoFormatMultipleLinksRule.oneLineLinkRegExp.hasMatch(value!)) { return widget.validationMessage ?? 'That is not a valid URL'; } diff --git a/lib/src/widgets/toolbar/buttons/select_alignment.dart b/lib/src/widgets/toolbar/buttons/select_alignment.dart index 2d4018dd..9ee36622 100644 --- a/lib/src/widgets/toolbar/buttons/select_alignment.dart +++ b/lib/src/widgets/toolbar/buttons/select_alignment.dart @@ -60,18 +60,18 @@ class _QuillToolbarSelectAlignmentButtonState return widget.controller; } - double get iconSize { + double get _iconSize { final baseFontSize = baseButtonExtraOptions.globalIconSize; final iconSize = options.iconSize; return iconSize ?? baseFontSize; } - VoidCallback? get afterButtonPressed { + VoidCallback? get _afterButtonPressed { return options.afterButtonPressed ?? baseButtonExtraOptions.afterButtonPressed; } - QuillIconTheme? get iconTheme { + QuillIconTheme? get _iconTheme { return options.iconTheme ?? baseButtonExtraOptions.iconTheme; } @@ -191,25 +191,42 @@ class _QuillToolbarSelectAlignmentButtonState final childBuilder = options.childBuilder ?? baseButtonExtraOptions.childBuilder; - if (childBuilder != null) { - throw UnsupportedError( - 'Sorry but the `childBuilder` for the Select alignment buttons' - ' is not supported. Yet but we will work on that soon.', - ); + void _sharedOnPressed(int index) { + _valueAttribute[index] == Attribute.leftAlignment + ? controller.formatSelection( + Attribute.clone(Attribute.align, null), + ) + : controller.formatSelection(_valueAttribute[index]); + _afterButtonPressed?.call(); } - final theme = Theme.of(context); - return Row( mainAxisSize: MainAxisSize.min, children: List.generate(buttonCount, (index) { + if (childBuilder != null) { + return childBuilder( + QuillToolbarSelectAlignmentButtonOptions( + afterButtonPressed: _afterButtonPressed, + iconSize: _iconSize, + iconTheme: _iconTheme, + tooltips: _tooltips, + iconsData: _iconsData, + ), + QuillToolbarSelectAlignmentButtonExtraOptions( + context: context, + controller: controller, + onPressed: () => _sharedOnPressed(index), + ), + ); + } + final theme = Theme.of(context); return Padding( padding: widget.padding ?? const EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0), child: ConstrainedBox( constraints: BoxConstraints.tightFor( - width: iconSize * kIconButtonFactor, - height: iconSize * kIconButtonFactor, + width: _iconSize * kIconButtonFactor, + height: _iconSize * kIconButtonFactor, ), child: UtilityWidgets.maybeTooltip( message: _valueString[index] == Attribute.leftAlignment.value @@ -226,19 +243,12 @@ class _QuillToolbarSelectAlignmentButtonState visualDensity: VisualDensity.compact, shape: RoundedRectangleBorder( borderRadius: - BorderRadius.circular(iconTheme?.borderRadius ?? 2)), + BorderRadius.circular(_iconTheme?.borderRadius ?? 2)), fillColor: _valueToText[_value] == _valueString[index] - ? (iconTheme?.iconSelectedFillColor ?? - Theme.of(context).primaryColor) - : (iconTheme?.iconUnselectedFillColor ?? theme.canvasColor), - onPressed: () { - _valueAttribute[index] == Attribute.leftAlignment - ? controller.formatSelection( - Attribute.clone(Attribute.align, null), - ) - : controller.formatSelection(_valueAttribute[index]); - afterButtonPressed?.call(); - }, + ? (_iconTheme?.iconSelectedFillColor ?? theme.primaryColor) + : (_iconTheme?.iconUnselectedFillColor ?? + theme.canvasColor), + onPressed: () => _sharedOnPressed(index), child: Icon( _valueString[index] == Attribute.leftAlignment.value ? _iconsData.leftAlignment @@ -248,11 +258,11 @@ class _QuillToolbarSelectAlignmentButtonState Attribute.rightAlignment.value ? _iconsData.rightAlignment : _iconsData.justifyAlignment, - size: iconSize, + size: _iconSize, color: _valueToText[_value] == _valueString[index] - ? (iconTheme?.iconSelectedColor ?? + ? (_iconTheme?.iconSelectedColor ?? theme.primaryIconTheme.color) - : (iconTheme?.iconUnselectedColor ?? + : (_iconTheme?.iconUnselectedColor ?? theme.iconTheme.color), ), ), diff --git a/lib/src/widgets/toolbar/buttons/select_header_style.dart b/lib/src/widgets/toolbar/buttons/select_header_style.dart index 57ba28d2..987f9f3e 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import '../../../../extensions.dart'; @@ -90,10 +91,20 @@ class _QuillToolbarSelectHeaderStyleButtonsState afterButtonPressed?.call(); } + List get _attrbuites { + return options.attributes ?? + const [ + Attribute.header, + Attribute.h1, + Attribute.h2, + Attribute.h3, + ]; + } + @override Widget build(BuildContext context) { assert( - options.attributes.every( + _attrbuites.every( (element) => _valueToText.keys.contains(element), ), 'All attributes must be one of them: header, h1, h2 or h3', @@ -107,19 +118,28 @@ class _QuillToolbarSelectHeaderStyleButtonsState final childBuilder = options.childBuilder ?? baseButtonExtraOptions.childBuilder; - if (childBuilder != null) { - throw UnsupportedError( - 'Sorry but the `childBuilder` for the Select header button' - ' is not supported. Yet but we will work on that soon.', - ); - } - final theme = Theme.of(context); - - final children = options.attributes.map((attribute) { + final children = _attrbuites.map((attribute) { + if (childBuilder != null) { + return childBuilder( + QuillToolbarSelectHeaderStyleButtonsOptions( + afterButtonPressed: afterButtonPressed, + attributes: _attrbuites, + axis: axis, + iconSize: iconSize, + iconTheme: iconTheme, + tooltip: tooltip, + ), + QuillToolbarSelectHeaderStyleButtonExtraOptions( + controller: controller, + context: context, + onPressed: () => _sharedOnPressed(attribute), + ), + ); + } + final theme = Theme.of(context); final isSelected = _selectedAttribute == attribute; return Padding( - // Do we really need to ignore (prefer_const_constructors)?? - padding: EdgeInsets.symmetric(horizontal: !isWeb() ? 1.0 : 5.0), + padding: const EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0), child: ConstrainedBox( constraints: BoxConstraints.tightFor( width: iconSize * kIconButtonFactor, @@ -136,12 +156,14 @@ class _QuillToolbarSelectHeaderStyleButtonsState borderRadius: BorderRadius.circular(iconTheme?.borderRadius ?? 2)), fillColor: isSelected - ? (iconTheme?.iconSelectedFillColor ?? - Theme.of(context).primaryColor) + ? (iconTheme?.iconSelectedFillColor ?? theme.primaryColor) : (iconTheme?.iconUnselectedFillColor ?? theme.canvasColor), onPressed: () => _sharedOnPressed(attribute), child: Text( - _valueToText[attribute] ?? '', + _valueToText[attribute] ?? + (throw ArgumentError.notNull( + 'attrbuite', + )), style: style.copyWith( color: isSelected ? (iconTheme?.iconSelectedColor ?? diff --git a/lib/src/widgets/toolbar/toolbar.dart b/lib/src/widgets/toolbar/toolbar.dart index 092f5012..6749f0b5 100644 --- a/lib/src/widgets/toolbar/toolbar.dart +++ b/lib/src/widgets/toolbar/toolbar.dart @@ -70,36 +70,47 @@ class QuillToolbar extends StatelessWidget { final axis = toolbarConfigurations.axis; final globalController = context.requireQuillController; + final spacerWidget = + configurations.spacerWidget ?? const SizedBox.shrink(); + return [ - if (configurations.showUndo) + if (configurations.showUndo) ...[ QuillToolbarHistoryButton( options: toolbarConfigurations.buttonOptions.undoHistory, controller: toolbarConfigurations .buttonOptions.undoHistory.controller ?? globalController, ), - if (configurations.showRedo) + spacerWidget, + ], + if (configurations.showRedo) ...[ QuillToolbarHistoryButton( options: toolbarConfigurations.buttonOptions.redoHistory, controller: toolbarConfigurations .buttonOptions.redoHistory.controller ?? globalController, ), - if (configurations.showFontFamily) + spacerWidget, + ], + if (configurations.showFontFamily) ...[ QuillToolbarFontFamilyButton( options: toolbarConfigurations.buttonOptions.fontFamily, controller: toolbarConfigurations .buttonOptions.fontFamily.controller ?? globalController, ), - if (configurations.showFontSize) + spacerWidget, + ], + if (configurations.showFontSize) ...[ QuillToolbarFontSizeButton( options: toolbarConfigurations.buttonOptions.fontSize, controller: toolbarConfigurations .buttonOptions.fontFamily.controller ?? globalController, ), - if (configurations.showBoldButton) + spacerWidget, + ], + if (configurations.showBoldButton) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.bold, options: toolbarConfigurations.buttonOptions.bold, @@ -107,7 +118,9 @@ class QuillToolbar extends StatelessWidget { toolbarConfigurations.buttonOptions.bold.controller ?? globalController, ), - if (configurations.showSubscript) + spacerWidget, + ], + if (configurations.showSubscript) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.subscript, options: toolbarConfigurations.buttonOptions.subscript, @@ -115,7 +128,9 @@ class QuillToolbar extends StatelessWidget { .buttonOptions.subscript.controller ?? globalController, ), - if (configurations.showSuperscript) + spacerWidget, + ], + if (configurations.showSuperscript) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.superscript, options: toolbarConfigurations.buttonOptions.superscript, @@ -123,7 +138,9 @@ class QuillToolbar extends StatelessWidget { .buttonOptions.superscript.controller ?? globalController, ), - if (configurations.showItalicButton) + spacerWidget, + ], + if (configurations.showItalicButton) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.italic, options: toolbarConfigurations.buttonOptions.italic, @@ -131,7 +148,9 @@ class QuillToolbar extends StatelessWidget { toolbarConfigurations.buttonOptions.italic.controller ?? globalController, ), - if (configurations.showSmallButton) + spacerWidget, + ], + if (configurations.showSmallButton) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.small, options: toolbarConfigurations.buttonOptions.small, @@ -139,7 +158,9 @@ class QuillToolbar extends StatelessWidget { toolbarConfigurations.buttonOptions.small.controller ?? globalController, ), - if (configurations.showUnderLineButton) + spacerWidget, + ], + if (configurations.showUnderLineButton) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.underline, options: toolbarConfigurations.buttonOptions.underLine, @@ -147,7 +168,9 @@ class QuillToolbar extends StatelessWidget { .buttonOptions.underLine.controller ?? globalController, ), - if (configurations.showStrikeThrough) + spacerWidget, + ], + if (configurations.showStrikeThrough) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.strikeThrough, options: toolbarConfigurations.buttonOptions.strikeThrough, @@ -155,7 +178,9 @@ class QuillToolbar extends StatelessWidget { .buttonOptions.strikeThrough.controller ?? globalController, ), - if (configurations.showInlineCode) + spacerWidget, + ], + if (configurations.showInlineCode) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.inlineCode, options: toolbarConfigurations.buttonOptions.inlineCode, @@ -163,23 +188,31 @@ class QuillToolbar extends StatelessWidget { .buttonOptions.inlineCode.controller ?? globalController, ), - if (configurations.showColorButton) + spacerWidget, + ], + if (configurations.showColorButton) ...[ QuillToolbarColorButton( controller: controller, isBackground: false, options: toolbarConfigurations.buttonOptions.color, ), - if (configurations.showBackgroundColorButton) + spacerWidget, + ], + if (configurations.showBackgroundColorButton) ...[ QuillToolbarColorButton( options: toolbarConfigurations.buttonOptions.backgroundColor, controller: controller, isBackground: true, ), - if (configurations.showClearFormat) + spacerWidget, + ], + if (configurations.showClearFormat) ...[ QuillToolbarClearFormatButton( controller: controller, options: toolbarConfigurations.buttonOptions.clearFormat, ), + spacerWidget, + ], if (theEmbedButtons != null) for (final builder in theEmbedButtons) builder( @@ -199,7 +232,7 @@ class QuillToolbar extends StatelessWidget { color: configurations.sectionDividerColor, space: configurations.sectionDividerSpace, ), - if (configurations.showAlignmentButtons) + if (configurations.showAlignmentButtons) ...[ QuillToolbarSelectAlignmentButton( controller: controller, options: toolbarConfigurations @@ -216,7 +249,9 @@ class QuillToolbar extends StatelessWidget { showRightAlignment: configurations.showRightAlignment, showJustifyAlignment: configurations.showJustifyAlignment, ), - if (configurations.showDirection) + spacerWidget, + ], + if (configurations.showDirection) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.rtl, options: toolbarConfigurations.buttonOptions.direction, @@ -224,6 +259,8 @@ class QuillToolbar extends StatelessWidget { .buttonOptions.direction.controller ?? context.requireQuillController, ), + spacerWidget, + ], if (configurations.showDividers && isButtonGroupShown[1] && (isButtonGroupShown[2] || @@ -235,12 +272,14 @@ class QuillToolbar extends StatelessWidget { color: configurations.sectionDividerColor, space: configurations.sectionDividerSpace, ), - if (configurations.showHeaderStyle) + if (configurations.showHeaderStyle) ...[ QuillToolbarSelectHeaderStyleButtons( controller: controller, options: toolbarConfigurations .buttonOptions.selectHeaderStyleButtons, ), + spacerWidget, + ], if (configurations.showDividers && configurations.showHeaderStyle && isButtonGroupShown[2] && @@ -252,7 +291,7 @@ class QuillToolbar extends StatelessWidget { color: configurations.sectionDividerColor, space: configurations.sectionDividerSpace, ), - if (configurations.showListNumbers) + if (configurations.showListNumbers) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.ol, options: toolbarConfigurations.buttonOptions.listNumbers, @@ -260,7 +299,9 @@ class QuillToolbar extends StatelessWidget { .buttonOptions.listNumbers.controller ?? globalController, ), - if (configurations.showListBullets) + spacerWidget, + ], + if (configurations.showListBullets) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.ul, options: toolbarConfigurations.buttonOptions.listBullets, @@ -268,14 +309,18 @@ class QuillToolbar extends StatelessWidget { .buttonOptions.listBullets.controller ?? globalController, ), - if (configurations.showListCheck) + spacerWidget, + ], + if (configurations.showListCheck) ...[ QuillToolbarToggleCheckListButton( options: toolbarConfigurations.buttonOptions.toggleCheckList, controller: toolbarConfigurations .buttonOptions.toggleCheckList.controller ?? globalController, ), - if (configurations.showCodeBlock) + spacerWidget, + ], + if (configurations.showCodeBlock) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.codeBlock, options: toolbarConfigurations.buttonOptions.codeBlock, @@ -283,15 +328,18 @@ class QuillToolbar extends StatelessWidget { .buttonOptions.codeBlock.controller ?? globalController, ), + spacerWidget, + ], if (configurations.showDividers && isButtonGroupShown[3] && - (isButtonGroupShown[4] || isButtonGroupShown[5])) + (isButtonGroupShown[4] || isButtonGroupShown[5])) ...[ QuillToolbarDivider( axis, color: configurations.sectionDividerColor, space: configurations.sectionDividerSpace, ), - if (configurations.showQuote) + ], + if (configurations.showQuote) ...[ QuillToolbarToggleStyleButton( options: toolbarConfigurations.buttonOptions.quote, controller: @@ -299,7 +347,9 @@ class QuillToolbar extends StatelessWidget { globalController, attribute: Attribute.blockQuote, ), - if (configurations.showIndent) + spacerWidget, + ], + if (configurations.showIndent) ...[ QuillToolbarIndentButton( controller: toolbarConfigurations .buttonOptions.indentIncrease.controller ?? @@ -307,7 +357,9 @@ class QuillToolbar extends StatelessWidget { isIncrease: true, options: toolbarConfigurations.buttonOptions.indentIncrease, ), - if (configurations.showIndent) + spacerWidget, + ], + if (configurations.showIndent) ...[ QuillToolbarIndentButton( controller: toolbarConfigurations .buttonOptions.indentDecrease.controller ?? @@ -315,6 +367,8 @@ class QuillToolbar extends StatelessWidget { isIncrease: false, options: toolbarConfigurations.buttonOptions.indentDecrease, ), + spacerWidget, + ], if (configurations.showDividers && isButtonGroupShown[4] && isButtonGroupShown[5]) @@ -323,45 +377,51 @@ class QuillToolbar extends StatelessWidget { color: configurations.sectionDividerColor, space: configurations.sectionDividerSpace, ), - if (configurations.showLink) + if (configurations.showLink) ...[ QuillToolbarLinkStyleButton( controller: controller, options: toolbarConfigurations.buttonOptions.linkStyle, ), - if (configurations.showSearchButton) + spacerWidget, + ], + if (configurations.showSearchButton) ...[ QuillToolbarSearchButton( controller: controller, options: toolbarConfigurations.buttonOptions.search, ), - if (configurations.customButtons.isNotEmpty) + spacerWidget, + ], + if (configurations.customButtons.isNotEmpty) ...[ if (configurations.showDividers) QuillToolbarDivider( axis, color: configurations.sectionDividerColor, space: configurations.sectionDividerSpace, ), - for (final customButton in configurations.customButtons) - if (customButton.child != null) ...[ - InkWell( - onTap: customButton.onTap, - child: customButton.child, - ), - ] else ...[ - CustomButton( - onPressed: customButton.onTap, - icon: customButton.iconData ?? - context.quillToolbarBaseButtonOptions?.iconData, - iconColor: customButton.iconColor, - iconSize: customButton.iconSize ?? globalIconSize, - iconTheme: - context.requireQuillToolbarBaseButtonOptions.iconTheme, - afterButtonPressed: customButton.afterButtonPressed ?? - context - .quillToolbarBaseButtonOptions?.afterButtonPressed, - tooltip: customButton.tooltip ?? - context.quillToolbarBaseButtonOptions?.tooltip, - ), - ], + for (final customButton in configurations.customButtons) + if (customButton.child != null) ...[ + InkWell( + onTap: customButton.onTap, + child: customButton.child, + ), + ] else ...[ + CustomButton( + onPressed: customButton.onTap, + icon: customButton.iconData ?? + context.quillToolbarBaseButtonOptions?.iconData, + iconColor: customButton.iconColor, + iconSize: customButton.iconSize ?? globalIconSize, + iconTheme: context + .requireQuillToolbarBaseButtonOptions.iconTheme, + afterButtonPressed: customButton.afterButtonPressed ?? + context.quillToolbarBaseButtonOptions + ?.afterButtonPressed, + tooltip: customButton.tooltip ?? + context.quillToolbarBaseButtonOptions?.tooltip, + ), + ], + spacerWidget, + ], ]; }, ), diff --git a/pubspec.yaml b/pubspec.yaml index 8fd42e6e..1be2a3a6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.1.1 +version: 8.1.2 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill topics: @@ -17,7 +17,8 @@ platforms: windows: environment: - sdk: ">=2.17.0 <4.0.0" + sdk: '>=3.1.3 <4.0.0' + # sdk: ">=2.17.0 <4.0.0" flutter: ">=3.10.0" dependencies: @@ -40,5 +41,6 @@ dependencies: flutter_test: sdk: flutter + meta: ^1.9.1 flutter: null \ No newline at end of file diff --git a/test/bug_fix_test.dart b/test/bug_fix_test.dart index 6ade28f5..9869d517 100644 --- a/test/bug_fix_test.dart +++ b/test/bug_fix_test.dart @@ -130,7 +130,7 @@ void main() { controller.formatSelection(Attribute.unchecked); editor.focusNode.unfocus(); await tester.pump(); - await tester.tap(find.byType(CheckboxPoint)); + await tester.tap(find.byType(QuillEditorCheckboxPoint)); expect(tester.takeException(), isNull); }); }); From dc6724868f91eb5719337dfd8ee04d6dbb502f51 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Wed, 1 Nov 2023 03:46:24 +0300 Subject: [PATCH 003/210] Use screenshots (#1496) --- CHANGELOG.md | 3 +++ README.md | 14 ++++++-------- example/assets/images/1.png | Bin 0 -> 411042 bytes example/assets/images/2.png | Bin 0 -> 356196 bytes example/assets/images/3.png | Bin 0 -> 350463 bytes example/assets/images/4.png | Bin 0 -> 285264 bytes pubspec.yaml | 15 ++++++++++++++- 7 files changed, 23 insertions(+), 9 deletions(-) create mode 100644 example/assets/images/1.png create mode 100644 example/assets/images/2.png create mode 100644 example/assets/images/3.png create mode 100644 example/assets/images/4.png diff --git a/CHANGELOG.md b/CHANGELOG.md index f406c647..20aa37aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.1.3] +- Move the images to screenshot instead of `README.md` + ## [8.1.2] - Fix bug that is related to the regexp of the insert link dialog - Require dart 3 as minimum diff --git a/README.md b/README.md index 916a1642..52ea4f47 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,6 @@ Pub: [FlutterQuill] ## Table of contents - [Flutter Quill](#flutter-quill) - [Table of contents](#table-of-contents) - - [Demo](#demo) - [Installation](#installation) - [Usage](#usage) - [Migration](#migration) @@ -56,21 +55,20 @@ Pub: [FlutterQuill] - [Testing](#testing) - [License](#license) - [Contributors](#contributors) - - [Sponsors](#sponsors) -## Demo + ## Installation diff --git a/example/assets/images/1.png b/example/assets/images/1.png new file mode 100644 index 0000000000000000000000000000000000000000..b42afad0501215b063b54b7241e9e61aa64ba5cb GIT binary patch literal 411042 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 dMtx}NhK1pa%y#*Fi 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

  • IfmL^c)>EiA;@u@&W%R^ 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:E7`x-y}o6JW7S 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 literal 0 HcmV?d00001 diff --git a/example/assets/images/2.png b/example/assets/images/2.png new file mode 100644 index 0000000000000000000000000000000000000000..c492b3c85f041b59fbe592e005dd964a12ca449f GIT binary patch literal 356196 zcmX`RbyQp36E2(}2^2_>7Iz8(ibEkl@M6UZRB+b<#kF`S(xQdp?rkaVPzuF8$csy` z5VR>$g7)igefQpd)~uPm*PMUm?3riIvv=GxU3H3kjQ0Ql0EMQ;69WK%a0mbZ14uys zR>;d=|C^B8IIE~U(^OGmf9B=x;OuG-0BFR0dIdHz9Hz}THPCd5AkiTG9>@7OJdM(X z2>3a&GU{RSGaGFZem@^$;(4KBqp25Es;^!t&PB$$nBRZ9ZuCrluK$H=WhW^qw!J3! z7j8UH!ExfILd5$QIUtC?OFKPjpYR#GU>fX6bp1eCS%XFrfCBqd;gQt{9j{$39#0Rj zFZ|ol*#@HY4O`S1KcD>lmp@uLMHvA22=q*U#=#rj$^htm!k$V;ph%7kTK@b_>@ls1 z>%$nJGQu#yTOuHf(a{;#9GX)~B-EDxNOlhHLVy9QFDo4%kb1Ev9dpI5mMO>G2gq^7 zB8hCeC^sL*#yq&M{c@{~Qda3LL!T^%gJVd4)~VE8l~Sm@f+MBN$v&M|<`a(5UA?~w zTBkqC*e#{ey+FxqBi2ua6Kr!hwY6=h$K^^Z+~e;P4Cfg){i%z}j{$|x>%{ntZIiOe z?wc7YbVn_i4?#afFEDSCIET8%zbyD97>8COe?=yvV=$yOJz>sk5CwZJJwFPA^--W* zr87$MOb0VAu3s#-@SlE^Ho0T6p>hxZ>strsdtk#4pl{OnNKIBJ)Tj2ov(G7k!og4g zGXPl_`b4^qKVoKxl<|NUbkhH{pW32|_7&~>)MAPA9zRn2?e82# zGvSY3AHe}n-g}A?wvnh>Z)C63Nv22`=Lq}hy`;}B%v%;5O`2cYveOSOHE}1b%PQv8 zm!)HSK|)s%&6bq%U;yU4*(dIOS+e!`H(He)|-$wh|j6{@7d{Eriz+rv~B` zAztAmtRKeqziXS zhK4=5cGLuaFAGrqVx?qa^^FeMyv?vc3?(wORb0zm7UrHFwD1Bk%4b@V7L)Qeoe|YX%052=a zB8T`y-*`CFG4ZVj&I-H8^tx@S^}n`;JDq$aL+}glZ!G@Ur;^-_}!CD%1C`tU7&i*YNnEO zHIE8!iMk6oVNcp-yTh9l>_6pSaaomJRd_w9Smb0<6omAIjh2scOK&REfD1V!zU^tlk;V) z+~)fLcGrg_r0O=wL=P#3pLkL76+dy{JWcVkBd&)mM$WP;aKt2U4Kb9mw8gEc%cT5B zhVn*FKjWGu@KsbVbWKC5m1ts#B*1x*v?XLHZYOS&gk!aXsV%JZ8UGjMf)Y9UZXXdI zhlDn3*Z2?p)_X>hJcACl_C~}n6aKT-!6}3=7+RYzyv>aj_nk0-di5a=ZSFK`ev)NUFez-~%|3f42X&lwG1nB` z@qmPlkSEAf)RWLtxGrl!H(2A4BSoY9;VT1nzQjJ*gO5)&T{Js12Q@M@SW5lvSn3}v zBAJzRVOqo7+xJd{PV`T>PiVY^RSRtNepmGAN2Tqhm8H3*@r)2Z1(#*KR`e|e8KhRW z%?8dsea&+I@EmgfDKRlIA+cb>h$U{qEbnPvh)jj=@j+(=!?c-`nF&Zo(^Pp`$)$X? z^n3Bl9^{NNNalNTSCoZ{g3=H5u!>O>OZDi?gZ+uAZ`0rAzn5MsClx!^3{K@#zN&gv z*RdFH_Ngxjlb=oNx)vKQl(s_h#niHImnSbpYbC(3wbZayJ#}< z7RG#$;Gu5%W^y5w?##)B0r)Uhgp*O4@prse!brj&`X&ZnCML$W3>EZx;?-jEHdQt@ z+F+iftVy$xmC4S58<9R6631Alp<)hS6(Nd17qQugeNXHR9O~z{zYK#7)16zL^Y^@F zKrk+RPo%?I=)qgblRxjgl9&bOkS$ksqsp{p+mZmn}w5I8x5576R zH3=m;^*V9m7C9Zw&rO@%nveLGX_w!~KI#zl6F+)=^k&iUaPg1L_2WMkhwCzMnNpeH zUnn$gcB(IB*XYpbAYd@=`2L|p|L3K>_u^AoN4dM5J(tB~`+u`p0 zLvGq*8=Jz-m7{jIv$4s6t2}Al)Vzqt_9TCY0#Mvmer-F}G{i*Lb?CUl)JHy9L>WtzLD{=qHvu zDQQj!qIaShg04_k-m@XL2f0BEh)uz#$gfDYsD)?}mF5`42He|Ax`GA1$dq6$l`(ps0D< z_zP=XVp`%n6*qNI%+}Z1H)NYVP-v@`WGs!*tqQ4UqJnL)M#@7 zU-!b64HmDRndQNsk^<-Re6^WViYhJBY)Q@g_-R;>FNlwU?=hddVXwif(k}xE^inP> zZ4wO_bMA{8!WN2US!Ex@eMDq_V0J#Se;MixG>D>I*PLn5wb8``{0c`pl`T z?eezm-#kAqUug;S43s^&Ix#%GpiL$dBZFvClm$-D4X3A8=)B2j8+mH~h40SrrQTk; z`e@4|%6=kM+afANXTd8Oz8{8b!uR;U@CQjfw%?C%2F;YtOz8P%bva$7ZpLo1Iikgh z#7!JbCUd1u?*t~Q1RGKojT=lc3lqj76}E4-SMp9PPfswnFE=gfi?`2jW-oQf1Zc<1 zak!45U$3=%wRXzpe?ak}Gs?k5cGk_kKVsRm`OX>-}29Wsee)PO3x&u{O4Dj8OD9a9mW^- z+V)!}9ZjQip=K}(|0e#%*S~^J&p*ulSY==FaJC&9XxE|58IcNE5LgVh)!I(KdL6U> z{#)NSRZ}*1twq0m^*>3Em&cnk-2XPJw5v3UTRXZWxa*7yotkU8Oqtlb?HB#PEc;<)NP0;53-PyXChze-IZv}6xz_n|ybbIhRtFYy9p1y?uMk@-wf# z1_FW21P2&{qP9-eOkZ~mj8=&e)YG(UHz|`{u*t|qkyCH_A*%4?pjWy z)OYvMwXCk?%lzBB*_c_VUQk8o!;q?*?VHbg-e zOaeepw{dCRiJ6!ej>Y6JC3T1W%zkVA0}prxmOb~(TPE+8Utq>4zgd`7KQE;W4+?@v ze&el|lanx$2-xE2JUDo34+MNB4c9yA>RO`+2`NCcJm?@*JiR||ZYcO9Kx(0?>mV}c z5p0ZjJr=`y^&)Zok0MJ19lrT5-2`D=JWFK^;lG~_S9>E(2OS*%|38}qKm=q25dX7) z|3n_h^#5!%ATQv5-ar5W01)F0Ao@Q(y8rb5M)E)T-#h=mCMYEMzaE4`g@pgt2LI0! zu%3}^_)n2~Xc&6~0JPly6QHKSLmU902+(|@^gIA~_8sY*oF8kcXiMExP z7Vd%We#*c&9mdKL=>sE!?_BM1mc8QL1_#&yp7=RAEex}&0d5FuSieWSSgDh^_)?l- z_I1oe@i^JW%%*Y+xJvP|vtCSbX2&Jex1I9{=E7L$8=Bx#;Bl0;^tpOzN#lZ2;%X=6 zo8H;{LyH-w7t%)a8{}yEds`<5#819RW?-1c*I&cu6*WE60^MrVXwiidq^3fR7(qp5tF67 zhoMAdjuSAcCbwTuf^5Zy>~QhgiNPVVQlDnm&xnpYAzlp|Y1RP&Lqdu^d~lwnoK1Tqqw(rxI%h$% zmJHg7QHm@YrPO-WE2$5?Eu634PJsrCVv1>em80*bA!)+BxUPF|+5T!YGYRq$3JzIV zcho93FTS^0h>c6TCZOf{=I|WLqsdwNLxh8%z>kECOt&MPZ2=egvX6`Fr%qMA*@H)= zhl!jb#cXkjtehZrdrL#ft7fZ4juXN$G|Z=c2Z&vTP=4Yo~zx#|{&=2O9G!DO1U9v%l41$eq_`p|RT^ge94n zSV$R$N`KA#F!Zmj(_1Q=wKcZIx`Y_gKz z4s*#6vwpr)#i8$sTX)Vo1a$fM`#aBC}TJz(h}>XH}h7L?NOhY2`^Cx?Zd) z5CNx81R07lVfXv-nE{?h9KXD|Ud#mMczulbOgN4C*_p4RKDQfn{rO##t|xUBc4^$` z@qODj`#;Pk@}*53b{$6lu*g3DQFbgNB)ysBK(s%Ik0_+C*kpd6{e)p>Xjo>~h=gVL zvY(7@v>D7Mkc7DLs9|3G`O;!n!IxGJ7??#Z=*(Y^mLblw8dEClnWMV@ZngizZz`U~ z2S=2)jOVmMLGO*<(=gi0t)?2@M2~kL;ieu>zJ0G6OENN4R5Bg+)Oe1fv@*xTCjMoD zgzDY~R}Mh(Xn4bG-d}TmwO@6gvGSu~f#<1_9%n?(I!Eq5iWDF%g zIjm|LiT8X2lHVn2vsdW9;5*YxVqBlp$=4(@J&Ipv*KvLH+uDolD>LTKaCHs6`v!;=y9X4gXRQG?? zrY!mR*a>V;#iZ=X>tAT`0Ij)x7s)TA`YFODU_5d~W!S-i!RvOiq~@~KOl?)!@Xuk} zNkb{|F#3A7c8-GPvV#7HTG=%9=E)@{*kn{Kti9MYceIC2-4N05Vr?y7(5@l1y-iVk zNVZ}3KAqlViHt=`(;r{txc`(!zhRcct-OmrboK-3OI&Om+eG;njx$l||E7eV4)!Gw zl&z}aN`#oxcj$9IVsej&&!`YrgubuxUvd{3=6XNPk-UlsP+u?4OH*sZjuwM;^SF6O z&{7X&i7Yp!q||+p36w`dt6OHJ<54lL`)o3)ApHox5(Rj{v;Dl=d%;)tZmBcjh03^n z>cu(E+ziO~Q@ZG%Ghrw$s>^U^(>IiXuE_ykvV)$|-pY(Tcc+gE<|xv7O)kZ5W(uc|kAA5_vy-a&lai$wRkLJX7lf*%z{T<_X|$h|GhiH-Vwc(LL(TzVcUX z_{0SFdrRDTlO>)dJlDhlL+`I*6T1_bv70w#idU*(&x{*Ww`X1z%SRID`w-JgQpHU+ zpa{zs;^6y*r-rR1wp*JVj0r0G48QGfDlCR7?r=Qg0qX9G(2E>wZ|!|@S-$r{QOspq zCdE15ay77^;3u{`ZseASLv294GiF1Dri2jr4-dBuC+OoSM@Vo;z1Rme9-SN9bMdNC z*y|#*X?F25L*w}IpB14CFYH9d-t$hvOX3yBl$_quzgsHS%=@M?`=VAr&#dKv$QdF4 zXC)nW7aX|xdyp_G$glwW16$L0EtIPan|jxU{YDtf%}EhD`=cZ$GnaR{{H5LI zdoWySeh)1Zb=%?9o0b5O7h!uWWIuH=o8MhBj?x0kD%;)wuE28b?N3%U$ObOSyX>jw zorhA?V?$w#;L^yi1pw=g!V0MWH&=_IRHwFlqx>|AkOV>+UgvXqroNVW$S3A)&m+v$ z@M8z-&?2)AKONga*Q~reiV$bh3DMKly+T~>aDJwWAJ#J~Bz7cV($kgsDxz`0qtb z9V4_MFDH+TR2}l9PY7zo4)mZ8BbI`Le2Pi37%9hTLQzyU9*OsDrBysO{R>(1eZ`@> z(b;L}x_MyM^>%xIsN#gxGw4;4+|fPtc{Sp>89c zZtSDdVq+XB*TkeUDn^`7dQO;G?cW|08;(xec@O6yJ66~(GN(=IPGxq=;swG4{8BB? zhz9z@1A1Xio4NCZ2Bw>q$#f zoodc629ab#l6Gs!vP)A3g>VrtHzM+o*xhtYF$G^qXd|q301So)wmi_Cxw#4MPN%)5 z0gde13I8mfCc;yrZQC%mS&ud!+-d~)J#)!IaTEY_#$ou;bfN%qiZWZ$U{CHDT;xC_ z&SZ82(RjwkvsSGjg01>$i$0B%Ra7rv?}lEve1SGbbLB_^27r*(sO*|+VZ3}i%@MHk z^$)AU0wps%fXvkImfS1=pw4p=C*3-Qk$=jXTUNc^As0S_!AXYA^e#6yk_W(_boiWv z*HlizlVd>4t}5X*X|aePs&0;FFSm-=B2H8fg`_cHcU;`=a}cx1$@#-PNg`ppSj!{hUuXn0?RawJ?PJ-rK z3jIoz-XAV&)z$EK7UpzK*2e|4{$F8$wH^S7DFf+ zDA%-}DrNRuZ$PkG;ne$7bfW$>VAa%#7SB#QBz}W@Cb7~nLLl7f!LIJpB(ZgmaP(uR zmC*hNMv2zcD${bt8!zffb6I9fA%Wj^`hg(LTs{y#)Q8;Y9H8D6t&fTL#%kw=7zw8- zL<$GaP!W39t}r^7ShAxDp{I|NOoW|4fyq)7biiqpk+9S2kn!I3k1+!$u`Ic2pcv08 z6_#roCzF}kz-f%L#oTIu8SZta@7DucGpptT*uI$nDHaJy;~EVdWtl}H!1$({t4*yo zHAdbqJkp5MPHHU-Yh+Y;MUQ2XyVRX`?EKUr$CTgAOW7pYIf=j z6=BQbBA*VfzUDlO%1)FxON&rn3y#&%8&eVy5WDhJAb7)2O@<&zbYbolSoY=6V*op! zJ_N;}8*QzcLNWFXeb~LzymlEyM}(^qL+hF5h#B2G~;m)DR3YXaI6o?_uNpgH5(D^#VMK1$b!~`%@sy8 zXbcnO(>KKMseTN5SB1G?cv?*QW-kRfv-|#IaaqIi^72N3J7xIP97{Xlk*2sq>o1kJ zk-3%+~h~Yr%>wXHh~DLQ=vGLc)Y!@!}$vnlI%5qS%iY z-O5Wy7SSI3V~EEIWPlqZQXm7G51cNS3bP_Qfs{^71=|+h53>vyo0P!$FtV0^y=1_& zvZ5mXi$L564DL)Y(ZTD#Std9#+nj#cOVE;b9?9jg?B)G>L>qg>5S0~kq(3UIGoB;S z6VOF(o3kXJ#x&?DNXUxWp-1$(vF&agd0q4?&Oy)6O!EQT-wJ#^vQCvs*-qJ;^M@YJ zN;XvYF(cswoz#?Zvw#B5#kP z0BzB)UpC>wd!Wpb&YUG|qt&PX>I8nS2eIEp0NH8gz9IkW9Kiq%;?Zwn9vLrav^TnF z9}A{v2t{R8c;;5P)(Vd^4%`X`+Cw61K*ro z=mV;e8_0TBz0<u>}$xIA^!#*2_Q> z50tVlb6RZC7)N?MR`0Ou#n!A>H^=M_W>4&t8x)NU{=M06WOMW%6D}&ziw(24(CoPu zEI24Cqo=2*E-ICsy!%Ha$prK-O^&YqJ91o&>)G*myEMV^OyRNn76BJrkMV9>us{MB zIwuae5@ikCk~JSJCB-^~k{aKVK}W$g1A`XTIf3C&^6V?L+I&>IH2H z9Q`#>XD?-$_bGJ~?(HdCWsbKEve{xB6xrp2k?$Y-wY+)EHo~mojk?3`ip}@l#Etjb zkN9XldnN2jUhuK0#RQj8#uwyTcyz2J#08Y^mQ)JE7Cp{G+8&ZodOh$nS6C% z4-XEf_?ZU-`6t(m@-?^y82k6ej`unTD1ldk!~b(WAg1WKVjQd+)wY~5RuicVE!?R* z|CiG|ZXFQ^XqlRRLS{6&P%E!y?{(`;I`I3ourt0@Xgeg_J)2SjXUm9m>FTa3upOAr z1_gtABT`t$a@ek(sd;EGb@IZFWd4H-iMwN&wSOT*YkRJ8=IRa{5Tlis^mL)j+Xv4^ z%g68oqVBunB?E*5%rSo7y>^~1w)?tF@}P|Mrqh+$({F(lEkqSTrfxWLx z_*LC;Iuz21ago_Q@N&v)A)la|`4={`>GIFNliiu8nHTPvP4_`iz^{9G)f?%AEIWyL zlI|yS%c89~&Pk>0x&?@^+i=f_+8b)1W1F;dZ*F;fol)1k*;vPRg@h0&t|xD-|5@9C9z-2gXqVNW=P1_J)f9K-`s0D)~l zXAG;4xiFfdNQ8PG&!qYM633r#8yYbjWiqil1Zs!o93^D0BlN&W5(?IV^`KUXMb_*w z!lE*5@;D_h1dXfHjb;GLqc}3GLLxkk6mT1=;V}mhu1uZMp4HeRU?KfS0$vw zH&gEb5T9l;N%65;0m=@xk+F=-E97o_ikf`j$m;PBT9NHgOFD?MyW&kZFA`!#AR|j5 ze-a+Cr6}zcm!h8S6%cU{PQIM%g)f4J++&Ii}$`;Hwc(F&5VanBdOJgF55FaDxU3w~59hUFWA-=O{vlBv@OAxQ$+ow79Q#eaVaPybE{vUKk1H`v9mgPfFj|hXU@BiUld0p;Y8@ zTI0Lo5w7HVcHv|!;2@4knJj-n8s_aDvY-OGQa9V}z)pfU^2g$hWI*Gz-XwrrkDm(6 z3fB>Q>2>Dr(~ytiU}Hs3V~FN6yzET#mnU``J^9pm@K_zjP}D~d1_3Xf>IKXEWcrSZ zIgoU=nP8c)9^f5J^HfAq6vohXl9rU%7BdOUvaVE*ujI#yKDxIw8R8gmH@4sP^=j38 zBfy|4CkVmku!!1uG_#YPPv2k->QGB`_SXjSLqI?q5CCdHE>Au|{+ihgp4sW){|Pt> z#wt^r5lkQgaq|1Mw%P!! z-=Ijk5@Btp;eo+=*UZdn!7`M|G3Iq-H*SxXDd4_E-<)7A96`vWU~Gy?c6%}SHWODX zp8^!-VLAg&d7bq-U?^B3 z5MVg-F?cS{n^aZ_s^{T%wDjQU^%}|w?BQ&B7|vQc#blw&l_8@{M&U8C@#`-3JLw#8 z8@dqe8^dabTTw@AG3Hn~dN{M$6u{1OoVr!>_nZmO6j>2iSZR^E-r>_F_z=6EEK)1r zUsRNZM@WVgcN-ihLBg&C?pI0Il{?P{fb#G;LY4#)*3o7V*MS5bc9$>3-7L_mWDvwrlaZHs&f}17XZO~^A@XtVU z&Igg?c0b92r%@iPS!{5kC1iL*_{8=U17ew!^_Zz!GiU9V=#J=0{KOS{R!lCJpuz^y zC1<_j%K6i%jb}IhgcErb!WN=Y?2`!1nTZ9E%mvFK5hTdg5F7isVwpZqI=qPHc6e9zq%cMycq8T( zt)4@PO7g;{K!r!*inw`o^I1Ai;swV(9FpyipEMLI@ zmWJy^6xA#v+e^g%l@vnrMSAz=S`CXNKCgrLw=FU|DZQY~a8xjFd`MFCT&urx@7>q1 z(_b%j4{}0Z3F*9U(KmnQOK=*OD7t#P*@q$8ed1WS(FYT8@)U6rTL@G}M=&Bl=F`1wJR zp~nxF6jBJLWBh3qGFGq<(oYv8^ai!)*Ay(ji)JxHdJZz(`I@G*9HV>4@zoVOrjpIk1LuV+ zh!vsjDGF9}(WAPJ*&IL(BZL)vHO0C>v`mw!I3w&V?5e2Ye?(GqX+5`X14d-(A;s`Hu6dZgsVJTe>y9H&p_dr%^%|>~gboJOJgqWlti^l}V5v z;2z*a98D+Fck#L(>F(D)ChCXI>4S^o6d`U(*+?wm;~6qprBEQKB(NSJY#BXRpd>`%Bt zL}t56%q>ARCcZg!tuL4@>+0tq7*XkxUcrKPH13<&I-8M2C*%sC`qcb-S*N_C3Vc;z zXTzjSzci(f{K|DN`En*SDdpE=qQXX0)31%@REd8xf)EDaE7dFt|=@W$`gjteha(`g~%S#!yFr1LCm_<3hYCVn@pbWW3rKIt^Knn$m8x5$ zMvjtt)}`Tk`@{l)T({?6PBlj-&~HA%<50?@CsH4;giZqitXuI9qw~qgq%{ZCun%r6 z{kGNkPZ)khh)-N}eG&*UmpVk|-VC@V)}U!tCa@pg^mUWGp*t%{>MpHjas$pbE3@{T zHT?te_UdN6Mq@{&5z;_iR6Z7|GO_UUvS2s$H#$YE&i^mZKM2#3ZuMpPOn5utMZJT2kdCu!^(DT*vWa1uwK=-Wp`JBd z*#s&D3?VoB$7nsy74sm)#GMZOZtX&j-Nc*%gZ|Ov;NT$@@L11Du?|tpL~}H#B3={; z`?_6MaG*pkFSA(wh6ZoS6M!Mj^(<(9&;fxRk=4+f?n#-;)j6HmeKL@@RWDiB8a-*ZXhrtZ=NruUR2WSLJaf&i2qNUQ!lQ#WgT)K_@6c4?;$3;N z{z87Djt_uGeYx~3-S04UgRGB|zkK4VG&xWv(*>{?5?PWl17(bFgJ>MbxCsLHC2kebSZ1_f><|r?C z{@mv0V~K|$pP9(5=){H|$`#(EvmM>{tVhzj9@=~`@KpGr$pN0B{`VxK5I zpy1Umyh_k;BqEZR`8*bMVC}>Hv_x6PwJ0;l%hStTl~N{KAuyex$Z~<+tjsfaicXgN zoep)PpT0k-QfWC`_(PFp272P6SNy!8(o>o{r<@}cpsqR!y1Qg)$r0k`sjRsE0#aIu z(RPgz*ewZyO`9NELKF0LhI8A&5=AV*GnrPVy^lO97BqvA#0#!LKvI;(V9{>YL37cMH}v5T4-TVO9Dn;hQMaXQx7w)vBL% zPU51ez7Jse#y;hBiw$(jY`A@<_rRf$j8UT1!0cu3W{5b%+; zd;<(GN>zfWgYqAZwuu2)in~||qk5y_NEvMz>^-|x$SW<+gr}#4-?rtixo{E(E7?-E z_a|@R# zU9XzIU=}fMSY@ej&{O#dE?>{@UWcz%+jEE)a<6vB?=`(+*0q9^I+0DNx+dtJ?XjxG zFx96)zHw*B>&Xo0Tc<)~K^%e=Pf+FG-GmQQ1q{WwK9q5ARlid%yjyVA907c|x~CR< zYH~zCzHHONF(ni&-c3P!rOGOuPNE*@W5c|`V~EmpzLJ4}WOj7GP1dVj{IRD+U)^W5 zsEdVXq)OSExrC{D=1<%l_wz&4eSQKb=p)9J_4;Q&S>4U1h!uRmKuxd}MCY(R=|Tx# z3U%#VWtigzeM0^3<}ygRZ&K38_Jg6O5pLdqfWsRaAd zb4fI2!Da=oc!98*FjC8>JbEa{KxGq58QDml7dvBY`5qQKo1nN#g8DeHw&>_Y!;j1# zUiaqOeH-KhpO@Ip{;$P5i4oPIiU6B zodu5cwpFd8Mx1s#;lYTLbC%|jCX<2Qh<%y8Po#JAV*@Okks$Zd3#0$Y=7} zz_;fqOYOr#&-9p`ox*8m2H;cimhkVoh7;3ATqbY+{#kY({3>VW81SqQ)}0@GG8`Lt z8&xrm;+PMi3YsQ59BmCa+HX1;47(Zp9Guoz(6LJJO;pN>>?HAbrx1zbME)an2pfM! zV=fX#FN)pUwqwVUJ{_|fB~2_D{Yb4Fs%w*;P#YD+t-8XpWru;l;0THy=?S2&N_K!q zG8+A_PuG_AH*bUEo$kfv0455t6AumoIK4H*<-X`< zf6hN(D!qAR`%!fJ2VZS0GM?>C zfYWqgqS7_@ulT+44cr$vvmOv(d~}d+uQcS`YpMOTk1y*T&nyRv!(mC>2ObR3L@HX7 zC!WONB<@R(+R?{nIvSb2J^}G;+2&93v!DF^cbvNVpsg+F%M%Wd|1!$`mPJip*_J5S z8w=6nP#RRl5|?#Ce1y!OA~1>-*0eCWOO>}TrO?4uB2)DSvnBU9`0novkX&tq7wg5` zCwVG+d=Hh~tZWCBwwtNqoC{mxVW3F<@FYYrRp&EL*2=>u{Tn-Tj)T1~OBIEQu-4n; z6J@I!gl?1F{0y|gCiJlPV&AQok>Wd6iwJGJTBU-e0X$VMniYM2=_#ujnFWH%wN2U4 zyzRU9??yr4us8d4#N@4$`^FTEqz6(y!bI(QMx!Gfu<0X1CgtAl!_T9iL}!NYrNvCb zR}Ur!D&YE&qQkt?lS3r)&*XYcP=P2NTX`a(3@+3Q9PimBx-aOnw1$&S>E z*j7|0N)Nxa;A+O{C>BQ0ZAqx{c$`ogko5OFTFR&{J86~F0vV&M=8M!1J)c-@Xjm{l zn)pPSP<*8ak4pp+-NO~%i(+*f9IPy-aCu22S`eTYSx+Fzi)4QARPIqQMi|<6PrC>~=+@Q>O2P1|? z+GAF-ZNbJ4_4RADnNzxo(IOS_XjUrBXLEF`=k=N1{Z>^{h=2bgT=M*Dctj^-jSzR9n8DNS zc2c=^wYDK~(gH|2cOe;PTexgUVZ-YO^M!yGt%tgH{e5DQ`o;7~^)kt2<+oORHZwY$ z#bd?o!=_l`yt~hO`y>V@^|wKkFkT)x$}0q~h}U>W^q;sHdA8}2euQs?&{_z;|(^}I%uT6S1^COdK{#J-LdAnCo|-fC^BeA^X#4l9rX|XS>DK%15p0Yu76@0b{d_J#CejV)3^e}o9rOUhE_)zXKA0+F+ zJ5LaN*LZqRS28~GY1;{a3%+sn(BemEG*f|5?b?F#O~i?A1$u2b%Fq$Z*j8~{SlVa# zZpr?2-m475dLi=~#W<&nY)QU4{dKQ26}!O4cUJ8mnIG~ATz;E$_=H$8)a^xIvgLk@ z-ctI_cl`au1Ks2g)BUpNKC37hVF^tmR{J{`Y?V2CD>hM5YXsG_e_#;nU3MRw z9a{VLn@T=7r0Y$_1L?5r5bn@<$-TVVqI z&szrt6fG_1rAHyCy?jfTpGt)6&c#x*>0oJAY6Qy3~o{HbUCZ z4KOV)nI&xA^{QN&^wiHiiYcFO0nx9J9A%$9cX#szJ#0KoFtYmgr){b^;)kc;XrK+- zn6G-1OceKWXO7&LS6Z8UotVkaNb#<~D(_5VneWCBZ=s%nz=7ZP$78bl0!Dt!Gj<@A^ns7SxAO~1$n-{b&vDoVDmmmdQC;C2s?x0-rZe>R zRU(6r_Us#pC4yUbLK2>XE>|+~SCrNtC0DimT^ta_G-g0;S z5k=SNe8bN5r<~*Oxczz=w%$Jmli79Kk#Ci=zJER?H(4DFTR`U@@#|Em%YOk&Gry2)nnPsC5e%qF_Rm|C z3+<&McZK@p=}cSpZ#M>a3tYppQAP@|50X`-}Is->qKV!B3UEtm*fUBQ7Re#wI=YZ>(;^eqxiu^{C6KDa8y@F*Yk+J;SjmQLB#Bsu1_PLjK06c+wk^rj=F$A z?PX-XMiORlb$9oC^{E_-#jKZey5?@j`>*4jYvIprS4nge!fGlG;*O50T~;D29mTvm ze4S6SiU0Q;M-d~2!)jb+63{E8t2tv(hlr-?z-VcUq%EsUllkL+f%)CBij)1koR{V% zTheP{Ee9X1>2-Ec5tbg?vNiEy`TyAZ3aGZ8=Is_K1&X)DrG-K%R@|K;r4T5zxLa|T z;4TG%y9B2ccXtWy?ht}&aR2hN_y5Yro|7f#aJV~rXP#$fcJADx57r<-7A{K)dYpp| z(mtFYN~J*^YcOa2{0%wg%OJQ55lWr5j-0o zN6cHn+3Liu-)}Lxg^0&D+PGWmolvKLEBh@uVOI6jAJFPB9fR*99`#|l37*6(XOL*z zG-=z*0{-&4w#um2vRSs#yw@&Yo4g($RF|Ko8ci;WLUX!+Eq3Rh>m5#_@!#Z<->Qyg8jMm0D;wVMppTNfX!#?* z^Sp5h>HYI}YE8m41L-dpmi-(kF3 zI@Jw^meCZFw4-_-7jf696j@eE3xT1OjOL{Ezob6B_3@|zS-q0Sv3#;?q8`6YSoTvV za$p!ae$Sw@#+6UJ@p<&?J{?)4nAP7#CD5E-mnHf$trbly#Diqnl?RQxXq{ARbYCJ3 z>N#bA&vjdg>u}kObMfdea~b>DT1lTXr%>kZ=SVPEcliyzIxr9gMhJ?br}0=}C=H)m zv^@!_9cI}uHtOplUjTi8UC7rz)h=+JkCLmSl236c59k8cCs(R{YQDk)nJR@~x4tcm zrUiu0eAw2j>dHXPiomL>(gUHHrnZ*2hu0Ku2_P)`(6A|9$h>`e{G|DKxp1(_3I$SE z%T{tu)vWz%Kw3)4x!0Yy3_;6+s>U3pkDJ_&?j8X%h0=a2 zTz}}4Wu7+E_R8b!V;MXz-t_LXESIrKN%y5j(&7!xrvEy+O%w8>Al~NEx(V2WYdK1n z-q9lU9T`*(0NCO0Bh**&j(T-)mQN6!yKs8iBrCumU|IA^#YXEEZGCF~+`eZ|{1Eig zN#e4Mj#`gUUpLIbtKwxNs~J*nAohbYy8X+R1;{fTlvE0*7(->bboKNSEsIPo^~o)= zs?JvTQHL&Ty506v*y4#b3@g;P?NHj_HR#n>v18ie$Enj=e{@!i4lXf_lit^C zWMZ^c+il~X=W>x9YA?cy>`PliB3nK$NtOxLz{DmFFl0Pwgw*h&4aA17p9m~-ixnqM zcB(k$w`8iA_|a&5ODIy=#Zy%a$%yH%ctv*QAGzGE5=hQraA|t%;1h0!l5VKx)jcXg zDN67tmvUBY+dKi#+OapKVa{34_TIm`L%YEYdWac%qumigUEWdhIq)F+pgiiwc*yv0 zb~K@Y#8%^$2fdb?|0^1C2kbGh|8p7(JX9HC_*=^4cQV_NiE0ZL`~&@DzdE9t%P@qb zQ4Vm!I^M{l>|cSJSK}>in?`M=!L(z2zbYn6ApB9ElESD%pWyp{#2~g!z#ePr6DzZ* z6oJxlguSDh<&T}Bj zEv;3VX9B(U!)wn=w*?!6v*U41DE$fV2syu-wY|7u#A2%a(6Pq9InbfUE`3b@>wskE ziSti-IT7&a3URk+iEo#3S`()GY(4c8ou{d>AxpeLIes7kobirp;tz3qO_y{9ktvhC zDq2R|PTCPC&jNm+%~Rot%TJ5CW=f&uKS^CABgl)je_{e7tbX%6{*{t?2(ujUSC$Uc zm?G9Q$+24%i1UQ8Ux@;rjW8_0sw5Wog-R4r*9Oa+WvrVUjLM_Y|cEn(F~ikLLroINn}-1lV#FK-sB7EdKYN7j}0dd z&aRkJV>RCSD@fmunM^0ua9PPXXb({x3&9vVa^K=F-%sYfF%ddV>QFLT1{lwAx;<}S zL7UkrC@8SoK5m4;Id0Lg5|Gibi%O4OUzr|jSouu9uU+gi$Gn0c-7oiNIk&uz--tm7uEkQQof$((45}X!83uGs5x?)-g^J9{qnmApUB~9R)v7`k8 z1nVYEImiY}i_d#}Zemmxa~HD6F{EaLMF|p^Zfe-&EqQ8_ElxZdY%Om`R;!Y%=PXGg zo}w=>{a~vlcE!@?saT+NDGS@Z4S1ouN=>~?uPD??8C;piM(cOeDLQ;qG|$={VnFpp zibQCw%75Y+nfM-3_MWq5m*b8IHmXcM&zGWSD0x1W!|b*O%Oc36>?d{4(JLFB66pvM zuQZju#ZNAM!Wy5vx`wr3+OU0LenoZS$95HkAw%Q(#)8;JPM?qi82u&n zS)xIwPyz@gaW+xuR|X}mJy3~i%C0$+jrqp+XyrG}hIaz&v&0fR;qf-rA!T9pPdkNg zBa=*Y%3}i!9TYlMV_sQ%Gg!~4em3-}f<;gjU!LrOb(ei^b}Y(;z>~>3d0`m6#H%YI zDn1ydr64T{t>lKW%kKd{G~@+D8=XKSP?X0if{k*wBK#b;%tALloHXf9 z7S3u*CBtdl$8?bezm%=2abG{khI_27q*pU;-$tr(+8~A4rkmMQhyeMMq_WlE6y+|( z5`VEaH(U7vpM0wvzGq24=bygwPj4T*e&X~RH?6;eBvW>p{pr(h<@>%!Hu@LE<~mj3 z)nb75_D!@!X>rlF!SAw>*C~yj=aI{eJLA4W%lr}E$Oqy>m3ApeRapA{`5PY^iMv<} zKKV!(UoIcjfnKjVes)#N3`39+?hf4tslv9j&PBeQk4QV9{pry=etk}o&NExlt# z&yVc6-@t$%+Agj!In+aU45FC=U4y0#`qDD?T=;gubKYZgv9vmdF{i$y(_+f?u7irc zQYcB)xhm!gNKgj#UQ+BXx;is$zqcpiQwNLVTX}QUXN)(U!4BV{HtY;r3LW8GfugNC zL1ODM?rTZE4IL)}O;dA1?a=L1o;wyb#l9fM^P_Hg|H?6x(kNq9z&EC!|M|{U*V}UM zK5ooDKf<me|WpN%#XL^z5N<8oo-)-TC+s}SJWEx4;^!_Q>8FjA5niYlJoR7 zk@SA(dpBfX`s33^ECrHQ!$-AYvk3;FY!22;G_mAM-%i$2YlTYUY4yzM2^i;~=}0$` z4{$pw#T_eQ$W?_n|FVznvimZ6uA4+E$uD=NY5A%WeE$XP!uRTk&gk4*l6r% zvN##RD?T4q+Ce6CR^rqsl%G58rL8tJUwtL7k-^z-Y31{H?RBlA;+bbeEEPd9-WI*k zX}@lRbaMC+M2d`xj3Up@zjNY=3`%abOa;Vk_476le9RR!@HAGegW3geRbgJdI!T&X zs&^<6oK=t;HxD>pHD9xmQ00k!F@AHIXRu8S5HuWkuZtU>hAbEJB7v0%^qagcQr93= z=MV!DW7y3q@|(OzVt^b#X0)NluAlyvt?X?80BaSO8ifK;-k1F)iTTMWY~qIalF?A@i7OSsLPwCdww_-ZSoZ@CeugjWQ~zhWv$Q!h zUeInsJSQZHmt^Nq+_Pw8VX?9aKrapHM3U9G43G+?v~313sVclpp(&E7Ky39{aYV6N zj>Z45S#$iXGAn=&j5`MCz&k7moD;39fi+Wu!L0hTc0wwSLJgX74 z>S?l=l9*2?vsuKpeLtEc4pze;$|ItG%@-aZ>K+yH7 z6dRqK+34QTgaFsItwhI>4L?2LuA$`^U2E?FKf_080$SK1FTWi#sphtZV*QQAs{agc zmB;~+RXLA4z}>Sa=whzxPSbg%6QqLqF6|ykt#DU!tewU1i7dVdQgk^vzi+UAG0$}r zZHyiLVXnlAtaE`bsivQ(uKkdxJo#4#2-9RFMf6zOTfw`?(ahp39M88L3(7f?J1#F? zE3CW_R71YAwJWe1F;;la`yiI?xlXx26=+ZPa!Bv(W-@rDOZEO;;9zUw!izmq<{32# z-LNQQp$RO!!8nt%hSj*8P}d=wtW+WU&){!-Y9KNJvXj1;{B?AuLcwVaUKQIVg(7g? zAgpW9NQ`c${u_>=)6v}0?FIpkX<}ui9w8uZ#dWV3o=tiGelw8~Vmwz3re%lZEa_X( zq!)eX0j|67dcbp9@Rh1IZc;ox6)A)sC8DYuEE-P;pO@#WFz*@~zg>+%dBtPOvu6KQ zW4(YC#Oj>qGULOBG|cM!o0g9DJk~{S;*I%5iFT9m=G zxv@o@{nSxJ7JpkD8Z4CY)?Youpe}B2WZ2FCuC1-VY})gocmZYDc~{%s67y6m!@;HS zS+KXQVof8axNljJB$AkXvAJ)I^E43~o-Gp$LpHe3LOZNZ*EeWn&05Si{X?6SOT!QN zA?_Alow^s^U0`*xt_0tO6@^WVD4|NcT!s5jOy(;_ds!i1_U{R#0!0eoPEQVXs#Cj9 z`3n|n<83kQBc24?_*1b#7H+ei9F5WS-yt{^s?0sRfwslUtNP$APS=cV=7*b5C&gxi z9ZxB=;t?$ik#wrh_vds^&@XdnWswzyBXdG3XyErsto7gS z8j#jRS7cD%EBdOoz!fQ~a$fp=b3V;MZbJp0R}9qwX^Gz1B0tyMlTr5(5|vI-7~I9# zCs@TzC(w)Z71&TnexJ6~;Qm;^PSn$=nwMwd>GjbbvB{~jsrw_olAo4%5y9$FvW0hQAhstoHV`6H>aUd&j_M6z|l zr}rHel^H>bcQf6h`uyW`n!yegnL*d6HAy+e;}@SVZ?xHbXn<#@$Jj0(zw@y@(F%=4 zPkd;@vOt{mp;B#b-(XV(?4$l7{SxE+wJ`RC18CqDSU*`}#jB9vxP2utZG*SzwM}TD zj7_*ggAzacTPfiUn52#|QIhFv1X*_5$ca?QFR8GPJ}(#?f(WPKJg>x^aFTPY43u*V zab{$C7+lWg3$xL?<=^UPx2TTLR~Fw^HK#pvYJlzX8IXeTEBXpoF;Ha zr2iCjop$XYtH@<*H{IKC*WAj*VdJf_np3B6TW1{_yX)I z46%u{jRnqjn~l0FWY0U!Jij@piq~wt9oB#aAbWve>a$dc;uG6YQr{!ek%0n1_bZ$0 z<;xb8l9M6*G@|o92#q)LR(woQqXPJDgU&#lIUc|sGMqc5QjNR}6qHGyHjH~W*Wi~& z*MsR=%R`I*JCxk;x6!O_vODGw(jVi}7gfKb;OCFS4(rm-y!Gs1JKA}~Zh|L!!43Gd z+IEJG=x;?`` zlwWKiKlDT1EVg8)+yn{qcT-!I%=+Z?KNI&BQ*p@TxHavKY`Vk@X}6xYWV+L(UY->& zN@Q`w6A&ny3}4v@Y|zs3A#gR-0W73e&%@AuFak&{sjNfxVx@Y&hEc z9!%AQAnnLXS(B1y5Sy+^p|OQ`9J`YzVzlSM*x9c^Vth}}`uOJYKyxMcH{vO^rCC+> zo8@mS&Z+10aB@TFGnco;y>%XY(3)OSp>Supn^2^+1!u5tM-xi-`>kX&3`XOl?}otd#>Y$t}%yJ-J&L~FP9$Fne#%dX#tCd^3z0j3i-dWXOmo&)VuHFX;SDgvxGU_I+!E|%B zQ{@ao9@w+jsI`ix5I2IaU(XWlZ3*AAz*JgYKk0<=5;1%vbkX`vxH>U_0=%BNFI@8vuZx&adK?z0R^J!vVt0Cq1OFqld#IePS-~PuJao{0^Cm z#y-8umswL831>qa)bp{4vqFwwFL&ljV3yw7^)H2jo538QoGf6(_J^{2~M8W8! z&_COF2}rRULo$P=pdFgSelifF$Y}vr4st4*?^XCDWM;TcDklW;`bmX#4!=v2w@^!q zFrQCTez3Dazk7P`!A|@AnU6^tpY7uN4#$YmPg;tESWm_XgA%{q8zxI+*;huXV0NCw zorVge>Sz-ht`McJ%jLkfg??SSU+x2GzAGOtH#4M9R+tRdpw;vg+VZRmd@?>CglCx* zeA8x6<{$adN|AaRRXzk$0^c0KHCoRXZlVXic}!gWxMmRsmfvkagy~CL&VF;%q{V&B zQhH@^I-i&0lMhO++>`9==ohmVuZ@F>!{C!~@U9lffKYSxVAI{t&0FxzWWGM|eC2Lv zC6@AT7475`iBscpvzs%KPYV78D#h%L$lT@FJ*;=F(=_A44Z<|)IK^KA5zO}nleOMo z@WX^3TUSCF?L4Db2|DP==vLAN-Sp|7IfJi;NqES3`b>sX$9gpF%hlS#geEvzc?t<) z?c}!|N?2D{(LF|ptH1q1+>U=At1T5zu$_bid!i^nrK0;ww?BZI49t`s`(qUn0j+zkftddynZ5h6Ka znz45vCFVn_5Of|P0(+^#YxZPLO5n5E5wVaBk9bnbUmaGFkNS@s@3 z9+F(6tor{ZSA*}%4^1C4HtOCw_XB<1FZPq{;2Wlv7&KC<*sRViE@odyQg410Dx8+C zF)cBU{@1W^R?B!437)~83%l@jsuFTNvjN^$s|?7tUKw3a$+9GKtTnGQjEz^%6R}06E(Pzi{SQZ-{lA3dT>if=b`ZN=CXeR>>>#$k}~L~ zl}!sEqt#EBCrWK4?NK`6_4v%m)vGm`FT8ceN#ZeVr3(I-ng-iBQ@DmFw2}b^br6Su zE)9b}71PrfxZCLSwWa5a-fg-UZ#J&nA96>Hb)=Px)ZC;+c>q4c`dG>Dm&AhxRvw0G zs}JrpkE~)CEFkgxQjE2$Abh$W*Z^aSb}+$iRn1TEcr=!fPM32S&}`7k{g|tne64-f zPJQveHe{61=26ujR z%jqzp`l?mC<#OpL9(=b=2lM6XI`7f0&i>-sY%l`~8fc+AW7-IEj)hRH5CCE>Wtd5i zDEJ(H-NAGojNAd&&YoM&Vk}M_h~qR}&chlI@O9{<0Cf$ zvCyz71+^beogcWI#_jWKiB^2pH(>s28m2surqZ@8gScPmGA zF!+P)jl}jWS94?WtBe`uP{^y|*Y_4hBu4e;G9Jqzbbam*A#G%oUfzCjS=8zn!%90x z_g*XJfap%K+RJ=F(H5Bt&$R$#_0aOK!)ai~mFdQ3gtQ|NW>2SJra*!x`M}mgL&4kq z%JPkl6x$P~S^@~bjGB3=mPq|WrM(KYfE55zd##T~tS!V#p5hgn^5?1GUuT2=e3sNc zu|F<$l>%;+XsNefYXUb3C|Lj=`}CF%=fTTz%fGK{m)T!qpI#Q)IeFdRFu<%^&kx`= z+9|2vG|a%*DG;ma6@GBv>EUS%B{0u@9|~s15#XUUQPn8`-i364rniRE7`#phz3^NZ zTQ_}(L2M4`djuoBeXUt4Ebod1Ww7^_Tfm53GqiIzm**Q-wv07X+pDF)uD*B6% z{`s8I@UA~aG-Gl1x;oDEv-8$r2|BAz>I)@Yua-_P!T0He$z>~9 zwikM4&Nz~If#j=wsp+eU0AH;-4#m8)<2@hC#sT94<)M5v7M*nF5rNY%r>O@f52sxf zSaI$0&k^DBipdrvhRJWFI7DTb?CtylbLo_A2f zYSy;3!-Xhd^lZqxO+n;zlGAX5W$yGb$RO`ic`%>WaH>%L(QnIfHXM&>Q$1RFA^vVq z@oymC%DS=7{|?0Y?kC<%iz~frXvJAR=1SmoASoL)VXN&eD0R~}y zVbB42HxmGu$-oXosA7ET0kvW;nP;_7;w|Q9=SGo?R7$wd$ijHMaTWVrJ0bzic|XdlEF&Dq(&HR` zd9*Qe!mEW%icTbhuGR&9xiDJUDl6ulfNM|jF&5OTjFIZq=>O^s$$cLe_a)pDhv-vw`Is1!ere)~9xeWAoUwoo$!734Xih*HDg&P?R52i6{c%jVc~(CQ z?7kvasWura)%L9C?L8W^;x7Ef+eTFir7aA z=h(Kwr%EZVV6rTGe(To#yoc6D*!+h#tFzaNh^qR9&yyAuH0y0kQP)coA;{d`j za`!myvn|#Y`a&S#*|D*q<}ttXl&N<4l{^~&bdB;-KpO~)Lp*i)@aYPrd{7-{Oj@Tt z>xg?VZa6{b#>hU>9J;*W@W=8+g)5G-(L66=C@T5zmR3@lcM`HeZ3-TX5-o(29GObtzD_N zSK;Z~I=6(@*Uv@z0u*jhpQJg@Rcu}(sAQbbqNaDuvutpeKp|8%6c(y;r+j5jWEIOkd~L`f;_5^8WI1$>*qcM0m+RzB&DqePn5EAC_qR_jnx5^mGiV zM1C><`2v`h?}+C`Ww`+-BD?1fBIEttDACYJQ^>MSqgq0?kzB*u!##7TvY zL=M7fY5YBLiZV;rb-2`Mu;Lw2NC%JvhMJ3*0|Z=6LN6+(}@GU%BlUjw~%x#ikU}^t^QT zs=XVdyjQ#~Y`tM%T3aSdc}V6K>I`1?+0+=MlTZBs5UL;f#MC158o>=%B+*)h^-8Dr zM~@=dhtcsemy|6NJ3B=VH*{ckHm6K}j~fSslRZ4%bsfSc#8+Z>@U_|fp1@#xo&ZW} z5ga)Er(bQ8!uXLUNR=V*>_a$n98l$qOXeX`e}l&U)KO2HTff?&^xtIind4;&r+7ZN zXX`82T6$WTYB(1DBEpRKdgKIQ;&ZaaPzNB^Zsq?1V51}XjV#W+1% zSBDr|MEw1klv6{q#S0W+E`G^11yg?stfQKdK2gej1o2uWn&OUM0dB>?5BYB#K?55FXTJ(jCf*CR}l%Q706!R$WpG_shs- zYN3@zdq3na8TQa)grRZ^!95PUg)Qua7deLeU^-7UH zN1I$#Tkzp}MEJ@*=v`%wZG2Fn5Te=f-+~Zheyr8mYs0ZA1GJk9s+7tl=ro@xU1J;E z9Kr)StfqN-DX)8_)=39fK@ky`>9nU3KxIf&w$wlq+4gHI5NfjDosiRp)nMzL%A+f6 zh+BJR0{UPz5ovoFSY|X3KO3DkJREw?=*Q!EC$R{l@4T6|J)b0U2fufU#-g^${2TmM zhgGRoc$e)={8x|)c>0>e5Bg@9aK}`+{#j-Qs=y;!vwTWwxvPUiPAZ>APE+w^l$2zx zzYZ%atK!2d&I47Coe*ocik(X|*+3DD4Ej+gsUe51kHC0pePtABNYs-OdHp3NpF2&B zT|V^2dvJi1!fn62LT8{*Oi8fZt#{zIpmv9MjGcrF=m9?|>9tpG~UP2t1a)9asuvcWCY@ zKV8yruhZc}(Zu4SCQok{!4|E)>;)`0z-4!zzm&fF9TxtJIE4=TT z1rP;OdflDCN5yfvpJ_J&1ZN2T4vb^(?^~yI^pNpuTQkgTcmBak2Q?!*7fJ$ZGNzgzL>Qa zr@V8Rgv=5~*FtQ7$a@;##FZ*9a5t7>wR+_4KCd~Gw|7r9(mCRB>G72E`!aBE$TzB~ zDp_7uie|(lE#2c{PW7;DDHW5Dc3?8s^ni@-1H>hhk&#LJvTK$O84!)=nfTX0r1W(i zBOeaC%d#4FvK(2y7f<~~)vF~{-YT(tPVc^-#fDRJuahtf-(E++jyc$ooGgW8Hq;IhI8;BY2D${X>{ty|BOL0G z<*amyg*SoC{13WKpzUY>QD6Up=#O6zzJQ2s z>Vl~c=dsOCi)&Zh#YrEnK1?LABp@2H#Iv}sVJZ%TrmtuPEPGf^ZhKenQ@n1i7aDt8 zMZNx5To1qVp?gx|zSrd}AY!Mg=+f(IEy%!+c^P?C5L(%x0$|3(JdMilobdr2A-klN zoct?ZTD{QFHBwt*jcmpYq(l8=QKYz{Zj+$7?{f9Srj_&UM8iagsr%8sVoCe&k;ahcn1oY&A~(i zy1F(TznnuD0W-YDQe(gSiNej-uB>Qa9R^1kbgo-37sr3m_Pkdu?nXUa_70j72+J2v2RW`>N9X1g#1Yr=Y#)Ih=Yt13!kwePS{{ZtzSsz~-YGhJ(oYt72W>q*I)tT=&BY zPkauImI{a+JeStc){ylzYX0E~Yz^IjlvI+1qg-$MFU^RzCH!ryh-U=u{n|Mm0+EMV z-3%F-2jid+?1XY#LGtPTZxg~!_m*YK`AUSk|3+j!bI z#KIVl2%_WgJbt62CGoR1oq_xY-MSq_gpRu0p2nV@9KIW4WZ4TYo;x*VwK#Y=Q$F!; z%hE+w)fJ72G>TVWL6(g!fMi{C|M-X6bfM~P*cF^b9;m`H6ytgAkO&H9_LebYR9{ba_8Qg1+IEHj)20;` zdBm{v!}{dAr5XA$wVlz!USkbs_@!@s(Z8}(&cjGer<}sv*)v8iyRMhawc68r!jpbC zRsSTX%UGFox9UJM;||h|Y5+O8_z4sFI6ce7ZrXMn!7~NmAC7q(gUb3F3Y^0`g@_pm z;>XAH$8#@p?mcAZqizc(gT-g6h`Sl)F1mtkpsxo>OvFZ{G7g6YZnm@6UO=B$cIi2N z2arBnX4M{$(H>Bwz+I~NCtx6LL;CXJ^@e5-+_1-ar)rGy{bdR3*VtT_)6*f|m1zCTV8UnoH=h@ zI@vyWT{i~PQZRw07&t}RGd)W4bPMnrD>0{2#H6QA2GzlMDx2oh=FX`{6unj~a3OX7 z%G=JWzLur~)-Ym^?9uM1TFm$2*M^gPUstbs$?cM$GS3eotxikU{!50MCx}=@_ZBOV z7`x;ijbf5q*h!jOr1b+Gv9Mu<0HUZIw&c8mwPJXCaj*t11K`UR1;La@dPTL(k@faQ z*Q=TS)H%(10rFv1?6QOpxRt5N!;<-(GMlUDY_b&JU)!;Lb>4hh!?f@>ciRxEKY`fW z0!w01E#o?t?jEr2!<9${*N4%SH9pnalH{6>|M{24?Tl?a!+zDGUcOD_Tc`&Nw!0fA z@Y&_1d77)wP4a5eQSU4*vTnXpW6Q3}~+HQmn_-VCc+ z^>u*#2DQ2{yau3kIF$wc|3b5mmDi*1X0wgn|w$ zCsgwi0z&GcV)u3uIoXo;VI$&9Y9 zynJk1fu{#Y;8-LFs2)~1C~xEW=;A55kZWGwiNBC%zbD!5j6h6rZaQM~e_`oAnEJ{<8b}`q%&=}hT6)XBKuVG zvyCG(@#i2uD%Zw(=Yj(dA2asp^CP6~p{sXJWv@M!^wMfV`WE!K{tx2+UE(1mzm`tK zTXhm*K&@|DTI{tw`@a@B!5kHYr1*JxiAw|5JFixsQt`Vwj+`a8Tel%y-aAL?@Yv|W zHtIv{)&>hyza9+Lt452MP;Y_;`(o%iQ}Ek3a1ox-Y<;`GZyTQ7}oW1ionGH5z|P~&HcNxp53Wr)mtUq zC8a^Zh$*r{IU#=P!$n5ZVQbutm-{qB=@TA=S1_IDFOdR7-YERv1PvFl3uN|^ZXG4b zcG#mZ3tBqt69loWkuB_(K|%aIag1*9ROZHMJEg%Ykc2lMFHqF(53f&b8N1%mJ9Twe zV%pb>Bp_|8Jw0{b^}mu?OxVh4qW^)ROF=&g)Y=luzx4GxPqNpb#dDHzPC034ARte9Gy1w+Iu42G5kk>ZHT$u`7JHwe`(n zIg8_|+ypth@1O&i{^Naz2hxLOqqJw89cd4a%>N}HLRt}&hSWDp@K8lfY9M6l+{oUg zYq~Oqy$CotEIvIr&)aK92rbx-p}MutEO~?-JY%Z zm$~HKn+uzVa-|J>6*zg;QeNqfHGmA}*il2ed#sml*& zOp;k!S@n=@q*DC;RJ1Y6uKdjMREsyxi_oXs#8GANT|AL_QolPsjW>p zKR;h(HW`%t4xG7{D;Q*0Iw3@#L&z1RwYjwbgqVTudHdHfY@!WhD!WuKQ8#BX=227Z z8FV^*f8*lZdWBzLqf(uN6%p-tuOvKPdisSIhO1-kMsH0V?6(V3ZnZGN$Vl0s2r~qzsfc)tKsP1jSit8t2$^tjls69 z96Wsw%buslYwE{%uiW6o=oK4$6M$}gE%qV$35n8@aqJqfEN>t#kvUd{7(4sY0_6+6 z=;w5E-wcW(uO~(niAQFBL@a%>&^26oYo?kf7e?(lvd?$FtNH)g)b}V2?pb>juM+yw zhVb&H)ayx9Fjez|8sei-c(-TMGdA}bwby>kd8rHqHnqZ8mejsncUO=ufeTK;a-s?NH32Ww{unHOW8!kd;MC~P*V#j z$W-&End6vjOw#Nm~?S=M#Ir56(psne$en4AGSgJ;R$Es^q{)@`0rCT$26%o zA8Sz5_I!8xoZ`$v%33F>7zFUwX@(Fjyr_QU**=_<>0%U_ift2h^x2dO!ugnY0sjuj ze`_Q)ZX`ENDG{D~=YWf7gj#2Z{)x4rG9foE(ZZ(& z3DL~t{Up-uLwvO*{LMw2>r_ERp8lv+GKK6U7!35!e)wR4uCh7cz-TlQDE1CApKX&zRTysZ+q@|tNC>v|^F2Um5A*5!OKJ#Ic zid3q0t0Z6_#eJ&*0`x3ew8f^>@eLC(HTyVG35ke`OHZmsdSyKIJmmo+0g1P7*ZSZ! z0M|5!7PW>!ggc;y^y}e&Df%CjBNQQG7sgz=-OyOTQf}vnr{_G&D_VQYpELn*08klSS(yH-`YufRCrWdjifAakmMfA{-yN*xraAhzzh?TK(Sq z&#k;f_0h9>6Va+k_Aij`xY{TNxqY;hq!? zaZ#tIl|)~71qDNW;!8B|*p3>^wEn}skL}+?dh~4&0+)&-VkI6Ksygsjrk6^LEgvV% zZ;L)Wbu`x}SKqLrg|!5<&EgyWVniArW|42-%gR=$XQ>EUGrG4QUPp|wmYijS{ut+^r{H=op z-~YG6e;7_%D=*T8_-R5w#3rF#L|(l>t2c^ltVXeIw0`NS^rZxZrE}Mvz~|&$Z#3D3 zsJx!+o59MwDXR)5neY5Aj@`YXv*#QmeD6AeFB%(Xi1UYAU!b^e;u~aADa*n)TaBM~`f{ztsQJ zCArglen&$gx>BW;Q&?@0nv#MEidK?}*)vT4;JSMyfCQC|Z2u%0wc(O8`d*@e+(@Qk ze_217>5F`}t)wGSiiNX311ifzqR!1u2{ggSd&ELd@2TZ6Ti(QkXc%Yl<#lBtpWDC? z7vYQKs+nH&O~%T|o!o%yP29HvqRI7hN#C7_WRiH(OsBt3ClBNf7`vI!J=63gmR4rM z{0|S!6B{KuX5%_^*Sn*~G~yldOKs z)w2hW;5CW`nnsEI@Y{zMCux;J-5LFJa}uW;ec8t5=5!qWc$xnLUDUW` zI>~oA1Dui)-5u5UCc@{wo`pM_)N~OWbT_p%r36DO_xCHZHp#8Gjjarhc1Tma5lo`f z-_=7DNK<`d>fQ$r3kwPfVY8HKi3v*M3U!{aFa5Glank)M_(A^qzUlc@*rKwQU6IWB z+?<*K)G5wh5}G)Znfl|?YX23pjZNQ^{>dDyaS3}A`gEyKf$l6T4N9l_q(b8W-adT8 zd5Z5Zx(rE&IQT22=8-Rc-O{t2oo2DOH zO@ghGmW~-$jt7PN_a!^h9Bs>cJi9V^v@cF~jHa2K9UlB%G&+XxLpnL`Z_dbS-VmT9 z)~+O45&O-msZahCK5$%=67GC)>Ykk=?@o=Apm%pTRyvz;<#{~hzOeZGi&XmU2|q}? zrdf$@6@0XxWni^rmUBDMKcvcibP6cd+uXX1I~-&JBOmFk6dwKbQEyfPvGuPC1oI!0 z*4ZViVqf5h_5a~)wZ25DDBZ5V*Y+yeJm8k}-B)hcl;E0hJv5KDbX-Tiyms2K&%Lh? z3TG0<*7~R}!ry}NMdt^Z){aNic%X2=?(T2IZSpts*A0K$nKT1#q`LolG-9&pZr~+U z7y~7+g8fd?QP({@HnO*M?SF+8oO6X#>9+nOek9p@h%86tnl)lOEH#aTp#QmqdUSJB z)9C&orQ{Vc%>r*ffKu4Z>2fpql2Z8o>zmuk(%KPa;Oy+IVFt3j+cQ3adFQ!^J{zeS z1@+itNul+|iJlM~l9`ja@j}A*A*lu9L?L0%B<nG}=14IVkoWzlL(<+`HW_yY29tYu;~dRC^>341}tFv=ng+r5VxVJP2QYt0gNOyyjfTW;wch{&%Hwcn~Fk%72B1Le7ovV!)GBkp)QD7q*Pm8N1Ikm&f3yObn`9 zqI&M-6Sksg9d)EGkYqSr-`KgHqpe4Ci65ql&7UU~JYD84)m4@!4j@e_F`(cq{$T578h?HKLDC zL6&?5=C1d8LRmicDlVXfz2%s(V6K5?kSatQuAOl$<$rV~xNy_xt!#;YRFCj*q z7X|&lH5O9UQ7(tfFRGqo4Q9ahKMbA$J_JW?iMP(9E~D94vQj4Ix%&WF+S^X@LXD5g zPm{n30P_avT`5OdryTM1@JEbmHktbw8PP3wgXF_3s~;-fU0y^!OD@-){%P!6BKmL_ zs(_~JuXDAf5WUU;Rk&BEiv5BAg(Z9d`P_a%cGah&6ZgtwVSe7qk_Yn9WU))UUsq~j zG~Rj4xfs-cZ74yd3pwppt*vcc&MBarCz!^dU8O#UvXUP@T}6Y`HbyVb#F;KzZ_5HT zFoc!ZY$a6ish$cKn)0%Z=_^se5k4UwslcG6tiZD!&!I?Uhp~@1W59^Y(HzTD3gPW; zM1ft^{iF(ZO&Zj9Z&^fc?5L~Z7eq+LZ~66%Z4M{4X2Jbl9h2C$c3*pXJ~uCQ`!F8}Mcyicf6)M2yM;Oa_gmkb>`37a*K`YU|BpOM4V*ukdn zM&r4_}F5aM|dnElrYabvYF>2`N={i43F)Q8h`a;aYl3frB%?@TI`!WPnu>g zCme1KKgvw;`|hMpLxYB#yRN_7 zsI4DIY=tgB2qtWiFmfUzL$)`x8I?!(7#jE>$A2lZpk-#f= z35Z#FLlH2ct2>{M@W=w|YP4OL0TQ$Q>@x+Nf*4~H=zZv`YAD<0f&%7a+L$Wy0+ zjhDqb%x3E9=l}MH-u~qI^cHG^L*)~I9BFa9&(-AxH(IVe5?pQr&Sm;EO}>HMDy>`8 zXBV#O?&}up_!MX+()l0yKT#c*bK|TGF?}sA13=wSd|YFc*LqjdvE3ifwAUskpnt^? zL6;?N(9Apq%`JbJNw+UOH|nD%ucj*JLu9jSd=0{Hh(`G6?(Li4O1pgm{P+hL(*uL@ z%C`xb;uwD*a%t6(+xZL4_GsQj((jxg8K7C`7yPj8~F>NUKdnn*)Y|B zl_%{oc$c_;)@nNFfI0Ako{8bBQlR?P1}p{L$IFWp(@@tCOF*V8g`U**pV%9>7KvbS z+^aE@a;RoRZqA<65@k)L3Y+zN2;YluFUD_)z@YZk`#oaFn0)vY*ZY`N+T0dgDkl9# z8H=e34D~uh-B^KY9?N=jzj*Yi5xQWvkN3*nr1-j_0KlW_aTEqT&VfnU!zL63(>0CSHQ|5c~mCdzfN^F$))7z%yYinE!@2+Lvw ze7ysyN{g0(GTz-{v1p9Zaj!jbfBeZz;w)vFm-~0#xQW^pPZCxLRQY?mlC!*I8m&(C zn0$MY39h9+ChFlAlvK+0R}Ds}{Nu>=pD{g4%*jn&mtxNK+seG$V51ta%|v7FJgS!d|$2o3Ex8w6vcCV+9m7@FPlLCpG| zbZO&fKlI5c*d4(OBWI*F)#Qrqaq!m05MsmtI`ZmaTy7;|!qy%6j5CGhKw!=#1nR0c z&o@&%9uRN~xrq?=_*uS@Rk0bODV@j;2y*2p@}mZu)SlflBEoeAi>hr5ipGKt1cv7Y z_D3@QFAKmEKrl@sq`xvjYSfKD1dXHQ4ty^Xt0E0I@+z}UrzCd6Yzkk5T3AcmiPPjH>76Ii7)e{p%y)TkFt*lkO)QpC!W z62F~CV9NJf(HWHGfHN_X860ks6IL7{AcMo7*J5S=Z09Qc%M#h!Mz*1E7_m;R-vGlX zLT+wX*iizFG_E9ah6~79IyF_OnU_v8Ts3j@)r)mWi5@$SKGj5E6$|Kg?bDW4fo4fN z#gOAYDc6I1@;;}83Xilk};Sv)VzbeZ(yPynXEfJ3o{F_EB!CklR zV_ReO8wGd2D8aQ9AhgkbBJY&YL?kBDWZ~n}{CxQ`4BW#Z;70H#YEIL+-l}uH_rZx) zHFX;rUDKo{4>**1htQh@x5j|KUuavrsydz^`pZ;*{qZ9H(4i^UaF+v1V20UfAH3kx z0mfbQXyW@}FZtd{T#A=>@;VK4l7O)20N(RRFwJnS)mOExaq+kdq2e8K;re^Oc>CQQ zJzv+fzYpfzQHJNqr87xP_#U*&6zc*MafTDK0@z2jGxj5wDN}P6PEkx2#p_tmL@lko ze+9zPvEuf~?}rr6x{>?w5Eui^XIpD)>lbG=q?m5G_RS5?8N%-dXcy(U>ew@*{2`1? z1SJkeM5l()xQ?mrhNV)EEGi?U`?OMBW9xF1TdG^y*jSE+^KBtp&!-12tbh5n`MJ7c zc@5tA9n`5x3+1;(db_%mr7cKVXbL6Kx$B5x2PgCDYlA~SJ>gs-6d=~!hb7dYkTaJy z&gqvk@0ZnWPPFf!c`{2oL1M+4YLJNYbo!Jex^k@i+Qx^~M&70$EN87w9k+9U0|C0e zgH~im_^iLXQ;At<_PLo;$CqoNp&^OOtAv(6*Fk3v?Mw7p_2F7{?m|R*`mq3|+&oO| z4}I~K;670fhE)MD<3&OWYJVEXP8=mk`T@^T1_3)y*I6oK86Qd}r;HPgy2S(lvez;fL@LY9~ z2~=5>XFsK5AYY3x?|-6JBX<*wMxM^<0Da%=>tndq-$NS$f2ojb>cGF3J&dQoj%0<= z!04kVi&OZjPHl6uoN=s)j0qg*-Us;cNhWXzV6VNyUsLrw<%fYx*ryM7%+b7^H*eP{ zX+2R}rNtJzGg&TX+8y@747_==IzBIC01(uVB;fInjdo(UQ4?$E*uqdMXzfL8kr#4f zg!QcE!6J)8$Q}}3tcCH0TPZK-{<{wwjKU#os6+d>sPI1IVasp>u`#TB@D%HYh9PL) z?oZ`rJ9fE;+v)uF?%#d{1#b1{kh48Gz>uFss$3zwiKgk}XzTDjouI*X=(xgKgf%ul zHM2jaNO6<>Q>BSiYlH$WcM$P%bYWgVgvg+K90ot<5WKsazeW&e4K;fyv}TBtG;4Ec zACT`@A3;gjB`$iJ0Dr>X3n>)ie-!@*Yjm|Mbot68O`JaOg*F*w^TiJN&AOK%id=1J zhXL5v60_9S=aj$46>t-tcH=39XE9h>o2qhN6@QQQ_GT%>iAV$>ogbB9yW*>bTj}c) zNujqi%XsHY9~^?lMP3&>@US|3Iyz~y?3icBEpGn(`Tccge(lv8DjErW2VkPsz1**> zzbvgF#oL4oTTf3)M82Y3IN>-0)oY^OBDH6;fl2@b!62WFqKrIWI z?-9a;uJBYGZfb7!UNVNv*%Ga$HFkjXTLR{wwVNBBP6IV4AIIBeVQ-I)j#ik6W!&50 z(l7@C92*_wgwRd|z6`gZv@i32fQXt$u>xJVurBDoy! zD~lcshp_4Cffb56A8sg1%iMJ@0#T%-CpYJ}c29Si-0E8U+IzKnx$Ahy?WH7S!CX2% z>2Q7?Epk_!icQa1w(giW+mG&oUil@YvGb+`c+8W3BzQ*P=}w^sQ~U zenudYtz~=*!M~#|D=WZSj-fA;|3{IqC>xa^tB4YdX*kW1ko!V!@sfDzM{>TiP`2)o z>;q;EvJO)t9xNR&CJB3fIs?&9EgJDC&ZwVDM)z^}ru2J3JRlS_W^f*D>CGr@j!ULCMZc+&}7 zvEyz&9Gjug8LuhM8ZRB6P+qjK&$w3)7jCF*WJffYmXLdh|IFQ-`90MKzg6mEgmC9I zL{zG=7xuj7T=emH0kU~a;sbViKz~dEH^hqK9ZxI~x@CubO{f31o;Elz;Dp*)va3D! zjFC`1$N&}@KYdDBWevWiK>xL5>g>J0ILBf3C0)8M zy55#;e@@*A1Kw}?t)to~iNo6N9~wK8!oF&F+#=jNao}taQrDT%_4~;?kiATdPuKDS zT}pW+gLyFlb+FUJ887=w#)g=Lha1uL0jG!C7&t_Ky@TM}ISbXHdoy@4l!?jwW6_y} zP)v=oa#|VC}>Ykuu7aCIXvk%KHF|7B??s;b`RBQF| zU4}2}5vPr9yusj!iHfd0pn-mlnWhl0nbbf@jIg3Z5?D59*2sEnY%l;`Yw){#EwG6o zMH(G7N3n4x9guKTA}7nzIY{KmCr1#a1Z~6t=M^{*peYPz(N0oXe*xW^r zdSmOl@`QlgQIb{lFmzgYGc8Tf;Z&5dB9lkA$p41h$ogdK?4}^gwrjM`$nZ+~BNQ1t0sN#UgdzQa2mUG_|&8vP&Xzj1l84Av%}9p0Gx{2tBmHniPn0%RJ2QlMp$o zHae9t2Yw6D)k7%%xkkEmuY zxYR2VtkI{g6{~2;$3cojP^s!MEo@3Uy0X=B_u-o4F>G0 z5-d--%o4IFhghh%i-YN2+aKHPTsd9LkLF6 zdb|koPNd6c2|&TP=_u>6y#IxSI%sM^8v2My^E)H2R$H~?#K4nF>o-lWi>{5R+JLty zx1b1L{1E2HHx?C{XwUj2i)q_%9>s55Uqv!aft5Jk; z3y}bta52?(;m5Uix02sFjaK@VTo~!uY2(%E?CWeEauo#MdV&V}J|TAMU8#LU59Tlt zbkN~_jxt($PuIgiVp5vG`qYKCH%=&uTEgpGdc@qE<5;J@^QwvS^NOrS*h;a(r>Rd~ zN%r282YP$WwqxO1pPIAQX1%8<9-2;x07m+_UC*)AyU4iM3@3HW;lybzrbZ5+B z5XNbT%`=6wOJV4_U@VlwHu%1jJW~#da0Th zSaK*IJskdIg zSRi<=E7+ikGyn`=;UBH5{09A?zCK(EtOT2uf0Hf@IqKzt{>2&t7V0egGBuqXqv_sy zoc@|&*fn7f$g&UUuGI}_k6e*__giE|j6kK!vk*@ zvTSKh8n(2dwMIxGW&lWd4~&sZsth?7h&>e1l{6C|2K0z-e_yXm24i6B31tTl3(hk` zP045#{#|;b)}(B^o)qWZe0dM76IU-Igq>>Y9hQpCIwDe?dRd-`3H}qwIU|lm?AiZW zDqe(5oa47zV)P^!MZd4#<-};*d=TJ5>aq})1I*@unCRBa5^u?#f1~PqMLY5QN6ayW zjR&hTs zTF5D5>9C1X%x6+N<==^5qA-K1m@OJ&@!uGZZ+^z@D%X{dCXWO2R*i>#psLy*6pd@(r=qu@Ei=+#W-z3q^oc?~9 zaMYqSM~NY>KeUZvOMV{kt@Ezkv)jS-}58R7em9=wJ2s8 zejVvTRh|zh&P^Lh+X_-{AF7Ra!!3d;S`k|nEZIi|#(iBUoPfI#DZdGm5F3Nd4c)%T z%3$AWpoSD7CjU(3)wPG`Xl)jso(kKXorOy|BsH-d9RH+_)b0sr(xRbxrg-?}nc@3h z4mIf>sAV1p18D$UvQkVe%!MWlNs57P<@tQrIJyi;i(oP*HG?U*yPwkZm4sgzgDD8m zCs>4Xz%oGxSs3mG=c|mzI<>LB1|e{ZiJwb>gOdL&Txqhv?lO^qt^-m~8ev#Au{3s| zZ*q4rfj{*}{c`3!si3jYE)jqa5S%AvJGswv85budQ1Zko9}^|d(3y2wc3H-usbdQ! z*W0R88J`C|N=Im}^d8-jo}Ci{4T$1n8i!UD8dd;i4WQHF3GgYkmV(;-(XPIn8;$lA z?2vqALX)7z;Y<6u=Nn2X=RBrj_mrt&KIxF@yAy0tqut8R;FY_SZt^_sOrK7rBFft5 z_@ScivQffQfU@^%n|V7lev_NhO=9d-1b>6>BO+XN`FRaTpW)zSRLKKTzHfSDm!%3; zm%enqDZ1tNzsQpl!+A$xa;?(3GfPuHZfrp60OT7DjRLIeC!YebF=lI8n|{>5MftF~ zlVktWm2EsQPVQ2+#8lS8IwmYnKLohv%tNqZ)?bC(1o)bg;EWzLy$P#k8S*uPlDxX% z_I`UGHTiEPmF!-JSofz?qcW$1se_n*UaR&tKYv4=E;5k8aK^i5 zYADF&lQ}7axZdHfz(3s%`fa{$g}K`j!6KN+VHthzoaylQf4paS*BRpI9pL~FnXL+ zC}x?pUddBc+xHmaXTl1kH7{Vw9l%Hax_7*0C9hYWZ5=e}GmM4(i?vWz8$H)dZ!ZOM-r>GQx;^R`7F z7QcYQet-hW=K<$d!}BcX&C&EF+!srZA8Wd6JwcK2w&nTacXjc2;uzR(l5Y_->T?WX zPVKTm{zM#uzp}&PxexB1pDD`)>qI=BZ4+zk=;CI?x0@D-hlIi0A49uEY&7JX zYEf~6QR2LAIB%(A4Xs0WG3>5Jzvo9^O7D1N-58Fu2_+pS(dv#f+o6n!hsndz@nhQG zk(n?&VqOPgpDqtjn@rzPbN}j_bzfu>f|IJ_ElM<%nl60T=e~E=6JLvr6=(C0X%qGX z&wPIa3=E6A#QOCp9XSac(p0*-a(iR-Xa2kW*PJ%*V4euf;$)ARV+%c`$x<=F_t*(6 z3}LON$0v_=-_Lm1Y$ZcFk458f+dscqB|$IvWJh5R1m_LE$3H3nN_jlJ_H-^9SMAp9z0fTP7Fo@0N! z^<|_HFk~u*?437L56EP7!S^F@;Me|lj1i&gl$F9xZUS)Xenm6hUT%%83oDSG@{-dz zeD~KiW=6PfQY`GdWXQS*{GgHMgOj77_v&6Sm&EWTudU6 z-n014`1m#^G&g0Ev2@AypXp0QBRrJ}C4m3P*Fx{I;;A(a4M^=)Sq|F3=+Mgah+XZ& zRb@7WJY?BL=AL&_TdIJ8k(LTJtU84J9_deV97;)#V#^v+hsR?1?rHb0d>)xY@19dm z+T$~umhu+hxog7}Q%RvqW`RkLdq``rouQ*tgh5X2%xVB)nc+!VRFE*YsWQ_! z3F$VY5l>O=`2+U@KK~^Wu`HS|y&P&1^lru)$7E*m(jiHYK^mmd+50IVD&2Dq+8%Wz z^QDOdHr^Sr;bt*V(tPeLRFR!TSA|9CxId&OM64WpCc-+8Xj@JqE{aL6##1>(0|e0h z{FvJ3^r5w_K>Y8_v&_qmp05+$8Cvwbwc|n24iXv`z8$L-*m8-4S29$y_*sH>Q#cM% z+}ey~dJ}?%F#{`~BN6?rUc&1;v3|bT-EB4}&&o4FBhF(U8puHdT`e$+|CS)@kxqjAW*i2n}uu!?ycQ-Cvm%ZNkg$OMwIrWh) z0Uc&j~_tLY8Gt*bG!2QoH^ z%>d82oYwc@7!pMDWC{Qz{g}W*Ynhw0s(9(psSIp+x>ZSK;h2z9K;a^tgPYYuz=Hqv z%tsT$0JLif+vC9GKGnLTHhrTPRYl?x)P}$CW?^MTHqsv^#(j8+Q>CooGDzA}Fg-%&!|dwt`bbkXLdc1qgEB2Y`_>0U2d9yq*re|mz&{}>26-fI zbgw)##veg9I2d#4CV6GqzA$7D_U0*R91gSwXO;TN{tSwnLju`y*O(drvkM)Gdaw9j zgtrPL{qLL4aKc8SkG;P_qlBI_qYwm_mSXFymIgrZCwx}Eh2nlgyh66l1%4rT~J?@h4bmpeetYJ?zcjzk~=`{3)i zhs&~pHIrwidElap%xyMozw+T0wz=>~3xHNmWmZ4wws)4Id?eHl*~<)e{Xy4(#Jkwj zQsNkvdX%B_isHJZzlV(_!;3jYc6BsqWa-dl;wiYculd%#+G)O^XWrU2^EQ~+FI!&n z$b&Tq@2bq`zzutFU))oPZ3D1=_G=ts6(xk zQ;z*YwG-WQieMg*nZrp<^=arx0wu)4Qsn7e-K#*JCYdBhjaN#uw)pjfZU}DI(l7%7 zhA5OnHMG>xyo+m`;>6Pj@e(#GIrs(d#UJKR+rOnRC} z2yt6b1$5mvy{$skU0(X_?O7*|-f6%sE0*__t#`=;N*!+6^h+pVrN+ck!}(8dXuXeH zgQB+UZ%%y4Cm{o@s-j8yX$}n#`jIsC;WjwfB869@jF&;$eXZTyY%4>|q2rd6l&YvV znN7cO&FTh2qTV3)iit`~|FwBf&OaK~HA1~V!T{PvfKYDsE!rh1NQWCuMu68J%eBQo zmEB}z)CZSv5fykJ_A3UFz^gIUhg16pP|a*`Z5gwxJ$Jf zQ~z!#7)ycmG~Z3fS|CGMcYWjOe_5QyRnys9dTJ3f1hD1e??4{Q-XNQ7tm>J6(EG)w zZKI9F?$1+*l;u)rz!o$;*}lhS3D_W*X)r^7I<_pmq{XptJ9lSJdhq<=Nx;WFi?}c+ z|D|9euh7}qSt>_xDS^SU79SQziT%~rux?B`_y?upqU56ON%%54kt%pzpf(fG>XB3G zTROEqAQeD(WOCxl>tU`?#IQ%)_POqAD|qbL7%M2CxY?olr^v%em2k0nNY(H=yvX!u zW7M5#-Iea_u-teO-I^frWX0hL8t`Luy=(B}CdLH0Ga5F(EQ4+}gbW$$jNVk9{VNy; z=pWfXz)=HhGu020U0L1*(!I2Q3A~PF8KM+`gaZhoo0I2RXDI6u#NcLiZT^?o<$^@_ z3};uZ`jr&#yr4Z282p*WPc?F3Q_FN_gW+Z!vLSc9rFNj0_K|0OoGY{y3>)7gC~>bb z<|#caT*%5R1+HNby|zN9*7`e-wSN-G<;#%3H)plo@0KJN#Jfr?v2-3lXqm!Kp49u7 ztViRLesfP+0Bca@SxnAn^IiDu@u%Uat{?QtZ3S-@E=BHfkRDpr>WT|*hx+aBVH6AI z`V0=>;{Vjq1JZ!~k7|I|Ij_W4|BCyDkx9M~KiG<~O?G-#Ca*upi-87qcOHLlEq6-{ z;>s({eT^3jGUeGHYu(c>J%0}TSs2oPkS|v>WZjck0)2^lc5tI65m%PcIx^B3pJbpC z%k3-FooB?zq%J=^G4SC`IE;*8eI?+?W>oWgxFVq8SO>-?JmXNf zYVHG$ilen~yQQt+=&qT01dX=@)c!8y68Fg#49jtJao0Dq);%V0o_Gh-|+xiV+BEswyomgV)bp&j4$U zXik)KVl7_-kCY%NZGa!UrOo7Ud5j6$JDrWLSz$67x6R+t#sC*(=xU)}BT!6q<~sWa zu`qaKy36~CTwKS z#GT`tyiXAjTrHel?vUy|*@^F^yr<(UBF(p>v}qO9F9 zk_|_%3y3wnzhb3dXVwFi=bCLW>Odt05y}ujT5^$+_;wZ8$U1zpJBp)et6sD}LF%om zngl6$EBXf1W7qwX4K%-`^`CBzV-TW)_V7<=`dtrw&)(2w4$YwPYjpDR zP%wA@gG$%--(Vmg7%}A5k`O8LgoHUk=t-}4ILV$oMR&O(Piq0H5qM!Kr)0cq^?h8S z>_3;vF&p}@Mzpgi)Es^6)$=vi-n2pHu<=?T<+0zp_zDjqa_xn%E($@(NDQ=U-R$sf zpPM*Mo)p@6@l#6_=e*8N_Ou{ZY;?xtYTurW>2=!?^CE}muaMMcOW!&~-);d54<-}f zn;Z$FQ@CH{B~vC(IGGci8EgcYo07OdE2)E^?^#P+|zY z;*@ANw`}>wnu_JkOkC__^YlM)jG(=a(@5AfO!;qdr^W>Ev+Ila)jNI3f;j2JiMEZQqs@LQ|>LgAh3EqwV01lfvx=Ql#un$IL+tm z2K;@)A`DIjkJCn+H=~jK>m)Mk z;dbxMN}4g7IbX-!t$B4f!|ia*fMo4aSu2@SnZglH;%EA@z7k;osie#h_uIzMd2K|l zoxULPeh_ZiwNqkCe6)Lba|!{89DyNoLKA5Qx4P0_9qNGZvV&1jX;n5xI)J;i9KH97 zhvE($7yq~PGFq@@iDY+IU%`Pd^%hh6tzOzTH5P<@8T)A>vW5*iLt8}39- zG5DnUm)tMEH{M_CWOI1PL6uxgm1m8G_p zmFmP-UboqgBVSF-M@Sgyl~9GN8K zk@!yGvl-;$;{!LAq!)-9Ziql5WIc@uqk-ML^aDvap#99rwXh@sMqFY|KrXv47Q^uC z7o95oy3>sBfJ^T5UK}l~?}q2BTq+bL+kjBrkRlrJnQ%v4Y$tJ@q4XTc(6Dkb6qnC6BmP zXaeoIM6u^$10X?5%FP~=EJb2`ESMqWXW1;lV-Wa$6U&^TyNBqS4>p+k+1E=R=HLIL z4hT}DZ&sZzALVR07Fh`{K`_Jzp1qg|d#p=FTuM6j-CR%8UaT6bY@XNsh20L@& zXIKVE*&(I5#(zAn@i*l&k66EWN9p=KME5d!-8YNkE>c_t&Jo|LuSN)e()Fh5Rn)E* zm_U79Gb4y5mQ_8vro5#HxihUjzj&0B5h7m+B?uX{QVp58yWxE-g;hS>bUKuEas`8 zzSRURn~LlGy-aqke!{ID&~8$n$9=L z(GU^T)lmxqeo$ml8wgvNVelnnvm_3z|6A-0>g6KOk`-r@7T61yv-cjj{|Oy%l;IIy z_&$FN`dLOnu@Ma4n-p|=MmTQjOUnu}jve4Kdf!;>`Ah|}&p;Dg|MhtE%e%ofL^v5= z{c4zp_@x14gBCV=JleJqicX~gX=P*Af3YuNd&fbuq<(&%V}`ji_cPH?0LF!Jg-T(K1gHOknNtaia^!cIQ}}svq?q;HrU0==-OASQkeH;enTS`MlixtO z>aj+;F)=8E$5=iQ%Kvedjo4|EQ!=M-KH_x8J^2CuhzjeyWh`0d~BMnH}XW%8A|xjgK(GX`&&n*gbFkMP2gSFWpVG>h`OotGsh6QQyZI_vOuprH;yq!cz>^C7upp z9P!|!-_f_Mw}i{Ic<*-9sBqBhbI!8n{=amOj;VsF*D>U}Oo>hqIpW_SM=AUI%M^Qq zH*4WM5I5|Ubtq6Mod~P=RyUM7?6lYdOPrN<%AGp;1zpxeRfy?29cDpT)l}Cfw>-iK ze6OimT*}F@DLG=eUkQIaA;;$h#S9hit7V{ZZS5%JY@jg{9K0OZPd(fDaBPV(f0#>y zxj&rgL-frbg<-|(@-Ae1LTO;x5gpV!BFQ@H`EJenTv~|t;T4cXJEDx$HN!7BPqX?K zT@BNBRXHQ^juBKHR9Edp&SE~`!|+#JqLN4Nm*KBmQ{kG$UneVBvLonnsR_>Seda=^ z?B8ccxyU*27&bk}!__I=?+6$)n`wUWjg!V>c%C0B%}tnNz2C7Ce6=F)lmzTb&0Xxl z68PC%pS$NerpeOk=d8CvP#){+hOpnqCG9M^gFKfAnRXDT`!=%U5N>fs5?Jq|y>>A< zE>XM^l`Yix+1hoD$7Hw1UUD|w2|Hz(F*hPQl@k({ds~wJ4Tc;^TyLSV=}W(ydtcJ- zAPF3n7!dnZAoIAzt{MEYfSlzV`h-Q}=<#m+`~#t!9S z*6>6lm)SRqazEvYm74#^ulq2 zH?-E>68hqGV7waHCP0?yJvR!tI=)(6?=b=9eNlgMC;LEtnF?$%WniREb7GS>@Rx$^ zlf2?k%6g7qJikL^PoR|0!A4#mp-nS;7VAS=SZ;)hU|;izxXwH#BFg42*`BYP`dY9` z$2aF8fA~syY&{5RI_r#2z&yfJS6tsM6uFER<2u$xqJAR#O}dxH|0Dp`v8iRi5rTH@ z5jq$K{U6LLn9(A8d6%NFqE*G{%bxeL{X~EEr8vLSawO!S(Aak=&);}zO6c+gR@jpsT?M9!U-ploQ>pR3rDPpco z_uF4i=s})-#GfptNVPQMdIzWZ3`5G>WDoLaqkixC&tKEC4CW|94x8Q;n``{G<_380 zOiW@s?v?!RVW6@UE+q9l{L4D^*_9=M$7mLmBtJ)w4)ZxKFuRNI2kmVvi(krE$tt<6 zT#RQx5?cUTzwODB!wv4q8#$}hV&}R_NQA?|R;vvm4`O*$&y(4Y6~3@M%&U2cM8M|#e6%237-XR0meoWW^lI^4nt7q+yRvxJ zVo;d*Bu8>!^B#x>6B5Y6+7Z*Ro2rf1>GOm7TAH|4I(AiPf7YmRcT5}UTWKadFT-1( z(!gE)Rd`}P0MK1RVN*!Cq;$I%8;fC`Dzg1y5i;S$e3pT{RPkb3nlY!GEl{Pl3KPzA zcKE>HPihGUpQrg7Ax+_x;cT=Pzl)63UfU!~d|)@FT>4zn4p%r!ZDC5F}=jQ5D#cDo%?RMlxSa(-4cl>;5m_H?rbvZ z`H^S2n_`8&13!@?q&O!%f09pE7T$BK&b=%)uUm?*k@c;xbD{be;~1AMFJR8teO(#V zwo_)j)IhkVpW~@U%YB>bzhz@=LDN6r*TIrIZaD~UVi@cI?^IGR5ngpPJLS;_FT=t-=v>30Y0jWC;E`vo{6_abwK_i9a?;(BX5?og`_-Fe>=%!1825QH z!QJSYL{@xfPeN+vhf}&o63)_d1C>d4RRiAX@kQ1f4bPKVANGgdkSn5)kWTF;x_V0M zxz7_j&+^Z-ucTfHVCl%|l>X`reqN-|&G56SZKU@^N~a3dGJZ)E=E8jROfI1JNYly! z$02$=GN3WfLQ|Z7`)!>AYhZ^jH14p074*+CNd@l1AoL2Au*WI*REIjec1ouyBSM~O zsbzWmXW*l5x53b`|ITk! zwse1+5X2N$0R2d=m%6cs%r^SCf|f329DSTZ^woKLHy0@f7jovAs^ z<)~lySMP=(B(5ZPpOUN*MkcIoi|A&4=j8Ypt^I zABS+|`v_aYtG~v>wgC<%5!9hW=$IFvfJyYeZmo6q1krGIwVl<}k=y32YlvKxYcEUb zxZnJGSS0YSU*0OeXt@njTa+u-ez?H-W_x}eD<@D-PSJs=2R$mlK~k^{KBQCkB4yBI zgVEDy+AAs`BT$34dD`dDj73%>ilvYTYDc|XDqfeW%OwCKGe}Dg!dV{ocl%CZ%h5{6 z*K`HF#=3lV>i5ipG{?^4R!jaj>+EfV2^hzZyl*T3Wi|&=yXrSeKu9@a%S=_ld2ON9 zTUc@prod%*=~G}a$woi5mmtn`1I>}NTBC+8hRY(R@rL1_iMgPRzps86NuQXgtBC0n z%l@JBEGzW!;i)@gF|4C4R~pCSEN|_4jl}hwpO00`4I0$bGqLXZ%LNK8T}|H;;riLn z=FHfd7I*4jT$&C%Q(YEL@+tr&?txcYH{gN0_a2h^}Dk62_wWt`*{+QZBjAy`4d? zBa17JGnPgA1f_~y-O%9I`ft_I?8GErr@`ogZ;kb${Ne=}|JN=;hPFNxsFkK)Clx6w z1&!SF%hZd$G#yngPFNbh9t{-Wbr)M{81AdscKaV|82R%w*`!xetIxGuD7%$eB`~kV zC7g>@p6KH(CZPirh9j8hTeIu?K-@*odB(2KBSCqR4#hd^@5xz(qQ->*55|Ds*u@A3 z6+Wo~G#$I6cZ@Gj(yx>#KH3#m8U|gOqF{87S`u6!aEn0#$hzL`c-@hW(DfVYcrO-u z`Wc`-c>nGlWLEZm25HrIz8epBNE5vtvS`KUKdUM{(CYT=U&4cczQ1@Fv;fI@C&bM* zye^WfVPDjREl6m$dNI4_uN26{)!6)=K#A^M3C|uhiu2n zb&3qFCL5M%|7FDLK)WJsUw`Y1#?2jalx{a4RHdzNCUr)Zlz5`8-5#~cI8^3ZHOJ2d z>1}dB)p(Z_=`FUc_Qbpl`-QX2EVH#O3I7>6L67UXA`JwDAn39CKE0OSH|nvIF$3lI zwXkGc9ZIW(&kf+nMf;o1@F`Yr5dwuif8VWz8>vIxlX!yfE`eWEs-S^$&r=&Ok=$ZU zn}XgW(YvJB1k`s7=BrkPMbdTgDMZ~LZB<@g`WD%x#-=KO6RuP)q|iB^r&0&VzS5M@ zeCYtzFeba!jfFbZ=gQ!WUhY(~%xp~ve?F&m)elOPqh+~jsvnAjt2vDl9b%U7BhdAw z6c33hvG;83sMHFQlW~xZY|A8*L?|G8MQRZFUQJ;2Y5Qxi-o>_Qd`-LPsYb}?S*H&( z4TS{KWF@G4+q9}{ zU=v~q)oOHyCb$%1aG>d3czukcV9?FnbuiNgfB+>KTSG%5Sv2D^=soUKDDVC9o680p5`c~LoM^=%Lk{_6`q0SB+1*cO6z_DVFILCyX!;c<9$f4%UKdJ&e#z} zePfyp&Lmd%k-B-|HK-WFS}&$d-N}IF5(jPl(XY(w=y~h$@?nE&MdFc_p>OhXqF@Ar z2}-PxiONVmuaLF>)Z#_e{l+WkdpBO_^KoCJUHPf+iVNgD;h*J+orjaOCo6{j$S?Q( zUcGZjVjR+Js5a8b#}nd=LQj1o?;xQgw*HaSg;vn}fW-qQ$>CY>q|lv?oV}rBgSIq4 zXNkPR-eoH%%Y0zMb+gNz9r{QWsUc-$%;`4tIS`@%$)GB?C~fyfXw)P2e>s`DtzD0h zV(qR6;6v!oQ8XWQkGVfwS+jU98=mVax7Bl#K7HEEx)?X9waiX|C`I81TPsgzrJ#-!k6=AXoITwlvvFcsTdOKKEzwSl(H zteO=CX0pd2ox&STqrr0G=8Zo5LRd0 z>mlZThU6d*W`XH$wOxhSywBJrPJo({uCW-Xyx3R34Hwud_3Ul#xEVS>c)k1k5FuPE zlTNoF=!W=EuViI*JC0mxU|rp>Nq6Mh-8;-xXzib~e4>M2AK8qCW9WA%ne(0?kkJQD z#k1)2CO1d8r!NAfM6VW+z1+s9>-e-t=mrZya+V|8_4@=1Z>xbk_7)WfO6lP~8D|)R z)r&o{w97M#M^47%<~L;Obcv*QXBtZ(jXozr6TkQuY$IKTI9^UO=O8UWnY-VPxC^ab zHq*F9ek}7(w#qKvc_d|h=uFpY2*kA>9BX}NDNA3F94jFQv8?jkg@l5o@P^L=)!RO>CS>)N7oUAnm!S;moK`x=+-psJ^$b;;?^x5p$3 zi&n;P8qHkkyeS2(XLiMMhi^V8cejTBr#JPjvBK(>As*tcPi$<@b}hOw{!z1ABr; zxbV$W#0kNPbL|uP!Ejdc6DCXuE`f~4LEK)nA{F0%!AuJE&qq%{pCe6`1@x0-s3?3m^8yI2tX;z$t#04one9M-j$SXNL zx82@}hj)#eIRZz1tora_;RFqJaBRlFs&>jS`h2*Tv0$<9kA|>YZ|0+V9`@Gf5xBP7 zXM*X5qQ%^QtM>2?h0QQ{+PK_!=(?t%g7AZn%()BkeT7_NfX3fTv)^4-ob(H)&aUW) zhwHK}D-qZH7D?+bkJD>^zRh?2On!il>;0^dTCYO*acV5uMJ&HGNm6I=ae=uXbU}n` z(YB(@Y*#d;CG9>=?%g|5Dl5g z035X&+XKyqUc#f8LQAA^8QeZlcXgVp;}azt2?kv~u>%0M&)**Tbj2d(k^@drxhu#| z`Yv#%Pr1s{K-QBEb9r53C2&_%QK8pY1k4FRq$s-TCP$_ z2e*!*Sx4fg?U#VYevhL;%I6qu*jg5%z zk;H9tk$@JOgfOP*nR1!F$pwj1lcs)T3G3W(%jsmIWb0*`b!}JmuSciYkarPhhs=#) z8SE`(oLCj82AsX7*w*~B@+Eeyu`VMpn?tr6DPq~EO?vg76&CDZ0~BVNDCjHAJ?5Y8 zCh#=CN!XeT4 z5;!GLZ?3QZUM|mc9(0W!cVLoI=BcgkQlPU9*deG!on5zSwhloMNM{q87cflh?-MW? zGbkoSfMGQ~OcVdLM6HT(!q@xO_b|(azgFiaD)-Bw4O3IIw@_@CY0gBzm1CrKb<*$z zY%9+Cet@K+5C?{n0JM4YGSEwaPvfebjl$1oBQuZN9}rtw)X}P;TF+JA)z-4MQlC}W zJA{WQlu|k_ToH=$;xP~uT2tVU$@UrW`@dWOXmf9yRK!e~tl56-p0*+#(_G-vZ6Gi; z)56>p(!<%!P#R(oK^g-dn>ucu7PE>zn9TlA*qJ(m2g$v(Sg`k(j1`)To`mwJU9WE4 zvwy#nRs4M9a%)XY4*dZwe(aE`@qxQ>lP(WzmuD!bEz0xnTSO+=dPHp-%al=_xo!#PE41`gk(l~r)-#?SA zv1jOu5ZALO|5{o&&R9%qxE&Dmh|Tx{ZH=+zCwpwp@7wO-)x^_Smh4-vW?F>M%6aizBGPp1v}`d}F)ow<|7w#I;-7d!_{4UlAZ{_$;1uhvYQ5;Hr#0D-1Lfo%^feCR zNj4E9b@wxzkRBh5FI(6$5_2=O?ynrBqHLV+eamuFL5jaahQ!RGE!OrW#{8PSU$~Ct zGw)XmI_UCWZJ_~6Q8gl~dF;?^eC9z$t15bU`RiCeC5?%y!kl;T2+(BSyX=MWi&d0d z)lV#%KOx{X0}YY+CnE1jIW)B|(YXPIG+@-@Ozy zoM-BEH5zO6zpsi*oiQwI8-^U?miUe~(=m$O5Y*E*(jk<~moPM%{z#7k-_?277>P5$ zpIhbNGd<)eacou@NxB7d=mpqqTUP#3tf?0wT#@T>A+{hwAEPPDeke}Pq0?&M9@AN$ z=tKkFpCtk5F6j0y*D5{QK|k>=BQ^l1cYuo(j8|Mrgl%!*+`?;I=|k>OEpdn~_HF!8 zHnq%S6{#O@BI0$O-t5NBMXp9%Cf}By;>Yj@8b3Bqyo9_&Sh$=I8g=zN@74jG*pH0j zM|n&&S`oV{u(Ne^yuKDXjc3VDctzsQm`o03C4$yCq~`CpuSg_joz=|lT@MWSGRySW zSIZzXa7_ZV)|Wpxn?j(~VBo+>>R|jvI%wh_=f}PAY({fNA$|%)gs~f0d}v%lqa7>( z8^&7@>M+yYEn$gD4OfR;^{5bqZ%mV~m))C)S8nQHn7!YD6Bcf~|3V$Z=v_}48AZKx zWV0Ce&*`re_4?dGDrd?2u(t3zIRH;EiE*0`EYAj*z84>XK)a&6$4_Tw;z&rn9`N(n ze%&9zNS_$P@+R4`9QX6DC?o}5-kYQb)HRj?Q~C3E5piKo^XhVAO;7TZX<5!Ii>uA! zb{g`8K9R6a?m6puJ-e5t>`rUn!9+2}Q*d$|Jgs3)j-!`PQ(ltH#}Nnk*xdZPuHP}9 zMfdK#HQcGLt(JcJp=Vw1Hfd%e4qVv5?X3=F`3$-RnM%K%n9e_WqNpdZCMpw-pW8M zMZ{*$q6TluGI}wqJ7iMAN`U`3^=_$DP5a8|no7{W3F+gWO4Wfcf7qbILj0cPR=Eew znNA|bx5wK_J#uSB;k-fZizVhDH?Q{c#m~@2f=^Pex6WPc);mi+W8W~(*p$h4SO=NA zyf=UiOhT+cab_?+^U(tH;EL6^Go2mH^v*8w_8+s_0v_tnx0!y(>uxlT6ygOk1$7;R z@6?0_rbpC{V<%y@VdikCn2jY3HzgY99e4ux_l9#L^{61ZuwvCfu+1k&=oi5tQ&6gC zZR>2IslKiNyHMEt6D!--pL4C8XgNbN68q|B?l$&<0e)A_eu~YB1tyD*3=_`1X^%nuA~yHoirZp_1R7&n5K0HB-)yy&j50Tq-HPDdog4jUy(n%^UCT8+hZ!z*-#g{DNU=VGT#g=$ zQ!Iu2GjbDOFd2E;>zhobs6db0>J3);&@9z-=8IJ=2JP&6!Cd6eRW04mob}!KPE3W)O>}PxjF~{pX%S+JuZ`D#oZ|--7X5{o< zNn;x-VEe&%>wZWnwh(cn!_1wz?I9gMV@n;`kk4n&G}F}y&Yz%fne!(U@6YVrtBEFZ zwx*|}lapX88l#1Cd`>6~J0VlIF7*M`1ZrI6p@51E$ZUr0Zrlv~cte33gDPlow1 z5R%ScLmHX8337I?_Z5iB=0Qt9t4Vl*N(V>;;FhIw#O-kx;|M%BkMxUzq$~j!yT(L? zHbHKeH4~W!x@q{RNXAcbOdj*zTypV1eu7pG~beU1;P(B8O8Q!8iR4^#{N2 zJ(fe967P;|flUsco+`sG<{?Xp`5dM{~ z`N6-#8WK>Xbsl*+(2${%e1Ct>b{jH_%e|Q-A$0d~mieOi;?3)&GAY>1%3&77vjUi9OeegMiNmbVmuI48QEIa@DZH|IV+!eU-e_UO zQn7_31G5ah&I37G7NMNkZ9IjnDV^dK+q<`Uya2xNz!i&%O^@e}6Y(p)^!be5lFi8z zI@hPB^v$2nOiY#0Yw);c)4c|zp8hMbLGTooC#Ti8cy=Hkgm-~PB6GlZ|NN{<*v~5b9>R{I! zte!W}Zzn#~YastVUKu^o=6k=(W7~&+YgDVhH0gutxQ6%MH9nIz=n1B=R$<3+eYv5j z*?GUI`Rw?7j7JD7<4P%Qp+P8t%(2|@mF!LpstJmVwhv2;LMaQ6!=+Uye`?t2az>~;=^fs8CC6tPo~k4%aKz({9=@%FMu zug?ee>~LVM8FWA?A53nt3yXw#9=B{x-lkXG*w>TdqfG5Hy%?k3R*xPfb~mw)Dhi)- z90*}L9o+XFvrd8<@qOa;xB<(qJr6&gll3yd7%2b4Ti0H^G|8X=3B-QK6Nl*H&5t`1 zXCFb!B5(a{mPA^7eP-N^o~pkR^P-%$-VIL*U0m}moAA59x@;dBJ+fU?>@KP z)y~$E&d(v4>dua+V{EOD$6=DZlYp2U=DQI&J~Pdy>!x~VqaJiwu{j0F8Czy?O4{Apdw`=!)5f3gzUH%7~zX zKabVV!#>=v#?pS7Gk-Mx$qLTu$-O6KW~rvg*Oi~SDX~35MJN;w;7;WAGQ-`{tRxXA zIYrZuSOgkvNM2EVnrO%7-%rSEZ}sPrH!|FkUm@JGSvK8C1R^G4Zo9m(K4ASk@7=(O zS8lHLp?rq$E-IAmu+RCxnf=Qxuk%GSuA`l4y^bEyh0DVEU*Q?@6+kgy*>vPX)z@F+ zoal17h>hL1UO85rBZ0h0H?yPv!ZF!1Ur-UrkA|b=m)05U2W9}*=p+ZTD1UCC_=s_- zsTpx02WW;Y3&v9Z#o<+X7JlRHhK?K*rbUre)cM1;A}M5;R2AgD^;EmX+#BN;M(bgp+l zcjuD=6V}f1;Zk|uUG6UA~c0I_|VOh?S8e%jRgvR5`@CNj0zoI+{8tEJM zVO^k##rQlbaUc}XrX%$mRdx_3C&Zf52P?-f+eITc=CaB|>zN^NPJn$?2!_vpIpzQP!z@e! z3{-NC+IT;pc0Vs7vJ~m$;<5u>F#!1doS*C*eMDrsSIFFl1l5~FA`|q>AmA$nZ{(9T zoGXV!I}fUGT#@+oZshK+eD?9ZWcOd^;D1b~!xS}IbZg8^r+zjUmc8v(FVH{%smeaK z+30?Ydq=4cgod-|6`kL}X2jWDep$dmD;%p2A_7Y&cYdef4JhVTOa3Z6eXBz%r$5#H zZ*=tDh`##AzjcVsdCELG*wC~5b@!^6nRimoG=BJz0k<@sg=tb63gAd_^J$dO6~RqbC0 znf@W&bn~xEqJPdWij>3^X9sP7dP3;p)P2s@!K5iUUC)e)Nj|0Cc9knQI2g>fbmEWG z?s3C}=~rHs_d(Id(OE^C@{GWlNXxHu?eX{uh1D;1VH5Lb6tU1X_I?VOBAwLg-F|VS z(-gEETZXSG>P~hH!G&}-(L49M_kV_|Feyv8F#6gSWo~Ei(@sJ{Y8?zpN)J)Z;_|Y! zs;cS-k2Ebo>2MWzA_9UARWMsQmyC>zzF%cS1J3om zMOb}(y+4kncUiK30Xzs4%nC8jioItayN0=jxf@#!&T9Y1f&TjMRo%ug{3Acza9zx0 zdqa!GXfoCQXC;)zZ`xFM;ofR$i6i6V-$wb4g97=iIPdk7EW6W;$>cwT5NAoxK+ce>l_$(@ zwd~BH7n{Q2$LxYWf!i z8xpi=OQ$=rL=UIsr(2#WlIFK%>oyAXQLHG1A?~}G1bxXlP(eOVxDnuEwXF;*8UTDa z_yoDXWwa)jktuUD6aQ=@=fX68&Bbp><6qLLDVmggj43&_!X8!pJ~VDGIu~aTnCW_i z+y`xDA~{?YL<-eA)6Lf_7o=*ZY{yY`ZAVlcoXY~Q#jrIUITq0F^Jy0l<#0ou@NX&| z#3Cd>afh%is^n6cBp7c7is7XV=?2-@t?4E__;3%MJwn-TktQYc!hrcGI$Ino)6%_4KkcaU~jJk0(JmMUi>Jm-t zUa94>r9#0ka~9Ffo!QOIMh)-T0;OV07c1$#Q*Qduj$5QE7RgzYO_^2F|4cn#&uPH$ zT_bG$k-02&@7gGiuD98*TwWEPo@S0sz$M$c6p^`S%z$B7N_J%6p6Fq<{;f4!a>)y9 z$ic4frPDO^9>h0a0`Lo?uRJ&6$=P+<|EDniADJicOiuG*od#^VM`)h)8#K4}%x~ds zuyN!CC*@L)Y28M)uH?k^f~LVF+)&~KC}sv?`P?wPORbBlB$VA5>A_3Xt=e6oqHn&p z>Hiu5oCAnxW_128ZUC+f9qm+*1Cr-f8akuv@f$MN!ZQjEY1%sy1P!v8?U+K(hnsj> z7ze-M`G-5lv9XqD!Svk6>&`;j=i%wj%`48SOz-N5gE{uFai=o>CA8Y!_-ABAt zGu4!tPsmJ?Eco_Fu|!BT$(Xyu_?m(7ui+1f;3I|J(FM|cb7-b^h(f)Q$L#|&9fKu+ z{v}4&3Q0)nr9PyAWQ9UqwQCwG5fF!TnzrU@?__ihwW*>_T%3t~Uyr><^7&I%ojk5j z(;$n4>y8(x;BcwObiyU?oV$kpExE8jN}FwCArn-UBLH z$9P*W9PB(Ewty8zeu1}%c)?N(*44`5%jW}z@GF~jOA^QwF@JrXl0d>fGa*~^sSa{e z!B@#nUO_>$5|c*my#sRH!g3p?w+H3 z0!T8s`BN81`l5*ayZVh))znf00|RfrRisgUb6gj|dld(fHOWlYGjnluO-)ZvC+RXZ zH6`VM|NacG61&sd+S-=vJj+2U>Ci;ZuSYkWODui&&oJO2BdI@~-NxEjyV4;rbT=tZ zPE9vAG2Ka7eFXE^udnN)8hm$gNK(iYd{>d2nQ4oam~h9ql03^}Am}*;_Jrj(hr4SH zz?Wkk_OYVDiHT1&ZEZvz!MuYx!qQ3aS#HEsD*>O(F4Ddhkbs=i|1RF~S8loe0qgY5 zE|F%4TY}KB=3->CPa!40XCBPFacwI)elxA6$GHmrFb8!rH#gVB!vp`5=kzdh1xKP? z+Bk2-px5JLZvu&etQ?mm{m_VVz%E!IPv4tFIsx%zQ|Q?+Ndx?bR$8%OnL-RmXwf!G zO4?HC*x(9VN}8yDvHJ5n)ZhElnZYv^4l#|5jV6wc>W;r&|L+Qv&uO9M`&BGaP)0?VB_EZYP|z$#5+N!@cCqGjCe%zqWtT9ZMI z-g5CtE*KJm_HOtP%#9|-16N}TBJfDyDcR-c=L=ZX=2EUxRO@s-0Q_78(AufN%D_i| zn0%5BcSQHFTp$sVP*i^AQ;fu#Y6ihM#U|AJqrAiW3PL)BCHO4;)IO5j=OGi+-r2~} z`6`oioqbyXn|*BdE>w;Ti0p?EL)frZ*nXptPqE9~0Hy zgg#&j7olti)Zd;j>X2s90JBW>y+^l+cBQwD;W3p!+*&w;WH~-#gKC_}^!jzDMB#eN z?9|!V&(%43?#5O)5s1O|59kA1N>oC+Fw(t6T>FDOV}BpF11bepYFM@I9Ul1&qB1e# zNKjPLCPRNdS~c)VJ5yHPsW6-?T{QJVi#|FzNpQZ33Ku0v81L<;a5T1)B=58&9k)d=DeZWVAL9T)!j%AYyK;wBlthdJaaQujyH79Ngf^u3B=%lEHn<{_NHbHupxh;=l}dW91Ku5y3+f&>%= zID9|5`BQInYPm(hq4!&ec4|Dd^bYGu)+PEZY5Jy#F`w9SpyDbGh8d_sgF7{ZMs`eJ zHu#V9s%?fCED(QtlHefB(Wb{+^p7xR_abA8VpOnM!*dl#vAgoj9S22A0}HuqDug3> zj99vX(KqVQAzw{Oz3GS%Tqqs%!;2M4`G6kssejH`7FNn|YI;vdmFMZF)jax7+tn52 zcS;NqA6lh_U>buJoD1t9aZy{V8^VHseRvm9JWLVrC#(j1YW>R=w3LS5(NvK=X8$z& zJ?v*^vGfe#+|OMUQF#$~??(JwvNM8I;woH1=4U_XPP??|p_-KmCyaj2{)_~fJ6MmV zS`isYQEY5BH8i=9=v#C0hmU@NWT#}oNdHAMr&6N&omr_+65b~hQ%+;*Tez_0J2u2! zYo(5_Mq)T*0`y>gbr}KHK$u2`WOTYAWb^(0$uweR#=gJ#Jb3uuVs8X~1tmmhM30hW zX0Zuai?xhHeu6%LV%v7g zpqEQD@FGU~W21*JofV|KXfCkSYQ( zmWkDZOj`}v8cF^PO2hVh7}N9%qAQzr*}QtU_+N_*?D+yT34$gT9PzTtd-~jE|xo`IjGKf+Az$604}iSIPx1@ld@( zpAXQL4ke;05I-g|#|*K&!`%Z5wj1!abh$;RdT1F1aPf^hS^YiSSr8#O#LCI@7z;{< znm(FgX7~(~bu~&AFdaz|#K~8%>*O*Dt{9+HuUs9&Pi=i+2{AN4l!E5^_N!nWVOU3X znT%-0&BGG-kBsULm&Le$DXybij7tbi@eemtxB@qH3iCAPpNjgE$tHa;UXzHKOBHqC zz`i&$JjW;7k9`)Z<=VLF@8pB}S$ox#6@cHeUjCLs!12|=fY#3`trMrh_z5vPgRZsv zaL7>BYjEf;5lT)cca$Ek)+K~72&vHJn^+$(+robM#&yE?{8c(_N7$jDK1< z6)=#06Ol~<2X*rXHz#Wye(U|SA=c@>dwPw9@h9kcqbXw%>ObvAg5J*=FrmWobnh2D zTRmq-8c7-bBay&Ui38)5u0(EVGa&Cw0qhuLe)Zh$LB>*{tbhP}8!5bs3Vpan`<*?B z3Bi8^ZnKCmS^c6I-X@+vcWLHl#KIX?4)|>q$%hGcI#5HRuw}6NCQ?EbO~P+V6H$r_ zMeE2(djIKhNp`$VK#^{Sq~?+8MXT-KUE&KQudlW;ja+H%pz6&y0p15WhQiE2Y|VmY zZ>1_6DjU`x24;1Lbisj2=Dti&)rc561acg3+o2LnLt95Y)_)Gxh1#EP`O(!`YF4Ds zP&~CK&Q+ps!(IB!UIBgZ?jYOrHy8X9hOBcpE0iXEG+G1f`cg+cmC5@9a4s?y;Hvsi zP4$dvLg_zpux+Apv^)^S`;T8x0T-4n`Z9In3$FhNpfF0&MxJ36(}!p~F3AFbg;5{-PbUL{;d3LFrnl81_*mefEB8;wRgy&fZ!y4kER6((E;XD{rFDx7B>O#*6 z?8pC^#AFq+eiH}oTGQ$5C*D@34;1OB3z>t}=LH<2^TG8nmoZ42p92G&cI46PbKQ-# zzjTJofzT9ia0FO-#9R?MHuf(kV9j-16*D4vx&B_iSbV7<(d!5jXZkOSuk2Rj@+2pM z&ROeV4LHJodg@TtX;}9?yn79~Ett{XZU0;g2K1qn!^pE9&J8}Y#`yqfTsucbV%EP8 zYQ_)2A+3`5`NmOV7^)|x&(1Q+`&g46i7y_{&Di9DhOPeby}t%!f2|@ zY(#-wA#?%snMs)QVv1X=tdVfo>XmgN~Ot2N~QbNzQd18j+Um8CpgaVv_DV_iwD$i8Y_ne z+60#$9{JuE!;hpIz$%>L3Zj4;H`l<^lF&dr-<51I}V6u-R; zoEGhzf<)Qd-sF;!gntLi7HQ2jIa|(O#0H#wCeTawGjcHH4x1W^Gv+n_Gd|wJ^-D{V za(r_d==ewwj%NZIB~+q_qB!~>V2(cF7B{W?j5qmnaRTz`crxLu@P@pE;l$}%+!&@z zuOLbmm}FshHt@7d_xKm8%m6LYR}1ge84U z0pmBLeP>VqX{wf0QgDE1M}C)=m>}%@3Sl4xYk(N;g`^;iY1suz!!JU_E(fM~!Tb#| zfdLdw&>Ky%S&Rt+psp>y^4@$eL0==aeVKdr78(sZAK%QRx2@KSWreWBzKgrsRF@y` z7h#;p@Q{{b(rG!%u^~{e)W3`=_GUz+zb;^+xR7l@!M?QjgHF8oEUL0RtND>~+Xb6| zoLiwxRx2cK?w(yg5=u5bxxqIluFg4i&%?OqY1%D$t>Pgj^M83&;fm;^NQZo;6v|mf z3zUe?Po2f|0%TRC4xxtZtm=g!lANyqj{>zz^SQ;s4hOTB^2C9yRtjN63vdpWh%^qE z<|?lIXRdUHqVOKag6bJmBQ%eUUp>2BpAxOlvUN&3&&yYtBDzcHQ!GL$!|Fdrrrz8? zjnOAfn?Gj*11N+~SC~V$O_XW>h>dkvDK*rZ?RzqX#4_=G{`Z-+UF24@%)X`SN2v4^ zPu7791YY(f?;O4dAqL~T9qwTR=B8&P$20`+^}Ro@UHHxV50Jw`2u|o(qQBoeFZeku zz|Z3opJ2XoAc}SQX8k*IkWPZWhIb0XtWLPVl(HT<9NLhK*if_4!T94)l7vL>M9a1T zmxJq^XkDj{NGE%wh zn0dVMeKETL`HiINgPAh=S;ZXW?L7TC1?xCFGm769zTvk$MYX8d@kUOt%T6tZ(RpFf zSV|{(59GM?k`9K4%zFfX4!uhmZ5g7irAP<2L=!L+UF*nd&EYc<$$_+;ZwPP877<^U zUPKBWnP8eFw1L3=E2+L%H~I(;`l334iJUAB9FD#SJGUmTRfbypx!#|HCuMxCgh3;FADMjMHlUw340_yD$u7NucH(Rq5S6{4E6zpGNX<<1cK&1|tH!Z&+#0S#leO zR*NDK^mQavj`Cy01Dgy++5b%1nvlEE+L-i=BRL<C>&pe;sZ}BCOBTnq^xLy}>M|4dKO^!bymy@V zdvlYu4drka8X28HlE7sC0h7`}`>Pv6sd`n8q`I>1QM~yGfwe{H_8qvhtx_nkck>PU zbik?*V(4y4#h=q;M{&cy%DV4q*=T)t{)dYOQIL?9@L&)7r-nfCMcStii`5NUaxhpI z>!^NqFr)fiah@{7)J`53X#d5t5gS)zSWpzR=}gRYh1D^B+rwnec|8z15>eso{Ou0? zAMu(b1L@GP$LY|T4d@{!56nnTOJcYRZyA~3o|4QgN|$Xb!tKNLRYlmE3PX2k)7V*kG1$x4=dHN6M@N>H@}IWFYB<8tp$tTDP7|< z^NB2KbNRX%x$X0Sk2`FwCW$0HEeuY7QdSq44i4(#{&Y!~oA$314rm-lWxN<;o9g+eD7(}q##y=EeG-# z6V^VRg?@+?j?Q%Dbou7C=$DGtYxvpbm8-#}kzKz#`R$-au3&U>cz$8#qIyY264 z1yAjd+syi#y%9su^U4|L@u!u+0;MPJ&$oR-L4|@>KfLb3SVb2;@a4V`gf;eH*t^p} zHa1CN-)N?A6=%=x;su*P>Zr_Vo6HmaT7$)ljn<vDb7U zGU@x82Y$b7ymL~t3M%*aFdPXpBfiN2O`RoR7%aMLu~+BstDeKD2n zlYXFGc&)2eIM8~`IjbE9#YQ+@nC_x^d!E=%aJ!s-@--Ud$%`WPa16cBJRV^)HH%2* zzzTB=nu86^*K%6fN(2&~u%2x1jHC{YSMrUvTGlfzOc%@$fS@!PqY+SB1!!>4Tj_Cd z@S!QmBML%^d7r|n`BYEvn5_pCjl&n1b^Cl05g@!hZGb~sL8&X31p|UkI-YPR?Jv&= zWYM#w8gW5N#LiPn>u?HgAJm&&%H&JJt0W5$m-bcbKjLr8^X=uGPFHwyYC8;2>VxyM z@qD8^%Oj}VwbjyXJWMy<8+LC#Pc$^*Voke|s^#1h`Hr-Ce#9mLa2aw>U*2F)t}uS| zpIw`dSdtD~s`dw;r&%AujGGov;9C@codjs4m1)I<>)3i%_9fWoHuw~5CGJO%&$H>i z`f9cDQ20Wcxqdms7}pKW-$mat9MeREWw|%f=nl@^o|2q@o3xi?N3L_3aqSM z-;MhwTiGBlPhOr+xdf7XjD?FA@zbSZ2yATPu{nbyhj}~Fu(z%5a>82z)b+$idh%DX;fH~L>a~Ecf3PxwEinn zee*wjeJBYAY?1mRJ3yUV0VNu-oBITgWB6)tov+WLd^|@9-YnJI2?hS_%48`I;0W54nCUh64Yk)p?9{pHVV(Q z)(;|kWERa@7%u7h5+Fsb-;k3pzb`dr(d@w!?Mj+6#n(}i^-~B!7aE3&99pZbaKS9} z3wuQQfQfeQ>T}~Nog{ebi;_0oSnKmp?~~f*`K9xBRH49;xpaV9Rb>*Up89b5_FFk% zHAWO?z1Y2d)(x;6Qphvy zq$cy}a0;!<zjvC$|85uT`)i#C5%Dw9j(AhrdRX#d>l=43tk{t$A z9k%<6E7w1rPO3`$9GVU`T@xQfyU(%PZ+lK(t-Y6F)#T338wujW?qmO<#fT8M*KJ>i zoQ`-fTTx-c+~0O=j|rlV0mY17Nor>{wV3XB$KNp4e_J_sxY#b^PscC=L+7CPjPz9< z9V}Fk(0Lp=vfNuCwen}39v zP*y$!)u8TL^$Tsemmw)Rwe88-(gj2RLQ(2YBuouLZr^6KmA)(H#%2Y%hG{L40iO00 zP+$n`gj1-8meks;aNN5SfjS)*PvE=-cm(HgdC|azYk})I^23@j!F6!Rx~8lutJ$hu zpvF4c9NMh8n+IR-(4D>wNY_VT8F_nBC&>H}^Z?ZO|2ugf@T~is^6y~pk=oB9Y}5E2 zO*c6kZ`RuU8z+`PyiRbtL{hw!2Fkzf&nLW;0a;yU*nSf1#k$$Xr?S|{Z4#t$7WEGb z9`D#rJZe$H#i7ZS*F;0BNVh^*OKq5CvqR%VTn<0?{Wv#b_+dk z3I&17`{X*<@~uef7Ps_59ncT1c6z|04M&~iLXyCV=31)0l<)7W8vSK1~g373w3T3DZwVR6k_ zuXRQ6pBf;%2*+Z4^p4r>R|}vCjrDmVv5jLn_lU{$_^rBVpi=nb4F4tiR|W5iJdT^R z-Pk5n%Ybi1mJOhdmC)*?8jH^i&ha};;pfOBP?`rK5}O79Hj?lt4v4BQ7Q<^9(ePlF z(r*I>L=MxXMlDm+=_hgZbC6wqxNO6po=cbd>R36F#L){7O6@{AOvV{@7P;PuA%zK# zk9T~~sw~A%L8K3&BA5P-b4Z!qsFDEMOwyY$<+$g1G5xO=NdeAWF ztGPsNLsTi8%sy@nW+wU^gu@8Y+@kgx zIb#r1o#~yF5>_1hE-ayaZUzCUaP~t_?a1}o_(l!g&HCUuP&2rBk@@mSA@;yTVzPz{ z;`QGP`%&J(uw#D=>lRd8(=h*9XgG}0c&8cosPHp;60NL4Z|bC%9Kz+3TMSKJo^F^I z4KiB%{|l#u1t5+$+wMkegSf#0b<*84i3_dT#}Dcpj$Dw)$P(BY;2ySSe5u+}^ro|= z!fIiR`E%cSOT(v6d#pQc9PP7tp0>K5Ii&H`x@A|s3{9318W37jzEiDAK+_LcKm~+^ zl%tWkZ1OytyK6OVhpnXaSb%R4jXD?j0vm>@gD_gZmhNgJ5qNaGC5i?Vv_PYzzI0-@ zDKgH~MD;0V4>YF;c^Ao>l{_E!hRBF*gK>Ge-MBdRmAygWew5dtA;kD7HnK0DTkGmg z+f5+2y50yBe)S^V(Yr{Q&6}`#u09!brCYwGvHS^(=X(5{U*X#BZDl$j#ah;Fz%R zW&}8IQXN7RgU@@gPIUOKw~qLiDPK2lvoGP-j^{j2S-SBcLO>-neRMOhgOS9%?4{+t z2DX9y1xUCod)w%z8`UIG5GQ#%(4g7A;*rwiSxlh{@&^H!M!SRv(hWU-U`Gp1WzlIk+E`>SR_C54bNg^B9QSxG>d%tE8 z`e=;UB3I)OHa3F*);k=WjRsUC9KB1LFymxJ34Vis&6

    {o<+k?y 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 literal 0 HcmV?d00001 diff --git a/example/assets/images/3.png b/example/assets/images/3.png new file mode 100644 index 0000000000000000000000000000000000000000..3debe4736ba594219305cb9f5210816be29efcd2 GIT binary patch literal 350463 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

    0(L(59sZedgG12}S{TaI-b<>8j(V&w= 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⁡fRCKC{QE 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 hzh3OY1?H; Date: Wed, 1 Nov 2023 19:15:07 +0100 Subject: [PATCH 004/210] Avoiding using ! operator with call and cascade operator. Closes #1423 (#1499) * Avoiding using ! operator with call and cascade operator. Closes #1423 * Format --- lib/src/widgets/text_selection.dart | 64 +++++++++++------------------ 1 file changed, 23 insertions(+), 41 deletions(-) diff --git a/lib/src/widgets/text_selection.dart b/lib/src/widgets/text_selection.dart index 07cbdeb8..a4285308 100644 --- a/lib/src/widgets/text_selection.dart +++ b/lib/src/widgets/text_selection.dart @@ -498,9 +498,7 @@ class _TextSelectionHandleOverlayState } void _handleTap() { - if (widget.onSelectionHandleTapped != null) { - widget.onSelectionHandleTapped!(); - } + widget.onSelectionHandleTapped?.call(); } @override @@ -756,9 +754,8 @@ class _EditorTextSelectionGestureDetectorState // The down handler is force-run on success of a single tap and optimistically // run before a long press success. void _handleTapDown(TapDownDetails details) { - if (widget.onTapDown != null) { - widget.onTapDown!(details); - } + widget.onTapDown?.call(details); + // This isn't detected as a double tap gesture in the gesture recognizer // because it's 2 single taps, each of which may do different things // depending on whether it's a single tap, the first tap of a double tap, @@ -767,9 +764,8 @@ class _EditorTextSelectionGestureDetectorState _isWithinDoubleTapTolerance(details.globalPosition)) { // If there was already a previous tap, the second down hold/tap is a // double tap down. - if (widget.onDoubleTapDown != null) { - widget.onDoubleTapDown!(details); - } + + widget.onDoubleTapDown?.call(details); _doubleTapTimer!.cancel(); _doubleTapTimeout(); @@ -779,9 +775,7 @@ class _EditorTextSelectionGestureDetectorState void _handleTapUp(TapUpDetails details) { if (!_isDoubleTap) { - if (widget.onSingleTapUp != null) { - widget.onSingleTapUp!(details); - } + widget.onSingleTapUp?.call(details); _lastTapOffset = details.globalPosition; _doubleTapTimer = Timer(kDoubleTapTimeout, _doubleTapTimeout); } @@ -789,21 +783,17 @@ class _EditorTextSelectionGestureDetectorState } void _handleTapCancel() { - if (widget.onSingleTapCancel != null) { - widget.onSingleTapCancel!(); - } + widget.onSingleTapCancel?.call(); } // added secondary tap function for mouse right click to show toolbar void _handleSecondaryTapDown(TapDownDetails details) { if (widget.onSecondaryTapDown != null) { - widget.onSecondaryTapDown!(details); + widget.onSecondaryTapDown?.call(details); } if (_doubleTapTimer != null && _isWithinDoubleTapTolerance(details.globalPosition)) { - if (widget.onSecondaryDoubleTapDown != null) { - widget.onSecondaryDoubleTapDown!(details); - } + widget.onSecondaryDoubleTapDown?.call(details); _doubleTapTimer!.cancel(); _doubleTapTimeout(); @@ -813,9 +803,7 @@ class _EditorTextSelectionGestureDetectorState void _handleSecondaryTapUp(TapUpDetails details) { if (!_isSecondaryDoubleTap) { - if (widget.onSecondarySingleTapUp != null) { - widget.onSecondarySingleTapUp!(details); - } + widget.onSecondarySingleTapUp?.call(details); _lastTapOffset = details.globalPosition; _doubleTapTimer = Timer(kDoubleTapTimeout, _doubleTapTimeout); } @@ -823,9 +811,7 @@ class _EditorTextSelectionGestureDetectorState } void _handleSecondaryTapCancel() { - if (widget.onSecondarySingleTapCancel != null) { - widget.onSecondarySingleTapCancel!(); - } + widget.onSecondarySingleTapCancel?.call(); } DragStartDetails? _lastDragStartDetails; @@ -835,9 +821,7 @@ class _EditorTextSelectionGestureDetectorState void _handleDragStart(DragStartDetails details) { assert(_lastDragStartDetails == null); _lastDragStartDetails = details; - if (widget.onDragSelectionStart != null) { - widget.onDragSelectionStart!(details); - } + widget.onDragSelectionStart?.call(details); } void _handleDragUpdate(DragUpdateDetails details) { @@ -874,9 +858,9 @@ class _EditorTextSelectionGestureDetectorState _dragUpdateThrottleTimer!.cancel(); _handleDragUpdateThrottled(); } - if (widget.onDragSelectionEnd != null) { - widget.onDragSelectionEnd!(details); - } + + widget.onDragSelectionEnd?.call(details); + _dragUpdateThrottleTimer = null; _lastDragStartDetails = null; _lastDragUpdateDetails = null; @@ -885,32 +869,30 @@ class _EditorTextSelectionGestureDetectorState void _forcePressStarted(ForcePressDetails details) { _doubleTapTimer?.cancel(); _doubleTapTimer = null; - if (widget.onForcePressStart != null) { - widget.onForcePressStart!(details); - } + widget.onForcePressStart?.call(details); } void _forcePressEnded(ForcePressDetails details) { if (widget.onForcePressEnd != null) { - widget.onForcePressEnd!(details); + widget.onForcePressEnd?.call(details); } } void _handleLongPressStart(LongPressStartDetails details) { - if (!_isDoubleTap && widget.onSingleLongTapStart != null) { - widget.onSingleLongTapStart!(details); + if (!_isDoubleTap) { + widget.onSingleLongTapStart?.call(details); } } void _handleLongPressMoveUpdate(LongPressMoveUpdateDetails details) { - if (!_isDoubleTap && widget.onSingleLongTapMoveUpdate != null) { - widget.onSingleLongTapMoveUpdate!(details); + if (!_isDoubleTap) { + widget.onSingleLongTapMoveUpdate?.call(details); } } void _handleLongPressEnd(LongPressEndDetails details) { - if (!_isDoubleTap && widget.onSingleLongTapEnd != null) { - widget.onSingleLongTapEnd!(details); + if (!_isDoubleTap) { + widget.onSingleLongTapEnd?.call(details); } _isDoubleTap = false; } From 464e0aa64ec0d971fa84d86e1baa2e412c01fbe2 Mon Sep 17 00:00:00 2001 From: SRevels Date: Fri, 3 Nov 2023 20:22:51 +0000 Subject: [PATCH 005/210] Background/Font Color toolbar button tooltips reversed --- lib/src/widgets/toolbar/buttons/color.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/widgets/toolbar/buttons/color.dart b/lib/src/widgets/toolbar/buttons/color.dart index ed431fea..d481ae5c 100644 --- a/lib/src/widgets/toolbar/buttons/color.dart +++ b/lib/src/widgets/toolbar/buttons/color.dart @@ -131,7 +131,7 @@ class _QuillToolbarColorButtonState extends State { String get tooltip { return options.tooltip ?? baseButtonExtraOptions.tooltip ?? - (widget.isBackground ? 'Font color'.i18n : 'Background color'.i18n); + (widget.isBackground ? 'Background color'.i18n : 'Font color'.i18n); } @override From 2faeda8a0a0233e63274acd79be76c5886e12934 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sat, 4 Nov 2023 05:07:50 +0300 Subject: [PATCH 006/210] Update CHANGELOG and pubspec.yaml version to 8.1.4 --- CHANGELOG.md | 3 +++ pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20aa37aa..98fbda83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.1.4] +- Background/Font Color toolbar button tooltips reversed. + ## [8.1.3] - Move the images to screenshot instead of `README.md` diff --git a/pubspec.yaml b/pubspec.yaml index 2ce71610..2aad9f3e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.1.3 +version: 8.1.4 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From 1b6859d1f387d84345ecde7086743fa2ace731c6 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sat, 4 Nov 2023 05:16:48 +0300 Subject: [PATCH 007/210] Fix font color and background color icons is reversed --- CHANGELOG.md | 3 +++ lib/src/widgets/toolbar/buttons/color.dart | 2 +- pubspec.yaml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98fbda83..be38b060 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.1.5] +- Background/Font Color toolbar button icons reversed. + ## [8.1.4] - Background/Font Color toolbar button tooltips reversed. diff --git a/lib/src/widgets/toolbar/buttons/color.dart b/lib/src/widgets/toolbar/buttons/color.dart index d481ae5c..9a0f0789 100644 --- a/lib/src/widgets/toolbar/buttons/color.dart +++ b/lib/src/widgets/toolbar/buttons/color.dart @@ -125,7 +125,7 @@ class _QuillToolbarColorButtonState extends State { IconData get iconData { return options.iconData ?? baseButtonExtraOptions.iconData ?? - (widget.isBackground ? Icons.color_lens : Icons.format_color_fill); + (widget.isBackground ? Icons.format_color_fill : Icons.color_lens); } String get tooltip { diff --git a/pubspec.yaml b/pubspec.yaml index 2aad9f3e..3d0bc8e4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.1.4 +version: 8.1.5 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From 1f8ebc4c7ff6fa9109ca9362c56218a036db0f6b Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sat, 4 Nov 2023 16:47:19 +0300 Subject: [PATCH 008/210] Version 8.1.6 --- CHANGELOG.md | 3 +++ pubspec.yaml | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be38b060..42d47bd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.1.6] +- Fix compatibility with `integration_test` by downgrade the minimum version of platform package to 3.1.0 + ## [8.1.5] - Background/Font Color toolbar button icons reversed. diff --git a/pubspec.yaml b/pubspec.yaml index 3d0bc8e4..e73282be 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.1.5 +version: 8.1.6 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill @@ -47,7 +47,7 @@ dependencies: diff_match_patch: ^0.4.1 i18n_extension: ^9.0.2 device_info_plus: ^9.1.0 - platform: ^3.1.3 + platform: ^3.1.0 pasteboard: ^0.2.0 equatable: ^2.0.5 flutter_animate: ^4.2.0+1 From 764d3d3cac41e6bc8f21f92bafbb2cd15e78e29e Mon Sep 17 00:00:00 2001 From: X Code Date: Sat, 4 Nov 2023 10:53:09 -0700 Subject: [PATCH 009/210] Update publish.yml --- .github/workflows/publish.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b51a07c7..6d79fe4e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,6 +7,8 @@ on: jobs: publish: + permissions: + id-token: write # Required for authentication using OIDC uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 # with: # working-directory: path/to/package/within/repository From 21c8f91511844a28868c62aaa89c1b3c626d1cde Mon Sep 17 00:00:00 2001 From: Cheryl Date: Sat, 4 Nov 2023 11:10:17 -0700 Subject: [PATCH 010/210] Upgrade to 8.1.7 --- .github/workflows/publish.yml | 21 +++++++++++++++------ CHANGELOG.md | 3 +++ pubspec.yaml | 2 +- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6d79fe4e..ef7341db 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,12 +3,21 @@ name: Publish to pub.dev on: push: tags: - - 'v[0-9]+.[0-9]+.[0-9]+*' + - 'v[0-9]+.[0-9]+.[0-9]+*' # Trigger this action when a version tag is pushed jobs: publish: - permissions: - id-token: write # Required for authentication using OIDC - uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 - # with: - # working-directory: path/to/package/within/repository + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Setup Dart environment + uses: dart-lang/setup-dart@v1 + + # If the package is not in the root, include a step to navigate to the package directory + # - name: Change to package directory + # run: cd path/to/your/package + + - name: Publish to pub.dev + run: dart pub publish --force + # This will fail without an access token for authentication unless you have a custom setup. diff --git a/CHANGELOG.md b/CHANGELOG.md index 42d47bd4..5a251d67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.1.7] +- Automated publishing to pub.dev. + ## [8.1.6] - Fix compatibility with `integration_test` by downgrade the minimum version of platform package to 3.1.0 diff --git a/pubspec.yaml b/pubspec.yaml index e73282be..f12f63a4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.1.6 +version: 8.1.7 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From 58953f2016dbdb74d180641a0a387450afdfba96 Mon Sep 17 00:00:00 2001 From: Cheryl Date: Sat, 4 Nov 2023 11:15:57 -0700 Subject: [PATCH 011/210] Upgrade to 8.1.8 --- .github/workflows/publish.yml | 15 +++++++-------- CHANGELOG.md | 3 +++ pubspec.yaml | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ef7341db..e70d3919 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -11,13 +11,12 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Setup Dart environment - uses: dart-lang/setup-dart@v1 - - # If the package is not in the root, include a step to navigate to the package directory - # - name: Change to package directory - # run: cd path/to/your/package + - name: Setup Flutter environment + uses: subosito/flutter-action@v1 + with: + flutter-version: '3.13.9' - name: Publish to pub.dev - run: dart pub publish --force - # This will fail without an access token for authentication unless you have a custom setup. + run: | + echo "Before you publish, make sure you've handled authentication properly" + flutter pub publish diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a251d67..c6bd489c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.1.8] +- Fix automated publishing to pub.dev. + ## [8.1.7] - Automated publishing to pub.dev. diff --git a/pubspec.yaml b/pubspec.yaml index f12f63a4..e27527f8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.1.7 +version: 8.1.8 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From 52d9a79bfc19cee5f103bb270350f61df92b7f3c Mon Sep 17 00:00:00 2001 From: Cheryl Date: Sat, 4 Nov 2023 11:25:13 -0700 Subject: [PATCH 012/210] Upgrade to 8.1.9 --- .github/workflows/publish.yml | 7 ++++--- CHANGELOG.md | 3 +++ pubspec.yaml | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e70d3919..40ce776e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -16,7 +16,8 @@ jobs: with: flutter-version: '3.13.9' + - name: Disable Flutter analytics + run: flutter config --no-analytics + - name: Publish to pub.dev - run: | - echo "Before you publish, make sure you've handled authentication properly" - flutter pub publish + run: echo 'y' | flutter pub publish --force diff --git a/CHANGELOG.md b/CHANGELOG.md index c6bd489c..d6b238e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.1.9] +- Fix automated publishing to pub.dev. + ## [8.1.8] - Fix automated publishing to pub.dev. diff --git a/pubspec.yaml b/pubspec.yaml index e27527f8..8bc2df1a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.1.8 +version: 8.1.9 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From b19c49968f3874b5b1b79ff6a756bed4fe51a66a Mon Sep 17 00:00:00 2001 From: Cheryl Date: Sat, 4 Nov 2023 11:37:32 -0700 Subject: [PATCH 013/210] Upgrade to 8.1.10 --- .github/workflows/publish.yml | 8 +++++--- CHANGELOG.md | 3 +++ pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 40ce776e..cec8f048 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -16,8 +16,10 @@ jobs: with: flutter-version: '3.13.9' - - name: Disable Flutter analytics - run: flutter config --no-analytics + - name: Disable Flutter telemetry + run: flutter --disable-telemetry - name: Publish to pub.dev - run: echo 'y' | flutter pub publish --force + run: flutter pub publish --force + env: + PUB_ACCESS_TOKEN: ${{ secrets.PUB_ACCESS_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index d6b238e1..a23ecd8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.1.10] +- Secret for automated publishing to pub.dev. + ## [8.1.9] - Fix automated publishing to pub.dev. diff --git a/pubspec.yaml b/pubspec.yaml index 8bc2df1a..4eae9614 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.1.9 +version: 8.1.10 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From ba4a416f837095f209349394d5df899ece231b5e Mon Sep 17 00:00:00 2001 From: Cheryl Date: Sat, 4 Nov 2023 11:45:02 -0700 Subject: [PATCH 014/210] Fix publish.yml --- .github/workflows/publish.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index cec8f048..bf4a66bc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,6 +8,10 @@ on: jobs: publish: runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + packages: write steps: - uses: actions/checkout@v2 @@ -20,6 +24,8 @@ jobs: run: flutter --disable-telemetry - name: Publish to pub.dev - run: flutter pub publish --force env: PUB_ACCESS_TOKEN: ${{ secrets.PUB_ACCESS_TOKEN }} + run: | + echo 'PUB_ACCESS_TOKEN=$PUB_ACCESS_TOKEN' > $HOME/.pub-cache/credentials.json + flutter pub publish --force From bffae92b5085969bc630fbc388464e17c269a207 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 02:21:01 +0300 Subject: [PATCH 015/210] Bring all the changes from fresh_quill_extensions (#1495) * Bring all the changes from fresh_quill_extensions * Update pubspec.yaml * Update pubspec.yaml and export new file * Update pubspec.yaml * Update CHANGELOG.md * Update README.md --- example/lib/pages/home_page.dart | 53 +- example/lib/pages/read_only_page.dart | 2 +- example/lib/widgets/demo_scaffold.dart | 8 +- flutter_quill_extensions/CHANGELOG.md | 3 + flutter_quill_extensions/README.md | 152 +++++- .../lib/core/exceptions.dart | 12 + .../lib/embeds/builders.dart | 476 ------------------ .../lib/embeds/toolbar/camera_button.dart | 159 ------ .../lib/embeds/toolbar/formula_button.dart | 55 -- .../lib/embeds/toolbar/image_button.dart | 138 ----- .../lib/embeds/toolbar/video_button.dart | 110 ---- .../lib/embeds/utils.dart | 106 ---- .../lib/flutter_quill_extensions.dart | 393 +++++---------- .../lib/logic/extensions/controller.dart | 39 ++ .../lib/logic/services/exceptions.dart | 23 + .../lib/logic/services/image_saver.dart | 7 + .../lib/logic/services/packages/gal.dart | 77 +++ .../lib/logic/services/s_image_saver.dart | 33 ++ .../lib/{ => logic}/utils/quill_utils.dart | 2 +- .../presentation/embeds/editor/formula.dart | 41 ++ .../embeds/editor/image/image.dart | 336 +++++++++++++ .../embeds/editor/image/image_web.dart | 45 ++ .../editor/image/shims/dart_ui_fake.dart | 43 ++ .../editor/image}/shims/dart_ui_real.dart | 0 .../presentation/embeds/editor/unknown.dart | 19 + .../lib/presentation/embeds/editor/video.dart | 81 +++ .../presentation/embeds/editor/webview.dart | 58 +++ .../embeds/embed_types.dart | 18 +- .../embeds/toolbar/camera_button.dart | 202 ++++++++ .../embeds/toolbar/formula_button.dart | 105 ++++ .../embeds/toolbar/image_button.dart | 182 +++++++ .../embeds/toolbar/media_button.dart | 277 +++++----- .../toolbar/utils}/image_video_utils.dart | 50 +- .../embeds/toolbar/video_button.dart | 155 ++++++ .../lib/presentation/embeds/utils.dart | 87 ++++ .../embeds/widgets/image.dart | 1 + .../embeds/widgets/image_resizer.dart | 21 +- .../embeds/widgets/simple_dialog_item.dart | 33 ++ .../embeds/widgets/video_app.dart | 5 +- .../embeds/widgets/youtube_video_app.dart | 21 +- .../models/config/editor/image.dart | 136 +++++ .../models/config/editor/video.dart | 24 + .../models/config/editor/webview.dart | 6 + .../models/config/toolbar/buttons/camera.dart | 49 ++ .../config/toolbar/buttons/formula.dart | 28 ++ .../models/config/toolbar/buttons/image.dart | 53 ++ .../config/toolbar/buttons/media_button.dart | 84 ++++ .../models/config/toolbar/buttons/video.dart | 47 ++ .../lib/shims/dart_ui_fake.dart | 23 - flutter_quill_extensions/pubspec.yaml | 43 +- 50 files changed, 2573 insertions(+), 1548 deletions(-) create mode 100644 flutter_quill_extensions/lib/core/exceptions.dart delete mode 100644 flutter_quill_extensions/lib/embeds/builders.dart delete mode 100644 flutter_quill_extensions/lib/embeds/toolbar/camera_button.dart delete mode 100644 flutter_quill_extensions/lib/embeds/toolbar/formula_button.dart delete mode 100644 flutter_quill_extensions/lib/embeds/toolbar/image_button.dart delete mode 100644 flutter_quill_extensions/lib/embeds/toolbar/video_button.dart delete mode 100644 flutter_quill_extensions/lib/embeds/utils.dart create mode 100644 flutter_quill_extensions/lib/logic/extensions/controller.dart create mode 100644 flutter_quill_extensions/lib/logic/services/exceptions.dart create mode 100644 flutter_quill_extensions/lib/logic/services/image_saver.dart create mode 100644 flutter_quill_extensions/lib/logic/services/packages/gal.dart create mode 100644 flutter_quill_extensions/lib/logic/services/s_image_saver.dart rename flutter_quill_extensions/lib/{ => logic}/utils/quill_utils.dart (99%) create mode 100644 flutter_quill_extensions/lib/presentation/embeds/editor/formula.dart create mode 100644 flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart create mode 100644 flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart create mode 100644 flutter_quill_extensions/lib/presentation/embeds/editor/image/shims/dart_ui_fake.dart rename flutter_quill_extensions/lib/{ => presentation/embeds/editor/image}/shims/dart_ui_real.dart (100%) create mode 100644 flutter_quill_extensions/lib/presentation/embeds/editor/unknown.dart create mode 100644 flutter_quill_extensions/lib/presentation/embeds/editor/video.dart create mode 100644 flutter_quill_extensions/lib/presentation/embeds/editor/webview.dart rename flutter_quill_extensions/lib/{ => presentation}/embeds/embed_types.dart (86%) create mode 100644 flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button.dart create mode 100644 flutter_quill_extensions/lib/presentation/embeds/toolbar/formula_button.dart create mode 100644 flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button.dart rename flutter_quill_extensions/lib/{ => presentation}/embeds/toolbar/media_button.dart (63%) rename flutter_quill_extensions/lib/{embeds/toolbar => presentation/embeds/toolbar/utils}/image_video_utils.dart (88%) create mode 100644 flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button.dart create mode 100644 flutter_quill_extensions/lib/presentation/embeds/utils.dart rename flutter_quill_extensions/lib/{ => presentation}/embeds/widgets/image.dart (99%) rename flutter_quill_extensions/lib/{ => presentation}/embeds/widgets/image_resizer.dart (88%) create mode 100644 flutter_quill_extensions/lib/presentation/embeds/widgets/simple_dialog_item.dart rename flutter_quill_extensions/lib/{ => presentation}/embeds/widgets/video_app.dart (96%) rename flutter_quill_extensions/lib/{ => presentation}/embeds/widgets/youtube_video_app.dart (78%) create mode 100644 flutter_quill_extensions/lib/presentation/models/config/editor/image.dart create mode 100644 flutter_quill_extensions/lib/presentation/models/config/editor/video.dart create mode 100644 flutter_quill_extensions/lib/presentation/models/config/editor/webview.dart create mode 100644 flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart create mode 100644 flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/formula.dart create mode 100644 flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart create mode 100644 flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart create mode 100644 flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart delete mode 100644 flutter_quill_extensions/lib/shims/dart_ui_fake.dart diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index fffc4abb..3411d5e7 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -13,6 +13,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_quill/extensions.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; +import 'package:flutter_quill_extensions/presentation/models/config/toolbar/buttons/video.dart'; import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart'; @@ -102,7 +103,7 @@ class _HomePageState extends State { context: context, builder: (context) => AlertDialog( content: Text(_controller.document.toPlainText([ - ...FlutterQuillEmbeds.builders(), + ...FlutterQuillEmbeds.editorBuilders(), TimeStampEmbedBuilderWidget() ])), ), @@ -254,7 +255,7 @@ class _HomePageState extends State { ), ), embedBuilders: [ - ...FlutterQuillEmbeds.builders(), + ...FlutterQuillEmbeds.editorBuilders(), TimeStampEmbedBuilderWidget() ], ), @@ -267,9 +268,11 @@ class _HomePageState extends State { if (kIsWeb) { return QuillToolbar( configurations: QuillToolbarConfigurations( - embedButtons: FlutterQuillEmbeds.buttons( - onImagePickCallback: _onImagePickCallback, - webImagePickImpl: _webImagePickImpl, + embedButtons: FlutterQuillEmbeds.toolbarButtons( + imageButtonOptions: QuillToolbarImageButtonOptions( + onImagePickCallback: _onImagePickCallback, + webImagePickImpl: _webImagePickImpl, + ), ), buttonOptions: QuillToolbarButtonOptions( base: QuillToolbarBaseButtonOptions( @@ -283,9 +286,11 @@ class _HomePageState extends State { if (_isDesktop()) { return QuillToolbar( configurations: QuillToolbarConfigurations( - embedButtons: FlutterQuillEmbeds.buttons( - onImagePickCallback: _onImagePickCallback, - filePickImpl: openFileSystemPickerForDesktop, + embedButtons: FlutterQuillEmbeds.toolbarButtons( + imageButtonOptions: QuillToolbarImageButtonOptions( + onImagePickCallback: _onImagePickCallback, + filePickImpl: openFileSystemPickerForDesktop, + ), ), showAlignmentButtons: true, buttonOptions: QuillToolbarButtonOptions( @@ -299,16 +304,20 @@ class _HomePageState extends State { } return QuillToolbar( configurations: QuillToolbarConfigurations( - embedButtons: FlutterQuillEmbeds.buttons( - // provide a callback to enable picking images from device. - // if omit, "image" button only allows adding images from url. - // same goes for videos. - onImagePickCallback: _onImagePickCallback, - onVideoPickCallback: _onVideoPickCallback, - // uncomment to provide a custom "pick from" dialog. - // mediaPickSettingSelector: _selectMediaPickSetting, - // uncomment to provide a custom "pick from" dialog. - // cameraPickSettingSelector: _selectCameraPickSetting, + embedButtons: FlutterQuillEmbeds.toolbarButtons( + imageButtonOptions: QuillToolbarImageButtonOptions( + // provide a callback to enable picking images from device. + // if omit, "image" button only allows adding images from url. + // same goes for videos. + onImagePickCallback: _onImagePickCallback, + // uncomment to provide a custom "pick from" dialog. + // mediaPickSettingSelector: _selectMediaPickSetting, + // uncomment to provide a custom "pick from" dialog. + // cameraPickSettingSelector: _selectCameraPickSetting, + ), + videoButtonOptions: QuillToolbarVideoButtonOptions( + onVideoPickCallback: _onVideoPickCallback, + ), ), showAlignmentButtons: true, buttonOptions: QuillToolbarButtonOptions( @@ -437,12 +446,12 @@ class _HomePageState extends State { TextButton.icon( icon: const Icon(Icons.collections), label: const Text('Gallery'), - onPressed: () => Navigator.pop(ctx, MediaPickSetting.Gallery), + onPressed: () => Navigator.pop(ctx, MediaPickSetting.gallery), ), TextButton.icon( icon: const Icon(Icons.link), label: const Text('Link'), - onPressed: () => Navigator.pop(ctx, MediaPickSetting.Link), + onPressed: () => Navigator.pop(ctx, MediaPickSetting.link), ) ], ), @@ -461,12 +470,12 @@ class _HomePageState extends State { TextButton.icon( icon: const Icon(Icons.camera), label: const Text('Capture a photo'), - onPressed: () => Navigator.pop(ctx, MediaPickSetting.Camera), + onPressed: () => Navigator.pop(ctx, MediaPickSetting.camera), ), TextButton.icon( icon: const Icon(Icons.video_call), label: const Text('Capture a video'), - onPressed: () => Navigator.pop(ctx, MediaPickSetting.Video), + onPressed: () => Navigator.pop(ctx, MediaPickSetting.video), ) ], ), diff --git a/example/lib/pages/read_only_page.dart b/example/lib/pages/read_only_page.dart index 5693f6b3..0f5af5d6 100644 --- a/example/lib/pages/read_only_page.dart +++ b/example/lib/pages/read_only_page.dart @@ -40,7 +40,7 @@ class _ReadOnlyPageState extends State { configurations: QuillEditorConfigurations( expands: false, padding: EdgeInsets.zero, - embedBuilders: FlutterQuillEmbeds.builders(), + embedBuilders: FlutterQuillEmbeds.editorBuilders(), scrollable: true, autoFocus: true, ), diff --git a/example/lib/widgets/demo_scaffold.dart b/example/lib/widgets/demo_scaffold.dart index fb96b01c..78c350fc 100644 --- a/example/lib/widgets/demo_scaffold.dart +++ b/example/lib/widgets/demo_scaffold.dart @@ -88,15 +88,17 @@ class _DemoScaffoldState extends State { if (_isDesktop()) { return QuillToolbar( configurations: QuillToolbarConfigurations( - embedButtons: FlutterQuillEmbeds.buttons( - filePickImpl: openFileSystemPickerForDesktop, + embedButtons: FlutterQuillEmbeds.toolbarButtons( + imageButtonOptions: QuillToolbarImageButtonOptions( + filePickImpl: openFileSystemPickerForDesktop, + ), ), ), ); } return QuillToolbar( configurations: QuillToolbarConfigurations( - embedButtons: FlutterQuillEmbeds.buttons(), + embedButtons: FlutterQuillEmbeds.toolbarButtons(), ), ); } diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 67c40380..67c8f430 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.6.0-dev.1 +- Breaking Changes, we have refactored most of the functions and it got renamed + ## 0.5.1 - Provide a way to use custom image provider for the image widgets diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index a685b8f0..e33f8362 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -1,22 +1,154 @@ # Flutter Quill Extensions -Helpers to support embed widgets in flutter_quill. See [Flutter Quill](https://pub.dev/packages/flutter_quill) for details of use. +A extensions for [flutter_quill](https://pub.dev/packages/flutter_quill) +to support embed widgets like image, formula, video and more. + +Currently the support for **Web** is limitied. + + Check [Flutter Quill](https://github.com/singerdmx/flutter-quill) for details of use. + + ## Table of Contents + +- [Flutter Quill Extensions](#flutter-quill-extensions) + - [Table of Contents](#table-of-contents) + - [About](#about) + - [Installation](#installation) + - [Platform Spesefic Configurations](#platform-spesefic-configurations) + - [Usage](#usage) + - [Features](#features) + - [Contributing](#contributing) + - [License](#license) + - [Acknowledgments](#acknowledgments) + + +## About +Flutter quill is a rich editor text and it's allow you to customize a lot of things, it has custom embed builders which allow you to render custom widgets in the editor
    +this is a extensions to extends it functionallities by adding more features like images, videos, and more + +## Installation + +Before start using this package, please make sure to install +[flutter_quill](https://github.com/singerdmx/flutter-quill) package first and follow it's usage instructions. + +```yaml +dependencies: + flutter_quill_extensions: ^ +``` + +## Platform Spesefic Configurations + +> +> 1. We are using [`gal`](https://github.com/natsuk4ze/) plugin to save images. +> For this to work, you need to add the appropriate permissions +> to your `Info.plist` and `AndroidManifest.xml` files. +> See to add the needed lines. +> +> 2. We also use [`image_picker`](https://pub.dev/packages/image_picker) plugin for picking images so please make sure follow the instructions +> +> 3. For loading the image from the internet we need internet permission +> 1. For Android, you need to add some permissions in `AndroidManifest.xml`, Please follow this [link](https://developer.android.com/training/basics/network-ops/connecting) for more info, the internet permission included by default only for debugging so you need to follow this link to add it in the release version too. you should allow loading images and videos only for the `https` protocol but if you want http too then you need to configure your android application to accept `http` in the release mode, follow this [link](https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted) for more info. +> 2. for macOS you also need to include a key in your `Info.plist`, please follow this [link](https://stackoverflow.com/a/61201081/18519412) to add the required configurations +> +> The extensions package also use [image_picker](https://pub.dev/packages/image_picker) which also require some configurations, follow this [link](https://pub.dev/packages/image_picker#installation). It's needed for Android, iOS, macOS, we must inform you that you can't pick photo using camera in desktop so make sure to handle that if you plan on add support for desktop, this might changed in the future and for more info follow this [link](https://pub.dev/packages/image_picker#windows-macos-and-linux)
    +> ## Usage -Set the `embedBuilders` and `embedToolbar` params in `QuillEditor` and `QuillToolbar` with the +Before starting using this package you must follow the setup + +Set the `embedBuilders` and `embedToolbar` params in configurations of `QuillEditor` and `QuillToolbar` with the values provided by this repository. +**Quill toolbar**: +```dart +QuillToolbar( + configurations: QuillToolbarConfigurations( + embedButtons: FlutterQuillEmbeds.toolbarButtons( + imageButtonOptions: QuillToolbarImageButtonOptions( + onImagePickCallback: (file) async { + return file.path; + }, + ), + ), + ), +), ``` -QuillEditor.basic( - controller: controller, - embedBuilders: FlutterQuillEmbeds.builders(), -); + +**Quill Editor** +```dart +Expanded( + child: QuillEditor.basic( + configurations: QuillEditorConfigurations( + readOnly: true, + embedBuilders: FlutterQuillEmbeds.editorBuilders( + imageEmbedConfigurations: + const QuillEditorImageEmbedConfigurations( + forceUseMobileOptionMenuForImageClick: true, + ), + ), + ), + ), +) ``` +They both should be have a parent `QuillProvider` in the widget tree and setup properly
    +Example: + +```dart +QuillProvider( + configurations: QuillConfigurations( + controller: _controller, + sharedConfigurations: const QuillSharedConfigurations(), + ), + child: Column( + children: [ + QuillToolbar( + configurations: QuillToolbarConfigurations( + embedButtons: FlutterQuillEmbeds.toolbarButtons( + imageButtonOptions: QuillToolbarImageButtonOptions(), + ), + ), + ), + Expanded( + child: QuillEditor.basic( + configurations: QuillEditorConfigurations( + padding: const EdgeInsets.all(16), + embedBuilders: FlutterQuillEmbeds.editorBuilders(), + ), + ), + ) + ], + ), +) ``` -QuillToolbar.basic( - controller: controller, - embedButtons: FlutterQuillEmbeds.buttons(), -); + +For web, use: +```dart +FlutterQuillEmbeds.editorsWebBuilders() ``` + +## Features + +```markdown +## Features + +- Easy to use and customizable +- Has the option to use custom image provider for the images +- Usefull utilities and widgets +- Handle different errors +``` + +## Contributing + +We welcome contributions! + +Please follow these guidelines when contributing to our project. See [CONTRIBUTING.md](CONTRIBUTING.md) for more details. + +## License + +This project is licensed under the [MIT License](LICENSE) - see the [LICENSE](LICENSE) file for details. + +## Acknowledgments + +- Thanks to the [Flutter Team](https://flutter.dev/) +- Thanks to [flutter_quill](https://pub.dev/packages/flutter_quill) \ No newline at end of file diff --git a/flutter_quill_extensions/lib/core/exceptions.dart b/flutter_quill_extensions/lib/core/exceptions.dart new file mode 100644 index 00000000..3967adb7 --- /dev/null +++ b/flutter_quill_extensions/lib/core/exceptions.dart @@ -0,0 +1,12 @@ +// import 'package:meta/meta.dart'; + +// @immutable +// class NetworkException implements Exception { +// const NetworkException({required this.message}); + +// final String message; + +// @override +// String toString() => +// 'Error while loading something from the network: $message'; +// } diff --git a/flutter_quill_extensions/lib/embeds/builders.dart b/flutter_quill_extensions/lib/embeds/builders.dart deleted file mode 100644 index 2492fd7c..00000000 --- a/flutter_quill_extensions/lib/embeds/builders.dart +++ /dev/null @@ -1,476 +0,0 @@ -import 'dart:io' show File; - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_quill/extensions.dart' as base; -import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/translations.dart'; -import 'package:math_keyboard/math_keyboard.dart'; -import 'package:universal_html/html.dart' as html; - -import '../shims/dart_ui_fake.dart' - if (dart.library.html) '../shims/dart_ui_real.dart' as ui; -import 'embed_types.dart'; -import 'utils.dart'; -import 'widgets/image.dart'; -import 'widgets/image_resizer.dart'; -import 'widgets/video_app.dart'; -import 'widgets/youtube_video_app.dart'; - -class ImageEmbedBuilder extends EmbedBuilder { - ImageEmbedBuilder({ - required this.imageProviderBuilder, - required this.imageErrorWidgetBuilder, - required this.onImageRemovedCallback, - required this.shouldRemoveImageCallback, - this.forceUseMobileOptionMenu = false, - }); - final ImageEmbedBuilderOnRemovedCallback? onImageRemovedCallback; - final ImageEmbedBuilderWillRemoveCallback? shouldRemoveImageCallback; - final bool forceUseMobileOptionMenu; - final ImageEmbedBuilderProviderBuilder? imageProviderBuilder; - final ImageEmbedBuilderErrorWidgetBuilder? imageErrorWidgetBuilder; - - @override - String get key => BlockEmbed.imageType; - - @override - bool get expanded => false; - - @override - Widget build( - BuildContext context, - QuillController controller, - base.Embed node, - bool readOnly, - bool inline, - TextStyle textStyle, - ) { - assert(!kIsWeb, 'Please provide image EmbedBuilder for Web'); - - Widget image = const SizedBox.shrink(); - final imageUrl = standardizeImageUrl(node.value.data); - OptionalSize? imageSize; - final style = node.style.attributes['style']; - - if (style != null) { - final attrs = base.isMobile() - ? base.parseKeyValuePairs(style.value.toString(), { - Attribute.mobileWidth, - Attribute.mobileHeight, - Attribute.mobileMargin, - Attribute.mobileAlignment, - }) - : base.parseKeyValuePairs(style.value.toString(), { - Attribute.width.key, - Attribute.height.key, - Attribute.margin, - Attribute.alignment, - }); - if (attrs.isNotEmpty) { - final width = double.tryParse( - (base.isMobile() - ? attrs[Attribute.mobileWidth] - : attrs[Attribute.width.key]) ?? - '', - ); - final height = double.tryParse( - (base.isMobile() - ? attrs[Attribute.mobileHeight] - : attrs[Attribute.height.key]) ?? - '', - ); - final alignment = base.getAlignment(base.isMobile() - ? attrs[Attribute.mobileAlignment] - : attrs[Attribute.alignment]); - final margin = (base.isMobile() - ? double.tryParse(Attribute.mobileMargin) - : double.tryParse(Attribute.margin)) ?? - 0.0; - - assert( - width != null && height != null, - base.isMobile() - ? 'mobileWidth and mobileHeight must be specified' - : 'width and height must be specified', - ); - imageSize = OptionalSize(width, height); - image = Padding( - padding: EdgeInsets.all(margin), - child: getQuillImageByUrl( - imageUrl, - width: width, - height: height, - alignment: alignment, - imageProviderBuilder: imageProviderBuilder, - imageErrorWidgetBuilder: imageErrorWidgetBuilder, - ), - ); - } - } - - if (imageSize == null) { - image = getQuillImageByUrl( - imageUrl, - imageProviderBuilder: imageProviderBuilder, - imageErrorWidgetBuilder: imageErrorWidgetBuilder, - ); - imageSize = OptionalSize((image as Image).width, image.height); - } - - if (!readOnly && (base.isMobile() || forceUseMobileOptionMenu)) { - return GestureDetector( - onTap: () { - showDialog( - context: context, - builder: (context) { - final copyOption = _SimpleDialogItem( - icon: Icons.copy_all_outlined, - color: Colors.cyanAccent, - text: 'Copy'.i18n, - onPressed: () { - final imageNode = - getEmbedNode(controller, controller.selection.start) - .value; - final imageUrl = imageNode.value.data; - controller.copiedImageUrl = - ImageUrl(imageUrl, getImageStyleString(controller)); - Navigator.pop(context); - }, - ); - final removeOption = _SimpleDialogItem( - icon: Icons.delete_forever_outlined, - color: Colors.red.shade200, - text: 'Remove'.i18n, - onPressed: () async { - Navigator.of(context).pop(); - - final imageFile = File(imageUrl); - - // Call the remove check callback if set - if (await shouldRemoveImageCallback?.call(imageFile) == - false) { - return; - } - - final offset = getEmbedNode( - controller, - controller.selection.start, - ).offset; - controller.replaceText( - offset, - 1, - '', - TextSelection.collapsed(offset: offset), - ); - // Call the post remove callback if set - await onImageRemovedCallback?.call(imageFile); - }, - ); - return Padding( - padding: const EdgeInsets.fromLTRB(50, 0, 50, 0), - child: SimpleDialog( - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all( - Radius.circular(10), - ), - ), - children: [ - _SimpleDialogItem( - icon: Icons.settings_outlined, - color: Colors.lightBlueAccent, - text: 'Resize'.i18n, - onPressed: () { - Navigator.pop(context); - showCupertinoModalPopup( - context: context, - builder: (context) { - final screenSize = MediaQuery.sizeOf(context); - return ImageResizer( - onImageResize: (w, h) { - final res = getEmbedNode( - controller, - controller.selection.start, - ); - - final attr = - base.replaceStyleStringWithSize( - getImageStyleString(controller), - width: w, - height: h, - isMobile: base.isMobile(), - ); - controller - ..skipRequestKeyboard = true - ..formatText( - res.offset, - 1, - StyleAttribute(attr), - ); - }, - imageWidth: imageSize?.width, - imageHeight: imageSize?.height, - maxWidth: screenSize.width, - maxHeight: screenSize.height, - ); - }, - ); - }, - ), - copyOption, - removeOption, - ]), - ); - }); - }, - child: image, - ); - } - - if (!readOnly || isImageBase64(imageUrl)) { - // To enforce using it on the web, desktop and other platforms - // and that is up to the developer - if (!base.isMobile() && forceUseMobileOptionMenu) { - return _menuOptionsForReadonlyImage( - context: context, - imageUrl: imageUrl, - image: image, - imageProviderBuilder: imageProviderBuilder, - imageErrorWidgetBuilder: imageErrorWidgetBuilder, - ); - } - return image; - } - - // We provide option menu for mobile platform excluding base64 image - return _menuOptionsForReadonlyImage( - context: context, - imageUrl: imageUrl, - image: image, - imageProviderBuilder: imageProviderBuilder, - imageErrorWidgetBuilder: imageErrorWidgetBuilder, - ); - } -} - -class ImageEmbedBuilderWeb extends EmbedBuilder { - ImageEmbedBuilderWeb({this.constraints}) - : assert(kIsWeb, 'ImageEmbedBuilderWeb is only for web platform'); - - final BoxConstraints? constraints; - - @override - String get key => BlockEmbed.imageType; - - @override - Widget build( - BuildContext context, - QuillController controller, - Embed node, - bool readOnly, - bool inline, - TextStyle textStyle, - ) { - final imageUrl = node.value.data; - - ui.platformViewRegistry.registerViewFactory(imageUrl, (viewId) { - return html.ImageElement() - ..src = imageUrl - ..style.height = 'auto' - ..style.width = 'auto'; - }); - - return ConstrainedBox( - constraints: constraints ?? BoxConstraints.loose(const Size(200, 200)), - child: HtmlElementView( - viewType: imageUrl, - ), - ); - } -} - -class VideoEmbedBuilder extends EmbedBuilder { - VideoEmbedBuilder({this.onVideoInit}); - - final void Function(GlobalKey videoContainerKey)? onVideoInit; - - @override - String get key => BlockEmbed.videoType; - - @override - Widget build( - BuildContext context, - QuillController controller, - base.Embed node, - bool readOnly, - bool inline, - TextStyle textStyle, - ) { - assert(!kIsWeb, 'Please provide video EmbedBuilder for Web'); - - final videoUrl = node.value.data; - if (isYouTubeUrl(videoUrl)) { - return YoutubeVideoApp( - videoUrl: videoUrl, context: context, readOnly: readOnly); - } - return VideoApp( - videoUrl: videoUrl, - context: context, - readOnly: readOnly, - onVideoInit: onVideoInit, - ); - } -} - -class FormulaEmbedBuilder extends EmbedBuilder { - @override - String get key => BlockEmbed.formulaType; - - @override - Widget build( - BuildContext context, - QuillController controller, - base.Embed node, - bool readOnly, - bool inline, - TextStyle textStyle, - ) { - assert(!kIsWeb, 'Please provide formula EmbedBuilder for Web'); - - final mathController = MathFieldEditingController(); - return Focus( - onFocusChange: (hasFocus) { - if (hasFocus) { - // If the MathField is tapped, hides the built in keyboard - SystemChannels.textInput.invokeMethod('TextInput.hide'); - debugPrint(mathController.currentEditingValue()); - } - }, - child: MathField( - controller: mathController, - variables: const ['x', 'y', 'z'], - onChanged: (value) {}, - onSubmitted: (value) {}, - ), - ); - } -} - -Widget _menuOptionsForReadonlyImage({ - required BuildContext context, - required String imageUrl, - required Widget image, - required ImageEmbedBuilderProviderBuilder? imageProviderBuilder, - required ImageEmbedBuilderErrorWidgetBuilder? imageErrorWidgetBuilder, -}) { - return GestureDetector( - onTap: () { - showDialog( - context: context, - builder: (context) { - final saveOption = _SimpleDialogItem( - icon: Icons.save, - color: Colors.greenAccent, - text: 'Save'.i18n, - onPressed: () async { - imageUrl = appendFileExtensionToImageUrl(imageUrl); - final messenger = ScaffoldMessenger.of(context); - Navigator.of(context).pop(); - - final saveImageResult = await saveImage(imageUrl); - final imageSavedSuccessfully = saveImageResult.isSuccess; - - messenger.clearSnackBars(); - - if (!imageSavedSuccessfully) { - messenger.showSnackBar(SnackBar( - content: Text( - 'Error while saving image'.i18n, - ))); - return; - } - - var message; - switch (saveImageResult.method) { - case SaveImageResultMethod.network: - message = 'Saved using the network'.i18n; - break; - case SaveImageResultMethod.localStorage: - message = 'Saved using the local storage'.i18n; - break; - } - - messenger.showSnackBar( - SnackBar( - content: Text(message), - ), - ); - }, - ); - final zoomOption = _SimpleDialogItem( - icon: Icons.zoom_in, - color: Colors.cyanAccent, - text: 'Zoom'.i18n, - onPressed: () { - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => ImageTapWrapper( - imageUrl: imageUrl, - imageProviderBuilder: imageProviderBuilder, - imageErrorWidgetBuilder: imageErrorWidgetBuilder, - ), - ), - ); - }, - ); - return Padding( - padding: const EdgeInsets.fromLTRB(50, 0, 50, 0), - child: SimpleDialog( - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all( - Radius.circular(10), - ), - ), - children: [saveOption, zoomOption], - ), - ); - }, - ); - }, - child: image); -} - -class _SimpleDialogItem extends StatelessWidget { - const _SimpleDialogItem( - {required this.icon, - required this.color, - required this.text, - required this.onPressed, - Key? key}) - : super(key: key); - - final IconData icon; - final Color color; - final String text; - final VoidCallback onPressed; - - @override - Widget build(BuildContext context) { - return SimpleDialogOption( - onPressed: onPressed, - child: Row( - children: [ - Icon(icon, size: 36, color: color), - Padding( - padding: const EdgeInsetsDirectional.only(start: 16), - child: - Text(text, style: const TextStyle(fontWeight: FontWeight.bold)), - ), - ], - ), - ); - } -} diff --git a/flutter_quill_extensions/lib/embeds/toolbar/camera_button.dart b/flutter_quill_extensions/lib/embeds/toolbar/camera_button.dart deleted file mode 100644 index 2c512567..00000000 --- a/flutter_quill_extensions/lib/embeds/toolbar/camera_button.dart +++ /dev/null @@ -1,159 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/translations.dart'; -import 'package:image_picker/image_picker.dart'; - -import '../embed_types.dart'; -import 'image_video_utils.dart'; - -class CameraButton extends StatelessWidget { - const CameraButton({ - required this.icon, - required this.controller, - this.iconSize = kDefaultIconSize, - this.fillColor, - this.onImagePickCallback, - this.onVideoPickCallback, - this.filePickImpl, - this.webImagePickImpl, - this.webVideoPickImpl, - this.cameraPickSettingSelector, - this.iconTheme, - this.tooltip, - Key? key, - }) : super(key: key); - - final IconData icon; - final double iconSize; - - final Color? fillColor; - - final QuillController controller; - - final OnImagePickCallback? onImagePickCallback; - - final OnVideoPickCallback? onVideoPickCallback; - - final WebImagePickImpl? webImagePickImpl; - - final WebVideoPickImpl? webVideoPickImpl; - - final FilePickImpl? filePickImpl; - - final MediaPickSettingSelector? cameraPickSettingSelector; - - final QuillIconTheme? iconTheme; - final String? tooltip; - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - - final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; - final iconFillColor = - iconTheme?.iconUnselectedFillColor ?? (fillColor ?? theme.canvasColor); - - return QuillToolbarIconButton( - icon: Icon(icon, size: iconSize, color: iconColor), - tooltip: tooltip, - highlightElevation: 0, - hoverElevation: 0, - size: iconSize * 1.77, - fillColor: iconFillColor, - borderRadius: iconTheme?.borderRadius ?? 2, - onPressed: () => _handleCameraButtonTap( - context, - controller, - onImagePickCallback: onImagePickCallback, - onVideoPickCallback: onVideoPickCallback, - filePickImpl: filePickImpl, - webImagePickImpl: webImagePickImpl, - ), - ); - } - - Future _handleCameraButtonTap( - BuildContext context, - QuillController controller, { - OnImagePickCallback? onImagePickCallback, - OnVideoPickCallback? onVideoPickCallback, - FilePickImpl? filePickImpl, - WebImagePickImpl? webImagePickImpl, - }) async { - if (onVideoPickCallback == null && onImagePickCallback == null) { - throw ArgumentError( - 'onImagePickCallback and onVideoPickCallback are both null', - ); - } - final selector = cameraPickSettingSelector ?? - (context) => showDialog( - context: context, - builder: (ctx) => AlertDialog( - contentPadding: EdgeInsets.zero, - backgroundColor: Colors.transparent, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (onImagePickCallback != null) - TextButton.icon( - icon: const Icon( - Icons.camera, - color: Colors.orangeAccent, - ), - label: Text('Camera'.i18n), - onPressed: () => - Navigator.pop(ctx, MediaPickSetting.Camera), - ), - if (onVideoPickCallback != null) - TextButton.icon( - icon: const Icon( - Icons.video_call, - color: Colors.cyanAccent, - ), - label: Text('Video'.i18n), - onPressed: () => - Navigator.pop(ctx, MediaPickSetting.Video), - ) - ], - ), - ), - ); - - final source = await selector(context); - if (source == null) { - return; - } - switch (source) { - case MediaPickSetting.Camera: - await ImageVideoUtils.handleImageButtonTap( - context, - controller, - ImageSource.camera, - onImagePickCallback!, - filePickImpl: filePickImpl, - webImagePickImpl: webImagePickImpl, - ); - break; - case MediaPickSetting.Video: - await ImageVideoUtils.handleVideoButtonTap( - context, - controller, - ImageSource.camera, - onVideoPickCallback!, - filePickImpl: filePickImpl, - webVideoPickImpl: webVideoPickImpl, - ); - break; - case MediaPickSetting.Gallery: - throw ArgumentError( - 'Invalid MediaSetting for the camera button.\n' - 'gallery is not related to camera button', - ); - case MediaPickSetting.Link: - throw ArgumentError( - 'Invalid MediaSetting for the camera button.\n' - 'link is not related to camera button', - ); - } - } -} diff --git a/flutter_quill_extensions/lib/embeds/toolbar/formula_button.dart b/flutter_quill_extensions/lib/embeds/toolbar/formula_button.dart deleted file mode 100644 index 882d067c..00000000 --- a/flutter_quill_extensions/lib/embeds/toolbar/formula_button.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill.dart'; - -class FormulaButton extends StatelessWidget { - const FormulaButton({ - required this.icon, - required this.controller, - this.iconSize = kDefaultIconSize, - this.fillColor, - this.iconTheme, - this.dialogTheme, - this.tooltip, - Key? key, - }) : super(key: key); - - final IconData icon; - - final double iconSize; - - final Color? fillColor; - - final QuillController controller; - - final QuillIconTheme? iconTheme; - - final QuillDialogTheme? dialogTheme; - final String? tooltip; - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - - final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; - final iconFillColor = - iconTheme?.iconUnselectedFillColor ?? (fillColor ?? theme.canvasColor); - - return QuillToolbarIconButton( - icon: Icon(icon, size: iconSize, color: iconColor), - tooltip: tooltip, - highlightElevation: 0, - hoverElevation: 0, - size: iconSize * 1.77, - fillColor: iconFillColor, - borderRadius: iconTheme?.borderRadius ?? 2, - onPressed: () => _onPressedHandler(context), - ); - } - - Future _onPressedHandler(BuildContext context) async { - final index = controller.selection.baseOffset; - final length = controller.selection.extentOffset - index; - - controller.replaceText(index, length, BlockEmbed.formula(''), null); - } -} diff --git a/flutter_quill_extensions/lib/embeds/toolbar/image_button.dart b/flutter_quill_extensions/lib/embeds/toolbar/image_button.dart deleted file mode 100644 index af5f924f..00000000 --- a/flutter_quill_extensions/lib/embeds/toolbar/image_button.dart +++ /dev/null @@ -1,138 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill.dart'; -import 'package:image_picker/image_picker.dart'; - -import '../embed_types.dart'; -import 'image_video_utils.dart'; - -class ImageButton extends StatelessWidget { - const ImageButton({ - required this.icon, - required this.controller, - this.iconSize = kDefaultIconSize, - this.onImagePickCallback, - this.fillColor, - this.filePickImpl, - this.webImagePickImpl, - this.mediaPickSettingSelector, - this.iconTheme, - this.dialogTheme, - this.tooltip, - this.linkRegExp, - Key? key, - }) : super(key: key); - - final IconData icon; - final double iconSize; - - final Color? fillColor; - - final QuillController controller; - - final OnImagePickCallback? onImagePickCallback; - - final WebImagePickImpl? webImagePickImpl; - - final FilePickImpl? filePickImpl; - - final MediaPickSettingSelector? mediaPickSettingSelector; - - final QuillIconTheme? iconTheme; - - final QuillDialogTheme? dialogTheme; - final String? tooltip; - final RegExp? linkRegExp; - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - - final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; - final iconFillColor = - iconTheme?.iconUnselectedFillColor ?? (fillColor ?? theme.canvasColor); - - return QuillToolbarIconButton( - icon: Icon(icon, size: iconSize, color: iconColor), - tooltip: tooltip, - highlightElevation: 0, - hoverElevation: 0, - size: iconSize * 1.77, - fillColor: iconFillColor, - borderRadius: iconTheme?.borderRadius ?? 2, - onPressed: () => _onPressedHandler(context), - ); - } - - Future _onPressedHandler(BuildContext context) async { - final onImagePickCallbackRef = onImagePickCallback; - if (onImagePickCallbackRef == null) { - await _typeLink(context); - return; - } - final selector = - mediaPickSettingSelector ?? ImageVideoUtils.selectMediaPickSetting; - final source = await selector(context); - if (source == null) { - return; - } - switch (source) { - case MediaPickSetting.Gallery: - _pickImage(context); - break; - case MediaPickSetting.Link: - await _typeLink(context); - break; - case MediaPickSetting.Camera: - await ImageVideoUtils.handleImageButtonTap( - context, - controller, - ImageSource.camera, - onImagePickCallbackRef, - filePickImpl: filePickImpl, - webImagePickImpl: webImagePickImpl, - ); - break; - case MediaPickSetting.Video: - throw ArgumentError( - 'Sorry but this is the Image button and not the video one', - ); - } - - // This will not work for the pick image using camera (bug fix) - // if (source != null) { - // if (source == MediaPickSetting.Gallery) { - - // } else { - // _typeLink(context); - // } - } - - void _pickImage(BuildContext context) => ImageVideoUtils.handleImageButtonTap( - context, - controller, - ImageSource.gallery, - onImagePickCallback!, - filePickImpl: filePickImpl, - webImagePickImpl: webImagePickImpl, - ); - - Future _typeLink(BuildContext context) async { - final value = await showDialog( - context: context, - builder: (_) => LinkDialog( - dialogTheme: dialogTheme, - linkRegExp: linkRegExp, - ), - ); - _linkSubmitted(value); - } - - void _linkSubmitted(String? value) { - if (value != null && value.isNotEmpty) { - final index = controller.selection.baseOffset; - final length = controller.selection.extentOffset - index; - - controller.replaceText(index, length, BlockEmbed.image(value), null); - } - } -} diff --git a/flutter_quill_extensions/lib/embeds/toolbar/video_button.dart b/flutter_quill_extensions/lib/embeds/toolbar/video_button.dart deleted file mode 100644 index f09d193b..00000000 --- a/flutter_quill_extensions/lib/embeds/toolbar/video_button.dart +++ /dev/null @@ -1,110 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill.dart'; -import 'package:image_picker/image_picker.dart'; - -import '../embed_types.dart'; -import 'image_video_utils.dart'; - -class VideoButton extends StatelessWidget { - const VideoButton({ - required this.icon, - required this.controller, - this.iconSize = kDefaultIconSize, - this.onVideoPickCallback, - this.fillColor, - this.filePickImpl, - this.webVideoPickImpl, - this.mediaPickSettingSelector, - this.iconTheme, - this.dialogTheme, - this.tooltip, - this.linkRegExp, - Key? key, - }) : super(key: key); - - final IconData icon; - final double iconSize; - - final Color? fillColor; - - final QuillController controller; - - final OnVideoPickCallback? onVideoPickCallback; - - final WebVideoPickImpl? webVideoPickImpl; - - final FilePickImpl? filePickImpl; - - final MediaPickSettingSelector? mediaPickSettingSelector; - - final QuillIconTheme? iconTheme; - - final QuillDialogTheme? dialogTheme; - - final String? tooltip; - - final RegExp? linkRegExp; - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - - final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; - final iconFillColor = - iconTheme?.iconUnselectedFillColor ?? (fillColor ?? theme.canvasColor); - - return QuillToolbarIconButton( - icon: Icon(icon, size: iconSize, color: iconColor), - tooltip: tooltip, - highlightElevation: 0, - hoverElevation: 0, - size: iconSize * 1.77, - fillColor: iconFillColor, - borderRadius: iconTheme?.borderRadius ?? 2, - onPressed: () => _onPressedHandler(context), - ); - } - - Future _onPressedHandler(BuildContext context) async { - if (onVideoPickCallback != null) { - final selector = - mediaPickSettingSelector ?? ImageVideoUtils.selectMediaPickSetting; - final source = await selector(context); - if (source != null) { - if (source == MediaPickSetting.Gallery) { - _pickVideo(context); - } else { - await _typeLink(context); - } - } - } else { - await _typeLink(context); - } - } - - void _pickVideo(BuildContext context) => ImageVideoUtils.handleVideoButtonTap( - context, - controller, - ImageSource.gallery, - onVideoPickCallback!, - filePickImpl: filePickImpl, - webVideoPickImpl: webVideoPickImpl, - ); - - Future _typeLink(BuildContext context) async { - final value = await showDialog( - context: context, - builder: (_) => LinkDialog(dialogTheme: dialogTheme), - ); - _linkSubmitted(value); - } - - void _linkSubmitted(String? value) { - if (value != null && value.isNotEmpty) { - final index = controller.selection.baseOffset; - final length = controller.selection.extentOffset - index; - - controller.replaceText(index, length, BlockEmbed.video(value), null); - } - } -} diff --git a/flutter_quill_extensions/lib/embeds/utils.dart b/flutter_quill_extensions/lib/embeds/utils.dart deleted file mode 100644 index 9d92f149..00000000 --- a/flutter_quill_extensions/lib/embeds/utils.dart +++ /dev/null @@ -1,106 +0,0 @@ -import 'dart:io' show File; - -import 'package:flutter/foundation.dart' show Uint8List, immutable; -import 'package:gal/gal.dart'; -import 'package:http/http.dart' as http; - -// I would like to orgnize the project structure and the code more -// but here I don't want to change too much since that is a community project - -RegExp _base64 = RegExp( - r'^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$', -); - -bool isBase64(String str) { - return _base64.hasMatch(str); -} - -bool isHttpBasedUrl(String url) { - try { - final uri = Uri.parse(url.trim()); - return uri.isScheme('HTTP') || uri.isScheme('HTTPS'); - } catch (_) { - return false; - } -} - -bool isYouTubeUrl(String videoUrl) { - try { - final uri = Uri.parse(videoUrl); - return uri.host == 'www.youtube.com' || - uri.host == 'youtube.com' || - uri.host == 'youtu.be'; - } catch (_) { - return false; - } -} - -bool isImageBase64(String imageUrl) { - return !isHttpBasedUrl(imageUrl) && isBase64(imageUrl); -} - -enum SaveImageResultMethod { network, localStorage } - -@immutable -class _SaveImageResult { - const _SaveImageResult({required this.isSuccess, required this.method}); - - final bool isSuccess; - final SaveImageResultMethod method; -} - -Future<_SaveImageResult> saveImage(String imageUrl) async { - final imageFile = File(imageUrl); - final hasPermission = await Gal.hasAccess(); - final imageExistsLocally = await imageFile.exists(); - if (!hasPermission) { - await Gal.requestAccess(); - } - if (!imageExistsLocally) { - final success = await _saveNetworkImageToLocal(imageUrl); - return _SaveImageResult( - isSuccess: success, - method: SaveImageResultMethod.network, - ); - } - final success = await _saveImageLocally(imageFile); - return _SaveImageResult( - isSuccess: success, - method: SaveImageResultMethod.localStorage, - ); -} - -Future _saveNetworkImageToLocal(String imageUrl) async { - try { - final response = await http.get( - Uri.parse(imageUrl), - ); - if (response.statusCode != 200) { - return false; - } - final imageBytes = response.bodyBytes; - await Gal.putImageBytes(imageBytes); - return true; - } catch (e) { - return false; - } -} - -Future _convertFileToUint8List(File file) async { - try { - final uint8list = await file.readAsBytes(); - return uint8list; - } catch (e) { - return Uint8List(0); - } -} - -Future _saveImageLocally(File imageFile) async { - try { - final imageBytes = await _convertFileToUint8List(imageFile); - await Gal.putImageBytes(imageBytes); - return true; - } catch (e) { - return false; - } -} diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index 0fc6a54e..efc3a6ab 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -1,27 +1,45 @@ library flutter_quill_extensions; -import 'package:flutter/material.dart'; -import 'package:flutter_quill/extensions.dart'; +import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter_quill/flutter_quill.dart'; +import 'package:meta/meta.dart' show immutable; -import 'embeds/builders.dart'; -import 'embeds/embed_types.dart'; -import 'embeds/toolbar/camera_button.dart'; -import 'embeds/toolbar/formula_button.dart'; -import 'embeds/toolbar/image_button.dart'; -import 'embeds/toolbar/media_button.dart'; -import 'embeds/toolbar/video_button.dart'; +import 'presentation/embeds/editor/image/image.dart'; +import 'presentation/embeds/editor/image/image_web.dart'; +import 'presentation/embeds/editor/video.dart'; +import 'presentation/embeds/editor/webview.dart'; +import 'presentation/embeds/toolbar/camera_button.dart'; +import 'presentation/embeds/toolbar/formula_button.dart'; +import 'presentation/embeds/toolbar/image_button.dart'; +import 'presentation/embeds/toolbar/media_button.dart'; +import 'presentation/embeds/toolbar/video_button.dart'; +import 'presentation/models/config/editor/image.dart'; +import 'presentation/models/config/editor/video.dart'; +import 'presentation/models/config/editor/webview.dart'; +import 'presentation/models/config/toolbar/buttons/camera.dart'; +import 'presentation/models/config/toolbar/buttons/formula.dart'; +import 'presentation/models/config/toolbar/buttons/image.dart'; +import 'presentation/models/config/toolbar/buttons/media_button.dart'; +import 'presentation/models/config/toolbar/buttons/video.dart'; -export 'embeds/embed_types.dart'; -export 'embeds/toolbar/camera_button.dart'; -export 'embeds/toolbar/formula_button.dart'; -export 'embeds/toolbar/image_button.dart'; -export 'embeds/toolbar/image_video_utils.dart'; -export 'embeds/toolbar/media_button.dart'; -export 'embeds/toolbar/video_button.dart'; -export 'embeds/utils.dart'; +export '/presentation/models/config/editor/webview.dart'; +export './logic/extensions/controller.dart'; +export 'presentation/embeds/editor/unknown.dart'; +export 'presentation/embeds/embed_types.dart'; +export 'presentation/embeds/toolbar/camera_button.dart'; +export 'presentation/embeds/toolbar/formula_button.dart'; +export 'presentation/embeds/toolbar/image_button.dart'; +export 'presentation/embeds/toolbar/media_button.dart'; +export 'presentation/embeds/toolbar/utils/image_video_utils.dart'; +export 'presentation/embeds/toolbar/video_button.dart'; +export 'presentation/embeds/utils.dart'; +export 'presentation/models/config/editor/image.dart'; +export 'presentation/models/config/toolbar/buttons/image.dart'; +@immutable class FlutterQuillEmbeds { + const FlutterQuillEmbeds._(); + /// Returns a list of embed builders for QuillEditor. /// /// This method provides a collection of embed builders to enhance the @@ -32,179 +50,89 @@ class FlutterQuillEmbeds { /// /// **Note:** This method is not intended for web usage. /// For web-specific embeds, - /// use [webBuilders]. - /// - /// [onVideoInit] is a callback function that gets triggered when - /// a video is initialized. - /// You can use this to perform actions or setup configurations related - /// to video embedding. - /// - /// [onImageRemovedCallback] is called when an image is - /// removed from the editor. - /// By default, [onImageRemovedCallback] deletes the - /// temporary image file if - /// the platform is mobile and if it still exists. You - /// can customize this behavior - /// by passing your own function that handles the removal process. - /// - /// Example of [onImageRemovedCallback] customization: - /// ```dart - /// afterRemoveImageFromEditor: (imageFile) async { - /// // Your custom logic here - /// // or leave it empty to do nothing - /// } - /// ``` - /// - /// [shouldRemoveImageCallback] is a callback - /// function that is invoked when the - /// user attempts to remove an image from the editor. It allows you to control - /// whether the image should be removed based on your custom logic. - /// - /// Example of [shouldRemoveImageCallback] customization: - /// ```dart - /// shouldRemoveImageFromEditor: (imageFile) async { - /// // Show a confirmation dialog before removing the image - /// final isShouldRemove = await showYesCancelDialog( - /// context: context, - /// options: const YesOrCancelDialogOptions( - /// title: 'Deleting an image', - /// message: 'Are you sure you want' ' to delete this - /// image from the editor?', - /// ), - /// ); - /// - /// // Return `true` to allow image removal if the user confirms, otherwise - /// `false` - /// return isShouldRemove; - /// } - /// ``` - /// - /// [imageProviderBuilder] if you want to use custom image provider, please - /// pass a value to this property - /// By default we will use [NetworkImage] provider if the image url/path - /// is using http/https, if not then we will use [FileImage] provider - /// If you ovveride this make sure to handle the case where if the [imageUrl] - /// is in the local storage or it does exists in the system file - /// or use the same way we did it - /// - /// Example of [imageProviderBuilder] customization: - /// ```dart - /// imageProviderBuilder: (imageUrl) async { - /// // Example of using cached_network_image package - /// // Don't forgot to check if that image is local or network one - /// return CachedNetworkImageProvider(imageUrl); - /// } - /// ``` - /// - /// [imageErrorWidgetBuilder] if you want to show a custom widget based on the - /// exception that happen while loading the image, if it network image or - /// local one, and it will get called on all the images even in the photo - /// preview widget and not just in the quill editor - /// by default the default error from flutter framework will thrown + /// use [editorsWebBuilders]. /// - /// [forceUseMobileOptionMenuForImageClick] is a boolean - /// flag that, when set to `true`, - /// enforces the use of the mobile-specific option menu for image clicks in - /// other platforms like desktop, this option doesn't affect mobile. it will - /// not affect web - /// This option - /// can be used to override the default behavior based on the platform. /// /// The method returns a list of [EmbedBuilder] objects that can be used with /// QuillEditor /// to enable embedded content features like images, videos, and formulas. /// - /// Example usage: - /// ```dart - /// final embedBuilders = QuillEmbedBuilders.builders( - /// onVideoInit: (videoContainerKey) { - /// // Custom video initialization logic - /// }, - /// // Customize other callback functions as needed - /// ); /// /// final quillEditor = QuillEditor( /// // Other editor configurations /// embedBuilders: embedBuilders, /// ); /// ``` - static List builders({ - void Function(GlobalKey videoContainerKey)? onVideoInit, - ImageEmbedBuilderOnRemovedCallback? onImageRemovedCallback, - ImageEmbedBuilderWillRemoveCallback? shouldRemoveImageCallback, - ImageEmbedBuilderProviderBuilder? imageProviderBuilder, - ImageEmbedBuilderErrorWidgetBuilder? imageErrorWidgetBuilder, - bool forceUseMobileOptionMenuForImageClick = false, - }) => - [ - ImageEmbedBuilder( - imageErrorWidgetBuilder: imageErrorWidgetBuilder, - imageProviderBuilder: imageProviderBuilder, - forceUseMobileOptionMenu: forceUseMobileOptionMenuForImageClick, - onImageRemovedCallback: onImageRemovedCallback ?? - (imageFile) async { - final mobile = isMobile(); - // If the platform is not mobile, return void; - // Since the mobile OS gives us a copy of the image - - // Note: We should remove the image on Flutter web - // since the behavior is similar to how it is on mobile, - // but since this builder is not for web, we will ignore it - if (!mobile) { - return; - } - - // On mobile OS (Android, iOS), the system will not give us - // direct access to the image; instead, - // it will give us the image - // in the temp directory of the application. So, we want to - // remove it when we no longer need it. - - // but on desktop we don't want to touch user files - // especially on macOS, where we can't even delete it without - // permission - - final isFileExists = await imageFile.exists(); - if (isFileExists) { - await imageFile.delete(); - } - }, - shouldRemoveImageCallback: shouldRemoveImageCallback, + /// + /// if you don't want image embed in your quill editor then please pass null + /// to [imageEmbedConfigurations]. same apply to [videoEmbedConfigurations] + static List editorBuilders({ + QuillEditorImageEmbedConfigurations? imageEmbedConfigurations = + const QuillEditorImageEmbedConfigurations(), + QuillEditorVideoEmbedConfigurations? videoEmbedConfigurations = + const QuillEditorVideoEmbedConfigurations(), + QuillEditorWebViewEmbedConfigurations? webViewEmbedConfigurations = + const QuillEditorWebViewEmbedConfigurations(), + }) { + if (kIsWeb) { + throw UnsupportedError( + 'The editorBuilders() is not for web, please use editorBuilders() ' + 'instead', + ); + } + return [ + if (imageEmbedConfigurations != null) + QuillEditorImageEmbedBuilder( + configurations: QuillEditorImageEmbedConfigurations( + imageErrorWidgetBuilder: + imageEmbedConfigurations.imageErrorWidgetBuilder, + imageProviderBuilder: imageEmbedConfigurations.imageProviderBuilder, + forceUseMobileOptionMenuForImageClick: + imageEmbedConfigurations.forceUseMobileOptionMenuForImageClick, + onImageRemovedCallback: + imageEmbedConfigurations.onImageRemovedCallback ?? + QuillEditorImageEmbedConfigurations + .defaultOnImageRemovedCallback, + shouldRemoveImageCallback: + imageEmbedConfigurations.shouldRemoveImageCallback, + ), ), - VideoEmbedBuilder(onVideoInit: onVideoInit), - FormulaEmbedBuilder(), - ]; + if (videoEmbedConfigurations != null) + QuillEditorVideoEmbedBuilder( + configurations: videoEmbedConfigurations, + ), + const QuillEditorFormulaEmbedBuilder(), + if (webViewEmbedConfigurations != null) + QuillEditorWebViewEmbedBuilder( + configurations: webViewEmbedConfigurations, + ) + ]; + } /// Returns a list of embed builders specifically designed for web support. /// /// [ImageEmbedBuilderWeb] is the embed builder for handling /// images on the web. /// - static List webBuilders() => [ - ImageEmbedBuilderWeb(), - ]; + static List editorsWebBuilders({ + QuillEditorWebImageEmbedConfigurations? imageEmbedConfigurations = + const QuillEditorWebImageEmbedConfigurations(), + }) { + if (!kIsWeb) { + throw UnsupportedError( + 'The editorsWebBuilders() is only for web, please use editorBuilders() ' + 'instead', + ); + } + return [ + if (imageEmbedConfigurations != null) const ImageEmbedBuilderWeb(), + ]; + } /// Returns a list of embed button builders to customize the toolbar buttons. /// - /// [showImageButton] determines whether the image button should be displayed. - /// [showVideoButton] determines whether the video button should be displayed. - /// [showCameraButton] determines whether the camera button should - /// be displayed. - /// [showFormulaButton] determines whether the formula button - /// should be displayed. - /// - /// [imageButtonTooltip] specifies the tooltip text for the image button. - /// [videoButtonTooltip] specifies the tooltip text for the video button. - /// [cameraButtonTooltip] specifies the tooltip text for the camera button. - /// [formulaButtonTooltip] specifies the tooltip text for the formula button. - /// - /// [onImagePickCallback] is a callback function called when an - /// image is picked. - /// [onVideoPickCallback] is a callback function called when a - /// video is picked. - /// - /// [mediaPickSettingSelector] allows customizing media pick settings. - /// [cameraPickSettingSelector] allows customizing camera pick settings. + /// If you don't want to show one of the buttons for soem reason, + /// pass null to the options of it /// /// Example of customizing media pick settings for the image button: /// ```dart @@ -222,110 +150,49 @@ class FlutterQuillEmbeds { /// } /// ``` /// - /// [filePickImpl] is an implementation for picking files. - /// [webImagePickImpl] is an implementation for picking web images. - /// [webVideoPickImpl] is an implementation for picking web videos. - /// - /// [imageLinkRegExp] is a regular expression to identify image links. - /// [videoLinkRegExp] is a regular expression to identify video links. /// /// The returned list contains embed button builders for the Quill toolbar. - static List buttons({ - bool showImageButton = true, - bool showVideoButton = true, - bool showCameraButton = true, - bool showImageMediaButton = false, - bool showFormulaButton = false, - String? imageButtonTooltip, - String? videoButtonTooltip, - String? cameraButtonTooltip, - String? formulaButtonTooltip, - OnImagePickCallback? onImagePickCallback, - OnVideoPickCallback? onVideoPickCallback, - MediaPickSettingSelector? mediaPickSettingSelector, - MediaPickSettingSelector? cameraPickSettingSelector, - MediaPickedCallback? onImageMediaPickedCallback, - FilePickImpl? filePickImpl, - WebImagePickImpl? webImagePickImpl, - WebVideoPickImpl? webVideoPickImpl, - RegExp? imageLinkRegExp, - RegExp? videoLinkRegExp, + /// the [formulaButtonOptions] will be disabled by default on web + static List toolbarButtons({ + QuillToolbarImageButtonOptions? imageButtonOptions = + const QuillToolbarImageButtonOptions(), + QuillToolbarVideoButtonOptions? videoButtonOptions = + const QuillToolbarVideoButtonOptions(), + QuillToolbarFormulaButtonOptions? formulaButtonOptions = + const QuillToolbarFormulaButtonOptions(), + QuillToolbarCameraButtonOptions? cameraButtonOptions, + QuillToolbarMediaButtonOptions? mediaButtonOptions, }) => [ - if (showImageButton) - (controller, toolbarIconSize, iconTheme, dialogTheme) => ImageButton( - icon: Icons.image, - iconSize: toolbarIconSize, - tooltip: imageButtonTooltip, - controller: controller, - onImagePickCallback: onImagePickCallback, - filePickImpl: filePickImpl, - webImagePickImpl: webImagePickImpl, - mediaPickSettingSelector: mediaPickSettingSelector, - iconTheme: iconTheme, - dialogTheme: dialogTheme, - linkRegExp: imageLinkRegExp, + if (imageButtonOptions != null) + (controller, toolbarIconSize, iconTheme, dialogTheme) => + QuillToolbarImageButton( + controller: imageButtonOptions.controller ?? controller, + options: imageButtonOptions, ), - if (showVideoButton) - (controller, toolbarIconSize, iconTheme, dialogTheme) => VideoButton( - icon: Icons.movie_creation, - iconSize: toolbarIconSize, - tooltip: videoButtonTooltip, - controller: controller, - onVideoPickCallback: onVideoPickCallback, - filePickImpl: filePickImpl, - webVideoPickImpl: webImagePickImpl, - mediaPickSettingSelector: mediaPickSettingSelector, - iconTheme: iconTheme, - dialogTheme: dialogTheme, - linkRegExp: videoLinkRegExp, + if (videoButtonOptions != null) + (controller, toolbarIconSize, iconTheme, dialogTheme) => + QuillToolbarVideoButton( + controller: videoButtonOptions.controller ?? controller, + options: videoButtonOptions, ), - if ((onImagePickCallback != null || onVideoPickCallback != null) && - showCameraButton) - (controller, toolbarIconSize, iconTheme, dialogTheme) => CameraButton( - icon: Icons.photo_camera, - iconSize: toolbarIconSize, - tooltip: cameraButtonTooltip, - controller: controller, - onImagePickCallback: onImagePickCallback, - onVideoPickCallback: onVideoPickCallback, - filePickImpl: filePickImpl, - webImagePickImpl: webImagePickImpl, - webVideoPickImpl: webVideoPickImpl, - cameraPickSettingSelector: cameraPickSettingSelector, - iconTheme: iconTheme, + if (cameraButtonOptions != null) + (controller, toolbarIconSize, iconTheme, dialogTheme) => + QuillToolbarCameraButton( + controller: cameraButtonOptions.controller ?? controller, + options: cameraButtonOptions, ), - if (showImageMediaButton) - (controller, toolbarIconSize, iconTheme, dialogTheme) => MediaButton( - controller: controller, - dialogTheme: dialogTheme, - iconTheme: iconTheme, - iconSize: toolbarIconSize, - onMediaPickedCallback: onImageMediaPickedCallback, - onImagePickCallback: onImagePickCallback ?? - (throw ArgumentError.notNull( - 'onImagePickCallback is required when showCameraButton is' - ' true', - )), - onVideoPickCallback: onVideoPickCallback ?? - (throw ArgumentError.notNull( - 'onVideoPickCallback is required when showCameraButton is' - ' true', - )), - filePickImpl: filePickImpl, - webImagePickImpl: webImagePickImpl, - webVideoPickImpl: webVideoPickImpl, - icon: Icons.perm_media, + if (mediaButtonOptions != null) + (controller, toolbarIconSize, iconTheme, dialogTheme) => + QuillToolbarMediaButton( + controller: mediaButtonOptions.controller ?? controller, + options: mediaButtonOptions, ), - if (showFormulaButton) + if (formulaButtonOptions != null && !kIsWeb) (controller, toolbarIconSize, iconTheme, dialogTheme) => - FormulaButton( - icon: Icons.functions, - iconSize: toolbarIconSize, - tooltip: formulaButtonTooltip, - controller: controller, - iconTheme: iconTheme, - dialogTheme: dialogTheme, + QuillToolbarFormulaButton( + controller: formulaButtonOptions.controller ?? controller, + options: formulaButtonOptions, ), ]; } diff --git a/flutter_quill_extensions/lib/logic/extensions/controller.dart b/flutter_quill_extensions/lib/logic/extensions/controller.dart new file mode 100644 index 00000000..3fe39ac2 --- /dev/null +++ b/flutter_quill_extensions/lib/logic/extensions/controller.dart @@ -0,0 +1,39 @@ +import 'package:flutter_quill/flutter_quill.dart'; + +import '../../presentation/embeds/editor/webview.dart'; + +extension QuillControllerExt on QuillController { + int get index => selection.baseOffset; + int get length => selection.extentOffset - index; + void insertWebViewBlock({ + required String initialUrl, + }) { + final block = BlockEmbed.custom( + QuillEditorWebViewBlockEmbed( + initialUrl, + ), + ); + + this + ..skipRequestKeyboard = true + ..replaceText( + index, + length, + block, + null, + ); + } + + void insertImageBlock({ + required String imageUrl, + }) { + this + ..skipRequestKeyboard = true + ..replaceText( + index, + length, + BlockEmbed.image(imageUrl), + null, + ); + } +} diff --git a/flutter_quill_extensions/lib/logic/services/exceptions.dart b/flutter_quill_extensions/lib/logic/services/exceptions.dart new file mode 100644 index 00000000..70933e10 --- /dev/null +++ b/flutter_quill_extensions/lib/logic/services/exceptions.dart @@ -0,0 +1,23 @@ +import 'package:meta/meta.dart' show immutable; + +enum ImageSaverExceptionType { + accessDenied, + notEnoughSpace, + notSupportedFormat, + unexpected, + unknown; +} + +@immutable +class ImageSaverException implements Exception { + const ImageSaverException({ + required this.message, + required this.type, + }); + + final String message; + final ImageSaverExceptionType type; + + @override + String toString() => 'Error while saving image, error type: ${type.name}'; +} diff --git a/flutter_quill_extensions/lib/logic/services/image_saver.dart b/flutter_quill_extensions/lib/logic/services/image_saver.dart new file mode 100644 index 00000000..2417ae8c --- /dev/null +++ b/flutter_quill_extensions/lib/logic/services/image_saver.dart @@ -0,0 +1,7 @@ +abstract class ImageSaverInterface { + const ImageSaverInterface(); + Future saveLocalImage(String imageUrl); + Future saveImageFromNetwork(Uri imageUrl); + Future hasAccess({required bool toAlbum}); + Future requestAccess({required bool toAlbum}); +} diff --git a/flutter_quill_extensions/lib/logic/services/packages/gal.dart b/flutter_quill_extensions/lib/logic/services/packages/gal.dart new file mode 100644 index 00000000..aec93ff4 --- /dev/null +++ b/flutter_quill_extensions/lib/logic/services/packages/gal.dart @@ -0,0 +1,77 @@ +import 'package:flutter/widgets.dart' show NetworkImageLoadException; +import 'package:gal/gal.dart' show Gal, GalException, GalExceptionType; +import 'package:http/http.dart' as http; + +import '../exceptions.dart'; +import '../image_saver.dart'; + +class ImageSaverGalImpl extends ImageSaverInterface { + @override + Future saveImageFromNetwork(Uri imageUrl) async { + try { + final response = await http.get( + imageUrl, + ); + if (response.statusCode != 200) { + throw NetworkImageLoadException( + statusCode: response.statusCode, + uri: imageUrl, + ); + } + final imageBytes = response.bodyBytes; + await Gal.putImageBytes(imageBytes); + } on GalException catch (e) { + throw ImageSaverException( + message: e.toString(), + type: e.type.toImageSaverExceptionType(), + ); + } catch (e) { + throw ImageSaverException( + message: e.toString(), + type: ImageSaverExceptionType.unknown, + ); + } + } + + @override + Future saveLocalImage(String imageUrl) async { + try { + await Gal.putImage(imageUrl); + } on GalException catch (e) { + throw ImageSaverException( + message: e.toString(), + type: e.type.toImageSaverExceptionType(), + ); + } catch (e) { + throw ImageSaverException( + message: e.toString(), + type: ImageSaverExceptionType.unknown, + ); + } + } + + @override + Future hasAccess({required bool toAlbum}) { + return Gal.hasAccess(toAlbum: toAlbum); + } + + @override + Future requestAccess({required bool toAlbum}) { + return Gal.requestAccess(toAlbum: toAlbum); + } +} + +extension GalExceptionTypeExt on GalExceptionType { + ImageSaverExceptionType toImageSaverExceptionType() { + switch (this) { + case GalExceptionType.accessDenied: + return ImageSaverExceptionType.accessDenied; + case GalExceptionType.notEnoughSpace: + return ImageSaverExceptionType.notEnoughSpace; + case GalExceptionType.notSupportedFormat: + return ImageSaverExceptionType.notSupportedFormat; + case GalExceptionType.unexpected: + return ImageSaverExceptionType.unexpected; + } + } +} diff --git a/flutter_quill_extensions/lib/logic/services/s_image_saver.dart b/flutter_quill_extensions/lib/logic/services/s_image_saver.dart new file mode 100644 index 00000000..487e06ac --- /dev/null +++ b/flutter_quill_extensions/lib/logic/services/s_image_saver.dart @@ -0,0 +1,33 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +import 'image_saver.dart'; +import 'packages/gal.dart' show ImageSaverGalImpl; + +class ImageSaverService extends ImageSaverInterface { + final ImageSaverInterface _provider; + const ImageSaverService({ + required ImageSaverInterface impl, + }) : _provider = impl; + + factory ImageSaverService.gal() => ImageSaverService( + impl: ImageSaverGalImpl(), + ); + + static final _instance = ImageSaverService.gal(); + factory ImageSaverService.getInstance() => _instance; + + @override + Future hasAccess({bool toAlbum = false}) => + _provider.hasAccess(toAlbum: toAlbum); + + @override + Future requestAccess({bool toAlbum = false}) => + _provider.requestAccess(toAlbum: toAlbum); + + @override + Future saveImageFromNetwork(Uri imageUrl) => + _provider.saveImageFromNetwork(imageUrl); + + @override + Future saveLocalImage(String imageUrl) => + _provider.saveLocalImage(imageUrl); +} diff --git a/flutter_quill_extensions/lib/utils/quill_utils.dart b/flutter_quill_extensions/lib/logic/utils/quill_utils.dart similarity index 99% rename from flutter_quill_extensions/lib/utils/quill_utils.dart rename to flutter_quill_extensions/lib/logic/utils/quill_utils.dart index 1ee9caff..154be39a 100644 --- a/flutter_quill_extensions/lib/utils/quill_utils.dart +++ b/flutter_quill_extensions/lib/logic/utils/quill_utils.dart @@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter_quill/flutter_quill.dart' as quill; import 'package:path/path.dart' as path; -import '../flutter_quill_extensions.dart'; +import '../../presentation/embeds/utils.dart'; class QuillImageUtilities { const QuillImageUtilities._(); diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/formula.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/formula.dart new file mode 100644 index 00000000..3e6de8f2 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/formula.dart @@ -0,0 +1,41 @@ +import 'package:flutter/foundation.dart' show kIsWeb; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_quill/extensions.dart' as base; +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:math_keyboard/math_keyboard.dart'; + +class FormulaEmbedBuilder extends EmbedBuilder { + const FormulaEmbedBuilder(); + @override + String get key => BlockEmbed.formulaType; + + @override + Widget build( + BuildContext context, + QuillController controller, + base.Embed node, + bool readOnly, + bool inline, + TextStyle textStyle, + ) { + assert(!kIsWeb, 'Please provide formula EmbedBuilder for Web'); + + final mathController = MathFieldEditingController(); + return Focus( + onFocusChange: (hasFocus) { + if (hasFocus) { + // If the MathField is tapped, hides the built in keyboard + SystemChannels.textInput.invokeMethod('TextInput.hide'); + debugPrint(mathController.currentEditingValue()); + } + }, + child: MathField( + controller: mathController, + variables: const ['x', 'y', 'z'], + onChanged: (value) {}, + onSubmitted: (value) {}, + ), + ); + } +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart new file mode 100644 index 00000000..9fb3fbc2 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart @@ -0,0 +1,336 @@ +import 'dart:io' show File; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_quill/extensions.dart' as base; +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:flutter_quill/translations.dart'; + +import '../../../models/config/editor/image.dart'; +import '../../embed_types.dart'; +import '../../utils.dart'; +import '../../widgets/image.dart'; +import '../../widgets/image_resizer.dart'; +import '../../widgets/simple_dialog_item.dart'; + +class QuillEditorImageEmbedBuilder extends EmbedBuilder { + QuillEditorImageEmbedBuilder({ + required this.configurations, + }); + final QuillEditorImageEmbedConfigurations configurations; + + @override + String get key => BlockEmbed.imageType; + + @override + bool get expanded => false; + + @override + Widget build( + BuildContext context, + QuillController controller, + base.Embed node, + bool readOnly, + bool inline, + TextStyle textStyle, + ) { + assert(!kIsWeb, 'Please provide image EmbedBuilder for Web'); + + Widget image = const SizedBox.shrink(); + final imageUrl = standardizeImageUrl(node.value.data); + OptionalSize? imageSize; + final style = node.style.attributes['style']; + + if (style != null) { + final attrs = base.isMobile() + ? base.parseKeyValuePairs(style.value.toString(), { + Attribute.mobileWidth, + Attribute.mobileHeight, + Attribute.mobileMargin, + Attribute.mobileAlignment, + }) + : base.parseKeyValuePairs(style.value.toString(), { + Attribute.width.key, + Attribute.height.key, + Attribute.margin, + Attribute.alignment, + }); + if (attrs.isNotEmpty) { + final width = double.tryParse( + (base.isMobile() + ? attrs[Attribute.mobileWidth] + : attrs[Attribute.width.key]) ?? + '', + ); + final height = double.tryParse( + (base.isMobile() + ? attrs[Attribute.mobileHeight] + : attrs[Attribute.height.key]) ?? + '', + ); + final alignment = base.getAlignment(base.isMobile() + ? attrs[Attribute.mobileAlignment] + : attrs[Attribute.alignment]); + final margin = (base.isMobile() + ? double.tryParse(Attribute.mobileMargin) + : double.tryParse(Attribute.margin)) ?? + 0.0; + + assert( + width != null && height != null, + base.isMobile() + ? 'mobileWidth and mobileHeight must be specified' + : 'width and height must be specified', + ); + imageSize = OptionalSize(width, height); + image = Padding( + padding: EdgeInsets.all(margin), + child: getQuillImageByUrl( + imageUrl, + width: width, + height: height, + alignment: alignment, + imageProviderBuilder: configurations.imageProviderBuilder, + imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder, + ), + ); + } + } + + if (imageSize == null) { + image = getQuillImageByUrl( + imageUrl, + imageProviderBuilder: configurations.imageProviderBuilder, + imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder, + ); + imageSize = OptionalSize((image as Image).width, image.height); + } + + if (!readOnly && + (base.isMobile() || + configurations.forceUseMobileOptionMenuForImageClick)) { + return GestureDetector( + onTap: () { + showDialog( + context: context, + builder: (context) { + final copyOption = SimpleDialogItem( + icon: Icons.copy_all_outlined, + color: Colors.cyanAccent, + text: 'Copy'.i18n, + onPressed: () { + final imageNode = + getEmbedNode(controller, controller.selection.start) + .value; + final imageUrl = imageNode.value.data; + controller.copiedImageUrl = ImageUrl( + imageUrl, + getImageStyleString(controller), + ); + Navigator.pop(context); + }, + ); + final removeOption = SimpleDialogItem( + icon: Icons.delete_forever_outlined, + color: Colors.red.shade200, + text: 'Remove'.i18n, + onPressed: () async { + Navigator.of(context).pop(); + + final imageFile = File(imageUrl); + + // Call the remove check callback if set + if (await configurations.shouldRemoveImageCallback + ?.call(imageFile) == + false) { + return; + } + + final offset = getEmbedNode( + controller, + controller.selection.start, + ).offset; + controller.replaceText( + offset, + 1, + '', + TextSelection.collapsed(offset: offset), + ); + // Call the post remove callback if set + await configurations.onImageRemovedCallback + ?.call(imageFile); + }, + ); + return Padding( + padding: const EdgeInsets.fromLTRB(50, 0, 50, 0), + child: SimpleDialog( + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(10), + ), + ), + children: [ + SimpleDialogItem( + icon: Icons.settings_outlined, + color: Colors.lightBlueAccent, + text: 'Resize'.i18n, + onPressed: () { + Navigator.pop(context); + showCupertinoModalPopup( + context: context, + builder: (context) { + final screenSize = MediaQuery.sizeOf(context); + return ImageResizer( + onImageResize: (w, h) { + final res = getEmbedNode( + controller, + controller.selection.start, + ); + + final attr = + base.replaceStyleStringWithSize( + getImageStyleString(controller), + width: w, + height: h, + isMobile: base.isMobile(), + ); + controller + ..skipRequestKeyboard = true + ..formatText( + res.offset, + 1, + StyleAttribute(attr), + ); + }, + imageWidth: imageSize?.width, + imageHeight: imageSize?.height, + maxWidth: screenSize.width, + maxHeight: screenSize.height, + ); + }, + ); + }, + ), + copyOption, + removeOption, + ]), + ); + }); + }, + child: image, + ); + } + + if (!readOnly || isImageBase64(imageUrl)) { + // To enforce using it on the web, desktop and other platforms + // and that is up to the developer + if (!base.isMobile() && + configurations.forceUseMobileOptionMenuForImageClick) { + return _menuOptionsForReadonlyImage( + context: context, + imageUrl: imageUrl, + image: image, + imageProviderBuilder: configurations.imageProviderBuilder, + imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder, + ); + } + return image; + } + + // We provide option menu for mobile platform excluding base64 image + return _menuOptionsForReadonlyImage( + context: context, + imageUrl: imageUrl, + image: image, + imageProviderBuilder: configurations.imageProviderBuilder, + imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder, + ); + } +} + +Widget _menuOptionsForReadonlyImage({ + required BuildContext context, + required String imageUrl, + required Widget image, + required ImageEmbedBuilderProviderBuilder? imageProviderBuilder, + required ImageEmbedBuilderErrorWidgetBuilder? imageErrorWidgetBuilder, +}) { + return GestureDetector( + onTap: () { + showDialog( + context: context, + builder: (context) { + final saveOption = SimpleDialogItem( + icon: Icons.save, + color: Colors.greenAccent, + text: 'Save'.i18n, + onPressed: () async { + imageUrl = appendFileExtensionToImageUrl(imageUrl); + final messenger = ScaffoldMessenger.of(context); + Navigator.of(context).pop(); + + final saveImageResult = await saveImage(imageUrl); + final imageSavedSuccessfully = saveImageResult.isSuccess; + + messenger.clearSnackBars(); + + if (!imageSavedSuccessfully) { + messenger.showSnackBar(SnackBar( + content: Text( + 'Error while saving image'.i18n, + ))); + return; + } + + String message; + switch (saveImageResult.method) { + case SaveImageResultMethod.network: + message = 'Saved using the network'.i18n; + break; + case SaveImageResultMethod.localStorage: + message = 'Saved using the local storage'.i18n; + break; + } + + messenger.showSnackBar( + SnackBar( + content: Text(message), + ), + ); + }, + ); + final zoomOption = SimpleDialogItem( + icon: Icons.zoom_in, + color: Colors.cyanAccent, + text: 'Zoom'.i18n, + onPressed: () { + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => ImageTapWrapper( + imageUrl: imageUrl, + imageProviderBuilder: imageProviderBuilder, + imageErrorWidgetBuilder: imageErrorWidgetBuilder, + ), + ), + ); + }, + ); + return Padding( + padding: const EdgeInsets.fromLTRB(50, 0, 50, 0), + child: SimpleDialog( + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(10), + ), + ), + children: [saveOption, zoomOption], + ), + ); + }, + ); + }, + child: image, + ); +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart new file mode 100644 index 00000000..970bf762 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart @@ -0,0 +1,45 @@ +import 'package:flutter/foundation.dart' show kIsWeb; +import 'package:flutter/widgets.dart'; +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:universal_html/html.dart' as html; + +import 'shims/dart_ui_fake.dart' + if (dart.library.html) 'shims/dart_ui_real.dart' as ui; + +class ImageEmbedBuilderWeb extends EmbedBuilder { + const ImageEmbedBuilderWeb({ + this.constraints, + }); + + final BoxConstraints? constraints; + + @override + String get key => BlockEmbed.imageType; + + @override + Widget build( + BuildContext context, + QuillController controller, + Embed node, + bool readOnly, + bool inline, + TextStyle textStyle, + ) { + assert(kIsWeb, 'ImageEmbedBuilderWeb is only for web platform'); + final imageUrl = node.value.data; + + ui.PlatformViewRegistry().registerViewFactory(imageUrl, (viewId) { + return html.ImageElement() + ..src = imageUrl + ..style.height = 'auto' + ..style.width = 'auto'; + }); + + return ConstrainedBox( + constraints: constraints ?? BoxConstraints.loose(const Size(200, 200)), + child: HtmlElementView( + viewType: imageUrl, + ), + ); + } +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/shims/dart_ui_fake.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/shims/dart_ui_fake.dart new file mode 100644 index 00000000..c42e2eb5 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/shims/dart_ui_fake.dart @@ -0,0 +1,43 @@ +// import 'package:universal_html/html.dart' as html; + +// Fake interface for the logic that this package needs from (web-only) dart:ui. +// This is conditionally exported so the analyzer sees these methods as +// available. + +// typedef PlatroformViewFactory = html.Element Function(int viewId); + +// /// Shim for web_ui engine.PlatformViewRegistry +// /// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/ui.dart#L62 +// class PlatformViewRegistry { +// /// Shim for registerViewFactory +// /// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/ui.dart#L72 +// static dynamic registerViewFactory( +// String viewTypeId, PlatroformViewFactory viewFactory) {} +// } + +// /// Shim for web_ui engine.AssetManager +// /// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/src/engine/assets.dart#L12 +// class WebOnlyAssetManager { +// static dynamic getAssetUrl(String asset) {} +// } + +class PlatformViewRegistry { + /// Register [viewType] as being created by the given [viewFactory]. + /// + /// [viewFactory] can be any function that takes an integer and optional + /// `params` and returns an `HTMLElement` DOM object. + bool registerViewFactory( + String viewType, + Function viewFactory, { + bool isVisible = true, + }) { + return false; + } + + /// Returns the view previously created for [viewId]. + /// + /// Throws if no view has been created for [viewId]. + Object getViewById(int viewId) { + return ''; + } +} diff --git a/flutter_quill_extensions/lib/shims/dart_ui_real.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/shims/dart_ui_real.dart similarity index 100% rename from flutter_quill_extensions/lib/shims/dart_ui_real.dart rename to flutter_quill_extensions/lib/presentation/embeds/editor/image/shims/dart_ui_real.dart diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/unknown.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/unknown.dart new file mode 100644 index 00000000..bac7a6f5 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/unknown.dart @@ -0,0 +1,19 @@ +import 'package:flutter/widgets.dart'; +import 'package:flutter_quill/flutter_quill.dart'; + +class QuillEditorUnknownEmbedBuilder extends EmbedBuilder { + @override + Widget build( + BuildContext context, + QuillController controller, + Embed node, + bool readOnly, + bool inline, + TextStyle textStyle, + ) { + return const Text('Unknown embed builder'); + } + + @override + String get key => 'unknown'; +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/video.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/video.dart new file mode 100644 index 00000000..35e927e8 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/video.dart @@ -0,0 +1,81 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_quill/extensions.dart' as base; +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:math_keyboard/math_keyboard.dart'; + +import '../../models/config/editor/video.dart'; +import '../utils.dart'; +import '../widgets/video_app.dart'; +import '../widgets/youtube_video_app.dart'; + +class QuillEditorVideoEmbedBuilder extends EmbedBuilder { + const QuillEditorVideoEmbedBuilder({ + required this.configurations, + }); + + final QuillEditorVideoEmbedConfigurations configurations; + + @override + String get key => BlockEmbed.videoType; + + @override + Widget build( + BuildContext context, + QuillController controller, + base.Embed node, + bool readOnly, + bool inline, + TextStyle textStyle, + ) { + assert(!kIsWeb, 'Please provide video EmbedBuilder for Web'); + + final videoUrl = node.value.data; + if (isYouTubeUrl(videoUrl)) { + return YoutubeVideoApp( + videoUrl: videoUrl, context: context, readOnly: readOnly); + } + return VideoApp( + videoUrl: videoUrl, + context: context, + readOnly: readOnly, + onVideoInit: configurations.onVideoInit, + ); + } +} + +class QuillEditorFormulaEmbedBuilder extends EmbedBuilder { + const QuillEditorFormulaEmbedBuilder(); + @override + String get key => BlockEmbed.formulaType; + + @override + Widget build( + BuildContext context, + QuillController controller, + base.Embed node, + bool readOnly, + bool inline, + TextStyle textStyle, + ) { + assert(!kIsWeb, 'Please provide formula EmbedBuilder for Web'); + + final mathController = MathFieldEditingController(); + return Focus( + onFocusChange: (hasFocus) { + if (hasFocus) { + // If the MathField is tapped, hides the built in keyboard + SystemChannels.textInput.invokeMethod('TextInput.hide'); + debugPrint(mathController.currentEditingValue()); + } + }, + child: MathField( + controller: mathController, + variables: const ['x', 'y', 'z'], + onChanged: (value) {}, + onSubmitted: (value) {}, + ), + ); + } +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/webview.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/webview.dart new file mode 100644 index 00000000..4df6cc55 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/webview.dart @@ -0,0 +1,58 @@ +import 'dart:convert' show jsonDecode, jsonEncode; + +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:meta/meta.dart' show experimental; + +import '../../models/config/editor/webview.dart'; + +@experimental +class QuillEditorWebViewBlockEmbed extends CustomBlockEmbed { + const QuillEditorWebViewBlockEmbed( + String value, + ) : super(webViewType, value); + + factory QuillEditorWebViewBlockEmbed.fromDocument(Document document) => + QuillEditorWebViewBlockEmbed(jsonEncode(document.toDelta().toJson())); + + static const String webViewType = 'webview'; + + Document get document => Document.fromJson(jsonDecode(data)); +} + +@experimental +class QuillEditorWebViewEmbedBuilder extends EmbedBuilder { + const QuillEditorWebViewEmbedBuilder({ + required this.configurations, + }); + + @override + bool get expanded => false; + + final QuillEditorWebViewEmbedConfigurations configurations; + @override + Widget build( + BuildContext context, + QuillController controller, + Embed node, + bool readOnly, + bool inline, + TextStyle textStyle, + ) { + final url = node.value.data as String; + + return SizedBox( + width: double.infinity, + height: 200, + child: InAppWebView( + initialUrlRequest: URLRequest( + url: Uri.parse(url), + ), + ), + ); + } + + @override + String get key => 'webview'; +} diff --git a/flutter_quill_extensions/lib/embeds/embed_types.dart b/flutter_quill_extensions/lib/presentation/embeds/embed_types.dart similarity index 86% rename from flutter_quill_extensions/lib/embeds/embed_types.dart rename to flutter_quill_extensions/lib/presentation/embeds/embed_types.dart index 9fa4184a..16774b00 100644 --- a/flutter_quill_extensions/lib/embeds/embed_types.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/embed_types.dart @@ -6,19 +6,25 @@ import 'package:flutter/material.dart' typedef OnImagePickCallback = Future Function(File file); typedef OnVideoPickCallback = Future Function(File file); + +/// [FilePickImpl] is an implementation for picking files. typedef FilePickImpl = Future Function(BuildContext context); + +/// [WebImagePickImpl] is an implementation for picking web images. typedef WebImagePickImpl = Future Function( - OnImagePickCallback onImagePickCallback); + OnImagePickCallback onImagePickCallback, +); typedef WebVideoPickImpl = Future Function( - OnVideoPickCallback onImagePickCallback); + OnVideoPickCallback onImagePickCallback, +); typedef MediaPickSettingSelector = Future Function( BuildContext context); enum MediaPickSetting { - Gallery, - Link, - Camera, - Video, + gallery, + link, + camera, + video, } typedef MediaFileUrl = String; diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button.dart new file mode 100644 index 00000000..690f0f66 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button.dart @@ -0,0 +1,202 @@ +// ignore_for_file: use_build_context_synchronously + +import 'package:flutter/material.dart'; +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:flutter_quill/translations.dart'; +import 'package:image_picker/image_picker.dart'; + +import '../../models/config/toolbar/buttons/camera.dart'; +import '../embed_types.dart'; +import 'utils/image_video_utils.dart'; + +class QuillToolbarCameraButton extends StatelessWidget { + const QuillToolbarCameraButton({ + required this.controller, + required this.options, + super.key, + }); + + final QuillController controller; + final QuillToolbarCameraButtonOptions options; + + double _iconSize(BuildContext context) { + final baseFontSize = baseButtonExtraOptions(context).globalIconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize; + } + + VoidCallback? _afterButtonPressed(BuildContext context) { + return options.afterButtonPressed ?? + baseButtonExtraOptions(context).afterButtonPressed; + } + + QuillIconTheme? _iconTheme(BuildContext context) { + return options.iconTheme ?? baseButtonExtraOptions(context).iconTheme; + } + + QuillToolbarBaseButtonOptions baseButtonExtraOptions(BuildContext context) { + return context.requireQuillToolbarBaseButtonOptions; + } + + IconData _iconData(BuildContext context) { + return options.iconData ?? + baseButtonExtraOptions(context).iconData ?? + Icons.photo_camera; + } + + String _tooltip(BuildContext context) { + return options.tooltip ?? + baseButtonExtraOptions(context).tooltip ?? + 'Camera'.i18n; + // ('Camera'.i18n); + } + + void _sharedOnPressed(BuildContext context) { + _onPressedHandler( + context, + controller, + onImagePickCallback: options.onImagePickCallback, + onVideoPickCallback: options.onVideoPickCallback, + filePickImpl: options.filePickImpl, + webImagePickImpl: options.webImagePickImpl, + ); + _afterButtonPressed(context); + } + + @override + Widget build(BuildContext context) { + final iconTheme = _iconTheme(context); + final tooltip = _tooltip(context); + final iconSize = _iconSize(context); + final iconData = _iconData(context); + + final childBuilder = + options.childBuilder ?? baseButtonExtraOptions(context).childBuilder; + + if (childBuilder != null) { + childBuilder( + QuillToolbarCameraButtonOptions( + onImagePickCallback: options.onImagePickCallback, + onVideoPickCallback: options.onVideoPickCallback, + afterButtonPressed: _afterButtonPressed(context), + cameraPickSettingSelector: options.cameraPickSettingSelector, + filePickImpl: options.filePickImpl, + iconData: options.iconData, + fillColor: options.fillColor, + iconSize: options.iconSize, + iconTheme: options.iconTheme, + tooltip: options.tooltip, + webImagePickImpl: options.webImagePickImpl, + webVideoPickImpl: options.webVideoPickImpl, + ), + QuillToolbarCameraButtonExtraOptions( + controller: controller, + context: context, + onPressed: () => _sharedOnPressed(context), + ), + ); + } + + final theme = Theme.of(context); + + final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; + final iconFillColor = iconTheme?.iconUnselectedFillColor ?? + (options.fillColor ?? theme.canvasColor); + + return QuillToolbarIconButton( + icon: Icon(iconData, size: iconSize, color: iconColor), + tooltip: tooltip, + highlightElevation: 0, + hoverElevation: 0, + size: iconSize * 1.77, + fillColor: iconFillColor, + borderRadius: iconTheme?.borderRadius ?? 2, + onPressed: () => _sharedOnPressed(context), + ); + } + + Future _onPressedHandler( + BuildContext context, + QuillController controller, { + OnImagePickCallback? onImagePickCallback, + OnVideoPickCallback? onVideoPickCallback, + FilePickImpl? filePickImpl, + WebImagePickImpl? webImagePickImpl, + }) async { + if (onVideoPickCallback == null && onImagePickCallback == null) { + throw ArgumentError( + 'onImagePickCallback and onVideoPickCallback are both null', + ); + } + final selector = options.cameraPickSettingSelector ?? + (context) => showDialog( + context: context, + builder: (ctx) => AlertDialog( + contentPadding: EdgeInsets.zero, + backgroundColor: Colors.transparent, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (onImagePickCallback != null) + TextButton.icon( + icon: const Icon( + Icons.camera, + color: Colors.orangeAccent, + ), + label: Text('Camera'.i18n), + onPressed: () => + Navigator.pop(ctx, MediaPickSetting.camera), + ), + if (onVideoPickCallback != null) + TextButton.icon( + icon: const Icon( + Icons.video_call, + color: Colors.cyanAccent, + ), + label: Text('Video'.i18n), + onPressed: () => + Navigator.pop(ctx, MediaPickSetting.video), + ) + ], + ), + ), + ); + + final source = await selector(context); + if (source == null) { + return; + } + switch (source) { + case MediaPickSetting.camera: + await ImageVideoUtils.handleImageButtonTap( + context, + controller, + ImageSource.camera, + onImagePickCallback!, + filePickImpl: filePickImpl, + webImagePickImpl: webImagePickImpl, + ); + break; + case MediaPickSetting.video: + await ImageVideoUtils.handleVideoButtonTap( + context, + controller, + ImageSource.camera, + onVideoPickCallback!, + filePickImpl: filePickImpl, + webVideoPickImpl: options.webVideoPickImpl, + ); + break; + case MediaPickSetting.gallery: + throw ArgumentError( + 'Invalid MediaSetting for the camera button.\n' + 'gallery is not related to camera button', + ); + case MediaPickSetting.link: + throw ArgumentError( + 'Invalid MediaSetting for the camera button.\n' + 'link is not related to camera button', + ); + } + } +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/formula_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/formula_button.dart new file mode 100644 index 00000000..4a0341d4 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/formula_button.dart @@ -0,0 +1,105 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_quill/flutter_quill.dart'; + +import '../../models/config/toolbar/buttons/formula.dart'; + +class QuillToolbarFormulaButton extends StatelessWidget { + const QuillToolbarFormulaButton({ + required this.controller, + required this.options, + super.key, + }); + + final QuillController controller; + final QuillToolbarFormulaButtonOptions options; + + double _iconSize(BuildContext context) { + final baseFontSize = baseButtonExtraOptions(context).globalIconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize; + } + + VoidCallback? _afterButtonPressed(BuildContext context) { + return options.afterButtonPressed ?? + baseButtonExtraOptions(context).afterButtonPressed; + } + + QuillIconTheme? _iconTheme(BuildContext context) { + return options.iconTheme ?? baseButtonExtraOptions(context).iconTheme; + } + + QuillToolbarBaseButtonOptions baseButtonExtraOptions(BuildContext context) { + return context.requireQuillToolbarBaseButtonOptions; + } + + IconData _iconData(BuildContext context) { + return options.iconData ?? + baseButtonExtraOptions(context).iconData ?? + Icons.functions; + } + + String _tooltip(BuildContext context) { + return options.tooltip ?? + baseButtonExtraOptions(context).tooltip ?? + 'Insert formula'; + // ('Insert formula'.i18n); + } + + void _sharedOnPressed(BuildContext context) { + _onPressedHandler(context); + _afterButtonPressed(context); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + + final iconTheme = _iconTheme(context); + + final tooltip = _tooltip(context); + final iconSize = _iconSize(context); + final iconData = _iconData(context); + final childBuilder = + options.childBuilder ?? baseButtonExtraOptions(context).childBuilder; + + final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; + final iconFillColor = iconTheme?.iconUnselectedFillColor ?? + (options.fillColor ?? theme.canvasColor); + + if (childBuilder != null) { + return childBuilder( + QuillToolbarFormulaButtonOptions( + afterButtonPressed: _afterButtonPressed(context), + fillColor: iconFillColor, + iconData: iconData, + iconSize: iconSize, + iconTheme: iconTheme, + tooltip: tooltip, + ), + QuillToolbarFormulaButtonExtraOptions( + context: context, + controller: controller, + onPressed: () => _sharedOnPressed(context), + ), + ); + } + + return QuillToolbarIconButton( + icon: Icon(iconData, size: iconSize, color: iconColor), + tooltip: tooltip, + highlightElevation: 0, + hoverElevation: 0, + size: iconSize * 1.77, + fillColor: iconFillColor, + borderRadius: iconTheme?.borderRadius ?? 2, + onPressed: () => _sharedOnPressed(context), + ); + } + + Future _onPressedHandler(BuildContext context) async { + final index = controller.selection.baseOffset; + final length = controller.selection.extentOffset - index; + + controller.replaceText(index, length, BlockEmbed.formula(''), null); + } +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button.dart new file mode 100644 index 00000000..88b54ee2 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button.dart @@ -0,0 +1,182 @@ +// ignore_for_file: use_build_context_synchronously + +import 'package:flutter/material.dart'; +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:image_picker/image_picker.dart'; + +import '../../models/config/toolbar/buttons/image.dart'; +import '../embed_types.dart'; +import 'utils/image_video_utils.dart'; + +class QuillToolbarImageButton extends StatelessWidget { + const QuillToolbarImageButton({ + required this.controller, + required this.options, + super.key, + }); + + final QuillController controller; + + final QuillToolbarImageButtonOptions options; + + double _iconSize(BuildContext context) { + final baseFontSize = baseButtonExtraOptions(context).globalIconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize; + } + + VoidCallback? _afterButtonPressed(BuildContext context) { + return options.afterButtonPressed ?? + baseButtonExtraOptions(context).afterButtonPressed; + } + + QuillIconTheme? _iconTheme(BuildContext context) { + return options.iconTheme ?? baseButtonExtraOptions(context).iconTheme; + } + + QuillToolbarBaseButtonOptions baseButtonExtraOptions(BuildContext context) { + return context.requireQuillToolbarBaseButtonOptions; + } + + IconData _iconData(BuildContext context) { + return options.iconData ?? + baseButtonExtraOptions(context).iconData ?? + Icons.image; + } + + String _tooltip(BuildContext context) { + return options.tooltip ?? + baseButtonExtraOptions(context).tooltip ?? + 'Insert image'; + // ('Insert Image'.i18n); + } + + void _sharedOnPressed(BuildContext context) { + _onPressedHandler(context); + _afterButtonPressed(context); + } + + @override + Widget build(BuildContext context) { + final tooltip = _tooltip(context); + final iconSize = _iconSize(context); + final iconData = _iconData(context); + final childBuilder = + options.childBuilder ?? baseButtonExtraOptions(context).childBuilder; + + if (childBuilder != null) { + return childBuilder( + QuillToolbarImageButtonOptions( + afterButtonPressed: _afterButtonPressed(context), + iconData: iconData, + iconSize: iconSize, + dialogTheme: options.dialogTheme, + filePickImpl: options.filePickImpl, + webImagePickImpl: options.webImagePickImpl, + fillColor: options.fillColor, + iconTheme: options.iconTheme, + linkRegExp: options.linkRegExp, + mediaPickSettingSelector: options.mediaPickSettingSelector, + onImagePickCallback: options.onImagePickCallback, + tooltip: options.tooltip, + ), + QuillToolbarImageButtonExtraOptions( + context: context, + controller: controller, + onPressed: () => _sharedOnPressed(context), + ), + ); + } + + final theme = Theme.of(context); + + final iconTheme = _iconTheme(context); + + final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; + final iconFillColor = iconTheme?.iconUnselectedFillColor ?? + (options.fillColor ?? theme.canvasColor); + + return QuillToolbarIconButton( + icon: Icon( + iconData, + size: iconSize, + color: iconColor, + ), + tooltip: tooltip, + highlightElevation: 0, + hoverElevation: 0, + size: iconSize * 1.77, + fillColor: iconFillColor, + borderRadius: iconTheme?.borderRadius ?? 2, + onPressed: () => _sharedOnPressed(context), + ); + } + + Future _onPressedHandler(BuildContext context) async { + final onImagePickCallbackRef = options.onImagePickCallback; + if (onImagePickCallbackRef == null) { + await _typeLink(context); + return; + } + final selector = options.mediaPickSettingSelector ?? + ImageVideoUtils.selectMediaPickSetting; + final source = await selector(context); + if (source == null) { + return; + } + switch (source) { + case MediaPickSetting.gallery: + _pickImage(context); + break; + case MediaPickSetting.link: + await _typeLink(context); + break; + case MediaPickSetting.camera: + await ImageVideoUtils.handleImageButtonTap( + context, + controller, + ImageSource.camera, + onImagePickCallbackRef, + filePickImpl: options.filePickImpl, + webImagePickImpl: options.webImagePickImpl, + ); + break; + case MediaPickSetting.video: + throw ArgumentError( + 'Sorry but this is the Image button and not the video one', + ); + } + } + + void _pickImage(BuildContext context) => ImageVideoUtils.handleImageButtonTap( + context, + controller, + ImageSource.gallery, + options.onImagePickCallback ?? + (throw ArgumentError( + 'onImagePickCallback should not be null', + )), + filePickImpl: options.filePickImpl, + webImagePickImpl: options.webImagePickImpl, + ); + + Future _typeLink(BuildContext context) async { + final value = await showDialog( + context: context, + builder: (_) => LinkDialog( + dialogTheme: options.dialogTheme, + linkRegExp: options.linkRegExp, + ), + ); + _linkSubmitted(value); + } + + void _linkSubmitted(String? value) { + if (value != null && value.isNotEmpty) { + final index = controller.selection.baseOffset; + final length = controller.selection.extentOffset - index; + + controller.replaceText(index, length, BlockEmbed.image(value), null); + } + } +} diff --git a/flutter_quill_extensions/lib/embeds/toolbar/media_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button.dart similarity index 63% rename from flutter_quill_extensions/lib/embeds/toolbar/media_button.dart rename to flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button.dart index a5eae3dd..212bd39e 100644 --- a/flutter_quill_extensions/lib/embeds/toolbar/media_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_build_context_synchronously + import 'dart:math' as math; import 'dart:ui'; @@ -8,145 +10,177 @@ import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill/translations.dart'; import 'package:image_picker/image_picker.dart'; +import '../../models/config/toolbar/buttons/media_button.dart'; import '../embed_types.dart'; -import 'image_video_utils.dart'; +import 'utils/image_video_utils.dart'; /// Widget which combines [ImageButton] and [VideButton] widgets. This widget /// has more customization and uses dialog similar to one which is used /// on [http://quilljs.com]. -class MediaButton extends StatelessWidget { - const MediaButton({ +class QuillToolbarMediaButton extends StatelessWidget { + QuillToolbarMediaButton({ required this.controller, - required this.onImagePickCallback, - required this.onVideoPickCallback, - required this.filePickImpl, - required this.webImagePickImpl, - required this.webVideoPickImpl, - required this.icon, - this.type = QuillMediaType.image, - this.iconSize = kDefaultIconSize, - this.fillColor, - this.mediaFilePicker = _defaultMediaPicker, - this.onMediaPickedCallback, - this.iconTheme, - this.dialogTheme, - this.tooltip, - this.childrenSpacing = 16.0, - this.labelText, - this.hintText, - this.submitButtonText, - this.submitButtonSize, - this.galleryButtonText, - this.linkButtonText, - this.autovalidateMode = AutovalidateMode.disabled, - this.dialogBarrierColor = Colors.black54, - Key? key, - this.validationMessage, - }) : assert(type == QuillMediaType.image, - 'Video selection is not supported yet'), - super(key: key); + required this.options, + super.key, + }) : assert(options.type == QuillMediaType.image, + 'Video selection is not supported yet'); final QuillController controller; - final IconData icon; - final double iconSize; - final Color? fillColor; - final QuillMediaType type; - final QuillIconTheme? iconTheme; - final QuillDialogTheme? dialogTheme; - final String? tooltip; - final MediaFilePicker mediaFilePicker; - final MediaPickedCallback? onMediaPickedCallback; - final Color dialogBarrierColor; + final QuillToolbarMediaButtonOptions options; - /// The margin between child widgets in the dialog. - final double childrenSpacing; + double _iconSize(BuildContext context) { + final baseFontSize = baseButtonExtraOptions(context).globalIconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize; + } - /// The text of label in link add mode. - final String? labelText; + VoidCallback? _afterButtonPressed(BuildContext context) { + return options.afterButtonPressed ?? + baseButtonExtraOptions(context).afterButtonPressed; + } - /// The hint text for link [TextField]. - final String? hintText; + QuillIconTheme? _iconTheme(BuildContext context) { + return options.iconTheme ?? baseButtonExtraOptions(context).iconTheme; + } - /// The text of the submit button. - final String? submitButtonText; + QuillToolbarBaseButtonOptions baseButtonExtraOptions(BuildContext context) { + return context.requireQuillToolbarBaseButtonOptions; + } - /// The size of dialog buttons. - final Size? submitButtonSize; + (IconData, String) get _defaultData { + switch (options.type) { + case QuillMediaType.image: + return (Icons.perm_media, 'Photo media button'); + case QuillMediaType.video: + throw UnsupportedError('The video is not supported yet.'); + } + } - /// The text of the gallery button [MediaSourceSelectorDialog]. - final String? galleryButtonText; + IconData _iconData(BuildContext context) { + return options.iconData ?? + baseButtonExtraOptions(context).iconData ?? + _defaultData.$1; + } - /// The text of the link button [MediaSourceSelectorDialog]. - final String? linkButtonText; + String _tooltip(BuildContext context) { + return options.tooltip ?? + baseButtonExtraOptions(context).tooltip ?? + _defaultData.$2; + // ('Camera'.i18n); + } - final AutovalidateMode autovalidateMode; - final String? validationMessage; - final OnImagePickCallback onImagePickCallback; - final FilePickImpl? filePickImpl; - final WebImagePickImpl? webImagePickImpl; - final OnVideoPickCallback onVideoPickCallback; - final WebVideoPickImpl? webVideoPickImpl; + void _sharedOnPressed(BuildContext context) { + _onPressedHandler(context); + _afterButtonPressed(context); + } @override Widget build(BuildContext context) { + final tooltip = _tooltip(context); + final iconSize = _iconSize(context); + final iconData = _iconData(context); + final childBuilder = + options.childBuilder ?? baseButtonExtraOptions(context).childBuilder; + final iconTheme = _iconTheme(context); + + if (childBuilder != null) { + return childBuilder( + QuillToolbarMediaButtonOptions( + type: options.type, + onMediaPickedCallback: options.onMediaPickedCallback, + onImagePickCallback: options.onImagePickCallback, + onVideoPickCallback: options.onVideoPickCallback, + iconData: iconData, + afterButtonPressed: _afterButtonPressed(context), + autovalidateMode: options.autovalidateMode, + childrenSpacing: options.childrenSpacing, + dialogBarrierColor: options.dialogBarrierColor, + dialogTheme: options.dialogTheme, + filePickImpl: options.filePickImpl, + fillColor: options.fillColor, + galleryButtonText: options.galleryButtonText, + iconTheme: iconTheme, + iconSize: iconSize, + hintText: options.hintText, + labelText: options.labelText, + submitButtonSize: options.submitButtonSize, + linkButtonText: options.linkButtonText, + mediaFilePicker: options.mediaFilePicker, + submitButtonText: options.submitButtonText, + validationMessage: options.validationMessage, + webImagePickImpl: options.webImagePickImpl, + webVideoPickImpl: options.webVideoPickImpl, + tooltip: options.tooltip, + ), + QuillToolbarMediaButtonExtraOptions( + context: context, + controller: controller, + onPressed: () => _sharedOnPressed(context), + ), + ); + } + final theme = Theme.of(context); - final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; - final iconFillColor = - iconTheme?.iconUnselectedFillColor ?? fillColor ?? theme.canvasColor; + + final iconColor = + options.iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; + final iconFillColor = options.iconTheme?.iconUnselectedFillColor ?? + options.fillColor ?? + theme.canvasColor; return QuillToolbarIconButton( - icon: Icon(icon, size: iconSize, color: iconColor), + icon: Icon(iconData, size: iconSize, color: iconColor), tooltip: tooltip, highlightElevation: 0, hoverElevation: 0, size: iconSize * 1.77, fillColor: iconFillColor, borderRadius: iconTheme?.borderRadius ?? 2, - onPressed: () => _onPressedHandler(context), + onPressed: () => _sharedOnPressed(context), ); } Future _onPressedHandler(BuildContext context) async { - if (onMediaPickedCallback == null) { + if (options.onMediaPickedCallback == null) { _inputLink(context); return; } final mediaSource = await showDialog( context: context, builder: (_) => MediaSourceSelectorDialog( - dialogTheme: dialogTheme, - galleryButtonText: galleryButtonText, - linkButtonText: linkButtonText, + dialogTheme: options.dialogTheme, + galleryButtonText: options.galleryButtonText, + linkButtonText: options.linkButtonText, ), ); if (mediaSource == null) { return; } switch (mediaSource) { - case MediaPickSetting.Gallery: + case MediaPickSetting.gallery: await _pickImage(); break; - case MediaPickSetting.Link: + case MediaPickSetting.link: _inputLink(context); break; - case MediaPickSetting.Camera: + case MediaPickSetting.camera: await ImageVideoUtils.handleImageButtonTap( context, controller, ImageSource.camera, - onImagePickCallback, - filePickImpl: filePickImpl, - webImagePickImpl: webImagePickImpl, + options.onImagePickCallback, + filePickImpl: options.filePickImpl, + webImagePickImpl: options.webImagePickImpl, ); break; - case MediaPickSetting.Video: + case MediaPickSetting.video: await ImageVideoUtils.handleVideoButtonTap( context, controller, ImageSource.camera, - onVideoPickCallback, - filePickImpl: filePickImpl, - webVideoPickImpl: webVideoPickImpl, + options.onVideoPickCallback, + filePickImpl: options.filePickImpl, + webVideoPickImpl: options.webVideoPickImpl, ); break; } @@ -174,22 +208,24 @@ class MediaButton extends StatelessWidget { } Future _pickMediaFileUrl() async { - final mediaFile = await mediaFilePicker(type); - return mediaFile != null ? onMediaPickedCallback?.call(mediaFile) : null; + final mediaFile = await options.mediaFilePicker?.call(options.type); + return mediaFile != null + ? options.onMediaPickedCallback?.call(mediaFile) + : null; } void _inputLink(BuildContext context) { showDialog( context: context, builder: (_) => MediaLinkDialog( - dialogTheme: dialogTheme, - labelText: labelText, - hintText: hintText, - buttonText: submitButtonText, - buttonSize: submitButtonSize, - childrenSpacing: childrenSpacing, - autovalidateMode: autovalidateMode, - validationMessage: validationMessage, + dialogTheme: options.dialogTheme, + labelText: options.labelText, + hintText: options.hintText, + buttonText: options.submitButtonText, + buttonSize: options.submitButtonSize, + childrenSpacing: options.childrenSpacing, + autovalidateMode: options.autovalidateMode, + validationMessage: options.validationMessage, ), ).then(_linkSubmitted); } @@ -198,8 +234,9 @@ class MediaButton extends StatelessWidget { if (value != null && value.isNotEmpty) { final index = controller.selection.baseOffset; final length = controller.selection.extentOffset - index; - final data = - type.isImage ? BlockEmbed.image(value) : BlockEmbed.video(value); + final data = options.type.isImage + ? BlockEmbed.image(value) + : BlockEmbed.video(value); controller.replaceText(index, length, data, null); } } @@ -208,7 +245,7 @@ class MediaButton extends StatelessWidget { /// Provides a dialog for input link to media resource. class MediaLinkDialog extends StatefulWidget { const MediaLinkDialog({ - Key? key, + super.key, this.link, this.dialogTheme, this.childrenSpacing = 16.0, @@ -218,8 +255,7 @@ class MediaLinkDialog extends StatefulWidget { this.buttonSize, this.autovalidateMode = AutovalidateMode.disabled, this.validationMessage, - }) : assert(childrenSpacing > 0), - super(key: key); + }) : assert(childrenSpacing > 0); final String? link; final QuillDialogTheme? dialogTheme; @@ -347,7 +383,7 @@ class _MediaLinkDialogState extends State { String? _validateLink(String? value) { if ((value?.isEmpty ?? false) || - !AutoFormatMultipleLinksRule.oneLineRegExp.hasMatch(value!)) { + !AutoFormatMultipleLinksRule.oneLineLinkRegExp.hasMatch(value!)) { return widget.validationMessage ?? 'That is not a valid URL'; } @@ -358,11 +394,11 @@ class _MediaLinkDialogState extends State { /// Media souce selector. class MediaSourceSelectorDialog extends StatelessWidget { const MediaSourceSelectorDialog({ - Key? key, + super.key, this.dialogTheme, this.galleryButtonText, this.linkButtonText, - }) : super(key: key); + }); final QuillDialogTheme? dialogTheme; @@ -408,7 +444,7 @@ class MediaSourceSelectorDialog extends StatelessWidget { icon: Icons.collections, label: galleryButtonText ?? 'Gallery'.i18n, onPressed: () => - Navigator.pop(context, MediaPickSetting.Gallery), + Navigator.pop(context, MediaPickSetting.gallery), ), ), const SizedBox(width: 10), @@ -417,7 +453,7 @@ class MediaSourceSelectorDialog extends StatelessWidget { icon: Icons.link, label: linkButtonText ?? 'Link'.i18n, onPressed: () => - Navigator.pop(context, MediaPickSetting.Link), + Navigator.pop(context, MediaPickSetting.link), ), ) ], @@ -434,8 +470,8 @@ class TextButtonWithIcon extends StatelessWidget { required this.icon, required this.onPressed, this.textStyle, - Key? key, - }) : super(key: key); + super.key, + }); final String label; final IconData icon; @@ -450,7 +486,10 @@ class TextButtonWithIcon extends StatelessWidget { final buttonStyle = TextButtonTheme.of(context).style; final shape = buttonStyle?.shape?.resolve({}) ?? const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(4))); + borderRadius: BorderRadius.all( + Radius.circular(4), + ), + ); return Material( shape: shape, textStyle: textStyle ?? @@ -477,18 +516,18 @@ class TextButtonWithIcon extends StatelessWidget { } /// Default file picker. -Future _defaultMediaPicker(QuillMediaType mediaType) async { - final pickedFile = mediaType.isImage - ? await ImagePicker().pickImage(source: ImageSource.gallery) - : await ImagePicker().pickVideo(source: ImageSource.gallery); - - if (pickedFile != null) { - return QuillFile( - name: pickedFile.name, - path: pickedFile.path, - bytes: await pickedFile.readAsBytes(), - ); - } - - return null; -} +// Future _defaultMediaPicker(QuillMediaType mediaType) async { +// final pickedFile = mediaType.isImage +// ? await ImagePicker().pickImage(source: ImageSource.gallery) +// : await ImagePicker().pickVideo(source: ImageSource.gallery); + +// if (pickedFile != null) { +// return QuillFile( +// name: pickedFile.name, +// path: pickedFile.path, +// bytes: await pickedFile.readAsBytes(), +// ); +// } + +// return null; +// } diff --git a/flutter_quill_extensions/lib/embeds/toolbar/image_video_utils.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/utils/image_video_utils.dart similarity index 88% rename from flutter_quill_extensions/lib/embeds/toolbar/image_video_utils.dart rename to flutter_quill_extensions/lib/presentation/embeds/toolbar/utils/image_video_utils.dart index 5da99c6d..4b03d7d7 100644 --- a/flutter_quill_extensions/lib/embeds/toolbar/image_video_utils.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/utils/image_video_utils.dart @@ -7,15 +7,16 @@ import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill/translations.dart'; import 'package:image_picker/image_picker.dart'; -import '../embed_types.dart'; +import '../../../../logic/extensions/controller.dart'; +import '../../embed_types.dart'; class LinkDialog extends StatefulWidget { const LinkDialog({ this.dialogTheme, this.link, this.linkRegExp, - Key? key, - }) : super(key: key); + super.key, + }); final QuillDialogTheme? dialogTheme; final String? link; @@ -122,7 +123,7 @@ class ImageVideoUtils { color: Colors.orangeAccent, ), label: Text('Gallery'.i18n), - onPressed: () => Navigator.pop(ctx, MediaPickSetting.Gallery), + onPressed: () => Navigator.pop(ctx, MediaPickSetting.gallery), ), TextButton.icon( icon: const Icon( @@ -130,7 +131,7 @@ class ImageVideoUtils { color: Colors.cyanAccent, ), label: Text('Link'.i18n), - onPressed: () => Navigator.pop(ctx, MediaPickSetting.Link), + onPressed: () => Navigator.pop(ctx, MediaPickSetting.link), ) ], ), @@ -146,16 +147,17 @@ class ImageVideoUtils { FilePickImpl? filePickImpl, WebImagePickImpl? webImagePickImpl, }) async { - final index = controller.selection.baseOffset; - final length = controller.selection.extentOffset - index; - String? imageUrl; if (kIsWeb) { - assert( - webImagePickImpl != null, - 'Please provide webImagePickImpl for Web ' - '(check out example directory for how to do it)'); - imageUrl = await webImagePickImpl!(onImagePickCallback); + if (webImagePickImpl != null) { + imageUrl = await webImagePickImpl(onImagePickCallback); + return; + } + final file = await ImagePicker().pickImage(source: ImageSource.gallery); + imageUrl = file?.path; + if (imageUrl == null) { + return; + } } else if (isMobile()) { imageUrl = await _pickImage(imageSource, onImagePickCallback); } else { @@ -164,9 +166,13 @@ class ImageVideoUtils { await _pickImageDesktop(context, filePickImpl!, onImagePickCallback); } - if (imageUrl != null) { - controller.replaceText(index, length, BlockEmbed.image(imageUrl), null); + if (imageUrl == null) { + return; } + + controller.insertImageBlock( + imageUrl: imageUrl, + ); } static Future _pickImage( @@ -182,9 +188,10 @@ class ImageVideoUtils { } static Future _pickImageDesktop( - BuildContext context, - FilePickImpl filePickImpl, - OnImagePickCallback onImagePickCallback) async { + BuildContext context, + FilePickImpl filePickImpl, + OnImagePickCallback onImagePickCallback, + ) async { final filePath = await filePickImpl(context); if (filePath == null || filePath.isEmpty) return null; @@ -207,9 +214,10 @@ class ImageVideoUtils { String? videoUrl; if (kIsWeb) { assert( - webVideoPickImpl != null, - 'Please provide webVideoPickImpl for Web ' - '(check out example directory for how to do it)'); + webVideoPickImpl != null, + 'Please provide webVideoPickImpl for Web ' + 'in the options of this button', + ); videoUrl = await webVideoPickImpl!(onVideoPickCallback); } else if (isMobile()) { videoUrl = await _pickVideo(videoSource, onVideoPickCallback); diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button.dart new file mode 100644 index 00000000..5019ac6b --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button.dart @@ -0,0 +1,155 @@ +// ignore_for_file: use_build_context_synchronously + +import 'package:flutter/material.dart'; +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:image_picker/image_picker.dart'; + +import '../../models/config/toolbar/buttons/video.dart'; +import '../embed_types.dart'; +import 'utils/image_video_utils.dart'; + +class QuillToolbarVideoButton extends StatelessWidget { + const QuillToolbarVideoButton({ + required this.options, + required this.controller, + super.key, + }); + + final QuillController controller; + + final QuillToolbarVideoButtonOptions options; + + double _iconSize(BuildContext context) { + final baseFontSize = baseButtonExtraOptions(context).globalIconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize; + } + + VoidCallback? _afterButtonPressed(BuildContext context) { + return options.afterButtonPressed ?? + baseButtonExtraOptions(context).afterButtonPressed; + } + + QuillIconTheme? _iconTheme(BuildContext context) { + return options.iconTheme ?? baseButtonExtraOptions(context).iconTheme; + } + + QuillToolbarBaseButtonOptions baseButtonExtraOptions(BuildContext context) { + return context.requireQuillToolbarBaseButtonOptions; + } + + IconData _iconData(BuildContext context) { + return options.iconData ?? + baseButtonExtraOptions(context).iconData ?? + Icons.movie_creation; + } + + String _tooltip(BuildContext context) { + return options.tooltip ?? + baseButtonExtraOptions(context).tooltip ?? + 'Insert video'; + // ('Insert video'.i18n); + } + + void _sharedOnPressed(BuildContext context) { + _onPressedHandler(context); + _afterButtonPressed(context); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + + final iconTheme = _iconTheme(context); + + final tooltip = _tooltip(context); + final iconSize = _iconSize(context); + final iconData = _iconData(context); + final childBuilder = + options.childBuilder ?? baseButtonExtraOptions(context).childBuilder; + + final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; + final iconFillColor = iconTheme?.iconUnselectedFillColor ?? + (options.fillColor ?? theme.canvasColor); + + if (childBuilder != null) { + return childBuilder( + QuillToolbarVideoButtonOptions( + afterButtonPressed: _afterButtonPressed(context), + iconData: iconData, + dialogTheme: options.dialogTheme, + filePickImpl: options.filePickImpl, + fillColor: iconFillColor, + iconSize: options.iconSize, + linkRegExp: options.linkRegExp, + tooltip: options.tooltip, + mediaPickSettingSelector: options.mediaPickSettingSelector, + iconTheme: options.iconTheme, + onVideoPickCallback: options.onVideoPickCallback, + webVideoPickImpl: options.webVideoPickImpl, + ), + QuillToolbarVideoButtonExtraOptions( + context: context, + controller: controller, + onPressed: () => _sharedOnPressed(context), + ), + ); + } + + return QuillToolbarIconButton( + icon: Icon(iconData, size: iconSize, color: iconColor), + tooltip: tooltip, + highlightElevation: 0, + hoverElevation: 0, + size: iconSize * 1.77, + fillColor: iconFillColor, + borderRadius: iconTheme?.borderRadius ?? 2, + onPressed: () => _sharedOnPressed(context), + ); + } + + Future _onPressedHandler(BuildContext context) async { + if (options.onVideoPickCallback != null) { + final selector = options.mediaPickSettingSelector ?? + ImageVideoUtils.selectMediaPickSetting; + final source = await selector(context); + if (source != null) { + if (source == MediaPickSetting.gallery) { + _pickVideo(context); + } else { + await _typeLink(context); + } + } + } else { + await _typeLink(context); + } + } + + void _pickVideo(BuildContext context) => ImageVideoUtils.handleVideoButtonTap( + context, + controller, + ImageSource.gallery, + options.onVideoPickCallback!, + filePickImpl: options.filePickImpl, + webVideoPickImpl: options.webVideoPickImpl, + ); + + Future _typeLink(BuildContext context) async { + final value = await showDialog( + context: context, + builder: (_) => LinkDialog( + dialogTheme: options.dialogTheme, + ), + ); + _linkSubmitted(value); + } + + void _linkSubmitted(String? value) { + if (value != null && value.isNotEmpty) { + final index = controller.selection.baseOffset; + final length = controller.selection.extentOffset - index; + + controller.replaceText(index, length, BlockEmbed.video(value), null); + } + } +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/utils.dart b/flutter_quill_extensions/lib/presentation/embeds/utils.dart new file mode 100644 index 00000000..c7adfc42 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/utils.dart @@ -0,0 +1,87 @@ +import 'dart:io' show File; + +import 'package:flutter/foundation.dart' show immutable; +import '../../logic/services/s_image_saver.dart'; + +// I would like to orgnize the project structure and the code more +// but here I don't want to change too much since that is a community project + +RegExp _base64 = RegExp( + r'^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$', +); + +bool isBase64(String str) { + return _base64.hasMatch(str); +} + +bool isHttpBasedUrl(String url) { + try { + final uri = Uri.parse(url.trim()); + return uri.isScheme('HTTP') || uri.isScheme('HTTPS'); + } catch (_) { + return false; + } +} + +bool isYouTubeUrl(String videoUrl) { + try { + final uri = Uri.parse(videoUrl); + return uri.host == 'www.youtube.com' || + uri.host == 'youtube.com' || + uri.host == 'youtu.be'; + } catch (_) { + return false; + } +} + +bool isImageBase64(String imageUrl) { + return !isHttpBasedUrl(imageUrl) && isBase64(imageUrl); +} + +enum SaveImageResultMethod { network, localStorage } + +@immutable +class SaveImageResult { + const SaveImageResult({required this.isSuccess, required this.method}); + + final bool isSuccess; + final SaveImageResultMethod method; +} + +Future saveImage(String imageUrl) async { + final imageSaverService = ImageSaverService.getInstance(); + final imageFile = File(imageUrl); + final hasPermission = await imageSaverService.hasAccess(); + final imageExistsLocally = await imageFile.exists(); + if (!hasPermission) { + await imageSaverService.requestAccess(); + } + if (!imageExistsLocally) { + try { + await imageSaverService.saveImageFromNetwork( + Uri.parse(imageUrl), + ); + return const SaveImageResult( + isSuccess: true, + method: SaveImageResultMethod.network, + ); + } catch (e) { + return const SaveImageResult( + isSuccess: false, + method: SaveImageResultMethod.network, + ); + } + } + try { + await imageSaverService.saveLocalImage(imageUrl); + return const SaveImageResult( + isSuccess: true, + method: SaveImageResultMethod.localStorage, + ); + } catch (e) { + return const SaveImageResult( + isSuccess: false, + method: SaveImageResultMethod.localStorage, + ); + } +} diff --git a/flutter_quill_extensions/lib/embeds/widgets/image.dart b/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart similarity index 99% rename from flutter_quill_extensions/lib/embeds/widgets/image.dart rename to flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart index fe698a43..8e3b617d 100644 --- a/flutter_quill_extensions/lib/embeds/widgets/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart @@ -99,6 +99,7 @@ class ImageTapWrapper extends StatelessWidget { required this.imageUrl, required this.imageProviderBuilder, required this.imageErrorWidgetBuilder, + super.key, }); final String imageUrl; diff --git a/flutter_quill_extensions/lib/embeds/widgets/image_resizer.dart b/flutter_quill_extensions/lib/presentation/embeds/widgets/image_resizer.dart similarity index 88% rename from flutter_quill_extensions/lib/embeds/widgets/image_resizer.dart rename to flutter_quill_extensions/lib/presentation/embeds/widgets/image_resizer.dart index 9f84ad17..92f2fb7c 100644 --- a/flutter_quill_extensions/lib/embeds/widgets/image_resizer.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/widgets/image_resizer.dart @@ -5,14 +5,14 @@ import 'package:flutter/scheduler.dart'; import 'package:flutter_quill/translations.dart'; class ImageResizer extends StatefulWidget { - const ImageResizer( - {required this.imageWidth, - required this.imageHeight, - required this.maxWidth, - required this.maxHeight, - required this.onImageResize, - Key? key}) - : super(key: key); + const ImageResizer({ + required this.imageWidth, + required this.imageHeight, + required this.maxWidth, + required this.maxHeight, + required this.onImageResize, + super.key, + }); final double? imageWidth; final double? imageHeight; @@ -21,10 +21,10 @@ class ImageResizer extends StatefulWidget { final Function(double, double) onImageResize; @override - _ImageResizerState createState() => _ImageResizerState(); + ImageResizerState createState() => ImageResizerState(); } -class _ImageResizerState extends State { +class ImageResizerState extends State { late double _width; late double _height; @@ -85,6 +85,7 @@ class _ImageResizerState extends State { value: value, max: max, divisions: 1000, + // Might need to be changed label: label.i18n, onChanged: (val) { setState(() { diff --git a/flutter_quill_extensions/lib/presentation/embeds/widgets/simple_dialog_item.dart b/flutter_quill_extensions/lib/presentation/embeds/widgets/simple_dialog_item.dart new file mode 100644 index 00000000..4053fc05 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/widgets/simple_dialog_item.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; + +class SimpleDialogItem extends StatelessWidget { + const SimpleDialogItem({ + required this.icon, + required this.color, + required this.text, + required this.onPressed, + super.key, + }); + + final IconData icon; + final Color color; + final String text; + final VoidCallback onPressed; + + @override + Widget build(BuildContext context) { + return SimpleDialogOption( + onPressed: onPressed, + child: Row( + children: [ + Icon(icon, size: 36, color: color), + Padding( + padding: const EdgeInsetsDirectional.only(start: 16), + child: + Text(text, style: const TextStyle(fontWeight: FontWeight.bold)), + ), + ], + ), + ); + } +} diff --git a/flutter_quill_extensions/lib/embeds/widgets/video_app.dart b/flutter_quill_extensions/lib/presentation/embeds/widgets/video_app.dart similarity index 96% rename from flutter_quill_extensions/lib/embeds/widgets/video_app.dart rename to flutter_quill_extensions/lib/presentation/embeds/widgets/video_app.dart index c65b9a78..895d40cd 100644 --- a/flutter_quill_extensions/lib/embeds/widgets/video_app.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/widgets/video_app.dart @@ -13,6 +13,7 @@ class VideoApp extends StatefulWidget { required this.videoUrl, required this.context, required this.readOnly, + super.key, this.onVideoInit, }); @@ -22,10 +23,10 @@ class VideoApp extends StatefulWidget { final void Function(GlobalKey videoContainerKey)? onVideoInit; @override - _VideoAppState createState() => _VideoAppState(); + VideoAppState createState() => VideoAppState(); } -class _VideoAppState extends State { +class VideoAppState extends State { late VideoPlayerController _controller; GlobalKey videoContainerKey = GlobalKey(); diff --git a/flutter_quill_extensions/lib/embeds/widgets/youtube_video_app.dart b/flutter_quill_extensions/lib/presentation/embeds/widgets/youtube_video_app.dart similarity index 78% rename from flutter_quill_extensions/lib/embeds/widgets/youtube_video_app.dart rename to flutter_quill_extensions/lib/presentation/embeds/widgets/youtube_video_app.dart index 02e53fbe..e278280b 100644 --- a/flutter_quill_extensions/lib/embeds/widgets/youtube_video_app.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/widgets/youtube_video_app.dart @@ -6,18 +6,21 @@ import 'package:youtube_player_flutter/youtube_player_flutter.dart'; class YoutubeVideoApp extends StatefulWidget { const YoutubeVideoApp( - {required this.videoUrl, required this.context, required this.readOnly}); + {required this.videoUrl, + required this.context, + required this.readOnly, + super.key}); final String videoUrl; final BuildContext context; final bool readOnly; @override - _YoutubeVideoAppState createState() => _YoutubeVideoAppState(); + YoutubeVideoAppState createState() => YoutubeVideoAppState(); } -class _YoutubeVideoAppState extends State { - var _youtubeController; +class YoutubeVideoAppState extends State { + YoutubePlayerController? _youtubeController; @override void initState() { @@ -36,7 +39,9 @@ class _YoutubeVideoAppState extends State { @override Widget build(BuildContext context) { final defaultStyles = DefaultStyles.getInstance(context); - if (_youtubeController == null) { + final youtubeController = _youtubeController; + + if (youtubeController == null) { if (widget.readOnly) { return RichText( text: TextSpan( @@ -51,11 +56,11 @@ class _YoutubeVideoAppState extends State { text: TextSpan(text: widget.videoUrl, style: defaultStyles.link)); } - return Container( + return SizedBox( height: 300, child: YoutubePlayerBuilder( player: YoutubePlayer( - controller: _youtubeController, + controller: youtubeController, showVideoProgressIndicator: true, ), builder: (context, player) { @@ -74,6 +79,6 @@ class _YoutubeVideoAppState extends State { @override void dispose() { super.dispose(); - _youtubeController.dispose(); + _youtubeController?.dispose(); } } diff --git a/flutter_quill_extensions/lib/presentation/models/config/editor/image.dart b/flutter_quill_extensions/lib/presentation/models/config/editor/image.dart new file mode 100644 index 00000000..5a30ab15 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/models/config/editor/image.dart @@ -0,0 +1,136 @@ +import 'package:flutter_quill/extensions.dart'; +import 'package:meta/meta.dart' show immutable; + +import '../../../embeds/embed_types.dart'; + +/// [QuillEditorImageEmbedConfigurations] for desktop, mobile and +/// other platforms +/// excluding web, it's configurations that is needed for the editor +/// +@immutable +class QuillEditorImageEmbedConfigurations { + const QuillEditorImageEmbedConfigurations({ + this.forceUseMobileOptionMenuForImageClick = false, + this.onImageRemovedCallback, + this.shouldRemoveImageCallback, + this.imageProviderBuilder, + this.imageErrorWidgetBuilder, + }); + + /// [onImageRemovedCallback] is called when an image is + /// removed from the editor. + /// By default, [onImageRemovedCallback] deletes the + /// temporary image file if + /// the platform is mobile and if it still exists. You + /// can customize this behavior + /// by passing your own function that handles the removal process. + /// + /// Example of [onImageRemovedCallback] customization: + /// ```dart + /// afterRemoveImageFromEditor: (imageFile) async { + /// // Your custom logic here + /// // or leave it empty to do nothing + /// } + /// ``` + /// + final ImageEmbedBuilderOnRemovedCallback? onImageRemovedCallback; + + /// [shouldRemoveImageCallback] is a callback + /// function that is invoked when the + /// user attempts to remove an image from the editor. It allows you to control + /// whether the image should be removed based on your custom logic. + /// + /// Example of [shouldRemoveImageCallback] customization: + /// ```dart + /// shouldRemoveImageFromEditor: (imageFile) async { + /// // Show a confirmation dialog before removing the image + /// final isShouldRemove = await showYesCancelDialog( + /// context: context, + /// options: const YesOrCancelDialogOptions( + /// title: 'Deleting an image', + /// message: 'Are you sure you want' ' to delete this + /// image from the editor?', + /// ), + /// ); + /// + /// // Return `true` to allow image removal if the user confirms, otherwise + /// `false` + /// return isShouldRemove; + /// } + /// ``` + /// + final ImageEmbedBuilderWillRemoveCallback? shouldRemoveImageCallback; + + /// [imageProviderBuilder] if you want to use custom image provider, please + /// pass a value to this property + /// By default we will use [NetworkImage] provider if the image url/path + /// is using http/https, if not then we will use [FileImage] provider + /// If you ovveride this make sure to handle the case where if the [imageUrl] + /// is in the local storage or it does exists in the system file + /// or use the same way we did it + /// + /// Example of [imageProviderBuilder] customization: + /// ```dart + /// imageProviderBuilder: (imageUrl) async { + /// // Example of using cached_network_image package + /// // Don't forgot to check if that image is local or network one + /// return CachedNetworkImageProvider(imageUrl); + /// } + /// ``` + /// + final ImageEmbedBuilderProviderBuilder? imageProviderBuilder; + + /// [imageErrorWidgetBuilder] if you want to show a custom widget based on the + /// exception that happen while loading the image, if it network image or + /// local one, and it will get called on all the images even in the photo + /// preview widget and not just in the quill editor + /// by default the default error from flutter framework will thrown + /// + final ImageEmbedBuilderErrorWidgetBuilder? imageErrorWidgetBuilder; + + /// [forceUseMobileOptionMenuForImageClick] is a boolean + /// flag that, when set to `true`, + /// enforces the use of the mobile-specific option menu for image clicks in + /// other platforms like desktop, this option doesn't affect mobile. it will + /// not affect web + /// This option + /// can be used to override the default behavior based on the platform. + /// + final bool forceUseMobileOptionMenuForImageClick; + + static ImageEmbedBuilderOnRemovedCallback get defaultOnImageRemovedCallback { + return (imageFile) async { + final mobile = isMobile(); + // If the platform is not mobile, return void; + // Since the mobile OS gives us a copy of the image + + // Note: We should remove the image on Flutter web + // since the behavior is similar to how it is on mobile, + // but since this builder is not for web, we will ignore it + if (!mobile) { + return; + } + + // On mobile OS (Android, iOS), the system will not give us + // direct access to the image; instead, + // it will give us the image + // in the temp directory of the application. So, we want to + // remove it when we no longer need it. + + // but on desktop we don't want to touch user files + // especially on macOS, where we can't even delete + // it without + // permission + + final isFileExists = await imageFile.exists(); + if (isFileExists) { + await imageFile.delete(); + } + }; + } +} + +@immutable +class QuillEditorWebImageEmbedConfigurations { + const QuillEditorWebImageEmbedConfigurations(); +} diff --git a/flutter_quill_extensions/lib/presentation/models/config/editor/video.dart b/flutter_quill_extensions/lib/presentation/models/config/editor/video.dart new file mode 100644 index 00000000..53039dee --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/models/config/editor/video.dart @@ -0,0 +1,24 @@ +import 'package:flutter/widgets.dart' show GlobalKey; +import 'package:meta/meta.dart' show immutable; + +@immutable +class QuillEditorVideoEmbedConfigurations { + const QuillEditorVideoEmbedConfigurations({ + this.onVideoInit, + }); + + /// [onVideoInit] is a callback function that gets triggered when + /// a video is initialized. + /// You can use this to perform actions or setup configurations related + /// to video embedding. + /// + /// + /// Example usage: + /// ```dart + /// onVideoInit: (videoContainerKey) { + /// // Custom video initialization logic + /// }, + /// // Customize other callback functions as needed + /// ``` + final void Function(GlobalKey videoContainerKey)? onVideoInit; +} diff --git a/flutter_quill_extensions/lib/presentation/models/config/editor/webview.dart b/flutter_quill_extensions/lib/presentation/models/config/editor/webview.dart new file mode 100644 index 00000000..0d2149c6 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/models/config/editor/webview.dart @@ -0,0 +1,6 @@ +import 'package:meta/meta.dart' show immutable; + +@immutable +class QuillEditorWebViewEmbedConfigurations { + const QuillEditorWebViewEmbedConfigurations(); +} diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart new file mode 100644 index 00000000..eef8d4dd --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart @@ -0,0 +1,49 @@ +import 'package:flutter/widgets.dart' show Color; +import 'package:flutter_quill/flutter_quill.dart'; + +import '../../../../embeds/embed_types.dart'; + +class QuillToolbarCameraButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarCameraButtonExtraOptions({ + required super.controller, + required super.context, + required super.onPressed, + }); +} + +class QuillToolbarCameraButtonOptions extends QuillToolbarBaseButtonOptions< + QuillToolbarCameraButtonOptions, QuillToolbarCameraButtonExtraOptions> { + const QuillToolbarCameraButtonOptions({ + required this.onImagePickCallback, + required this.onVideoPickCallback, + this.webImagePickImpl, + this.webVideoPickImpl, + this.filePickImpl, + this.cameraPickSettingSelector, + this.iconSize, + this.fillColor, + super.iconData, + super.afterButtonPressed, + super.tooltip, + super.iconTheme, + super.childBuilder, + super.controller, + }); + + final OnImagePickCallback onImagePickCallback; + + final OnVideoPickCallback onVideoPickCallback; + + final WebImagePickImpl? webImagePickImpl; + + final WebVideoPickImpl? webVideoPickImpl; + + final FilePickImpl? filePickImpl; + + final MediaPickSettingSelector? cameraPickSettingSelector; + + final double? iconSize; + + final Color? fillColor; +} diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/formula.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/formula.dart new file mode 100644 index 00000000..7d716251 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/formula.dart @@ -0,0 +1,28 @@ +import 'package:flutter/widgets.dart' show Color; +import 'package:flutter_quill/flutter_quill.dart'; + +class QuillToolbarFormulaButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarFormulaButtonExtraOptions({ + required super.controller, + required super.context, + required super.onPressed, + }); +} + +class QuillToolbarFormulaButtonOptions extends QuillToolbarBaseButtonOptions< + QuillToolbarFormulaButtonOptions, QuillToolbarFormulaButtonExtraOptions> { + const QuillToolbarFormulaButtonOptions({ + super.tooltip, + super.iconData, + super.iconTheme, + super.afterButtonPressed, + super.childBuilder, + this.fillColor, + this.iconSize, + }); + + final Color? fillColor; + + final double? iconSize; +} diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart new file mode 100644 index 00000000..98bbb265 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart @@ -0,0 +1,53 @@ +import 'package:flutter/widgets.dart' show Color; +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:meta/meta.dart' show immutable; + +import '../../../../embeds/embed_types.dart'; + +class QuillToolbarImageButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarImageButtonExtraOptions({ + required super.controller, + required super.context, + required super.onPressed, + }); +} + +@immutable +class QuillToolbarImageButtonOptions extends QuillToolbarBaseButtonOptions< + QuillToolbarImageButtonOptions, QuillToolbarImageButtonExtraOptions> { + const QuillToolbarImageButtonOptions({ + super.iconData, + super.controller, + this.iconSize, + + /// specifies the tooltip text for the image button. + super.tooltip, + super.afterButtonPressed, + super.childBuilder, + super.iconTheme, + this.fillColor, + this.onImagePickCallback, + this.filePickImpl, + this.webImagePickImpl, + this.mediaPickSettingSelector, + this.dialogTheme, + this.linkRegExp, + }); + + final double? iconSize; + final Color? fillColor; + + final OnImagePickCallback? onImagePickCallback; + + final WebImagePickImpl? webImagePickImpl; + + final FilePickImpl? filePickImpl; + + final MediaPickSettingSelector? mediaPickSettingSelector; + + final QuillDialogTheme? dialogTheme; + + /// [imageLinkRegExp] is a regular expression to identify image links. + final RegExp? linkRegExp; +} diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart new file mode 100644 index 00000000..06001e2d --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart @@ -0,0 +1,84 @@ +import 'package:flutter/widgets.dart' show AutovalidateMode; +import 'package:flutter/widgets.dart' show Color, Size; +import 'package:flutter_quill/flutter_quill.dart'; + +import '../../../../embeds/embed_types.dart'; + +class QuillToolbarMediaButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarMediaButtonExtraOptions({ + required super.controller, + required super.context, + required super.onPressed, + }); +} + +class QuillToolbarMediaButtonOptions extends QuillToolbarBaseButtonOptions< + QuillToolbarMediaButtonOptions, QuillToolbarMediaButtonExtraOptions> { + const QuillToolbarMediaButtonOptions({ + required this.type, + required this.onMediaPickedCallback, + required this.onImagePickCallback, + required this.onVideoPickCallback, + this.dialogBarrierColor, + this.mediaFilePicker, + this.childrenSpacing = 16.0, + this.autovalidateMode = AutovalidateMode.disabled, + this.iconSize, + this.fillColor, + this.dialogTheme, + this.labelText, + this.hintText, + this.submitButtonText, + this.submitButtonSize, + this.galleryButtonText, + this.linkButtonText, + this.validationMessage, + this.filePickImpl, + this.webImagePickImpl, + this.webVideoPickImpl, + super.iconData, + super.afterButtonPressed, + super.tooltip, + super.iconTheme, + super.childBuilder, + super.controller, + }); + + final double? iconSize; + final Color? fillColor; + final QuillMediaType type; + final QuillDialogTheme? dialogTheme; + final MediaFilePicker? mediaFilePicker; + final MediaPickedCallback? onMediaPickedCallback; + final Color? dialogBarrierColor; + + /// The margin between child widgets in the dialog. + final double childrenSpacing; + + /// The text of label in link add mode. + final String? labelText; + + /// The hint text for link [TextField]. + final String? hintText; + + /// The text of the submit button. + final String? submitButtonText; + + /// The size of dialog buttons. + final Size? submitButtonSize; + + /// The text of the gallery button [MediaSourceSelectorDialog]. + final String? galleryButtonText; + + /// The text of the link button [MediaSourceSelectorDialog]. + final String? linkButtonText; + + final AutovalidateMode autovalidateMode; + final String? validationMessage; + final OnImagePickCallback onImagePickCallback; + final FilePickImpl? filePickImpl; + final WebImagePickImpl? webImagePickImpl; + final OnVideoPickCallback onVideoPickCallback; + final WebVideoPickImpl? webVideoPickImpl; +} diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart new file mode 100644 index 00000000..12995fda --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart @@ -0,0 +1,47 @@ +import 'package:flutter/widgets.dart' show Color; +import 'package:flutter_quill/flutter_quill.dart'; + +import '../../../../embeds/embed_types.dart'; + +class QuillToolbarVideoButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarVideoButtonExtraOptions({ + required super.controller, + required super.context, + required super.onPressed, + }); +} + +class QuillToolbarVideoButtonOptions extends QuillToolbarBaseButtonOptions< + QuillToolbarVideoButtonOptions, QuillToolbarVideoButtonExtraOptions> { + const QuillToolbarVideoButtonOptions({ + this.linkRegExp, + this.dialogTheme, + this.onVideoPickCallback, + this.webVideoPickImpl, + this.filePickImpl, + this.mediaPickSettingSelector, + this.fillColor, + this.iconSize, + super.iconData, + super.afterButtonPressed, + super.tooltip, + super.iconTheme, + super.childBuilder, + super.controller, + }); + + final RegExp? linkRegExp; + final QuillDialogTheme? dialogTheme; + final OnVideoPickCallback? onVideoPickCallback; + + final WebVideoPickImpl? webVideoPickImpl; + + final FilePickImpl? filePickImpl; + + final MediaPickSettingSelector? mediaPickSettingSelector; + + final Color? fillColor; + + final double? iconSize; +} diff --git a/flutter_quill_extensions/lib/shims/dart_ui_fake.dart b/flutter_quill_extensions/lib/shims/dart_ui_fake.dart deleted file mode 100644 index baaf9ebd..00000000 --- a/flutter_quill_extensions/lib/shims/dart_ui_fake.dart +++ /dev/null @@ -1,23 +0,0 @@ -// ignore_for_file: avoid_classes_with_only_static_members, camel_case_types, lines_longer_than_80_chars - -import 'package:universal_html/html.dart' as html; - -// Fake interface for the logic that this package needs from (web-only) dart:ui. -// This is conditionally exported so the analyzer sees these methods as available. - -typedef PlatroformViewFactory = html.Element Function(int viewId); - -/// Shim for web_ui engine.PlatformViewRegistry -/// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/ui.dart#L62 -class platformViewRegistry { - /// Shim for registerViewFactory - /// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/ui.dart#L72 - static dynamic registerViewFactory( - String viewTypeId, PlatroformViewFactory viewFactory) {} -} - -/// Shim for web_ui engine.AssetManager -/// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/src/engine/assets.dart#L12 -class webOnlyAssetManager { - static dynamic getAssetUrl(String asset) {} -} diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 7e2259e5..00ad2745 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,8 +1,15 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 0.5.1 -homepage: https://bulletjournal.us/home/index.html -repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions +version: 0.6.0-dev.1 +homepage: https://github.com/singerdmx/flutter-quill +repository: https://github.com/singerdmx/flutter-quill + +topics: + - ui + - widgets + - widget + - rich-text-editor + platforms: android: ios: @@ -12,31 +19,37 @@ platforms: windows: environment: - sdk: ">=2.17.0 <4.0.0" - flutter: ">=3.0.0" + sdk: '>=3.1.3 <4.0.0' + flutter: ">=1.17.0" dependencies: flutter: sdk: flutter - flutter_quill: ^7.8.0 - # In case you are working on changes for both libraries, - # flutter_quill: - # path: ../ + flutter_quill: ^8.1.6 http: ^1.1.0 - image_picker: ">=1.0.4" photo_view: ^0.14.0 - video_player: ^2.7.2 + video_player: ^2.8.1 youtube_player_flutter: ^8.1.2 - math_keyboard: ">=0.2.1" + flutter_inappwebview: ^5.8.0 universal_html: ^2.2.4 - gal: ^2.1.2 + path: ^1.8.3 + image_picker: ^1.0.4 + math_keyboard: ^0.2.1 + url_launcher: ^6.2.1 + meta: ^1.9.1 + +# In case you are working on changes for both libraries, please uncomment this section +# dependency_overrides: +# flutter_quill: +# path: ../ dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.11.1 - + flutter_lints: ^3.0.0 + flutter: + uses-material-design: true \ No newline at end of file From a934f4ddac28b17864c5aaeaeb949663980717d0 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 02:29:27 +0300 Subject: [PATCH 016/210] Fix the example --- example/pubspec.yaml | 10 +++++----- .../lib/presentation/embeds/editor/image/image.dart | 12 ++++++------ lib/src/models/structs/optional_size.dart | 5 ++++- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 4053c2c7..4c74eae5 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -14,15 +14,15 @@ dependencies: cupertino_icons: ^1.0.6 path_provider: ^2.1.1 filesystem_picker: ^4.0.0 - file_picker: ^6.0.0 - flutter_quill: - path: ../ - flutter_quill_extensions: - path: ../flutter_quill_extensions + file_picker: ^6.1.1 + flutter_quill: ^8.1.10 + flutter_quill_extensions: ^0.5.0 dependency_overrides: flutter_quill: path: ../ + flutter_quill_extensions: + path: ../flutter_quill_extensions dev_dependencies: flutter_test: diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart index 9fb3fbc2..c5170fa2 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart @@ -77,12 +77,12 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { : double.tryParse(Attribute.margin)) ?? 0.0; - assert( - width != null && height != null, - base.isMobile() - ? 'mobileWidth and mobileHeight must be specified' - : 'width and height must be specified', - ); + // assert( + // width != null && height != null, + // base.isMobile() + // ? 'mobileWidth and mobileHeight must be specified' + // : 'width and height must be specified', + // ); imageSize = OptionalSize(width, height); image = Padding( padding: EdgeInsets.all(margin), diff --git a/lib/src/models/structs/optional_size.dart b/lib/src/models/structs/optional_size.dart index a887b468..49d274c8 100644 --- a/lib/src/models/structs/optional_size.dart +++ b/lib/src/models/structs/optional_size.dart @@ -1,5 +1,8 @@ +import 'package:meta/meta.dart' show immutable; + +@immutable class OptionalSize { - OptionalSize( + const OptionalSize( this.width, this.height, ); From 90511b31a86c5dc552e36d7a29d409db9440a525 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 02:44:21 +0300 Subject: [PATCH 017/210] Move all the md files to the doc && Update pubspec.yaml of the extensions package --- flutter_quill_extensions/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 00ad2745..b90ceb10 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -26,7 +26,7 @@ dependencies: flutter: sdk: flutter - flutter_quill: ^8.1.6 + flutter_quill: ^8.1.10 http: ^1.1.0 photo_view: ^0.14.0 From b6fe4ade5540baa6778c4195153d08288997f2ed Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 02:44:21 +0300 Subject: [PATCH 018/210] Move all the md files to the doc && Update pubspec.yaml of the extensions package --- README.md | 4 ++-- CodeIntroduction.md => doc/CodeIntroduction.md | 0 doc_cn.md => doc/readme/cn.md | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename CodeIntroduction.md => doc/CodeIntroduction.md (100%) rename doc_cn.md => doc/readme/cn.md (100%) diff --git a/README.md b/README.md index 52ea4f47..1bd119d8 100644 --- a/README.md +++ b/README.md @@ -741,8 +741,8 @@ Made with [contrib.rocks](https://contrib.rocks). [Youtube Playlist]: https://youtube.com/playlist?list=PLbhaS_83B97vONkOAWGJrSXWX58et9zZ2 [Slack Group]: https://join.slack.com/t/bulletjournal1024/shared_invite/zt-fys7t9hi-ITVU5PGDen1rNRyCjdcQ2g [Sample Page]: https://github.com/singerdmx/flutter-quill/blob/master/example/lib/pages/home_page.dart -[Code Introduction]: https://github.com/singerdmx/flutter-quill/blob/master/CodeIntroduction.md +[Code Introduction]: https://github.com/singerdmx/flutter-quill/blob/master/doc/CodeIntroduction.md


    -[中文文档](./doc_cn.md) +[中文文档](./doc/readme/cn.md) diff --git a/CodeIntroduction.md b/doc/CodeIntroduction.md similarity index 100% rename from CodeIntroduction.md rename to doc/CodeIntroduction.md diff --git a/doc_cn.md b/doc/readme/cn.md similarity index 100% rename from doc_cn.md rename to doc/readme/cn.md From 0d38e8787dd0e44b958aa93a3908192f1dcda124 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 03:21:53 +0300 Subject: [PATCH 019/210] Follow dart best practices by using and remove as well since they are not used --- CHANGELOG.md | 3 + analysis_options.yaml | 3 +- example/lib/pages/home_page.dart | 10 +-- .../analysis_options.yaml | 2 +- flutter_quill_extensions/pubspec.yaml | 2 +- lib/src/models/documents/attribute.dart | 62 +++++++++---------- lib/src/models/documents/document.dart | 16 ++--- lib/src/models/documents/history.dart | 4 +- lib/src/models/documents/nodes/container.dart | 8 +-- .../models/documents/nodes/embeddable.dart | 4 +- lib/src/models/documents/nodes/leaf.dart | 6 +- lib/src/models/documents/nodes/line.dart | 36 +++++------ lib/src/models/documents/style.dart | 6 +- lib/src/models/quill_delta.dart | 20 +++--- lib/src/models/rules/delete.dart | 2 +- lib/src/models/rules/format.dart | 6 +- lib/src/models/rules/insert.dart | 2 +- lib/src/models/rules/rule.dart | 2 +- lib/src/utils/embeds.dart | 2 +- lib/src/utils/string.dart | 30 ++++----- lib/src/widgets/controller.dart | 16 ++--- lib/src/widgets/default_styles.dart | 16 ++--- lib/src/widgets/editor/editor.dart | 26 ++++---- lib/src/widgets/keyboard_listener.dart | 8 +-- lib/src/widgets/link.dart | 6 +- lib/src/widgets/proxy.dart | 27 ++++---- .../quill_single_child_scroll_view.dart | 5 +- lib/src/widgets/raw_editor/raw_editor.dart | 36 +++++------ ...editor_state_selection_delegate_mixin.dart | 6 +- ..._editor_state_text_input_client_mixin.dart | 2 +- .../widgets/style_widgets/bullet_point.dart | 4 +- .../widgets/style_widgets/checkbox_point.dart | 6 +- lib/src/widgets/text_block.dart | 13 ++-- lib/src/widgets/text_line.dart | 6 +- lib/src/widgets/text_selection.dart | 56 ++++++++--------- .../toolbar/buttons/arrow_indicated_list.dart | 6 +- lib/src/widgets/toolbar/buttons/color.dart | 5 +- .../widgets/toolbar/buttons/font_family.dart | 6 +- .../widgets/toolbar/buttons/font_size.dart | 6 +- lib/src/widgets/toolbar/buttons/history.dart | 6 +- lib/src/widgets/toolbar/buttons/indent.dart | 6 +- .../widgets/toolbar/buttons/link_style.dart | 8 +-- .../widgets/toolbar/buttons/link_style2.dart | 2 +- .../widgets/toolbar/buttons/quill_icon.dart | 4 +- .../toolbar/buttons/search/search_dialog.dart | 8 +-- .../toolbar/buttons/select_alignment.dart | 39 ++++++------ .../toolbar/buttons/select_header_style.dart | 10 +-- .../toolbar/buttons/toggle_check_list.dart | 6 +- .../widgets/toolbar/buttons/toggle_style.dart | 6 +- pubspec.yaml | 9 +-- test/widgets/controller_test.dart | 34 +++++----- 51 files changed, 301 insertions(+), 319 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a23ecd8a..430f82ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.1.11] +- Follow dart best practices by using `lints` and remove `pedantic` as well `platform` since they are not used + ## [8.1.10] - Secret for automated publishing to pub.dev. diff --git a/analysis_options.yaml b/analysis_options.yaml index 7749c861..f3e3dd31 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,4 +1,5 @@ -include: package:pedantic/analysis_options.yaml +include: package:lints/recommended.yaml +# include: package:pedantic/analysis_options.yaml analyzer: errors: diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 3411d5e7..288e9595 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -166,7 +166,7 @@ class _HomePageState extends State { extentOffset: offset + length, ); - controller.updateSelection(selection, ChangeSource.REMOTE); + controller.updateSelection(selection, ChangeSource.remote); // _selectionType = _SelectionType.line; @@ -539,7 +539,7 @@ class _HomePageState extends State { TextSelection.collapsed( offset: controller.selection.extentOffset + 1, ), - ChangeSource.LOCAL, + ChangeSource.local, ); controller.document.insert( @@ -551,7 +551,7 @@ class _HomePageState extends State { TextSelection.collapsed( offset: controller.selection.extentOffset + 1, ), - ChangeSource.LOCAL, + ChangeSource.local, ); controller.document.insert(controller.selection.extentOffset, ' '); @@ -559,7 +559,7 @@ class _HomePageState extends State { TextSelection.collapsed( offset: controller.selection.extentOffset + 1, ), - ChangeSource.LOCAL, + ChangeSource.local, ); controller.document.insert(controller.selection.extentOffset, '\n'); @@ -567,7 +567,7 @@ class _HomePageState extends State { TextSelection.collapsed( offset: controller.selection.extentOffset + 1, ), - ChangeSource.LOCAL, + ChangeSource.local, ); } } diff --git a/flutter_quill_extensions/analysis_options.yaml b/flutter_quill_extensions/analysis_options.yaml index 7749c861..8f1b96e4 100644 --- a/flutter_quill_extensions/analysis_options.yaml +++ b/flutter_quill_extensions/analysis_options.yaml @@ -1,4 +1,4 @@ -include: package:pedantic/analysis_options.yaml +include: package:lints/recommended.yaml analyzer: errors: diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index b90ceb10..66fd0b4b 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -49,7 +49,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^3.0.0 + flutter_lints: ^3.0.1 flutter: uses-material-design: true \ No newline at end of file diff --git a/lib/src/models/documents/attribute.dart b/lib/src/models/documents/attribute.dart index 91e6c89e..7797b2e6 100644 --- a/lib/src/models/documents/attribute.dart +++ b/lib/src/models/documents/attribute.dart @@ -4,10 +4,10 @@ import 'package:equatable/equatable.dart'; import 'package:quiver/core.dart'; enum AttributeScope { - INLINE, // refer to https://quilljs.com/docs/formats/#inline - BLOCK, // refer to https://quilljs.com/docs/formats/#block - EMBEDS, // refer to https://quilljs.com/docs/formats/#embeds - IGNORE, // attributes that can be ignored + inline, // refer to https://quilljs.com/docs/formats/#inline + block, // refer to https://quilljs.com/docs/formats/#block + embeds, // refer to https://quilljs.com/docs/formats/#embeds + ignore, // attributes that can be ignored } class Attribute extends Equatable { @@ -227,7 +227,7 @@ class Attribute extends Equatable { return IndentAttribute(level: level); } - bool get isInline => scope == AttributeScope.INLINE; + bool get isInline => scope == AttributeScope.inline; bool get isBlockExceptHeader => blockKeysExceptHeader.contains(key); @@ -283,110 +283,110 @@ class Attribute extends Equatable { } class BoldAttribute extends Attribute { - const BoldAttribute() : super('bold', AttributeScope.INLINE, true); + const BoldAttribute() : super('bold', AttributeScope.inline, true); } class ItalicAttribute extends Attribute { - const ItalicAttribute() : super('italic', AttributeScope.INLINE, true); + const ItalicAttribute() : super('italic', AttributeScope.inline, true); } class SmallAttribute extends Attribute { - const SmallAttribute() : super('small', AttributeScope.INLINE, true); + const SmallAttribute() : super('small', AttributeScope.inline, true); } class UnderlineAttribute extends Attribute { - const UnderlineAttribute() : super('underline', AttributeScope.INLINE, true); + const UnderlineAttribute() : super('underline', AttributeScope.inline, true); } class StrikeThroughAttribute extends Attribute { - const StrikeThroughAttribute() : super('strike', AttributeScope.INLINE, true); + const StrikeThroughAttribute() : super('strike', AttributeScope.inline, true); } class InlineCodeAttribute extends Attribute { - const InlineCodeAttribute() : super('code', AttributeScope.INLINE, true); + const InlineCodeAttribute() : super('code', AttributeScope.inline, true); } class FontAttribute extends Attribute { - const FontAttribute(String? val) : super('font', AttributeScope.INLINE, val); + const FontAttribute(String? val) : super('font', AttributeScope.inline, val); } class SizeAttribute extends Attribute { - const SizeAttribute(String? val) : super('size', AttributeScope.INLINE, val); + const SizeAttribute(String? val) : super('size', AttributeScope.inline, val); } class LinkAttribute extends Attribute { - const LinkAttribute(String? val) : super('link', AttributeScope.INLINE, val); + const LinkAttribute(String? val) : super('link', AttributeScope.inline, val); } class ColorAttribute extends Attribute { const ColorAttribute(String? val) - : super('color', AttributeScope.INLINE, val); + : super('color', AttributeScope.inline, val); } class BackgroundAttribute extends Attribute { const BackgroundAttribute(String? val) - : super('background', AttributeScope.INLINE, val); + : super('background', AttributeScope.inline, val); } /// This is custom attribute for hint class PlaceholderAttribute extends Attribute { const PlaceholderAttribute() - : super('placeholder', AttributeScope.INLINE, true); + : super('placeholder', AttributeScope.inline, true); } class HeaderAttribute extends Attribute { const HeaderAttribute({int? level}) - : super('header', AttributeScope.BLOCK, level); + : super('header', AttributeScope.block, level); } class IndentAttribute extends Attribute { const IndentAttribute({int? level}) - : super('indent', AttributeScope.BLOCK, level); + : super('indent', AttributeScope.block, level); } class AlignAttribute extends Attribute { - const AlignAttribute(String? val) : super('align', AttributeScope.BLOCK, val); + const AlignAttribute(String? val) : super('align', AttributeScope.block, val); } class ListAttribute extends Attribute { - const ListAttribute(String? val) : super('list', AttributeScope.BLOCK, val); + const ListAttribute(String? val) : super('list', AttributeScope.block, val); } class CodeBlockAttribute extends Attribute { - const CodeBlockAttribute() : super('code-block', AttributeScope.BLOCK, true); + const CodeBlockAttribute() : super('code-block', AttributeScope.block, true); } class BlockQuoteAttribute extends Attribute { - const BlockQuoteAttribute() : super('blockquote', AttributeScope.BLOCK, true); + const BlockQuoteAttribute() : super('blockquote', AttributeScope.block, true); } class DirectionAttribute extends Attribute { const DirectionAttribute(String? val) - : super('direction', AttributeScope.BLOCK, val); + : super('direction', AttributeScope.block, val); } class WidthAttribute extends Attribute { const WidthAttribute(String? val) - : super('width', AttributeScope.IGNORE, val); + : super('width', AttributeScope.ignore, val); } class HeightAttribute extends Attribute { const HeightAttribute(String? val) - : super('height', AttributeScope.IGNORE, val); + : super('height', AttributeScope.ignore, val); } class StyleAttribute extends Attribute { const StyleAttribute(String? val) - : super('style', AttributeScope.IGNORE, val); + : super('style', AttributeScope.ignore, val); } class TokenAttribute extends Attribute { - const TokenAttribute(String val) : super('token', AttributeScope.IGNORE, val); + const TokenAttribute(String val) : super('token', AttributeScope.ignore, val); } class ScriptAttribute extends Attribute { ScriptAttribute(ScriptAttributes? val) - : super('script', AttributeScope.INLINE, val?.value); + : super('script', AttributeScope.inline, val?.value); } enum ScriptAttributes { @@ -400,10 +400,10 @@ enum ScriptAttributes { class ImageAttribute extends Attribute { const ImageAttribute(String? url) - : super('image', AttributeScope.EMBEDS, url); + : super('image', AttributeScope.embeds, url); } class VideoAttribute extends Attribute { const VideoAttribute(String? url) - : super('video', AttributeScope.EMBEDS, url); + : super('video', AttributeScope.embeds, url); } diff --git a/lib/src/models/documents/document.dart b/lib/src/models/documents/document.dart index 55617865..9b8c21fd 100644 --- a/lib/src/models/documents/document.dart +++ b/lib/src/models/documents/document.dart @@ -78,9 +78,9 @@ class Document { return Delta(); } - final delta = _rules.apply(RuleType.INSERT, this, index, + final delta = _rules.apply(RuleType.insert, this, index, data: data, len: replaceLength); - compose(delta, ChangeSource.LOCAL); + compose(delta, ChangeSource.local); return delta; } @@ -92,9 +92,9 @@ class Document { /// Returns an instance of [Delta] actually composed into this document. Delta delete(int index, int len) { assert(index >= 0 && len > 0); - final delta = _rules.apply(RuleType.DELETE, this, index, len: len); + final delta = _rules.apply(RuleType.delete, this, index, len: len); if (delta.isNotEmpty) { - compose(delta, ChangeSource.LOCAL); + compose(delta, ChangeSource.local); } return delta; } @@ -142,10 +142,10 @@ class Document { var delta = Delta(); - final formatDelta = _rules.apply(RuleType.FORMAT, this, index, + final formatDelta = _rules.apply(RuleType.format, this, index, len: len, attribute: attribute); if (formatDelta.isNotEmpty) { - compose(formatDelta, ChangeSource.LOCAL); + compose(formatDelta, ChangeSource.local); delta = delta.compose(formatDelta); } @@ -445,8 +445,8 @@ class Document { /// Source of a [Change]. enum ChangeSource { /// Change originated from a local action. Typically triggered by user. - LOCAL, + local, /// Change originated from a remote action. - REMOTE, + remote, } diff --git a/lib/src/models/documents/history.dart b/lib/src/models/documents/history.dart index fa87700c..aa1ae769 100644 --- a/lib/src/models/documents/history.dart +++ b/lib/src/models/documents/history.dart @@ -34,7 +34,7 @@ class History { void handleDocChange(DocChange docChange) { if (ignoreChange) return; - if (!userOnly || docChange.source == ChangeSource.LOCAL) { + if (!userOnly || docChange.source == ChangeSource.local) { record(docChange.change, docChange.before); } else { transform(docChange.change); @@ -105,7 +105,7 @@ class History { dest.add(inverseDelta); lastRecorded = 0; ignoreChange = true; - doc.compose(delta, ChangeSource.LOCAL); + doc.compose(delta, ChangeSource.local); ignoreChange = false; return HistoryChanged(true, len); } diff --git a/lib/src/models/documents/nodes/container.dart b/lib/src/models/documents/nodes/container.dart index 47bc37e4..605e472e 100644 --- a/lib/src/models/documents/nodes/container.dart +++ b/lib/src/models/documents/nodes/container.dart @@ -137,17 +137,17 @@ abstract base class Container extends Node { } @override - void retain(int index, int? length, Style? attributes) { + void retain(int index, int? len, Style? style) { assert(isNotEmpty); final child = queryChild(index, false); - child.node!.retain(child.offset, length, attributes); + child.node!.retain(child.offset, len, style); } @override - void delete(int index, int? length) { + void delete(int index, int? len) { assert(isNotEmpty); final child = queryChild(index, false); - child.node!.delete(child.offset, length); + child.node!.delete(child.offset, len); } @override diff --git a/lib/src/models/documents/nodes/embeddable.dart b/lib/src/models/documents/nodes/embeddable.dart index b2db0abc..1db18da8 100644 --- a/lib/src/models/documents/nodes/embeddable.dart +++ b/lib/src/models/documents/nodes/embeddable.dart @@ -30,7 +30,7 @@ class Embeddable { /// the document model itself does not make any assumptions about the types /// of embedded objects and allows users to define their own types. class BlockEmbed extends Embeddable { - const BlockEmbed(String type, String data) : super(type, data); + const BlockEmbed(super.type, String super.data); static const String imageType = 'image'; static BlockEmbed image(String imageUrl) => BlockEmbed(imageType, imageUrl); @@ -47,7 +47,7 @@ class BlockEmbed extends Embeddable { } class CustomBlockEmbed extends BlockEmbed { - const CustomBlockEmbed(String type, String data) : super(type, data); + const CustomBlockEmbed(super.type, super.data); String toJsonString() => jsonEncode(toJson()); diff --git a/lib/src/models/documents/nodes/leaf.dart b/lib/src/models/documents/nodes/leaf.dart index 8ae3be36..4f1fd3b0 100644 --- a/lib/src/models/documents/nodes/leaf.dart +++ b/lib/src/models/documents/nodes/leaf.dart @@ -217,9 +217,9 @@ abstract base class Leaf extends Node { /// conflict with the one from the widgets, material or cupertino library /// base class QuillText extends Leaf { - QuillText([String text = '']) + QuillText([String super.text = '']) : assert(!text.contains('\n')), - super.val(text); + super.val(); @override Node newInstance() => QuillText(value); @@ -250,7 +250,7 @@ base class QuillText extends Leaf { /// applying "bold" style to an image gives no effect, while adding a "link" to /// an image actually makes the image react to user's action. base class Embed extends Leaf { - Embed(Embeddable data) : super.val(data); + Embed(Embeddable super.data) : super.val(); // Refer to https://www.fileformat.info/info/unicode/char/fffc/index.htm static const kObjectReplacementCharacter = '\uFFFC'; diff --git a/lib/src/models/documents/nodes/line.dart b/lib/src/models/documents/nodes/line.dart index 4a0c8c71..e11f095c 100644 --- a/lib/src/models/documents/nodes/line.dart +++ b/lib/src/models/documents/nodes/line.dart @@ -136,15 +136,15 @@ base class Line extends Container { if (isLineFormat) { assert( style.values.every((attr) => - attr.scope == AttributeScope.BLOCK || - attr.scope == AttributeScope.IGNORE), + attr.scope == AttributeScope.block || + attr.scope == AttributeScope.ignore), 'It is not allowed to apply inline attributes to line itself.'); _format(style); } else { // Otherwise forward to children as it's an inline format update. assert(style.values.every((attr) => - attr.scope == AttributeScope.INLINE || - attr.scope == AttributeScope.IGNORE)); + attr.scope == AttributeScope.inline || + attr.scope == AttributeScope.ignore)); assert(index + local != thisLength); super.retain(index, local, style); } @@ -351,7 +351,7 @@ base class Line extends Container { var result = const Style(); final excluded = {}; - void _handle(Style style) { + void handle(Style style) { for (final attr in result.values) { if (!style.containsKey(attr.key) || (style.attributes[attr.key] != attr.value)) { @@ -368,7 +368,7 @@ base class Line extends Container { var pos = node.length - data.offset; while (!node!.isLast && pos < local) { node = node.next as Leaf; - _handle(node.style); + handle(node.style); pos += node.length; } } @@ -382,7 +382,7 @@ base class Line extends Container { final remaining = len - local; if (remaining > 0 && nextLine != null) { final rest = nextLine!.collectStyle(0, remaining); - _handle(rest); + handle(rest); } return result; @@ -521,35 +521,35 @@ base class Line extends Container { } int _getPlainText(int offset, int len, StringBuffer plainText) { - var _len = len; + var len0 = len; final data = queryChild(offset, false); var node = data.node as Leaf?; - while (_len > 0) { + while (len0 > 0) { if (node == null) { // blank line plainText.write('\n'); - _len -= 1; + len0 -= 1; } else { - _len = _getNodeText(node, plainText, offset - node.offset, _len); + len0 = _getNodeText(node, plainText, offset - node.offset, len0); - while (!node!.isLast && _len > 0) { + while (!node!.isLast && len0 > 0) { node = node.next as Leaf; - _len = _getNodeText(node, plainText, 0, _len); + len0 = _getNodeText(node, plainText, 0, len0); } - if (_len > 0) { + if (len0 > 0) { // end of this line plainText.write('\n'); - _len -= 1; + len0 -= 1; } } - if (_len > 0 && nextLine != null) { - _len = nextLine!._getPlainText(0, _len, plainText); + if (len0 > 0 && nextLine != null) { + len0 = nextLine!._getPlainText(0, len0, plainText); } } - return _len; + return len0; } } diff --git a/lib/src/models/documents/style.dart b/lib/src/models/documents/style.dart index d3e1247a..589bfc15 100644 --- a/lib/src/models/documents/style.dart +++ b/lib/src/models/documents/style.dart @@ -21,7 +21,7 @@ class Style { final result = attributes.map((key, dynamic value) { final attr = Attribute.fromKeyValue(key, value); return MapEntry( - key, attr ?? Attribute(key, AttributeScope.IGNORE, value)); + key, attr ?? Attribute(key, AttributeScope.ignore, value)); }); return Style.attr(result); } @@ -45,10 +45,10 @@ class Style { bool get isInline => isNotEmpty && values.every((item) => item.isInline); bool get isBlock => - isNotEmpty && values.every((item) => item.scope == AttributeScope.BLOCK); + isNotEmpty && values.every((item) => item.scope == AttributeScope.block); bool get isIgnored => - isNotEmpty && values.every((item) => item.scope == AttributeScope.IGNORE); + isNotEmpty && values.every((item) => item.scope == AttributeScope.ignore); Attribute get single => _attributes.values.single; diff --git a/lib/src/models/quill_delta.dart b/lib/src/models/quill_delta.dart index a9babf60..196651e9 100644 --- a/lib/src/models/quill_delta.dart +++ b/lib/src/models/quill_delta.dart @@ -1,4 +1,6 @@ /// Implementation of Quill Delta format in Dart. +library; + import 'dart:math' as math; import 'package:collection/collection.dart'; @@ -262,11 +264,11 @@ class Delta { b ??= const {}; final attributes = {}; - (a.keys.toList()..addAll(b.keys)).forEach((key) { - if (a![key] != b![key]) { + for (final key in (a.keys.toList()..addAll(b.keys))) { + if (a[key] != b[key]) { attributes[key] = b.containsKey(key) ? b[key] : null; } - }); + } return attributes.keys.isNotEmpty ? attributes : null; } @@ -514,7 +516,7 @@ class Delta { final thisIter = DeltaIterator(this); final otherIter = DeltaIterator(other); - diffResult.forEach((component) { + for (final component in diffResult) { var length = component.text.length; while (length > 0) { var opLength = 0; @@ -549,7 +551,7 @@ class Delta { } length -= opLength; } - }); + } return retDelta..trim(); } @@ -787,9 +789,9 @@ class DeltaIterator { final op = delta.elementAt(_index); final opKey = op.key; final opAttributes = op.attributes; - final _currentOffset = _offset; - final actualLength = math.min(op.length! - _currentOffset, length); - if (actualLength == op.length! - _currentOffset) { + final currentOffset = _offset; + final actualLength = math.min(op.length! - currentOffset, length); + if (actualLength == op.length! - currentOffset) { _index++; _offset = 0; } else { @@ -797,7 +799,7 @@ class DeltaIterator { } final opData = op.isInsert && op.data is String ? (op.data as String) - .substring(_currentOffset, _currentOffset + actualLength) + .substring(currentOffset, currentOffset + actualLength) : op.data; final opIsNotEmpty = opData is String ? opData.isNotEmpty : true; // embeds are never empty diff --git a/lib/src/models/rules/delete.dart b/lib/src/models/rules/delete.dart index fd547825..b4555320 100644 --- a/lib/src/models/rules/delete.dart +++ b/lib/src/models/rules/delete.dart @@ -8,7 +8,7 @@ abstract class DeleteRule extends Rule { const DeleteRule(); @override - RuleType get type => RuleType.DELETE; + RuleType get type => RuleType.delete; @override void validateArgs(int? len, Object? data, Attribute? attribute) { diff --git a/lib/src/models/rules/format.dart b/lib/src/models/rules/format.dart index a57bac7a..7dea5e04 100644 --- a/lib/src/models/rules/format.dart +++ b/lib/src/models/rules/format.dart @@ -7,7 +7,7 @@ abstract class FormatRule extends Rule { const FormatRule(); @override - RuleType get type => RuleType.FORMAT; + RuleType get type => RuleType.format; @override void validateArgs(int? len, Object? data, Attribute? attribute) { @@ -30,7 +30,7 @@ class ResolveLineFormatRule extends FormatRule { Object? data, Attribute? attribute, }) { - if (attribute!.scope != AttributeScope.BLOCK) { + if (attribute!.scope != AttributeScope.block) { return null; } @@ -159,7 +159,7 @@ class ResolveInlineFormatRule extends FormatRule { Object? data, Attribute? attribute, }) { - if (attribute!.scope != AttributeScope.INLINE) { + if (attribute!.scope != AttributeScope.inline) { return null; } diff --git a/lib/src/models/rules/insert.dart b/lib/src/models/rules/insert.dart index 8f1c1dea..b4331d8f 100644 --- a/lib/src/models/rules/insert.dart +++ b/lib/src/models/rules/insert.dart @@ -10,7 +10,7 @@ abstract class InsertRule extends Rule { const InsertRule(); @override - RuleType get type => RuleType.INSERT; + RuleType get type => RuleType.insert; @override void validateArgs(int? len, Object? data, Attribute? attribute) { diff --git a/lib/src/models/rules/rule.dart b/lib/src/models/rules/rule.dart index 45b8bdf8..7f2c26cd 100644 --- a/lib/src/models/rules/rule.dart +++ b/lib/src/models/rules/rule.dart @@ -5,7 +5,7 @@ import 'delete.dart'; import 'format.dart'; import 'insert.dart'; -enum RuleType { INSERT, DELETE, FORMAT } +enum RuleType { insert, delete, format } abstract class Rule { const Rule(); diff --git a/lib/src/utils/embeds.dart b/lib/src/utils/embeds.dart index db693ba8..9ab16b65 100644 --- a/lib/src/utils/embeds.dart +++ b/lib/src/utils/embeds.dart @@ -7,7 +7,7 @@ import '../widgets/controller.dart'; OffsetValue getEmbedNode(QuillController controller, int offset) { var offset = controller.selection.start; var embedNode = controller.queryNode(offset); - if (embedNode == null || !(embedNode is Embed)) { + if (embedNode == null || embedNode is! Embed) { offset = max(0, offset - 1); embedNode = controller.queryNode(offset); } diff --git a/lib/src/utils/string.dart b/lib/src/utils/string.dart index 3de84e65..fe0207de 100644 --- a/lib/src/utils/string.dart +++ b/lib/src/utils/string.dart @@ -6,13 +6,13 @@ Map parseKeyValuePairs(String s, Set targetKeys) { final result = {}; final pairs = s.split(';'); for (final pair in pairs) { - final _index = pair.indexOf(':'); - if (_index < 0) { + final index = pair.indexOf(':'); + if (index < 0) { continue; } - final _key = pair.substring(0, _index).trim(); - if (targetKeys.contains(_key)) { - result[_key] = pair.substring(_index + 1).trim(); + final key = pair.substring(0, index).trim(); + if (targetKeys.contains(key)) { + result[key] = pair.substring(index + 1).trim(); } } @@ -28,12 +28,12 @@ String replaceStyleStringWithSize( final result = {}; final pairs = s.split(';'); for (final pair in pairs) { - final _index = pair.indexOf(':'); - if (_index < 0) { + final index = pair.indexOf(':'); + if (index < 0) { continue; } - final _key = pair.substring(0, _index).trim(); - result[_key] = pair.substring(_index + 1).trim(); + final key = pair.substring(0, index).trim(); + result[key] = pair.substring(index + 1).trim(); } if (isMobile) { @@ -55,12 +55,12 @@ String replaceStyleStringWithSize( } Alignment getAlignment(String? s) { - const _defaultAlignment = Alignment.center; + const defaultAlignment = Alignment.center; if (s == null) { - return _defaultAlignment; + return defaultAlignment; } - final _index = [ + final index = [ 'topLeft', 'topCenter', 'topRight', @@ -71,8 +71,8 @@ Alignment getAlignment(String? s) { 'bottomCenter', 'bottomRight' ].indexOf(s); - if (_index < 0) { - return _defaultAlignment; + if (index < 0) { + return defaultAlignment; } return [ @@ -85,5 +85,5 @@ Alignment getAlignment(String? s) { Alignment.bottomLeft, Alignment.bottomCenter, Alignment.bottomRight - ][_index]; + ][index]; } diff --git a/lib/src/widgets/controller.dart b/lib/src/widgets/controller.dart index fbfc77f0..b48ab9eb 100644 --- a/lib/src/widgets/controller.dart +++ b/lib/src/widgets/controller.dart @@ -202,7 +202,7 @@ class QuillController extends ChangeNotifier { // TextSelection.collapsed(offset: document.length), ChangeSource.LOCAL); updateSelection( TextSelection.collapsed(offset: selection.baseOffset + len), - ChangeSource.LOCAL); + ChangeSource.local); } else { // no need to move cursor notifyListeners(); @@ -261,13 +261,13 @@ class QuillController extends ChangeNotifier { final retainDelta = Delta() ..retain(index) ..retain(data is String ? data.length : 1, toggledStyle.toJson()); - document.compose(retainDelta, ChangeSource.LOCAL); + document.compose(retainDelta, ChangeSource.local); } } if (textSelection != null) { if (delta == null || delta.isEmpty) { - _updateSelection(textSelection, ChangeSource.LOCAL); + _updateSelection(textSelection, ChangeSource.local); } else { final user = Delta() ..retain(index) @@ -279,7 +279,7 @@ class QuillController extends ChangeNotifier { baseOffset: textSelection.baseOffset + positionDelta, extentOffset: textSelection.extentOffset + positionDelta, ), - ChangeSource.LOCAL, + ChangeSource.local, ); } } @@ -322,7 +322,7 @@ class QuillController extends ChangeNotifier { baseOffset: change.transformPosition(selection.baseOffset), extentOffset: change.transformPosition(selection.extentOffset)); if (selection != adjustedSelection) { - _updateSelection(adjustedSelection, ChangeSource.LOCAL); + _updateSelection(adjustedSelection, ChangeSource.local); } notifyListeners(); } @@ -334,21 +334,21 @@ class QuillController extends ChangeNotifier { void moveCursorToStart() { updateSelection( const TextSelection.collapsed(offset: 0), - ChangeSource.LOCAL, + ChangeSource.local, ); } void moveCursorToPosition(int position) { updateSelection( TextSelection.collapsed(offset: position), - ChangeSource.LOCAL, + ChangeSource.local, ); } void moveCursorToEnd() { updateSelection( TextSelection.collapsed(offset: plainTextEditingValue.text.length), - ChangeSource.LOCAL, + ChangeSource.local, ); } diff --git a/lib/src/widgets/default_styles.dart b/lib/src/widgets/default_styles.dart index dded6d08..6af846eb 100644 --- a/lib/src/widgets/default_styles.dart +++ b/lib/src/widgets/default_styles.dart @@ -11,9 +11,9 @@ import 'style_widgets/checkbox_point.dart'; class QuillStyles extends InheritedWidget { const QuillStyles({ required this.data, - required Widget child, - Key? key, - }) : super(key: key, child: child); + required super.child, + super.key, + }); final DefaultStyles data; @@ -128,12 +128,12 @@ class InlineCodeStyle { @immutable class DefaultListBlockStyle extends DefaultTextBlockStyle { const DefaultListBlockStyle( - TextStyle style, - VerticalSpacing verticalSpacing, - VerticalSpacing lineSpacing, - BoxDecoration? decoration, + super.style, + super.verticalSpacing, + super.lineSpacing, + super.decoration, this.checkboxUIBuilder, - ) : super(style, verticalSpacing, lineSpacing, decoration); + ); final QuillCheckboxBuilder? checkboxUIBuilder; } diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index 3c25cdb4..258f32c1 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -402,8 +402,8 @@ class _QuillEditorSelectionGestureDetectorBuilder return; } - final _platform = Theme.of(_state.context).platform; - if (isAppleOS(_platform)) { + final platform = Theme.of(_state.context).platform; + if (isAppleOS(platform)) { renderEditor!.selectPositionAt( from: details.globalPosition, cause: SelectionChangedCause.longPress, @@ -432,7 +432,7 @@ class _QuillEditorSelectionGestureDetectorBuilder if (segmentLeaf == null && line.length == 1) { editor!.widget.controller.updateSelection( TextSelection.collapsed(offset: pos.offset), - ChangeSource.LOCAL, + ChangeSource.local, ); return true; } @@ -475,8 +475,8 @@ class _QuillEditorSelectionGestureDetectorBuilder try { if (delegate.selectionEnabled && !_isPositionSelected(details)) { - final _platform = Theme.of(_state.context).platform; - if (isAppleOS(_platform) || isDesktop()) { + final platform = Theme.of(_state.context).platform; + if (isAppleOS(platform) || isDesktop()) { // added isDesktop() to enable extend selection in Windows platform switch (details.kind) { case PointerDeviceKind.mouse: @@ -539,8 +539,8 @@ class _QuillEditorSelectionGestureDetectorBuilder } if (delegate.selectionEnabled) { - final _platform = Theme.of(_state.context).platform; - if (isAppleOS(_platform)) { + final platform = Theme.of(_state.context).platform; + if (isAppleOS(platform)) { renderEditor!.selectPositionAt( from: details.globalPosition, cause: SelectionChangedCause.longPress, @@ -608,20 +608,20 @@ class RenderEditor extends RenderEditableContainerBox implements RenderAbstractEditor { RenderEditor({ required this.document, - required TextDirection textDirection, + required super.textDirection, required bool hasFocus, required this.selection, required this.scrollable, required LayerLink startHandleLayerLink, required LayerLink endHandleLayerLink, - required EdgeInsetsGeometry padding, + required super.padding, required CursorCont cursorController, required this.onSelectionChanged, required this.onSelectionCompleted, - required double scrollBottomInset, + required super.scrollBottomInset, required this.floatingCursorDisabled, ViewportOffset? offset, - List? children, + super.children, EdgeInsets floatingCursorAddedMargin = const EdgeInsets.fromLTRB(4, 4, 4, 5), double? maxContentWidth, @@ -632,11 +632,7 @@ class RenderEditor extends RenderEditableContainerBox _cursorController = cursorController, _maxContentWidth = maxContentWidth, super( - children: children, container: document.root, - textDirection: textDirection, - scrollBottomInset: scrollBottomInset, - padding: padding, ); final CursorCont _cursorController; diff --git a/lib/src/widgets/keyboard_listener.dart b/lib/src/widgets/keyboard_listener.dart index ee1e3d11..cba72b4f 100644 --- a/lib/src/widgets/keyboard_listener.dart +++ b/lib/src/widgets/keyboard_listener.dart @@ -31,8 +31,7 @@ class QuillPressedKeys extends ChangeNotifier { } class QuillKeyboardListener extends StatefulWidget { - const QuillKeyboardListener({required this.child, Key? key}) - : super(key: key); + const QuillKeyboardListener({required this.child, super.key}); final Widget child; @@ -77,9 +76,8 @@ class QuillKeyboardListenerState extends State { class _QuillPressedKeysAccess extends InheritedWidget { const _QuillPressedKeysAccess({ required this.pressedKeys, - required Widget child, - Key? key, - }) : super(key: key, child: child); + required super.child, + }); final QuillPressedKeys pressedKeys; diff --git a/lib/src/widgets/link.dart b/lib/src/widgets/link.dart index 345a0027..1489ba26 100644 --- a/lib/src/widgets/link.dart +++ b/lib/src/widgets/link.dart @@ -124,8 +124,7 @@ class _CupertinoAction extends StatelessWidget { required this.title, required this.icon, required this.onPressed, - Key? key, - }) : super(key: key); + }); final String title; final IconData icon; @@ -195,8 +194,7 @@ class _MaterialAction extends StatelessWidget { required this.title, required this.icon, required this.onPressed, - Key? key, - }) : super(key: key); + }); final String title; final IconData icon; diff --git a/lib/src/widgets/proxy.dart b/lib/src/widgets/proxy.dart index 2379c883..06f44191 100644 --- a/lib/src/widgets/proxy.dart +++ b/lib/src/widgets/proxy.dart @@ -7,11 +7,11 @@ import 'box.dart'; class BaselineProxy extends SingleChildRenderObjectWidget { const BaselineProxy({ - Key? key, - Widget? child, + super.key, + super.child, this.textStyle, this.padding, - }) : super(key: key, child: child); + }); final TextStyle? textStyle; final EdgeInsets? padding; @@ -36,15 +36,14 @@ class BaselineProxy extends SingleChildRenderObjectWidget { class RenderBaselineProxy extends RenderProxyBox { RenderBaselineProxy( - RenderParagraph? child, + RenderParagraph? super.child, TextStyle textStyle, EdgeInsets? padding, - ) : _prototypePainter = TextPainter( + ) : _prototypePainter = TextPainter( text: TextSpan(text: ' ', style: textStyle), textDirection: TextDirection.ltr, strutStyle: - StrutStyle.fromTextStyle(textStyle, forceStrutHeight: true)), - super(child); + StrutStyle.fromTextStyle(textStyle, forceStrutHeight: true)); final TextPainter _prototypePainter; @@ -87,7 +86,7 @@ class EmbedProxy extends SingleChildRenderObjectWidget { } class RenderEmbedProxy extends RenderProxyBox implements RenderContentProxyBox { - RenderEmbedProxy(RenderBox? child) : super(child); + RenderEmbedProxy(super.child); @override List getBoxesForSelection(TextSelection selection) { @@ -131,7 +130,7 @@ class RenderEmbedProxy extends RenderProxyBox implements RenderContentProxyBox { class RichTextProxy extends SingleChildRenderObjectWidget { /// Child argument should be an instance of RichText widget. const RichTextProxy( - {required RichText child, + {required RichText super.child, required this.textStyle, required this.textAlign, required this.textDirection, @@ -140,8 +139,7 @@ class RichTextProxy extends SingleChildRenderObjectWidget { this.textScaleFactor = 1.0, this.textWidthBasis = TextWidthBasis.parent, this.textHeightBehavior, - Key? key}) - : super(key: key, child: child); + super.key}); final TextStyle textStyle; final TextAlign textAlign; @@ -184,7 +182,7 @@ class RichTextProxy extends SingleChildRenderObjectWidget { class RenderParagraphProxy extends RenderProxyBox implements RenderContentProxyBox { RenderParagraphProxy( - RenderParagraph? child, + RenderParagraph? super.child, TextStyle textStyle, TextAlign textAlign, TextDirection textDirection, @@ -193,7 +191,7 @@ class RenderParagraphProxy extends RenderProxyBox Locale locale, TextWidthBasis textWidthBasis, TextHeightBehavior? textHeightBehavior, - ) : _prototypePainter = TextPainter( + ) : _prototypePainter = TextPainter( text: TextSpan(text: ' ', style: textStyle), textAlign: textAlign, textDirection: textDirection, @@ -201,8 +199,7 @@ class RenderParagraphProxy extends RenderProxyBox strutStyle: strutStyle, locale: locale, textWidthBasis: textWidthBasis, - textHeightBehavior: textHeightBehavior), - super(child); + textHeightBehavior: textHeightBehavior); final TextPainter _prototypePainter; diff --git a/lib/src/widgets/quill_single_child_scroll_view.dart b/lib/src/widgets/quill_single_child_scroll_view.dart index ba6c0371..80efbda7 100644 --- a/lib/src/widgets/quill_single_child_scroll_view.dart +++ b/lib/src/widgets/quill_single_child_scroll_view.dart @@ -77,9 +77,8 @@ class QuillSingleChildScrollView extends StatelessWidget { class _SingleChildViewport extends SingleChildRenderObjectWidget { const _SingleChildViewport({ required this.offset, - Key? key, - Widget? child, - }) : super(key: key, child: child); + super.child, + }); final ViewportOffset offset; diff --git a/lib/src/widgets/raw_editor/raw_editor.dart b/lib/src/widgets/raw_editor/raw_editor.dart index 28d6c342..fa2944a1 100644 --- a/lib/src/widgets/raw_editor/raw_editor.dart +++ b/lib/src/widgets/raw_editor/raw_editor.dart @@ -468,10 +468,10 @@ class RawEditorState extends EditorState assert(debugCheckHasMediaQuery(context)); super.build(context); - var _doc = controller.document; - if (_doc.isEmpty() && widget.placeholder != null) { + var doc = controller.document; + if (doc.isEmpty() && widget.placeholder != null) { final raw = widget.placeholder?.replaceAll(r'"', '\\"'); - _doc = Document.fromJson( + doc = Document.fromJson( jsonDecode( '[{"attributes":{"placeholder":true},"insert":"$raw\\n"}]', ), @@ -485,7 +485,7 @@ class RawEditorState extends EditorState cursor: SystemMouseCursors.text, child: _Editor( key: _editorKey, - document: _doc, + document: doc, selection: controller.selection, hasFocus: _hasFocus, scrollable: widget.scrollable, @@ -499,7 +499,7 @@ class RawEditorState extends EditorState padding: widget.padding, maxContentWidth: widget.maxContentWidth, floatingCursorDisabled: widget.floatingCursorDisabled, - children: _buildChildren(_doc, context), + children: _buildChildren(doc, context), ), ), ), @@ -527,7 +527,7 @@ class RawEditorState extends EditorState child: _Editor( key: _editorKey, offset: offset, - document: _doc, + document: doc, selection: controller.selection, hasFocus: _hasFocus, scrollable: widget.scrollable, @@ -541,7 +541,7 @@ class RawEditorState extends EditorState maxContentWidth: widget.maxContentWidth, cursorController: _cursorCont, floatingCursorDisabled: widget.floatingCursorDisabled, - children: _buildChildren(_doc, context), + children: _buildChildren(doc, context), ), ), ), @@ -853,7 +853,7 @@ class RawEditorState extends EditorState controller.selection.copyWith( baseOffset: selection.baseOffset + chars, extentOffset: selection.baseOffset + chars), - ChangeSource.LOCAL); + ChangeSource.local); } void _updateSelectionForKeyPhrase(String phrase, Attribute attribute) { @@ -871,7 +871,7 @@ class RawEditorState extends EditorState SelectionChangedCause cause, ) { final oldSelection = controller.selection; - controller.updateSelection(selection, ChangeSource.LOCAL); + controller.updateSelection(selection, ChangeSource.local); _selectionOverlay?.handlesVisible = _shouldShowSelectionHandles(); @@ -925,7 +925,7 @@ class RawEditorState extends EditorState controller ..ignoreFocusOnTextChange = false ..skipRequestKeyboard = !requestKeyboardFocusOnCheckListChanged - ..updateSelection(currentSelection, ChangeSource.LOCAL); + ..updateSelection(currentSelection, ChangeSource.local); }); } } @@ -1839,8 +1839,8 @@ class RawEditorState extends EditorState class _Editor extends MultiChildRenderObjectWidget { const _Editor({ - required Key key, - required List children, + required Key super.key, + required super.children, required this.document, required this.textDirection, required this.hasFocus, @@ -1856,7 +1856,7 @@ class _Editor extends MultiChildRenderObjectWidget { this.padding = EdgeInsets.zero, this.maxContentWidth, this.offset, - }) : super(key: key, children: children); + }); final ViewportOffset? offset; final Document document; @@ -2292,7 +2292,7 @@ class _UpdateTextSelectionAction final collapseSelection = intent.collapseSelection || !state.widget.selectionEnabled; // Collapse to the logical start/end. - TextSelection _collapse(TextSelection selection) { + TextSelection collapse(TextSelection selection) { assert(selection.isValid); assert(!selection.isCollapsed); return selection.copyWith( @@ -2306,7 +2306,7 @@ class _UpdateTextSelectionAction collapseSelection) { return Actions.invoke( context!, - UpdateSelectionIntent(state.textEditingValue, _collapse(selection), + UpdateSelectionIntent(state.textEditingValue, collapse(selection), SelectionChangedCause.keyboard), ); } @@ -2322,7 +2322,7 @@ class _UpdateTextSelectionAction return Actions.invoke( context!, UpdateSelectionIntent(state.textEditingValue, - _collapse(textBoundarySelection), SelectionChangedCause.keyboard), + collapse(textBoundarySelection), SelectionChangedCause.keyboard), ); } @@ -2682,9 +2682,9 @@ class _ApplyHeaderAction extends Action { @override void invoke(ApplyHeaderIntent intent, [BuildContext? context]) { - final _attribute = + final attribute = _getHeaderValue() == intent.header ? Attribute.header : intent.header; - state.controller.formatSelection(_attribute); + state.controller.formatSelection(attribute); } @override diff --git a/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart b/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart index 603402fa..0ad2c1c7 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart @@ -24,7 +24,7 @@ mixin RawEditorStateSelectionDelegateMixin on EditorState final diff = getDiff(oldText, newText, cursorPosition); if (diff.deleted == '' && diff.inserted == '') { // Only changing selection range - widget.controller.updateSelection(value.selection, ChangeSource.LOCAL); + widget.controller.updateSelection(value.selection, ChangeSource.local); return; } @@ -61,9 +61,9 @@ mixin RawEditorStateSelectionDelegateMixin on EditorState final node = widget.controller.document.queryChild(local).node; if (node != null && pasteStyleAndEmbed[i].length == node.length - 1) { - style.values.forEach((attribute) { + for (final attribute in style.values) { widget.controller.document.format(local, 0, attribute); - }); + } } } } diff --git a/lib/src/widgets/raw_editor/raw_editor_state_text_input_client_mixin.dart b/lib/src/widgets/raw_editor/raw_editor_state_text_input_client_mixin.dart index 2cd9ebf1..01411570 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state_text_input_client_mixin.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state_text_input_client_mixin.dart @@ -187,7 +187,7 @@ mixin RawEditorStateTextInputClientMixin on EditorState final cursorPosition = value.selection.extentOffset; final diff = getDiff(oldText, text, cursorPosition); if (diff.deleted.isEmpty && diff.inserted.isEmpty) { - widget.controller.updateSelection(value.selection, ChangeSource.LOCAL); + widget.controller.updateSelection(value.selection, ChangeSource.local); } else { widget.controller.replaceText( diff.start, diff.deleted.length, diff.inserted, value.selection); diff --git a/lib/src/widgets/style_widgets/bullet_point.dart b/lib/src/widgets/style_widgets/bullet_point.dart index f760c992..1dd1b4cf 100644 --- a/lib/src/widgets/style_widgets/bullet_point.dart +++ b/lib/src/widgets/style_widgets/bullet_point.dart @@ -5,8 +5,8 @@ class QuillEditorBulletPoint extends StatelessWidget { required this.style, required this.width, this.padding = 0, - Key? key, - }) : super(key: key); + super.key, + }); final TextStyle style; final double width; diff --git a/lib/src/widgets/style_widgets/checkbox_point.dart b/lib/src/widgets/style_widgets/checkbox_point.dart index 4d87df16..509db66f 100644 --- a/lib/src/widgets/style_widgets/checkbox_point.dart +++ b/lib/src/widgets/style_widgets/checkbox_point.dart @@ -20,11 +20,11 @@ class QuillEditorCheckboxPoint extends StatefulWidget { final QuillCheckboxBuilder? uiBuilder; @override - _QuillEditorCheckboxPointState createState() => - _QuillEditorCheckboxPointState(); + QuillEditorCheckboxPointState createState() => + QuillEditorCheckboxPointState(); } -class _QuillEditorCheckboxPointState extends State { +class QuillEditorCheckboxPointState extends State { @override Widget build(BuildContext context) { final uiBuilder = widget.uiBuilder; diff --git a/lib/src/widgets/text_block.dart b/lib/src/widgets/text_block.dart index f99ccbb0..71494df0 100644 --- a/lib/src/widgets/text_block.dart +++ b/lib/src/widgets/text_block.dart @@ -351,21 +351,18 @@ class RenderEditableTextBlock extends RenderEditableContainerBox implements RenderEditableBox { RenderEditableTextBlock({ required Block block, - required TextDirection textDirection, + required super.textDirection, required EdgeInsetsGeometry padding, - required double scrollBottomInset, + required super.scrollBottomInset, required Decoration decoration, - List? children, + super.children, EdgeInsets contentPadding = EdgeInsets.zero, }) : _decoration = decoration, _configuration = ImageConfiguration(textDirection: textDirection), _savedPadding = padding, _contentPadding = contentPadding, super( - children: children, container: block, - textDirection: textDirection, - scrollBottomInset: scrollBottomInset, padding: padding.add(contentPadding), ); @@ -665,9 +662,7 @@ class _EditableBlock extends MultiChildRenderObjectWidget { required this.scrollBottomInset, required this.decoration, required this.contentPadding, - required List children, - Key? key}) - : super(key: key, children: children); + required super.children}); final Block block; final TextDirection textDirection; diff --git a/lib/src/widgets/text_line.dart b/lib/src/widgets/text_line.dart index 8aa88ccb..b482ed79 100644 --- a/lib/src/widgets/text_line.dart +++ b/lib/src/widgets/text_line.dart @@ -294,14 +294,14 @@ class _TextLineState extends State { if (widget.customStyleBuilder == null) { return textStyle; } - attributes.keys.forEach((key) { + for (final key in attributes.keys) { final attr = attributes[key]; if (attr != null) { /// Custom Attribute final customAttr = widget.customStyleBuilder!.call(attr); textStyle = textStyle.merge(customAttr); } - }); + } return textStyle; } @@ -1292,7 +1292,7 @@ class RenderEditableTextLine extends RenderEditableBox { } class _TextLineElement extends RenderObjectElement { - _TextLineElement(EditableTextLine line) : super(line); + _TextLineElement(EditableTextLine super.line); final Map _slotToChildren = {}; diff --git a/lib/src/widgets/text_selection.dart b/lib/src/widgets/text_selection.dart index a4285308..7d88d316 100644 --- a/lib/src/widgets/text_selection.dart +++ b/lib/src/widgets/text_selection.dart @@ -21,22 +21,17 @@ TextSelection localSelection(Node node, TextSelection selection, fromParent) { /// The text position that a give selection handle manipulates. Dragging the /// [start] handle always moves the [start]/[baseOffset] of the selection. -enum _TextSelectionHandlePosition { START, END } +enum _TextSelectionHandlePosition { start, end } /// internal use, used to get drag direction information class DragTextSelection extends TextSelection { const DragTextSelection({ - TextAffinity affinity = TextAffinity.downstream, - int baseOffset = 0, - int extentOffset = 0, - bool isDirectional = false, + super.affinity, + super.baseOffset = 0, + super.extentOffset = 0, + super.isDirectional, this.first = true, - }) : super( - baseOffset: baseOffset, - extentOffset: extentOffset, - affinity: affinity, - isDirectional: isDirectional, - ); + }); final bool first; @@ -236,7 +231,7 @@ class EditorTextSelectionOverlay { Widget _buildHandle( BuildContext context, _TextSelectionHandlePosition position) { if (_selection.isCollapsed && - position == _TextSelectionHandlePosition.END) { + position == _TextSelectionHandlePosition.end) { return Container(); } return Visibility( @@ -282,12 +277,12 @@ class EditorTextSelectionOverlay { TextSelection? newSelection, _TextSelectionHandlePosition position) { TextPosition textPosition; switch (position) { - case _TextSelectionHandlePosition.START: + case _TextSelectionHandlePosition.start: textPosition = newSelection != null ? newSelection.base : const TextPosition(offset: 0); break; - case _TextSelectionHandlePosition.END: + case _TextSelectionHandlePosition.end: textPosition = newSelection != null ? newSelection.extent : const TextPosition(offset: 0); @@ -302,7 +297,7 @@ class EditorTextSelectionOverlay { extentOffset: newSelection.extentOffset, affinity: newSelection.affinity, isDirectional: newSelection.isDirectional, - first: position == _TextSelectionHandlePosition.START, + first: position == _TextSelectionHandlePosition.start, ) : null; @@ -344,10 +339,10 @@ class EditorTextSelectionOverlay { _handles = [ OverlayEntry( builder: (context) => - _buildHandle(context, _TextSelectionHandlePosition.START)), + _buildHandle(context, _TextSelectionHandlePosition.start)), OverlayEntry( builder: (context) => - _buildHandle(context, _TextSelectionHandlePosition.END)), + _buildHandle(context, _TextSelectionHandlePosition.end)), ]; Overlay.of(context, rootOverlay: true, debugRequiredFor: debugRequiredFor) @@ -375,8 +370,7 @@ class _TextSelectionHandleOverlay extends StatefulWidget { required this.onSelectionHandleTapped, required this.selectionControls, this.dragStartBehavior = DragStartBehavior.start, - Key? key, - }) : super(key: key); + }); final TextSelection selection; final _TextSelectionHandlePosition position; @@ -394,9 +388,9 @@ class _TextSelectionHandleOverlay extends StatefulWidget { ValueListenable get _visibility { switch (position) { - case _TextSelectionHandlePosition.START: + case _TextSelectionHandlePosition.start: return renderObject.selectionStartInViewport; - case _TextSelectionHandlePosition.END: + case _TextSelectionHandlePosition.end: return renderObject.selectionEndInViewport; default: throw 'Invalid position'; @@ -449,7 +443,7 @@ class _TextSelectionHandleOverlayState } void _handleDragStart(DragStartDetails details) { - final textPosition = widget.position == _TextSelectionHandlePosition.START + final textPosition = widget.position == _TextSelectionHandlePosition.start ? widget.selection.base : widget.selection.extent; final lineHeight = widget.renderObject.preferredLineHeight(textPosition); @@ -470,7 +464,7 @@ class _TextSelectionHandleOverlayState widget.selection.extentOffset >= widget.selection.baseOffset; TextSelection newSelection; switch (widget.position) { - case _TextSelectionHandlePosition.START: + case _TextSelectionHandlePosition.start: newSelection = TextSelection( baseOffset: isNormalized ? position.offset : widget.selection.baseOffset, @@ -478,7 +472,7 @@ class _TextSelectionHandleOverlayState isNormalized ? widget.selection.extentOffset : position.offset, ); break; - case _TextSelectionHandlePosition.END: + case _TextSelectionHandlePosition.end: newSelection = TextSelection( baseOffset: isNormalized ? widget.selection.baseOffset : position.offset, @@ -507,7 +501,7 @@ class _TextSelectionHandleOverlayState TextSelectionHandleType? type; switch (widget.position) { - case _TextSelectionHandlePosition.START: + case _TextSelectionHandlePosition.start: layerLink = widget.startHandleLayerLink; type = _chooseType( widget.renderObject.textDirection, @@ -515,7 +509,7 @@ class _TextSelectionHandleOverlayState TextSelectionHandleType.right, ); break; - case _TextSelectionHandlePosition.END: + case _TextSelectionHandlePosition.end: // For collapsed selections, we shouldn't be building the [end] handle. assert(!widget.selection.isCollapsed); layerLink = widget.endHandleLayerLink; @@ -533,7 +527,7 @@ class _TextSelectionHandleOverlayState // May have to use getSelectionBoxes instead of preferredLineHeight. // or expose TextStyle on the render object and calculate // preferredLineHeight / style.height - final textPosition = widget.position == _TextSelectionHandlePosition.START + final textPosition = widget.position == _TextSelectionHandlePosition.start ? widget.selection.base : widget.selection.extent; final lineHeight = widget.renderObject.preferredLineHeight(textPosition); @@ -649,8 +643,8 @@ class EditorTextSelectionGestureDetector extends StatefulWidget { this.onDragSelectionEnd, this.behavior, this.detectWordBoundary = true, - Key? key, - }) : super(key: key); + super.key, + }); /// Called for every tap down including every tap down that's part of a /// double click or a long press, except touches that include enough movement @@ -1001,8 +995,8 @@ class _EditorTextSelectionGestureDetectorState // underlying input. class _TransparentTapGestureRecognizer extends TapGestureRecognizer { _TransparentTapGestureRecognizer({ - Object? debugOwner, - }) : super(debugOwner: debugOwner); + super.debugOwner, + }); @override void rejectGesture(int pointer) { diff --git a/lib/src/widgets/toolbar/buttons/arrow_indicated_list.dart b/lib/src/widgets/toolbar/buttons/arrow_indicated_list.dart index f90b9b4d..c8ccd1bc 100644 --- a/lib/src/widgets/toolbar/buttons/arrow_indicated_list.dart +++ b/lib/src/widgets/toolbar/buttons/arrow_indicated_list.dart @@ -17,11 +17,11 @@ class QuillToolbarArrowIndicatedButtonList extends StatefulWidget { final List buttons; @override - _QuillToolbarArrowIndicatedButtonListState createState() => - _QuillToolbarArrowIndicatedButtonListState(); + QuillToolbarArrowIndicatedButtonListState createState() => + QuillToolbarArrowIndicatedButtonListState(); } -class _QuillToolbarArrowIndicatedButtonListState +class QuillToolbarArrowIndicatedButtonListState extends State with WidgetsBindingObserver { final ScrollController _controller = ScrollController(); diff --git a/lib/src/widgets/toolbar/buttons/color.dart b/lib/src/widgets/toolbar/buttons/color.dart index 9a0f0789..83da1e06 100644 --- a/lib/src/widgets/toolbar/buttons/color.dart +++ b/lib/src/widgets/toolbar/buttons/color.dart @@ -28,11 +28,10 @@ class QuillToolbarColorButton extends StatefulWidget { final QuillToolbarColorButtonOptions options; @override - _QuillToolbarColorButtonState createState() => - _QuillToolbarColorButtonState(); + QuillToolbarColorButtonState createState() => QuillToolbarColorButtonState(); } -class _QuillToolbarColorButtonState extends State { +class QuillToolbarColorButtonState extends State { late bool _isToggledColor; late bool _isToggledBackground; late bool _isWhite; diff --git a/lib/src/widgets/toolbar/buttons/font_family.dart b/lib/src/widgets/toolbar/buttons/font_family.dart index a82424a1..163fb295 100644 --- a/lib/src/widgets/toolbar/buttons/font_family.dart +++ b/lib/src/widgets/toolbar/buttons/font_family.dart @@ -26,11 +26,11 @@ class QuillToolbarFontFamilyButton extends StatefulWidget { final QuillController controller; @override - _QuillToolbarFontFamilyButtonState createState() => - _QuillToolbarFontFamilyButtonState(); + QuillToolbarFontFamilyButtonState createState() => + QuillToolbarFontFamilyButtonState(); } -class _QuillToolbarFontFamilyButtonState +class QuillToolbarFontFamilyButtonState extends State { var _currentValue = ''; diff --git a/lib/src/widgets/toolbar/buttons/font_size.dart b/lib/src/widgets/toolbar/buttons/font_size.dart index 419ad46a..a6ddf7e8 100644 --- a/lib/src/widgets/toolbar/buttons/font_size.dart +++ b/lib/src/widgets/toolbar/buttons/font_size.dart @@ -21,11 +21,11 @@ class QuillToolbarFontSizeButton extends StatefulWidget { final QuillController controller; @override - _QuillToolbarFontSizeButtonState createState() => - _QuillToolbarFontSizeButtonState(); + QuillToolbarFontSizeButtonState createState() => + QuillToolbarFontSizeButtonState(); } -class _QuillToolbarFontSizeButtonState +class QuillToolbarFontSizeButtonState extends State { String _currentValue = ''; diff --git a/lib/src/widgets/toolbar/buttons/history.dart b/lib/src/widgets/toolbar/buttons/history.dart index 297b4b9f..5bae3bfd 100644 --- a/lib/src/widgets/toolbar/buttons/history.dart +++ b/lib/src/widgets/toolbar/buttons/history.dart @@ -16,11 +16,11 @@ class QuillToolbarHistoryButton extends StatefulWidget { final QuillController controller; @override - _QuillToolbarHistoryButtonState createState() => - _QuillToolbarHistoryButtonState(); + QuillToolbarHistoryButtonState createState() => + QuillToolbarHistoryButtonState(); } -class _QuillToolbarHistoryButtonState extends State { +class QuillToolbarHistoryButtonState extends State { late ThemeData theme; var _canPressed = false; diff --git a/lib/src/widgets/toolbar/buttons/indent.dart b/lib/src/widgets/toolbar/buttons/indent.dart index 8aad9671..2c8cdf94 100644 --- a/lib/src/widgets/toolbar/buttons/indent.dart +++ b/lib/src/widgets/toolbar/buttons/indent.dart @@ -24,11 +24,11 @@ class QuillToolbarIndentButton extends StatefulWidget { final QuillToolbarIndentButtonOptions options; @override - _QuillToolbarIndentButtonState createState() => - _QuillToolbarIndentButtonState(); + QuillToolbarIndentButtonState createState() => + QuillToolbarIndentButtonState(); } -class _QuillToolbarIndentButtonState extends State { +class QuillToolbarIndentButtonState extends State { QuillToolbarIndentButtonOptions get options { return widget.options; } diff --git a/lib/src/widgets/toolbar/buttons/link_style.dart b/lib/src/widgets/toolbar/buttons/link_style.dart index b7bf91c0..5234dbaf 100644 --- a/lib/src/widgets/toolbar/buttons/link_style.dart +++ b/lib/src/widgets/toolbar/buttons/link_style.dart @@ -22,11 +22,11 @@ class QuillToolbarLinkStyleButton extends StatefulWidget { final QuillToolbarLinkStyleButtonOptions options; @override - _QuillToolbarLinkStyleButtonState createState() => - _QuillToolbarLinkStyleButtonState(); + QuillToolbarLinkStyleButtonState createState() => + QuillToolbarLinkStyleButtonState(); } -class _QuillToolbarLinkStyleButtonState +class QuillToolbarLinkStyleButtonState extends State { void _didChangeSelection() { setState(() {}); @@ -161,7 +161,7 @@ class _QuillToolbarLinkStyleButtonState final link = _getLinkAttributeValue(); final index = controller.selection.start; - var text; + String? text; if (link != null) { // text should be the link's corresponding text, not selection final leaf = controller.document.querySegmentLeafNode(index).leaf; diff --git a/lib/src/widgets/toolbar/buttons/link_style2.dart b/lib/src/widgets/toolbar/buttons/link_style2.dart index 57e0bcf1..751c860b 100644 --- a/lib/src/widgets/toolbar/buttons/link_style2.dart +++ b/lib/src/widgets/toolbar/buttons/link_style2.dart @@ -448,7 +448,7 @@ class QuillTextLink { controller.getSelectionStyle().attributes[Attribute.link.key]?.value; final index = controller.selection.start; - var text; + String? text; if (link != null) { // text should be the link's corresponding text, not selection final leaf = controller.document.querySegmentLeafNode(index).leaf; diff --git a/lib/src/widgets/toolbar/buttons/quill_icon.dart b/lib/src/widgets/toolbar/buttons/quill_icon.dart index 0ac6e8f9..37e5b81a 100644 --- a/lib/src/widgets/toolbar/buttons/quill_icon.dart +++ b/lib/src/widgets/toolbar/buttons/quill_icon.dart @@ -13,8 +13,8 @@ class QuillToolbarIconButton extends StatelessWidget { this.highlightElevation = 1, this.borderRadius = 2, this.tooltip, - Key? key, - }) : super(key: key); + super.key, + }); final VoidCallback? onPressed; final VoidCallback? afterPressed; diff --git a/lib/src/widgets/toolbar/buttons/search/search_dialog.dart b/lib/src/widgets/toolbar/buttons/search/search_dialog.dart index dc279ab4..1ff4c856 100644 --- a/lib/src/widgets/toolbar/buttons/search/search_dialog.dart +++ b/lib/src/widgets/toolbar/buttons/search/search_dialog.dart @@ -52,11 +52,11 @@ class QuillToolbarSearchDialog extends StatefulWidget { final QuillToolbarSearchDialogChildBuilder? childBuilder; @override - _QuillToolbarSearchDialogState createState() => - _QuillToolbarSearchDialogState(); + QuillToolbarSearchDialogState createState() => + QuillToolbarSearchDialogState(); } -class _QuillToolbarSearchDialogState extends State { +class QuillToolbarSearchDialogState extends State { late String _text; late TextEditingController _controller; late List? _offsets; @@ -217,7 +217,7 @@ class _QuillToolbarSearchDialogState extends State { baseOffset: _offsets![_index], extentOffset: _offsets![_index] + _text.length, ), - ChangeSource.LOCAL, + ChangeSource.local, ); } diff --git a/lib/src/widgets/toolbar/buttons/select_alignment.dart b/lib/src/widgets/toolbar/buttons/select_alignment.dart index 9ee36622..fac78d85 100644 --- a/lib/src/widgets/toolbar/buttons/select_alignment.dart +++ b/lib/src/widgets/toolbar/buttons/select_alignment.dart @@ -32,11 +32,11 @@ class QuillToolbarSelectAlignmentButton extends StatefulWidget { final EdgeInsetsGeometry? padding; @override - _QuillToolbarSelectAlignmentButtonState createState() => - _QuillToolbarSelectAlignmentButtonState(); + QuillToolbarSelectAlignmentButtonState createState() => + QuillToolbarSelectAlignmentButtonState(); } -class _QuillToolbarSelectAlignmentButtonState +class QuillToolbarSelectAlignmentButtonState extends State { Attribute? _value; @@ -149,7 +149,7 @@ class _QuillToolbarSelectAlignmentButtonState @override Widget build(BuildContext context) { - final _valueToText = { + final valueToText = { if (widget.showLeftAlignment!) Attribute.leftAlignment: Attribute.leftAlignment.value!, if (widget.showCenterAlignment!) @@ -160,13 +160,13 @@ class _QuillToolbarSelectAlignmentButtonState Attribute.justifyAlignment: Attribute.justifyAlignment.value!, }; - final _valueAttribute = [ + final valueAttribute = [ if (widget.showLeftAlignment!) Attribute.leftAlignment, if (widget.showCenterAlignment!) Attribute.centerAlignment, if (widget.showRightAlignment!) Attribute.rightAlignment, if (widget.showJustifyAlignment!) Attribute.justifyAlignment ]; - final _valueString = [ + final valueString = [ if (widget.showLeftAlignment!) Attribute.leftAlignment.value!, if (widget.showCenterAlignment!) Attribute.centerAlignment.value!, if (widget.showRightAlignment!) Attribute.rightAlignment.value!, @@ -191,12 +191,12 @@ class _QuillToolbarSelectAlignmentButtonState final childBuilder = options.childBuilder ?? baseButtonExtraOptions.childBuilder; - void _sharedOnPressed(int index) { - _valueAttribute[index] == Attribute.leftAlignment + void sharedOnPressed(int index) { + valueAttribute[index] == Attribute.leftAlignment ? controller.formatSelection( Attribute.clone(Attribute.align, null), ) - : controller.formatSelection(_valueAttribute[index]); + : controller.formatSelection(valueAttribute[index]); _afterButtonPressed?.call(); } @@ -215,7 +215,7 @@ class _QuillToolbarSelectAlignmentButtonState QuillToolbarSelectAlignmentButtonExtraOptions( context: context, controller: controller, - onPressed: () => _sharedOnPressed(index), + onPressed: () => sharedOnPressed(index), ), ); } @@ -229,11 +229,11 @@ class _QuillToolbarSelectAlignmentButtonState height: _iconSize * kIconButtonFactor, ), child: UtilityWidgets.maybeTooltip( - message: _valueString[index] == Attribute.leftAlignment.value + message: valueString[index] == Attribute.leftAlignment.value ? _tooltips.leftAlignment - : _valueString[index] == Attribute.centerAlignment.value + : valueString[index] == Attribute.centerAlignment.value ? _tooltips.centerAlignment - : _valueString[index] == Attribute.rightAlignment.value + : valueString[index] == Attribute.rightAlignment.value ? _tooltips.rightAlignment : _tooltips.justifyAlignment, child: RawMaterialButton( @@ -244,22 +244,21 @@ class _QuillToolbarSelectAlignmentButtonState shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(_iconTheme?.borderRadius ?? 2)), - fillColor: _valueToText[_value] == _valueString[index] + fillColor: valueToText[_value] == valueString[index] ? (_iconTheme?.iconSelectedFillColor ?? theme.primaryColor) : (_iconTheme?.iconUnselectedFillColor ?? theme.canvasColor), - onPressed: () => _sharedOnPressed(index), + onPressed: () => sharedOnPressed(index), child: Icon( - _valueString[index] == Attribute.leftAlignment.value + valueString[index] == Attribute.leftAlignment.value ? _iconsData.leftAlignment - : _valueString[index] == Attribute.centerAlignment.value + : valueString[index] == Attribute.centerAlignment.value ? _iconsData.centerAlignment - : _valueString[index] == - Attribute.rightAlignment.value + : valueString[index] == Attribute.rightAlignment.value ? _iconsData.rightAlignment : _iconsData.justifyAlignment, size: _iconSize, - color: _valueToText[_value] == _valueString[index] + color: valueToText[_value] == valueString[index] ? (_iconTheme?.iconSelectedColor ?? theme.primaryIconTheme.color) : (_iconTheme?.iconUnselectedColor ?? diff --git a/lib/src/widgets/toolbar/buttons/select_header_style.dart b/lib/src/widgets/toolbar/buttons/select_header_style.dart index 987f9f3e..15a05597 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style.dart @@ -21,11 +21,11 @@ class QuillToolbarSelectHeaderStyleButtons extends StatefulWidget { final QuillToolbarSelectHeaderStyleButtonsOptions options; @override - _QuillToolbarSelectHeaderStyleButtonsState createState() => - _QuillToolbarSelectHeaderStyleButtonsState(); + QuillToolbarSelectHeaderStyleButtonsState createState() => + QuillToolbarSelectHeaderStyleButtonsState(); } -class _QuillToolbarSelectHeaderStyleButtonsState +class QuillToolbarSelectHeaderStyleButtonsState extends State { Attribute? _selectedAttribute; @@ -85,9 +85,9 @@ class _QuillToolbarSelectHeaderStyleButtonsState } void _sharedOnPressed(Attribute attribute) { - final _attribute = + final attribute0 = _selectedAttribute == attribute ? Attribute.header : attribute; - controller.formatSelection(_attribute); + controller.formatSelection(attribute0); afterButtonPressed?.call(); } diff --git a/lib/src/widgets/toolbar/buttons/toggle_check_list.dart b/lib/src/widgets/toolbar/buttons/toggle_check_list.dart index 189b9a30..b30a2243 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_check_list.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_check_list.dart @@ -23,11 +23,11 @@ class QuillToolbarToggleCheckListButton extends StatefulWidget { final QuillController controller; @override - _QuillToolbarToggleCheckListButtonState createState() => - _QuillToolbarToggleCheckListButtonState(); + QuillToolbarToggleCheckListButtonState createState() => + QuillToolbarToggleCheckListButtonState(); } -class _QuillToolbarToggleCheckListButtonState +class QuillToolbarToggleCheckListButtonState extends State { bool? _isToggled; diff --git a/lib/src/widgets/toolbar/buttons/toggle_style.dart b/lib/src/widgets/toolbar/buttons/toggle_style.dart index 38b8bc6b..04a27c03 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style.dart @@ -36,11 +36,11 @@ class QuillToolbarToggleStyleButton extends StatefulWidget { final QuillController controller; @override - _QuillToolbarToggleStyleButtonState createState() => - _QuillToolbarToggleStyleButtonState(); + QuillToolbarToggleStyleButtonState createState() => + QuillToolbarToggleStyleButtonState(); } -class _QuillToolbarToggleStyleButtonState +class QuillToolbarToggleStyleButtonState extends State { bool? _isToggled; diff --git a/pubspec.yaml b/pubspec.yaml index 4eae9614..5be31f2b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.1.10 +version: 8.1.11 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill @@ -42,12 +42,10 @@ dependencies: flutter_keyboard_visibility: ^5.4.1 quiver: ^3.2.1 url_launcher: ^6.1.14 - pedantic: ^1.11.1 characters: ^1.3.0 diff_match_patch: ^0.4.1 i18n_extension: ^9.0.2 device_info_plus: ^9.1.0 - platform: ^3.1.0 pasteboard: ^0.2.0 equatable: ^2.0.5 flutter_animate: ^4.2.0+1 @@ -56,4 +54,7 @@ dependencies: sdk: flutter meta: ^1.9.1 -flutter: null \ No newline at end of file +flutter: + uses-material-design: true +dev_dependencies: + lints: ^3.0.0 \ No newline at end of file diff --git a/test/widgets/controller_test.dart b/test/widgets/controller_test.dart index e2405d4b..3decfc47 100644 --- a/test/widgets/controller_test.dart +++ b/test/widgets/controller_test.dart @@ -9,7 +9,7 @@ void main() { setUp(() { controller = QuillController.basic() ..compose(Delta()..insert(testDocumentContents), - const TextSelection.collapsed(offset: 0), ChangeSource.LOCAL); + const TextSelection.collapsed(offset: 0), ChangeSource.local); }); group('controller', () { @@ -31,7 +31,7 @@ void main() { controller ..formatText(0, 5, Attribute.h1) ..updateSelection(const TextSelection(baseOffset: 0, extentOffset: 4), - ChangeSource.LOCAL); + ChangeSource.local); expect(controller.getSelectionStyle().values, [Attribute.h1]); }); @@ -41,7 +41,7 @@ void main() { // With selection range controller ..updateSelection(const TextSelection(baseOffset: 0, extentOffset: 4), - ChangeSource.LOCAL) + ChangeSource.local) ..addListener(() { listenerCalled = true; }) @@ -58,12 +58,12 @@ void main() { // With collapsed selection controller ..updateSelection( - const TextSelection.collapsed(offset: 0), ChangeSource.LOCAL) + const TextSelection.collapsed(offset: 0), ChangeSource.local) ..indentSelection(true); expect(controller.getSelectionStyle().values, [Attribute.indentL1]); controller ..updateSelection( - const TextSelection.collapsed(offset: 0), ChangeSource.LOCAL) + const TextSelection.collapsed(offset: 0), ChangeSource.local) ..indentSelection(true); expect(controller.getSelectionStyle().values, [Attribute.indentL2]); controller.indentSelection(false); @@ -75,17 +75,17 @@ void main() { test('indentSelection with multiline document', () { controller ..compose(Delta()..insert('line1\nline2\nline3\n'), - const TextSelection.collapsed(offset: 0), ChangeSource.LOCAL) + const TextSelection.collapsed(offset: 0), ChangeSource.local) // Indent first line ..updateSelection( - const TextSelection.collapsed(offset: 0), ChangeSource.LOCAL) + const TextSelection.collapsed(offset: 0), ChangeSource.local) ..indentSelection(true); expect(controller.getSelectionStyle().values, [Attribute.indentL1]); // Indent first two lines controller ..updateSelection(const TextSelection(baseOffset: 0, extentOffset: 11), - ChangeSource.LOCAL) + ChangeSource.local) ..indentSelection(true); // Should have both L1 and L2 indent attributes in selection. @@ -101,7 +101,7 @@ void main() { TextSelection( baseOffset: 12, extentOffset: controller.document.toPlainText().length - 1), - ChangeSource.LOCAL); + ChangeSource.local); expect(controller.getAllSelectionStyles(), everyElement(const Style())); }); @@ -110,7 +110,7 @@ void main() { ..formatText(0, 2, Attribute.bold) ..replaceText(2, 2, BlockEmbed.image('/test'), null) ..updateSelection(const TextSelection(baseOffset: 0, extentOffset: 4), - ChangeSource.REMOTE); + ChangeSource.remote); final result = controller.getAllIndividualSelectionStylesAndEmbed(); expect(result.length, 2); expect(result[0].offset, 0); @@ -121,7 +121,7 @@ void main() { test('getPlainText', () { controller.updateSelection( const TextSelection(baseOffset: 0, extentOffset: 4), - ChangeSource.LOCAL); + ChangeSource.local); expect(controller.getPlainText(), testDocumentContents); }); @@ -135,7 +135,7 @@ void main() { test('undo', () { var listenerCalled = false; controller.updateSelection( - const TextSelection.collapsed(offset: 4), ChangeSource.LOCAL); + const TextSelection.collapsed(offset: 4), ChangeSource.local); expect( controller.document.toDelta(), @@ -153,7 +153,7 @@ void main() { test('redo', () { var listenerCalled = false; controller.updateSelection( - const TextSelection.collapsed(offset: 4), ChangeSource.LOCAL); + const TextSelection.collapsed(offset: 4), ChangeSource.local); expect(controller.document.toDelta(), Delta()..insert('data\n')); controller.undo(); @@ -222,7 +222,7 @@ void main() { var listenerCalled = false; controller ..updateSelection(const TextSelection(baseOffset: 0, extentOffset: 2), - ChangeSource.LOCAL) + ChangeSource.local) ..addListener(() { listenerCalled = true; }) @@ -238,7 +238,7 @@ void main() { var listenerCalled = false; controller ..updateSelection( - const TextSelection.collapsed(offset: 4), ChangeSource.LOCAL) + const TextSelection.collapsed(offset: 4), ChangeSource.local) ..addListener(() { listenerCalled = true; }); @@ -281,7 +281,7 @@ void main() { ..addListener(() { listenerCalled = true; }) - ..updateSelection(selection, ChangeSource.LOCAL); + ..updateSelection(selection, ChangeSource.local); expect(listenerCalled, isTrue); expect(controller.selection, selection); @@ -295,7 +295,7 @@ void main() { listenerCalled = true; }) ..compose(Delta()..insert('test '), - const TextSelection.collapsed(offset: 0), ChangeSource.LOCAL); + const TextSelection.collapsed(offset: 0), ChangeSource.local); expect(listenerCalled, isTrue); expect(controller.document.toDelta(), From 69c8b22e9422dd408b807489fe0ff3a1dfcce64a Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 03:59:34 +0300 Subject: [PATCH 020/210] Fix Text direction default iconData and tooltip --- example/lib/pages/home_page.dart | 13 ++- .../widgets/toolbar/buttons/toggle_style.dart | 108 +++++++++--------- 2 files changed, 63 insertions(+), 58 deletions(-) diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 288e9595..34567dbb 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -102,10 +102,14 @@ class _HomePageState extends State { onPressed: () => showDialog( context: context, builder: (context) => AlertDialog( - content: Text(_controller.document.toPlainText([ - ...FlutterQuillEmbeds.editorBuilders(), - TimeStampEmbedBuilderWidget() - ])), + content: Text( + _controller.document.toPlainText( + [ + ...FlutterQuillEmbeds.editorBuilders(), + TimeStampEmbedBuilderWidget() + ], + ), + ), ), ), icon: const Icon(Icons.text_fields_rounded), @@ -286,6 +290,7 @@ class _HomePageState extends State { if (_isDesktop()) { return QuillToolbar( configurations: QuillToolbarConfigurations( + showDirection: true, embedButtons: FlutterQuillEmbeds.toolbarButtons( imageButtonOptions: QuillToolbarImageButtonOptions( onImagePickCallback: _onImagePickCallback, diff --git a/lib/src/widgets/toolbar/buttons/toggle_style.dart b/lib/src/widgets/toolbar/buttons/toggle_style.dart index 04a27c03..d228c680 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style.dart @@ -78,36 +78,36 @@ class QuillToolbarToggleStyleButtonState context.requireQuillToolbarBaseButtonOptions.iconTheme; } - String? get _defaultTooltip { + (String?, IconData) get _defaultTooltipAndIconData { switch (widget.attribute.key) { case 'bold': - return 'Bold'.i18n; + return ('Bold'.i18n, Icons.format_bold); case 'script': if (widget.attribute.value == ScriptAttributes.sub.value) { - return 'Subscript'.i18n; + return ('Subscript'.i18n, Icons.subscript); } - return 'Superscript'.i18n; + return ('Superscript'.i18n, Icons.superscript); case 'italic': - return 'Italic'.i18n; + return ('Italic'.i18n, Icons.format_italic); case 'small': - return 'Small'.i18n; + return ('Small'.i18n, Icons.format_size); case 'underline': - return 'Underline'.i18n; + return ('Underline'.i18n, Icons.format_underline); case 'strike': - return 'Strike through'.i18n; + return ('Strike through'.i18n, Icons.format_strikethrough); case 'code': - return 'Inline code'.i18n; - case 'rtl': - return 'Text direction'.i18n; + return ('Inline code'.i18n, Icons.code); + case 'direction': + return ('Text direction'.i18n, Icons.format_textdirection_r_to_l); case 'list': if (widget.attribute.value == 'bullet') { - return 'Bullet list'.i18n; + return ('Bullet list'.i18n, Icons.format_list_bulleted); } - return 'Numbered list'.i18n; + return ('Numbered list'.i18n, Icons.format_list_numbered); case 'code-block': - return 'Code block'.i18n; + return ('Code block'.i18n, Icons.code); case 'blockquote': - return 'Quote'.i18n; + return ('Quote'.i18n, Icons.format_quote); default: throw ArgumentError( 'Could not find the default tooltip for ' @@ -116,53 +116,53 @@ class QuillToolbarToggleStyleButtonState } } + // IconData get _defaultIconData { + // switch (widget.attribute.key) { + // case 'bold': + // return Icons.format_bold; + // case 'script': + // if (widget.attribute.value == ScriptAttributes.sub.value) { + // return Icons.subscript; + // } + // return Icons.superscript; + // case 'italic': + // return Icons.format_italic; + // case 'small': + // return Icons.format_size; + // case 'underline': + // return Icons.format_underline; + // case 'strike': + // return Icons.format_strikethrough; + // case 'code': + // return Icons.code; + // case 'rtl': + // return Icons.format_textdirection_r_to_l; + // case 'list': + // if (widget.attribute.value == 'bullet') { + // return Icons.format_list_bulleted; + // } + // return Icons.format_list_numbered; + // case 'code-block': + // return Icons.code; + // case 'blockquote': + // return Icons.format_quote; + // default: + // throw ArgumentError( + // 'Could not find the icon for ${widget.attribute.toString()}', + // ); + // } + // } + String? get tooltip { return options.tooltip ?? context.requireQuillToolbarBaseButtonOptions.tooltip ?? - _defaultTooltip; - } - - IconData get _defaultIconData { - switch (widget.attribute.key) { - case 'bold': - return Icons.format_bold; - case 'script': - if (widget.attribute.value == ScriptAttributes.sub.value) { - return Icons.subscript; - } - return Icons.superscript; - case 'italic': - return Icons.format_italic; - case 'small': - return Icons.format_size; - case 'underline': - return Icons.format_underline; - case 'strike': - return Icons.format_strikethrough; - case 'code': - return Icons.code; - case 'rtl': - return Icons.format_textdirection_r_to_l; - case 'list': - if (widget.attribute.value == 'bullet') { - return Icons.format_list_bulleted; - } - return Icons.format_list_numbered; - case 'code-block': - return Icons.code; - case 'blockquote': - return Icons.format_quote; - default: - throw ArgumentError( - 'Could not find the icon for ${widget.attribute.toString()}', - ); - } + _defaultTooltipAndIconData.$1; } IconData get iconData { return options.iconData ?? context.requireQuillToolbarBaseButtonOptions.iconData ?? - _defaultIconData; + _defaultTooltipAndIconData.$2; } void _onPressed() { From 029367361324daeaae9a1cc19a6491eed3a7aa07 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 04:00:18 +0300 Subject: [PATCH 021/210] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 430f82ad..0e9b9e55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## [8.1.11] - Follow dart best practices by using `lints` and remove `pedantic` as well `platform` since they are not used +- Fix text direction bug ## [8.1.10] - Secret for automated publishing to pub.dev. From 75ebd0585870313e56c876e9c1e8ad192723a650 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 04:01:25 +0300 Subject: [PATCH 022/210] Remove unused comments --- .../widgets/toolbar/buttons/toggle_style.dart | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/lib/src/widgets/toolbar/buttons/toggle_style.dart b/lib/src/widgets/toolbar/buttons/toggle_style.dart index d228c680..439df53b 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style.dart @@ -116,43 +116,6 @@ class QuillToolbarToggleStyleButtonState } } - // IconData get _defaultIconData { - // switch (widget.attribute.key) { - // case 'bold': - // return Icons.format_bold; - // case 'script': - // if (widget.attribute.value == ScriptAttributes.sub.value) { - // return Icons.subscript; - // } - // return Icons.superscript; - // case 'italic': - // return Icons.format_italic; - // case 'small': - // return Icons.format_size; - // case 'underline': - // return Icons.format_underline; - // case 'strike': - // return Icons.format_strikethrough; - // case 'code': - // return Icons.code; - // case 'rtl': - // return Icons.format_textdirection_r_to_l; - // case 'list': - // if (widget.attribute.value == 'bullet') { - // return Icons.format_list_bulleted; - // } - // return Icons.format_list_numbered; - // case 'code-block': - // return Icons.code; - // case 'blockquote': - // return Icons.format_quote; - // default: - // throw ArgumentError( - // 'Could not find the icon for ${widget.attribute.toString()}', - // ); - // } - // } - String? get tooltip { return options.tooltip ?? context.requireQuillToolbarBaseButtonOptions.tooltip ?? From f6bea337207d1c5fe12a4eb55917dc2ba429e17b Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 04:20:29 +0300 Subject: [PATCH 023/210] Update README.md --- README.md | 44 ++++++-------------------------------------- 1 file changed, 6 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 1bd119d8..3356a40e 100644 --- a/README.md +++ b/README.md @@ -56,20 +56,6 @@ Pub: [FlutterQuill] - [License](#license) - [Contributors](#contributors) - - ## Installation ```yaml @@ -85,13 +71,10 @@ dependencies: git: https://github.com/singerdmx/flutter-quill.git ``` -> **Important note** -> -> Currently, we're in the process of refactoring the library's configurations. We're actively working on this, and while we don't have a development version available at the moment, your feedback is essential to us. > > Using the latest version and reporting any issues you encounter on GitHub will greatly contribute to the improvement of the library. Your input and insights are valuable in shaping a stable and reliable version for all our users. Thank you for being part of the open-source community! > -> also [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) will not work with the latest versions, please use [fresh_quill_extensions](https://pub.dev/packages/fresh_quill_extensions) as temporary alternative +> Please use the latest pre-release of [FlutterQuill Extensions] in order to work with the latest stable version of [FlutterQuill] > ## Usage @@ -192,7 +175,7 @@ localizationsDelegates: const [ ], ``` -And you might need more depending on your use case, for example if you are using custom localizations for your app, using custom app widget like [FluentApp](https://pub.dev/packages/fluent_ui) +And you might need more depending on your use case, for example if you are using custom localizations for your app, using custom app widget like `FluentApp` from [FluentUI] which will also need ```dart @@ -205,6 +188,8 @@ localizationsDelegates: const [ in addition to the required delegates by this library +Note: In the latest versions of `FluentApp` you no longer need to add the `localizationsDelegates` but this is just an example, for more [info](https://github.com/bdlukaa/fluent_ui/pull/946) + ### Font Size Within the editor toolbar, a drop-down with font-sizing capabilities is available. This can be enabled or disabled with `showFontSize`. @@ -307,25 +292,6 @@ Expanded( ) ``` - - - ### Custom Size Image for Mobile Define `mobileWidth`, `mobileHeight`, `mobileMargin`, `mobileAlignment` as follows: @@ -737,11 +703,13 @@ Made with [contrib.rocks](https://contrib.rocks). [Quill]: https://quilljs.com/docs/formats [Flutter]: https://github.com/flutter/flutter [FlutterQuill]: https://pub.dev/packages/flutter_quill +[FlutterQuill Extensions]: https://pub.dev/packages/flutter_quill_extensions [ReactQuill]: https://github.com/zenoamaro/react-quill [Youtube Playlist]: https://youtube.com/playlist?list=PLbhaS_83B97vONkOAWGJrSXWX58et9zZ2 [Slack Group]: https://join.slack.com/t/bulletjournal1024/shared_invite/zt-fys7t9hi-ITVU5PGDen1rNRyCjdcQ2g [Sample Page]: https://github.com/singerdmx/flutter-quill/blob/master/example/lib/pages/home_page.dart [Code Introduction]: https://github.com/singerdmx/flutter-quill/blob/master/doc/CodeIntroduction.md +[FluentUI]: https://pub.dev/packages/fluent_ui
    From 9b6a298e2ccf311aff2c44088930eea3d6434bed Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 04:29:49 +0300 Subject: [PATCH 024/210] Remove empty FETCH_HEAD file --- FETCH_HEAD | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 FETCH_HEAD diff --git a/FETCH_HEAD b/FETCH_HEAD deleted file mode 100644 index e69de29b..00000000 From 503849fe939fb474e4fe786e9bfcf88522f1bf70 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 04:35:03 +0300 Subject: [PATCH 025/210] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e9b9e55..68f121a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## [8.1.11] - Follow dart best practices by using `lints` and remove `pedantic` as well `platform` since they are not used - Fix text direction bug +- Update `README.md` ## [8.1.10] - Secret for automated publishing to pub.dev. From 0967c8cabf6caa972759a4fb1e88a57cbb866bc2 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 17:06:17 +0300 Subject: [PATCH 026/210] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 498b3e0a..aaec6d89 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 Xin Yao +Copyright (c) 2023 Xin Yao Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From e2cfa1d453893fc874d04ec875ec1c4529e5bf34 Mon Sep 17 00:00:00 2001 From: X Code Date: Sun, 5 Nov 2023 10:38:30 -0800 Subject: [PATCH 027/210] Update publish.yml --- .github/workflows/publish.yml | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index bf4a66bc..ac60cf6b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,29 +3,19 @@ name: Publish to pub.dev on: push: tags: - - 'v[0-9]+.[0-9]+.[0-9]+*' # Trigger this action when a version tag is pushed + - 'v[0-9]+.[0-9]+.[0-9]+*' # tag pattern on pub.dev: 'v' jobs: publish: - runs-on: ubuntu-latest permissions: - contents: read - id-token: write - packages: write + id-token: write # Required for authentication using OIDC + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - - name: Setup Flutter environment - uses: subosito/flutter-action@v1 - with: - flutter-version: '3.13.9' - - - name: Disable Flutter telemetry - run: flutter --disable-telemetry - - - name: Publish to pub.dev - env: - PUB_ACCESS_TOKEN: ${{ secrets.PUB_ACCESS_TOKEN }} - run: | - echo 'PUB_ACCESS_TOKEN=$PUB_ACCESS_TOKEN' > $HOME/.pub-cache/credentials.json - flutter pub publish --force + - uses: actions/checkout@v3 + - uses: dart-lang/setup-dart@v1 + - name: Install dependencies + run: dart pub get + # Here you can insert custom steps you need + # - run: dart tool/generate-code.dart + - name: Publish + run: dart pub publish --force From 11dd8e7d39cf4b7eb52d08fdd58c84a2e4d09a05 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 20:00:53 +0300 Subject: [PATCH 028/210] Step one --- .../lib/flutter_quill_extensions.dart | 21 +- .../lib/logic/extensions/controller.dart | 2 +- .../logic/models/config/configurations.dart | 51 +++ .../services/image_picker/image_options.dart | 20 ++ .../services/image_picker/image_picker.dart | 30 ++ .../image_picker/packages/image_picker.dart | 80 +++++ .../services/image_picker/s_image_picker.dart | 60 ++++ .../{ => image_saver}/exceptions.dart | 0 .../{ => image_saver}/image_saver.dart | 0 .../{ => image_saver}/packages/gal.dart | 0 .../services/image_saver/s_image_saver.dart | 30 ++ .../lib/logic/services/s_image_saver.dart | 33 -- .../embeds/editor/image/image.dart | 8 +- .../lib/presentation/embeds/embed_types.dart | 16 +- .../embeds/embed_types/image.dart | 42 +++ .../embeds/toolbar/camera_button.dart | 14 +- .../{ => image_button}/image_button.dart | 99 +++--- .../image_button/select_image_source.dart | 57 ++++ .../toolbar/utils/image_video_utils.dart | 303 +++++++++--------- .../embeds/toolbar/video_button.dart | 2 +- .../lib/presentation/embeds/utils.dart | 16 +- .../models/config/editor/image.dart | 36 ++- .../models/config/toolbar/buttons/camera.dart | 15 +- .../models/config/toolbar/buttons/image.dart | 34 +- .../config/toolbar/buttons/media_button.dart | 2 - .../models/config/toolbar/buttons/video.dart | 2 - flutter_quill_extensions/pubspec.yaml | 7 +- 27 files changed, 661 insertions(+), 319 deletions(-) create mode 100644 flutter_quill_extensions/lib/logic/models/config/configurations.dart create mode 100644 flutter_quill_extensions/lib/logic/services/image_picker/image_options.dart create mode 100644 flutter_quill_extensions/lib/logic/services/image_picker/image_picker.dart create mode 100644 flutter_quill_extensions/lib/logic/services/image_picker/packages/image_picker.dart create mode 100644 flutter_quill_extensions/lib/logic/services/image_picker/s_image_picker.dart rename flutter_quill_extensions/lib/logic/services/{ => image_saver}/exceptions.dart (100%) rename flutter_quill_extensions/lib/logic/services/{ => image_saver}/image_saver.dart (100%) rename flutter_quill_extensions/lib/logic/services/{ => image_saver}/packages/gal.dart (100%) create mode 100644 flutter_quill_extensions/lib/logic/services/image_saver/s_image_saver.dart delete mode 100644 flutter_quill_extensions/lib/logic/services/s_image_saver.dart create mode 100644 flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart rename flutter_quill_extensions/lib/presentation/embeds/toolbar/{ => image_button}/image_button.dart (62%) create mode 100644 flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index efc3a6ab..78e1bc77 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -4,13 +4,14 @@ import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter_quill/flutter_quill.dart'; import 'package:meta/meta.dart' show immutable; +import 'logic/models/config/configurations.dart'; import 'presentation/embeds/editor/image/image.dart'; import 'presentation/embeds/editor/image/image_web.dart'; import 'presentation/embeds/editor/video.dart'; import 'presentation/embeds/editor/webview.dart'; import 'presentation/embeds/toolbar/camera_button.dart'; import 'presentation/embeds/toolbar/formula_button.dart'; -import 'presentation/embeds/toolbar/image_button.dart'; +import 'presentation/embeds/toolbar/image_button/image_button.dart'; import 'presentation/embeds/toolbar/media_button.dart'; import 'presentation/embeds/toolbar/video_button.dart'; import 'presentation/models/config/editor/image.dart'; @@ -28,7 +29,7 @@ export 'presentation/embeds/editor/unknown.dart'; export 'presentation/embeds/embed_types.dart'; export 'presentation/embeds/toolbar/camera_button.dart'; export 'presentation/embeds/toolbar/formula_button.dart'; -export 'presentation/embeds/toolbar/image_button.dart'; +export 'presentation/embeds/toolbar/image_button/image_button.dart'; export 'presentation/embeds/toolbar/media_button.dart'; export 'presentation/embeds/toolbar/utils/image_video_utils.dart'; export 'presentation/embeds/toolbar/video_button.dart'; @@ -83,19 +84,7 @@ class FlutterQuillEmbeds { return [ if (imageEmbedConfigurations != null) QuillEditorImageEmbedBuilder( - configurations: QuillEditorImageEmbedConfigurations( - imageErrorWidgetBuilder: - imageEmbedConfigurations.imageErrorWidgetBuilder, - imageProviderBuilder: imageEmbedConfigurations.imageProviderBuilder, - forceUseMobileOptionMenuForImageClick: - imageEmbedConfigurations.forceUseMobileOptionMenuForImageClick, - onImageRemovedCallback: - imageEmbedConfigurations.onImageRemovedCallback ?? - QuillEditorImageEmbedConfigurations - .defaultOnImageRemovedCallback, - shouldRemoveImageCallback: - imageEmbedConfigurations.shouldRemoveImageCallback, - ), + configurations: imageEmbedConfigurations, ), if (videoEmbedConfigurations != null) QuillEditorVideoEmbedBuilder( @@ -115,6 +104,8 @@ class FlutterQuillEmbeds { /// images on the web. /// static List editorsWebBuilders({ + QuillSharedExtensionsConfigurations sharedExtensionsConfigurations = + const QuillSharedExtensionsConfigurations(), QuillEditorWebImageEmbedConfigurations? imageEmbedConfigurations = const QuillEditorWebImageEmbedConfigurations(), }) { diff --git a/flutter_quill_extensions/lib/logic/extensions/controller.dart b/flutter_quill_extensions/lib/logic/extensions/controller.dart index 3fe39ac2..856b87b7 100644 --- a/flutter_quill_extensions/lib/logic/extensions/controller.dart +++ b/flutter_quill_extensions/lib/logic/extensions/controller.dart @@ -28,7 +28,7 @@ extension QuillControllerExt on QuillController { required String imageUrl, }) { this - ..skipRequestKeyboard = true + ..skipRequestKeyboard = skipRequestKeyboard ..replaceText( index, length, diff --git a/flutter_quill_extensions/lib/logic/models/config/configurations.dart b/flutter_quill_extensions/lib/logic/models/config/configurations.dart new file mode 100644 index 00000000..307be978 --- /dev/null +++ b/flutter_quill_extensions/lib/logic/models/config/configurations.dart @@ -0,0 +1,51 @@ +import 'package:flutter/widgets.dart' show BuildContext; +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:meta/meta.dart' show immutable; + +import '../../services/image_picker/s_image_picker.dart'; +import '../../services/image_saver/s_image_saver.dart'; + +@immutable +class QuillSharedExtensionsConfigurations { + const QuillSharedExtensionsConfigurations({ + ImagePickerService? imagePickerService, + ImageSaverService? imageSaverService, + }) : _imagePickerService = imagePickerService, + _imageSaverService = imageSaverService; + + /// Get the instance from the widget tree in [QuillSharedConfigurations] + /// if it doesn't exists, we will create new one with default options + factory QuillSharedExtensionsConfigurations.get({ + required BuildContext context, + }) { + final quillSharedExtensionsConfigurations = + context.requireQuillSharedConfigurations.extraConfigurations[key]; + if (quillSharedExtensionsConfigurations != null) { + if (quillSharedExtensionsConfigurations + is! QuillSharedExtensionsConfigurations) { + throw ArgumentError( + 'The value of key `$key` should be of type ' + 'QuillSharedExtensionsConfigurations', + ); + } + return quillSharedExtensionsConfigurations; + } + return const QuillSharedExtensionsConfigurations(); + } + + static const String key = 'quillSharedExtensionsConfigurations'; + + /// Default to [ImagePickerService.defaultImpl] + final ImagePickerService? _imagePickerService; + + ImagePickerService get imagePickerService { + return _imagePickerService ?? ImagePickerService.defaultImpl(); + } + + /// Default to [ImageSaverService.defaultImpl] + final ImageSaverService? _imageSaverService; + + ImageSaverService get imageSaverService { + return _imageSaverService ?? ImageSaverService.defaultImpl(); + } +} diff --git a/flutter_quill_extensions/lib/logic/services/image_picker/image_options.dart b/flutter_quill_extensions/lib/logic/services/image_picker/image_options.dart new file mode 100644 index 00000000..acecbacf --- /dev/null +++ b/flutter_quill_extensions/lib/logic/services/image_picker/image_options.dart @@ -0,0 +1,20 @@ +/// Specifies the source where the picked image should come from. +enum ImageSource { + /// Opens up the device camera, letting the user to take a new picture. + camera, + + /// Opens the user's photo gallery. + gallery, +} + +enum CameraDevice { + /// Use the rear camera. + /// + /// In most of the cases, it is the default configuration. + rear, + + /// Use the front camera. + /// + /// Supported on all iPhones/iPads and some Android devices. + front, +} diff --git a/flutter_quill_extensions/lib/logic/services/image_picker/image_picker.dart b/flutter_quill_extensions/lib/logic/services/image_picker/image_picker.dart new file mode 100644 index 00000000..b79d816a --- /dev/null +++ b/flutter_quill_extensions/lib/logic/services/image_picker/image_picker.dart @@ -0,0 +1,30 @@ +import 'package:cross_file/cross_file.dart' show XFile; + +import 'image_options.dart'; + +export 'package:cross_file/cross_file.dart' show XFile; + +export 'image_options.dart'; + +abstract class ImagePickerInterface { + const ImagePickerInterface(); + Future pickImage({ + required ImageSource source, + double? maxWidth, + double? maxHeight, + int? imageQuality, + CameraDevice preferredCameraDevice = CameraDevice.rear, + bool requestFullMetadata = true, + }); + Future pickMedia({ + double? maxWidth, + double? maxHeight, + int? imageQuality, + bool requestFullMetadata = true, + }); + Future pickVideo({ + required ImageSource source, + CameraDevice preferredCameraDevice = CameraDevice.rear, + Duration? maxDuration, + }); +} diff --git a/flutter_quill_extensions/lib/logic/services/image_picker/packages/image_picker.dart b/flutter_quill_extensions/lib/logic/services/image_picker/packages/image_picker.dart new file mode 100644 index 00000000..e009648d --- /dev/null +++ b/flutter_quill_extensions/lib/logic/services/image_picker/packages/image_picker.dart @@ -0,0 +1,80 @@ +import 'package:image_picker/image_picker.dart' as package + show ImagePicker, ImageSource, CameraDevice; + +import '../image_picker.dart'; + +class ImagePickerPackageImpl extends ImagePickerInterface { + const ImagePickerPackageImpl(); + package.ImagePicker get _picker { + return package.ImagePicker(); + } + + @override + Future pickImage({ + required ImageSource source, + double? maxWidth, + double? maxHeight, + int? imageQuality, + CameraDevice preferredCameraDevice = CameraDevice.rear, + bool requestFullMetadata = true, + }) { + return _picker.pickImage( + source: source.toImagePickerPackage(), + maxWidth: maxWidth, + maxHeight: maxHeight, + imageQuality: imageQuality, + preferredCameraDevice: preferredCameraDevice.toImagePickerPackage(), + requestFullMetadata: requestFullMetadata, + ); + } + + @override + Future pickMedia({ + double? maxWidth, + double? maxHeight, + int? imageQuality, + bool requestFullMetadata = true, + }) { + return _picker.pickMedia( + maxWidth: maxWidth, + maxHeight: maxHeight, + imageQuality: imageQuality, + requestFullMetadata: requestFullMetadata, + ); + } + + @override + Future pickVideo({ + required ImageSource source, + CameraDevice preferredCameraDevice = CameraDevice.rear, + Duration? maxDuration, + }) { + return _picker.pickVideo( + source: source.toImagePickerPackage(), + preferredCameraDevice: preferredCameraDevice.toImagePickerPackage(), + maxDuration: maxDuration, + ); + } +} + +extension ImageSoureceExt on ImageSource { + package.ImageSource toImagePickerPackage() { + switch (this) { + case ImageSource.camera: + return package.ImageSource.camera; + case ImageSource.gallery: + return package.ImageSource.gallery; + } + } +} + +extension CameraDeviceExt on CameraDevice { + package.CameraDevice toImagePickerPackage() { + switch (this) { + case CameraDevice.rear: + return package.CameraDevice.rear; + case CameraDevice.front: + return package.CameraDevice.front; + } + } +} diff --git a/flutter_quill_extensions/lib/logic/services/image_picker/s_image_picker.dart b/flutter_quill_extensions/lib/logic/services/image_picker/s_image_picker.dart new file mode 100644 index 00000000..9b9a43e4 --- /dev/null +++ b/flutter_quill_extensions/lib/logic/services/image_picker/s_image_picker.dart @@ -0,0 +1,60 @@ +import 'image_picker.dart'; +import 'packages/image_picker.dart'; + +class ImagePickerService extends ImagePickerInterface { + const ImagePickerService( + this._impl, + ); + + factory ImagePickerService.imagePickerPackage() => const ImagePickerService( + ImagePickerPackageImpl(), + ); + + factory ImagePickerService.defaultImpl() => + ImagePickerService.imagePickerPackage(); + + final ImagePickerInterface _impl; + @override + Future pickImage({ + required ImageSource source, + double? maxWidth, + double? maxHeight, + int? imageQuality, + CameraDevice preferredCameraDevice = CameraDevice.rear, + bool requestFullMetadata = true, + }) => + _impl.pickImage( + source: source, + maxWidth: maxWidth, + maxHeight: maxHeight, + imageQuality: imageQuality, + preferredCameraDevice: preferredCameraDevice, + requestFullMetadata: requestFullMetadata, + ); + + @override + Future pickMedia({ + double? maxWidth, + double? maxHeight, + int? imageQuality, + bool requestFullMetadata = true, + }) => + _impl.pickMedia( + maxWidth: maxWidth, + maxHeight: maxHeight, + imageQuality: imageQuality, + requestFullMetadata: requestFullMetadata, + ); + + @override + Future pickVideo({ + required ImageSource source, + CameraDevice preferredCameraDevice = CameraDevice.rear, + Duration? maxDuration, + }) => + _impl.pickVideo( + source: source, + preferredCameraDevice: preferredCameraDevice, + maxDuration: maxDuration, + ); +} diff --git a/flutter_quill_extensions/lib/logic/services/exceptions.dart b/flutter_quill_extensions/lib/logic/services/image_saver/exceptions.dart similarity index 100% rename from flutter_quill_extensions/lib/logic/services/exceptions.dart rename to flutter_quill_extensions/lib/logic/services/image_saver/exceptions.dart diff --git a/flutter_quill_extensions/lib/logic/services/image_saver.dart b/flutter_quill_extensions/lib/logic/services/image_saver/image_saver.dart similarity index 100% rename from flutter_quill_extensions/lib/logic/services/image_saver.dart rename to flutter_quill_extensions/lib/logic/services/image_saver/image_saver.dart diff --git a/flutter_quill_extensions/lib/logic/services/packages/gal.dart b/flutter_quill_extensions/lib/logic/services/image_saver/packages/gal.dart similarity index 100% rename from flutter_quill_extensions/lib/logic/services/packages/gal.dart rename to flutter_quill_extensions/lib/logic/services/image_saver/packages/gal.dart diff --git a/flutter_quill_extensions/lib/logic/services/image_saver/s_image_saver.dart b/flutter_quill_extensions/lib/logic/services/image_saver/s_image_saver.dart new file mode 100644 index 00000000..f11587fd --- /dev/null +++ b/flutter_quill_extensions/lib/logic/services/image_saver/s_image_saver.dart @@ -0,0 +1,30 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +import 'image_saver.dart'; +import 'packages/gal.dart' show ImageSaverGalImpl; + +class ImageSaverService extends ImageSaverInterface { + final ImageSaverInterface _impl; + const ImageSaverService(this._impl); + + factory ImageSaverService.galPackage() => ImageSaverService( + ImageSaverGalImpl(), + ); + + factory ImageSaverService.defaultImpl() => ImageSaverService.galPackage(); + + @override + Future hasAccess({bool toAlbum = false}) => + _impl.hasAccess(toAlbum: toAlbum); + + @override + Future requestAccess({bool toAlbum = false}) => + _impl.requestAccess(toAlbum: toAlbum); + + @override + Future saveImageFromNetwork(Uri imageUrl) => + _impl.saveImageFromNetwork(imageUrl); + + @override + Future saveLocalImage(String imageUrl) => + _impl.saveLocalImage(imageUrl); +} diff --git a/flutter_quill_extensions/lib/logic/services/s_image_saver.dart b/flutter_quill_extensions/lib/logic/services/s_image_saver.dart deleted file mode 100644 index 487e06ac..00000000 --- a/flutter_quill_extensions/lib/logic/services/s_image_saver.dart +++ /dev/null @@ -1,33 +0,0 @@ -// ignore_for_file: public_member_api_docs, sort_constructors_first -import 'image_saver.dart'; -import 'packages/gal.dart' show ImageSaverGalImpl; - -class ImageSaverService extends ImageSaverInterface { - final ImageSaverInterface _provider; - const ImageSaverService({ - required ImageSaverInterface impl, - }) : _provider = impl; - - factory ImageSaverService.gal() => ImageSaverService( - impl: ImageSaverGalImpl(), - ); - - static final _instance = ImageSaverService.gal(); - factory ImageSaverService.getInstance() => _instance; - - @override - Future hasAccess({bool toAlbum = false}) => - _provider.hasAccess(toAlbum: toAlbum); - - @override - Future requestAccess({bool toAlbum = false}) => - _provider.requestAccess(toAlbum: toAlbum); - - @override - Future saveImageFromNetwork(Uri imageUrl) => - _provider.saveImageFromNetwork(imageUrl); - - @override - Future saveLocalImage(String imageUrl) => - _provider.saveLocalImage(imageUrl); -} diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart index c5170fa2..45fd1399 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart @@ -158,8 +158,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { TextSelection.collapsed(offset: offset), ); // Call the post remove callback if set - await configurations.onImageRemovedCallback - ?.call(imageFile); + await configurations.onImageRemovedCallback.call(imageFile); }, ); return Padding( @@ -270,7 +269,10 @@ Widget _menuOptionsForReadonlyImage({ final messenger = ScaffoldMessenger.of(context); Navigator.of(context).pop(); - final saveImageResult = await saveImage(imageUrl); + final saveImageResult = await saveImage( + imageUrl: imageUrl, + context: context, + ); final imageSavedSuccessfully = saveImageResult.isSuccess; messenger.clearSnackBars(); diff --git a/flutter_quill_extensions/lib/presentation/embeds/embed_types.dart b/flutter_quill_extensions/lib/presentation/embeds/embed_types.dart index 16774b00..3a2e9330 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/embed_types.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/embed_types.dart @@ -4,28 +4,18 @@ import 'dart:typed_data'; import 'package:flutter/material.dart' show ImageErrorWidgetBuilder, BuildContext, ImageProvider; -typedef OnImagePickCallback = Future Function(File file); typedef OnVideoPickCallback = Future Function(File file); /// [FilePickImpl] is an implementation for picking files. typedef FilePickImpl = Future Function(BuildContext context); /// [WebImagePickImpl] is an implementation for picking web images. -typedef WebImagePickImpl = Future Function( - OnImagePickCallback onImagePickCallback, -); +// typedef WebImagePickImpl = Future Function( +// OnImagePickCallback onImagePickCallback, +// ); typedef WebVideoPickImpl = Future Function( OnVideoPickCallback onImagePickCallback, ); -typedef MediaPickSettingSelector = Future Function( - BuildContext context); - -enum MediaPickSetting { - gallery, - link, - camera, - video, -} typedef MediaFileUrl = String; typedef MediaFilePicker = Future Function(QuillMediaType mediaType); diff --git a/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart b/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart new file mode 100644 index 00000000..5f1bc001 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart @@ -0,0 +1,42 @@ +import 'package:flutter/widgets.dart' show BuildContext; +import 'package:flutter_quill/flutter_quill.dart'; +import '../../../logic/extensions/controller.dart'; +import '../../../logic/services/image_picker/s_image_picker.dart'; + +/// When request picking an image, for example when the image button toolbar +/// clicked, it should be null in case the user didn't choose any image or +/// any other reasons, and it should be the image file path as string that is +/// existied in case the user picked the image successfully +/// +/// by default we already have a default implementation that show a dialog +/// request the source for picking the image, from gallery, link or camera +typedef OnRequestPickImage = Future Function( + BuildContext context, + ImagePickerService imagePickerService, +); + +/// When a new image picked this callback will called and you might want to +/// do some logic depending on your use case +typedef OnImagePickedCallback = Future Function( + String image, +); + +/// A callback will called when inserting a image in the editor +typedef OnImageInsertCallback = Future Function( + String image, + QuillController controller, +); + +OnImageInsertCallback defaultOnImageInsertCallback() { + return (imageUrl, controller) async { + controller + ..skipRequestKeyboard = true + ..insertImageBlock(imageUrl: imageUrl); + }; +} + +enum InsertImageSource { + gallery, + camera, + link, +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button.dart index 690f0f66..25859832 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button.dart @@ -6,8 +6,6 @@ import 'package:flutter_quill/translations.dart'; import 'package:image_picker/image_picker.dart'; import '../../models/config/toolbar/buttons/camera.dart'; -import '../embed_types.dart'; -import 'utils/image_video_utils.dart'; class QuillToolbarCameraButton extends StatelessWidget { const QuillToolbarCameraButton({ @@ -55,10 +53,6 @@ class QuillToolbarCameraButton extends StatelessWidget { _onPressedHandler( context, controller, - onImagePickCallback: options.onImagePickCallback, - onVideoPickCallback: options.onVideoPickCallback, - filePickImpl: options.filePickImpl, - webImagePickImpl: options.webImagePickImpl, ); _afterButtonPressed(context); } @@ -117,12 +111,8 @@ class QuillToolbarCameraButton extends StatelessWidget { Future _onPressedHandler( BuildContext context, - QuillController controller, { - OnImagePickCallback? onImagePickCallback, - OnVideoPickCallback? onVideoPickCallback, - FilePickImpl? filePickImpl, - WebImagePickImpl? webImagePickImpl, - }) async { + QuillController controller, + ) async { if (onVideoPickCallback == null && onImagePickCallback == null) { throw ArgumentError( 'onImagePickCallback and onVideoPickCallback are both null', diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart similarity index 62% rename from flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button.dart rename to flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart index 88b54ee2..fbc7d361 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart @@ -2,11 +2,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:image_picker/image_picker.dart'; -import '../../models/config/toolbar/buttons/image.dart'; -import '../embed_types.dart'; -import 'utils/image_video_utils.dart'; +import '../../../../logic/models/config/configurations.dart'; +import '../../../../logic/services/image_picker/image_picker.dart'; +import '../../../models/config/toolbar/buttons/image.dart'; +import '../../embed_types/image.dart'; +import '../utils/image_video_utils.dart'; +import 'select_image_source.dart'; class QuillToolbarImageButton extends StatelessWidget { const QuillToolbarImageButton({ @@ -71,14 +73,11 @@ class QuillToolbarImageButton extends StatelessWidget { iconData: iconData, iconSize: iconSize, dialogTheme: options.dialogTheme, - filePickImpl: options.filePickImpl, - webImagePickImpl: options.webImagePickImpl, fillColor: options.fillColor, iconTheme: options.iconTheme, linkRegExp: options.linkRegExp, - mediaPickSettingSelector: options.mediaPickSettingSelector, - onImagePickCallback: options.onImagePickCallback, tooltip: options.tooltip, + imageButtonConfigurations: options.imageButtonConfigurations, ), QuillToolbarImageButtonExtraOptions( context: context, @@ -113,70 +112,60 @@ class QuillToolbarImageButton extends StatelessWidget { } Future _onPressedHandler(BuildContext context) async { - final onImagePickCallbackRef = options.onImagePickCallback; - if (onImagePickCallbackRef == null) { - await _typeLink(context); + final imagePickerService = + QuillSharedExtensionsConfigurations.get(context: context) + .imagePickerService; + final onRequestPickImage = + options.imageButtonConfigurations.onRequestPickImage; + if (onRequestPickImage != null) { + final imageUrl = await onRequestPickImage( + context, + imagePickerService, + ); + if (imageUrl != null) { + await options.imageButtonConfigurations + .onImageInsertCallback(imageUrl, controller); + } return; } - final selector = options.mediaPickSettingSelector ?? - ImageVideoUtils.selectMediaPickSetting; - final source = await selector(context); + final source = await showSelectImageSourceDialog( + context: context, + ); if (source == null) { return; } + final String? imageUrl; switch (source) { - case MediaPickSetting.gallery: - _pickImage(context); + case InsertImageSource.gallery: + imageUrl = (await imagePickerService.pickImage( + source: ImageSource.gallery, + )) + ?.path; break; - case MediaPickSetting.link: - await _typeLink(context); + case InsertImageSource.link: + imageUrl = await _typeLink(context); break; - case MediaPickSetting.camera: - await ImageVideoUtils.handleImageButtonTap( - context, - controller, - ImageSource.camera, - onImagePickCallbackRef, - filePickImpl: options.filePickImpl, - webImagePickImpl: options.webImagePickImpl, - ); + case InsertImageSource.camera: + imageUrl = (await imagePickerService.pickImage( + source: ImageSource.camera, + )) + ?.path; break; - case MediaPickSetting.video: - throw ArgumentError( - 'Sorry but this is the Image button and not the video one', - ); + } + if (imageUrl != null && imageUrl.trim().isNotEmpty) { + await options.imageButtonConfigurations + .onImageInsertCallback(imageUrl, controller); } } - void _pickImage(BuildContext context) => ImageVideoUtils.handleImageButtonTap( - context, - controller, - ImageSource.gallery, - options.onImagePickCallback ?? - (throw ArgumentError( - 'onImagePickCallback should not be null', - )), - filePickImpl: options.filePickImpl, - webImagePickImpl: options.webImagePickImpl, - ); - - Future _typeLink(BuildContext context) async { + Future _typeLink(BuildContext context) async { final value = await showDialog( context: context, - builder: (_) => LinkDialog( + builder: (_) => TypeLinkDialog( dialogTheme: options.dialogTheme, linkRegExp: options.linkRegExp, ), ); - _linkSubmitted(value); - } - - void _linkSubmitted(String? value) { - if (value != null && value.isNotEmpty) { - final index = controller.selection.baseOffset; - final length = controller.selection.extentOffset - index; - - controller.replaceText(index, length, BlockEmbed.image(value), null); - } + return value; } } diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart new file mode 100644 index 00000000..ab18fb28 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; + +import '../../embed_types/image.dart'; + +class SelectImageSourceDialog extends StatelessWidget { + const SelectImageSourceDialog({super.key}); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 230, + width: double.infinity, + child: SingleChildScrollView( + child: Column( + children: [ + ListTile( + title: const Text('Gallery'), + subtitle: const Text( + 'Pick a photo from your gallery', + ), + leading: const Icon(Icons.photo_sharp), + onTap: () => Navigator.of(context).pop(InsertImageSource.gallery), + ), + ListTile( + title: const Text('Camera'), + subtitle: const Text( + 'Take a photo using your phone camera', + ), + leading: const Icon(Icons.camera), + onTap: () => Navigator.of(context).pop(InsertImageSource.camera), + ), + ListTile( + title: const Text('Link'), + subtitle: const Text( + 'Paste a photo using https link', + ), + leading: const Icon(Icons.link), + onTap: () => Navigator.of(context).pop(InsertImageSource.link), + ), + ], + ), + ), + ); + } +} + +Future showSelectImageSourceDialog({ + required BuildContext context, +}) async { + final imageSource = await showModalBottomSheet( + showDragHandle: true, + context: context, + constraints: const BoxConstraints(maxWidth: 640), + builder: (context) => const SelectImageSourceDialog(), + ); + return imageSource; +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/utils/image_video_utils.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/utils/image_video_utils.dart index 4b03d7d7..b4d6ae57 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/utils/image_video_utils.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/utils/image_video_utils.dart @@ -1,17 +1,15 @@ -import 'dart:io' show File; - -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_quill/extensions.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill/translations.dart'; -import 'package:image_picker/image_picker.dart'; -import '../../../../logic/extensions/controller.dart'; -import '../../embed_types.dart'; +enum LinkType { + video, + image, +} -class LinkDialog extends StatefulWidget { - const LinkDialog({ +class TypeLinkDialog extends StatefulWidget { + const TypeLinkDialog({ + required this.linkType, this.dialogTheme, this.link, this.linkRegExp, @@ -21,12 +19,13 @@ class LinkDialog extends StatefulWidget { final QuillDialogTheme? dialogTheme; final String? link; final RegExp? linkRegExp; + final LinkType linkType; @override - LinkDialogState createState() => LinkDialogState(); + TypeLinkDialogState createState() => TypeLinkDialogState(); } -class LinkDialogState extends State { +class TypeLinkDialogState extends State { late String _link; late TextEditingController _controller; late RegExp _linkRegExp; @@ -65,7 +64,9 @@ class LinkDialogState extends State { style: widget.dialogTheme?.inputTextStyle, decoration: InputDecoration( labelText: 'Paste a link'.i18n, - hintText: 'Please enter a valid image url'.i18n, + hintText: widget.linkType == LinkType.image + ? 'Please enter a valid image url'.i18n + : 'Please enter a valid video url'.i18n, labelStyle: widget.dialogTheme?.labelTextStyle, floatingLabelStyle: widget.dialogTheme?.labelTextStyle, ), @@ -106,150 +107,152 @@ class LinkDialogState extends State { } } -class ImageVideoUtils { - static Future selectMediaPickSetting( - BuildContext context, - ) => - showDialog( - context: context, - builder: (ctx) => AlertDialog( - contentPadding: EdgeInsets.zero, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - TextButton.icon( - icon: const Icon( - Icons.collections, - color: Colors.orangeAccent, - ), - label: Text('Gallery'.i18n), - onPressed: () => Navigator.pop(ctx, MediaPickSetting.gallery), - ), - TextButton.icon( - icon: const Icon( - Icons.link, - color: Colors.cyanAccent, - ), - label: Text('Link'.i18n), - onPressed: () => Navigator.pop(ctx, MediaPickSetting.link), - ) - ], - ), - ), - ); - - /// For image picking logic - static Future handleImageButtonTap( - BuildContext context, - QuillController controller, - ImageSource imageSource, - OnImagePickCallback onImagePickCallback, { - FilePickImpl? filePickImpl, - WebImagePickImpl? webImagePickImpl, - }) async { - String? imageUrl; - if (kIsWeb) { - if (webImagePickImpl != null) { - imageUrl = await webImagePickImpl(onImagePickCallback); - return; - } - final file = await ImagePicker().pickImage(source: ImageSource.gallery); - imageUrl = file?.path; - if (imageUrl == null) { - return; - } - } else if (isMobile()) { - imageUrl = await _pickImage(imageSource, onImagePickCallback); - } else { - assert(filePickImpl != null, 'Desktop must provide filePickImpl'); - imageUrl = - await _pickImageDesktop(context, filePickImpl!, onImagePickCallback); - } - - if (imageUrl == null) { - return; - } - - controller.insertImageBlock( - imageUrl: imageUrl, - ); - } +// @immutable +// class ImageVideoUtils { +// const ImageVideoUtils._(); +// static Future selectMediaPickSetting( +// BuildContext context, +// ) => +// showDialog( +// context: context, +// builder: (ctx) => AlertDialog( +// contentPadding: EdgeInsets.zero, +// content: Column( +// mainAxisSize: MainAxisSize.min, +// children: [ +// TextButton.icon( +// icon: const Icon( +// Icons.collections, +// color: Colors.orangeAccent, +// ), +// label: Text('Gallery'.i18n), +// onPressed: () => Navigator.pop(ctx, MediaPickSetting.gallery), +// ), +// TextButton.icon( +// icon: const Icon( +// Icons.link, +// color: Colors.cyanAccent, +// ), +// label: Text('Link'.i18n), +// onPressed: () => Navigator.pop(ctx, MediaPickSetting.link), +// ) +// ], +// ), +// ), +// ); - static Future _pickImage( - ImageSource source, - OnImagePickCallback onImagePickCallback, - ) async { - final pickedFile = await ImagePicker().pickImage(source: source); - if (pickedFile == null) { - return null; - } +// /// For image picking logic +// static Future handleImageButtonTap( +// BuildContext context, +// QuillController controller, +// ImageSource imageSource, +// OnImagePickCallback onImagePickCallback, { +// FilePickImpl? filePickImpl, +// WebImagePickImpl? webImagePickImpl, +// }) async { +// String? imageUrl; +// if (kIsWeb) { +// if (webImagePickImpl != null) { +// imageUrl = await webImagePickImpl(onImagePickCallback); +// return; +// } +// final file = await ImagePicker().pickImage(source: ImageSource.gallery); +// imageUrl = file?.path; +// if (imageUrl == null) { +// return; +// } +// } else if (isMobile()) { +// imageUrl = await _pickImage(imageSource, onImagePickCallback); +// } else { +// assert(filePickImpl != null, 'Desktop must provide filePickImpl'); +// imageUrl = +// await _pickImageDesktop(context, filePickImpl!, onImagePickCallback); +// } - return onImagePickCallback(File(pickedFile.path)); - } +// if (imageUrl == null) { +// return; +// } - static Future _pickImageDesktop( - BuildContext context, - FilePickImpl filePickImpl, - OnImagePickCallback onImagePickCallback, - ) async { - final filePath = await filePickImpl(context); - if (filePath == null || filePath.isEmpty) return null; +// controller.insertImageBlock( +// imageUrl: imageUrl, +// ); +// } - final file = File(filePath); - return onImagePickCallback(file); - } +// static Future _pickImage( +// ImageSource source, +// OnImagePickCallback onImagePickCallback, +// ) async { +// final pickedFile = await ImagePicker().pickImage(source: source); +// if (pickedFile == null) { +// return null; +// } - /// For video picking logic - static Future handleVideoButtonTap( - BuildContext context, - QuillController controller, - ImageSource videoSource, - OnVideoPickCallback onVideoPickCallback, { - FilePickImpl? filePickImpl, - WebVideoPickImpl? webVideoPickImpl, - }) async { - final index = controller.selection.baseOffset; - final length = controller.selection.extentOffset - index; - - String? videoUrl; - if (kIsWeb) { - assert( - webVideoPickImpl != null, - 'Please provide webVideoPickImpl for Web ' - 'in the options of this button', - ); - videoUrl = await webVideoPickImpl!(onVideoPickCallback); - } else if (isMobile()) { - videoUrl = await _pickVideo(videoSource, onVideoPickCallback); - } else { - assert(filePickImpl != null, 'Desktop must provide filePickImpl'); - videoUrl = - await _pickVideoDesktop(context, filePickImpl!, onVideoPickCallback); - } - - if (videoUrl != null) { - controller.replaceText(index, length, BlockEmbed.video(videoUrl), null); - } - } +// return onImagePickCallback(File(pickedFile.path)); +// } - static Future _pickVideo( - ImageSource source, OnVideoPickCallback onVideoPickCallback) async { - final pickedFile = await ImagePicker().pickVideo(source: source); - if (pickedFile == null) { - return null; - } +// static Future _pickImageDesktop( +// BuildContext context, +// FilePickImpl filePickImpl, +// OnImagePickCallback onImagePickCallback, +// ) async { +// final filePath = await filePickImpl(context); +// if (filePath == null || filePath.isEmpty) return null; - return onVideoPickCallback(File(pickedFile.path)); - } +// final file = File(filePath); +// return onImagePickCallback(file); +// } - static Future _pickVideoDesktop( - BuildContext context, - FilePickImpl filePickImpl, - OnVideoPickCallback onVideoPickCallback) async { - final filePath = await filePickImpl(context); - if (filePath == null || filePath.isEmpty) return null; +// /// For video picking logic +// static Future handleVideoButtonTap( +// BuildContext context, +// QuillController controller, +// ImageSource videoSource, +// OnVideoPickCallback onVideoPickCallback, { +// FilePickImpl? filePickImpl, +// WebVideoPickImpl? webVideoPickImpl, +// }) async { +// final index = controller.selection.baseOffset; +// final length = controller.selection.extentOffset - index; - final file = File(filePath); - return onVideoPickCallback(file); - } -} +// String? videoUrl; +// if (kIsWeb) { +// assert( +// webVideoPickImpl != null, +// 'Please provide webVideoPickImpl for Web ' +// 'in the options of this button', +// ); +// videoUrl = await webVideoPickImpl!(onVideoPickCallback); +// } else if (isMobile()) { +// videoUrl = await _pickVideo(videoSource, onVideoPickCallback); +// } else { +// assert(filePickImpl != null, 'Desktop must provide filePickImpl'); +// videoUrl = +// await _pickVideoDesktop(context, filePickImpl!, onVideoPickCallback); +// } + +// if (videoUrl != null) { +// controller.replaceText(index, length, BlockEmbed.video(videoUrl), null); +// } +// } + +// static Future _pickVideo( +// ImageSource source, OnVideoPickCallback onVideoPickCallback) async { +// final pickedFile = await ImagePicker().pickVideo(source: source); +// if (pickedFile == null) { +// return null; +// } + +// return onVideoPickCallback(File(pickedFile.path)); +// } + +// static Future _pickVideoDesktop( +// BuildContext context, +// FilePickImpl filePickImpl, +// OnVideoPickCallback onVideoPickCallback) async { +// final filePath = await filePickImpl(context); +// if (filePath == null || filePath.isEmpty) return null; + +// final file = File(filePath); +// return onVideoPickCallback(file); +// } +// } diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button.dart index 5019ac6b..2bed465d 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button.dart @@ -137,7 +137,7 @@ class QuillToolbarVideoButton extends StatelessWidget { Future _typeLink(BuildContext context) async { final value = await showDialog( context: context, - builder: (_) => LinkDialog( + builder: (_) => TypeLinkDialog( dialogTheme: options.dialogTheme, ), ); diff --git a/flutter_quill_extensions/lib/presentation/embeds/utils.dart b/flutter_quill_extensions/lib/presentation/embeds/utils.dart index c7adfc42..68f8c314 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/utils.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/utils.dart @@ -1,7 +1,10 @@ import 'dart:io' show File; import 'package:flutter/foundation.dart' show immutable; -import '../../logic/services/s_image_saver.dart'; +import 'package:flutter/widgets.dart' show BuildContext; +import 'package:flutter_quill/flutter_quill.dart'; +import '../../logic/models/config/configurations.dart'; +import '../../logic/services/image_saver/s_image_saver.dart'; // I would like to orgnize the project structure and the code more // but here I don't want to change too much since that is a community project @@ -48,14 +51,19 @@ class SaveImageResult { final SaveImageResultMethod method; } -Future saveImage(String imageUrl) async { - final imageSaverService = ImageSaverService.getInstance(); +Future saveImage({ + required String imageUrl, + required BuildContext context, +}) async { + final imageSaverService = + QuillSharedExtensionsConfigurations.get(context: context) + .imageSaverService; final imageFile = File(imageUrl); final hasPermission = await imageSaverService.hasAccess(); - final imageExistsLocally = await imageFile.exists(); if (!hasPermission) { await imageSaverService.requestAccess(); } + final imageExistsLocally = await imageFile.exists(); if (!imageExistsLocally) { try { await imageSaverService.saveImageFromNetwork( diff --git a/flutter_quill_extensions/lib/presentation/models/config/editor/image.dart b/flutter_quill_extensions/lib/presentation/models/config/editor/image.dart index 5a30ab15..2b494128 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/editor/image.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/editor/image.dart @@ -11,11 +11,11 @@ import '../../../embeds/embed_types.dart'; class QuillEditorImageEmbedConfigurations { const QuillEditorImageEmbedConfigurations({ this.forceUseMobileOptionMenuForImageClick = false, - this.onImageRemovedCallback, + ImageEmbedBuilderOnRemovedCallback? onImageRemovedCallback, this.shouldRemoveImageCallback, this.imageProviderBuilder, this.imageErrorWidgetBuilder, - }); + }) : _onImageRemovedCallback = onImageRemovedCallback; /// [onImageRemovedCallback] is called when an image is /// removed from the editor. @@ -33,7 +33,17 @@ class QuillEditorImageEmbedConfigurations { /// } /// ``` /// - final ImageEmbedBuilderOnRemovedCallback? onImageRemovedCallback; + /// Default value if the passed value is null: + /// [QuillEditorImageEmbedConfigurations.defaultOnImageRemovedCallback] + /// + /// so if you want to do nothing make sure to pass a empty callback + /// instead of passing null as value + final ImageEmbedBuilderOnRemovedCallback? _onImageRemovedCallback; + + ImageEmbedBuilderOnRemovedCallback get onImageRemovedCallback { + return _onImageRemovedCallback ?? + QuillEditorImageEmbedConfigurations.defaultOnImageRemovedCallback; + } /// [shouldRemoveImageCallback] is a callback /// function that is invoked when the @@ -128,6 +138,26 @@ class QuillEditorImageEmbedConfigurations { } }; } + + QuillEditorImageEmbedConfigurations copyWith({ + ImageEmbedBuilderOnRemovedCallback? onImageRemovedCallback, + ImageEmbedBuilderWillRemoveCallback? shouldRemoveImageCallback, + ImageEmbedBuilderProviderBuilder? imageProviderBuilder, + ImageEmbedBuilderErrorWidgetBuilder? imageErrorWidgetBuilder, + bool? forceUseMobileOptionMenuForImageClick, + }) { + return QuillEditorImageEmbedConfigurations( + onImageRemovedCallback: onImageRemovedCallback ?? _onImageRemovedCallback, + shouldRemoveImageCallback: + shouldRemoveImageCallback ?? this.shouldRemoveImageCallback, + imageProviderBuilder: imageProviderBuilder ?? this.imageProviderBuilder, + imageErrorWidgetBuilder: + imageErrorWidgetBuilder ?? this.imageErrorWidgetBuilder, + forceUseMobileOptionMenuForImageClick: + forceUseMobileOptionMenuForImageClick ?? + this.forceUseMobileOptionMenuForImageClick, + ); + } } @immutable diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart index eef8d4dd..b1b5bd8e 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart @@ -2,6 +2,8 @@ import 'package:flutter/widgets.dart' show Color; import 'package:flutter_quill/flutter_quill.dart'; import '../../../../embeds/embed_types.dart'; +import '../../../../embeds/embed_types/image.dart'; +import 'image.dart'; class QuillToolbarCameraButtonExtraOptions extends QuillToolbarBaseButtonExtraOptions { @@ -15,12 +17,9 @@ class QuillToolbarCameraButtonExtraOptions class QuillToolbarCameraButtonOptions extends QuillToolbarBaseButtonOptions< QuillToolbarCameraButtonOptions, QuillToolbarCameraButtonExtraOptions> { const QuillToolbarCameraButtonOptions({ - required this.onImagePickCallback, required this.onVideoPickCallback, - this.webImagePickImpl, + this.imageConfigurations = const QuillToolbarImageButtonConfigurations(), this.webVideoPickImpl, - this.filePickImpl, - this.cameraPickSettingSelector, this.iconSize, this.fillColor, super.iconData, @@ -31,18 +30,12 @@ class QuillToolbarCameraButtonOptions extends QuillToolbarBaseButtonOptions< super.controller, }); - final OnImagePickCallback onImagePickCallback; + final QuillToolbarImageButtonConfigurations imageConfigurations; final OnVideoPickCallback onVideoPickCallback; - final WebImagePickImpl? webImagePickImpl; - final WebVideoPickImpl? webVideoPickImpl; - final FilePickImpl? filePickImpl; - - final MediaPickSettingSelector? cameraPickSettingSelector; - final double? iconSize; final Color? fillColor; diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart index 98bbb265..d6195c4c 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart @@ -2,7 +2,9 @@ import 'package:flutter/widgets.dart' show Color; import 'package:flutter_quill/flutter_quill.dart'; import 'package:meta/meta.dart' show immutable; +import '../../../../../logic/extensions/controller.dart'; import '../../../../embeds/embed_types.dart'; +import '../../../../embeds/embed_types/image.dart'; class QuillToolbarImageButtonExtraOptions extends QuillToolbarBaseButtonExtraOptions { @@ -27,27 +29,37 @@ class QuillToolbarImageButtonOptions extends QuillToolbarBaseButtonOptions< super.childBuilder, super.iconTheme, this.fillColor, - this.onImagePickCallback, - this.filePickImpl, - this.webImagePickImpl, - this.mediaPickSettingSelector, this.dialogTheme, this.linkRegExp, + this.imageButtonConfigurations = + const QuillToolbarImageButtonConfigurations(), }); final double? iconSize; final Color? fillColor; - final OnImagePickCallback? onImagePickCallback; + final QuillDialogTheme? dialogTheme; - final WebImagePickImpl? webImagePickImpl; + /// [imageLinkRegExp] is a regular expression to identify image links. + final RegExp? linkRegExp; - final FilePickImpl? filePickImpl; + final QuillToolbarImageButtonConfigurations imageButtonConfigurations; +} - final MediaPickSettingSelector? mediaPickSettingSelector; +class QuillToolbarImageButtonConfigurations { + const QuillToolbarImageButtonConfigurations({ + this.onRequestPickImage, + this.onImagePickedCallback, + OnImageInsertCallback? onImageInsertCallback, + }) : _onImageInsertCallback = onImageInsertCallback; - final QuillDialogTheme? dialogTheme; + final OnRequestPickImage? onRequestPickImage; - /// [imageLinkRegExp] is a regular expression to identify image links. - final RegExp? linkRegExp; + final OnImagePickedCallback? onImagePickedCallback; + + final OnImageInsertCallback? _onImageInsertCallback; + + OnImageInsertCallback get onImageInsertCallback { + return _onImageInsertCallback ?? defaultOnImageInsertCallback(); + } } diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart index 06001e2d..e35d59e9 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart @@ -76,9 +76,7 @@ class QuillToolbarMediaButtonOptions extends QuillToolbarBaseButtonOptions< final AutovalidateMode autovalidateMode; final String? validationMessage; - final OnImagePickCallback onImagePickCallback; final FilePickImpl? filePickImpl; - final WebImagePickImpl? webImagePickImpl; final OnVideoPickCallback onVideoPickCallback; final WebVideoPickImpl? webVideoPickImpl; } diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart index 12995fda..96f121ec 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart @@ -39,8 +39,6 @@ class QuillToolbarVideoButtonOptions extends QuillToolbarBaseButtonOptions< final FilePickImpl? filePickImpl; - final MediaPickSettingSelector? mediaPickSettingSelector; - final Color? fillColor; final double? iconSize; diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 66fd0b4b..7a82cfff 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -40,11 +40,12 @@ dependencies: math_keyboard: ^0.2.1 url_launcher: ^6.2.1 meta: ^1.9.1 + cross_file: ^0.3.3+6 # In case you are working on changes for both libraries, please uncomment this section -# dependency_overrides: -# flutter_quill: -# path: ../ +dependency_overrides: + flutter_quill: + path: ../ dev_dependencies: flutter_test: From eeb720e097bd8d7642303a5926051918c9244840 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 21:38:13 +0300 Subject: [PATCH 029/210] Step 2 --- CHANGELOG.md | 3 + example/ios/Runner/Info.plist | 4 +- example/lib/pages/home_page.dart | 148 ++--- example/lib/widgets/demo_scaffold.dart | 7 +- .../lib/flutter_quill_extensions.dart | 26 +- .../lib/logic/extensions/controller.dart | 10 +- .../embeds/embed_types/camera.dart | 36 ++ .../embeds/embed_types/image.dart | 37 +- .../embeds/embed_types/video.dart | 66 +++ .../{ => camera_button}/camera_button.dart | 158 +++--- .../camera_button/select_camera_action.dart | 37 ++ .../toolbar/image_button/image_button.dart | 31 +- .../image_button/select_image_source.dart | 2 +- .../embeds/toolbar/media_button.dart | 533 ------------------ .../toolbar/media_button/media_button.dart | 533 ++++++++++++++++++ .../video_button/select_video_source.dart | 57 ++ .../{ => video_button}/video_button.dart | 89 ++- .../models/config/toolbar/buttons/camera.dart | 13 +- .../models/config/toolbar/buttons/image.dart | 25 +- .../config/toolbar/buttons/media_button.dart | 2 - .../models/config/toolbar/buttons/video.dart | 9 +- .../models/config/shared_configurations.dart | 4 + pubspec.yaml | 2 +- 23 files changed, 1049 insertions(+), 783 deletions(-) create mode 100644 flutter_quill_extensions/lib/presentation/embeds/embed_types/camera.dart create mode 100644 flutter_quill_extensions/lib/presentation/embeds/embed_types/video.dart rename flutter_quill_extensions/lib/presentation/embeds/toolbar/{ => camera_button}/camera_button.dart (53%) create mode 100644 flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/select_camera_action.dart delete mode 100644 flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button.dart create mode 100644 flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button/media_button.dart create mode 100644 flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/select_video_source.dart rename flutter_quill_extensions/lib/presentation/embeds/toolbar/{ => video_button}/video_button.dart (62%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68f121a6..1153a751 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.1.12] +- Add the option to add configurations for `fresh_quill_extensions` using `extraConfigurations` + ## [8.1.11] - Follow dart best practices by using `lints` and remove `pedantic` as well `platform` since they are not used - Fix text direction bug diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index b8fc1f1d..4a49f260 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -21,7 +21,9 @@ CFBundleVersion $(FLUTTER_BUILD_NUMBER) NSPhotoLibraryUsageDescription - Need to save image + The app will use it to pick images + NSCameraUsageDescription + The app will use it to capture a images, record videos. LSRequiresIPhoneOS UILaunchStoryboardName diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 34567dbb..f5a4a4a5 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -13,6 +13,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_quill/extensions.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; +import 'package:flutter_quill_extensions/presentation/embeds/embed_types/image.dart'; import 'package:flutter_quill_extensions/presentation/models/config/toolbar/buttons/video.dart'; import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart'; @@ -274,8 +275,12 @@ class _HomePageState extends State { configurations: QuillToolbarConfigurations( embedButtons: FlutterQuillEmbeds.toolbarButtons( imageButtonOptions: QuillToolbarImageButtonOptions( - onImagePickCallback: _onImagePickCallback, - webImagePickImpl: _webImagePickImpl, + imageButtonConfigurations: QuillToolbarImageConfigurations( + onImageInsertedCallback: (image) async { + _onImagePickCallback(File(image)); + }, + ), + // webImagePickImpl: _webImagePickImpl, ), ), buttonOptions: QuillToolbarButtonOptions( @@ -290,11 +295,15 @@ class _HomePageState extends State { if (_isDesktop()) { return QuillToolbar( configurations: QuillToolbarConfigurations( - showDirection: true, embedButtons: FlutterQuillEmbeds.toolbarButtons( imageButtonOptions: QuillToolbarImageButtonOptions( - onImagePickCallback: _onImagePickCallback, - filePickImpl: openFileSystemPickerForDesktop, + imageButtonConfigurations: QuillToolbarImageConfigurations( + onImageInsertedCallback: (image) async { + _onImagePickCallback(File(image)); + }, + ), + // onImagePickCallback: _onImagePickCallback, + // filePickImpl: openFileSystemPickerForDesktop, ), ), showAlignmentButtons: true, @@ -311,18 +320,23 @@ class _HomePageState extends State { configurations: QuillToolbarConfigurations( embedButtons: FlutterQuillEmbeds.toolbarButtons( imageButtonOptions: QuillToolbarImageButtonOptions( + imageButtonConfigurations: QuillToolbarImageConfigurations( + onImageInsertedCallback: (image) async { + _onImagePickCallback(File(image)); + }, + ), // provide a callback to enable picking images from device. // if omit, "image" button only allows adding images from url. // same goes for videos. - onImagePickCallback: _onImagePickCallback, + // onImagePickCallback: _onImagePickCallback, // uncomment to provide a custom "pick from" dialog. // mediaPickSettingSelector: _selectMediaPickSetting, // uncomment to provide a custom "pick from" dialog. // cameraPickSettingSelector: _selectCameraPickSetting, ), - videoButtonOptions: QuillToolbarVideoButtonOptions( - onVideoPickCallback: _onVideoPickCallback, - ), + // videoButtonOptions: QuillToolbarVideoButtonOptions( + // onVideoPickCallback: _onVideoPickCallback, + // ), ), showAlignmentButtons: true, buttonOptions: QuillToolbarButtonOptions( @@ -414,19 +428,19 @@ class _HomePageState extends State { return copiedFile.path.toString(); } - Future _webImagePickImpl( - OnImagePickCallback onImagePickCallback) async { - final result = await FilePicker.platform.pickFiles(); - if (result == null) { - return null; - } + // Future _webImagePickImpl( + // OnImagePickCallback onImagePickCallback) async { + // final result = await FilePicker.platform.pickFiles(); + // if (result == null) { + // return null; + // } - // Take first, because we don't allow picking multiple files. - final fileName = result.files.first.name; - final file = File(fileName); + // // Take first, because we don't allow picking multiple files. + // final fileName = result.files.first.name; + // final file = File(fileName); - return onImagePickCallback(file); - } + // return onImagePickCallback(file); + // } // Renders the video picked by imagePicker from local file storage // You can also upload the picked video to any server (eg : AWS s3 @@ -439,53 +453,53 @@ class _HomePageState extends State { return copiedFile.path.toString(); } - // ignore: unused_element - Future _selectMediaPickSetting(BuildContext context) => - showDialog( - context: context, - builder: (ctx) => AlertDialog( - contentPadding: EdgeInsets.zero, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - TextButton.icon( - icon: const Icon(Icons.collections), - label: const Text('Gallery'), - onPressed: () => Navigator.pop(ctx, MediaPickSetting.gallery), - ), - TextButton.icon( - icon: const Icon(Icons.link), - label: const Text('Link'), - onPressed: () => Navigator.pop(ctx, MediaPickSetting.link), - ) - ], - ), - ), - ); - - // ignore: unused_element - Future _selectCameraPickSetting(BuildContext context) => - showDialog( - context: context, - builder: (ctx) => AlertDialog( - contentPadding: EdgeInsets.zero, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - TextButton.icon( - icon: const Icon(Icons.camera), - label: const Text('Capture a photo'), - onPressed: () => Navigator.pop(ctx, MediaPickSetting.camera), - ), - TextButton.icon( - icon: const Icon(Icons.video_call), - label: const Text('Capture a video'), - onPressed: () => Navigator.pop(ctx, MediaPickSetting.video), - ) - ], - ), - ), - ); + // // ignore: unused_element + // Future _selectMediaPickSetting(BuildContext context) => + // showDialog( + // context: context, + // builder: (ctx) => AlertDialog( + // contentPadding: EdgeInsets.zero, + // content: Column( + // mainAxisSize: MainAxisSize.min, + // children: [ + // TextButton.icon( + // icon: const Icon(Icons.collections), + // label: const Text('Gallery'), + // onPressed: () => Navigator.pop(ctx, MediaPickSetting.gallery), + // ), + // TextButton.icon( + // icon: const Icon(Icons.link), + // label: const Text('Link'), + // onPressed: () => Navigator.pop(ctx, MediaPickSetting.link), + // ) + // ], + // ), + // ), + // ); + + // // ignore: unused_element + // Future _selectCameraPickSetting(BuildContext context) => + // showDialog( + // context: context, + // builder: (ctx) => AlertDialog( + // contentPadding: EdgeInsets.zero, + // content: Column( + // mainAxisSize: MainAxisSize.min, + // children: [ + // TextButton.icon( + // icon: const Icon(Icons.camera), + // label: const Text('Capture a photo'), + // onPressed: () => Navigator.pop(ctx, MediaPickSetting.camera), + // ), + // TextButton.icon( + // icon: const Icon(Icons.video_call), + // label: const Text('Capture a video'), + // onPressed: () => Navigator.pop(ctx, MediaPickSetting.video), + // ) + // ], + // ), + // ), + // ); Widget _buildMenuBar(BuildContext context) { final size = MediaQuery.sizeOf(context); diff --git a/example/lib/widgets/demo_scaffold.dart b/example/lib/widgets/demo_scaffold.dart index 78c350fc..27c6ebb0 100644 --- a/example/lib/widgets/demo_scaffold.dart +++ b/example/lib/widgets/demo_scaffold.dart @@ -89,9 +89,10 @@ class _DemoScaffoldState extends State { return QuillToolbar( configurations: QuillToolbarConfigurations( embedButtons: FlutterQuillEmbeds.toolbarButtons( - imageButtonOptions: QuillToolbarImageButtonOptions( - filePickImpl: openFileSystemPickerForDesktop, - ), + // ignore: avoid_redundant_argument_values + imageButtonOptions: const QuillToolbarImageButtonOptions( + // filePickImpl: openFileSystemPickerForDesktop, + ), ), ), ); diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index 78e1bc77..bb617431 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -9,11 +9,13 @@ import 'presentation/embeds/editor/image/image.dart'; import 'presentation/embeds/editor/image/image_web.dart'; import 'presentation/embeds/editor/video.dart'; import 'presentation/embeds/editor/webview.dart'; -import 'presentation/embeds/toolbar/camera_button.dart'; +import 'presentation/embeds/toolbar/camera_button/camera_button.dart'; import 'presentation/embeds/toolbar/formula_button.dart'; import 'presentation/embeds/toolbar/image_button/image_button.dart'; -import 'presentation/embeds/toolbar/media_button.dart'; -import 'presentation/embeds/toolbar/video_button.dart'; +// TODO: Temporary +// ignore: unused_import +import 'presentation/embeds/toolbar/media_button/media_button.dart'; +import 'presentation/embeds/toolbar/video_button/video_button.dart'; import 'presentation/models/config/editor/image.dart'; import 'presentation/models/config/editor/video.dart'; import 'presentation/models/config/editor/webview.dart'; @@ -27,12 +29,12 @@ export '/presentation/models/config/editor/webview.dart'; export './logic/extensions/controller.dart'; export 'presentation/embeds/editor/unknown.dart'; export 'presentation/embeds/embed_types.dart'; -export 'presentation/embeds/toolbar/camera_button.dart'; +export 'presentation/embeds/toolbar/camera_button/camera_button.dart'; export 'presentation/embeds/toolbar/formula_button.dart'; export 'presentation/embeds/toolbar/image_button/image_button.dart'; -export 'presentation/embeds/toolbar/media_button.dart'; +export 'presentation/embeds/toolbar/media_button/media_button.dart'; export 'presentation/embeds/toolbar/utils/image_video_utils.dart'; -export 'presentation/embeds/toolbar/video_button.dart'; +export 'presentation/embeds/toolbar/video_button/video_button.dart'; export 'presentation/embeds/utils.dart'; export 'presentation/models/config/editor/image.dart'; export 'presentation/models/config/toolbar/buttons/image.dart'; @@ -173,12 +175,12 @@ class FlutterQuillEmbeds { controller: cameraButtonOptions.controller ?? controller, options: cameraButtonOptions, ), - if (mediaButtonOptions != null) - (controller, toolbarIconSize, iconTheme, dialogTheme) => - QuillToolbarMediaButton( - controller: mediaButtonOptions.controller ?? controller, - options: mediaButtonOptions, - ), + // if (mediaButtonOptions != null) + // (controller, toolbarIconSize, iconTheme, dialogTheme) => + // QuillToolbarMediaButton( + // controller: mediaButtonOptions.controller ?? controller, + // options: mediaButtonOptions, + // ), if (formulaButtonOptions != null && !kIsWeb) (controller, toolbarIconSize, iconTheme, dialogTheme) => QuillToolbarFormulaButton( diff --git a/flutter_quill_extensions/lib/logic/extensions/controller.dart b/flutter_quill_extensions/lib/logic/extensions/controller.dart index 856b87b7..2318e5f6 100644 --- a/flutter_quill_extensions/lib/logic/extensions/controller.dart +++ b/flutter_quill_extensions/lib/logic/extensions/controller.dart @@ -28,7 +28,7 @@ extension QuillControllerExt on QuillController { required String imageUrl, }) { this - ..skipRequestKeyboard = skipRequestKeyboard + ..skipRequestKeyboard = true ..replaceText( index, length, @@ -36,4 +36,12 @@ extension QuillControllerExt on QuillController { null, ); } + + void insertVideoBlock({ + required String videoUrl, + }) { + this + ..skipRequestKeyboard = true + ..replaceText(index, length, BlockEmbed.video(videoUrl), null); + } } diff --git a/flutter_quill_extensions/lib/presentation/embeds/embed_types/camera.dart b/flutter_quill_extensions/lib/presentation/embeds/embed_types/camera.dart new file mode 100644 index 00000000..7ce65321 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/embed_types/camera.dart @@ -0,0 +1,36 @@ +import 'package:flutter/widgets.dart' show BuildContext; +import 'package:meta/meta.dart' show immutable; + +import 'image.dart'; + +enum CameraAction { + video, + image, +} + +/// When the user click the camera button, should we take a photo or record +/// a video using the camera +/// +/// by default will show a dialog that ask the user which option he/she wants +typedef OnRequestCameraActionCallback = Future Function( + BuildContext context, +); + +@immutable +class QuillToolbarCameraConfigurations { + const QuillToolbarCameraConfigurations({ + this.onRequestCameraActionCallback, + OnImageInsertCallback? onImageInsertCallback, + this.onImageInsertedCallback, + }) : _onImageInsertCallback = onImageInsertCallback; + + final OnRequestCameraActionCallback? onRequestCameraActionCallback; + + final OnImageInsertedCallback? onImageInsertedCallback; + + final OnImageInsertCallback? _onImageInsertCallback; + + OnImageInsertCallback get onImageInsertCallback { + return _onImageInsertCallback ?? defaultOnImageInsertCallback(); + } +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart b/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart index 5f1bc001..e191c129 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart @@ -1,12 +1,13 @@ import 'package:flutter/widgets.dart' show BuildContext; import 'package:flutter_quill/flutter_quill.dart'; +import 'package:meta/meta.dart' show immutable; import '../../../logic/extensions/controller.dart'; import '../../../logic/services/image_picker/s_image_picker.dart'; /// When request picking an image, for example when the image button toolbar /// clicked, it should be null in case the user didn't choose any image or /// any other reasons, and it should be the image file path as string that is -/// existied in case the user picked the image successfully +/// exists in case the user picked the image successfully /// /// by default we already have a default implementation that show a dialog /// request the source for picking the image, from gallery, link or camera @@ -15,13 +16,8 @@ typedef OnRequestPickImage = Future Function( ImagePickerService imagePickerService, ); -/// When a new image picked this callback will called and you might want to -/// do some logic depending on your use case -typedef OnImagePickedCallback = Future Function( - String image, -); - /// A callback will called when inserting a image in the editor +/// it have the logic that will insert the image block using the controller typedef OnImageInsertCallback = Future Function( String image, QuillController controller, @@ -35,8 +31,35 @@ OnImageInsertCallback defaultOnImageInsertCallback() { }; } +/// When a new image picked this callback will called and you might want to +/// do some logic depending on your use case +typedef OnImageInsertedCallback = Future Function( + String image, +); + enum InsertImageSource { gallery, camera, link, } + +/// Configurations for dealing with images, on insert a image +/// on request picking a image +@immutable +class QuillToolbarImageConfigurations { + const QuillToolbarImageConfigurations({ + this.onRequestPickImage, + this.onImageInsertedCallback, + OnImageInsertCallback? onImageInsertCallback, + }) : _onImageInsertCallback = onImageInsertCallback; + + final OnRequestPickImage? onRequestPickImage; + + final OnImageInsertedCallback? onImageInsertedCallback; + + final OnImageInsertCallback? _onImageInsertCallback; + + OnImageInsertCallback get onImageInsertCallback { + return _onImageInsertCallback ?? defaultOnImageInsertCallback(); + } +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/embed_types/video.dart b/flutter_quill_extensions/lib/presentation/embeds/embed_types/video.dart new file mode 100644 index 00000000..d69ab5e0 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/embed_types/video.dart @@ -0,0 +1,66 @@ +import 'package:flutter/widgets.dart' show BuildContext; +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:meta/meta.dart' show immutable; + +import '../../../logic/extensions/controller.dart'; +import '../../../logic/services/image_picker/s_image_picker.dart'; + +/// When request picking an video, for example when the video button toolbar +/// clicked, it should be null in case the user didn't choose any video or +/// any other reasons, and it should be the video file path as string that is +/// exists in case the user picked the video successfully +/// +/// by default we already have a default implementation that show a dialog +/// request the source for picking the video, from gallery, link or camera +typedef OnRequestPickVideo = Future Function( + BuildContext context, + ImagePickerService imagePickerService, +); + +/// A callback will called when inserting a video in the editor +/// it have the logic that will insert the video block using the controller +typedef OnVideoInsertCallback = Future Function( + String video, + QuillController controller, +); + +OnVideoInsertCallback defaultOnVideoInsertCallback() { + return (videoUrl, controller) async { + controller + ..skipRequestKeyboard = true + ..insertVideoBlock(videoUrl: videoUrl); + }; +} + +/// When a new video picked this callback will called and you might want to +/// do some logic depending on your use case +typedef OnVideoInsertedCallback = Future Function( + String video, +); + +enum InsertVideoSource { + gallery, + camera, + link, +} + +/// Configurations for dealing with videos, on insert a video +/// on request picking a video +@immutable +class QuillToolbarVideoConfigurations { + const QuillToolbarVideoConfigurations({ + this.onRequestPickVideo, + this.onVideoInsertedCallback, + OnVideoInsertCallback? onVideoInsertCallback, + }) : _onVideoInsertCallback = onVideoInsertCallback; + + final OnRequestPickVideo? onRequestPickVideo; + + final OnVideoInsertedCallback? onVideoInsertedCallback; + + final OnVideoInsertCallback? _onVideoInsertCallback; + + OnVideoInsertCallback get onVideoInsertCallback { + return _onVideoInsertCallback ?? defaultOnVideoInsertCallback(); + } +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart similarity index 53% rename from flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button.dart rename to flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart index 25859832..1324c936 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart @@ -3,9 +3,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill/translations.dart'; -import 'package:image_picker/image_picker.dart'; -import '../../models/config/toolbar/buttons/camera.dart'; +import '../../../../logic/models/config/configurations.dart'; +import '../../../../logic/services/image_picker/image_options.dart'; +import '../../../models/config/toolbar/buttons/camera.dart'; +import '../../embed_types/camera.dart'; +import 'select_camera_action.dart'; class QuillToolbarCameraButton extends StatelessWidget { const QuillToolbarCameraButton({ @@ -70,17 +73,14 @@ class QuillToolbarCameraButton extends StatelessWidget { if (childBuilder != null) { childBuilder( QuillToolbarCameraButtonOptions( - onImagePickCallback: options.onImagePickCallback, onVideoPickCallback: options.onVideoPickCallback, afterButtonPressed: _afterButtonPressed(context), - cameraPickSettingSelector: options.cameraPickSettingSelector, - filePickImpl: options.filePickImpl, iconData: options.iconData, fillColor: options.fillColor, iconSize: options.iconSize, iconTheme: options.iconTheme, tooltip: options.tooltip, - webImagePickImpl: options.webImagePickImpl, + cameraConfigurations: options.cameraConfigurations, webVideoPickImpl: options.webVideoPickImpl, ), QuillToolbarCameraButtonExtraOptions( @@ -109,84 +109,92 @@ class QuillToolbarCameraButton extends StatelessWidget { ); } + Future _getCameraAction(BuildContext context) async { + final customCallback = + options.cameraConfigurations.onRequestCameraActionCallback; + if (customCallback != null) { + return await customCallback(context); + } + final cameraAction = await showDialog( + context: context, + builder: (ctx) => const SelectCameraActionDialog(), + ); + + return cameraAction; + } + Future _onPressedHandler( BuildContext context, QuillController controller, ) async { - if (onVideoPickCallback == null && onImagePickCallback == null) { - throw ArgumentError( - 'onImagePickCallback and onVideoPickCallback are both null', - ); - } - final selector = options.cameraPickSettingSelector ?? - (context) => showDialog( - context: context, - builder: (ctx) => AlertDialog( - contentPadding: EdgeInsets.zero, - backgroundColor: Colors.transparent, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (onImagePickCallback != null) - TextButton.icon( - icon: const Icon( - Icons.camera, - color: Colors.orangeAccent, - ), - label: Text('Camera'.i18n), - onPressed: () => - Navigator.pop(ctx, MediaPickSetting.camera), - ), - if (onVideoPickCallback != null) - TextButton.icon( - icon: const Icon( - Icons.video_call, - color: Colors.cyanAccent, - ), - label: Text('Video'.i18n), - onPressed: () => - Navigator.pop(ctx, MediaPickSetting.video), - ) - ], - ), - ), - ); - - final source = await selector(context); - if (source == null) { + // if (onVideoPickCallback == null && onImagePickCallback == null) { + // throw ArgumentError( + // 'onImagePickCallback and onVideoPickCallback are both null', + // ); + // } + + final cameraAction = await _getCameraAction(context); + + if (cameraAction == null) { return; } - switch (source) { - case MediaPickSetting.camera: - await ImageVideoUtils.handleImageButtonTap( - context, - controller, - ImageSource.camera, - onImagePickCallback!, - filePickImpl: filePickImpl, - webImagePickImpl: webImagePickImpl, - ); - break; - case MediaPickSetting.video: - await ImageVideoUtils.handleVideoButtonTap( - context, - controller, - ImageSource.camera, - onVideoPickCallback!, - filePickImpl: filePickImpl, - webVideoPickImpl: options.webVideoPickImpl, + + final imagePickerService = + QuillSharedExtensionsConfigurations.get(context: context) + .imagePickerService; + + switch (cameraAction) { + case CameraAction.video: + final videoFile = await imagePickerService.pickVideo( + source: ImageSource.camera, ); - break; - case MediaPickSetting.gallery: - throw ArgumentError( - 'Invalid MediaSetting for the camera button.\n' - 'gallery is not related to camera button', + if (videoFile == null) { + return; + } + // TODO: Implement this + case CameraAction.image: + final imageFile = await imagePickerService.pickImage( + source: ImageSource.camera, ); - case MediaPickSetting.link: - throw ArgumentError( - 'Invalid MediaSetting for the camera button.\n' - 'link is not related to camera button', + if (imageFile == null) { + return; + } + options.cameraConfigurations.onImageInsertCallback( + imageFile.path, + controller, ); + await options.cameraConfigurations.onImageInsertedCallback + ?.call(imageFile.path); } + + // final file = await switch (cameraAction) { + // CameraAction.image => + // imagePickerService.pickImage(source: ImageSource.camera), + // CameraAction.video => + // imagePickerService.pickVideo(source: ImageSource.camera), + // }; + + // switch (source) { + // case MediaPickSetting.camera: + // await ImageVideoUtils.handleImageButtonTap( + // context, + // controller, + // ImageSource.camera, + // onImagePickCallback!, + // filePickImpl: filePickImpl, + // webImagePickImpl: webImagePickImpl, + // ); + // break; + // case MediaPickSetting.video: + // await ImageVideoUtils.handleVideoButtonTap( + // context, + // controller, + // ImageSource.camera, + // onVideoPickCallback!, + // filePickImpl: filePickImpl, + // webVideoPickImpl: options.webVideoPickImpl, + // ); + // break; + // } } } diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/select_camera_action.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/select_camera_action.dart new file mode 100644 index 00000000..a79fa393 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/select_camera_action.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_quill/translations.dart'; + +import '../../embed_types/camera.dart'; + +class SelectCameraActionDialog extends StatelessWidget { + const SelectCameraActionDialog({super.key}); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + backgroundColor: Colors.transparent, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextButton.icon( + icon: const Icon( + Icons.camera, + color: Colors.orangeAccent, + ), + label: Text('Photo'.i18n), + onPressed: () => Navigator.pop(context, CameraAction.image), + ), + TextButton.icon( + icon: const Icon( + Icons.video_call, + color: Colors.cyanAccent, + ), + label: Text('Video'.i18n), + onPressed: () => Navigator.pop(context, CameraAction.video), + ) + ], + ), + ); + } +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart index fbc7d361..7451a435 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart @@ -115,6 +115,7 @@ class QuillToolbarImageButton extends StatelessWidget { final imagePickerService = QuillSharedExtensionsConfigurations.get(context: context) .imagePickerService; + final onRequestPickImage = options.imageButtonConfigurations.onRequestPickImage; if (onRequestPickImage != null) { @@ -125,6 +126,8 @@ class QuillToolbarImageButton extends StatelessWidget { if (imageUrl != null) { await options.imageButtonConfigurations .onImageInsertCallback(imageUrl, controller); + await options.imageButtonConfigurations.onImageInsertedCallback + ?.call(imageUrl); } return; } @@ -134,27 +137,26 @@ class QuillToolbarImageButton extends StatelessWidget { if (source == null) { return; } - final String? imageUrl; - switch (source) { - case InsertImageSource.gallery: - imageUrl = (await imagePickerService.pickImage( + + final imageUrl = switch (source) { + InsertImageSource.gallery => (await imagePickerService.pickImage( source: ImageSource.gallery, )) - ?.path; - break; - case InsertImageSource.link: - imageUrl = await _typeLink(context); - break; - case InsertImageSource.camera: - imageUrl = (await imagePickerService.pickImage( + ?.path, + InsertImageSource.link => await _typeLink(context), + InsertImageSource.camera => (await imagePickerService.pickImage( source: ImageSource.camera, )) - ?.path; - break; + ?.path, + }; + if (imageUrl == null) { + return; } - if (imageUrl != null && imageUrl.trim().isNotEmpty) { + if (imageUrl.trim().isNotEmpty) { await options.imageButtonConfigurations .onImageInsertCallback(imageUrl, controller); + await options.imageButtonConfigurations.onImageInsertedCallback + ?.call(imageUrl); } } @@ -164,6 +166,7 @@ class QuillToolbarImageButton extends StatelessWidget { builder: (_) => TypeLinkDialog( dialogTheme: options.dialogTheme, linkRegExp: options.linkRegExp, + linkType: LinkType.image, ), ); return value; diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart index ab18fb28..3c838934 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart @@ -32,7 +32,7 @@ class SelectImageSourceDialog extends StatelessWidget { ListTile( title: const Text('Link'), subtitle: const Text( - 'Paste a photo using https link', + 'Paste a photo using a link', ), leading: const Icon(Icons.link), onTap: () => Navigator.of(context).pop(InsertImageSource.link), diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button.dart deleted file mode 100644 index 212bd39e..00000000 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button.dart +++ /dev/null @@ -1,533 +0,0 @@ -// ignore_for_file: use_build_context_synchronously - -import 'dart:math' as math; -import 'dart:ui'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_quill/extensions.dart'; -import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/translations.dart'; -import 'package:image_picker/image_picker.dart'; - -import '../../models/config/toolbar/buttons/media_button.dart'; -import '../embed_types.dart'; -import 'utils/image_video_utils.dart'; - -/// Widget which combines [ImageButton] and [VideButton] widgets. This widget -/// has more customization and uses dialog similar to one which is used -/// on [http://quilljs.com]. -class QuillToolbarMediaButton extends StatelessWidget { - QuillToolbarMediaButton({ - required this.controller, - required this.options, - super.key, - }) : assert(options.type == QuillMediaType.image, - 'Video selection is not supported yet'); - - final QuillController controller; - final QuillToolbarMediaButtonOptions options; - - double _iconSize(BuildContext context) { - final baseFontSize = baseButtonExtraOptions(context).globalIconSize; - final iconSize = options.iconSize; - return iconSize ?? baseFontSize; - } - - VoidCallback? _afterButtonPressed(BuildContext context) { - return options.afterButtonPressed ?? - baseButtonExtraOptions(context).afterButtonPressed; - } - - QuillIconTheme? _iconTheme(BuildContext context) { - return options.iconTheme ?? baseButtonExtraOptions(context).iconTheme; - } - - QuillToolbarBaseButtonOptions baseButtonExtraOptions(BuildContext context) { - return context.requireQuillToolbarBaseButtonOptions; - } - - (IconData, String) get _defaultData { - switch (options.type) { - case QuillMediaType.image: - return (Icons.perm_media, 'Photo media button'); - case QuillMediaType.video: - throw UnsupportedError('The video is not supported yet.'); - } - } - - IconData _iconData(BuildContext context) { - return options.iconData ?? - baseButtonExtraOptions(context).iconData ?? - _defaultData.$1; - } - - String _tooltip(BuildContext context) { - return options.tooltip ?? - baseButtonExtraOptions(context).tooltip ?? - _defaultData.$2; - // ('Camera'.i18n); - } - - void _sharedOnPressed(BuildContext context) { - _onPressedHandler(context); - _afterButtonPressed(context); - } - - @override - Widget build(BuildContext context) { - final tooltip = _tooltip(context); - final iconSize = _iconSize(context); - final iconData = _iconData(context); - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions(context).childBuilder; - final iconTheme = _iconTheme(context); - - if (childBuilder != null) { - return childBuilder( - QuillToolbarMediaButtonOptions( - type: options.type, - onMediaPickedCallback: options.onMediaPickedCallback, - onImagePickCallback: options.onImagePickCallback, - onVideoPickCallback: options.onVideoPickCallback, - iconData: iconData, - afterButtonPressed: _afterButtonPressed(context), - autovalidateMode: options.autovalidateMode, - childrenSpacing: options.childrenSpacing, - dialogBarrierColor: options.dialogBarrierColor, - dialogTheme: options.dialogTheme, - filePickImpl: options.filePickImpl, - fillColor: options.fillColor, - galleryButtonText: options.galleryButtonText, - iconTheme: iconTheme, - iconSize: iconSize, - hintText: options.hintText, - labelText: options.labelText, - submitButtonSize: options.submitButtonSize, - linkButtonText: options.linkButtonText, - mediaFilePicker: options.mediaFilePicker, - submitButtonText: options.submitButtonText, - validationMessage: options.validationMessage, - webImagePickImpl: options.webImagePickImpl, - webVideoPickImpl: options.webVideoPickImpl, - tooltip: options.tooltip, - ), - QuillToolbarMediaButtonExtraOptions( - context: context, - controller: controller, - onPressed: () => _sharedOnPressed(context), - ), - ); - } - - final theme = Theme.of(context); - - final iconColor = - options.iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; - final iconFillColor = options.iconTheme?.iconUnselectedFillColor ?? - options.fillColor ?? - theme.canvasColor; - - return QuillToolbarIconButton( - icon: Icon(iconData, size: iconSize, color: iconColor), - tooltip: tooltip, - highlightElevation: 0, - hoverElevation: 0, - size: iconSize * 1.77, - fillColor: iconFillColor, - borderRadius: iconTheme?.borderRadius ?? 2, - onPressed: () => _sharedOnPressed(context), - ); - } - - Future _onPressedHandler(BuildContext context) async { - if (options.onMediaPickedCallback == null) { - _inputLink(context); - return; - } - final mediaSource = await showDialog( - context: context, - builder: (_) => MediaSourceSelectorDialog( - dialogTheme: options.dialogTheme, - galleryButtonText: options.galleryButtonText, - linkButtonText: options.linkButtonText, - ), - ); - if (mediaSource == null) { - return; - } - switch (mediaSource) { - case MediaPickSetting.gallery: - await _pickImage(); - break; - case MediaPickSetting.link: - _inputLink(context); - break; - case MediaPickSetting.camera: - await ImageVideoUtils.handleImageButtonTap( - context, - controller, - ImageSource.camera, - options.onImagePickCallback, - filePickImpl: options.filePickImpl, - webImagePickImpl: options.webImagePickImpl, - ); - break; - case MediaPickSetting.video: - await ImageVideoUtils.handleVideoButtonTap( - context, - controller, - ImageSource.camera, - options.onVideoPickCallback, - filePickImpl: options.filePickImpl, - webVideoPickImpl: options.webVideoPickImpl, - ); - break; - } - } - - Future _pickImage() async { - if (!(kIsWeb || isMobile() || isDesktop())) { - throw UnsupportedError( - 'Unsupported target platform: ${defaultTargetPlatform.name}', - ); - } - - final mediaFileUrl = await _pickMediaFileUrl(); - - if (mediaFileUrl != null) { - final index = controller.selection.baseOffset; - final length = controller.selection.extentOffset - index; - controller.replaceText( - index, - length, - BlockEmbed.image(mediaFileUrl), - null, - ); - } - } - - Future _pickMediaFileUrl() async { - final mediaFile = await options.mediaFilePicker?.call(options.type); - return mediaFile != null - ? options.onMediaPickedCallback?.call(mediaFile) - : null; - } - - void _inputLink(BuildContext context) { - showDialog( - context: context, - builder: (_) => MediaLinkDialog( - dialogTheme: options.dialogTheme, - labelText: options.labelText, - hintText: options.hintText, - buttonText: options.submitButtonText, - buttonSize: options.submitButtonSize, - childrenSpacing: options.childrenSpacing, - autovalidateMode: options.autovalidateMode, - validationMessage: options.validationMessage, - ), - ).then(_linkSubmitted); - } - - void _linkSubmitted(String? value) { - if (value != null && value.isNotEmpty) { - final index = controller.selection.baseOffset; - final length = controller.selection.extentOffset - index; - final data = options.type.isImage - ? BlockEmbed.image(value) - : BlockEmbed.video(value); - controller.replaceText(index, length, data, null); - } - } -} - -/// Provides a dialog for input link to media resource. -class MediaLinkDialog extends StatefulWidget { - const MediaLinkDialog({ - super.key, - this.link, - this.dialogTheme, - this.childrenSpacing = 16.0, - this.labelText, - this.hintText, - this.buttonText, - this.buttonSize, - this.autovalidateMode = AutovalidateMode.disabled, - this.validationMessage, - }) : assert(childrenSpacing > 0); - - final String? link; - final QuillDialogTheme? dialogTheme; - - /// The margin between child widgets in the dialog. - final double childrenSpacing; - - /// The text of label in link add mode. - final String? labelText; - - /// The hint text for link [TextField]. - final String? hintText; - - /// The text of the submit button. - final String? buttonText; - - /// The size of dialog buttons. - final Size? buttonSize; - - final AutovalidateMode autovalidateMode; - final String? validationMessage; - - @override - State createState() => _MediaLinkDialogState(); -} - -class _MediaLinkDialogState extends State { - final _linkFocus = FocusNode(); - final _linkController = TextEditingController(); - - @override - void dispose() { - _linkFocus.dispose(); - _linkController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - final constraints = widget.dialogTheme?.linkDialogConstraints ?? - () { - final size = MediaQuery.sizeOf(context); - final maxWidth = kIsWeb ? size.width / 4 : size.width - 80; - return BoxConstraints(maxWidth: maxWidth, maxHeight: 80); - }(); - - final buttonStyle = widget.buttonSize != null - ? Theme.of(context) - .elevatedButtonTheme - .style - ?.copyWith(fixedSize: MaterialStatePropertyAll(widget.buttonSize)) - : widget.dialogTheme?.buttonStyle; - - final isWrappable = widget.dialogTheme?.isWrappable ?? false; - - final children = [ - Text(widget.labelText ?? 'Enter media'.i18n), - UtilityWidgets.maybeWidget( - enabled: !isWrappable, - wrapper: (child) => Expanded( - child: child, - ), - child: Padding( - padding: EdgeInsets.symmetric(horizontal: widget.childrenSpacing), - child: TextFormField( - controller: _linkController, - focusNode: _linkFocus, - style: widget.dialogTheme?.inputTextStyle, - keyboardType: TextInputType.url, - textInputAction: TextInputAction.done, - decoration: InputDecoration( - labelStyle: widget.dialogTheme?.labelTextStyle, - hintText: widget.hintText, - ), - autofocus: true, - autovalidateMode: widget.autovalidateMode, - validator: _validateLink, - onChanged: _linkChanged, - ), - ), - ), - ElevatedButton( - onPressed: _canPress() ? _submitLink : null, - style: buttonStyle, - child: Text(widget.buttonText ?? 'Ok'.i18n), - ), - ]; - - return Dialog( - backgroundColor: widget.dialogTheme?.dialogBackgroundColor, - shape: widget.dialogTheme?.shape ?? - DialogTheme.of(context).shape ?? - RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), - child: ConstrainedBox( - constraints: constraints, - child: Padding( - padding: - widget.dialogTheme?.linkDialogPadding ?? const EdgeInsets.all(16), - child: Form( - child: isWrappable - ? Wrap( - alignment: WrapAlignment.center, - crossAxisAlignment: WrapCrossAlignment.center, - runSpacing: widget.dialogTheme?.runSpacing ?? 0.0, - children: children, - ) - : Row( - children: children, - ), - ), - ), - ), - ); - } - - bool _canPress() => _validateLink(_linkController.text) == null; - - void _linkChanged(String value) { - setState(() { - _linkController.text = value; - }); - } - - void _submitLink() => Navigator.pop(context, _linkController.text); - - String? _validateLink(String? value) { - if ((value?.isEmpty ?? false) || - !AutoFormatMultipleLinksRule.oneLineLinkRegExp.hasMatch(value!)) { - return widget.validationMessage ?? 'That is not a valid URL'; - } - - return null; - } -} - -/// Media souce selector. -class MediaSourceSelectorDialog extends StatelessWidget { - const MediaSourceSelectorDialog({ - super.key, - this.dialogTheme, - this.galleryButtonText, - this.linkButtonText, - }); - - final QuillDialogTheme? dialogTheme; - - /// The text of the gallery button [MediaSourceSelectorDialog]. - final String? galleryButtonText; - - /// The text of the link button [MediaSourceSelectorDialog]. - final String? linkButtonText; - - @override - Widget build(BuildContext context) { - final constraints = dialogTheme?.mediaSelectorDialogConstraints ?? - () { - final size = MediaQuery.sizeOf(context); - double maxWidth, maxHeight; - if (kIsWeb) { - maxWidth = size.width / 7; - maxHeight = size.height / 7; - } else { - maxWidth = size.width - 80; - maxHeight = maxWidth / 2; - } - return BoxConstraints(maxWidth: maxWidth, maxHeight: maxHeight); - }(); - - final shape = dialogTheme?.shape ?? - DialogTheme.of(context).shape ?? - RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)); - - return Dialog( - backgroundColor: dialogTheme?.dialogBackgroundColor, - shape: shape, - child: ConstrainedBox( - constraints: constraints, - child: Padding( - padding: dialogTheme?.mediaSelectorDialogPadding ?? - const EdgeInsets.all(16), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: TextButtonWithIcon( - icon: Icons.collections, - label: galleryButtonText ?? 'Gallery'.i18n, - onPressed: () => - Navigator.pop(context, MediaPickSetting.gallery), - ), - ), - const SizedBox(width: 10), - Expanded( - child: TextButtonWithIcon( - icon: Icons.link, - label: linkButtonText ?? 'Link'.i18n, - onPressed: () => - Navigator.pop(context, MediaPickSetting.link), - ), - ) - ], - ), - ), - ), - ); - } -} - -class TextButtonWithIcon extends StatelessWidget { - const TextButtonWithIcon({ - required this.label, - required this.icon, - required this.onPressed, - this.textStyle, - super.key, - }); - - final String label; - final IconData icon; - final VoidCallback onPressed; - final TextStyle? textStyle; - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - final scale = MediaQuery.maybeOf(context)?.textScaleFactor ?? 1; - final gap = scale <= 1 ? 8.0 : lerpDouble(8, 4, math.min(scale - 1, 1))!; - final buttonStyle = TextButtonTheme.of(context).style; - final shape = buttonStyle?.shape?.resolve({}) ?? - const RoundedRectangleBorder( - borderRadius: BorderRadius.all( - Radius.circular(4), - ), - ); - return Material( - shape: shape, - textStyle: textStyle ?? - theme.textButtonTheme.style?.textStyle?.resolve({}) ?? - theme.textTheme.labelLarge, - elevation: buttonStyle?.elevation?.resolve({}) ?? 0, - child: InkWell( - customBorder: shape, - onTap: onPressed, - child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Icon(icon), - SizedBox(height: gap), - Flexible(child: Text(label)), - ], - ), - ), - ), - ); - } -} - -/// Default file picker. -// Future _defaultMediaPicker(QuillMediaType mediaType) async { -// final pickedFile = mediaType.isImage -// ? await ImagePicker().pickImage(source: ImageSource.gallery) -// : await ImagePicker().pickVideo(source: ImageSource.gallery); - -// if (pickedFile != null) { -// return QuillFile( -// name: pickedFile.name, -// path: pickedFile.path, -// bytes: await pickedFile.readAsBytes(), -// ); -// } - -// return null; -// } diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button/media_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button/media_button.dart new file mode 100644 index 00000000..1d8e5fcf --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button/media_button.dart @@ -0,0 +1,533 @@ +// // ignore_for_file: use_build_context_synchronously + +// import 'dart:math' as math; +// import 'dart:ui'; + +// import 'package:flutter/foundation.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter_quill/extensions.dart'; +// import 'package:flutter_quill/flutter_quill.dart'; +// import 'package:flutter_quill/translations.dart'; +// import 'package:image_picker/image_picker.dart'; + +// import '../../../models/config/toolbar/buttons/media_button.dart'; +// import '../../embed_types.dart'; +// import '../utils/image_video_utils.dart'; + +// /// Widget which combines [ImageButton] and [VideButton] widgets. This widget +// /// has more customization and uses dialog similar to one which is used +// /// on [http://quilljs.com]. +// class QuillToolbarMediaButton extends StatelessWidget { +// QuillToolbarMediaButton({ +// required this.controller, +// required this.options, +// super.key, +// }) : assert(options.type == QuillMediaType.image, +// 'Video selection is not supported yet'); + +// final QuillController controller; +// final QuillToolbarMediaButtonOptions options; + +// double _iconSize(BuildContext context) { +// final baseFontSize = baseButtonExtraOptions(context).globalIconSize; +// final iconSize = options.iconSize; +// return iconSize ?? baseFontSize; +// } + +// VoidCallback? _afterButtonPressed(BuildContext context) { +// return options.afterButtonPressed ?? +// baseButtonExtraOptions(context).afterButtonPressed; +// } + +// QuillIconTheme? _iconTheme(BuildContext context) { +// return options.iconTheme ?? baseButtonExtraOptions(context).iconTheme; +// } + +// QuillToolbarBaseButtonOptions baseButtonExtraOptions(BuildContext context) { +// return context.requireQuillToolbarBaseButtonOptions; +// } + +// (IconData, String) get _defaultData { +// switch (options.type) { +// case QuillMediaType.image: +// return (Icons.perm_media, 'Photo media button'); +// case QuillMediaType.video: +// throw UnsupportedError('The video is not supported yet.'); +// } +// } + +// IconData _iconData(BuildContext context) { +// return options.iconData ?? +// baseButtonExtraOptions(context).iconData ?? +// _defaultData.$1; +// } + +// String _tooltip(BuildContext context) { +// return options.tooltip ?? +// baseButtonExtraOptions(context).tooltip ?? +// _defaultData.$2; +// // ('Camera'.i18n); +// } + +// void _sharedOnPressed(BuildContext context) { +// _onPressedHandler(context); +// _afterButtonPressed(context); +// } + +// @override +// Widget build(BuildContext context) { +// final tooltip = _tooltip(context); +// final iconSize = _iconSize(context); +// final iconData = _iconData(context); +// final childBuilder = +// options.childBuilder ?? baseButtonExtraOptions(context).childBuilder; +// final iconTheme = _iconTheme(context); + +// if (childBuilder != null) { +// return childBuilder( +// QuillToolbarMediaButtonOptions( +// type: options.type, +// onMediaPickedCallback: options.onMediaPickedCallback, +// onImagePickCallback: options.onImagePickCallback, +// onVideoPickCallback: options.onVideoPickCallback, +// iconData: iconData, +// afterButtonPressed: _afterButtonPressed(context), +// autovalidateMode: options.autovalidateMode, +// childrenSpacing: options.childrenSpacing, +// dialogBarrierColor: options.dialogBarrierColor, +// dialogTheme: options.dialogTheme, +// filePickImpl: options.filePickImpl, +// fillColor: options.fillColor, +// galleryButtonText: options.galleryButtonText, +// iconTheme: iconTheme, +// iconSize: iconSize, +// hintText: options.hintText, +// labelText: options.labelText, +// submitButtonSize: options.submitButtonSize, +// linkButtonText: options.linkButtonText, +// mediaFilePicker: options.mediaFilePicker, +// submitButtonText: options.submitButtonText, +// validationMessage: options.validationMessage, +// webImagePickImpl: options.webImagePickImpl, +// webVideoPickImpl: options.webVideoPickImpl, +// tooltip: options.tooltip, +// ), +// QuillToolbarMediaButtonExtraOptions( +// context: context, +// controller: controller, +// onPressed: () => _sharedOnPressed(context), +// ), +// ); +// } + +// final theme = Theme.of(context); + +// final iconColor = +// options.iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; +// final iconFillColor = options.iconTheme?.iconUnselectedFillColor ?? +// options.fillColor ?? +// theme.canvasColor; + +// return QuillToolbarIconButton( +// icon: Icon(iconData, size: iconSize, color: iconColor), +// tooltip: tooltip, +// highlightElevation: 0, +// hoverElevation: 0, +// size: iconSize * 1.77, +// fillColor: iconFillColor, +// borderRadius: iconTheme?.borderRadius ?? 2, +// onPressed: () => _sharedOnPressed(context), +// ); +// } + +// Future _onPressedHandler(BuildContext context) async { +// if (options.onMediaPickedCallback == null) { +// _inputLink(context); +// return; +// } +// final mediaSource = await showDialog( +// context: context, +// builder: (_) => MediaSourceSelectorDialog( +// dialogTheme: options.dialogTheme, +// galleryButtonText: options.galleryButtonText, +// linkButtonText: options.linkButtonText, +// ), +// ); +// if (mediaSource == null) { +// return; +// } +// switch (mediaSource) { +// case MediaPickSetting.gallery: +// await _pickImage(); +// break; +// case MediaPickSetting.link: +// _inputLink(context); +// break; +// case MediaPickSetting.camera: +// await ImageVideoUtils.handleImageButtonTap( +// context, +// controller, +// ImageSource.camera, +// options.onImagePickCallback, +// filePickImpl: options.filePickImpl, +// webImagePickImpl: options.webImagePickImpl, +// ); +// break; +// case MediaPickSetting.video: +// await ImageVideoUtils.handleVideoButtonTap( +// context, +// controller, +// ImageSource.camera, +// options.onVideoPickCallback, +// filePickImpl: options.filePickImpl, +// webVideoPickImpl: options.webVideoPickImpl, +// ); +// break; +// } +// } + +// Future _pickImage() async { +// if (!(kIsWeb || isMobile() || isDesktop())) { +// throw UnsupportedError( +// 'Unsupported target platform: ${defaultTargetPlatform.name}', +// ); +// } + +// final mediaFileUrl = await _pickMediaFileUrl(); + +// if (mediaFileUrl != null) { +// final index = controller.selection.baseOffset; +// final length = controller.selection.extentOffset - index; +// controller.replaceText( +// index, +// length, +// BlockEmbed.image(mediaFileUrl), +// null, +// ); +// } +// } + +// Future _pickMediaFileUrl() async { +// final mediaFile = await options.mediaFilePicker?.call(options.type); +// return mediaFile != null +// ? options.onMediaPickedCallback?.call(mediaFile) +// : null; +// } + +// void _inputLink(BuildContext context) { +// showDialog( +// context: context, +// builder: (_) => MediaLinkDialog( +// dialogTheme: options.dialogTheme, +// labelText: options.labelText, +// hintText: options.hintText, +// buttonText: options.submitButtonText, +// buttonSize: options.submitButtonSize, +// childrenSpacing: options.childrenSpacing, +// autovalidateMode: options.autovalidateMode, +// validationMessage: options.validationMessage, +// ), +// ).then(_linkSubmitted); +// } + +// void _linkSubmitted(String? value) { +// if (value != null && value.isNotEmpty) { +// final index = controller.selection.baseOffset; +// final length = controller.selection.extentOffset - index; +// final data = options.type.isImage +// ? BlockEmbed.image(value) +// : BlockEmbed.video(value); +// controller.replaceText(index, length, data, null); +// } +// } +// } + +// /// Provides a dialog for input link to media resource. +// class MediaLinkDialog extends StatefulWidget { +// const MediaLinkDialog({ +// super.key, +// this.link, +// this.dialogTheme, +// this.childrenSpacing = 16.0, +// this.labelText, +// this.hintText, +// this.buttonText, +// this.buttonSize, +// this.autovalidateMode = AutovalidateMode.disabled, +// this.validationMessage, +// }) : assert(childrenSpacing > 0); + +// final String? link; +// final QuillDialogTheme? dialogTheme; + +// /// The margin between child widgets in the dialog. +// final double childrenSpacing; + +// /// The text of label in link add mode. +// final String? labelText; + +// /// The hint text for link [TextField]. +// final String? hintText; + +// /// The text of the submit button. +// final String? buttonText; + +// /// The size of dialog buttons. +// final Size? buttonSize; + +// final AutovalidateMode autovalidateMode; +// final String? validationMessage; + +// @override +// State createState() => _MediaLinkDialogState(); +// } + +// class _MediaLinkDialogState extends State { +// final _linkFocus = FocusNode(); +// final _linkController = TextEditingController(); + +// @override +// void dispose() { +// _linkFocus.dispose(); +// _linkController.dispose(); +// super.dispose(); +// } + +// @override +// Widget build(BuildContext context) { +// final constraints = widget.dialogTheme?.linkDialogConstraints ?? +// () { +// final size = MediaQuery.sizeOf(context); +// final maxWidth = kIsWeb ? size.width / 4 : size.width - 80; +// return BoxConstraints(maxWidth: maxWidth, maxHeight: 80); +// }(); + +// final buttonStyle = widget.buttonSize != null +// ? Theme.of(context) +// .elevatedButtonTheme +// .style +// ?.copyWith(fixedSize: MaterialStatePropertyAll(widget.buttonSize)) +// : widget.dialogTheme?.buttonStyle; + +// final isWrappable = widget.dialogTheme?.isWrappable ?? false; + +// final children = [ +// Text(widget.labelText ?? 'Enter media'.i18n), +// UtilityWidgets.maybeWidget( +// enabled: !isWrappable, +// wrapper: (child) => Expanded( +// child: child, +// ), +// child: Padding( +// padding: EdgeInsets.symmetric(horizontal: widget.childrenSpacing), +// child: TextFormField( +// controller: _linkController, +// focusNode: _linkFocus, +// style: widget.dialogTheme?.inputTextStyle, +// keyboardType: TextInputType.url, +// textInputAction: TextInputAction.done, +// decoration: InputDecoration( +// labelStyle: widget.dialogTheme?.labelTextStyle, +// hintText: widget.hintText, +// ), +// autofocus: true, +// autovalidateMode: widget.autovalidateMode, +// validator: _validateLink, +// onChanged: _linkChanged, +// ), +// ), +// ), +// ElevatedButton( +// onPressed: _canPress() ? _submitLink : null, +// style: buttonStyle, +// child: Text(widget.buttonText ?? 'Ok'.i18n), +// ), +// ]; + +// return Dialog( +// backgroundColor: widget.dialogTheme?.dialogBackgroundColor, +// shape: widget.dialogTheme?.shape ?? +// DialogTheme.of(context).shape ?? +// RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), +// child: ConstrainedBox( +// constraints: constraints, +// child: Padding( +// padding: +// widget.dialogTheme?.linkDialogPadding ?? const EdgeInsets.all(16), +// child: Form( +// child: isWrappable +// ? Wrap( +// alignment: WrapAlignment.center, +// crossAxisAlignment: WrapCrossAlignment.center, +// runSpacing: widget.dialogTheme?.runSpacing ?? 0.0, +// children: children, +// ) +// : Row( +// children: children, +// ), +// ), +// ), +// ), +// ); +// } + +// bool _canPress() => _validateLink(_linkController.text) == null; + +// void _linkChanged(String value) { +// setState(() { +// _linkController.text = value; +// }); +// } + +// void _submitLink() => Navigator.pop(context, _linkController.text); + +// String? _validateLink(String? value) { +// if ((value?.isEmpty ?? false) || +// !AutoFormatMultipleLinksRule.oneLineLinkRegExp.hasMatch(value!)) { +// return widget.validationMessage ?? 'That is not a valid URL'; +// } + +// return null; +// } +// } + +// /// Media souce selector. +// class MediaSourceSelectorDialog extends StatelessWidget { +// const MediaSourceSelectorDialog({ +// super.key, +// this.dialogTheme, +// this.galleryButtonText, +// this.linkButtonText, +// }); + +// final QuillDialogTheme? dialogTheme; + +// /// The text of the gallery button [MediaSourceSelectorDialog]. +// final String? galleryButtonText; + +// /// The text of the link button [MediaSourceSelectorDialog]. +// final String? linkButtonText; + +// @override +// Widget build(BuildContext context) { +// final constraints = dialogTheme?.mediaSelectorDialogConstraints ?? +// () { +// final size = MediaQuery.sizeOf(context); +// double maxWidth, maxHeight; +// if (kIsWeb) { +// maxWidth = size.width / 7; +// maxHeight = size.height / 7; +// } else { +// maxWidth = size.width - 80; +// maxHeight = maxWidth / 2; +// } +// return BoxConstraints(maxWidth: maxWidth, maxHeight: maxHeight); +// }(); + +// final shape = dialogTheme?.shape ?? +// DialogTheme.of(context).shape ?? +// RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)); + +// return Dialog( +// backgroundColor: dialogTheme?.dialogBackgroundColor, +// shape: shape, +// child: ConstrainedBox( +// constraints: constraints, +// child: Padding( +// padding: dialogTheme?.mediaSelectorDialogPadding ?? +// const EdgeInsets.all(16), +// child: Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// Expanded( +// child: TextButtonWithIcon( +// icon: Icons.collections, +// label: galleryButtonText ?? 'Gallery'.i18n, +// onPressed: () => +// Navigator.pop(context, MediaPickSetting.gallery), +// ), +// ), +// const SizedBox(width: 10), +// Expanded( +// child: TextButtonWithIcon( +// icon: Icons.link, +// label: linkButtonText ?? 'Link'.i18n, +// onPressed: () => +// Navigator.pop(context, MediaPickSetting.link), +// ), +// ) +// ], +// ), +// ), +// ), +// ); +// } +// } + +// class TextButtonWithIcon extends StatelessWidget { +// const TextButtonWithIcon({ +// required this.label, +// required this.icon, +// required this.onPressed, +// this.textStyle, +// super.key, +// }); + +// final String label; +// final IconData icon; +// final VoidCallback onPressed; +// final TextStyle? textStyle; + +// @override +// Widget build(BuildContext context) { +// final theme = Theme.of(context); +// final scale = MediaQuery.maybeOf(context)?.textScaleFactor ?? 1; +// final gap = scale <= 1 ? 8.0 : lerpDouble(8, 4, math.min(scale - 1, 1))!; +// final buttonStyle = TextButtonTheme.of(context).style; +// final shape = buttonStyle?.shape?.resolve({}) ?? +// const RoundedRectangleBorder( +// borderRadius: BorderRadius.all( +// Radius.circular(4), +// ), +// ); +// return Material( +// shape: shape, +// textStyle: textStyle ?? +// theme.textButtonTheme.style?.textStyle?.resolve({}) ?? +// theme.textTheme.labelLarge, +// elevation: buttonStyle?.elevation?.resolve({}) ?? 0, +// child: InkWell( +// customBorder: shape, +// onTap: onPressed, +// child: Padding( +// padding: const EdgeInsets.all(16), +// child: Column( +// mainAxisSize: MainAxisSize.min, +// children: [ +// Icon(icon), +// SizedBox(height: gap), +// Flexible(child: Text(label)), +// ], +// ), +// ), +// ), +// ); +// } +// } + +// /// Default file picker. +// // Future _defaultMediaPicker(QuillMediaType mediaType) async { +// // final pickedFile = mediaType.isImage +// // ? await ImagePicker().pickImage(source: ImageSource.gallery) +// // : await ImagePicker().pickVideo(source: ImageSource.gallery); + +// // if (pickedFile != null) { +// // return QuillFile( +// // name: pickedFile.name, +// // path: pickedFile.path, +// // bytes: await pickedFile.readAsBytes(), +// // ); +// // } + +// // return null; +// // } diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/select_video_source.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/select_video_source.dart new file mode 100644 index 00000000..7187f10b --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/select_video_source.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; + +import '../../embed_types/video.dart'; + +class SelectVideoSourceDialog extends StatelessWidget { + const SelectVideoSourceDialog({super.key}); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 230, + width: double.infinity, + child: SingleChildScrollView( + child: Column( + children: [ + ListTile( + title: const Text('Gallery'), + subtitle: const Text( + 'Pick a video from your gallery', + ), + leading: const Icon(Icons.photo_sharp), + onTap: () => Navigator.of(context).pop(InsertVideoSource.gallery), + ), + ListTile( + title: const Text('Camera'), + subtitle: const Text( + 'Record a video using your phone camera', + ), + leading: const Icon(Icons.camera), + onTap: () => Navigator.of(context).pop(InsertVideoSource.camera), + ), + ListTile( + title: const Text('Link'), + subtitle: const Text( + 'Paste a video using a link', + ), + leading: const Icon(Icons.link), + onTap: () => Navigator.of(context).pop(InsertVideoSource.link), + ), + ], + ), + ), + ); + } +} + +Future showSelectVideoSourceDialog({ + required BuildContext context, +}) async { + final imageSource = await showModalBottomSheet( + showDragHandle: true, + context: context, + constraints: const BoxConstraints(maxWidth: 640), + builder: (context) => const SelectVideoSourceDialog(), + ); + return imageSource; +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart similarity index 62% rename from flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button.dart rename to flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart index 2bed465d..2b9bace3 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart @@ -2,11 +2,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:image_picker/image_picker.dart'; -import '../../models/config/toolbar/buttons/video.dart'; -import '../embed_types.dart'; -import 'utils/image_video_utils.dart'; +import '../../../../logic/models/config/configurations.dart'; +import '../../../../logic/services/image_picker/image_options.dart'; +import '../../../models/config/toolbar/buttons/video.dart'; +import '../../embed_types.dart'; +import '../../embed_types/video.dart'; +import '../utils/image_video_utils.dart'; +import 'select_video_source.dart'; class QuillToolbarVideoButton extends StatelessWidget { const QuillToolbarVideoButton({ @@ -78,15 +81,13 @@ class QuillToolbarVideoButton extends StatelessWidget { afterButtonPressed: _afterButtonPressed(context), iconData: iconData, dialogTheme: options.dialogTheme, - filePickImpl: options.filePickImpl, fillColor: iconFillColor, iconSize: options.iconSize, linkRegExp: options.linkRegExp, tooltip: options.tooltip, - mediaPickSettingSelector: options.mediaPickSettingSelector, iconTheme: options.iconTheme, - onVideoPickCallback: options.onVideoPickCallback, webVideoPickImpl: options.webVideoPickImpl, + videoConfigurations: options.videoConfigurations, ), QuillToolbarVideoButtonExtraOptions( context: context, @@ -109,39 +110,67 @@ class QuillToolbarVideoButton extends StatelessWidget { } Future _onPressedHandler(BuildContext context) async { - if (options.onVideoPickCallback != null) { - final selector = options.mediaPickSettingSelector ?? - ImageVideoUtils.selectMediaPickSetting; - final source = await selector(context); - if (source != null) { - if (source == MediaPickSetting.gallery) { - _pickVideo(context); - } else { - await _typeLink(context); - } + final imagePickerService = + QuillSharedExtensionsConfigurations.get(context: context) + .imagePickerService; + + final onRequestPickVideo = options.videoConfigurations.onRequestPickVideo; + if (onRequestPickVideo != null) { + final videoUrl = await onRequestPickVideo(context, imagePickerService); + if (videoUrl != null) { + await options.videoConfigurations + .onVideoInsertCallback(videoUrl, controller); + await options.videoConfigurations.onVideoInsertedCallback + ?.call(videoUrl); } - } else { - await _typeLink(context); + return; } - } - void _pickVideo(BuildContext context) => ImageVideoUtils.handleVideoButtonTap( - context, - controller, - ImageSource.gallery, - options.onVideoPickCallback!, - filePickImpl: options.filePickImpl, - webVideoPickImpl: options.webVideoPickImpl, - ); + final imageSource = await showSelectVideoSourceDialog(context: context); + + if (imageSource == null) { + return; + } + + final videoUrl = switch (imageSource) { + InsertVideoSource.gallery => + (await imagePickerService.pickVideo(source: ImageSource.gallery))?.path, + InsertVideoSource.camera => + (await imagePickerService.pickVideo(source: ImageSource.camera))?.path, + InsertVideoSource.link => await _typeLink(context), + }; + if (videoUrl == null) { + return; + } + + if (videoUrl.trim().isNotEmpty) { + await options.videoConfigurations + .onVideoInsertCallback(videoUrl, controller); + await options.videoConfigurations.onVideoInsertedCallback?.call(videoUrl); + } + + // if (options.onVideoPickCallback != null) { + // final selector = options.mediaPickSettingSelector ?? + // ImageVideoUtils.selectMediaPickSetting; + // final source = await selector(context); + // if (source != null) { + // if (source == MediaPickSetting.gallery) { + // } else { + // await _typeLink(context); + // } + // } + // } else {} + } - Future _typeLink(BuildContext context) async { + Future _typeLink(BuildContext context) async { final value = await showDialog( context: context, builder: (_) => TypeLinkDialog( dialogTheme: options.dialogTheme, + linkType: LinkType.video, ), ); - _linkSubmitted(value); + return value; } void _linkSubmitted(String? value) { diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart index b1b5bd8e..c685bb4a 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart @@ -2,8 +2,7 @@ import 'package:flutter/widgets.dart' show Color; import 'package:flutter_quill/flutter_quill.dart'; import '../../../../embeds/embed_types.dart'; -import '../../../../embeds/embed_types/image.dart'; -import 'image.dart'; +import '../../../../embeds/embed_types/camera.dart'; class QuillToolbarCameraButtonExtraOptions extends QuillToolbarBaseButtonExtraOptions { @@ -18,7 +17,7 @@ class QuillToolbarCameraButtonOptions extends QuillToolbarBaseButtonOptions< QuillToolbarCameraButtonOptions, QuillToolbarCameraButtonExtraOptions> { const QuillToolbarCameraButtonOptions({ required this.onVideoPickCallback, - this.imageConfigurations = const QuillToolbarImageButtonConfigurations(), + this.cameraConfigurations = const QuillToolbarCameraConfigurations(), this.webVideoPickImpl, this.iconSize, this.fillColor, @@ -30,13 +29,13 @@ class QuillToolbarCameraButtonOptions extends QuillToolbarBaseButtonOptions< super.controller, }); - final QuillToolbarImageButtonConfigurations imageConfigurations; + final double? iconSize; + + final Color? fillColor; final OnVideoPickCallback onVideoPickCallback; final WebVideoPickImpl? webVideoPickImpl; - final double? iconSize; - - final Color? fillColor; + final QuillToolbarCameraConfigurations cameraConfigurations; } diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart index d6195c4c..b0084eeb 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart @@ -2,8 +2,6 @@ import 'package:flutter/widgets.dart' show Color; import 'package:flutter_quill/flutter_quill.dart'; import 'package:meta/meta.dart' show immutable; -import '../../../../../logic/extensions/controller.dart'; -import '../../../../embeds/embed_types.dart'; import '../../../../embeds/embed_types/image.dart'; class QuillToolbarImageButtonExtraOptions @@ -31,8 +29,7 @@ class QuillToolbarImageButtonOptions extends QuillToolbarBaseButtonOptions< this.fillColor, this.dialogTheme, this.linkRegExp, - this.imageButtonConfigurations = - const QuillToolbarImageButtonConfigurations(), + this.imageButtonConfigurations = const QuillToolbarImageConfigurations(), }); final double? iconSize; @@ -43,23 +40,5 @@ class QuillToolbarImageButtonOptions extends QuillToolbarBaseButtonOptions< /// [imageLinkRegExp] is a regular expression to identify image links. final RegExp? linkRegExp; - final QuillToolbarImageButtonConfigurations imageButtonConfigurations; -} - -class QuillToolbarImageButtonConfigurations { - const QuillToolbarImageButtonConfigurations({ - this.onRequestPickImage, - this.onImagePickedCallback, - OnImageInsertCallback? onImageInsertCallback, - }) : _onImageInsertCallback = onImageInsertCallback; - - final OnRequestPickImage? onRequestPickImage; - - final OnImagePickedCallback? onImagePickedCallback; - - final OnImageInsertCallback? _onImageInsertCallback; - - OnImageInsertCallback get onImageInsertCallback { - return _onImageInsertCallback ?? defaultOnImageInsertCallback(); - } + final QuillToolbarImageConfigurations imageButtonConfigurations; } diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart index e35d59e9..a1c6fca9 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart @@ -18,7 +18,6 @@ class QuillToolbarMediaButtonOptions extends QuillToolbarBaseButtonOptions< const QuillToolbarMediaButtonOptions({ required this.type, required this.onMediaPickedCallback, - required this.onImagePickCallback, required this.onVideoPickCallback, this.dialogBarrierColor, this.mediaFilePicker, @@ -35,7 +34,6 @@ class QuillToolbarMediaButtonOptions extends QuillToolbarBaseButtonOptions< this.linkButtonText, this.validationMessage, this.filePickImpl, - this.webImagePickImpl, this.webVideoPickImpl, super.iconData, super.afterButtonPressed, diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart index 96f121ec..4e030192 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart @@ -2,6 +2,7 @@ import 'package:flutter/widgets.dart' show Color; import 'package:flutter_quill/flutter_quill.dart'; import '../../../../embeds/embed_types.dart'; +import '../../../../embeds/embed_types/video.dart'; class QuillToolbarVideoButtonExtraOptions extends QuillToolbarBaseButtonExtraOptions { @@ -17,10 +18,7 @@ class QuillToolbarVideoButtonOptions extends QuillToolbarBaseButtonOptions< const QuillToolbarVideoButtonOptions({ this.linkRegExp, this.dialogTheme, - this.onVideoPickCallback, this.webVideoPickImpl, - this.filePickImpl, - this.mediaPickSettingSelector, this.fillColor, this.iconSize, super.iconData, @@ -29,16 +27,15 @@ class QuillToolbarVideoButtonOptions extends QuillToolbarBaseButtonOptions< super.iconTheme, super.childBuilder, super.controller, + this.videoConfigurations = const QuillToolbarVideoConfigurations(), }); final RegExp? linkRegExp; final QuillDialogTheme? dialogTheme; - final OnVideoPickCallback? onVideoPickCallback; + final QuillToolbarVideoConfigurations videoConfigurations; final WebVideoPickImpl? webVideoPickImpl; - final FilePickImpl? filePickImpl; - final Color? fillColor; final double? iconSize; diff --git a/lib/src/models/config/shared_configurations.dart b/lib/src/models/config/shared_configurations.dart index 78dd6b06..98a87e03 100644 --- a/lib/src/models/config/shared_configurations.dart +++ b/lib/src/models/config/shared_configurations.dart @@ -18,6 +18,7 @@ class QuillSharedConfigurations extends Equatable { this.animationConfigurations = const QuillAnimationConfigurations( checkBoxPointItem: false, ), + this.extraConfigurations = const {}, }); // This is just example or showcase of this major update to make the library @@ -36,6 +37,9 @@ class QuillSharedConfigurations extends Equatable { /// To configure which animations you want to be enabled final QuillAnimationConfigurations animationConfigurations; + /// Store custom configurations in here and use it in the widget tree + final Map extraConfigurations; + @override List get props => [ dialogBarrierColor, diff --git a/pubspec.yaml b/pubspec.yaml index 5be31f2b..56015302 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.1.11 +version: 8.1.12 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From 0c6d33d0fcc6e49dc652079bfce66dd3a509da86 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 21:48:41 +0300 Subject: [PATCH 030/210] Fix warrnings --- CHANGELOG.md | 2 +- example/lib/pages/home_page.dart | 2 -- .../embeds/toolbar/utils/image_video_utils.dart | 15 ++++++++++----- .../embeds/toolbar/video_button/video_button.dart | 15 +++++++-------- .../lib/presentation/embeds/utils.dart | 2 -- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1153a751..4f19545b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ ## [8.1.12] -- Add the option to add configurations for `fresh_quill_extensions` using `extraConfigurations` +- Add the option to add configurations for `flutter_quill_extensions` using `extraConfigurations` ## [8.1.11] - Follow dart best practices by using `lints` and remove `pedantic` as well `platform` since they are not used diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index f5a4a4a5..f5fd5239 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -5,7 +5,6 @@ import 'dart:convert'; import 'dart:io' show File, Platform; import 'dart:ui'; -import 'package:file_picker/file_picker.dart'; import 'package:filesystem_picker/filesystem_picker.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -14,7 +13,6 @@ import 'package:flutter_quill/extensions.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; import 'package:flutter_quill_extensions/presentation/embeds/embed_types/image.dart'; -import 'package:flutter_quill_extensions/presentation/models/config/toolbar/buttons/video.dart'; import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart'; diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/utils/image_video_utils.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/utils/image_video_utils.dart index b4d6ae57..bb35dddc 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/utils/image_video_utils.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/utils/image_video_utils.dart @@ -126,7 +126,8 @@ class TypeLinkDialogState extends State { // color: Colors.orangeAccent, // ), // label: Text('Gallery'.i18n), -// onPressed: () => Navigator.pop(ctx, MediaPickSetting.gallery), +// onPressed: () => Navigator.pop(ctx, +// MediaPickSetting.gallery), // ), // TextButton.icon( // icon: const Icon( @@ -156,7 +157,8 @@ class TypeLinkDialogState extends State { // imageUrl = await webImagePickImpl(onImagePickCallback); // return; // } -// final file = await ImagePicker().pickImage(source: ImageSource.gallery); +// final file = await ImagePicker() +//.pickImage(source: ImageSource.gallery); // imageUrl = file?.path; // if (imageUrl == null) { // return; @@ -166,7 +168,8 @@ class TypeLinkDialogState extends State { // } else { // assert(filePickImpl != null, 'Desktop must provide filePickImpl'); // imageUrl = -// await _pickImageDesktop(context, filePickImpl!, onImagePickCallback); +// await _pickImageDesktop +//(context, filePickImpl!, onImagePickCallback); // } // if (imageUrl == null) { @@ -227,11 +230,13 @@ class TypeLinkDialogState extends State { // } else { // assert(filePickImpl != null, 'Desktop must provide filePickImpl'); // videoUrl = -// await _pickVideoDesktop(context, filePickImpl!, onVideoPickCallback); +// await _pickVideoDesktop(context, filePickImpl!, +// onVideoPickCallback); // } // if (videoUrl != null) { -// controller.replaceText(index, length, BlockEmbed.video(videoUrl), null); +// controller.replaceText(index, length, BlockEmbed.video(videoUrl), +// null); // } // } diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart index 2b9bace3..f06d59df 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart @@ -6,7 +6,6 @@ import 'package:flutter_quill/flutter_quill.dart'; import '../../../../logic/models/config/configurations.dart'; import '../../../../logic/services/image_picker/image_options.dart'; import '../../../models/config/toolbar/buttons/video.dart'; -import '../../embed_types.dart'; import '../../embed_types/video.dart'; import '../utils/image_video_utils.dart'; import 'select_video_source.dart'; @@ -173,12 +172,12 @@ class QuillToolbarVideoButton extends StatelessWidget { return value; } - void _linkSubmitted(String? value) { - if (value != null && value.isNotEmpty) { - final index = controller.selection.baseOffset; - final length = controller.selection.extentOffset - index; + // void _linkSubmitted(String? value) { + // if (value != null && value.isNotEmpty) { + // final index = controller.selection.baseOffset; + // final length = controller.selection.extentOffset - index; - controller.replaceText(index, length, BlockEmbed.video(value), null); - } - } + // controller.replaceText(index, length, BlockEmbed.video(value), null); + // } + // } } diff --git a/flutter_quill_extensions/lib/presentation/embeds/utils.dart b/flutter_quill_extensions/lib/presentation/embeds/utils.dart index 68f8c314..edd463de 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/utils.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/utils.dart @@ -2,9 +2,7 @@ import 'dart:io' show File; import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' show BuildContext; -import 'package:flutter_quill/flutter_quill.dart'; import '../../logic/models/config/configurations.dart'; -import '../../logic/services/image_saver/s_image_saver.dart'; // I would like to orgnize the project structure and the code more // but here I don't want to change too much since that is a community project From 6a789490d0b190362fd90524faab9f955f318744 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 21:50:35 +0300 Subject: [PATCH 031/210] Bump flutter_quill to 8.2.0 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 56015302..c7dc1a0b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.1.12 +version: 8.2.0 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From d139770db7860b4e9da656db09eee896c0382475 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 22:49:20 +0300 Subject: [PATCH 032/210] Fix warrnings 2 --- example/lib/pages/home_page.dart | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index f5fd5239..b5cfa905 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -13,6 +13,8 @@ import 'package:flutter_quill/extensions.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; import 'package:flutter_quill_extensions/presentation/embeds/embed_types/image.dart'; +import 'package:flutter_quill_extensions/presentation/embeds/embed_types/video.dart'; +import 'package:flutter_quill_extensions/presentation/models/config/toolbar/buttons/video.dart'; import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart'; @@ -317,6 +319,12 @@ class _HomePageState extends State { return QuillToolbar( configurations: QuillToolbarConfigurations( embedButtons: FlutterQuillEmbeds.toolbarButtons( + videoButtonOptions: QuillToolbarVideoButtonOptions( + videoConfigurations: QuillToolbarVideoConfigurations( + onVideoInsertedCallback: (video) => + _onVideoPickCallback(File(video)), + ), + ), imageButtonOptions: QuillToolbarImageButtonOptions( imageButtonConfigurations: QuillToolbarImageConfigurations( onImageInsertedCallback: (image) async { @@ -463,7 +471,8 @@ class _HomePageState extends State { // TextButton.icon( // icon: const Icon(Icons.collections), // label: const Text('Gallery'), - // onPressed: () => Navigator.pop(ctx, MediaPickSetting.gallery), + // onPressed: () => Navigator.pop(ctx, + // MediaPickSetting.gallery), // ), // TextButton.icon( // icon: const Icon(Icons.link), From 6cb666bac229edb1e090882d31396a219638a955 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 22:50:25 +0300 Subject: [PATCH 033/210] Fix warrnings 2 (save file) --- .../embeds/toolbar/media_button/media_button.dart | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button/media_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button/media_button.dart index 1d8e5fcf..fdebb485 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button/media_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button/media_button.dart @@ -43,7 +43,8 @@ // return options.iconTheme ?? baseButtonExtraOptions(context).iconTheme; // } -// QuillToolbarBaseButtonOptions baseButtonExtraOptions(BuildContext context) { +// QuillToolbarBaseButtonOptions baseButtonExtraOptions( +//BuildContext context) { // return context.requireQuillToolbarBaseButtonOptions; // } @@ -306,7 +307,8 @@ // ? Theme.of(context) // .elevatedButtonTheme // .style -// ?.copyWith(fixedSize: MaterialStatePropertyAll(widget.buttonSize)) +// ?.copyWith( +//fixedSize: MaterialStatePropertyAll(widget.buttonSize)) // : widget.dialogTheme?.buttonStyle; // final isWrappable = widget.dialogTheme?.isWrappable ?? false; @@ -353,7 +355,8 @@ // constraints: constraints, // child: Padding( // padding: -// widget.dialogTheme?.linkDialogPadding ?? const EdgeInsets.all(16), +// widget.dialogTheme?.linkDialogPadding ?? const +// EdgeInsets.all(16), // child: Form( // child: isWrappable // ? Wrap( From 303c6e4efb50b667ba564f897439fe994521984e Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 22:51:28 +0300 Subject: [PATCH 034/210] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f19545b..14f26c4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## [8.1.12] +## [8.2.0] - Add the option to add configurations for `flutter_quill_extensions` using `extraConfigurations` ## [8.1.11] From 3a56ccff513006038ee8a68689cc673c1c1c682b Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 22:59:00 +0300 Subject: [PATCH 035/210] Update CHANGELOG.md and pubspec.yaml --- flutter_quill_extensions/CHANGELOG.md | 3 +++ flutter_quill_extensions/pubspec.yaml | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 67c8f430..7d5a3a5c 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.6.0-dev.2 +- Another breaking changes, we will add mirgrate guide soon. + ## 0.6.0-dev.1 - Breaking Changes, we have refactored most of the functions and it got renamed diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 7a82cfff..82f93111 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 0.6.0-dev.1 +version: 0.6.0-dev.2 homepage: https://github.com/singerdmx/flutter-quill repository: https://github.com/singerdmx/flutter-quill @@ -26,7 +26,7 @@ dependencies: flutter: sdk: flutter - flutter_quill: ^8.1.10 + flutter_quill: ^8.2.0 http: ^1.1.0 photo_view: ^0.14.0 From d306fb2fdeff3cb7c04c8a6f5a8a7c81002bea55 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 23:11:30 +0300 Subject: [PATCH 036/210] Mirgrate the example to material 3 --- example/lib/main.dart | 6 ++++++ example/lib/pages/home_page.dart | 20 +++++--------------- example/pubspec.yaml | 4 ++-- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index c4a44613..0ea04409 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -17,7 +17,13 @@ class MyApp extends StatelessWidget { theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, + useMaterial3: true, ), + // darkTheme: ThemeData( + // primarySwatch: Colors.blue, + // visualDensity: VisualDensity.adaptivePlatformDensity, + // useMaterial3: true, + // ), localizationsDelegates: [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index b5cfa905..573432dd 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -85,9 +85,6 @@ class _HomePageState extends State { } return Scaffold( appBar: AppBar( - backgroundColor: Colors.grey.shade800, - elevation: 0, - centerTitle: false, title: const Text( 'Flutter Quill', ), @@ -117,10 +114,7 @@ class _HomePageState extends State { ) ], ), - drawer: Container( - constraints: BoxConstraints( - maxWidth: MediaQuery.sizeOf(context).width * 0.7), - color: Colors.grey.shade800, + drawer: Drawer( child: _buildMenuBar(context), ), body: _buildWelcomeEditor(context), @@ -510,29 +504,25 @@ class _HomePageState extends State { Widget _buildMenuBar(BuildContext context) { final size = MediaQuery.sizeOf(context); - const itemStyle = TextStyle( - color: Colors.white, - fontSize: 18, - fontWeight: FontWeight.bold, - ); return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Divider( thickness: 2, - color: Colors.white, indent: size.width * 0.1, endIndent: size.width * 0.1, ), ListTile( - title: const Center(child: Text('Read only demo', style: itemStyle)), + title: const Center( + child: Text( + 'Read only demo', + )), dense: true, visualDensity: VisualDensity.compact, onTap: _readOnly, ), Divider( thickness: 2, - color: Colors.white, indent: size.width * 0.1, endIndent: size.width * 0.1, ), diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 4c74eae5..d4fd099b 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -15,8 +15,8 @@ dependencies: path_provider: ^2.1.1 filesystem_picker: ^4.0.0 file_picker: ^6.1.1 - flutter_quill: ^8.1.10 - flutter_quill_extensions: ^0.5.0 + flutter_quill: ^8.2.0 + flutter_quill_extensions: ^0.6.0-dev.2 dependency_overrides: flutter_quill: From d83e274f6f8648a1bec291e98041a7966a0d463f Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 23:15:37 +0300 Subject: [PATCH 037/210] Support dark theme in the example --- example/lib/main.dart | 14 +++++++----- example/lib/pages/home_page.dart | 37 ++++++++++++++++---------------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 0ea04409..11114782 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -18,12 +18,16 @@ class MyApp extends StatelessWidget { primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, useMaterial3: true, + brightness: Brightness.light, ), - // darkTheme: ThemeData( - // primarySwatch: Colors.blue, - // visualDensity: VisualDensity.adaptivePlatformDensity, - // useMaterial3: true, - // ), + darkTheme: ThemeData( + primarySwatch: Colors.blue, + visualDensity: VisualDensity.adaptivePlatformDensity, + useMaterial3: true, + brightness: Brightness.dark, + ), + // ignore: avoid_redundant_argument_values + themeMode: ThemeMode.system, localizationsDelegates: [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 573432dd..81c6abac 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -202,15 +202,15 @@ class _HomePageState extends State { }, customStyles: const DefaultStyles( h1: DefaultTextBlockStyle( - TextStyle( - fontSize: 32, - color: Colors.black, - height: 1.15, - fontWeight: FontWeight.w300, - ), - VerticalSpacing(16, 0), - VerticalSpacing(0, 0), - null), + TextStyle( + fontSize: 32, + height: 1.15, + fontWeight: FontWeight.w300, + ), + VerticalSpacing(16, 0), + VerticalSpacing(0, 0), + null, + ), sizeSmall: TextStyle(fontSize: 9), ), embedBuilders: [ @@ -234,15 +234,15 @@ class _HomePageState extends State { }, customStyles: const DefaultStyles( h1: DefaultTextBlockStyle( - TextStyle( - fontSize: 32, - color: Colors.black, - height: 1.15, - fontWeight: FontWeight.w300, - ), - VerticalSpacing(16, 0), - VerticalSpacing(0, 0), - null), + TextStyle( + fontSize: 32, + height: 1.15, + fontWeight: FontWeight.w300, + ), + VerticalSpacing(16, 0), + VerticalSpacing(0, 0), + null, + ), sizeSmall: TextStyle(fontSize: 9), subscript: TextStyle( fontFamily: 'SF-UI-Display', @@ -385,7 +385,6 @@ class _HomePageState extends State { Expanded( flex: 15, child: Container( - color: Colors.white, padding: const EdgeInsets.only(left: 16, right: 16), child: quillEditor, ), From c532fb4de943d9d86118bf13eb63c6cfc82ca0f7 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 23:18:17 +0300 Subject: [PATCH 038/210] Update readonly page --- example/lib/pages/read_only_page.dart | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/example/lib/pages/read_only_page.dart b/example/lib/pages/read_only_page.dart index 0f5af5d6..4324051d 100644 --- a/example/lib/pages/read_only_page.dart +++ b/example/lib/pages/read_only_page.dart @@ -61,15 +61,12 @@ class _ReadOnlyPageState extends State { focusNode: _focusNode, ); } - return Padding( - padding: const EdgeInsets.all(8), - child: Container( - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.grey.shade200), - ), - child: quillEditor, + return Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.grey.shade200), ), + padding: const EdgeInsets.all(8), + child: quillEditor, ); } From eea58c6634e960011f9745917b0a457661ac6900 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 23:30:04 +0300 Subject: [PATCH 039/210] Disable camera option by default on desktop --- example/macos/Runner/DebugProfile.entitlements | 2 ++ example/macos/Runner/Release.entitlements | 4 ++++ .../embeds/toolbar/image_button/select_image_source.dart | 2 ++ .../embeds/toolbar/video_button/select_video_source.dart | 2 ++ 4 files changed, 10 insertions(+) diff --git a/example/macos/Runner/DebugProfile.entitlements b/example/macos/Runner/DebugProfile.entitlements index d6c8ee0c..2302f9b8 100644 --- a/example/macos/Runner/DebugProfile.entitlements +++ b/example/macos/Runner/DebugProfile.entitlements @@ -10,5 +10,7 @@ com.apple.security.network.client + com.apple.security.files.user-selected.read-only + diff --git a/example/macos/Runner/Release.entitlements b/example/macos/Runner/Release.entitlements index 04336df3..7370dc0b 100644 --- a/example/macos/Runner/Release.entitlements +++ b/example/macos/Runner/Release.entitlements @@ -4,5 +4,9 @@ com.apple.security.app-sandbox + com.apple.security.network.client + + com.apple.security.files.user-selected.read-only + diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart index 3c838934..8753bb87 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_quill/extensions.dart' show isDesktop; import '../../embed_types/image.dart'; @@ -27,6 +28,7 @@ class SelectImageSourceDialog extends StatelessWidget { 'Take a photo using your phone camera', ), leading: const Icon(Icons.camera), + enabled: !isDesktop(), onTap: () => Navigator.of(context).pop(InsertImageSource.camera), ), ListTile( diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/select_video_source.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/select_video_source.dart index 7187f10b..da2fb8ef 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/select_video_source.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/select_video_source.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_quill/extensions.dart' show isDesktop; import '../../embed_types/video.dart'; @@ -27,6 +28,7 @@ class SelectVideoSourceDialog extends StatelessWidget { 'Record a video using your phone camera', ), leading: const Icon(Icons.camera), + enabled: !isDesktop(), onTap: () => Navigator.of(context).pop(InsertVideoSource.camera), ), ListTile( From 711e47d0f59d6d58a7de040726bbcb7b9cf0cd0b Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 23:39:37 +0300 Subject: [PATCH 040/210] Disable camera option by default on desktop --- example/lib/pages/read_only_page.dart | 4 +++- flutter_quill_extensions/CHANGELOG.md | 3 +++ flutter_quill_extensions/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/example/lib/pages/read_only_page.dart b/example/lib/pages/read_only_page.dart index 4324051d..82b8185f 100644 --- a/example/lib/pages/read_only_page.dart +++ b/example/lib/pages/read_only_page.dart @@ -40,7 +40,9 @@ class _ReadOnlyPageState extends State { configurations: QuillEditorConfigurations( expands: false, padding: EdgeInsets.zero, - embedBuilders: FlutterQuillEmbeds.editorBuilders(), + embedBuilders: kIsWeb + ? FlutterQuillEmbeds.editorsWebBuilders() + : FlutterQuillEmbeds.editorBuilders(), scrollable: true, autoFocus: true, ), diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 7d5a3a5c..a434c84a 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.6.0-dev.3 +- Disable the camera option by default on desktop + ## 0.6.0-dev.2 - Another breaking changes, we will add mirgrate guide soon. diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 82f93111..93f46784 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 0.6.0-dev.2 +version: 0.6.0-dev.3 homepage: https://github.com/singerdmx/flutter-quill repository: https://github.com/singerdmx/flutter-quill From becaf7c4d073256539afe3a16f3995363eb09988 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 23:42:22 +0300 Subject: [PATCH 041/210] Add new comment in flutter_quill_extensions --- flutter_quill_extensions/pubspec.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 93f46784..dd2b23d4 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -42,7 +42,9 @@ dependencies: meta: ^1.9.1 cross_file: ^0.3.3+6 -# In case you are working on changes for both libraries, please uncomment this section +# In case you are working on changes for both libraries +# Comment the dependency_overrides section when publishing the package, +# then uncooment it back, this will be automated later dependency_overrides: flutter_quill: path: ../ From ae7c0c9bb38fed3b45d765c17e0cc20534bd079f Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 5 Nov 2023 23:44:14 +0300 Subject: [PATCH 042/210] Fix a typo --- flutter_quill_extensions/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index dd2b23d4..a55fadfb 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -44,7 +44,7 @@ dependencies: # In case you are working on changes for both libraries # Comment the dependency_overrides section when publishing the package, -# then uncooment it back, this will be automated later +# then uncomment it back, this will be automated later dependency_overrides: flutter_quill: path: ../ From 4869edbf874712038a8edd1d350fb60a2e01f565 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 00:35:53 +0300 Subject: [PATCH 043/210] Remove Unused plugins in the example, update README.md, add more exports in flutter_quill_extensions --- CHANGELOG.md | 3 ++ README.md | 34 +------------------ example/README.md | 18 +++++----- example/lib/pages/home_page.dart | 21 +++++------- example/lib/widgets/demo_scaffold.dart | 19 +++++------ example/pubspec.yaml | 6 ++-- flutter_quill_extensions/CHANGELOG.md | 3 ++ .../lib/flutter_quill_extensions.dart | 5 ++- ...ations.dart => shared_configurations.dart} | 0 .../toolbar/camera_button/camera_button.dart | 3 +- .../toolbar/image_button/image_button.dart | 2 +- .../toolbar/video_button/video_button.dart | 2 +- .../lib/presentation/embeds/utils.dart | 2 +- flutter_quill_extensions/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 15 files changed, 46 insertions(+), 76 deletions(-) rename flutter_quill_extensions/lib/logic/models/config/{configurations.dart => shared_configurations.dart} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14f26c4d..58ae1a15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.2.1] +- Update `README.md` + ## [8.2.0] - Add the option to add configurations for `flutter_quill_extensions` using `extraConfigurations` diff --git a/README.md b/README.md index 3356a40e..1a86623c 100644 --- a/README.md +++ b/README.md @@ -150,10 +150,6 @@ The `QuillToolbar` class lets you customize which formatting options are availab For **web development**, use `flutter config --enable-web` for flutter or use [ReactQuill] for React. It is required to provide `EmbedBuilder`, e.g. [defaultEmbedBuildersWeb](https://github.com/singerdmx/flutter-quill/blob/master/example/lib/universal_ui/universal_ui.dart#L99). -Also it is required to provide `webImagePickImpl`, e.g. [Sample Page](https://github.com/singerdmx/flutter-quill/blob/master/example/lib/pages/home_page.dart#L317). - -For **desktop platforms** It is required to provide `filePickImpl` for toolbar image button, e.g. [Sample Page](https://github.com/singerdmx/flutter-quill/blob/master/example/lib/pages/home_page.dart#L297). - ### Using Custom App Widget @@ -262,35 +258,7 @@ Provide a list of embed ### Using the embed blocks from `flutter_quill_extensions` -```dart -QuillToolbar( - configurations: QuillToolbarConfigurations( - embedButtons: FlutterQuillEmbeds.toolbarButtons( - imageButtonOptions: QuillToolbarImageButtonOptions( - onImagePickCallback: (file) async { - return file.path; - }, - ), - ), - ), -), -``` - -```dart -Expanded( - child: QuillEditor.basic( - configurations: QuillEditorConfigurations( - readOnly: true, - embedBuilders: FlutterQuillEmbeds.editorBuilders( - imageEmbedConfigurations: - const QuillEditorImageEmbedConfigurations( - forceUseMobileOptionMenuForImageClick: true, - ), - ), - ), - ), -) -``` +Too see how to use the extensions package, please take a look at the [README](./flutter_quill_extensions/README.md) of [FlutterQuill Extensions] ### Custom Size Image for Mobile diff --git a/example/README.md b/example/README.md index 5c0ad6d4..681e3e69 100644 --- a/example/README.md +++ b/example/README.md @@ -1,16 +1,14 @@ -# app +# Demo -demo app +This is just a demo of Flutter Quill -## Getting Started -This project is a starting point for a Flutter application. +## Screenshots -A few resources to get you started if this is your first Flutter project: +![Screenshot 1](./assets/images/1.png) -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) +![Screenshot 2](./assets/images/2.png) -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +![Screenshot 3](./assets/images/3.png) + +![Screenshot 4](./assets/images/4.png) \ No newline at end of file diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 81c6abac..6d24895f 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -5,16 +5,12 @@ import 'dart:convert'; import 'dart:io' show File, Platform; import 'dart:ui'; -import 'package:filesystem_picker/filesystem_picker.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_quill/extensions.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; -import 'package:flutter_quill_extensions/presentation/embeds/embed_types/image.dart'; -import 'package:flutter_quill_extensions/presentation/embeds/embed_types/video.dart'; -import 'package:flutter_quill_extensions/presentation/models/config/toolbar/buttons/video.dart'; import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart'; @@ -407,14 +403,15 @@ class _HomePageState extends State { bool _isDesktop() => !kIsWeb && !Platform.isAndroid && !Platform.isIOS; - Future openFileSystemPickerForDesktop(BuildContext context) async { - return await FilesystemPicker.open( - context: context, - rootDirectory: await getApplicationDocumentsDirectory(), - fsType: FilesystemType.file, - fileTileSelectMode: FileTileSelectMode.wholeTile, - ); - } + // Future _openFileSystemPickerForDesktop(BuildContext context) + // async { + // return await FilesystemPicker.open( + // context: context, + // rootDirectory: await getApplicationDocumentsDirectory(), + // fsType: FilesystemType.file, + // fileTileSelectMode: FileTileSelectMode.wholeTile, + // ); + // } // Renders the image picked by imagePicker from local file storage // You can also upload the picked image to any server (eg : AWS s3 diff --git a/example/lib/widgets/demo_scaffold.dart b/example/lib/widgets/demo_scaffold.dart index 27c6ebb0..9de4e786 100644 --- a/example/lib/widgets/demo_scaffold.dart +++ b/example/lib/widgets/demo_scaffold.dart @@ -1,13 +1,11 @@ import 'dart:convert'; import 'dart:io' show Platform; -import 'package:filesystem_picker/filesystem_picker.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; -import 'package:path_provider/path_provider.dart'; typedef DemoContentBuilder = Widget Function( BuildContext context, QuillController? controller); @@ -75,14 +73,15 @@ class _DemoScaffoldState extends State { } } - Future openFileSystemPickerForDesktop(BuildContext context) async { - return await FilesystemPicker.open( - context: context, - rootDirectory: await getApplicationDocumentsDirectory(), - fsType: FilesystemType.file, - fileTileSelectMode: FileTileSelectMode.wholeTile, - ); - } + // Future _openFileSystemPickerForDesktop(BuildContext context) + //async { + // return await FilesystemPicker.open( + // context: context, + // rootDirectory: await getApplicationDocumentsDirectory(), + // fsType: FilesystemType.file, + // fileTileSelectMode: FileTileSelectMode.wholeTile, + // ); + // } QuillToolbar get quillToolbar { if (_isDesktop()) { diff --git a/example/pubspec.yaml b/example/pubspec.yaml index d4fd099b..92df9d83 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -4,7 +4,7 @@ publish_to: 'none' version: 1.0.0+1 environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=3.1.3 <4.0.0' dependencies: flutter: @@ -13,8 +13,8 @@ dependencies: cupertino_icons: ^1.0.6 path_provider: ^2.1.1 - filesystem_picker: ^4.0.0 - file_picker: ^6.1.1 + # filesystem_picker: ^4.0.0 + # file_picker: ^6.1.1 flutter_quill: ^8.2.0 flutter_quill_extensions: ^0.6.0-dev.2 diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index a434c84a..0c462f61 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.6.0-dev.4 +- Add more exports + ## 0.6.0-dev.3 - Disable the camera option by default on desktop diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index bb617431..b1c6b37d 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter_quill/flutter_quill.dart'; import 'package:meta/meta.dart' show immutable; -import 'logic/models/config/configurations.dart'; +import 'logic/models/config/shared_configurations.dart'; import 'presentation/embeds/editor/image/image.dart'; import 'presentation/embeds/editor/image/image_web.dart'; import 'presentation/embeds/editor/video.dart'; @@ -29,6 +29,8 @@ export '/presentation/models/config/editor/webview.dart'; export './logic/extensions/controller.dart'; export 'presentation/embeds/editor/unknown.dart'; export 'presentation/embeds/embed_types.dart'; +export 'presentation/embeds/embed_types/image.dart'; +export 'presentation/embeds/embed_types/video.dart'; export 'presentation/embeds/toolbar/camera_button/camera_button.dart'; export 'presentation/embeds/toolbar/formula_button.dart'; export 'presentation/embeds/toolbar/image_button/image_button.dart'; @@ -38,6 +40,7 @@ export 'presentation/embeds/toolbar/video_button/video_button.dart'; export 'presentation/embeds/utils.dart'; export 'presentation/models/config/editor/image.dart'; export 'presentation/models/config/toolbar/buttons/image.dart'; +export 'presentation/models/config/toolbar/buttons/video.dart'; @immutable class FlutterQuillEmbeds { diff --git a/flutter_quill_extensions/lib/logic/models/config/configurations.dart b/flutter_quill_extensions/lib/logic/models/config/shared_configurations.dart similarity index 100% rename from flutter_quill_extensions/lib/logic/models/config/configurations.dart rename to flutter_quill_extensions/lib/logic/models/config/shared_configurations.dart diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart index 1324c936..404bd589 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill/translations.dart'; -import '../../../../logic/models/config/configurations.dart'; +import '../../../../logic/models/config/shared_configurations.dart'; import '../../../../logic/services/image_picker/image_options.dart'; import '../../../models/config/toolbar/buttons/camera.dart'; import '../../embed_types/camera.dart'; @@ -151,7 +151,6 @@ class QuillToolbarCameraButton extends StatelessWidget { if (videoFile == null) { return; } - // TODO: Implement this case CameraAction.image: final imageFile = await imagePickerService.pickImage( source: ImageSource.camera, diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart index 7451a435..8c27c1e3 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import '../../../../logic/models/config/configurations.dart'; +import '../../../../logic/models/config/shared_configurations.dart'; import '../../../../logic/services/image_picker/image_picker.dart'; import '../../../models/config/toolbar/buttons/image.dart'; import '../../embed_types/image.dart'; diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart index f06d59df..2c2dbefa 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import '../../../../logic/models/config/configurations.dart'; +import '../../../../logic/models/config/shared_configurations.dart'; import '../../../../logic/services/image_picker/image_options.dart'; import '../../../models/config/toolbar/buttons/video.dart'; import '../../embed_types/video.dart'; diff --git a/flutter_quill_extensions/lib/presentation/embeds/utils.dart b/flutter_quill_extensions/lib/presentation/embeds/utils.dart index edd463de..f8f08245 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/utils.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/utils.dart @@ -2,7 +2,7 @@ import 'dart:io' show File; import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' show BuildContext; -import '../../logic/models/config/configurations.dart'; +import '../../logic/models/config/shared_configurations.dart'; // I would like to orgnize the project structure and the code more // but here I don't want to change too much since that is a community project diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index a55fadfb..8edb68c9 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 0.6.0-dev.3 +version: 0.6.0-dev.4 homepage: https://github.com/singerdmx/flutter-quill repository: https://github.com/singerdmx/flutter-quill diff --git a/pubspec.yaml b/pubspec.yaml index c7dc1a0b..5d6cd6f2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.2.0 +version: 8.2.1 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From 7fab7b8d71104c8806f5693fce436603e73a8c0c Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 00:38:31 +0300 Subject: [PATCH 044/210] Remove comment --- flutter_quill_extensions/lib/presentation/embeds/utils.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/flutter_quill_extensions/lib/presentation/embeds/utils.dart b/flutter_quill_extensions/lib/presentation/embeds/utils.dart index f8f08245..5ce82ee9 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/utils.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/utils.dart @@ -4,9 +4,6 @@ import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' show BuildContext; import '../../logic/models/config/shared_configurations.dart'; -// I would like to orgnize the project structure and the code more -// but here I don't want to change too much since that is a community project - RegExp _base64 = RegExp( r'^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$', ); From 72a16b608cf59c8c628064fb76cd8e37b524c333 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 01:15:47 +0300 Subject: [PATCH 045/210] Quick fixes and changes --- CONTRIBUTING.md | 3 ++ README.md | 4 ++ example/lib/pages/home_page.dart | 50 ++++++++++-------- flutter_quill_extensions/CHANGELOG.md | 3 ++ flutter_quill_extensions/README.md | 27 ++-------- .../embeds/editor/image/image.dart | 12 ++--- .../lib/presentation/embeds/embed_types.dart | 52 ++----------------- .../embeds/embed_types/image.dart | 17 ++++++ .../toolbar/camera_button/camera_button.dart | 2 - .../toolbar/video_button/video_button.dart | 1 - .../presentation/embeds/widgets/image.dart | 2 +- .../models/config/editor/image.dart | 16 ++++-- .../models/config/toolbar/buttons/camera.dart | 7 --- .../config/toolbar/buttons/media_button.dart | 7 +-- .../models/config/toolbar/buttons/video.dart | 4 -- 15 files changed, 82 insertions(+), 125 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..36907521 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,3 @@ +# Contributing + +We welcome contributions! \ No newline at end of file diff --git a/README.md b/README.md index 1a86623c..c5261690 100644 --- a/README.md +++ b/README.md @@ -668,6 +668,10 @@ Special thanks for everyone that have contributed to this project... Made with [contrib.rocks](https://contrib.rocks). +We welcome contributions! + +Please follow these guidelines when contributing to our project. See [CONTRIBUTING.md](./../CONTRIBUTING.md) for more details. + [Quill]: https://quilljs.com/docs/formats [Flutter]: https://github.com/flutter/flutter [FlutterQuill]: https://pub.dev/packages/flutter_quill diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 6d24895f..81947f0f 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:io' show File, Platform; +import 'dart:io' show File; import 'dart:ui'; import 'package:flutter/foundation.dart'; @@ -35,6 +35,7 @@ class _HomePageState extends State { final FocusNode _focusNode = FocusNode(); Timer? _selectAllTimer; _SelectionType _selectionType = _SelectionType.none; + var _isReadOnly = false; @override void dispose() { @@ -85,6 +86,13 @@ class _HomePageState extends State { 'Flutter Quill', ), actions: [ + IconButton( + onPressed: () { + setState(() => _isReadOnly = !_isReadOnly); + }, + icon: Icon( + _isReadOnly ? Icons.lock : Icons.edit, + )), IconButton( onPressed: () => _insertTimeStamp( _controller, @@ -219,7 +227,7 @@ class _HomePageState extends State { return QuillEditor( configurations: QuillEditorConfigurations( placeholder: 'Add content', - readOnly: false, + readOnly: _isReadOnly, autoFocus: false, enableSelectionToolbar: isMobile(), expands: false, @@ -250,7 +258,11 @@ class _HomePageState extends State { ), ), embedBuilders: [ - ...FlutterQuillEmbeds.editorBuilders(), + ...FlutterQuillEmbeds.editorBuilders( + imageEmbedConfigurations: const QuillEditorImageEmbedConfigurations( + forceUseMobileOptionMenuForImageClick: true, + ), + ), TimeStampEmbedBuilderWidget() ], ), @@ -282,7 +294,7 @@ class _HomePageState extends State { // afterButtonPressed: _focusNode.requestFocus, ); } - if (_isDesktop()) { + if (isDesktop()) { return QuillToolbar( configurations: QuillToolbarConfigurations( embedButtons: FlutterQuillEmbeds.toolbarButtons( @@ -292,8 +304,6 @@ class _HomePageState extends State { _onImagePickCallback(File(image)); }, ), - // onImagePickCallback: _onImagePickCallback, - // filePickImpl: openFileSystemPickerForDesktop, ), ), showAlignmentButtons: true, @@ -303,7 +313,6 @@ class _HomePageState extends State { ), ), ), - // afterButtonPressed: _focusNode.requestFocus, ); } return QuillToolbar( @@ -385,24 +394,23 @@ class _HomePageState extends State { child: quillEditor, ), ), - kIsWeb - ? Expanded( - child: Container( - padding: - const EdgeInsets.symmetric(vertical: 16, horizontal: 8), - child: quillToolbar, - )) - : Container( - child: quillToolbar, - ) + if (!_isReadOnly) + kIsWeb + ? Expanded( + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 16, horizontal: 8), + child: quillToolbar, + )) + : Container( + child: quillToolbar, + ) ], ), ), ); } - bool _isDesktop() => !kIsWeb && !Platform.isAndroid && !Platform.isIOS; - // Future _openFileSystemPickerForDesktop(BuildContext context) // async { // return await FilesystemPicker.open( @@ -515,7 +523,7 @@ class _HomePageState extends State { )), dense: true, visualDensity: VisualDensity.compact, - onTap: _readOnly, + onTap: _openReadOnlyPage, ), Divider( thickness: 2, @@ -526,7 +534,7 @@ class _HomePageState extends State { ); } - void _readOnly() { + void _openReadOnlyPage() { Navigator.pop(super.context); Navigator.push( super.context, diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 0c462f61..5ff6b595 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,5 +1,8 @@ ## 0.6.0-dev.4 - Add more exports +- Update `README.md`` +- Fix save image bug +- Quick fixes ## 0.6.0-dev.3 - Disable the camera option by default on desktop diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index e33f8362..b1810c95 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -59,17 +59,11 @@ Before starting using this package you must follow the setup Set the `embedBuilders` and `embedToolbar` params in configurations of `QuillEditor` and `QuillToolbar` with the values provided by this repository. -**Quill toolbar**: +**Quill Toolbar**: ```dart QuillToolbar( configurations: QuillToolbarConfigurations( - embedButtons: FlutterQuillEmbeds.toolbarButtons( - imageButtonOptions: QuillToolbarImageButtonOptions( - onImagePickCallback: (file) async { - return file.path; - }, - ), - ), + embedButtons: FlutterQuillEmbeds.toolbarButtons(), ), ), ``` @@ -79,13 +73,7 @@ QuillToolbar( Expanded( child: QuillEditor.basic( configurations: QuillEditorConfigurations( - readOnly: true, - embedBuilders: FlutterQuillEmbeds.editorBuilders( - imageEmbedConfigurations: - const QuillEditorImageEmbedConfigurations( - forceUseMobileOptionMenuForImageClick: true, - ), - ), + embedBuilders: kIsWeb ? FlutterQuillEmbeds.editorsWebBuilders() : FlutterQuillEmbeds.editorBuilders(), ), ), ) @@ -113,7 +101,7 @@ QuillProvider( child: QuillEditor.basic( configurations: QuillEditorConfigurations( padding: const EdgeInsets.all(16), - embedBuilders: FlutterQuillEmbeds.editorBuilders(), + embedBuilders: kIsWeb ? FlutterQuillEmbeds.editorsWebBuilders() : FlutterQuillEmbeds.editorBuilders(), ), ), ) @@ -122,11 +110,6 @@ QuillProvider( ) ``` -For web, use: -```dart -FlutterQuillEmbeds.editorsWebBuilders() -``` - ## Features ```markdown @@ -142,7 +125,7 @@ FlutterQuillEmbeds.editorsWebBuilders() We welcome contributions! -Please follow these guidelines when contributing to our project. See [CONTRIBUTING.md](CONTRIBUTING.md) for more details. +Please follow these guidelines when contributing to our project. See [CONTRIBUTING.md](./../CONTRIBUTING.md) for more details. ## License diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart index 45fd1399..666fe993 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart @@ -1,5 +1,3 @@ -import 'dart:io' show File; - import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -8,7 +6,7 @@ import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill/translations.dart'; import '../../../models/config/editor/image.dart'; -import '../../embed_types.dart'; +import '../../embed_types/image.dart'; import '../../utils.dart'; import '../../widgets/image.dart'; import '../../widgets/image_resizer.dart'; @@ -138,11 +136,9 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { onPressed: () async { Navigator.of(context).pop(); - final imageFile = File(imageUrl); - // Call the remove check callback if set if (await configurations.shouldRemoveImageCallback - ?.call(imageFile) == + ?.call(imageUrl) == false) { return; } @@ -158,7 +154,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { TextSelection.collapsed(offset: offset), ); // Call the post remove callback if set - await configurations.onImageRemovedCallback.call(imageFile); + await configurations.onImageRemovedCallback.call(imageUrl); }, ); return Padding( @@ -259,7 +255,7 @@ Widget _menuOptionsForReadonlyImage({ onTap: () { showDialog( context: context, - builder: (context) { + builder: (_) { final saveOption = SimpleDialogItem( icon: Icons.save, color: Colors.greenAccent, diff --git a/flutter_quill_extensions/lib/presentation/embeds/embed_types.dart b/flutter_quill_extensions/lib/presentation/embeds/embed_types.dart index 3a2e9330..249fb40b 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/embed_types.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/embed_types.dart @@ -1,25 +1,8 @@ -import 'dart:io' show File; -import 'dart:typed_data'; - -import 'package:flutter/material.dart' - show ImageErrorWidgetBuilder, BuildContext, ImageProvider; - -typedef OnVideoPickCallback = Future Function(File file); - -/// [FilePickImpl] is an implementation for picking files. -typedef FilePickImpl = Future Function(BuildContext context); - -/// [WebImagePickImpl] is an implementation for picking web images. -// typedef WebImagePickImpl = Future Function( -// OnImagePickCallback onImagePickCallback, -// ); -typedef WebVideoPickImpl = Future Function( - OnVideoPickCallback onImagePickCallback, -); +import 'package:cross_file/cross_file.dart' show XFile; typedef MediaFileUrl = String; -typedef MediaFilePicker = Future Function(QuillMediaType mediaType); -typedef MediaPickedCallback = Future Function(QuillFile file); +typedef MediaFilePicker = Future Function(QuillMediaType mediaType); +typedef MediaPickedCallback = Future Function(XFile file); enum QuillMediaType { image, video } @@ -27,32 +10,3 @@ extension QuillMediaTypeX on QuillMediaType { bool get isImage => this == QuillMediaType.image; bool get isVideo => this == QuillMediaType.video; } - -/// Represents a file data which returned by file picker. -class QuillFile { - QuillFile({ - required this.name, - this.path = '', - Uint8List? bytes, - }) : assert(name.isNotEmpty), - bytes = bytes ?? Uint8List(0); - - final String name; - final String path; - final Uint8List bytes; -} - -typedef ImageEmbedBuilderWillRemoveCallback = Future Function( - File imageFile, -); - -typedef ImageEmbedBuilderOnRemovedCallback = Future Function( - File imageFile, -); - -typedef ImageEmbedBuilderProviderBuilder = ImageProvider Function( - String imageUrl, - // {required bool isLocalImage} -); - -typedef ImageEmbedBuilderErrorWidgetBuilder = ImageErrorWidgetBuilder; diff --git a/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart b/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart index e191c129..0a10ba6a 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart @@ -1,6 +1,9 @@ +import 'package:flutter/widgets.dart' + show ImageErrorWidgetBuilder, ImageProvider; import 'package:flutter/widgets.dart' show BuildContext; import 'package:flutter_quill/flutter_quill.dart'; import 'package:meta/meta.dart' show immutable; + import '../../../logic/extensions/controller.dart'; import '../../../logic/services/image_picker/s_image_picker.dart'; @@ -63,3 +66,17 @@ class QuillToolbarImageConfigurations { return _onImageInsertCallback ?? defaultOnImageInsertCallback(); } } + +typedef ImageEmbedBuilderWillRemoveCallback = Future Function( + String imageUrl, +); + +typedef ImageEmbedBuilderOnRemovedCallback = Future Function( + String imageUrl, +); + +typedef ImageEmbedBuilderProviderBuilder = ImageProvider Function( + String imageUrl, +); + +typedef ImageEmbedBuilderErrorWidgetBuilder = ImageErrorWidgetBuilder; diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart index 404bd589..5cde1ace 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart @@ -73,7 +73,6 @@ class QuillToolbarCameraButton extends StatelessWidget { if (childBuilder != null) { childBuilder( QuillToolbarCameraButtonOptions( - onVideoPickCallback: options.onVideoPickCallback, afterButtonPressed: _afterButtonPressed(context), iconData: options.iconData, fillColor: options.fillColor, @@ -81,7 +80,6 @@ class QuillToolbarCameraButton extends StatelessWidget { iconTheme: options.iconTheme, tooltip: options.tooltip, cameraConfigurations: options.cameraConfigurations, - webVideoPickImpl: options.webVideoPickImpl, ), QuillToolbarCameraButtonExtraOptions( controller: controller, diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart index 2c2dbefa..76b5a4d0 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart @@ -85,7 +85,6 @@ class QuillToolbarVideoButton extends StatelessWidget { linkRegExp: options.linkRegExp, tooltip: options.tooltip, iconTheme: options.iconTheme, - webVideoPickImpl: options.webVideoPickImpl, videoConfigurations: options.videoConfigurations, ), QuillToolbarVideoButtonExtraOptions( diff --git a/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart b/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart index 8e3b617d..6d00500c 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart @@ -5,7 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:photo_view/photo_view.dart'; -import '../embed_types.dart'; +import '../embed_types/image.dart'; import '../utils.dart'; const List imageFileExtensions = [ diff --git a/flutter_quill_extensions/lib/presentation/models/config/editor/image.dart b/flutter_quill_extensions/lib/presentation/models/config/editor/image.dart index 2b494128..31fa75ef 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/editor/image.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/editor/image.dart @@ -1,7 +1,9 @@ +import 'dart:io' show File; + import 'package:flutter_quill/extensions.dart'; import 'package:meta/meta.dart' show immutable; -import '../../../embeds/embed_types.dart'; +import '../../../embeds/embed_types/image.dart'; /// [QuillEditorImageEmbedConfigurations] for desktop, mobile and /// other platforms @@ -109,7 +111,7 @@ class QuillEditorImageEmbedConfigurations { final bool forceUseMobileOptionMenuForImageClick; static ImageEmbedBuilderOnRemovedCallback get defaultOnImageRemovedCallback { - return (imageFile) async { + return (imageUrl) async { final mobile = isMobile(); // If the platform is not mobile, return void; // Since the mobile OS gives us a copy of the image @@ -132,9 +134,15 @@ class QuillEditorImageEmbedConfigurations { // it without // permission - final isFileExists = await imageFile.exists(); + if (isWeb()) { + return; + } + + final dartIoImageFile = File(imageUrl); + + final isFileExists = await dartIoImageFile.exists(); if (isFileExists) { - await imageFile.delete(); + await dartIoImageFile.delete(); } }; } diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart index c685bb4a..3c4c21cb 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart @@ -1,7 +1,6 @@ import 'package:flutter/widgets.dart' show Color; import 'package:flutter_quill/flutter_quill.dart'; -import '../../../../embeds/embed_types.dart'; import '../../../../embeds/embed_types/camera.dart'; class QuillToolbarCameraButtonExtraOptions @@ -16,9 +15,7 @@ class QuillToolbarCameraButtonExtraOptions class QuillToolbarCameraButtonOptions extends QuillToolbarBaseButtonOptions< QuillToolbarCameraButtonOptions, QuillToolbarCameraButtonExtraOptions> { const QuillToolbarCameraButtonOptions({ - required this.onVideoPickCallback, this.cameraConfigurations = const QuillToolbarCameraConfigurations(), - this.webVideoPickImpl, this.iconSize, this.fillColor, super.iconData, @@ -33,9 +30,5 @@ class QuillToolbarCameraButtonOptions extends QuillToolbarBaseButtonOptions< final Color? fillColor; - final OnVideoPickCallback onVideoPickCallback; - - final WebVideoPickImpl? webVideoPickImpl; - final QuillToolbarCameraConfigurations cameraConfigurations; } diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart index a1c6fca9..d55f20f1 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/media_button.dart @@ -18,7 +18,7 @@ class QuillToolbarMediaButtonOptions extends QuillToolbarBaseButtonOptions< const QuillToolbarMediaButtonOptions({ required this.type, required this.onMediaPickedCallback, - required this.onVideoPickCallback, + // required this.onVideoPickCallback, this.dialogBarrierColor, this.mediaFilePicker, this.childrenSpacing = 16.0, @@ -33,8 +33,6 @@ class QuillToolbarMediaButtonOptions extends QuillToolbarBaseButtonOptions< this.galleryButtonText, this.linkButtonText, this.validationMessage, - this.filePickImpl, - this.webVideoPickImpl, super.iconData, super.afterButtonPressed, super.tooltip, @@ -74,7 +72,4 @@ class QuillToolbarMediaButtonOptions extends QuillToolbarBaseButtonOptions< final AutovalidateMode autovalidateMode; final String? validationMessage; - final FilePickImpl? filePickImpl; - final OnVideoPickCallback onVideoPickCallback; - final WebVideoPickImpl? webVideoPickImpl; } diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart index 4e030192..17f80453 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart @@ -1,7 +1,6 @@ import 'package:flutter/widgets.dart' show Color; import 'package:flutter_quill/flutter_quill.dart'; -import '../../../../embeds/embed_types.dart'; import '../../../../embeds/embed_types/video.dart'; class QuillToolbarVideoButtonExtraOptions @@ -18,7 +17,6 @@ class QuillToolbarVideoButtonOptions extends QuillToolbarBaseButtonOptions< const QuillToolbarVideoButtonOptions({ this.linkRegExp, this.dialogTheme, - this.webVideoPickImpl, this.fillColor, this.iconSize, super.iconData, @@ -34,8 +32,6 @@ class QuillToolbarVideoButtonOptions extends QuillToolbarBaseButtonOptions< final QuillDialogTheme? dialogTheme; final QuillToolbarVideoConfigurations videoConfigurations; - final WebVideoPickImpl? webVideoPickImpl; - final Color? fillColor; final double? iconSize; From 9e0db463e5dfeff4e50faabbbbbf4bf1848df8be Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 01:23:57 +0300 Subject: [PATCH 046/210] Update README.md --- README.md | 45 +++++++++++++++------------------------------ 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index c5261690..7a9ae38a 100644 --- a/README.md +++ b/README.md @@ -590,36 +590,21 @@ The package offers translations for the quill toolbar and editor, it will follow Currently, translations are available for these 31 locales: -* `Locale('en')` -* `Locale('ar')` -* `Locale('bn')` -* `Locale('bs')` -* `Locale('cs')` -* `Locale('de')` -* `Locale('da')` -* `Locale('fr')` -* `Locale('he')` -* `Locale('zh', 'cn')` -* `Locale('zh', 'hk')` -* `Locale('ko')` -* `Locale('ru')` -* `Locale('es')` -* `Locale('tk')` -* `Locale('tr')` -* `Locale('uk')` -* `Locale('ur')` -* `Locale('pt')` -* `Locale('pl')` -* `Locale('vi')` -* `Locale('id')` -* `Locale('it')` -* `Locale('ms')` -* `Locale('nl')` -* `Locale('no')` -* `Locale('fa')` -* `Locale('hi')` -* `Locale('sr')` -* `Locale('sw')` +* `Locale('en')`, `Locale('ar')` +* `Locale('bn')`, `Locale('bs')` +* `Locale('cs')`, `Locale('de')` +* `Locale('da')`, `Locale('fr')` +* `Locale('he')`, `Locale('zh', 'cn')` +* `Locale('zh', 'hk')`, `Locale('ko')` +* `Locale('ru')`, `Locale('es')` +* `Locale('tk')`, `Locale('tr')` +* `Locale('uk')`, `Locale('ur')` +* `Locale('pt')`, `Locale('pl')` +* `Locale('vi')`, `Locale('id')` +* `Locale('it')`, `Locale('ms')` +* `Locale('nl')`, `Locale('no')` +* `Locale('fa')`, `Locale('hi')` +* `Locale('sr')`, `Locale('sw')` * `Locale('ja')` #### Contributing to translations From adc067fe26e8797b1e77e020e20d3b7d63d7c24c Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 02:10:11 +0300 Subject: [PATCH 047/210] Move flutter_quill_test to seperated package (#1507) * Split flutter_quill_test to a separated package * Update version and main workflow --- .github/workflows/main.yml | 3 + CHANGELOG.md | 3 + README.md | 14 +---- flutter_quill_extensions/LICENSE | 2 +- flutter_quill_extensions/pubspec.yaml | 4 +- flutter_quill_test/.gitignore | 30 ++++++++++ flutter_quill_test/.metadata | 10 ++++ flutter_quill_test/CHANGELOG.md | 3 + flutter_quill_test/LICENSE | 21 +++++++ flutter_quill_test/README.md | 26 ++++++++ flutter_quill_test/analysis_options.yaml | 4 ++ .../lib}/flutter_quill_test.dart | 0 .../src/test/widget_tester_extension.dart | 9 ++- flutter_quill_test/pubspec.yaml | 29 +++++++++ .../test/flutter_quill_test_test.dart | 1 + lib/flutter_quill.dart | 1 + lib/src/widgets/editor/editor.dart | 7 +-- lib/src/widgets/raw_editor/raw_editor.dart | 59 ++++++++++--------- pubspec.yaml | 11 ++-- test/bug_fix_test.dart | 2 +- test/widgets/editor_test.dart | 5 +- 21 files changed, 181 insertions(+), 63 deletions(-) create mode 100644 flutter_quill_test/.gitignore create mode 100644 flutter_quill_test/.metadata create mode 100644 flutter_quill_test/CHANGELOG.md create mode 100644 flutter_quill_test/LICENSE create mode 100644 flutter_quill_test/README.md create mode 100644 flutter_quill_test/analysis_options.yaml rename {lib => flutter_quill_test/lib}/flutter_quill_test.dart (100%) rename {lib => flutter_quill_test/lib}/src/test/widget_tester_extension.dart (90%) create mode 100644 flutter_quill_test/pubspec.yaml create mode 100644 flutter_quill_test/test/flutter_quill_test_test.dart diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c5314cc0..b8ad209b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,6 +25,9 @@ jobs: - name: Install flutter_quill_extensions dependencies run: flutter pub get -C flutter_quill_extensions + - name: Install flutter_quill_test dependencies + run: flutter pub get -C flutter_quill_test + - name: Run flutter analysis run: flutter analyze diff --git a/CHANGELOG.md b/CHANGELOG.md index 58ae1a15..91598874 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.2.2] +- Move the `flutter_quill_test` to seperated package [flutter_quill_test](https://pub.dev/packages/fresh_quill_extensions) + ## [8.2.1] - Update `README.md` diff --git a/README.md b/README.md index 7a9ae38a..63e43be0 100644 --- a/README.md +++ b/README.md @@ -623,19 +623,7 @@ Typescript/Javascript package. ## Testing -To aid in testing applications using the editor an extension to the flutter `WidgetTester` is provided which includes methods to simplify interacting with the editor in test cases. - -Import the test utilities in your test file: - -```dart -import 'package:flutter_quill/flutter_quill_test.dart'; -``` - -and then enter text using `quillEnterText`: - -```dart -await tester.quillEnterText(find.byType(QuillEditor), 'test\n'); -``` +Please use [flutter_quill_test](https://pub.dev/packages/flutter_quill_test) for testing ## License diff --git a/flutter_quill_extensions/LICENSE b/flutter_quill_extensions/LICENSE index 498b3e0a..aaec6d89 100644 --- a/flutter_quill_extensions/LICENSE +++ b/flutter_quill_extensions/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 Xin Yao +Copyright (c) 2023 Xin Yao Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 8edb68c9..18c81d21 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,8 +1,8 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. version: 0.6.0-dev.4 -homepage: https://github.com/singerdmx/flutter-quill -repository: https://github.com/singerdmx/flutter-quill +homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions +repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions topics: - ui diff --git a/flutter_quill_test/.gitignore b/flutter_quill_test/.gitignore new file mode 100644 index 00000000..96486fd9 --- /dev/null +++ b/flutter_quill_test/.gitignore @@ -0,0 +1,30 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.packages +build/ diff --git a/flutter_quill_test/.metadata b/flutter_quill_test/.metadata new file mode 100644 index 00000000..6176c000 --- /dev/null +++ b/flutter_quill_test/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "d211f42860350d914a5ad8102f9ec32764dc6d06" + channel: "stable" + +project_type: package diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md new file mode 100644 index 00000000..77b39e53 --- /dev/null +++ b/flutter_quill_test/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* initial release. diff --git a/flutter_quill_test/LICENSE b/flutter_quill_test/LICENSE new file mode 100644 index 00000000..19efa532 --- /dev/null +++ b/flutter_quill_test/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Flutter Quill Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/flutter_quill_test/README.md b/flutter_quill_test/README.md new file mode 100644 index 00000000..c32a78fe --- /dev/null +++ b/flutter_quill_test/README.md @@ -0,0 +1,26 @@ +# Flutter Quill Test + +## Testing +To aid in testing applications using the editor an extension to the flutter `WidgetTester` is provided which includes methods to simplify interacting with the editor in test cases. + +Import the test utilities in your test file: + +```dart +import 'package:flutter_quill/flutter_quill_test.dart'; +``` + +and then enter text using `quillEnterText`: + +```dart +await tester.quillEnterText(find.byType(QuillEditor), 'test\n'); +``` + +## Contributing + +We welcome contributions! + +Please follow these guidelines when contributing to our project. See [CONTRIBUTING.md](./../CONTRIBUTING.md) for more details. + +## License + +This project is licensed under the [MIT License](LICENSE) - see the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/flutter_quill_test/analysis_options.yaml b/flutter_quill_test/analysis_options.yaml new file mode 100644 index 00000000..a5744c1c --- /dev/null +++ b/flutter_quill_test/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/lib/flutter_quill_test.dart b/flutter_quill_test/lib/flutter_quill_test.dart similarity index 100% rename from lib/flutter_quill_test.dart rename to flutter_quill_test/lib/flutter_quill_test.dart diff --git a/lib/src/test/widget_tester_extension.dart b/flutter_quill_test/lib/src/test/widget_tester_extension.dart similarity index 90% rename from lib/src/test/widget_tester_extension.dart rename to flutter_quill_test/lib/src/test/widget_tester_extension.dart index ab811fdc..a3ef9f53 100644 --- a/lib/src/test/widget_tester_extension.dart +++ b/flutter_quill_test/lib/src/test/widget_tester_extension.dart @@ -1,9 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_test/flutter_test.dart'; -import '../widgets/editor/editor.dart'; -import '../widgets/raw_editor/raw_editor.dart'; - /// Extends extension QuillEnterText on WidgetTester { /// Give the QuillEditor widget specified by [finder] the focus. @@ -44,10 +42,11 @@ extension QuillEnterText on WidgetTester { /// `find.byType(QuillEditor)`. Future quillUpdateEditingValue(Finder finder, String text) async { return TestAsyncUtils.guard(() async { - final editor = state( + final editor = state( find.descendant( of: finder, - matching: find.byType(RawEditor, skipOffstage: finder.skipOffstage), + matching: + find.byType(QuillRawEditor, skipOffstage: finder.skipOffstage), matchRoot: true), ); testTextInput.updateEditingValue(TextEditingValue( diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml new file mode 100644 index 00000000..731789dc --- /dev/null +++ b/flutter_quill_test/pubspec.yaml @@ -0,0 +1,29 @@ +name: flutter_quill_test +description: Testing for flutter_quill +version: 0.0.1 +homepage: https://1o24bbs.com/c/bulletjournal/108 +repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test + +environment: + sdk: '>=3.1.5 <4.0.0' + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + flutter_quill: ^8.2.1 + flutter_test: + sdk: flutter + +dev_dependencies: + flutter_lints: ^2.0.0 + +# In case you are working on changes for both libraries +# Comment the dependency_overrides section when publishing the package, +# then uncomment it back, this will be automated later +dependency_overrides: + flutter_quill: + path: ../ + + +flutter: diff --git a/flutter_quill_test/test/flutter_quill_test_test.dart b/flutter_quill_test/test/flutter_quill_test_test.dart new file mode 100644 index 00000000..ab73b3a2 --- /dev/null +++ b/flutter_quill_test/test/flutter_quill_test_test.dart @@ -0,0 +1 @@ +void main() {} diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index 25f8c901..7f5f6459 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -27,6 +27,7 @@ export 'src/widgets/default_styles.dart'; export 'src/widgets/editor/editor.dart'; export 'src/widgets/embeds.dart'; export 'src/widgets/link.dart' show LinkActionPickerDelegate, LinkMenuAction; +export 'src/widgets/raw_editor/raw_editor.dart'; export 'src/widgets/style_widgets/style_widgets.dart'; export 'src/widgets/toolbar/base_toolbar.dart'; export 'src/widgets/toolbar/toolbar.dart'; diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index 258f32c1..b4e35811 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -15,12 +15,11 @@ import '../box.dart'; import '../cursor.dart'; import '../delegate.dart'; import '../float_cursor.dart'; -import '../raw_editor/raw_editor.dart'; import '../text_selection.dart'; /// Base interface for the editor state which defines contract used by /// various mixins. -abstract class EditorState extends State +abstract class EditorState extends State implements TextSelectionDelegate { ScrollController get scrollController; @@ -239,7 +238,7 @@ class QuillEditorState extends State final child = QuillEditorProvider( editorConfigurations: configurations, - child: RawEditor( + child: QuillRawEditor( key: _editorKey, controller: context.requireQuillController, focusNode: widget.focusNode, @@ -252,7 +251,7 @@ class QuillEditorState extends State onLaunchUrl: configurations.onLaunchUrl, contextMenuBuilder: showSelectionToolbar ? (configurations.contextMenuBuilder ?? - RawEditor.defaultContextMenuBuilder) + QuillRawEditor.defaultContextMenuBuilder) : null, showSelectionHandles: isMobile(theme.platform), showCursor: configurations.showCursor, diff --git a/lib/src/widgets/raw_editor/raw_editor.dart b/lib/src/widgets/raw_editor/raw_editor.dart index fa2944a1..8da91981 100644 --- a/lib/src/widgets/raw_editor/raw_editor.dart +++ b/lib/src/widgets/raw_editor/raw_editor.dart @@ -55,8 +55,8 @@ import '../toolbar/buttons/search/search_dialog.dart'; import 'raw_editor_state_selection_delegate_mixin.dart'; import 'raw_editor_state_text_input_client_mixin.dart'; -class RawEditor extends StatefulWidget { - const RawEditor({ +class QuillRawEditor extends StatefulWidget { + const QuillRawEditor({ required this.controller, required this.focusNode, required this.scrollController, @@ -139,7 +139,7 @@ class RawEditor extends StatefulWidget { static Widget defaultContextMenuBuilder( BuildContext context, - RawEditorState state, + QuillRawEditorState state, ) { return TextFieldTapRegion( child: AdaptiveTextSelectionToolbar.buttonItems( @@ -227,9 +227,10 @@ class RawEditor extends StatefulWidget { /// Delegate for building the text selection handles and toolbar. /// - /// The [RawEditor] widget used on its own will not trigger the display + /// The [QuillRawEditor] widget used on its own will not trigger the display /// of the selection toolbar by itself. The toolbar is shown by calling - /// [RawEditorState.showToolbar] in response to an appropriate user event. + /// [QuillRawEditorState.showToolbar] in response to + /// an appropriate user event. final TextSelectionControls selectionCtrls; /// The appearance of the keyboard. @@ -287,14 +288,14 @@ class RawEditor extends StatefulWidget { final ContentInsertionConfiguration? contentInsertionConfiguration; @override - State createState() => RawEditorState(); + State createState() => QuillRawEditorState(); } -class RawEditorState extends EditorState +class QuillRawEditorState extends EditorState with - AutomaticKeepAliveClientMixin, + AutomaticKeepAliveClientMixin, WidgetsBindingObserver, - TickerProviderStateMixin, + TickerProviderStateMixin, RawEditorStateTextInputClientMixin, RawEditorStateSelectionDelegateMixin { final GlobalKey _editorKey = GlobalKey(); @@ -354,7 +355,7 @@ class RawEditorState extends EditorState } /// Returns the [ContextMenuButtonItem]s representing the buttons in this - /// platform's default selection menu for [RawEditor]. + /// platform's default selection menu for [QuillRawEditor]. /// /// Copied from [EditableTextState]. List get contextMenuButtonItems { @@ -390,7 +391,7 @@ class RawEditorState extends EditorState } /// Gets the line heights at the start and end of the selection for the given - /// [RawEditorState]. + /// [QuillRawEditorState]. /// /// Copied from [EditableTextState]. _GlyphHeights _getGlyphHeights() { @@ -1171,7 +1172,7 @@ class RawEditorState extends EditorState } @override - void didUpdateWidget(RawEditor oldWidget) { + void didUpdateWidget(QuillRawEditor oldWidget) { super.didUpdateWidget(oldWidget); _cursorCont.show.value = widget.showCursor; @@ -2208,7 +2209,7 @@ class _DeleteTextAction extends ContextAction { _DeleteTextAction(this.state, this.getTextBoundariesForIntent); - final RawEditorState state; + final QuillRawEditorState state; final _TextBoundary Function(T intent) getTextBoundariesForIntent; TextRange _expandNonCollapsedRange(TextEditingValue value) { @@ -2280,7 +2281,7 @@ class _UpdateTextSelectionAction _UpdateTextSelectionAction(this.state, this.ignoreNonCollapsedSelection, this.getTextBoundariesForIntent); - final RawEditorState state; + final QuillRawEditorState state; final bool ignoreNonCollapsedSelection; final _TextBoundary Function(T intent) getTextBoundariesForIntent; @@ -2366,7 +2367,7 @@ class _ExtendSelectionOrCaretPositionAction extends ContextAction< _ExtendSelectionOrCaretPositionAction( this.state, this.getTextBoundariesForIntent); - final RawEditorState state; + final QuillRawEditorState state; final _TextBoundary Function( ExtendSelectionToNextWordBoundaryOrCaretLocationIntent intent) getTextBoundariesForIntent; @@ -2417,7 +2418,7 @@ class _UpdateTextSelectionToAdjacentLineAction< T extends DirectionalCaretMovementIntent> extends ContextAction { _UpdateTextSelectionToAdjacentLineAction(this.state); - final RawEditorState state; + final QuillRawEditorState state; QuillVerticalCaretMovementRun? _verticalMovementRun; TextSelection? _runSelection; @@ -2484,7 +2485,7 @@ class _UpdateTextSelectionToAdjacentLineAction< class _SelectAllAction extends ContextAction { _SelectAllAction(this.state); - final RawEditorState state; + final QuillRawEditorState state; @override Object? invoke(SelectAllTextIntent intent, [BuildContext? context]) { @@ -2506,7 +2507,7 @@ class _SelectAllAction extends ContextAction { class _CopySelectionAction extends ContextAction { _CopySelectionAction(this.state); - final RawEditorState state; + final QuillRawEditorState state; @override void invoke(CopySelectionTextIntent intent, [BuildContext? context]) { @@ -2532,7 +2533,7 @@ class _HideSelectionToolbarAction extends ContextAction { _HideSelectionToolbarAction(this.state); - final RawEditorState state; + final QuillRawEditorState state; @override void invoke(HideSelectionToolbarIntent intent, [BuildContext? context]) { @@ -2546,7 +2547,7 @@ class _HideSelectionToolbarAction class _UndoKeyboardAction extends ContextAction { _UndoKeyboardAction(this.state); - final RawEditorState state; + final QuillRawEditorState state; @override void invoke(UndoTextIntent intent, [BuildContext? context]) { @@ -2562,7 +2563,7 @@ class _UndoKeyboardAction extends ContextAction { class _RedoKeyboardAction extends ContextAction { _RedoKeyboardAction(this.state); - final RawEditorState state; + final QuillRawEditorState state; @override void invoke(RedoTextIntent intent, [BuildContext? context]) { @@ -2585,7 +2586,7 @@ class ToggleTextStyleIntent extends Intent { class _ToggleTextStyleAction extends Action { _ToggleTextStyleAction(this.state); - final RawEditorState state; + final QuillRawEditorState state; bool _isStyleActive(Attribute styleAttr, Map attrs) { if (styleAttr.key == Attribute.list.key) { @@ -2620,7 +2621,7 @@ class IndentSelectionIntent extends Intent { class _IndentSelectionAction extends Action { _IndentSelectionAction(this.state); - final RawEditorState state; + final QuillRawEditorState state; @override void invoke(IndentSelectionIntent intent, [BuildContext? context]) { @@ -2639,7 +2640,7 @@ class OpenSearchIntent extends Intent { class _OpenSearchAction extends ContextAction { _OpenSearchAction(this.state); - final RawEditorState state; + final QuillRawEditorState state; @override Future invoke(OpenSearchIntent intent, [BuildContext? context]) async { @@ -2671,7 +2672,7 @@ class ApplyHeaderIntent extends Intent { class _ApplyHeaderAction extends Action { _ApplyHeaderAction(this.state); - final RawEditorState state; + final QuillRawEditorState state; Attribute _getHeaderValue() { return state.controller @@ -2699,7 +2700,7 @@ class ApplyCheckListIntent extends Intent { class _ApplyCheckListAction extends Action { _ApplyCheckListAction(this.state); - final RawEditorState state; + final QuillRawEditorState state; bool _getIsToggled() { final attrs = state.controller.getSelectionStyle().attributes; @@ -2737,7 +2738,7 @@ class ApplyLinkIntent extends Intent { class ApplyLinkAction extends Action { ApplyLinkAction(this.state); - final RawEditorState state; + final QuillRawEditorState state; @override Object? invoke(ApplyLinkIntent intent) async { @@ -2768,7 +2769,7 @@ class InsertEmbedIntent extends Intent { } /// Signature for a widget builder that builds a context menu for the given -/// [RawEditorState]. +/// [QuillRawEditorState]. /// /// See also: /// @@ -2776,7 +2777,7 @@ class InsertEmbedIntent extends Intent { /// [EditableText] typedef QuillEditorContextMenuBuilder = Widget Function( BuildContext context, - RawEditorState rawEditorState, + QuillRawEditorState rawEditorState, ); class _GlyphHeights { diff --git a/pubspec.yaml b/pubspec.yaml index 5d6cd6f2..6ea8f4ea 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.2.1 +version: 8.2.2 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill @@ -49,12 +49,13 @@ dependencies: pasteboard: ^0.2.0 equatable: ^2.0.5 flutter_animate: ^4.2.0+1 - - flutter_test: - sdk: flutter meta: ^1.9.1 flutter: uses-material-design: true dev_dependencies: - lints: ^3.0.0 \ No newline at end of file + lints: ^3.0.0 + flutter_test: + sdk: flutter + flutter_quill_test: + path: ./flutter_quill_test \ No newline at end of file diff --git a/test/bug_fix_test.dart b/test/bug_fix_test.dart index 9869d517..041b7d2f 100644 --- a/test/bug_fix_test.dart +++ b/test/bug_fix_test.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/flutter_quill_test.dart'; +import 'package:flutter_quill_test/flutter_quill_test.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { diff --git a/test/widgets/editor_test.dart b/test/widgets/editor_test.dart index adaaea49..f063e429 100644 --- a/test/widgets/editor_test.dart +++ b/test/widgets/editor_test.dart @@ -3,8 +3,7 @@ import 'dart:convert' show jsonDecode; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/flutter_quill_test.dart'; -import 'package:flutter_quill/src/widgets/raw_editor/raw_editor.dart'; +import 'package:flutter_quill_test/flutter_quill_test.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { @@ -95,7 +94,7 @@ void main() { expect(latestUri, equals(uri)); }); - Widget customBuilder(BuildContext context, RawEditorState state) { + Widget customBuilder(BuildContext context, QuillRawEditorState state) { return AdaptiveTextSelectionToolbar( anchors: state.contextMenuAnchors, children: [ From 57bb57a22d915c549ad56e84ce224b85fdafab43 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 02:25:21 +0300 Subject: [PATCH 048/210] Configure flutter_quill_test as testing package --- flutter_quill_test/.test_config | 3 +++ flutter_quill_test/CHANGELOG.md | 3 +++ flutter_quill_test/pubspec.yaml | 10 +++++----- 3 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 flutter_quill_test/.test_config diff --git a/flutter_quill_test/.test_config b/flutter_quill_test/.test_config new file mode 100644 index 00000000..412fc5c5 --- /dev/null +++ b/flutter_quill_test/.test_config @@ -0,0 +1,3 @@ +{ + "test_package": true +} \ No newline at end of file diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 77b39e53..b3827d25 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.0.2 +* Add `.test_config` to mark the package as testing package + ## 0.0.1 * initial release. diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 731789dc..a4a2a960 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Testing for flutter_quill -version: 0.0.1 +version: 0.0.2 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test @@ -11,7 +11,7 @@ environment: dependencies: flutter: sdk: flutter - flutter_quill: ^8.2.1 + flutter_quill: ^8.2.2 flutter_test: sdk: flutter @@ -21,9 +21,9 @@ dev_dependencies: # In case you are working on changes for both libraries # Comment the dependency_overrides section when publishing the package, # then uncomment it back, this will be automated later -dependency_overrides: - flutter_quill: - path: ../ +# dependency_overrides: +# flutter_quill: +# path: ../ flutter: From 676077cb0cdc3b905adb77baffb050f81a221485 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 02:45:30 +0300 Subject: [PATCH 049/210] Update flutter_quill_test --- analysis_options.yaml | 1 - flutter_quill_extensions/pubspec.yaml | 8 ++--- flutter_quill_test/analysis_options.yaml | 39 ++++++++++++++++++++++-- flutter_quill_test/pubspec.yaml | 1 + pubspec.yaml | 7 +++-- 5 files changed, 45 insertions(+), 11 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index f3e3dd31..8f1b96e4 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,5 +1,4 @@ include: package:lints/recommended.yaml -# include: package:pedantic/analysis_options.yaml analyzer: errors: diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 18c81d21..beae97f6 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -26,7 +26,7 @@ dependencies: flutter: sdk: flutter - flutter_quill: ^8.2.0 + flutter_quill: ^8.2.2 http: ^1.1.0 photo_view: ^0.14.0 @@ -45,9 +45,9 @@ dependencies: # In case you are working on changes for both libraries # Comment the dependency_overrides section when publishing the package, # then uncomment it back, this will be automated later -dependency_overrides: - flutter_quill: - path: ../ +# dependency_overrides: +# flutter_quill: +# path: ../ dev_dependencies: flutter_test: diff --git a/flutter_quill_test/analysis_options.yaml b/flutter_quill_test/analysis_options.yaml index a5744c1c..8f1b96e4 100644 --- a/flutter_quill_test/analysis_options.yaml +++ b/flutter_quill_test/analysis_options.yaml @@ -1,4 +1,37 @@ -include: package:flutter_lints/flutter.yaml +include: package:lints/recommended.yaml -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options +analyzer: + errors: + undefined_prefixed_name: ignore + unsafe_html: ignore +linter: + rules: + - always_declare_return_types + - always_put_required_named_parameters_first + - annotate_overrides + - avoid_empty_else + - avoid_escaping_inner_quotes + - avoid_print + - avoid_redundant_argument_values + - avoid_types_on_closure_parameters + - avoid_void_async + - cascade_invocations + - directives_ordering + - lines_longer_than_80_chars + - omit_local_variable_types + - prefer_const_constructors + - prefer_const_constructors_in_immutables + - prefer_const_declarations + - prefer_final_fields + - prefer_final_in_for_each + - prefer_final_locals + - prefer_initializing_formals + - prefer_int_literals + - prefer_interpolation_to_compose_strings + - prefer_relative_imports + - prefer_single_quotes + - sort_constructors_first + - sort_unnamed_constructors_first + - unnecessary_lambdas + - unnecessary_parenthesis + - unnecessary_string_interpolations diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index a4a2a960..7f941557 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -27,3 +27,4 @@ dev_dependencies: flutter: + uses-material-design: true diff --git a/pubspec.yaml b/pubspec.yaml index 6ea8f4ea..b53cd569 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,7 +30,7 @@ platforms: windows: environment: - sdk: '>=3.1.3 <4.0.0' + sdk: '>=3.1.5 <4.0.0' # sdk: ">=2.17.0 <4.0.0" flutter: ">=3.10.0" @@ -57,5 +57,6 @@ dev_dependencies: lints: ^3.0.0 flutter_test: sdk: flutter - flutter_quill_test: - path: ./flutter_quill_test \ No newline at end of file + flutter_quill_test: ^0.0.2 + # flutter_quill_test: + # path: ./flutter_quill_test \ No newline at end of file From 32d9d9a4f985cc093a75caa29d19ed030d20b880 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 02:57:34 +0300 Subject: [PATCH 050/210] Update README.md --- README.md | 285 ++----------------------------------- doc/custom_embed_blocks.md | 124 ++++++++++++++++ doc/custom_toolbar.md | 143 +++++++++++++++++++ 3 files changed, 277 insertions(+), 275 deletions(-) create mode 100644 doc/custom_embed_blocks.md create mode 100644 doc/custom_toolbar.md diff --git a/README.md b/README.md index 63e43be0..65305d67 100644 --- a/README.md +++ b/README.md @@ -294,270 +294,13 @@ Define `width`, `height`, `margin`, `alignment` as follows: Sometimes you want to add some custom content inside your text, custom widgets inside of them. An example is adding notes to the text, or anything custom that you want to add in your text editor. -The only thing that you need is to add a `CustomBlockEmbed` and provider a builder for it to the `embedBuilders` parameter, to transform the data inside of the Custom Block into a widget! - -Here is an example: - -Starting with the `CustomBlockEmbed`, here we extend it and add the methods that are useful for the 'Note' widget, that will be the `Document`, used by the `flutter_quill` to render the rich text. - -```dart -class NotesBlockEmbed extends CustomBlockEmbed { - const NotesBlockEmbed(String value) : super(noteType, value); - - static const String noteType = 'notes'; - - static NotesBlockEmbed fromDocument(Document document) => - NotesBlockEmbed(jsonEncode(document.toDelta().toJson())); - - Document get document => Document.fromJson(jsonDecode(data)); -} -``` - -After that, we need to map this "notes" type into a widget. In that case, I used a `ListTile` with a text to show the plain text resume of the note, and the `onTap` function to edit the note. -Don't forget to add this method to the `QuillEditor` after that! - -```dart -class NotesEmbedBuilder extends EmbedBuilder { - NotesEmbedBuilder({required this.addEditNote}); - - Future Function(BuildContext context, {Document? document}) addEditNote; - - @override - String get key => 'notes'; - - @override - Widget build( - BuildContext context, - QuillController controller, - Embed node, - bool readOnly, - bool inline, - TextStyle textStyle, - ) { - final notes = NotesBlockEmbed(node.value.data).document; - - return Material( - color: Colors.transparent, - child: ListTile( - title: Text( - notes.toPlainText().replaceAll('\n', ' '), - maxLines: 3, - overflow: TextOverflow.ellipsis, - ), - leading: const Icon(Icons.notes), - onTap: () => addEditNote(context, document: notes), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - side: const BorderSide(color: Colors.grey), - ), - ), - ); - } -} -``` - -And finally, we write the function to add/edit this note. The `showDialog` function shows the QuillEditor to edit the note, after the user ends the edition, we check if the document has something, and if it has, we add or edit the `NotesBlockEmbed` inside of a `BlockEmbed.custom` (this is a little detail that will not work if you don't pass the `CustomBlockEmbed` inside of a `BlockEmbed.custom`). - -```dart -Future _addEditNote(BuildContext context, {Document? document}) async { - final isEditing = document != null; - final quillEditorController = QuillController( - document: document ?? Document(), - selection: const TextSelection.collapsed(offset: 0), - ); - - await showDialog( - context: context, - builder: (context) => AlertDialog( - titlePadding: const EdgeInsets.only(left: 16, top: 8), - title: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text('${isEditing ? 'Edit' : 'Add'} note'), - IconButton( - onPressed: () => Navigator.of(context).pop(), - icon: const Icon(Icons.close), - ) - ], - ), - content: QuillEditor.basic( - controller: quillEditorController, - readOnly: false, - ), - ), - ); - - if (quillEditorController.document.isEmpty()) return; - - final block = BlockEmbed.custom( - NotesBlockEmbed.fromDocument(quillEditorController.document), - ); - final controller = _controller!; - final index = controller.selection.baseOffset; - final length = controller.selection.extentOffset - index; - - if (isEditing) { - final offset = getEmbedNode(controller, controller.selection.start).offset; - controller.replaceText( - offset, 1, block, TextSelection.collapsed(offset: offset)); - } else { - controller.replaceText(index, length, block, null); - } -} -``` - -And voila, we have a custom widget inside of the rich text editor! - -

    - 1 -

    - -> 1. For more info and a video example, see the [PR of this feature](https://github.com/singerdmx/flutter-quill/pull/877) -> 2. For more details, check out [this YouTube video](https://youtu.be/pI5p5j7cfHc) +Open this [page](./doc/custom_embed_blocks.dart) for more info ### Custom Toolbar If you want to use custom toolbar but still want the support of this libray -You can use the `QuillBaseToolbar` which is the base for the `QuillToolbar` - -> If you are using the toolbar buttons like `QuillToolbarHistoryButton`, `QuillToolbarToggleStyleButton` in the somewhere like the the custom toolbar then you must provide them with `QuillToolbarProvider` inherited widget, you don't have to do this if you are using the `QuillToolbar` since it will be done for you - -Example: - -```dart -QuillProvider( - configurations: QuillConfigurations( - controller: _controller, - sharedConfigurations: const QuillSharedConfigurations(), - ), - child: Column( - children: [ - QuillToolbarProvider( - toolbarConfigurations: const QuillToolbarConfigurations(), - child: QuillBaseToolbar( - configurations: QuillBaseToolbarConfigurations( - toolbarSize: 15 * 2, - multiRowsDisplay: false, - childrenBuilder: (context) { - final controller = context.requireQuillController; - return [ - QuillToolbarHistoryButton( - controller: controller, - options: const QuillToolbarHistoryButtonOptions( - isUndo: true), - ), - QuillToolbarHistoryButton( - controller: controller, - options: const QuillToolbarHistoryButtonOptions( - isUndo: false), - ), - QuillToolbarToggleStyleButton( - attribute: Attribute.bold, - controller: controller, - options: const QuillToolbarToggleStyleButtonOptions( - iconData: Icons.format_bold, - iconSize: 20, - ), - ), - QuillToolbarToggleStyleButton( - attribute: Attribute.italic, - controller: controller, - options: const QuillToolbarToggleStyleButtonOptions( - iconData: Icons.format_italic, - iconSize: 20, - ), - ), - QuillToolbarToggleStyleButton( - attribute: Attribute.underline, - controller: controller, - options: const QuillToolbarToggleStyleButtonOptions( - iconData: Icons.format_underline, - iconSize: 20, - ), - ), - QuillToolbarClearFormatButton( - controller: controller, - options: const QuillToolbarClearFormatButtonOptions( - iconData: Icons.format_clear, - iconSize: 20, - ), - ), - VerticalDivider( - indent: 12, - endIndent: 12, - color: Colors.grey.shade400, - ), - QuillToolbarSelectHeaderStyleButtons( - controller: controller, - options: - const QuillToolbarSelectHeaderStyleButtonsOptions( - iconSize: 20, - ), - ), - QuillToolbarToggleStyleButton( - attribute: Attribute.ol, - controller: controller, - options: const QuillToolbarToggleStyleButtonOptions( - iconData: Icons.format_list_numbered, - iconSize: 20, - ), - ), - QuillToolbarToggleStyleButton( - attribute: Attribute.ul, - controller: controller, - options: const QuillToolbarToggleStyleButtonOptions( - iconData: Icons.format_list_bulleted, - iconSize: 20, - ), - ), - QuillToolbarToggleStyleButton( - attribute: Attribute.blockQuote, - controller: controller, - options: const QuillToolbarToggleStyleButtonOptions( - iconData: Icons.format_quote, - iconSize: 20, - ), - ), - VerticalDivider( - indent: 12, - endIndent: 12, - color: Colors.grey.shade400, - ), - QuillToolbarIndentButton( - controller: controller, - isIncrease: true, - options: const QuillToolbarIndentButtonOptions( - iconData: Icons.format_indent_increase, - iconSize: 20, - )), - QuillToolbarIndentButton( - controller: controller, - isIncrease: false, - options: const QuillToolbarIndentButtonOptions( - iconData: Icons.format_indent_decrease, - iconSize: 20, - ), - ), - ]; - }, - ), - ), - ), - Expanded( - child: QuillEditor.basic( - configurations: const QuillEditorConfigurations( - readOnly: false, - placeholder: 'Write your notes', - padding: EdgeInsets.all(16), - ), - ), - ) - ], - ), -) -``` -if you want more customized toolbar feel free to create your own and use the `controller` to interact with the editor. checkout the `QuillToolbar` and the buttons inside it to see an example of how that will works +Open this [page](./doc/custom_toolbar.md) for more info ### Translation @@ -590,22 +333,14 @@ The package offers translations for the quill toolbar and editor, it will follow Currently, translations are available for these 31 locales: -* `Locale('en')`, `Locale('ar')` -* `Locale('bn')`, `Locale('bs')` -* `Locale('cs')`, `Locale('de')` -* `Locale('da')`, `Locale('fr')` -* `Locale('he')`, `Locale('zh', 'cn')` -* `Locale('zh', 'hk')`, `Locale('ko')` -* `Locale('ru')`, `Locale('es')` -* `Locale('tk')`, `Locale('tr')` -* `Locale('uk')`, `Locale('ur')` -* `Locale('pt')`, `Locale('pl')` -* `Locale('vi')`, `Locale('id')` -* `Locale('it')`, `Locale('ms')` -* `Locale('nl')`, `Locale('no')` -* `Locale('fa')`, `Locale('hi')` -* `Locale('sr')`, `Locale('sw')` -* `Locale('ja')` +* `Locale('en')`, `Locale('ar')`, `Locale('bn')`, `Locale('bs')` +* `Locale('cs')`, `Locale('de')`, `Locale('da')`, `Locale('fr')` +* `Locale('he')`, `Locale('zh', 'cn')`, `Locale('zh', 'hk')`, `Locale('ko')` +* `Locale('ru')`, `Locale('es')`, `Locale('tk')`, `Locale('tr')` +* `Locale('uk')`, `Locale('ur')`, `Locale('pt')`, `Locale('pl')` +* `Locale('vi')`, `Locale('id')`, `Locale('it')`, `Locale('ms')` +* `Locale('nl')`, `Locale('no')`, `Locale('fa')`, `Locale('hi')` +* `Locale('sr')`, `Locale('sw')`, `Locale('ja')` #### Contributing to translations diff --git a/doc/custom_embed_blocks.md b/doc/custom_embed_blocks.md new file mode 100644 index 00000000..82a1e44c --- /dev/null +++ b/doc/custom_embed_blocks.md @@ -0,0 +1,124 @@ +# Custom Embed Blocks + +Sometimes you want to add some custom content inside your text, custom widgets inside of them. An example is adding notes to the text, or anything custom that you want to add in your text editor. + +The only thing that you need is to add a `CustomBlockEmbed` and provider a builder for it to the `embedBuilders` parameter, to transform the data inside of the Custom Block into a widget! + +Here is an example: + +Starting with the `CustomBlockEmbed`, here we extend it and add the methods that are useful for the 'Note' widget, that will be the `Document`, used by the `flutter_quill` to render the rich text. + +```dart +class NotesBlockEmbed extends CustomBlockEmbed { + const NotesBlockEmbed(String value) : super(noteType, value); + + static const String noteType = 'notes'; + + static NotesBlockEmbed fromDocument(Document document) => + NotesBlockEmbed(jsonEncode(document.toDelta().toJson())); + + Document get document => Document.fromJson(jsonDecode(data)); +} +``` + +After that, we need to map this "notes" type into a widget. In that case, I used a `ListTile` with a text to show the plain text resume of the note, and the `onTap` function to edit the note. +Don't forget to add this method to the `QuillEditor` after that! + +```dart +class NotesEmbedBuilder extends EmbedBuilder { + NotesEmbedBuilder({required this.addEditNote}); + + Future Function(BuildContext context, {Document? document}) addEditNote; + + @override + String get key => 'notes'; + + @override + Widget build( + BuildContext context, + QuillController controller, + Embed node, + bool readOnly, + bool inline, + TextStyle textStyle, + ) { + final notes = NotesBlockEmbed(node.value.data).document; + + return Material( + color: Colors.transparent, + child: ListTile( + title: Text( + notes.toPlainText().replaceAll('\n', ' '), + maxLines: 3, + overflow: TextOverflow.ellipsis, + ), + leading: const Icon(Icons.notes), + onTap: () => addEditNote(context, document: notes), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: const BorderSide(color: Colors.grey), + ), + ), + ); + } +} +``` + +And finally, we write the function to add/edit this note. The `showDialog` function shows the QuillEditor to edit the note, after the user ends the edition, we check if the document has something, and if it has, we add or edit the `NotesBlockEmbed` inside of a `BlockEmbed.custom` (this is a little detail that will not work if you don't pass the `CustomBlockEmbed` inside of a `BlockEmbed.custom`). + +```dart +Future _addEditNote(BuildContext context, {Document? document}) async { + final isEditing = document != null; + final quillEditorController = QuillController( + document: document ?? Document(), + selection: const TextSelection.collapsed(offset: 0), + ); + + await showDialog( + context: context, + builder: (context) => AlertDialog( + titlePadding: const EdgeInsets.only(left: 16, top: 8), + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('${isEditing ? 'Edit' : 'Add'} note'), + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.close), + ) + ], + ), + content: QuillEditor.basic( + controller: quillEditorController, + readOnly: false, + ), + ), + ); + + if (quillEditorController.document.isEmpty()) return; + + final block = BlockEmbed.custom( + NotesBlockEmbed.fromDocument(quillEditorController.document), + ); + final controller = _controller!; + final index = controller.selection.baseOffset; + final length = controller.selection.extentOffset - index; + + if (isEditing) { + final offset = getEmbedNode(controller, controller.selection.start).offset; + controller.replaceText( + offset, 1, block, TextSelection.collapsed(offset: offset)); + } else { + controller.replaceText(index, length, block, null); + } +} +``` + +And voila, we have a custom widget inside of the rich text editor! + +

    + 1 +

    + +> 1. For more info and a video example, see the [PR of this feature](https://github.com/singerdmx/flutter-quill/pull/877) +> 2. For more details, check out [this YouTube video](https://youtu.be/pI5p5j7cfHc) \ No newline at end of file diff --git a/doc/custom_toolbar.md b/doc/custom_toolbar.md new file mode 100644 index 00000000..06c8bb72 --- /dev/null +++ b/doc/custom_toolbar.md @@ -0,0 +1,143 @@ +# Custom Toolbar + +If you want to use custom toolbar but still want the support of this libray +You can use the `QuillBaseToolbar` which is the base for the `QuillToolbar` + +> If you are using the toolbar buttons like `QuillToolbarHistoryButton`, `QuillToolbarToggleStyleButton` in the somewhere like the the custom toolbar then you must provide them with `QuillToolbarProvider` inherited widget, you don't have to do this if you are using the `QuillToolbar` since it will be done for you + +Example: + +```dart +QuillProvider( + configurations: QuillConfigurations( + controller: _controller, + sharedConfigurations: const QuillSharedConfigurations(), + ), + child: Column( + children: [ + QuillToolbarProvider( + toolbarConfigurations: const QuillToolbarConfigurations(), + child: QuillBaseToolbar( + configurations: QuillBaseToolbarConfigurations( + toolbarSize: 15 * 2, + multiRowsDisplay: false, + childrenBuilder: (context) { + final controller = context.requireQuillController; + return [ + QuillToolbarHistoryButton( + controller: controller, + options: const QuillToolbarHistoryButtonOptions( + isUndo: true), + ), + QuillToolbarHistoryButton( + controller: controller, + options: const QuillToolbarHistoryButtonOptions( + isUndo: false), + ), + QuillToolbarToggleStyleButton( + attribute: Attribute.bold, + controller: controller, + options: const QuillToolbarToggleStyleButtonOptions( + iconData: Icons.format_bold, + iconSize: 20, + ), + ), + QuillToolbarToggleStyleButton( + attribute: Attribute.italic, + controller: controller, + options: const QuillToolbarToggleStyleButtonOptions( + iconData: Icons.format_italic, + iconSize: 20, + ), + ), + QuillToolbarToggleStyleButton( + attribute: Attribute.underline, + controller: controller, + options: const QuillToolbarToggleStyleButtonOptions( + iconData: Icons.format_underline, + iconSize: 20, + ), + ), + QuillToolbarClearFormatButton( + controller: controller, + options: const QuillToolbarClearFormatButtonOptions( + iconData: Icons.format_clear, + iconSize: 20, + ), + ), + VerticalDivider( + indent: 12, + endIndent: 12, + color: Colors.grey.shade400, + ), + QuillToolbarSelectHeaderStyleButtons( + controller: controller, + options: + const QuillToolbarSelectHeaderStyleButtonsOptions( + iconSize: 20, + ), + ), + QuillToolbarToggleStyleButton( + attribute: Attribute.ol, + controller: controller, + options: const QuillToolbarToggleStyleButtonOptions( + iconData: Icons.format_list_numbered, + iconSize: 20, + ), + ), + QuillToolbarToggleStyleButton( + attribute: Attribute.ul, + controller: controller, + options: const QuillToolbarToggleStyleButtonOptions( + iconData: Icons.format_list_bulleted, + iconSize: 20, + ), + ), + QuillToolbarToggleStyleButton( + attribute: Attribute.blockQuote, + controller: controller, + options: const QuillToolbarToggleStyleButtonOptions( + iconData: Icons.format_quote, + iconSize: 20, + ), + ), + VerticalDivider( + indent: 12, + endIndent: 12, + color: Colors.grey.shade400, + ), + QuillToolbarIndentButton( + controller: controller, + isIncrease: true, + options: const QuillToolbarIndentButtonOptions( + iconData: Icons.format_indent_increase, + iconSize: 20, + )), + QuillToolbarIndentButton( + controller: controller, + isIncrease: false, + options: const QuillToolbarIndentButtonOptions( + iconData: Icons.format_indent_decrease, + iconSize: 20, + ), + ), + ]; + }, + ), + ), + ), + Expanded( + child: QuillEditor.basic( + configurations: const QuillEditorConfigurations( + readOnly: false, + placeholder: 'Write your notes', + padding: EdgeInsets.all(16), + ), + ), + ) + ], + ), +) +``` + +if you want more customized toolbar feel free to create your own and use the `controller` to interact with the editor. checkout the `QuillToolbar` and the buttons inside it to see an example of how that will works \ No newline at end of file From f1f45d30bf8cc6f8b630cd1dcd5871b1e3d9b111 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 02:59:01 +0300 Subject: [PATCH 051/210] Fix link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 65305d67..000201df 100644 --- a/README.md +++ b/README.md @@ -294,7 +294,7 @@ Define `width`, `height`, `margin`, `alignment` as follows: Sometimes you want to add some custom content inside your text, custom widgets inside of them. An example is adding notes to the text, or anything custom that you want to add in your text editor. -Open this [page](./doc/custom_embed_blocks.dart) for more info +Open this [page](./doc/custom_embed_blocks.md) for more info ### Custom Toolbar From 83ec05b9e6773138c5c23c8008fc4ce79ad1aff4 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 03:07:40 +0300 Subject: [PATCH 052/210] Fix another link in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 000201df..23f71c4b 100644 --- a/README.md +++ b/README.md @@ -378,7 +378,7 @@ Made with [contrib.rocks](https://contrib.rocks). We welcome contributions! -Please follow these guidelines when contributing to our project. See [CONTRIBUTING.md](./../CONTRIBUTING.md) for more details. +Please follow these guidelines when contributing to our project. See [CONTRIBUTING.md](./CONTRIBUTING.md) for more details. [Quill]: https://quilljs.com/docs/formats [Flutter]: https://github.com/flutter/flutter From 829eafa3e4d856c1decaffbbcf4bf7ddea067d2a Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 03:22:51 +0300 Subject: [PATCH 053/210] Update flutter_quill_extensions --- flutter_quill_extensions/lib/flutter_quill_extensions.dart | 3 +++ .../embeds/toolbar/camera_button/select_camera_action.dart | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index b1c6b37d..6b011b06 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -39,7 +39,10 @@ export 'presentation/embeds/toolbar/utils/image_video_utils.dart'; export 'presentation/embeds/toolbar/video_button/video_button.dart'; export 'presentation/embeds/utils.dart'; export 'presentation/models/config/editor/image.dart'; +export 'presentation/models/config/toolbar/buttons/camera.dart'; +export 'presentation/models/config/toolbar/buttons/formula.dart'; export 'presentation/models/config/toolbar/buttons/image.dart'; +export 'presentation/models/config/toolbar/buttons/media_button.dart'; export 'presentation/models/config/toolbar/buttons/video.dart'; @immutable diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/select_camera_action.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/select_camera_action.dart index a79fa393..b68742db 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/select_camera_action.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/select_camera_action.dart @@ -10,14 +10,12 @@ class SelectCameraActionDialog extends StatelessWidget { Widget build(BuildContext context) { return AlertDialog( contentPadding: EdgeInsets.zero, - backgroundColor: Colors.transparent, content: Column( mainAxisSize: MainAxisSize.min, children: [ TextButton.icon( icon: const Icon( Icons.camera, - color: Colors.orangeAccent, ), label: Text('Photo'.i18n), onPressed: () => Navigator.pop(context, CameraAction.image), @@ -25,7 +23,6 @@ class SelectCameraActionDialog extends StatelessWidget { TextButton.icon( icon: const Icon( Icons.video_call, - color: Colors.cyanAccent, ), label: Text('Video'.i18n), onPressed: () => Navigator.pop(context, CameraAction.video), From 6de3a850465bf730250139fe6a7be7b509bb0925 Mon Sep 17 00:00:00 2001 From: X Code Date: Sun, 5 Nov 2023 16:29:43 -0800 Subject: [PATCH 054/210] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 23f71c4b..cc0f6855 100644 --- a/README.md +++ b/README.md @@ -258,7 +258,7 @@ Provide a list of embed ### Using the embed blocks from `flutter_quill_extensions` -Too see how to use the extensions package, please take a look at the [README](./flutter_quill_extensions/README.md) of [FlutterQuill Extensions] +To see how to use the extensions package, please take a look at the [README](./flutter_quill_extensions/README.md) of [FlutterQuill Extensions] ### Custom Size Image for Mobile From 6c0a994a98a8ab9ebc739dd4a2af46c8139d4467 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 03:37:54 +0300 Subject: [PATCH 055/210] Update flutter_quill_extensions --- flutter_quill_extensions/CHANGELOG.md | 3 ++ .../embeds/embed_types/camera.dart | 14 ++++++++- .../toolbar/camera_button/camera_button.dart | 31 +++++-------------- flutter_quill_extensions/pubspec.yaml | 2 +- 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 5ff6b595..0ae9e262 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.6.0-dev.5 +- Update the camera button + ## 0.6.0-dev.4 - Add more exports - Update `README.md`` diff --git a/flutter_quill_extensions/lib/presentation/embeds/embed_types/camera.dart b/flutter_quill_extensions/lib/presentation/embeds/embed_types/camera.dart index 7ce65321..1e293123 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/embed_types/camera.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/embed_types/camera.dart @@ -2,6 +2,7 @@ import 'package:flutter/widgets.dart' show BuildContext; import 'package:meta/meta.dart' show immutable; import 'image.dart'; +import 'video.dart'; enum CameraAction { video, @@ -22,7 +23,10 @@ class QuillToolbarCameraConfigurations { this.onRequestCameraActionCallback, OnImageInsertCallback? onImageInsertCallback, this.onImageInsertedCallback, - }) : _onImageInsertCallback = onImageInsertCallback; + this.onVideoInsertedCallback, + OnVideoInsertCallback? onVideoInsertCallback, + }) : _onImageInsertCallback = onImageInsertCallback, + _onVideoInsertCallback = onVideoInsertCallback; final OnRequestCameraActionCallback? onRequestCameraActionCallback; @@ -33,4 +37,12 @@ class QuillToolbarCameraConfigurations { OnImageInsertCallback get onImageInsertCallback { return _onImageInsertCallback ?? defaultOnImageInsertCallback(); } + + final OnVideoInsertedCallback? onVideoInsertedCallback; + + final OnVideoInsertCallback? _onVideoInsertCallback; + + OnVideoInsertCallback get onVideoInsertCallback { + return _onVideoInsertCallback ?? defaultOnVideoInsertCallback(); + } } diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart index 5cde1ace..43d74f04 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart @@ -149,6 +149,12 @@ class QuillToolbarCameraButton extends StatelessWidget { if (videoFile == null) { return; } + await options.cameraConfigurations.onVideoInsertCallback( + videoFile.path, + controller, + ); + await options.cameraConfigurations.onVideoInsertedCallback + ?.call(videoFile.path); case CameraAction.image: final imageFile = await imagePickerService.pickImage( source: ImageSource.camera, @@ -156,7 +162,7 @@ class QuillToolbarCameraButton extends StatelessWidget { if (imageFile == null) { return; } - options.cameraConfigurations.onImageInsertCallback( + await options.cameraConfigurations.onImageInsertCallback( imageFile.path, controller, ); @@ -170,28 +176,5 @@ class QuillToolbarCameraButton extends StatelessWidget { // CameraAction.video => // imagePickerService.pickVideo(source: ImageSource.camera), // }; - - // switch (source) { - // case MediaPickSetting.camera: - // await ImageVideoUtils.handleImageButtonTap( - // context, - // controller, - // ImageSource.camera, - // onImagePickCallback!, - // filePickImpl: filePickImpl, - // webImagePickImpl: webImagePickImpl, - // ); - // break; - // case MediaPickSetting.video: - // await ImageVideoUtils.handleVideoButtonTap( - // context, - // controller, - // ImageSource.camera, - // onVideoPickCallback!, - // filePickImpl: filePickImpl, - // webVideoPickImpl: options.webVideoPickImpl, - // ); - // break; - // } } } diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index beae97f6..3a6948f9 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 0.6.0-dev.4 +version: 0.6.0-dev.5 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions From c42e9561c2d39bc0cbcb1658bf1977c0ecad2dc8 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 03:47:58 +0300 Subject: [PATCH 056/210] Update flutter_quill_test --- flutter_quill_test/CHANGELOG.md | 3 +++ flutter_quill_test/README.md | 2 ++ flutter_quill_test/pubspec.yaml | 19 +++++++++++++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index b3827d25..158ce0f2 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.0.3 +* Update the `README.md` and description + ## 0.0.2 * Add `.test_config` to mark the package as testing package diff --git a/flutter_quill_test/README.md b/flutter_quill_test/README.md index c32a78fe..d244e54b 100644 --- a/flutter_quill_test/README.md +++ b/flutter_quill_test/README.md @@ -1,5 +1,7 @@ # Flutter Quill Test +Test utilities for [flutter_quill](https://pub.dev/packages/flutter_quill) which includes methods to simplify interacting with the editor in test cases. + ## Testing To aid in testing applications using the editor an extension to the flutter `WidgetTester` is provided which includes methods to simplify interacting with the editor in test cases. diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 7f941557..c8a535ff 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,9 +1,24 @@ name: flutter_quill_test -description: Testing for flutter_quill -version: 0.0.2 +description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. +version: 0.0.3 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test +topics: + - ui + - widgets + - widget + - rich-text-editor + - quill + +platforms: + android: + ios: + linux: + macos: + web: + windows: + environment: sdk: '>=3.1.5 <4.0.0' flutter: ">=1.17.0" From 80e68aab40f78e3422c399dee711368f96255dff Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 03:53:07 +0300 Subject: [PATCH 057/210] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91598874..d19c5509 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ ## [8.2.2] -- Move the `flutter_quill_test` to seperated package [flutter_quill_test](https://pub.dev/packages/fresh_quill_extensions) +- Move the `flutter_quill_test` to seperated package [flutter_quill_test](https://pub.dev/packages/flutter_quill_test) ## [8.2.1] - Update `README.md` From da240eee0b400897af6c05df3f354a455d0a7664 Mon Sep 17 00:00:00 2001 From: X Code Date: Sun, 5 Nov 2023 16:55:15 -0800 Subject: [PATCH 058/210] Update README.md --- flutter_quill_extensions/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index b1810c95..f65bf91b 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -49,7 +49,7 @@ dependencies: > 1. For Android, you need to add some permissions in `AndroidManifest.xml`, Please follow this [link](https://developer.android.com/training/basics/network-ops/connecting) for more info, the internet permission included by default only for debugging so you need to follow this link to add it in the release version too. you should allow loading images and videos only for the `https` protocol but if you want http too then you need to configure your android application to accept `http` in the release mode, follow this [link](https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted) for more info. > 2. for macOS you also need to include a key in your `Info.plist`, please follow this [link](https://stackoverflow.com/a/61201081/18519412) to add the required configurations > -> The extensions package also use [image_picker](https://pub.dev/packages/image_picker) which also require some configurations, follow this [link](https://pub.dev/packages/image_picker#installation). It's needed for Android, iOS, macOS, we must inform you that you can't pick photo using camera in desktop so make sure to handle that if you plan on add support for desktop, this might changed in the future and for more info follow this [link](https://pub.dev/packages/image_picker#windows-macos-and-linux)
    +> The extensions package also use [image_picker](https://pub.dev/packages/image_picker) which also require some configurations, follow this [link](https://pub.dev/packages/image_picker#installation). It's needed for Android, iOS, macOS, we must inform you that you can't pick photo using camera in desktop so make sure to handle that if you plan on add support for desktop, this may change in the future and for more info follow this [link](https://pub.dev/packages/image_picker#windows-macos-and-linux)
    > ## Usage @@ -134,4 +134,4 @@ This project is licensed under the [MIT License](LICENSE) - see the [LICENSE](LI ## Acknowledgments - Thanks to the [Flutter Team](https://flutter.dev/) -- Thanks to [flutter_quill](https://pub.dev/packages/flutter_quill) \ No newline at end of file +- Thanks to [flutter_quill](https://pub.dev/packages/flutter_quill) From 606e4d878d23e6e83ad2b7b6b0a093885d90ce33 Mon Sep 17 00:00:00 2001 From: Cheryl Date: Sun, 5 Nov 2023 16:57:06 -0800 Subject: [PATCH 059/210] Update README --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cc0f6855..ee031081 100644 --- a/README.md +++ b/README.md @@ -264,7 +264,7 @@ To see how to use the extensions package, please take a look at the [README](./f Define `mobileWidth`, `mobileHeight`, `mobileMargin`, `mobileAlignment` as follows: -```dart +```json { "insert": { "image": "https://user-images.githubusercontent.com/122956/72955931-ccc07900-3d52-11ea-89b1-d468a6e2aa2b.png" @@ -279,7 +279,7 @@ Define `mobileWidth`, `mobileHeight`, `mobileMargin`, `mobileAlignment` as follo Define `width`, `height`, `margin`, `alignment` as follows: -```dart +```json { "insert": { "image": "https://user-images.githubusercontent.com/122956/72955931-ccc07900-3d52-11ea-89b1-d468a6e2aa2b.png" @@ -392,5 +392,3 @@ Please follow these guidelines when contributing to our project. See [CONTRIBUTI [FluentUI]: https://pub.dev/packages/fluent_ui
    - -[中文文档](./doc/readme/cn.md) From d2553a42b92a7b05414c6a95953fba729c55c5c5 Mon Sep 17 00:00:00 2001 From: X Code Date: Sun, 5 Nov 2023 16:58:29 -0800 Subject: [PATCH 060/210] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index ee031081..844f5f1d 100644 --- a/README.md +++ b/README.md @@ -391,4 +391,3 @@ Please follow these guidelines when contributing to our project. See [CONTRIBUTI [Code Introduction]: https://github.com/singerdmx/flutter-quill/blob/master/doc/CodeIntroduction.md [FluentUI]: https://pub.dev/packages/fluent_ui -
    From 3968f7f87952b2f63333fdf690d732d421ba2b4d Mon Sep 17 00:00:00 2001 From: X Code Date: Sun, 5 Nov 2023 17:00:03 -0800 Subject: [PATCH 061/210] Update README.md --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 844f5f1d..180cc19f 100644 --- a/README.md +++ b/README.md @@ -360,10 +360,6 @@ Typescript/Javascript package. Please use [flutter_quill_test](https://pub.dev/packages/flutter_quill_test) for testing -## License - -[MIT](LICENSE) - ## Contributors Special thanks for everyone that have contributed to this project... From 6d3692f01ed35fc75fe4a4e862b6f5e0262dc071 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 04:04:31 +0300 Subject: [PATCH 062/210] Remove license from table of contents --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 180cc19f..0679b469 100644 --- a/README.md +++ b/README.md @@ -49,11 +49,9 @@ Pub: [FlutterQuill] - [Custom Embed Blocks](#custom-embed-blocks) - [Custom Toolbar](#custom-toolbar) - [Translation](#translation) - - [](#) - [Contributing to translations](#contributing-to-translations) - [Conversion to HTML](#conversion-to-html) - [Testing](#testing) - - [License](#license) - [Contributors](#contributors) ## Installation @@ -329,8 +327,6 @@ The package offers translations for the quill toolbar and editor, it will follow ) ``` -### - Currently, translations are available for these 31 locales: * `Locale('en')`, `Locale('ar')`, `Locale('bn')`, `Locale('bs')` From 7d5b1cdf8b7b2806073f56840011055ecea7a576 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 04:15:48 +0300 Subject: [PATCH 063/210] Move translation section in README.md --- README.md | 41 ++--------------------------------------- doc/translation.md | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 39 deletions(-) create mode 100644 doc/translation.md diff --git a/README.md b/README.md index 0679b469..b3287eb8 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,6 @@ Pub: [FlutterQuill] - [Custom Embed Blocks](#custom-embed-blocks) - [Custom Toolbar](#custom-toolbar) - [Translation](#translation) - - [Contributing to translations](#contributing-to-translations) - [Conversion to HTML](#conversion-to-html) - [Testing](#testing) - [Contributors](#contributors) @@ -302,45 +301,9 @@ Open this [page](./doc/custom_toolbar.md) for more info ### Translation -The package offers translations for the quill toolbar and editor, it will follow the system locale unless you set your own locale with: +The package offers translations for the quill toolbar and editor, it will follow the system locale unless you set your own locale. -```dart - QuillProvider( - configurations: QuillConfigurations( - controller: _controller, - sharedConfigurations: const QuillSharedConfigurations( - locale: Locale('fr'), - ), - ), - child: Column( - children: [ - const QuillToolbar( - configurations: QuillToolbarConfigurations(), - ), - Expanded( - child: QuillEditor.basic( - configurations: const QuillEditorConfigurations(), - ), - ) - ], - ), -) -``` - -Currently, translations are available for these 31 locales: - -* `Locale('en')`, `Locale('ar')`, `Locale('bn')`, `Locale('bs')` -* `Locale('cs')`, `Locale('de')`, `Locale('da')`, `Locale('fr')` -* `Locale('he')`, `Locale('zh', 'cn')`, `Locale('zh', 'hk')`, `Locale('ko')` -* `Locale('ru')`, `Locale('es')`, `Locale('tk')`, `Locale('tr')` -* `Locale('uk')`, `Locale('ur')`, `Locale('pt')`, `Locale('pl')` -* `Locale('vi')`, `Locale('id')`, `Locale('it')`, `Locale('ms')` -* `Locale('nl')`, `Locale('no')`, `Locale('fa')`, `Locale('hi')` -* `Locale('sr')`, `Locale('sw')`, `Locale('ja')` - -#### Contributing to translations - -The translation file is located at [toolbar.i18n.dart](lib/src/translations/toolbar.i18n.dart). Feel free to contribute your own translations, just copy the English translations map and replace the values with your translations. Then open a pull request so everyone can benefit from your translations! +Open this [page](./doc/translation.md) for more info ## Conversion to HTML diff --git a/doc/translation.md b/doc/translation.md new file mode 100644 index 00000000..48f235f0 --- /dev/null +++ b/doc/translation.md @@ -0,0 +1,41 @@ +# Translation + +The package offers translations for the quill toolbar and editor, it will follow the system locale unless you set your own locale with: + +```dart + QuillProvider( + configurations: QuillConfigurations( + controller: _controller, + sharedConfigurations: const QuillSharedConfigurations( + locale: Locale('fr'), + ), + ), + child: Column( + children: [ + const QuillToolbar( + configurations: QuillToolbarConfigurations(), + ), + Expanded( + child: QuillEditor.basic( + configurations: const QuillEditorConfigurations(), + ), + ) + ], + ), +) +``` + +Currently, translations are available for these 31 locales: + +* `Locale('en')`, `Locale('ar')`, `Locale('bn')`, `Locale('bs')` +* `Locale('cs')`, `Locale('de')`, `Locale('da')`, `Locale('fr')` +* `Locale('he')`, `Locale('zh', 'cn')`, `Locale('zh', 'hk')`, `Locale('ko')` +* `Locale('ru')`, `Locale('es')`, `Locale('tk')`, `Locale('tr')` +* `Locale('uk')`, `Locale('ur')`, `Locale('pt')`, `Locale('pl')` +* `Locale('vi')`, `Locale('id')`, `Locale('it')`, `Locale('ms')` +* `Locale('nl')`, `Locale('no')`, `Locale('fa')`, `Locale('hi')` +* `Locale('sr')`, `Locale('sw')`, `Locale('ja')` + +#### Contributing to translations + +The translation file is located at [toolbar.i18n.dart](lib/src/translations/toolbar.i18n.dart). Feel free to contribute your own translations, just copy the English translations map and replace the values with your translations. Then open a pull request so everyone can benefit from your translations! \ No newline at end of file From e2be04cd2c697831574c6af89a7d92c92f551edd Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 04:25:00 +0300 Subject: [PATCH 064/210] Update README.md --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index b3287eb8..8efbfc94 100644 --- a/README.md +++ b/README.md @@ -141,13 +141,9 @@ _controller = QuillController( ## Configurations -The `QuillToolbar` class lets you customize which formatting options are available. +The `QuillToolbar` and `QuillEditor` widgets lets you customize a lot of things [Sample Page] provides sample code for advanced usage and configuration. -For **web development**, use `flutter config --enable-web` for flutter or use [ReactQuill] for React. - -It is required to provide `EmbedBuilder`, e.g. [defaultEmbedBuildersWeb](https://github.com/singerdmx/flutter-quill/blob/master/example/lib/universal_ui/universal_ui.dart#L99). - ### Using Custom App Widget This project use some adaptive widgets like `AdaptiveTextSelectionToolbar` which require the following delegates: From 35c49ffd7c22f084e3b7d004c85787935ac50ac1 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 06:14:37 +0300 Subject: [PATCH 065/210] Update flutter_quill_extensions and example --- example/lib/universal_ui/universal_ui.dart | 21 ++++++----- example/lib/widgets/responsive_widget.dart | 4 +-- example/pubspec.yaml | 4 +-- .../lib/flutter_quill_extensions.dart | 6 ++-- .../embeds/editor/image/image_web.dart | 36 ++++++++++++++++--- .../lib/presentation/embeds/utils.dart | 8 ++--- 6 files changed, 57 insertions(+), 22 deletions(-) diff --git a/example/lib/universal_ui/universal_ui.dart b/example/lib/universal_ui/universal_ui.dart index 421725e2..291593e0 100644 --- a/example/lib/universal_ui/universal_ui.dart +++ b/example/lib/universal_ui/universal_ui.dart @@ -4,6 +4,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; +import 'package:flutter_quill_extensions/presentation/embeds/editor/image/image.dart'; import 'package:universal_html/html.dart' as html; import 'package:youtube_player_flutter/youtube_player_flutter.dart'; @@ -61,7 +62,7 @@ class ImageEmbedBuilderWeb extends EmbedBuilder { : size.width * 0.2, ), child: SizedBox( - height: MediaQuery.sizeOf(context).height * 0.45, + height: size.height * 0.45, child: HtmlElementView( viewType: imageUrl, ), @@ -91,13 +92,16 @@ class VideoEmbedBuilderWeb extends EmbedBuilder { } } + final size = MediaQuery.sizeOf(context); + UniversalUI().platformViewRegistry.registerViewFactory( - videoUrl, - (id) => html.IFrameElement() - ..width = MediaQuery.sizeOf(context).width.toString() - ..height = MediaQuery.sizeOf(context).height.toString() - ..src = videoUrl - ..style.border = 'none'); + videoUrl, + (id) => html.IFrameElement() + ..width = size.width.toString() + ..height = size.height.toString() + ..src = videoUrl + ..style.border = 'none', + ); return SizedBox( height: 500, @@ -109,6 +113,7 @@ class VideoEmbedBuilderWeb extends EmbedBuilder { } List get defaultEmbedBuildersWeb => [ - ImageEmbedBuilderWeb(), + // ImageEmbedBuilderWeb(), + const QuillEditorWebImageEmbedBuilder(), VideoEmbedBuilderWeb(), ]; diff --git a/example/lib/widgets/responsive_widget.dart b/example/lib/widgets/responsive_widget.dart index f9de4027..d815f734 100644 --- a/example/lib/widgets/responsive_widget.dart +++ b/example/lib/widgets/responsive_widget.dart @@ -5,8 +5,8 @@ class ResponsiveWidget extends StatelessWidget { required this.largeScreen, this.mediumScreen, this.smallScreen, - Key? key, - }) : super(key: key); + super.key, + }); final Widget largeScreen; final Widget? mediumScreen; diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 92df9d83..0067ce4a 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -15,8 +15,8 @@ dependencies: path_provider: ^2.1.1 # filesystem_picker: ^4.0.0 # file_picker: ^6.1.1 - flutter_quill: ^8.2.0 - flutter_quill_extensions: ^0.6.0-dev.2 + flutter_quill: ^8.2.2 + flutter_quill_extensions: ^0.6.0-dev.5 dependency_overrides: flutter_quill: diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index 6b011b06..862b6663 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -27,6 +27,7 @@ import 'presentation/models/config/toolbar/buttons/video.dart'; export '/presentation/models/config/editor/webview.dart'; export './logic/extensions/controller.dart'; +export 'presentation/embeds/editor/image/image_web.dart'; export 'presentation/embeds/editor/unknown.dart'; export 'presentation/embeds/embed_types.dart'; export 'presentation/embeds/embed_types/image.dart'; @@ -108,7 +109,7 @@ class FlutterQuillEmbeds { /// Returns a list of embed builders specifically designed for web support. /// - /// [ImageEmbedBuilderWeb] is the embed builder for handling + /// [QuillEditorImageEmbedBuilderWeb] is the embed builder for handling /// images on the web. /// static List editorsWebBuilders({ @@ -124,7 +125,8 @@ class FlutterQuillEmbeds { ); } return [ - if (imageEmbedConfigurations != null) const ImageEmbedBuilderWeb(), + if (imageEmbedConfigurations != null) + const QuillEditorWebImageEmbedBuilder(), ]; } diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart index 970bf762..34e40f2d 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart @@ -1,13 +1,15 @@ import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/widgets.dart'; +import 'package:flutter_quill/extensions.dart' as base; import 'package:flutter_quill/flutter_quill.dart'; import 'package:universal_html/html.dart' as html; +import '../../utils.dart'; import 'shims/dart_ui_fake.dart' if (dart.library.html) 'shims/dart_ui_real.dart' as ui; -class ImageEmbedBuilderWeb extends EmbedBuilder { - const ImageEmbedBuilderWeb({ +class QuillEditorWebImageEmbedBuilder extends EmbedBuilder { + const QuillEditorWebImageEmbedBuilder({ this.constraints, }); @@ -28,11 +30,37 @@ class ImageEmbedBuilderWeb extends EmbedBuilder { assert(kIsWeb, 'ImageEmbedBuilderWeb is only for web platform'); final imageUrl = node.value.data; + if (isImageBase64(imageUrl)) { + // TODO: handle imageUrl of base64 + return const Text('Image base 64 is not supported yet.'); + } + + var height = 'auto'; + var width = 'auto'; + + final style = node.style.attributes['style']; + if (style != null) { + final attrs = base.parseKeyValuePairs(style.value.toString(), { + Attribute.width.key, + Attribute.height.key, + Attribute.margin, + Attribute.alignment, + }); + final heightValue = attrs[Attribute.height.key]; + if (heightValue != null) { + height = heightValue; + } + final widthValue = attrs[Attribute.width.key]; + if (widthValue != null) { + width = widthValue; + } + } + ui.PlatformViewRegistry().registerViewFactory(imageUrl, (viewId) { return html.ImageElement() ..src = imageUrl - ..style.height = 'auto' - ..style.width = 'auto'; + ..style.height = height + ..style.width = width; }); return ConstrainedBox( diff --git a/flutter_quill_extensions/lib/presentation/embeds/utils.dart b/flutter_quill_extensions/lib/presentation/embeds/utils.dart index 5ce82ee9..0d890e4e 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/utils.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/utils.dart @@ -21,6 +21,10 @@ bool isHttpBasedUrl(String url) { } } +bool isImageBase64(String imageUrl) { + return !isHttpBasedUrl(imageUrl) && isBase64(imageUrl); +} + bool isYouTubeUrl(String videoUrl) { try { final uri = Uri.parse(videoUrl); @@ -32,10 +36,6 @@ bool isYouTubeUrl(String videoUrl) { } } -bool isImageBase64(String imageUrl) { - return !isHttpBasedUrl(imageUrl) && isBase64(imageUrl); -} - enum SaveImageResultMethod { network, localStorage } @immutable From b9b1ecb2bd201ef7ec7a1d0860daaa06e8988844 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 06:16:28 +0300 Subject: [PATCH 066/210] Remove unused import --- example/lib/universal_ui/universal_ui.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/example/lib/universal_ui/universal_ui.dart b/example/lib/universal_ui/universal_ui.dart index 291593e0..0e6d382d 100644 --- a/example/lib/universal_ui/universal_ui.dart +++ b/example/lib/universal_ui/universal_ui.dart @@ -4,7 +4,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; -import 'package:flutter_quill_extensions/presentation/embeds/editor/image/image.dart'; import 'package:universal_html/html.dart' as html; import 'package:youtube_player_flutter/youtube_player_flutter.dart'; From f0d011007ee5292129e80e26f349af407ee635cb Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 20:59:50 +0300 Subject: [PATCH 067/210] Update extensions and example --- CHANGELOG.md | 3 + README.md | 32 --- example/assets/sample_data.json | 2 +- example/assets/sample_data_nomedia.json | 10 - example/assets/sample_data_testing.json | 97 +++++++++ example/lib/pages/home_page.dart | 11 +- example/lib/universal_ui/universal_ui.dart | 195 +++++++++--------- flutter_quill_extensions/CHANGELOG.md | 4 + flutter_quill_extensions/README.md | 37 ++++ .../lib/flutter_quill_extensions.dart | 32 +-- .../embeds/editor/image/image.dart | 6 +- .../embeds/editor/image/image_web.dart | 111 +++++++--- .../{image => }/shims/dart_ui_fake.dart | 0 .../{image => }/shims/dart_ui_real.dart | 0 .../embeds/editor/{ => video}/video.dart | 8 +- .../embeds/editor/video/video_web.dart | 57 +++++ .../lib/presentation/embeds/utils.dart | 3 +- .../presentation/embeds/widgets/image.dart | 22 +- .../config/editor/{ => image}/image.dart | 7 +- .../models/config/editor/image/image_web.dart | 11 + .../config/editor/{ => video}/video.dart | 0 .../models/config/editor/video/video_web.dart | 11 + flutter_quill_extensions/pubspec.yaml | 8 +- lib/src/models/documents/nodes/node.dart | 14 ++ pubspec.yaml | 2 +- 25 files changed, 466 insertions(+), 217 deletions(-) create mode 100644 example/assets/sample_data_testing.json rename flutter_quill_extensions/lib/presentation/embeds/editor/{image => }/shims/dart_ui_fake.dart (100%) rename flutter_quill_extensions/lib/presentation/embeds/editor/{image => }/shims/dart_ui_real.dart (100%) rename flutter_quill_extensions/lib/presentation/embeds/editor/{ => video}/video.dart (92%) create mode 100644 flutter_quill_extensions/lib/presentation/embeds/editor/video/video_web.dart rename flutter_quill_extensions/lib/presentation/models/config/editor/{ => image}/image.dart (97%) create mode 100644 flutter_quill_extensions/lib/presentation/models/config/editor/image/image_web.dart rename flutter_quill_extensions/lib/presentation/models/config/editor/{ => video}/video.dart (100%) create mode 100644 flutter_quill_extensions/lib/presentation/models/config/editor/video/video_web.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index d19c5509..87ecc8eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.2.3] +- Update `README.md` + ## [8.2.2] - Move the `flutter_quill_test` to seperated package [flutter_quill_test](https://pub.dev/packages/flutter_quill_test) diff --git a/README.md b/README.md index 8efbfc94..472313f9 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,6 @@ Pub: [FlutterQuill] - [Custom Buttons](#custom-buttons) - [Embed Blocks](#embed-blocks) - [Using the embed blocks from `flutter_quill_extensions`](#using-the-embed-blocks-from-flutter_quill_extensions) - - [Custom Size Image for Mobile](#custom-size-image-for-mobile) - - [Custom Size Image for other platforms (excluding web)](#custom-size-image-for-other-platforms-excluding-web) - [Custom Embed Blocks](#custom-embed-blocks) - [Custom Toolbar](#custom-toolbar) - [Translation](#translation) @@ -253,36 +251,6 @@ Provide a list of embed To see how to use the extensions package, please take a look at the [README](./flutter_quill_extensions/README.md) of [FlutterQuill Extensions] -### Custom Size Image for Mobile - -Define `mobileWidth`, `mobileHeight`, `mobileMargin`, `mobileAlignment` as follows: - -```json -{ - "insert": { - "image": "https://user-images.githubusercontent.com/122956/72955931-ccc07900-3d52-11ea-89b1-d468a6e2aa2b.png" - }, - "attributes":{ - "style":"mobileWidth: 50; mobileHeight: 50; mobileMargin: 10; mobileAlignment: topLeft" - } -} -``` - -### Custom Size Image for other platforms (excluding web) - -Define `width`, `height`, `margin`, `alignment` as follows: - -```json -{ - "insert": { - "image": "https://user-images.githubusercontent.com/122956/72955931-ccc07900-3d52-11ea-89b1-d468a6e2aa2b.png" - }, - "attributes":{ - "style":"width: 50; height: 50; margin: 10; alignment: topLeft" - } -} -``` - ### Custom Embed Blocks Sometimes you want to add some custom content inside your text, custom widgets inside of them. An example is adding notes to the text, or anything custom that you want to add in your text editor. diff --git a/example/assets/sample_data.json b/example/assets/sample_data.json index 467bcadd..2d376d7f 100644 --- a/example/assets/sample_data.json +++ b/example/assets/sample_data.json @@ -531,7 +531,7 @@ }, "attributes": { "width": "230", - "style": "display: block; margin: auto;" + "style": "display: block; margin: auto; width: 500px;" } }, { diff --git a/example/assets/sample_data_nomedia.json b/example/assets/sample_data_nomedia.json index e541d153..37289149 100644 --- a/example/assets/sample_data_nomedia.json +++ b/example/assets/sample_data_nomedia.json @@ -63,16 +63,6 @@ }, "insert": " and " }, - { - "attributes": { - "strike": true, - "color": "black" - }, - "insert": "web" - }, - { - "insert": " is not supported.\nYou are welcome to use " - }, { "attributes": { "link": "https://bulletjournal.us/home/index.html" diff --git a/example/assets/sample_data_testing.json b/example/assets/sample_data_testing.json new file mode 100644 index 00000000..bd725222 --- /dev/null +++ b/example/assets/sample_data_testing.json @@ -0,0 +1,97 @@ +[ + { + "insert": "Here is an image: \n" + }, + { + "insert": "\n" + }, + { + "insert": { + "image": "https://helpx.adobe.com/content/dam/help/en/photoshop/using/convert-color-image-black-white/jcr_content/main-pars/before_and_after/image-before/Landscape-Color.jpg" + }, + "attributes": { + "width": "100", + "height": "100", + "style": "width:250px; height:250px;" + } + }, + { + "insert": "\n" + }, + { + "insert": "\n" + }, + { + "insert": "\nThe image above have 250px width and height in the css style attribute which will be used for web, and 100 width and height that is in the attributes which will be used for desktop and mobile\n" + }, + { + "insert": "\n" + }, + { + "insert": { + "image": "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" + }, + "attributes": { + "width": "100", + "height": "100", + "style": "width:250px; height:250px;" + } + }, + { + "insert": "\n" + }, + { + "insert": "\nThe source of the above image is image base 64 directly without `data:image/png;base64,` in the start" + }, + { + "insert": "\n" + }, + { + "insert": "\n" + }, + { + "insert": "" + }, + { + "insert": { + "image": "data:image/png;base64,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" + }, + "attributes": { + "width": "100", + "height": "100", + "style": "width:250px; height:250px;" + } + }, + { + "insert": "\n" + }, + { + "insert": "\n" + }, + { + "insert": "The source of the above image is also image base 64 but this time it start with `data:image/png;base64,`" + }, + { + "insert": "\n" + }, + { + "insert": "\n" + }, + { + "insert": { + "video": "https://youtu.be/xz6_AlJkDPA" + } + }, + { + "insert": "\n" + }, + { + "insert": "\n" + }, + { + "insert": "And this is just a youtube video" + }, + { + "insert": "\n" + } +] \ No newline at end of file diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 81947f0f..69c9c8a6 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -53,16 +53,19 @@ class _HomePageState extends State { Future _loadFromAssets() async { try { - final result = await rootBundle.loadString(isDesktop() - ? 'assets/sample_data_nomedia.json' - : 'assets/sample_data.json'); + final result = + await rootBundle.loadString('assets/sample_data_testing.json'); + // final result = await rootBundle.loadString(isDesktop() + // ? 'assets/sample_data_nomedia.json' + // : 'assets/sample_data.json'); final doc = Document.fromJson(jsonDecode(result)); _controller = QuillController( document: doc, selection: const TextSelection.collapsed(offset: 0), ); } catch (error) { - final doc = Document()..insert(0, 'Empty asset'); + final doc = Document() + ..insert(0, 'Error while loading the document: ${error.toString()}'); _controller = QuillController( document: doc, selection: const TextSelection.collapsed(offset: 0), diff --git a/example/lib/universal_ui/universal_ui.dart b/example/lib/universal_ui/universal_ui.dart index 0e6d382d..9971b926 100644 --- a/example/lib/universal_ui/universal_ui.dart +++ b/example/lib/universal_ui/universal_ui.dart @@ -1,118 +1,115 @@ library universal_ui; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; -import 'package:universal_html/html.dart' as html; -import 'package:youtube_player_flutter/youtube_player_flutter.dart'; -import '../widgets/responsive_widget.dart'; -import 'fake_ui.dart' if (dart.library.html) 'real_ui.dart' as ui_instance; +// import '../widgets/responsive_widget.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 PlatformViewRegistryFix { +// void registerViewFactory(dynamic x, dynamic y) { +// if (kIsWeb) { +// ui_instance.PlatformViewRegistry.registerViewFactory( +// x, +// y, +// ); +// } +// } +// } -class UniversalUI { - PlatformViewRegistryFix platformViewRegistry = PlatformViewRegistryFix(); -} +// class UniversalUI { +// PlatformViewRegistryFix platformViewRegistry = PlatformViewRegistryFix(); +// } -var ui = UniversalUI(); +// var ui = UniversalUI(); -class ImageEmbedBuilderWeb extends EmbedBuilder { - @override - String get key => BlockEmbed.imageType; +// class ImageEmbedBuilderWeb extends EmbedBuilder { +// @override +// String get key => BlockEmbed.imageType; - @override - Widget build( - BuildContext context, - QuillController controller, - Embed node, - bool readOnly, - bool inline, - TextStyle textStyle, - ) { - final imageUrl = node.value.data; - if (isImageBase64(imageUrl)) { - // TODO: handle imageUrl of base64 - return const SizedBox(); - } - final size = MediaQuery.sizeOf(context); - UniversalUI().platformViewRegistry.registerViewFactory(imageUrl, (viewId) { - return html.ImageElement() - ..src = imageUrl - ..style.height = 'auto' - ..style.width = 'auto'; - }); - 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: size.height * 0.45, - child: HtmlElementView( - viewType: imageUrl, - ), - ), - ); - } -} +// @override +// Widget build( +// BuildContext context, +// QuillController controller, +// Embed node, +// bool readOnly, +// bool inline, +// TextStyle textStyle, +// ) { +// final imageUrl = node.value.data; +// if (isImageBase64(imageUrl)) { +// // TODO: handle imageUrl of base64 +// return const SizedBox(); +// } +// final size = MediaQuery.sizeOf(context); +// UniversalUI().platformViewRegistry.registerViewFactory(imageUrl, +//(viewId) { +// return html.ImageElement() +// ..src = imageUrl +// ..style.height = 'auto' +// ..style.width = 'auto'; +// }); +// 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: size.height * 0.45, +// child: HtmlElementView( +// viewType: imageUrl, +// ), +// ), +// ); +// } +// } -class VideoEmbedBuilderWeb extends EmbedBuilder { - @override - String get key => BlockEmbed.videoType; +// class VideoEmbedBuilderWeb extends EmbedBuilder { +// @override +// String get key => BlockEmbed.videoType; - @override - Widget build( - BuildContext context, - QuillController controller, - Embed node, - bool readOnly, - bool inline, - TextStyle textStyle, - ) { - var videoUrl = node.value.data; - if (videoUrl.contains('youtube.com') || videoUrl.contains('youtu.be')) { - final youtubeID = YoutubePlayer.convertUrlToId(videoUrl); - if (youtubeID != null) { - videoUrl = 'https://www.youtube.com/embed/$youtubeID'; - } - } +// @override +// Widget build( +// BuildContext context, +// QuillController controller, +// Embed node, +// bool readOnly, +// bool inline, +// TextStyle textStyle, +// ) { +// var videoUrl = node.value.data; +// if (videoUrl.contains('youtube.com') || videoUrl.contains('youtu.be')) { +// final youtubeID = YoutubePlayer.convertUrlToId(videoUrl); +// if (youtubeID != null) { +// videoUrl = 'https://www.youtube.com/embed/$youtubeID'; +// } +// } - final size = MediaQuery.sizeOf(context); +// final size = MediaQuery.sizeOf(context); - UniversalUI().platformViewRegistry.registerViewFactory( - videoUrl, - (id) => html.IFrameElement() - ..width = size.width.toString() - ..height = size.height.toString() - ..src = videoUrl - ..style.border = 'none', - ); +// UniversalUI().platformViewRegistry.registerViewFactory( +// videoUrl, +// (id) => html.IFrameElement() +// ..width = size.width.toString() +// ..height = size.height.toString() +// ..src = videoUrl +// ..style.border = 'none', +// ); - return SizedBox( - height: 500, - child: HtmlElementView( - viewType: videoUrl, - ), - ); - } -} +// return SizedBox( +// height: 500, +// child: HtmlElementView( +// viewType: videoUrl, +// ), +// ); +// } +// } List get defaultEmbedBuildersWeb => [ + ...FlutterQuillEmbeds.editorsWebBuilders(), // ImageEmbedBuilderWeb(), - const QuillEditorWebImageEmbedBuilder(), - VideoEmbedBuilderWeb(), + // VideoEmbedBuilderWeb(), ]; diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 0ae9e262..ce1f9d3a 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.0-dev.6 +- Better support for web +- Smal fixes and updates + ## 0.6.0-dev.5 - Update the camera button diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index f65bf91b..3e8575cb 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -15,6 +15,9 @@ Currently the support for **Web** is limitied. - [Installation](#installation) - [Platform Spesefic Configurations](#platform-spesefic-configurations) - [Usage](#usage) + - [Embed Blocks](#embed-blocks) + - [Custom Size Image for Mobile](#custom-size-image-for-mobile) + - [Custom Size Image for other platforms (excluding web)](#custom-size-image-for-other-platforms-excluding-web) - [Features](#features) - [Contributing](#contributing) - [License](#license) @@ -110,6 +113,40 @@ QuillProvider( ) ``` +## Embed Blocks + +As of version [flutter_quill](https://pub.dev/packages/flutter_quill) 6.0, embed blocks are not provided by default as part of Flutter quill. Instead, it provides an interface to all the user to provide there own implementations for embed blocks. Implementations for image, video and formula embed blocks is proved in this package + +### Custom Size Image for Mobile + +Define `mobileWidth`, `mobileHeight`, `mobileMargin`, `mobileAlignment` as follows: + +```json +{ + "insert": { + "image": "https://user-images.githubusercontent.com/122956/72955931-ccc07900-3d52-11ea-89b1-d468a6e2aa2b.png" + }, + "attributes":{ + "style":"mobileWidth: 50; mobileHeight: 50; mobileMargin: 10; mobileAlignment: topLeft" + } +} +``` + +### Custom Size Image for other platforms (excluding web) + +Define `width`, `height`, `margin`, `alignment` as follows: + +```json +{ + "insert": { + "image": "https://user-images.githubusercontent.com/122956/72955931-ccc07900-3d52-11ea-89b1-d468a6e2aa2b.png" + }, + "attributes": { + "style":"width: 50; height: 50; margin: 10; alignment: topLeft" + } +} +``` + ## Features ```markdown diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index 862b6663..a5c372ef 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -4,10 +4,10 @@ import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter_quill/flutter_quill.dart'; import 'package:meta/meta.dart' show immutable; -import 'logic/models/config/shared_configurations.dart'; import 'presentation/embeds/editor/image/image.dart'; import 'presentation/embeds/editor/image/image_web.dart'; -import 'presentation/embeds/editor/video.dart'; +import 'presentation/embeds/editor/video/video.dart'; +import 'presentation/embeds/editor/video/video_web.dart'; import 'presentation/embeds/editor/webview.dart'; import 'presentation/embeds/toolbar/camera_button/camera_button.dart'; import 'presentation/embeds/toolbar/formula_button.dart'; @@ -16,8 +16,10 @@ import 'presentation/embeds/toolbar/image_button/image_button.dart'; // ignore: unused_import import 'presentation/embeds/toolbar/media_button/media_button.dart'; import 'presentation/embeds/toolbar/video_button/video_button.dart'; -import 'presentation/models/config/editor/image.dart'; -import 'presentation/models/config/editor/video.dart'; +import 'presentation/models/config/editor/image/image.dart'; +import 'presentation/models/config/editor/image/image_web.dart'; +import 'presentation/models/config/editor/video/video.dart'; +import 'presentation/models/config/editor/video/video_web.dart'; import 'presentation/models/config/editor/webview.dart'; import 'presentation/models/config/toolbar/buttons/camera.dart'; import 'presentation/models/config/toolbar/buttons/formula.dart'; @@ -39,7 +41,7 @@ export 'presentation/embeds/toolbar/media_button/media_button.dart'; export 'presentation/embeds/toolbar/utils/image_video_utils.dart'; export 'presentation/embeds/toolbar/video_button/video_button.dart'; export 'presentation/embeds/utils.dart'; -export 'presentation/models/config/editor/image.dart'; +export 'presentation/models/config/editor/image/image.dart'; export 'presentation/models/config/toolbar/buttons/camera.dart'; export 'presentation/models/config/toolbar/buttons/formula.dart'; export 'presentation/models/config/toolbar/buttons/image.dart'; @@ -112,12 +114,11 @@ class FlutterQuillEmbeds { /// [QuillEditorImageEmbedBuilderWeb] is the embed builder for handling /// images on the web. /// - static List editorsWebBuilders({ - QuillSharedExtensionsConfigurations sharedExtensionsConfigurations = - const QuillSharedExtensionsConfigurations(), - QuillEditorWebImageEmbedConfigurations? imageEmbedConfigurations = - const QuillEditorWebImageEmbedConfigurations(), - }) { + static List editorsWebBuilders( + {QuillEditorWebImageEmbedConfigurations? imageEmbedConfigurations = + const QuillEditorWebImageEmbedConfigurations(), + QuillEditorWebVideoEmbedConfigurations? videoEmbedConfigurations = + const QuillEditorWebVideoEmbedConfigurations()}) { if (!kIsWeb) { throw UnsupportedError( 'The editorsWebBuilders() is only for web, please use editorBuilders() ' @@ -126,7 +127,13 @@ class FlutterQuillEmbeds { } return [ if (imageEmbedConfigurations != null) - const QuillEditorWebImageEmbedBuilder(), + QuillEditorWebImageEmbedBuilder( + configurations: imageEmbedConfigurations, + ), + if (videoEmbedConfigurations != null) + QuillEditorWebVideoEmbedBuilder( + configurations: videoEmbedConfigurations, + ), ]; } @@ -183,6 +190,7 @@ class FlutterQuillEmbeds { controller: cameraButtonOptions.controller ?? controller, options: cameraButtonOptions, ), + // TODO: We will return the support for this later // if (mediaButtonOptions != null) // (controller, toolbarIconSize, iconTheme, dialogTheme) => // QuillToolbarMediaButton( diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart index 666fe993..1c87a0f6 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart @@ -5,7 +5,7 @@ import 'package:flutter_quill/extensions.dart' as base; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill/translations.dart'; -import '../../../models/config/editor/image.dart'; +import '../../../models/config/editor/image/image.dart'; import '../../embed_types/image.dart'; import '../../utils.dart'; import '../../widgets/image.dart'; @@ -84,7 +84,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { imageSize = OptionalSize(width, height); image = Padding( padding: EdgeInsets.all(margin), - child: getQuillImageByUrl( + child: getQuillImageByImageSource( imageUrl, width: width, height: height, @@ -97,7 +97,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { } if (imageSize == null) { - image = getQuillImageByUrl( + image = getQuillImageByImageSource( imageUrl, imageProviderBuilder: configurations.imageProviderBuilder, imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder, diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart index 34e40f2d..660c8c02 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart @@ -4,16 +4,17 @@ import 'package:flutter_quill/extensions.dart' as base; import 'package:flutter_quill/flutter_quill.dart'; import 'package:universal_html/html.dart' as html; +import '../../../models/config/editor/image/image_web.dart'; import '../../utils.dart'; -import 'shims/dart_ui_fake.dart' +import '../shims/dart_ui_fake.dart' if (dart.library.html) 'shims/dart_ui_real.dart' as ui; class QuillEditorWebImageEmbedBuilder extends EmbedBuilder { const QuillEditorWebImageEmbedBuilder({ - this.constraints, + required this.configurations, }); - final BoxConstraints? constraints; + final QuillEditorWebImageEmbedConfigurations configurations; @override String get key => BlockEmbed.imageType; @@ -28,46 +29,94 @@ class QuillEditorWebImageEmbedBuilder extends EmbedBuilder { TextStyle textStyle, ) { assert(kIsWeb, 'ImageEmbedBuilderWeb is only for web platform'); - final imageUrl = node.value.data; - if (isImageBase64(imageUrl)) { - // TODO: handle imageUrl of base64 - return const Text('Image base 64 is not supported yet.'); - } + final (height, width, margin, alignment) = _getImageSizeForWeb(node); - var height = 'auto'; - var width = 'auto'; - - final style = node.style.attributes['style']; - if (style != null) { - final attrs = base.parseKeyValuePairs(style.value.toString(), { - Attribute.width.key, - Attribute.height.key, - Attribute.margin, - Attribute.alignment, - }); - final heightValue = attrs[Attribute.height.key]; - if (heightValue != null) { - height = heightValue; - } - final widthValue = attrs[Attribute.width.key]; - if (widthValue != null) { - width = widthValue; + var imageSource = node.value.data.toString(); + + // This logic make sure if the image is imageBase64 then + // it make sure if the pattern is like + // data:image/png;base64, [base64 encoded image string here] + // if not then it will add the data:image/png;base64, at the first + if (isImageBase64(imageSource)) { + // Sometimes the image base 64 for some reasons + // doesn't displayed with the + if (!(imageSource.startsWith('data:image/') && + imageSource.contains('base64'))) { + imageSource = 'data:image/png;base64, $imageSource'; } } - ui.PlatformViewRegistry().registerViewFactory(imageUrl, (viewId) { + ui.PlatformViewRegistry().registerViewFactory(imageSource, (viewId) { return html.ImageElement() - ..src = imageUrl + ..src = imageSource ..style.height = height - ..style.width = width; + ..style.width = width + ..style.margin = margin + ..style.alignSelf = alignment; }); return ConstrainedBox( - constraints: constraints ?? BoxConstraints.loose(const Size(200, 200)), + constraints: configurations.constraints ?? + BoxConstraints.loose(const Size(200, 200)), child: HtmlElementView( - viewType: imageUrl, + viewType: imageSource, ), ); } } + +/// Prefer the width, and height from the css style attribute if exits +/// it can be `auto` or `100px` so it's specific to HTML && CSS +/// if not, we will use the one from attributes which is usually just an double +( + String height, + String width, + String margin, + String alignment, +) _getImageSizeForWeb( + Node node, +) { + var height = 'auto'; + var width = 'auto'; + const margin = 'auto'; + const alignment = 'center'; + + final cssStyle = node.style.attributes['style']; + + // Usually double value + final heightValue = node.style.attributes[Attribute.height.key]?.value; + final widthValue = node.style.attributes[Attribute.width.key]?.value; + + if (cssStyle != null) { + final attrs = base.parseKeyValuePairs(cssStyle.value.toString(), { + Attribute.width.key, + Attribute.height.key, + Attribute.margin, + Attribute.alignment, + }); + final cssHeightValue = attrs[Attribute.height.key]; + if (cssHeightValue != null) { + height = cssHeightValue; + } else { + height = '${heightValue}px'; + } + final cssWidthValue = attrs[Attribute.width.key]; + if (cssWidthValue != null) { + width = cssWidthValue; + } else if (widthValue != null) { + width = '${widthValue}px'; + } + + return (height, width, margin, alignment); + } + + if (heightValue != null) { + height = '${heightValue}px'; + } + if (widthValue != null) { + width = '${widthValue}px'; + } + + return (height, width, margin, alignment); +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/shims/dart_ui_fake.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/shims/dart_ui_fake.dart similarity index 100% rename from flutter_quill_extensions/lib/presentation/embeds/editor/image/shims/dart_ui_fake.dart rename to flutter_quill_extensions/lib/presentation/embeds/editor/shims/dart_ui_fake.dart diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/shims/dart_ui_real.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/shims/dart_ui_real.dart similarity index 100% rename from flutter_quill_extensions/lib/presentation/embeds/editor/image/shims/dart_ui_real.dart rename to flutter_quill_extensions/lib/presentation/embeds/editor/shims/dart_ui_real.dart diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/video.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/video/video.dart similarity index 92% rename from flutter_quill_extensions/lib/presentation/embeds/editor/video.dart rename to flutter_quill_extensions/lib/presentation/embeds/editor/video/video.dart index 35e927e8..94aa2ea8 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/video.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/video/video.dart @@ -5,10 +5,10 @@ import 'package:flutter_quill/extensions.dart' as base; import 'package:flutter_quill/flutter_quill.dart'; import 'package:math_keyboard/math_keyboard.dart'; -import '../../models/config/editor/video.dart'; -import '../utils.dart'; -import '../widgets/video_app.dart'; -import '../widgets/youtube_video_app.dart'; +import '../../../models/config/editor/video/video.dart'; +import '../../utils.dart'; +import '../../widgets/video_app.dart'; +import '../../widgets/youtube_video_app.dart'; class QuillEditorVideoEmbedBuilder extends EmbedBuilder { const QuillEditorVideoEmbedBuilder({ diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/video/video_web.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/video/video_web.dart new file mode 100644 index 00000000..4bff6a01 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/video/video_web.dart @@ -0,0 +1,57 @@ +import 'package:flutter/widgets.dart'; +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:universal_html/html.dart' as html; +import 'package:youtube_player_flutter/youtube_player_flutter.dart' + show YoutubePlayer; + +import '../../../models/config/editor/video/video_web.dart'; +import '../../utils.dart'; +import '../shims/dart_ui_fake.dart' + if (dart.library.html) 'shims/dart_ui_real.dart' as ui; + +class QuillEditorWebVideoEmbedBuilder extends EmbedBuilder { + const QuillEditorWebVideoEmbedBuilder({ + required this.configurations, + }); + + final QuillEditorWebVideoEmbedConfigurations configurations; + + @override + String get key => BlockEmbed.videoType; + + @override + Widget build( + BuildContext context, + QuillController controller, + Embed node, + bool readOnly, + bool inline, + TextStyle textStyle, + ) { + var videoUrl = node.value.data; + if (isYouTubeUrl(videoUrl)) { + final youtubeID = YoutubePlayer.convertUrlToId(videoUrl); + if (youtubeID != null) { + videoUrl = 'https://www.youtube.com/embed/$youtubeID'; + } + } + + final size = MediaQuery.sizeOf(context); + + ui.PlatformViewRegistry().registerViewFactory( + videoUrl, + (id) => html.IFrameElement() + ..width = size.width.toString() + ..height = size.height.toString() + ..src = videoUrl + ..style.border = 'none', + ); + + return SizedBox( + height: 500, + child: HtmlElementView( + viewType: videoUrl, + ), + ); + } +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/utils.dart b/flutter_quill_extensions/lib/presentation/embeds/utils.dart index 0d890e4e..f1331f84 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/utils.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/utils.dart @@ -30,7 +30,8 @@ bool isYouTubeUrl(String videoUrl) { final uri = Uri.parse(videoUrl); return uri.host == 'www.youtube.com' || uri.host == 'youtube.com' || - uri.host == 'youtu.be'; + uri.host == 'youtu.be' || + uri.host == 'www.youtu.be'; } catch (_) { return false; } diff --git a/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart b/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart index 6d00500c..e73226e2 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart @@ -28,31 +28,35 @@ String getImageStyleString(QuillController controller) { return s ?? ''; } -Image getQuillImageByUrl( - String imageUrl, { +Image getQuillImageByImageSource( + String imageSource, { required ImageEmbedBuilderProviderBuilder? imageProviderBuilder, required ImageErrorWidgetBuilder? imageErrorWidgetBuilder, double? width, double? height, AlignmentGeometry alignment = Alignment.center, }) { - if (isImageBase64(imageUrl)) { - return Image.memory(base64.decode(imageUrl), - width: width, height: height, alignment: alignment); + if (isImageBase64(imageSource)) { + return Image.memory( + base64.decode(imageSource), + width: width, + height: height, + alignment: alignment, + ); } if (imageProviderBuilder != null) { return Image( - image: imageProviderBuilder(imageUrl), + image: imageProviderBuilder(imageSource), width: width, height: height, alignment: alignment, errorBuilder: imageErrorWidgetBuilder, ); } - if (isHttpBasedUrl(imageUrl)) { + if (isHttpBasedUrl(imageSource)) { return Image.network( - imageUrl, + imageSource, width: width, height: height, alignment: alignment, @@ -60,7 +64,7 @@ Image getQuillImageByUrl( ); } return Image.file( - File(imageUrl), + File(imageSource), width: width, height: height, alignment: alignment, diff --git a/flutter_quill_extensions/lib/presentation/models/config/editor/image.dart b/flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart similarity index 97% rename from flutter_quill_extensions/lib/presentation/models/config/editor/image.dart rename to flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart index 31fa75ef..f33913e7 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/editor/image.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart @@ -3,7 +3,7 @@ import 'dart:io' show File; import 'package:flutter_quill/extensions.dart'; import 'package:meta/meta.dart' show immutable; -import '../../../embeds/embed_types/image.dart'; +import '../../../../embeds/embed_types/image.dart'; /// [QuillEditorImageEmbedConfigurations] for desktop, mobile and /// other platforms @@ -167,8 +167,3 @@ class QuillEditorImageEmbedConfigurations { ); } } - -@immutable -class QuillEditorWebImageEmbedConfigurations { - const QuillEditorWebImageEmbedConfigurations(); -} diff --git a/flutter_quill_extensions/lib/presentation/models/config/editor/image/image_web.dart b/flutter_quill_extensions/lib/presentation/models/config/editor/image/image_web.dart new file mode 100644 index 00000000..8facc8a6 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/models/config/editor/image/image_web.dart @@ -0,0 +1,11 @@ +import 'package:flutter/widgets.dart' show BoxConstraints; +import 'package:meta/meta.dart' show immutable; + +@immutable +class QuillEditorWebImageEmbedConfigurations { + const QuillEditorWebImageEmbedConfigurations({ + this.constraints, + }); + + final BoxConstraints? constraints; +} diff --git a/flutter_quill_extensions/lib/presentation/models/config/editor/video.dart b/flutter_quill_extensions/lib/presentation/models/config/editor/video/video.dart similarity index 100% rename from flutter_quill_extensions/lib/presentation/models/config/editor/video.dart rename to flutter_quill_extensions/lib/presentation/models/config/editor/video/video.dart diff --git a/flutter_quill_extensions/lib/presentation/models/config/editor/video/video_web.dart b/flutter_quill_extensions/lib/presentation/models/config/editor/video/video_web.dart new file mode 100644 index 00000000..26d7f110 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/models/config/editor/video/video_web.dart @@ -0,0 +1,11 @@ +import 'package:flutter/widgets.dart' show BoxConstraints; +import 'package:meta/meta.dart' show immutable; + +@immutable +class QuillEditorWebVideoEmbedConfigurations { + const QuillEditorWebVideoEmbedConfigurations({ + this.constraints, + }); + + final BoxConstraints? constraints; +} diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 3a6948f9..be42577a 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 0.6.0-dev.5 +version: 0.6.0-dev.6 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions @@ -45,9 +45,9 @@ dependencies: # In case you are working on changes for both libraries # Comment the dependency_overrides section when publishing the package, # then uncomment it back, this will be automated later -# dependency_overrides: -# flutter_quill: -# path: ../ +dependency_overrides: + flutter_quill: + path: ../ dev_dependencies: flutter_test: diff --git a/lib/src/models/documents/nodes/node.dart b/lib/src/models/documents/nodes/node.dart index bb6a1c59..c196b47f 100644 --- a/lib/src/models/documents/nodes/node.dart +++ b/lib/src/models/documents/nodes/node.dart @@ -21,6 +21,20 @@ abstract base class Node extends LinkedListEntry { /// Current parent of this node. May be null if this node is not mounted. Container? parent; + /// The style attributes + /// Note: This is not the same as style attribute of css + /// + /// Example: + /// + /// { + /// "insert": { + /// "image": "https://user-images.githubusercontent.com/122956/72955931-ccc07900-3d52-11ea-89b1-d468a6e2aa2b.png" + /// }, + /// "attributes": { // this one + /// "width": "230", + /// "style": "display: block; margin: auto; width: 500px;" // Not this + /// } + /// }, Style get style => _style; Style _style = const Style(); diff --git a/pubspec.yaml b/pubspec.yaml index b53cd569..63bf0a6c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.2.2 +version: 8.2.3 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From a59f6e5e4792ff538b1df101e71eca7a59e42924 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 21:06:16 +0300 Subject: [PATCH 068/210] Update flutter_quill_extensions and example --- example/lib/pages/home_page.dart | 3 +-- example/lib/pages/read_only_page.dart | 3 +-- example/lib/universal_ui/universal_ui.dart | 14 +++++++------- .../presentation/embeds/editor/image/image.dart | 4 ++-- .../lib/presentation/embeds/widgets/image.dart | 2 +- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 69c9c8a6..fd0c0b7e 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -14,7 +14,6 @@ import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart'; -import '../universal_ui/universal_ui.dart'; import '../widgets/time_stamp_embed_widget.dart'; import 'read_only_page.dart'; @@ -221,7 +220,7 @@ class _HomePageState extends State { sizeSmall: TextStyle(fontSize: 9), ), embedBuilders: [ - ...defaultEmbedBuildersWeb, + ...FlutterQuillEmbeds.editorsWebBuilders(), TimeStampEmbedBuilderWidget() ], ), diff --git a/example/lib/pages/read_only_page.dart b/example/lib/pages/read_only_page.dart index 82b8185f..44c85b3f 100644 --- a/example/lib/pages/read_only_page.dart +++ b/example/lib/pages/read_only_page.dart @@ -6,7 +6,6 @@ import 'package:flutter_quill/extensions.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; -import '../universal_ui/universal_ui.dart'; import '../widgets/demo_scaffold.dart'; class ReadOnlyPage extends StatefulWidget { @@ -56,7 +55,7 @@ class _ReadOnlyPageState extends State { autoFocus: true, expands: false, padding: EdgeInsets.zero, - embedBuilders: defaultEmbedBuildersWeb, + embedBuilders: FlutterQuillEmbeds.editorsWebBuilders(), scrollable: true, ), scrollController: ScrollController(), diff --git a/example/lib/universal_ui/universal_ui.dart b/example/lib/universal_ui/universal_ui.dart index 9971b926..aa276dbc 100644 --- a/example/lib/universal_ui/universal_ui.dart +++ b/example/lib/universal_ui/universal_ui.dart @@ -1,7 +1,7 @@ library universal_ui; -import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; +// import 'package:flutter_quill/flutter_quill.dart'; +// import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; // import '../widgets/responsive_widget.dart'; // import 'fake_ui.dart' if (dart.library.html) 'real_ui.dart' as ui_instance; @@ -108,8 +108,8 @@ import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; // } // } -List get defaultEmbedBuildersWeb => [ - ...FlutterQuillEmbeds.editorsWebBuilders(), - // ImageEmbedBuilderWeb(), - // VideoEmbedBuilderWeb(), - ]; +// List get defaultEmbedBuildersWeb => [ +// ...FlutterQuillEmbeds.editorsWebBuilders(), +// // ImageEmbedBuilderWeb(), +// // VideoEmbedBuilderWeb(), +// ]; diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart index 1c87a0f6..d54b9d42 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart @@ -84,7 +84,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { imageSize = OptionalSize(width, height); image = Padding( padding: EdgeInsets.all(margin), - child: getQuillImageByImageSource( + child: getImageWidgetByImageSource( imageUrl, width: width, height: height, @@ -97,7 +97,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { } if (imageSize == null) { - image = getQuillImageByImageSource( + image = getImageWidgetByImageSource( imageUrl, imageProviderBuilder: configurations.imageProviderBuilder, imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder, diff --git a/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart b/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart index e73226e2..a4f8f717 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart @@ -28,7 +28,7 @@ String getImageStyleString(QuillController controller) { return s ?? ''; } -Image getQuillImageByImageSource( +Image getImageWidgetByImageSource( String imageSource, { required ImageEmbedBuilderProviderBuilder? imageProviderBuilder, required ImageErrorWidgetBuilder? imageErrorWidgetBuilder, From f92187fe406f90784d7516d052afaf4c67919545 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 21:10:53 +0300 Subject: [PATCH 069/210] Update flutter_quill_extensions --- flutter_quill_extensions/CHANGELOG.md | 3 +++ flutter_quill_extensions/pubspec.yaml | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index ce1f9d3a..be67e782 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.6.0 +- This version is not stable yet as it doesn't have mirgration guide and missing some things and we might introduce more breaking changes very soon but we decided to publish it because the latest stable version is not compatible with latest stable version of `flutter_quill`` + ## 0.6.0-dev.6 - Better support for web - Smal fixes and updates diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index be42577a..58f0ee40 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 0.6.0-dev.6 +version: 0.6.0 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions @@ -26,7 +26,7 @@ dependencies: flutter: sdk: flutter - flutter_quill: ^8.2.2 + flutter_quill: ^8.2.3 http: ^1.1.0 photo_view: ^0.14.0 @@ -34,7 +34,7 @@ dependencies: youtube_player_flutter: ^8.1.2 flutter_inappwebview: ^5.8.0 universal_html: ^2.2.4 - gal: ^2.1.2 + gal: ^2.1.3 path: ^1.8.3 image_picker: ^1.0.4 math_keyboard: ^0.2.1 From dc85c572299ce0e20b06990cdaa4122f1851a16f Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 21:12:20 +0300 Subject: [PATCH 070/210] Update CHANGELOG.md --- flutter_quill_extensions/CHANGELOG.md | 2 +- flutter_quill_extensions/pubspec.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index be67e782..f99b72d2 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,5 +1,5 @@ ## 0.6.0 -- This version is not stable yet as it doesn't have mirgration guide and missing some things and we might introduce more breaking changes very soon but we decided to publish it because the latest stable version is not compatible with latest stable version of `flutter_quill`` +- This version is not stable yet as it doesn't have mirgration guide and missing some things and we might introduce more breaking changes very soon but we decided to publish it because the latest stable version is not compatible with latest stable version of `flutter_quill` ## 0.6.0-dev.6 - Better support for web diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 58f0ee40..9155df77 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -45,9 +45,9 @@ dependencies: # In case you are working on changes for both libraries # Comment the dependency_overrides section when publishing the package, # then uncomment it back, this will be automated later -dependency_overrides: - flutter_quill: - path: ../ +# dependency_overrides: +# flutter_quill: +# path: ../ dev_dependencies: flutter_test: From bd338c00c2faf9ea75407e488c67245c83fbb5bb Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Mon, 6 Nov 2023 21:56:27 +0300 Subject: [PATCH 071/210] Update quill_extensions and the example --- example/.metadata | 39 +- example/analysis_options.yaml | 28 + example/android/app/build.gradle | 34 +- .../android/app/src/debug/AndroidManifest.xml | 7 +- .../android/app/src/main/AndroidManifest.xml | 9 +- .../com/example/example/MainActivity.kt | 2 +- .../app/src/main/res/values-night/styles.xml | 4 +- .../app/src/main/res/values/styles.xml | 2 +- .../app/src/profile/AndroidManifest.xml | 7 +- example/android/build.gradle | 4 +- example/android/gradle.properties | 3 + .../gradle/wrapper/gradle-wrapper.properties | 3 +- example/android/settings.gradle | 25 +- example/ios/.gitignore | 2 + example/ios/Flutter/AppFrameworkInfo.plist | 2 +- example/ios/Podfile | 3 + example/ios/Runner.xcodeproj/project.pbxproj | 313 +++++++--- .../xcshareddata/xcschemes/Runner.xcscheme | 19 +- example/ios/Runner/AppDelegate.h | 6 - example/ios/Runner/AppDelegate.m | 13 - .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 564 -> 295 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1283 -> 406 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 1588 -> 450 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1025 -> 282 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 1716 -> 462 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 1920 -> 704 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1283 -> 406 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 1895 -> 586 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 2665 -> 862 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 2665 -> 862 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 3831 -> 1674 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 1888 -> 762 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 3294 -> 1226 bytes .../Icon-App-83.5x83.5@2x.png | Bin 3612 -> 1418 bytes example/ios/Runner/Info.plist | 14 +- example/ios/Runner/main.m | 9 - example/ios/RunnerTests/RunnerTests.swift | 12 + example/lib/universal_ui/fake_ui.dart | 6 +- example/lib/universal_ui/real_ui.dart | 12 +- example/linux/.gitignore | 2 +- example/linux/CMakeLists.txt | 245 ++++---- example/linux/flutter/CMakeLists.txt | 179 +++--- example/linux/main.cc | 12 +- example/linux/my_application.cc | 208 +++---- example/linux/my_application.h | 36 +- example/macos/RunnerTests/RunnerTests.swift | 12 + example/web/icons/Icon-maskable-192.png | Bin 0 -> 5594 bytes example/web/icons/Icon-maskable-512.png | Bin 0 -> 20998 bytes example/web/index.html | 38 +- example/web/manifest.json | 16 +- example/windows/.gitignore | 34 +- example/windows/CMakeLists.txt | 197 +++---- example/windows/flutter/CMakeLists.txt | 207 +++---- example/windows/runner/CMakeLists.txt | 58 +- example/windows/runner/Runner.rc | 242 ++++---- example/windows/runner/flutter_window.cpp | 135 ++--- example/windows/runner/flutter_window.h | 72 ++- example/windows/runner/main.cpp | 85 +-- example/windows/runner/resource.h | 32 +- example/windows/runner/run_loop.cpp | 66 --- example/windows/runner/run_loop.h | 40 -- example/windows/runner/runner.exe.manifest | 40 +- example/windows/runner/utils.cpp | 129 ++--- example/windows/runner/utils.h | 38 +- example/windows/runner/win32_window.cpp | 533 ++++++++++-------- example/windows/runner/win32_window.h | 200 +++---- flutter_quill_extensions/CHANGELOG.md | 3 + flutter_quill_extensions/README.md | 6 + .../embeds/editor/image/image_web.dart | 5 +- .../embeds/editor/video/video_web.dart | 5 +- flutter_quill_extensions/pubspec.yaml | 2 +- 71 files changed, 1862 insertions(+), 1593 deletions(-) create mode 100644 example/analysis_options.yaml delete mode 100644 example/ios/Runner/AppDelegate.h delete mode 100644 example/ios/Runner/AppDelegate.m delete mode 100644 example/ios/Runner/main.m create mode 100644 example/ios/RunnerTests/RunnerTests.swift create mode 100644 example/macos/RunnerTests/RunnerTests.swift create mode 100644 example/web/icons/Icon-maskable-192.png create mode 100644 example/web/icons/Icon-maskable-512.png delete mode 100644 example/windows/runner/run_loop.cpp delete mode 100644 example/windows/runner/run_loop.h diff --git a/example/.metadata b/example/.metadata index 24544cb7..a778330b 100644 --- a/example/.metadata +++ b/example/.metadata @@ -4,7 +4,42 @@ # This file should be version controlled and should not be manually edited. version: - revision: 84f3d28555368a70270e9ac8390a9441df95e752 - channel: stable + revision: "d211f42860350d914a5ad8102f9ec32764dc6d06" + channel: "stable" project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + - platform: android + create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + - platform: ios + create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + - platform: linux + create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + - platform: macos + create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + - platform: web + create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + - platform: windows + create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml new file mode 100644 index 00000000..0d290213 --- /dev/null +++ b/example/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 4eef2899..b69a36c7 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -1,3 +1,9 @@ +plugins { + id "com.android.application" + id "kotlin-android" + id "dev.flutter.flutter-gradle-plugin" +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) { } } -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' @@ -21,20 +22,18 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { - compileSdkVersion flutter.compileSdkVersion + namespace "com.example.example" + compileSdk flutter.compileSdkVersion + ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = JavaVersion.VERSION_17.toString() } sourceSets { @@ -42,12 +41,11 @@ android { } defaultConfig { - applicationId "com.example.app" - minSdkVersion 21 + applicationId "com.example.example" + minSdkVersion 24 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName - // Multidex is not required for api level 21 } buildTypes { @@ -62,6 +60,4 @@ flutter { source '../..' } -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} +dependencies {} diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml index 9bc03bb2..399f6981 100644 --- a/example/android/app/src/debug/AndroidManifest.xml +++ b/example/android/app/src/debug/AndroidManifest.xml @@ -1,8 +1,7 @@ - - - diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index aeb699d6..b075bde1 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,5 @@ - + + @@ -8,9 +8,10 @@ - - diff --git a/example/android/build.gradle b/example/android/build.gradle index 85ed7b51..a250f58c 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.9.0' + ext.kotlin_version = '1.9.20' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.0' + classpath 'com.android.tools.build:gradle:8.1.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 94adc3a3..b9a9a246 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -1,3 +1,6 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true +android.defaults.buildfeatures.buildconfig=true +android.nonTransitiveRClass=false +android.nonFinalResIds=false diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 6b665338..8bc9958a 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip diff --git a/example/android/settings.gradle b/example/android/settings.gradle index 44e62bcf..55c4ca8b 100644 --- a/example/android/settings.gradle +++ b/example/android/settings.gradle @@ -1,11 +1,20 @@ -include ':app' +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + } + settings.ext.flutterSdkPath = flutterSdkPath() -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() + includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + plugins { + id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false + } +} -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" +include ":app" + +apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/example/ios/.gitignore b/example/ios/.gitignore index e96ef602..7a7f9873 100644 --- a/example/ios/.gitignore +++ b/example/ios/.gitignore @@ -1,3 +1,4 @@ +**/dgph *.mode1v3 *.mode2v3 *.moved-aside @@ -18,6 +19,7 @@ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig +Flutter/ephemeral/ Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist index 4f8d4d24..9625e105 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) + en CFBundleExecutable App CFBundleIdentifier diff --git a/example/ios/Podfile b/example/ios/Podfile index 88359b22..fdcc671e 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -32,6 +32,9 @@ target 'Runner' do use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end end post_install do |installer| diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 01a3496a..bcaa8216 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -7,16 +7,27 @@ objects = { /* Begin PBXBuildFile section */ + 110D5FB266DE0C87D485C5A1 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CA159BA3A0CB20166BDC7649 /* Pods_RunnerTests.framework */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; - 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - D290BBC2BCE42906E260DD85 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC245C6D0FF6BF1D0B733C5B /* Pods_Runner.framework */; }; + E0CFF8B0B56159E612BD1BF1 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 56338E24E520D8744CFF5FE2 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXCopyFilesBuildPhase section */ 9705A1C41CF9048500538489 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; @@ -33,42 +44,75 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 2F435AE316A2CEF9DB2FCB44 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 45FB9682812B691627A14497 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - 48A1E3B04AC3F3F79EE01940 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 56338E24E520D8744CFF5FE2 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 6B6E89A47C28537B66DC0FA4 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 7D464E3E73705EDBCA621B35 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - DC245C6D0FF6BF1D0B733C5B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A5625BCCF88D6127AE26675C /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + CA159BA3A0CB20166BDC7649 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0600C43B20FD3C51A3985DD /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + E008F2A10A874EB0C8AB0591 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + F65D90E41795239C733C3B48 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 729BF1F2E5A6188112D79F62 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 110D5FB266DE0C87D485C5A1 /* Pods_RunnerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D290BBC2BCE42906E260DD85 /* Pods_Runner.framework in Frameworks */, + E0CFF8B0B56159E612BD1BF1 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 54D582D77359D2F1CFEABAD6 /* Pods */ = { + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 808219EA7A4ECE8B7D2A26F2 /* Frameworks */ = { isa = PBXGroup; children = ( - 2F435AE316A2CEF9DB2FCB44 /* Pods-Runner.debug.xcconfig */, - 48A1E3B04AC3F3F79EE01940 /* Pods-Runner.release.xcconfig */, - 45FB9682812B691627A14497 /* Pods-Runner.profile.xcconfig */, + 56338E24E520D8744CFF5FE2 /* Pods_Runner.framework */, + CA159BA3A0CB20166BDC7649 /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 839C085E910FF72A20C1DC94 /* Pods */ = { + isa = PBXGroup; + children = ( + E008F2A10A874EB0C8AB0591 /* Pods-Runner.debug.xcconfig */, + D0600C43B20FD3C51A3985DD /* Pods-Runner.release.xcconfig */, + F65D90E41795239C733C3B48 /* Pods-Runner.profile.xcconfig */, + 7D464E3E73705EDBCA621B35 /* Pods-RunnerTests.debug.xcconfig */, + A5625BCCF88D6127AE26675C /* Pods-RunnerTests.release.xcconfig */, + 6B6E89A47C28537B66DC0FA4 /* Pods-RunnerTests.profile.xcconfig */, ); name = Pods; path = Pods; @@ -91,8 +135,9 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, - 54D582D77359D2F1CFEABAD6 /* Pods */, - 9B5485B940DE97CC1A7B761C /* Frameworks */, + 331C8082294A63A400263BE5 /* RunnerTests */, + 839C085E910FF72A20C1DC94 /* Pods */, + 808219EA7A4ECE8B7D2A26F2 /* Frameworks */, ); sourceTree = ""; }; @@ -100,6 +145,7 @@ isa = PBXGroup; children = ( 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, ); name = Products; sourceTree = ""; @@ -107,50 +153,52 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, ); path = Runner; sourceTree = ""; }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 97C146F21CF9000F007C117D /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 9B5485B940DE97CC1A7B761C /* Frameworks */ = { - isa = PBXGroup; - children = ( - DC245C6D0FF6BF1D0B733C5B /* Pods_Runner.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 81CBE292094CBE166A4095F9 /* [CP] Check Pods Manifest.lock */, + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + 729BF1F2E5A6188112D79F62 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 97C146ED1CF9000F007C117D /* Runner */ = { isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - C781F89B47F2E7DB7E2B4898 /* [CP] Check Pods Manifest.lock */, + 06DBD2892C9AFDD9AA47E269 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 869AA06D856BCA582968F111 /* [CP] Embed Pods Frameworks */, + 7C1D0099598B9B03C264FE8E /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -167,11 +215,17 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { + BuildIndependentTargetsInParallel = YES; LastUpgradeCheck = 1430; ORGANIZATIONNAME = ""; TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; }; }; }; @@ -189,11 +243,19 @@ projectRoot = ""; targets = ( 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 97C146EC1CF9000F007C117D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -208,6 +270,28 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 06DBD2892C9AFDD9AA47E269 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -224,7 +308,7 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 869AA06D856BCA582968F111 /* [CP] Embed Pods Frameworks */ = { + 7C1D0099598B9B03C264FE8E /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -241,58 +325,73 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 9740EEB61CF901F6004384FC /* Run Script */ = { + 81CBE292094CBE166A4095F9 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - name = "Run Script"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; - C781F89B47F2E7DB7E2B4898 /* [CP] Check Pods Manifest.lock */ = { + 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( ); + name = "Run Script"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 97C146EA1CF9000F007C117D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, - 97C146F31CF9000F007C117D /* main.m in Sources */, + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 97C146FA1CF9000F007C117D /* Main.storyboard */ = { isa = PBXVariantGroup; @@ -368,27 +467,72 @@ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.app; + PRODUCT_BUNDLE_IDENTIFIER = com.example.example; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Profile; }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7D464E3E73705EDBCA621B35 /* Pods-RunnerTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A5625BCCF88D6127AE26675C /* Pods-RunnerTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6B6E89A47C28537B66DC0FA4 /* Pods-RunnerTests.profile.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -489,6 +633,8 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -499,23 +645,19 @@ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.app; + PRODUCT_BUNDLE_IDENTIFIER = com.example.example; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; @@ -525,23 +667,18 @@ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.app; + PRODUCT_BUNDLE_IDENTIFIER = com.example.example; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; @@ -549,6 +686,16 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index b52b2e69..87131a09 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -27,8 +27,6 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> - - - - + + + + + + - - -#import - -@interface AppDelegate : FlutterAppDelegate - -@end diff --git a/example/ios/Runner/AppDelegate.m b/example/ios/Runner/AppDelegate.m deleted file mode 100644 index 70e83933..00000000 --- a/example/ios/Runner/AppDelegate.m +++ /dev/null @@ -1,13 +0,0 @@ -#import "AppDelegate.h" -#import "GeneratedPluginRegistrant.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application - didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [GeneratedPluginRegistrant registerWithRegistry:self]; - // Override point for customization after application launch. - return [super application:application didFinishLaunchingWithOptions:launchOptions]; -} - -@end diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png index 28c6bf03016f6c994b70f38d1b7346e5831b531f..7353c41ecf9ca08017312dc233d9830079b50717 100644 GIT binary patch delta 279 zcmV+y0qFj;1g8R!8Gi!+006pI?LPnj0Blf9R7L;)|5U~J`u_j-{Qm)0oAmqtj@kOz z^8J|I`-|B6ht~R5kG+%I`zf~eztraM`u^bc{`dO)zUlmg)%x%C`E}6wSI77~z4s`y z^XT{f(eM4n?EUff`e@AgO~UxV*5*r_%Uhbj5N)LaQj!wdIe!-b004GLL_t&-)18pX z4udcZ1u-#g(~z+5JN*AY5?>Gw7hsN~k)CYt4dQDFxbs5*_&e@Hj)wtt(&JE<3Eq*D z;_gQLvqXoKv=I*gWqM9C(Tvu0>=?hTbOp9!6k6AF;>f6|S5%jGEE}TA9h)e`Yuiu8 d7)l?o1NFcJg%EAfM$P~L002ovPDHLkV1g^Dnv?(l delta 550 zcmV+>0@?ki0<;8>8Gi-<0051N9Sr~g00DDSM?wIu&K&6g00HhvL_t(I5v`QFOB_)Y z#?QI;j_a;jjf#Z$YJ7mH(xecJU?W)A`9CN~KrBV85C}GDQ=|;GDFPNjtWty!L{u=? zh>8yo%^GE+J9o~_IZFoiamQVQXP7%LzTbT3F@uf+9x&7cvVV%GdjTaC;zf>@mq<=3 z!c<%*UT)@yJ|0BK6~d4Jx-*KV`ZQ(@VyUPupum=XhInNG#Z_k-X|hK{B}~9IfiWx} zLD5QY6Vm)p0NrWymdkrHPN5Vgwd>5>4HI1=@PA+e^rq~CEj|n2X`??)0mUI*D{KBn zjv{V=y5X9|X@3grkpcXC6oou4ML~ezCc2EtnsQTB4tWNg?4bkf;hG7IMfhgNI(FV5 zGs4|*GyMTIY0$B=_*mso9+>eB z?J{?+FLkYu+4_Uk`r_>LHF~flZm0oBf#vr8%vJ>#p~!KNvqGG3)|f1T_)ydeh8$vDceZ>oNbH^|*hJ*t?Yc*1`WB&W>VYVEzu) zq#7;;VjO)t*nbgf(!`OXJBr45rP>>AQr$6c7slJWvbpNW@KTwna6d?PP>hvXCcp=4 zF;=GR@R4E7{4VU^0p4F>v^#A|>07*qoM6N<$f<+$JJpcdz delta 1274 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 diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png index 4cde12118dda48d71e01fcb589a74d069c5d7cb5..4cd7b0099ca80c806f8fe495613e8d6c69460d76 100644 GIT binary patch delta 266 zcmV+l0rmcY2$}+r8Gi!+003c4mpuRg09{Z_R7L;)|5U~JDYo_jSDX9(|7FYh`2GLd z^Zv2r{H^2sT*&w!Y^SB+`<>qVZqE6)=lqo0`vF#&*75!I`TIh@_d&k*HoEtQyV-iD z%Xz2D9EQRbeYh5Nr~y=#0ZD;^+vz0$004MNL_t(2&&|%+4u6C&2tZM$Wf&dzefR%A z(^3-?6X>hnCz2Ba@RH&`m!pgy?n@#@AuLYB&}Q)FGY`?vcft0!vht0Z@M&ZeNCWXh75gzRTXR8EE3oN&6 Q00000NkvXXt^-0~g5kS`djJ3c delta 1014 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 Zxpx7IC@PekH?;r&002ovPDHLkV1i)CYaajr delta 1916 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 delta 1274 zcmV@pi1MCNO0zH7s z{8#}P0)7Ba8DqYf&QgSne>X__O83t$NZM4&R0{XJq|x}oAU?tcfC@|eNz$04T}34& z8DJf78R&>*Zz`k$q{`#gfGHnx7nlH^G{y`jfER)1<_fNi<9aM%_zrm1C`yPkKma(+ ztQ;y*CR2bbBYz>zG*SVsfpkGU(q>uHZf3iogk_%#9E|5SWeHrmAo>P;ejX7mwq#*} zW25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+X$F_KMdb6sRz!~7K zkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&IDi_4_D!s#MVXp|-XhH;H z#&@_;oApJVd}}5O@b=X_gJboD^-fM@6|#V@sA%X)Rlkd}3MLH0dGXGG&-HX|aD~|M zC)W#H7=H?AbtdaV#dGpubj_O^J-SlWpVNv-5(;wR%mvE9`Qaqo>03b&##eNNf=m#B z9@^lsd8tJ;BvI86kNV zc~0CY(7V{s+h%cWG|y=gt|q`z$l<(@qU=i?9q#uz`G?PgDMK!VMGidHZt*N+1L0ZI zFkH=mFtywc6rJ}C_?)=m)18V!ZQ`*-j(D`gCFK|nt#{bk*%%zuQ7o7kvJgA^=(^7b zzkm5GZ;jxRn{Wup8IOUx8D4uh&(=Ox-7$a;U><*5L^!% zxRlw)vAbh;sdlR||&e}8_8%)c2Fwy=F& zH|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}Jb#viX>Oi;kBKp1x_fc0#UIbIeSJ^EkWFox zijdim{ojmn@#7EC*aY;fC0W*WN+DmQtE06pNK3SfZ^#@2K`6RgEuU_KwJTQ>E?Yar zc_9e#I$F8%>kuy-JI6ocSsYvQGbsxUCx04(w1z-pMRz9`kH5smmF@WHEG?dcYkv){ zV?kn3XB$_3zr*h1Uow)(<5)w5;3Wh1jHI)`ZlXp&!yEV{Y_~@;?CLwq;4eeaGOe6( zEsSSbwSGD0-`dUUl014$1_O8Gi!+006nq0-pc?0H{z*R7L;)|5U~JDYo_jSDXF*|5nEMy6F5^ z$M}8I`uzU?*Yf=uXr;5|{0m;6_Wb|A>ik^D_|)+I$?g3CSDK^3+eX0mD!2CP`2NN0 z{dLg!a?km&%iyTt`yiax0acdp`~T(l{$a`ZF1YpsRg(cvjDG_-U$Er-fz#Bw>2W$eUI#iU z)Wdgs8Y3U+A$Gd&{+j)d)BmGKx+43U_!tik_YlN)>$7G!hkE!s;%oku3;IwG3U^2k zw?z+HM)jB{@zFhK8P#KMSytSthr+4!c(5c%+^UBn_j%}l|2+O?a>_7qq7W zmx(qtA2nV^tZlLpy_#$U%ZNx5;$`0L&dZ!@e7rFXPGAOup%q`|03hpdtXsPP0000< KMNUMnLSTZ1N;Pr- delta 1891 zcmV-p2b}oI1m_Nr8Gi-<0052=@~r>>2QEoOK~#9!?VW3E6jc<*XLh$yKNt;)Mial3 z7z%<>zxaV5DhMs*(b6YIW1=KP6Jj(m21QYbiJ}su&;o5EN=$%gptMj6p|(7#AOTUJ zlt8fsX(iGq?ZQ50=XmbU+~w|cmz~|6$KBbz$-g^IcV>Hk`+q<8%-p?uMi3G-0B~!5 ze-yPCwFPw?HGmpMc~K)7BCq;C528+>zC*o^8h^XKC)IFgkv#xzm!ewK7j|kRa9dFo zC>MoDSR@P2#cWSU{i1oH5K2-Xb3jRz>|h7VOh0K` zhq^--L3H}A0r)nr z;Tr|-kPjB1s=ItpnS`oT%|U=a4oK-ZFIE^YBLH{u2#~@%%D^K)$`9*Tg(~9M-B+Zj z;~H?4LVsEt0eFtN4&>H(DZ@KpI6RhBKLL21CxC`J&m4Gc^9wwMZU#7SR1+KtuhSZM z+yLY}Vekzw6T_ApfEkuB_yU;e&a)L@rX~z70A_N+upOXN!qygmPDmKG0d%7CECcAI zgkd>ArzH$a0XjKsO$X@IgkcH5Y;m3`0G*yNOn(KK4GF_EfL4aB5i1j9o&Z{vFk~k> z&?@K2jQcJO%W!cddG(_DyfSoO55bUMHtbDF8DPkwF^~Ql#Eq4w15k{h%ML5Ar&pzi zl-D7v8kQXQ!&RRgKCW#5DZB$$6?mjWm50rRw*ukK>P-GkA|k69h{NARc>e}uLx+U4 z0DqE>7pa}9Fez+Vc-3jb`%i^uulglFoMzAVR|2%rf= zf#;74FXF^Ku_4+G&-4$KVy%YP>%2rxu2VG_cdm?XRjEhF&wPXJ># z_Q2+jGs=l~Fyx#MmGn+PZ0`@kBfGp|fO;Vov<$;z`(+sSZ7;Y=zXaF(8rb@CuQDV^ zq3i(2LfqO%AS!Ss>V%j7%>{6mtbYQrtQK5V4InPq0NZSaXv+f2U=&2}Z6OvkBfNHi z{LSaVJ!d5dC2K*ft_L^DRk;boQhOoVw!~Kt#0b2vd%!(&DF|~u1F@nG#LA5zR&7Fv z4GKgXooMSKb1g)6Obo-rgpuEP20T;W0Aa>55KC4gtQrKkAq-Hgs@FigV1GG8+rQ=z z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRet3L_uNyQ*c zE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=kyx=~RKa4{iT zm{_>_vSCm?$Ej=i6@=m%@PE9t1zZaoM}@2|h!#1K02~31S_I<0ZV=|K0}n!RRX6Ac zXmMf*5P-dLW}WPVsCKq)-x(0*txpZ2xrv3cxJ%l=7lpoNCyG< zK92ySAcmb-3m&}s@VwXv9(0#p<>B-5$bMxT;rk;OmENa6eM4D&LVo~01soUL39?R{ zyFLt3m|v?rCK7#KNu9E9Q4KV-pEUv^{rrClE&X&9I4-e7%pu_31#zGTOfC=ab%w20R*zBP+uT#l2{a~~~0wuG%6 zco*tVxK&e>%SJj*K!2tq*_h&ES5S9@TKb8WzpK;`&b9dNdxh4S)z%Q)o`aYWUh}9L z(`p!#WO5IxI|nf?yz{90R93Ed6@2qim*}Zjj$H&Esd`?JsFJUnDfiAgF_eYiWR3GC z>M9SHDylEWrA(%mfm~;u7OU9!Wz^!7Z%jZF zi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i0WYBP d*#0Ks^FNSabJA*5${_#%002ovPDHLkV1gB0Vle;! diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png index a6d6b8609df07bf62e5100a53a01510388bd2b22..0ec303439225b78712f49115768196d8d76f6790 100644 GIT binary patch delta 850 zcmV-Y1Fih&6y64q8Gi!+000iU#^3+|0OwFlR7L;)|5U~J09TtSw)Xt~|5(QO`~Ck( z!T0|D|3<*~RmJ%E{r+;#`2ba!klFf7!uJMSo%Q?vP{jByxcAZE>;OrUCbaZYjJo^$ z{nGILmD~Da$@upC{`C6(Ey4dPw)Pyc^>5DkHoEo!QcuK-Jwl-l}t(fQKv z{dds$V#@dygS`PvhX6is7Z+@*x-d;$ zb=6f@U3Jw}_s+W3%*+b9H_vS)-R#9?zrXogeLVI2We2RFTTAL}&3C8PS~<5D&v@UI z+`s*$wqQ=yd$laNUY-|ovcS9~n_90tFUdl#qq0tEUXle|k{Op|DHpSrbxEeZ5~$>o%>OSe z^=41qvh3LlC2xXzu+-2eQoqs1^L>7ylB$bCP);(%(xYZL1 cY5!B-0ft0f?Lgb>C;$Ke07*qoM6N<$f@rA97ytkO literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png index a6d6b8609df07bf62e5100a53a01510388bd2b22..0ec303439225b78712f49115768196d8d76f6790 100644 GIT binary patch delta 850 zcmV-Y1Fih&6y64q8Gi!+000iU#^3+|0OwFlR7L;)|5U~J09TtSw)Xt~|5(QO`~Ck( z!T0|D|3<*~RmJ%E{r+;#`2ba!klFf7!uJMSo%Q?vP{jByxcAZE>;OrUCbaZYjJo^$ z{nGILmD~Da$@upC{`C6(Ey4dPw)Pyc^>5DkHoEo!QcuK-Jwl-l}t(fQKv z{dds$V#@dygS`PvhX6is7Z+@*x-d;$ zb=6f@U3Jw}_s+W3%*+b9H_vS)-R#9?zrXogeLVI2We2RFTTAL}&3C8PS~<5D&v@UI z+`s*$wqQ=yd$laNUY-|ovcS9~n_90tFUdl#qq0tEUXle|k{Op|DHpSrbxEeZ5~$>o%>OSe z^=41qvh3LlC2xXzu+-2eQoqs1^L>7ylB$bCP);(%(xYZL1 cY5!B-0ft0f?Lgb>C;$Ke07*qoM6N<$f@rA97ytkO literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png index 75b2d164a5a98e212cca15ea7bf2ab5de5108680..e9f5fea27c705180eb716271f41b582e76dcbd90 100644 GIT binary patch delta 1668 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 diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png index c4df70d39da7941ef3f6dcb7f06a192d8dcb308d..84ac32ae7d989f82d5e46a60405adcc8279e8001 100644 GIT binary patch delta 749 zcmVg;Ps8|O$@u8^{Z_{KM!@$5TAfS6_e#O{MZfpz`2O`0$7~@NRr(1{THzH08y3x{{PYM{eL;T_A9^tcF_4Sxb`8l z_9V3RD6;a(-0A^Pjsi!1?)d#Ap4Tk3^CP0(07;VpJ7@tgQ}z4)*zx@&yZwC9`DV-b z0ZobH_5IB4{KxD3;p_6%|f=bdFhu+F!zMZ2UFj;GUKX7tI;hv3{q~!*pMj75WP_c}> z6)IWvg5_yyg<9Op()eD1hWC19M@?_9_MHec{Z8n3FMs~w_u?Av_yNBmRxVYrpi(M% zFMP21g+hmocQp3ay*Su=qM6He)*HaaTg$E^sym`(t%s3A)x!M+vfjXUBEpK6X9%iU zU!u9jj3(-$dM~sJ%Liy#?|+!6IY#MTau#O6vVj`yh_7%Ni!?!VS+MPTO(_fG+1<#p zqu;A#i+_(N%CmVnYvb>#nA{>Q%3E`Ds7<~jZMywn@h2t>G-LrYy7?Dj{aZqhQd6tzX%(Trn+ z)HNF}%-F{rr=m*0{=a;s#YDL00000NkvXXu0mjfaGjYE delta 1884 zcmV-i2c!7<1>g>l8Gi-<0076AQ7Zrd2Pa8HK~#9!?VNjT6h$1z_m0EFf5bmb1dTDK zp;kdKV1h(V(8Sc1M<37!RE>znAk{x4#zX@eOeE1j3~!+nB5IL z<xS}u?#DBMB>w^b($1Z)`9G?eP95EKi& z$eOy@K%h;ryrR3la%;>|o*>CgB(s>dDcNOXg}CK9SPmD?Uu$P4(=PGA0ShFasNfcIHTL?9WjB9#(2xSLC z`0%$#9DW9F;B4mbU{BlaYx!SjF!QSeF~(msQRxwboh5B_O$BWOQja)GboJz$&!?mgB&3$ytsA zvns&b3Cl5Hx#%p%faR*Q906u&fbXy$maV`n?S>A)vJIH!F-vxCrY+rq5_JA(GcOgu7(Ky4X3ATR9z8*%k&<5qYeV&4Y`~}XYmK(j{)!g8d2UgHXIINM!Rvn zKtEq~Foe0s!U{kux~F6Y7Sp+2f|*Cc${S{@oh8D0=XhB8Ec-w9CflfL+te4ium2cU zoPTCj_m<3d#gjK=<*8R`HP^C$lOPM5d~UhKhRRmvv{LI za^|oavk1$QiEApSrP@~Jjbg`<*dW4TO@DPEEX$Tg$xh?Y>Qd}y@kaH~IT8!lLpS^J zR7(&wZSI6+>Eb)tX>9Z?GX#q$u z4I>7e#b7ojyJ1grOh!^}s8S#ubi^Jkd1?UK)3mp6rI^_zxRY zrx6_QmhoWoDR`fp4R7gu6@OBFGu7IDVR6~nJsB{^f5jHn<{WJ&&f^X?3f8TIk3#U& zu1*Q-e@;snJxNx8-PBnpI|uFTKN!+Lp;fPfZ+eqqU^Y1|#DJY~126?zOx-+d>%4*? z&o`TbrXSNXZW^!P0t2>@$6&aiBtUDh2wLXLD9&a(1J=k_FK|iGbAQ@x4Qmx}Ms+*; zze&q6bH(=wYuXHfz0H6<05!LkE4rl~v^!bj=^9d+vI5fN<;GP>*Pas=q2l9RxDkk` zPRk&EQI+t_0$Y%nKE)Ma)W?jaA@4Z{h zTk*7;;#lG?hvTN_On=Jaxp%bdE;mDq(q#dgdYF|-?wrMeI4h`$idZ6^VyXZVlaCd0 z;i)OYR3npf@9>00Gqn##Zb4HRurgaWFCzL9u6@J@sse>Z1XznxWvSy%Td32I3!#YN zXt9v0)RQtDDZRd?#WY?~KF7A0UcR{jt9 W+;fr}hV%pg0000&=UXv0SHh`R7L;)|5U~JDYo_jSDRDC`1<|-SjPDL z{{Q{{{{H{}09Kk-#rR9Y_viNgVafPO!S|ls`uzR=MZfp^{QU=8od8La1X`Tr_Wmff z_5e$ivgQ1@=KMy$_g9a+`TPAle6cOJ_Fc#L7qIpvwDkd1mw$fK`6IOUD75rX!}mad zv(fMTE4=(Nx%L54lL1hVF1YpqNrC`FddBPg#_Ietx%Lrkq5wX00X1L{S%Cm9QY*av z#_Rh5PKy9KYTWbvz3BX9%J>0Hi1+#X{rLA{m%$Kamk?i!03AC38#Yrxs)5QTeTVRiEmz~MKK1WAjCw(c-JK6eox;2O)?`?TG`AHia671e^vgmp!llK zp|=5sVHk#C7=~epA~VAf-~%aPC=%Qw01h8mnSZ|p?tc*y?iZ$PR7_ceEIapF3KB14K0Pog?7wtd+^xgUCa_GVmlD z<^nU>AU_Yn-JU?NFdu|wf^bTCNf-wSBYVZltDdvGBln-YrbeGvJ!|s{#`gjN@yAMb zM6cjFz0eFECCsc|_8hTa3*9-JQGehksdoVP^K4m?&wpA~+|b%{EP5D-+7h)6CE; z*{>BP=GRR3Ea}xyV*bqry{l^J=0#DaC4ej;1qs8_by?H6Tr@7hl>UKNZt)^B&yl;)&oqzLg zcfZxpE?3k%_iTOVywh%`XVN-E#COl+($9{v(pqSQcrz=)>G!!3HeNxbXGM@})1|9g zG4*@(OBaMvY0P0_TfMFPh fVHk#CZX3S=^^2mI>Ux-D00000NkvXXu0mjfzK(<8 literal 3294 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 cX)(b1KSk$MOV07*qoM6N<$f&{Qds= z{r_0T`1}6fwc-8!#-TGX}_?g)CZq4{k!uZ_g@DrQdoW0kI zu+W69&uN^)W`CK&06mMNcYMVF00dG=L_t(|+U?wHQxh>12H+Dm+1+fh+IF>G0SjJM zkQQre1x4|G*Z==(Ot&kCnUrL4I(rf(ucITwmuHf^hXiJTkdTm&kdTm&kdTm&kdP`e zsgWG0BcWCVkVZ&2dUwN`cgM8QJb`Z7Z~e<&Yj2(}>VI$fQI%^ugM`#6By?GeadWcu z0gy9!D`m!H>Bd!JW(@avE8`|5XX(0PN}!8K>`dkavs;rHL+wy96QGNT=S@#7%xtlm zIW!++@*2zm-Py#Zr`DzqsLm!b{iskFNULSqE9A>SqHem>o31A%XL>S_5?=;V_i_y+ z(xxXhnt#r-l1Y8_*h`r?8Tr|)(RAiO)4jQR`13X0mx07C&p@KBP_2s``KEhv^|*8c z$$_T(v6^1Ig=#R}sE{vjA?ErGDZGUsyoJuWdJMc7Nb1^KF)-u<7q zPy$=;)0>vuWuK2hQhswLf!9yg`88u&eBbR8uhod?Nw09AXH}-#qOLLxeT2%C;R)QQ$Za#qp~cM&YVmS4i-*Fpd!cC zBXc?(4wcg>sHmXGd^VdE<5QX{Kyz$;$sCPl(_*-P2Iw?p^C6J2ZC!+UppiK6&y3Kmbv&O!oYF34$0Z;QO!J zOY#!`qyGH<3Pd}Pt@q*A0V=3SVtWKRR8d8Z&@)3qLPA19LPA19LPEUCUoZo%k(yku QW&i*H07*qoM6N<$g47z!?*IS* literal 3612 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 iW8 CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Example CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -11,7 +13,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - app + example CFBundlePackageType APPL CFBundleShortVersionString @@ -20,10 +22,6 @@ ???? CFBundleVersion $(FLUTTER_BUILD_NUMBER) - NSPhotoLibraryUsageDescription - The app will use it to pick images - NSCameraUsageDescription - The app will use it to capture a images, record videos. LSRequiresIPhoneOS UILaunchStoryboardName @@ -43,11 +41,13 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - UIViewControllerBasedStatusBarAppearance - CADisableMinimumFrameDurationOnPhone UIApplicationSupportsIndirectInputEvents + NSPhotoLibraryUsageDescription + The app will use it to pick images + NSCameraUsageDescription + The app will use it to capture a images, record videos. diff --git a/example/ios/Runner/main.m b/example/ios/Runner/main.m deleted file mode 100644 index dff6597e..00000000 --- a/example/ios/Runner/main.m +++ /dev/null @@ -1,9 +0,0 @@ -#import -#import -#import "AppDelegate.h" - -int main(int argc, char* argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/example/ios/RunnerTests/RunnerTests.swift b/example/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 00000000..86a7c3b1 --- /dev/null +++ b/example/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/example/lib/universal_ui/fake_ui.dart b/example/lib/universal_ui/fake_ui.dart index 1711ad5f..334e022c 100644 --- a/example/lib/universal_ui/fake_ui.dart +++ b/example/lib/universal_ui/fake_ui.dart @@ -1,3 +1,3 @@ -class PlatformViewRegistry { - static void registerViewFactory(String viewId, dynamic cb) {} -} +// class PlatformViewRegistry { +// static void registerViewFactory(String viewId, dynamic cb) {} +// } diff --git a/example/lib/universal_ui/real_ui.dart b/example/lib/universal_ui/real_ui.dart index 6c1072fc..2ac0d8fe 100644 --- a/example/lib/universal_ui/real_ui.dart +++ b/example/lib/universal_ui/real_ui.dart @@ -1,7 +1,7 @@ -import 'dart:ui' if (dart.library.html) 'dart:ui_web' as ui; +// import 'dart:ui' if (dart.library.html) 'dart:ui_web' as ui; -class PlatformViewRegistry { - static void registerViewFactory(String viewId, dynamic cb) { - ui.platformViewRegistry.registerViewFactory(viewId, cb); - } -} +// class PlatformViewRegistry { +// static void registerViewFactory(String viewId, dynamic cb) { +// ui.platformViewRegistry.registerViewFactory(viewId, cb); +// } +// } diff --git a/example/linux/.gitignore b/example/linux/.gitignore index c7ea17fc..d3896c98 100644 --- a/example/linux/.gitignore +++ b/example/linux/.gitignore @@ -1 +1 @@ -flutter/ephemeral +flutter/ephemeral diff --git a/example/linux/CMakeLists.txt b/example/linux/CMakeLists.txt index 6ec85464..d67bd4e0 100644 --- a/example/linux/CMakeLists.txt +++ b/example/linux/CMakeLists.txt @@ -1,106 +1,139 @@ -cmake_minimum_required(VERSION 3.10) -project(runner LANGUAGES CXX) - -set(BINARY_NAME "app") -set(APPLICATION_ID "com.example.app") - -cmake_policy(SET CMP0063 NEW) - -set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") - -# Configure build options. -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE "Debug" CACHE - STRING "Flutter build mode" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Profile" "Release") -endif() - -# Compilation settings that should be applied to most targets. -function(APPLY_STANDARD_SETTINGS TARGET) - target_compile_features(${TARGET} PUBLIC cxx_std_14) - target_compile_options(${TARGET} PRIVATE -Wall -Werror) - target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") - target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") -endfunction() - -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") - -# Flutter library and tool build rules. -add_subdirectory(${FLUTTER_MANAGED_DIR}) - -# System-level dependencies. -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) - -add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") - -# Application build -add_executable(${BINARY_NAME} - "main.cc" - "my_application.cc" - "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" -) -apply_standard_settings(${BINARY_NAME}) -target_link_libraries(${BINARY_NAME} PRIVATE flutter) -target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) -add_dependencies(${BINARY_NAME} flutter_assemble) -# Only the install-generated bundle's copy of the executable will launch -# correctly, since the resources must in the right relative locations. To avoid -# people trying to run the unbundled copy, put it in a subdirectory instead of -# the default top-level location. -set_target_properties(${BINARY_NAME} - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" -) - -# Generated plugin build rules, which manage building the plugins and adding -# them to the application. -include(flutter/generated_plugins.cmake) - - -# === Installation === -# By default, "installing" just makes a relocatable bundle in the build -# directory. -set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) -endif() - -# Start with a clean build bundle directory every time. -install(CODE " - file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") - " COMPONENT Runtime) - -set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") -set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") - -install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -if(PLUGIN_BUNDLED_LIBRARIES) - install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() - -# Fully re-copy the assets directory on each build to avoid having stale files -# from a previous install. -set(FLUTTER_ASSET_DIR_NAME "flutter_assets") -install(CODE " - file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") - " COMPONENT Runtime) -install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" - DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) - -# Install the AOT library on non-Debug builds only. -if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") - install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() +# Project-level configuration. +cmake_minimum_required(VERSION 3.10) +project(runner LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "example") +# The unique GTK application identifier for this application. See: +# https://wiki.gnome.org/HowDoI/ChooseApplicationID +set(APPLICATION_ID "com.example.example") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(SET CMP0063 NEW) + +# Load bundled libraries from the lib/ directory relative to the binary. +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Root filesystem for cross-building. +if(FLUTTER_TARGET_PLATFORM_SYSROOT) + set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endif() + +# Define build configuration options. +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") +endif() + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_14) + target_compile_options(${TARGET} PRIVATE -Wall -Werror) + target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) + +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + +# Define the application target. To change its name, change BINARY_NAME above, +# not the value here, or `flutter run` will no longer work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add dependency libraries. Add any application-specific dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) + +# Only the install-generated bundle's copy of the executable will launch +# correctly, since the resources must in the right relative locations. To avoid +# people trying to run the unbundled copy, put it in a subdirectory instead of +# the default top-level location. +set_target_properties(${BINARY_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" +) + + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# By default, "installing" just makes a relocatable bundle in the build +# directory. +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) + install(FILES "${bundled_library}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endforeach(bundled_library) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() diff --git a/example/linux/flutter/CMakeLists.txt b/example/linux/flutter/CMakeLists.txt index 40425dce..d5bd0164 100644 --- a/example/linux/flutter/CMakeLists.txt +++ b/example/linux/flutter/CMakeLists.txt @@ -1,91 +1,88 @@ -cmake_minimum_required(VERSION 3.10) - -set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") - -# Configuration provided via flutter tool. -include(${EPHEMERAL_DIR}/generated_config.cmake) - -# TODO: Move the rest of this into files in ephemeral. See -# https://github.com/flutter/flutter/issues/57146. - -# Serves the same purpose as list(TRANSFORM ... PREPEND ...), -# which isn't available in 3.10. -function(list_prepend LIST_NAME PREFIX) - set(NEW_LIST "") - foreach(element ${${LIST_NAME}}) - list(APPEND NEW_LIST "${PREFIX}${element}") - endforeach(element) - set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) -endfunction() - -# === Flutter Library === -# System-level dependencies. -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) -pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) -pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) -pkg_check_modules(BLKID REQUIRED IMPORTED_TARGET blkid) -pkg_check_modules(LZMA REQUIRED IMPORTED_TARGET liblzma) - -set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") - -# Published to parent scope for install step. -set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) -set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) -set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) -set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) - -list(APPEND FLUTTER_LIBRARY_HEADERS - "fl_basic_message_channel.h" - "fl_binary_codec.h" - "fl_binary_messenger.h" - "fl_dart_project.h" - "fl_engine.h" - "fl_json_message_codec.h" - "fl_json_method_codec.h" - "fl_message_codec.h" - "fl_method_call.h" - "fl_method_channel.h" - "fl_method_codec.h" - "fl_method_response.h" - "fl_plugin_registrar.h" - "fl_plugin_registry.h" - "fl_standard_message_codec.h" - "fl_standard_method_codec.h" - "fl_string_codec.h" - "fl_value.h" - "fl_view.h" - "flutter_linux.h" -) -list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") -add_library(flutter INTERFACE) -target_include_directories(flutter INTERFACE - "${EPHEMERAL_DIR}" -) -target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") -target_link_libraries(flutter INTERFACE - PkgConfig::GTK - PkgConfig::GLIB - PkgConfig::GIO - PkgConfig::BLKID - PkgConfig::LZMA -) -add_dependencies(flutter flutter_assemble) - -# === Flutter tool backend === -# _phony_ is a non-existent file to force this command to run every time, -# since currently there's no way to get a full input/output list from the -# flutter tool. -add_custom_command( - OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} - ${CMAKE_CURRENT_BINARY_DIR}/_phony_ - COMMAND ${CMAKE_COMMAND} -E env - ${FLUTTER_TOOL_ENVIRONMENT} - "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" - ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} - VERBATIM -) -add_custom_target(flutter_assemble DEPENDS - "${FLUTTER_LIBRARY}" - ${FLUTTER_LIBRARY_HEADERS} -) +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) + +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "fl_basic_message_channel.h" + "fl_binary_codec.h" + "fl_binary_messenger.h" + "fl_dart_project.h" + "fl_engine.h" + "fl_json_message_codec.h" + "fl_json_method_codec.h" + "fl_message_codec.h" + "fl_method_call.h" + "fl_method_channel.h" + "fl_method_codec.h" + "fl_method_response.h" + "fl_plugin_registrar.h" + "fl_plugin_registry.h" + "fl_standard_message_codec.h" + "fl_standard_method_codec.h" + "fl_string_codec.h" + "fl_value.h" + "fl_view.h" + "flutter_linux.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE + PkgConfig::GTK + PkgConfig::GLIB + PkgConfig::GIO +) +add_dependencies(flutter flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/_phony_ + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" + ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} +) diff --git a/example/linux/main.cc b/example/linux/main.cc index 4340ffc1..e7c5c543 100644 --- a/example/linux/main.cc +++ b/example/linux/main.cc @@ -1,6 +1,6 @@ -#include "my_application.h" - -int main(int argc, char** argv) { - g_autoptr(MyApplication) app = my_application_new(); - return g_application_run(G_APPLICATION(app), argc, argv); -} +#include "my_application.h" + +int main(int argc, char** argv) { + g_autoptr(MyApplication) app = my_application_new(); + return g_application_run(G_APPLICATION(app), argc, argv); +} diff --git a/example/linux/my_application.cc b/example/linux/my_application.cc index 5f64f84a..0ba8f430 100644 --- a/example/linux/my_application.cc +++ b/example/linux/my_application.cc @@ -1,104 +1,104 @@ -#include "my_application.h" - -#include -#ifdef GDK_WINDOWING_X11 -#include -#endif - -#include "flutter/generated_plugin_registrant.h" - -struct _MyApplication { - GtkApplication parent_instance; - char** dart_entrypoint_arguments; -}; - -G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) - -// Implements GApplication::activate. -static void my_application_activate(GApplication* application) { - MyApplication* self = MY_APPLICATION(application); - GtkWindow* window = - GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); - - // Use a header bar when running in GNOME as this is the common style used - // by applications and is the setup most users will be using (e.g. Ubuntu - // desktop). - // If running on X and not using GNOME then just use a traditional title bar - // in case the window manager does more exotic layout, e.g. tiling. - // If running on Wayland assume the header bar will work (may need changing - // if future cases occur). - gboolean use_header_bar = FALSE; -#ifdef GDK_WINDOWING_X11 - GdkScreen *screen = gtk_window_get_screen(window); - if (GDK_IS_X11_SCREEN(screen)) { - const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); - if (g_strcmp0(wm_name, "GNOME Shell") != 0) { - use_header_bar = FALSE; - } - } -#endif - if (use_header_bar) { - GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); - gtk_widget_show(GTK_WIDGET(header_bar)); - gtk_header_bar_set_title(header_bar, "app"); - gtk_header_bar_set_show_close_button(header_bar, TRUE); - gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); - } - else { - gtk_window_set_title(window, "app"); - } - - gtk_window_set_default_size(window, 1280, 720); - gtk_widget_show(GTK_WIDGET(window)); - - g_autoptr(FlDartProject) project = fl_dart_project_new(); - fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); - - FlView* view = fl_view_new(project); - gtk_widget_show(GTK_WIDGET(view)); - gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); - - fl_register_plugins(FL_PLUGIN_REGISTRY(view)); - - gtk_widget_grab_focus(GTK_WIDGET(view)); -} - -// Implements GApplication::local_command_line. -static gboolean my_application_local_command_line(GApplication* application, gchar ***arguments, int *exit_status) { - MyApplication* self = MY_APPLICATION(application); - // Strip out the first argument as it is the binary name. - self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); - - g_autoptr(GError) error = nullptr; - if (!g_application_register(application, nullptr, &error)) { - g_warning("Failed to register: %s", error->message); - *exit_status = 1; - return TRUE; - } - - g_application_activate(application); - *exit_status = 0; - - return TRUE; -} - -// Implements GObject::dispose. -static void my_application_dispose(GObject *object) { - MyApplication* self = MY_APPLICATION(object); - g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); - G_OBJECT_CLASS(my_application_parent_class)->dispose(object); -} - -static void my_application_class_init(MyApplicationClass* klass) { - G_APPLICATION_CLASS(klass)->activate = my_application_activate; - G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; - G_OBJECT_CLASS(klass)->dispose = my_application_dispose; -} - -static void my_application_init(MyApplication* self) {} - -MyApplication* my_application_new() { - return MY_APPLICATION(g_object_new(my_application_get_type(), - "application-id", APPLICATION_ID, - nullptr)); -} +#include "my_application.h" + +#include +#ifdef GDK_WINDOWING_X11 +#include +#endif + +#include "flutter/generated_plugin_registrant.h" + +struct _MyApplication { + GtkApplication parent_instance; + char** dart_entrypoint_arguments; +}; + +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) + +// Implements GApplication::activate. +static void my_application_activate(GApplication* application) { + MyApplication* self = MY_APPLICATION(application); + GtkWindow* window = + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + + // Use a header bar when running in GNOME as this is the common style used + // by applications and is the setup most users will be using (e.g. Ubuntu + // desktop). + // If running on X and not using GNOME then just use a traditional title bar + // in case the window manager does more exotic layout, e.g. tiling. + // If running on Wayland assume the header bar will work (may need changing + // if future cases occur). + gboolean use_header_bar = TRUE; +#ifdef GDK_WINDOWING_X11 + GdkScreen* screen = gtk_window_get_screen(window); + if (GDK_IS_X11_SCREEN(screen)) { + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { + use_header_bar = FALSE; + } + } +#endif + if (use_header_bar) { + GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); + gtk_widget_show(GTK_WIDGET(header_bar)); + gtk_header_bar_set_title(header_bar, "example"); + gtk_header_bar_set_show_close_button(header_bar, TRUE); + gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); + } else { + gtk_window_set_title(window, "example"); + } + + gtk_window_set_default_size(window, 1280, 720); + gtk_widget_show(GTK_WIDGET(window)); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); + + FlView* view = fl_view_new(project); + gtk_widget_show(GTK_WIDGET(view)); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus(GTK_WIDGET(view)); +} + +// Implements GApplication::local_command_line. +static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { + MyApplication* self = MY_APPLICATION(application); + // Strip out the first argument as it is the binary name. + self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); + + g_autoptr(GError) error = nullptr; + if (!g_application_register(application, nullptr, &error)) { + g_warning("Failed to register: %s", error->message); + *exit_status = 1; + return TRUE; + } + + g_application_activate(application); + *exit_status = 0; + + return TRUE; +} + +// Implements GObject::dispose. +static void my_application_dispose(GObject* object) { + MyApplication* self = MY_APPLICATION(object); + g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); + G_OBJECT_CLASS(my_application_parent_class)->dispose(object); +} + +static void my_application_class_init(MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = my_application_activate; + G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; + G_OBJECT_CLASS(klass)->dispose = my_application_dispose; +} + +static void my_application_init(MyApplication* self) {} + +MyApplication* my_application_new() { + return MY_APPLICATION(g_object_new(my_application_get_type(), + "application-id", APPLICATION_ID, + "flags", G_APPLICATION_NON_UNIQUE, + nullptr)); +} diff --git a/example/linux/my_application.h b/example/linux/my_application.h index 8f20fb55..72271d5e 100644 --- a/example/linux/my_application.h +++ b/example/linux/my_application.h @@ -1,18 +1,18 @@ -#ifndef FLUTTER_MY_APPLICATION_H_ -#define FLUTTER_MY_APPLICATION_H_ - -#include - -G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, - GtkApplication) - -/** - * my_application_new: - * - * Creates a new Flutter-based application. - * - * Returns: a new #MyApplication. - */ -MyApplication* my_application_new(); - -#endif // FLUTTER_MY_APPLICATION_H_ +#ifndef FLUTTER_MY_APPLICATION_H_ +#define FLUTTER_MY_APPLICATION_H_ + +#include + +G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, + GtkApplication) + +/** + * my_application_new: + * + * Creates a new Flutter-based application. + * + * Returns: a new #MyApplication. + */ +MyApplication* my_application_new(); + +#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/example/macos/RunnerTests/RunnerTests.swift b/example/macos/RunnerTests/RunnerTests.swift new file mode 100644 index 00000000..5418c9f5 --- /dev/null +++ b/example/macos/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import FlutterMacOS +import Cocoa +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/example/web/icons/Icon-maskable-192.png b/example/web/icons/Icon-maskable-192.png new file mode 100644 index 0000000000000000000000000000000000000000..eb9b4d76e525556d5d89141648c724331630325d GIT binary patch literal 5594 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 X>c!)3PgKfL&lX^$Z>Cpu&6)6jvi^Z! literal 0 HcmV?d00001 diff --git a/example/web/icons/Icon-maskable-512.png b/example/web/icons/Icon-maskable-512.png new file mode 100644 index 0000000000000000000000000000000000000000..d69c56691fbdb0b7efa65097c7cc1edac12a6d3e GIT binary patch literal 20998 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 MPgg&ebxsLQ025IeI{*Lx literal 0 HcmV?d00001 diff --git a/example/web/index.html b/example/web/index.html index 887a139d..45cf2ca3 100644 --- a/example/web/index.html +++ b/example/web/index.html @@ -8,10 +8,13 @@ The path provided below has to start and end with a slash "/" in order for it to work correctly. - Fore more details: + For more details: * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base + + This is a placeholder for base href that will be replaced by the value of + the `--base-href` argument provided to `flutter build`. --> - + @@ -20,26 +23,37 @@ - + - app + example + + + + - - diff --git a/example/web/manifest.json b/example/web/manifest.json index c3c31e3b..096edf8f 100644 --- a/example/web/manifest.json +++ b/example/web/manifest.json @@ -1,6 +1,6 @@ { - "name": "app", - "short_name": "app", + "name": "example", + "short_name": "example", "start_url": ".", "display": "standalone", "background_color": "#0175C2", @@ -18,6 +18,18 @@ "src": "icons/Icon-512.png", "sizes": "512x512", "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" } ] } diff --git a/example/windows/.gitignore b/example/windows/.gitignore index ec4098aa..d492d0d9 100644 --- a/example/windows/.gitignore +++ b/example/windows/.gitignore @@ -1,17 +1,17 @@ -flutter/ephemeral/ - -# Visual Studio user-specific files. -*.suo -*.user -*.userosscache -*.sln.docstates - -# Visual Studio build-related files. -x64/ -x86/ - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/example/windows/CMakeLists.txt b/example/windows/CMakeLists.txt index c4363c4c..c09389c5 100644 --- a/example/windows/CMakeLists.txt +++ b/example/windows/CMakeLists.txt @@ -1,95 +1,102 @@ -cmake_minimum_required(VERSION 3.15) -project(app LANGUAGES CXX) - -set(BINARY_NAME "app") - -cmake_policy(SET CMP0063 NEW) - -set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") - -# Configure build options. -get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) -if(IS_MULTICONFIG) - set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" - CACHE STRING "" FORCE) -else() - if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE "Debug" CACHE - STRING "Flutter build mode" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Profile" "Release") - endif() -endif() - -set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") -set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") -set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") -set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") - -# Use Unicode for all projects. -add_definitions(-DUNICODE -D_UNICODE) - -# Compilation settings that should be applied to most targets. -function(APPLY_STANDARD_SETTINGS TARGET) - target_compile_features(${TARGET} PUBLIC cxx_std_17) - target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") - target_compile_options(${TARGET} PRIVATE /EHsc) - target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") - target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") -endfunction() - -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") - -# Flutter library and tool build rules. -add_subdirectory(${FLUTTER_MANAGED_DIR}) - -# Application build -add_subdirectory("runner") - -# Generated plugin build rules, which manage building the plugins and adding -# them to the application. -include(flutter/generated_plugins.cmake) - - -# === Installation === -# Support files are copied into place next to the executable, so that it can -# run in place. This is done instead of making a separate bundle (as on Linux) -# so that building and running from within Visual Studio will work. -set(BUILD_BUNDLE_DIR "$") -# Make the "install" step default, as it's required to run. -set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) -endif() - -set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") -set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") - -install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -if(PLUGIN_BUNDLED_LIBRARIES) - install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() - -# Fully re-copy the assets directory on each build to avoid having stale files -# from a previous install. -set(FLUTTER_ASSET_DIR_NAME "flutter_assets") -install(CODE " - file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") - " COMPONENT Runtime) -install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" - DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) - -# Install the AOT library on non-Debug builds only. -install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - CONFIGURATIONS Profile;Release - COMPONENT Runtime) +# Project-level configuration. +cmake_minimum_required(VERSION 3.14) +project(example LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "example") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(VERSION 3.14...3.25) + +# Define build configuration option. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() +# Define settings for the Profile build mode. +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") + + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/example/windows/flutter/CMakeLists.txt b/example/windows/flutter/CMakeLists.txt index c10f4f62..930d2071 100644 --- a/example/windows/flutter/CMakeLists.txt +++ b/example/windows/flutter/CMakeLists.txt @@ -1,103 +1,104 @@ -cmake_minimum_required(VERSION 3.15) - -set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") - -# Configuration provided via flutter tool. -include(${EPHEMERAL_DIR}/generated_config.cmake) - -# TODO: Move the rest of this into files in ephemeral. See -# https://github.com/flutter/flutter/issues/57146. -set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") - -# === Flutter Library === -set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") - -# Published to parent scope for install step. -set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) -set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) -set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) -set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) - -list(APPEND FLUTTER_LIBRARY_HEADERS - "flutter_export.h" - "flutter_windows.h" - "flutter_messenger.h" - "flutter_plugin_registrar.h" - "flutter_texture_registrar.h" -) -list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") -add_library(flutter INTERFACE) -target_include_directories(flutter INTERFACE - "${EPHEMERAL_DIR}" -) -target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") -add_dependencies(flutter flutter_assemble) - -# === Wrapper === -list(APPEND CPP_WRAPPER_SOURCES_CORE - "core_implementations.cc" - "standard_codec.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") -list(APPEND CPP_WRAPPER_SOURCES_PLUGIN - "plugin_registrar.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") -list(APPEND CPP_WRAPPER_SOURCES_APP - "flutter_engine.cc" - "flutter_view_controller.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") - -# Wrapper sources needed for a plugin. -add_library(flutter_wrapper_plugin STATIC - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} -) -apply_standard_settings(flutter_wrapper_plugin) -set_target_properties(flutter_wrapper_plugin PROPERTIES - POSITION_INDEPENDENT_CODE ON) -set_target_properties(flutter_wrapper_plugin PROPERTIES - CXX_VISIBILITY_PRESET hidden) -target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) -target_include_directories(flutter_wrapper_plugin PUBLIC - "${WRAPPER_ROOT}/include" -) -add_dependencies(flutter_wrapper_plugin flutter_assemble) - -# Wrapper sources needed for the runner. -add_library(flutter_wrapper_app STATIC - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_APP} -) -apply_standard_settings(flutter_wrapper_app) -target_link_libraries(flutter_wrapper_app PUBLIC flutter) -target_include_directories(flutter_wrapper_app PUBLIC - "${WRAPPER_ROOT}/include" -) -add_dependencies(flutter_wrapper_app flutter_assemble) - -# === Flutter tool backend === -# _phony_ is a non-existent file to force this command to run every time, -# since currently there's no way to get a full input/output list from the -# flutter tool. -set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") -set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) -add_custom_command( - OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} - ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} - ${CPP_WRAPPER_SOURCES_APP} - ${PHONY_OUTPUT} - COMMAND ${CMAKE_COMMAND} -E env - ${FLUTTER_TOOL_ENVIRONMENT} - "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" - windows-x64 $ - VERBATIM -) -add_custom_target(flutter_assemble DEPENDS - "${FLUTTER_LIBRARY}" - ${FLUTTER_LIBRARY_HEADERS} - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} - ${CPP_WRAPPER_SOURCES_APP} -) +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.14) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + windows-x64 $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/example/windows/runner/CMakeLists.txt b/example/windows/runner/CMakeLists.txt index e9932176..394917c0 100644 --- a/example/windows/runner/CMakeLists.txt +++ b/example/windows/runner/CMakeLists.txt @@ -1,18 +1,40 @@ -cmake_minimum_required(VERSION 3.15) -project(runner LANGUAGES CXX) - -add_executable(${BINARY_NAME} WIN32 - "flutter_window.cpp" - "main.cpp" - "run_loop.cpp" - "utils.cpp" - "win32_window.cpp" - "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" - "Runner.rc" - "runner.exe.manifest" -) -apply_standard_settings(${BINARY_NAME}) -target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") -target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) -target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") -add_dependencies(${BINARY_NAME} flutter_assemble) +cmake_minimum_required(VERSION 3.14) +project(runner LANGUAGES CXX) + +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add preprocessor definitions for the build version. +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") + +# Disable Windows macros that collide with C++ standard library functions. +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") + +# Add dependency libraries and include directories. Add any application-specific +# dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/example/windows/runner/Runner.rc b/example/windows/runner/Runner.rc index a922e84e..aecaa2b5 100644 --- a/example/windows/runner/Runner.rc +++ b/example/windows/runner/Runner.rc @@ -1,121 +1,121 @@ -// Microsoft Visual C++ generated resource script. -// -#pragma code_page(65001) -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_APP_ICON ICON "resources\\app_icon.ico" - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) -#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD -#else -#define VERSION_AS_NUMBER 1,0,0,0 -#endif - -#if defined(FLUTTER_VERSION) -#define VERSION_AS_STRING FLUTTER_VERSION -#else -#define VERSION_AS_STRING "1.0.0" -#endif - -VS_VERSION_INFO VERSIONINFO - FILEVERSION VERSION_AS_NUMBER - PRODUCTVERSION VERSION_AS_NUMBER - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -#ifdef _DEBUG - FILEFLAGS VS_FF_DEBUG -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_APP - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904e4" - BEGIN - VALUE "CompanyName", "com.example" "\0" - VALUE "FileDescription", "A new Flutter project." "\0" - VALUE "FileVersion", VERSION_AS_STRING "\0" - VALUE "InternalName", "app" "\0" - VALUE "LegalCopyright", "Copyright (C) 2021 com.example. All rights reserved." "\0" - VALUE "OriginalFilename", "app.exe" "\0" - VALUE "ProductName", "app" "\0" - VALUE "ProductVersion", VERSION_AS_STRING "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1252 - END -END - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) +#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD +#else +#define VERSION_AS_NUMBER 1,0,0,0 +#endif + +#if defined(FLUTTER_VERSION) +#define VERSION_AS_STRING FLUTTER_VERSION +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "com.example" "\0" + VALUE "FileDescription", "example" "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "example" "\0" + VALUE "LegalCopyright", "Copyright (C) 2023 com.example. All rights reserved." "\0" + VALUE "OriginalFilename", "example.exe" "\0" + VALUE "ProductName", "example" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/example/windows/runner/flutter_window.cpp b/example/windows/runner/flutter_window.cpp index ac04f779..955ee303 100644 --- a/example/windows/runner/flutter_window.cpp +++ b/example/windows/runner/flutter_window.cpp @@ -1,64 +1,71 @@ -#include "flutter_window.h" - -#include - -#include "flutter/generated_plugin_registrant.h" - -FlutterWindow::FlutterWindow(RunLoop* run_loop, - const flutter::DartProject& project) - : run_loop_(run_loop), project_(project) {} - -FlutterWindow::~FlutterWindow() {} - -bool FlutterWindow::OnCreate() { - if (!Win32Window::OnCreate()) { - return false; - } - - RECT frame = GetClientArea(); - - // The size here must match the window dimensions to avoid unnecessary surface - // creation / destruction in the startup path. - flutter_controller_ = std::make_unique( - frame.right - frame.left, frame.bottom - frame.top, project_); - // Ensure that basic setup of the controller was successful. - if (!flutter_controller_->engine() || !flutter_controller_->view()) { - return false; - } - RegisterPlugins(flutter_controller_->engine()); - run_loop_->RegisterFlutterInstance(flutter_controller_->engine()); - SetChildContent(flutter_controller_->view()->GetNativeWindow()); - return true; -} - -void FlutterWindow::OnDestroy() { - if (flutter_controller_) { - run_loop_->UnregisterFlutterInstance(flutter_controller_->engine()); - flutter_controller_ = nullptr; - } - - Win32Window::OnDestroy(); -} - -LRESULT -FlutterWindow::MessageHandler(HWND hwnd, UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - // Give Flutter, including plugins, an opporutunity to handle window messages. - if (flutter_controller_) { - std::optional result = - flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, - lparam); - if (result) { - return *result; - } - } - - switch (message) { - case WM_FONTCHANGE: - flutter_controller_->engine()->ReloadSystemFonts(); - break; - } - - return Win32Window::MessageHandler(hwnd, message, wparam, lparam); -} +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + + flutter_controller_->engine()->SetNextFrameCallback([&]() { + this->Show(); + }); + + // Flutter can complete the first frame before the "show window" callback is + // registered. The following call ensures a frame is pending to ensure the + // window is shown. It is a no-op if the first frame hasn't completed yet. + flutter_controller_->ForceRedraw(); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opportunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/example/windows/runner/flutter_window.h b/example/windows/runner/flutter_window.h index ba86031c..6da0652f 100644 --- a/example/windows/runner/flutter_window.h +++ b/example/windows/runner/flutter_window.h @@ -1,39 +1,33 @@ -#ifndef RUNNER_FLUTTER_WINDOW_H_ -#define RUNNER_FLUTTER_WINDOW_H_ - -#include -#include - -#include - -#include "run_loop.h" -#include "win32_window.h" - -// A window that does nothing but host a Flutter view. -class FlutterWindow : public Win32Window { - public: - // Creates a new FlutterWindow driven by the |run_loop|, hosting a - // Flutter view running |project|. - explicit FlutterWindow(RunLoop* run_loop, - const flutter::DartProject& project); - virtual ~FlutterWindow(); - - protected: - // Win32Window: - bool OnCreate() override; - void OnDestroy() override; - LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, - LPARAM const lparam) noexcept override; - - private: - // The run loop driving events for this window. - RunLoop* run_loop_; - - // The project to run. - flutter::DartProject project_; - - // The Flutter instance hosted by this window. - std::unique_ptr flutter_controller_; -}; - -#endif // RUNNER_FLUTTER_WINDOW_H_ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/example/windows/runner/main.cpp b/example/windows/runner/main.cpp index 81da1d1c..a61bf80d 100644 --- a/example/windows/runner/main.cpp +++ b/example/windows/runner/main.cpp @@ -1,42 +1,43 @@ -#include -#include -#include - -#include "flutter_window.h" -#include "run_loop.h" -#include "utils.h" - -int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, - _In_ wchar_t *command_line, _In_ int show_command) { - // Attach to console when present (e.g., 'flutter run') or create a - // new console when running with a debugger. - if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { - CreateAndAttachConsole(); - } - - // Initialize COM, so that it is available for use in the library and/or - // plugins. - ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); - - RunLoop run_loop; - - flutter::DartProject project(L"data"); - - std::vector command_line_arguments = - GetCommandLineArguments(); - - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - FlutterWindow window(&run_loop, project); - Win32Window::Point origin(10, 10); - Win32Window::Size size(1280, 720); - if (!window.CreateAndShow(L"app", origin, size)) { - return EXIT_FAILURE; - } - window.SetQuitOnClose(true); - - run_loop.Run(); - - ::CoUninitialize(); - return EXIT_SUCCESS; -} +#include +#include +#include + +#include "flutter_window.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.Create(L"example", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/example/windows/runner/resource.h b/example/windows/runner/resource.h index ddc7f3ef..66a65d1e 100644 --- a/example/windows/runner/resource.h +++ b/example/windows/runner/resource.h @@ -1,16 +1,16 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by Runner.rc -// -#define IDI_APP_ICON 101 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/example/windows/runner/run_loop.cpp b/example/windows/runner/run_loop.cpp deleted file mode 100644 index 0d912118..00000000 --- a/example/windows/runner/run_loop.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "run_loop.h" - -#include - -#include - -RunLoop::RunLoop() {} - -RunLoop::~RunLoop() {} - -void RunLoop::Run() { - bool keep_running = true; - TimePoint next_flutter_event_time = TimePoint::clock::now(); - while (keep_running) { - std::chrono::nanoseconds wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - TimePoint::clock::now()); - ::MsgWaitForMultipleObjects( - 0, nullptr, FALSE, static_cast(wait_duration.count() / 1000), - QS_ALLINPUT); - bool processed_events = false; - MSG message; - // All pending Windows messages must be processed; MsgWaitForMultipleObjects - // won't return again for items left in the queue after PeekMessage. - while (::PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) { - processed_events = true; - if (message.message == WM_QUIT) { - keep_running = false; - break; - } - ::TranslateMessage(&message); - ::DispatchMessage(&message); - // Allow Flutter to process messages each time a Windows message is - // processed, to prevent starvation. - next_flutter_event_time = - std::min(next_flutter_event_time, ProcessFlutterMessages()); - } - // If the PeekMessage loop didn't run, process Flutter messages. - if (!processed_events) { - next_flutter_event_time = - std::min(next_flutter_event_time, ProcessFlutterMessages()); - } - } -} - -void RunLoop::RegisterFlutterInstance( - flutter::FlutterEngine* flutter_instance) { - flutter_instances_.insert(flutter_instance); -} - -void RunLoop::UnregisterFlutterInstance( - flutter::FlutterEngine* flutter_instance) { - flutter_instances_.erase(flutter_instance); -} - -RunLoop::TimePoint RunLoop::ProcessFlutterMessages() { - TimePoint next_event_time = TimePoint::max(); - for (auto instance : flutter_instances_) { - std::chrono::nanoseconds wait_duration = instance->ProcessMessages(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, TimePoint::clock::now() + wait_duration); - } - } - return next_event_time; -} diff --git a/example/windows/runner/run_loop.h b/example/windows/runner/run_loop.h deleted file mode 100644 index 54927f97..00000000 --- a/example/windows/runner/run_loop.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef RUNNER_RUN_LOOP_H_ -#define RUNNER_RUN_LOOP_H_ - -#include - -#include -#include - -// A runloop that will service events for Flutter instances as well -// as native messages. -class RunLoop { - public: - RunLoop(); - ~RunLoop(); - - // Prevent copying - RunLoop(RunLoop const&) = delete; - RunLoop& operator=(RunLoop const&) = delete; - - // Runs the run loop until the application quits. - void Run(); - - // Registers the given Flutter instance for event servicing. - void RegisterFlutterInstance( - flutter::FlutterEngine* flutter_instance); - - // Unregisters the given Flutter instance from event servicing. - void UnregisterFlutterInstance( - flutter::FlutterEngine* flutter_instance); - - private: - using TimePoint = std::chrono::steady_clock::time_point; - - // Processes all currently pending messages for registered Flutter instances. - TimePoint ProcessFlutterMessages(); - - std::set flutter_instances_; -}; - -#endif // RUNNER_RUN_LOOP_H_ diff --git a/example/windows/runner/runner.exe.manifest b/example/windows/runner/runner.exe.manifest index 2c680b8b..a42ea768 100644 --- a/example/windows/runner/runner.exe.manifest +++ b/example/windows/runner/runner.exe.manifest @@ -1,20 +1,20 @@ - - - - - PerMonitorV2 - - - - - - - - - - - - - - - + + + + + PerMonitorV2 + + + + + + + + + + + + + + + diff --git a/example/windows/runner/utils.cpp b/example/windows/runner/utils.cpp index 05b53c01..b2b08734 100644 --- a/example/windows/runner/utils.cpp +++ b/example/windows/runner/utils.cpp @@ -1,64 +1,65 @@ -#include "utils.h" - -#include -#include -#include -#include - -#include - -void CreateAndAttachConsole() { - if (::AllocConsole()) { - FILE *unused; - if (freopen_s(&unused, "CONOUT$", "w", stdout)) { - _dup2(_fileno(stdout), 1); - } - if (freopen_s(&unused, "CONOUT$", "w", stderr)) { - _dup2(_fileno(stdout), 2); - } - std::ios::sync_with_stdio(); - FlutterDesktopResyncOutputStreams(); - } -} - -std::vector GetCommandLineArguments() { - // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. - int argc; - wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); - if (argv == nullptr) { - return std::vector(); - } - - std::vector command_line_arguments; - - // Skip the first argument as it's the binary name. - for (int i = 1; i < argc; i++) { - command_line_arguments.push_back(Utf8FromUtf16(argv[i])); - } - - ::LocalFree(argv); - - return command_line_arguments; -} - -std::string Utf8FromUtf16(const wchar_t* utf16_string) { - if (utf16_string == nullptr) { - return std::string(); - } - int target_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - -1, nullptr, 0, nullptr, nullptr); - if (target_length == 0) { - return std::string(); - } - std::string utf8_string; - utf8_string.resize(target_length); - int converted_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - -1, utf8_string.data(), - target_length, nullptr, nullptr); - if (converted_length == 0) { - return std::string(); - } - return utf8_string; -} +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr) + -1; // remove the trailing null character + int input_length = (int)wcslen(utf16_string); + std::string utf8_string; + if (target_length <= 0 || target_length > utf8_string.max_size()) { + return utf8_string; + } + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + input_length, utf8_string.data(), target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} diff --git a/example/windows/runner/utils.h b/example/windows/runner/utils.h index 3f0e05cb..3879d547 100644 --- a/example/windows/runner/utils.h +++ b/example/windows/runner/utils.h @@ -1,19 +1,19 @@ -#ifndef RUNNER_UTILS_H_ -#define RUNNER_UTILS_H_ - -#include -#include - -// Creates a console for the process, and redirects stdout and stderr to -// it for both the runner and the Flutter library. -void CreateAndAttachConsole(); - -// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string -// encoded in UTF-8. Returns an empty std::string on failure. -std::string Utf8FromUtf16(const wchar_t* utf16_string); - -// Gets the command line arguments passed in as a std::vector, -// encoded in UTF-8. Returns an empty std::vector on failure. -std::vector GetCommandLineArguments(); - -#endif // RUNNER_UTILS_H_ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ diff --git a/example/windows/runner/win32_window.cpp b/example/windows/runner/win32_window.cpp index 97f4439c..60608d0f 100644 --- a/example/windows/runner/win32_window.cpp +++ b/example/windows/runner/win32_window.cpp @@ -1,245 +1,288 @@ -#include "win32_window.h" - -#include - -#include "resource.h" - -namespace { - -constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; - -// The number of Win32Window objects that currently exist. -static int g_active_window_count = 0; - -using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); - -// Scale helper to convert logical scaler values to physical using passed in -// scale factor -int Scale(int source, double scale_factor) { - return static_cast(source * scale_factor); -} - -// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. -// This API is only needed for PerMonitor V1 awareness mode. -void EnableFullDpiSupportIfAvailable(HWND hwnd) { - HMODULE user32_module = LoadLibraryA("User32.dll"); - if (!user32_module) { - return; - } - auto enable_non_client_dpi_scaling = - reinterpret_cast( - GetProcAddress(user32_module, "EnableNonClientDpiScaling")); - if (enable_non_client_dpi_scaling != nullptr) { - enable_non_client_dpi_scaling(hwnd); - FreeLibrary(user32_module); - } -} - -} // namespace - -// Manages the Win32Window's window class registration. -class WindowClassRegistrar { - public: - ~WindowClassRegistrar() = default; - - // Returns the singleton registar instance. - static WindowClassRegistrar* GetInstance() { - if (!instance_) { - instance_ = new WindowClassRegistrar(); - } - return instance_; - } - - // Returns the name of the window class, registering the class if it hasn't - // previously been registered. - const wchar_t* GetWindowClass(); - - // Unregisters the window class. Should only be called if there are no - // instances of the window. - void UnregisterWindowClass(); - - private: - WindowClassRegistrar() = default; - - static WindowClassRegistrar* instance_; - - bool class_registered_ = false; -}; - -WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; - -const wchar_t* WindowClassRegistrar::GetWindowClass() { - if (!class_registered_) { - WNDCLASS window_class{}; - window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); - window_class.lpszClassName = kWindowClassName; - window_class.style = CS_HREDRAW | CS_VREDRAW; - window_class.cbClsExtra = 0; - window_class.cbWndExtra = 0; - window_class.hInstance = GetModuleHandle(nullptr); - window_class.hIcon = - LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); - window_class.hbrBackground = 0; - window_class.lpszMenuName = nullptr; - window_class.lpfnWndProc = Win32Window::WndProc; - RegisterClass(&window_class); - class_registered_ = true; - } - return kWindowClassName; -} - -void WindowClassRegistrar::UnregisterWindowClass() { - UnregisterClass(kWindowClassName, nullptr); - class_registered_ = false; -} - -Win32Window::Win32Window() { - ++g_active_window_count; -} - -Win32Window::~Win32Window() { - --g_active_window_count; - Destroy(); -} - -bool Win32Window::CreateAndShow(const std::wstring& title, - const Point& origin, - const Size& size) { - Destroy(); - - const wchar_t* window_class = - WindowClassRegistrar::GetInstance()->GetWindowClass(); - - const POINT target_point = {static_cast(origin.x), - static_cast(origin.y)}; - HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); - UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); - double scale_factor = dpi / 96.0; - - HWND window = CreateWindow( - window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, - Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), - Scale(size.width, scale_factor), Scale(size.height, scale_factor), - nullptr, nullptr, GetModuleHandle(nullptr), this); - - if (!window) { - return false; - } - - return OnCreate(); -} - -// static -LRESULT CALLBACK Win32Window::WndProc(HWND const window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - if (message == WM_NCCREATE) { - auto window_struct = reinterpret_cast(lparam); - SetWindowLongPtr(window, GWLP_USERDATA, - reinterpret_cast(window_struct->lpCreateParams)); - - auto that = static_cast(window_struct->lpCreateParams); - EnableFullDpiSupportIfAvailable(window); - that->window_handle_ = window; - } else if (Win32Window* that = GetThisFromHandle(window)) { - return that->MessageHandler(window, message, wparam, lparam); - } - - return DefWindowProc(window, message, wparam, lparam); -} - -LRESULT -Win32Window::MessageHandler(HWND hwnd, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - switch (message) { - case WM_DESTROY: - window_handle_ = nullptr; - Destroy(); - if (quit_on_close_) { - PostQuitMessage(0); - } - return 0; - - case WM_DPICHANGED: { - auto newRectSize = reinterpret_cast(lparam); - LONG newWidth = newRectSize->right - newRectSize->left; - LONG newHeight = newRectSize->bottom - newRectSize->top; - - SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, - newHeight, SWP_NOZORDER | SWP_NOACTIVATE); - - return 0; - } - case WM_SIZE: { - RECT rect = GetClientArea(); - if (child_content_ != nullptr) { - // Size and position the child window. - MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, - rect.bottom - rect.top, TRUE); - } - return 0; - } - - case WM_ACTIVATE: - if (child_content_ != nullptr) { - SetFocus(child_content_); - } - return 0; - } - - return DefWindowProc(window_handle_, message, wparam, lparam); -} - -void Win32Window::Destroy() { - OnDestroy(); - - if (window_handle_) { - DestroyWindow(window_handle_); - window_handle_ = nullptr; - } - if (g_active_window_count == 0) { - WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); - } -} - -Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { - return reinterpret_cast( - GetWindowLongPtr(window, GWLP_USERDATA)); -} - -void Win32Window::SetChildContent(HWND content) { - child_content_ = content; - SetParent(content, window_handle_); - RECT frame = GetClientArea(); - - MoveWindow(content, frame.left, frame.top, frame.right - frame.left, - frame.bottom - frame.top, true); - - SetFocus(child_content_); -} - -RECT Win32Window::GetClientArea() { - RECT frame; - GetClientRect(window_handle_, &frame); - return frame; -} - -HWND Win32Window::GetHandle() { - return window_handle_; -} - -void Win32Window::SetQuitOnClose(bool quit_on_close) { - quit_on_close_ = quit_on_close; -} - -bool Win32Window::OnCreate() { - // No-op; provided for subclasses. - return true; -} - -void Win32Window::OnDestroy() { - // No-op; provided for subclasses. -} +#include "win32_window.h" + +#include +#include + +#include "resource.h" + +namespace { + +/// Window attribute that enables dark mode window decorations. +/// +/// Redefined in case the developer's machine has a Windows SDK older than +/// version 10.0.22000.0. +/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +/// Registry key for app theme preference. +/// +/// A value of 0 indicates apps should use dark mode. A non-zero or missing +/// value indicates apps should use light mode. +constexpr const wchar_t kGetPreferredBrightnessRegKey[] = + L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; +constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + } + FreeLibrary(user32_module); +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registrar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::Create(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + UpdateTheme(window); + + return OnCreate(); +} + +bool Win32Window::Show() { + return ShowWindow(window_handle_, SW_SHOWNORMAL); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + + case WM_DWMCOLORIZATIONCOLORCHANGED: + UpdateTheme(hwnd); + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} + +void Win32Window::UpdateTheme(HWND const window) { + DWORD light_mode; + DWORD light_mode_size = sizeof(light_mode); + LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, + kGetPreferredBrightnessRegValue, + RRF_RT_REG_DWORD, nullptr, &light_mode, + &light_mode_size); + + if (result == ERROR_SUCCESS) { + BOOL enable_dark_mode = light_mode == 0; + DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, + &enable_dark_mode, sizeof(enable_dark_mode)); + } +} diff --git a/example/windows/runner/win32_window.h b/example/windows/runner/win32_window.h index d9bcac1b..e901dde6 100644 --- a/example/windows/runner/win32_window.h +++ b/example/windows/runner/win32_window.h @@ -1,98 +1,102 @@ -#ifndef RUNNER_WIN32_WINDOW_H_ -#define RUNNER_WIN32_WINDOW_H_ - -#include - -#include -#include -#include - -// A class abstraction for a high DPI-aware Win32 Window. Intended to be -// inherited from by classes that wish to specialize with custom -// rendering and input handling -class Win32Window { - public: - struct Point { - unsigned int x; - unsigned int y; - Point(unsigned int x, unsigned int y) : x(x), y(y) {} - }; - - struct Size { - unsigned int width; - unsigned int height; - Size(unsigned int width, unsigned int height) - : width(width), height(height) {} - }; - - Win32Window(); - virtual ~Win32Window(); - - // Creates and shows a win32 window with |title| and position and size using - // |origin| and |size|. New windows are created on the default monitor. Window - // sizes are specified to the OS in physical pixels, hence to ensure a - // consistent size to will treat the width height passed in to this function - // as logical pixels and scale to appropriate for the default monitor. Returns - // true if the window was created successfully. - bool CreateAndShow(const std::wstring& title, - const Point& origin, - const Size& size); - - // Release OS resources associated with window. - void Destroy(); - - // Inserts |content| into the window tree. - void SetChildContent(HWND content); - - // Returns the backing Window handle to enable clients to set icon and other - // window properties. Returns nullptr if the window has been destroyed. - HWND GetHandle(); - - // If true, closing this window will quit the application. - void SetQuitOnClose(bool quit_on_close); - - // Return a RECT representing the bounds of the current client area. - RECT GetClientArea(); - - protected: - // Processes and route salient window messages for mouse handling, - // size change and DPI. Delegates handling of these to member overloads that - // inheriting classes can handle. - virtual LRESULT MessageHandler(HWND window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept; - - // Called when CreateAndShow is called, allowing subclass window-related - // setup. Subclasses should return false if setup fails. - virtual bool OnCreate(); - - // Called when Destroy is called. - virtual void OnDestroy(); - - private: - friend class WindowClassRegistrar; - - // OS callback called by message pump. Handles the WM_NCCREATE message which - // is passed when the non-client area is being created and enables automatic - // non-client DPI scaling so that the non-client area automatically - // responsponds to changes in DPI. All other messages are handled by - // MessageHandler. - static LRESULT CALLBACK WndProc(HWND const window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept; - - // Retrieves a class instance pointer for |window| - static Win32Window* GetThisFromHandle(HWND const window) noexcept; - - bool quit_on_close_ = false; - - // window handle for top level window. - HWND window_handle_ = nullptr; - - // window handle for hosted content. - HWND child_content_ = nullptr; -}; - -#endif // RUNNER_WIN32_WINDOW_H_ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates a win32 window with |title| that is positioned and sized using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size this function will scale the inputted width and height as + // as appropriate for the default monitor. The window is invisible until + // |Show| is called. Returns true if the window was created successfully. + bool Create(const std::wstring& title, const Point& origin, const Size& size); + + // Show the current window. Returns true if the window was successfully shown. + bool Show(); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + // Update the window frame's theme to match the system theme. + static void UpdateTheme(HWND const window); + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_ diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index f99b72d2..591acd85 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.6.1 +- Fix bug on web that causing the project to not build + ## 0.6.0 - This version is not stable yet as it doesn't have mirgration guide and missing some things and we might introduce more breaking changes very soon but we decided to publish it because the latest stable version is not compatible with latest stable version of `flutter_quill` diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index 3e8575cb..3078767c 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -117,6 +117,8 @@ QuillProvider( As of version [flutter_quill](https://pub.dev/packages/flutter_quill) 6.0, embed blocks are not provided by default as part of Flutter quill. Instead, it provides an interface to all the user to provide there own implementations for embed blocks. Implementations for image, video and formula embed blocks is proved in this package +The instructions for using the embed blocks is in the [Usage](#usage) section + ### Custom Size Image for Mobile Define `mobileWidth`, `mobileHeight`, `mobileMargin`, `mobileAlignment` as follows: @@ -147,6 +149,10 @@ Define `width`, `height`, `margin`, `alignment` as follows: } ``` +On mobile we will use `mobileWidth`, `mobileHeight`, on desktop will use `width`, `heigth` +on Web we will use the `width` and the `height` but the ones in the `attributes` +This may not clear but don't worry we will update it soon. + ## Features ```markdown diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart index 660c8c02..84d3cd84 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart @@ -7,7 +7,7 @@ import 'package:universal_html/html.dart' as html; import '../../../models/config/editor/image/image_web.dart'; import '../../utils.dart'; import '../shims/dart_ui_fake.dart' - if (dart.library.html) 'shims/dart_ui_real.dart' as ui; + if (dart.library.html) '../shims/dart_ui_real.dart' as ui; class QuillEditorWebImageEmbedBuilder extends EmbedBuilder { const QuillEditorWebImageEmbedBuilder({ @@ -19,6 +19,9 @@ class QuillEditorWebImageEmbedBuilder extends EmbedBuilder { @override String get key => BlockEmbed.imageType; + @override + bool get expanded => false; + @override Widget build( BuildContext context, diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/video/video_web.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/video/video_web.dart index 4bff6a01..252f1cee 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/video/video_web.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/video/video_web.dart @@ -7,7 +7,7 @@ import 'package:youtube_player_flutter/youtube_player_flutter.dart' import '../../../models/config/editor/video/video_web.dart'; import '../../utils.dart'; import '../shims/dart_ui_fake.dart' - if (dart.library.html) 'shims/dart_ui_real.dart' as ui; + if (dart.library.html) '../shims/dart_ui_real.dart' as ui; class QuillEditorWebVideoEmbedBuilder extends EmbedBuilder { const QuillEditorWebVideoEmbedBuilder({ @@ -19,6 +19,9 @@ class QuillEditorWebVideoEmbedBuilder extends EmbedBuilder { @override String get key => BlockEmbed.videoType; + @override + bool get expanded => false; + @override Widget build( BuildContext context, diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 9155df77..ecbea806 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 0.6.0 +version: 0.6.1 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions From 8e0441e224a7ca9557da7c304cd9014fd2367bcb Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Tue, 7 Nov 2023 00:48:10 +0300 Subject: [PATCH 072/210] New patch --- CHANGELOG.md | 4 + analysis_options.yaml | 59 ++++--- example/analysis_options.yaml | 57 ++++--- example/android/app/build.gradle | 14 +- .../android/app/src/main/AndroidManifest.xml | 2 - example/android/build.gradle | 4 +- example/android/gradle.properties | 3 - .../gradle/wrapper/gradle-wrapper.properties | 2 +- example/assets/sample_data_nomedia.json | 37 ----- example/lib/main.dart | 16 +- example/lib/pages/home_page.dart | 154 ++++++++++++++++-- example/lib/pages/read_only_page.dart | 2 + example/lib/widgets/demo_scaffold.dart | 4 +- .../lib/widgets/time_stamp_embed_widget.dart | 4 +- example/pubspec.yaml | 13 +- example/test/widget_test.dart | 2 +- flutter_quill_extensions/CHANGELOG.md | 3 + flutter_quill_extensions/LICENSE | 2 +- flutter_quill_extensions/README.md | 2 +- .../analysis_options.yaml | 59 ++++--- .../lib/core/exceptions.dart | 12 -- .../lib/flutter_quill_extensions.dart | 19 ++- .../lib/logic/extensions/controller.dart | 24 ++- .../models/config/shared_configurations.dart | 38 ++++- .../services/image_picker/s_image_picker.dart | 1 + .../services/image_saver/s_image_saver.dart | 1 + ...uill_utils.dart => quill_image_utils.dart} | 0 .../embeds/embed_types/image.dart | 2 +- flutter_quill_extensions/pubspec.yaml | 8 +- flutter_quill_test/CHANGELOG.md | 4 + flutter_quill_test/LICENSE | 2 +- flutter_quill_test/README.md | 17 ++ flutter_quill_test/analysis_options.yaml | 59 ++++--- .../lib/src/test/widget_tester_extension.dart | 34 ++-- flutter_quill_test/pubspec.yaml | 4 +- .../test/flutter_quill_test_test.dart | 1 + lib/src/core/utils/logger.dart | 68 ++++++++ lib/src/widgets/proxy.dart | 2 +- lib/src/widgets/raw_editor/raw_editor.dart | 3 +- .../widgets/style_widgets/checkbox_point.dart | 6 +- lib/src/widgets/text_line.dart | 26 +-- lib/src/widgets/toolbar/base_toolbar.dart | 8 +- .../widgets/toolbar/buttons/link_style.dart | 4 +- lib/src/widgets/utils/provider.dart | 4 + pubspec.yaml | 4 +- 45 files changed, 538 insertions(+), 256 deletions(-) delete mode 100644 flutter_quill_extensions/lib/core/exceptions.dart rename flutter_quill_extensions/lib/logic/utils/{quill_utils.dart => quill_image_utils.dart} (100%) create mode 100644 lib/src/core/utils/logger.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 87ecc8eb..a79192b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [8.2.4] +- Follow flutter best practices +- Auto focus bug fix + ## [8.2.3] - Update `README.md` diff --git a/analysis_options.yaml b/analysis_options.yaml index 8f1b96e4..f1a38172 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,4 +1,4 @@ -include: package:lints/recommended.yaml +include: package:flutter_lints/flutter.yaml analyzer: errors: @@ -6,32 +6,31 @@ analyzer: unsafe_html: ignore linter: rules: - - always_declare_return_types - - always_put_required_named_parameters_first - - annotate_overrides - - avoid_empty_else - - avoid_escaping_inner_quotes - - avoid_print - - avoid_redundant_argument_values - - avoid_types_on_closure_parameters - - avoid_void_async - - cascade_invocations - - directives_ordering - - lines_longer_than_80_chars - - omit_local_variable_types - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - - prefer_initializing_formals - - prefer_int_literals - - prefer_interpolation_to_compose_strings - - prefer_relative_imports - - prefer_single_quotes - - sort_constructors_first - - sort_unnamed_constructors_first - - unnecessary_lambdas - - unnecessary_parenthesis - - unnecessary_string_interpolations + always_declare_return_types: true + always_put_required_named_parameters_first: true + annotate_overrides: true + avoid_empty_else: true + avoid_escaping_inner_quotes: true + avoid_print: true + avoid_redundant_argument_values: true + avoid_types_on_closure_parameters: true + avoid_void_async: true + cascade_invocations: true + directives_ordering: true + omit_local_variable_types: true + prefer_const_constructors: true + prefer_const_constructors_in_immutables: true + prefer_const_declarations: true + prefer_final_fields: true + prefer_final_in_for_each: true + prefer_final_locals: true + prefer_initializing_formals: true + prefer_int_literals: true + prefer_interpolation_to_compose_strings: true + prefer_relative_imports: true + prefer_single_quotes: true + sort_constructors_first: true + sort_unnamed_constructors_first: true + unnecessary_lambdas: true + unnecessary_parenthesis: true + unnecessary_string_interpolations: true diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml index 0d290213..b55e627b 100644 --- a/example/analysis_options.yaml +++ b/example/analysis_options.yaml @@ -1,28 +1,37 @@ -# This file configures the analyzer, which statically analyzes Dart code to -# check for errors, warnings, and lints. -# -# The issues identified by the analyzer are surfaced in the UI of Dart-enabled -# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be -# invoked from the command line by running `flutter analyze`. - -# The following line activates a set of recommended lints for Flutter apps, -# packages, and plugins designed to encourage good coding practices. include: package:flutter_lints/flutter.yaml +analyzer: + errors: + undefined_prefixed_name: ignore + unsafe_html: ignore linter: - # The lint rules applied to this project can be customized in the - # section below to disable rules from the `package:flutter_lints/flutter.yaml` - # included above or to enable additional rules. A list of all available lints - # and their documentation is published at https://dart.dev/lints. - # - # Instead of disabling a lint rule for the entire project in the - # section below, it can also be suppressed for a single line of code - # or a specific dart file by using the `// ignore: name_of_lint` and - # `// ignore_for_file: name_of_lint` syntax on the line or in the file - # producing the lint. rules: - # avoid_print: false # Uncomment to disable the `avoid_print` rule - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options + always_declare_return_types: true + always_put_required_named_parameters_first: true + annotate_overrides: true + avoid_empty_else: true + avoid_escaping_inner_quotes: true + avoid_print: true + avoid_redundant_argument_values: true + avoid_types_on_closure_parameters: true + avoid_void_async: true + cascade_invocations: true + directives_ordering: true + omit_local_variable_types: true + prefer_const_constructors: true + prefer_const_constructors_in_immutables: true + prefer_const_declarations: true + prefer_final_fields: true + prefer_final_in_for_each: true + prefer_final_locals: true + prefer_initializing_formals: true + prefer_int_literals: true + prefer_interpolation_to_compose_strings: true + prefer_relative_imports: true + prefer_single_quotes: true + sort_constructors_first: true + sort_unnamed_constructors_first: true + unnecessary_lambdas: true + unnecessary_parenthesis: true + unnecessary_string_interpolations: true + library_private_types_in_public_api: false diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index b69a36c7..118ee1d9 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -24,16 +24,16 @@ if (flutterVersionName == null) { android { namespace "com.example.example" - compileSdk flutter.compileSdkVersion + compileSdkVersion flutter.compileSdkVersion ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_17 - targetCompatibility JavaVersion.VERSION_17 + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { - jvmTarget = JavaVersion.VERSION_17.toString() + jvmTarget = '1.8' } sourceSets { @@ -41,8 +41,11 @@ android { } defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.example" - minSdkVersion 24 + // You can update the following values to match your application needs. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. + minSdkVersion flutter.minSdkVersion targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName @@ -50,6 +53,7 @@ android { buildTypes { release { + // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index b075bde1..7285ab78 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - @@ -8,7 +7,6 @@ - _HomePageState(); } @@ -54,9 +58,6 @@ class _HomePageState extends State { try { final result = await rootBundle.loadString('assets/sample_data_testing.json'); - // final result = await rootBundle.loadString(isDesktop() - // ? 'assets/sample_data_nomedia.json' - // : 'assets/sample_data.json'); final doc = Document.fromJson(jsonDecode(result)); _controller = QuillController( document: doc, @@ -89,12 +90,32 @@ class _HomePageState extends State { ), actions: [ IconButton( - onPressed: () { - setState(() => _isReadOnly = !_isReadOnly); - }, - icon: Icon( - _isReadOnly ? Icons.lock : Icons.edit, - )), + tooltip: 'Print to log', + onPressed: () { + print( + jsonEncode(_controller.document.toDelta().toJson()), + ); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'The quill delta json has been printed to the log.', + ), + ), + ); + }, + icon: const Icon( + Icons.print, + ), + ), + IconButton( + tooltip: 'Toggle read only', + onPressed: () { + setState(() => _isReadOnly = !_isReadOnly); + }, + icon: Icon( + _isReadOnly ? Icons.lock : Icons.edit, + ), + ), IconButton( onPressed: () => _insertTimeStamp( _controller, @@ -121,7 +142,116 @@ class _HomePageState extends State { ], ), drawer: Drawer( - child: _buildMenuBar(context), + child: ListView( + children: [ + DrawerHeader( + child: IconButton( + tooltip: 'Open document by json delta', + onPressed: () async { + final scaffoldMessenger = ScaffoldMessenger.of(context); + try { + final result = await FilePicker.platform.pickFiles( + dialogTitle: 'Pick json delta', + type: FileType.custom, + allowedExtensions: ['json'], + allowMultiple: false, + ); + final file = result?.files.firstOrNull; + final filePath = file?.path; + if (file == null || filePath == null) { + return; + } + final jsonString = await XFile(filePath).readAsString(); + _controller.document = + Document.fromJson(jsonDecode(jsonString)); + } catch (e) { + print( + 'Error while loading json delta file: ${e.toString()}', + ); + scaffoldMessenger.showSnackBar( + SnackBar( + content: Text( + 'Error while loading json delta file: ${e.toString()}', + ), + ), + ); + } + }, + icon: const Icon(Icons.file_copy), + ), + ), + ListTile( + title: const Text('Load sample data'), + onTap: () async { + final scaffoldMessenger = ScaffoldMessenger.of(context); + try { + final jsonString = await rootBundle.loadString( + 'assets/sample_data.json', + ); + _controller.document = Document.fromJson( + jsonDecode(jsonString), + ); + } catch (e) { + print( + 'Error while loading json delta file: ${e.toString()}', + ); + scaffoldMessenger.showSnackBar(SnackBar( + content: Text( + 'Error while loading json delta file: ${e.toString()}', + ), + )); + } + }, + ), + ListTile( + title: const Text('Load sample data with no media'), + onTap: () async { + final scaffoldMessenger = ScaffoldMessenger.of(context); + try { + final jsonString = await rootBundle.loadString( + 'assets/sample_data_nomedia.json', + ); + _controller.document = Document.fromJson( + jsonDecode(jsonString), + ); + } catch (e) { + print( + 'Error while loading json delta file: ${e.toString()}', + ); + scaffoldMessenger.showSnackBar(SnackBar( + content: Text( + 'Error while loading json delta file: ${e.toString()}', + ), + )); + } + }, + ), + ListTile( + title: const Text('Load testing sample data '), + onTap: () async { + final scaffoldMessenger = ScaffoldMessenger.of(context); + try { + final jsonString = await rootBundle.loadString( + 'assets/sample_data_testing.json', + ); + _controller.document = Document.fromJson( + jsonDecode(jsonString), + ); + } catch (e) { + print( + 'Error while loading json delta file: ${e.toString()}', + ); + scaffoldMessenger.showSnackBar(SnackBar( + content: Text( + 'Error while loading json delta file: ${e.toString()}', + ), + )); + } + }, + ), + _buildMenuBar(context), + ], + ), ), body: _buildWelcomeEditor(context), ); @@ -541,7 +671,7 @@ class _HomePageState extends State { Navigator.push( super.context, MaterialPageRoute( - builder: (context) => ReadOnlyPage(), + builder: (context) => const ReadOnlyPage(), ), ); } diff --git a/example/lib/pages/read_only_page.dart b/example/lib/pages/read_only_page.dart index 44c85b3f..6f38741a 100644 --- a/example/lib/pages/read_only_page.dart +++ b/example/lib/pages/read_only_page.dart @@ -9,6 +9,8 @@ import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; import '../widgets/demo_scaffold.dart'; class ReadOnlyPage extends StatefulWidget { + const ReadOnlyPage({super.key}); + @override _ReadOnlyPageState createState() => _ReadOnlyPageState(); } diff --git a/example/lib/widgets/demo_scaffold.dart b/example/lib/widgets/demo_scaffold.dart index 9de4e786..85311a85 100644 --- a/example/lib/widgets/demo_scaffold.dart +++ b/example/lib/widgets/demo_scaffold.dart @@ -18,8 +18,8 @@ class DemoScaffold extends StatefulWidget { this.actions, this.showToolbar = true, this.floatingActionButton, - Key? key, - }) : super(key: key); + super.key, + }); /// Filename of the document to load into the editor. final String documentFilename; diff --git a/example/lib/widgets/time_stamp_embed_widget.dart b/example/lib/widgets/time_stamp_embed_widget.dart index 968cb441..d78457f0 100644 --- a/example/lib/widgets/time_stamp_embed_widget.dart +++ b/example/lib/widgets/time_stamp_embed_widget.dart @@ -21,8 +21,8 @@ class TimeStampEmbedBuilderWidget extends EmbedBuilder { String get key => 'timeStamp'; @override - String toPlainText(Embed embed) { - return embed.value.data; + String toPlainText(Embed node) { + return node.value.data; } @override diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 0067ce4a..c9db1b46 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -9,22 +9,29 @@ environment: dependencies: flutter: sdk: flutter + flutter_localizations: + sdk: flutter universal_html: ^2.2.4 cupertino_icons: ^1.0.6 path_provider: ^2.1.1 # filesystem_picker: ^4.0.0 - # file_picker: ^6.1.1 - flutter_quill: ^8.2.2 - flutter_quill_extensions: ^0.6.0-dev.5 + file_picker: ^6.1.1 + flutter_quill: ^8.2.3 + flutter_quill_extensions: ^0.6.1 + path: ^1.8.3 dependency_overrides: flutter_quill: path: ../ flutter_quill_extensions: path: ../flutter_quill_extensions + flutter_quill_test: + path: ../flutter_quill_test dev_dependencies: + flutter_lints: ^3.0.1 + flutter_quill_test: ^0.0.3 flutter_test: sdk: flutter diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index ca3ecf17..5f46835d 100644 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -12,7 +12,7 @@ import 'package:flutter_test/flutter_test.dart'; void main() { testWidgets('Counter increments smoke test', (tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); + await tester.pumpWidget(const MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 591acd85..3754c611 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.6.2 +- Add more default exports + ## 0.6.1 - Fix bug on web that causing the project to not build diff --git a/flutter_quill_extensions/LICENSE b/flutter_quill_extensions/LICENSE index aaec6d89..e82b91ed 100644 --- a/flutter_quill_extensions/LICENSE +++ b/flutter_quill_extensions/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Xin Yao +Copyright (c) 2023 Flutter Quill Team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index 3078767c..c59ae175 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -57,7 +57,7 @@ dependencies: ## Usage -Before starting using this package you must follow the setup +Before starting using this package you must follow the [setup](#installation) Set the `embedBuilders` and `embedToolbar` params in configurations of `QuillEditor` and `QuillToolbar` with the values provided by this repository. diff --git a/flutter_quill_extensions/analysis_options.yaml b/flutter_quill_extensions/analysis_options.yaml index 8f1b96e4..f1a38172 100644 --- a/flutter_quill_extensions/analysis_options.yaml +++ b/flutter_quill_extensions/analysis_options.yaml @@ -1,4 +1,4 @@ -include: package:lints/recommended.yaml +include: package:flutter_lints/flutter.yaml analyzer: errors: @@ -6,32 +6,31 @@ analyzer: unsafe_html: ignore linter: rules: - - always_declare_return_types - - always_put_required_named_parameters_first - - annotate_overrides - - avoid_empty_else - - avoid_escaping_inner_quotes - - avoid_print - - avoid_redundant_argument_values - - avoid_types_on_closure_parameters - - avoid_void_async - - cascade_invocations - - directives_ordering - - lines_longer_than_80_chars - - omit_local_variable_types - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - - prefer_initializing_formals - - prefer_int_literals - - prefer_interpolation_to_compose_strings - - prefer_relative_imports - - prefer_single_quotes - - sort_constructors_first - - sort_unnamed_constructors_first - - unnecessary_lambdas - - unnecessary_parenthesis - - unnecessary_string_interpolations + always_declare_return_types: true + always_put_required_named_parameters_first: true + annotate_overrides: true + avoid_empty_else: true + avoid_escaping_inner_quotes: true + avoid_print: true + avoid_redundant_argument_values: true + avoid_types_on_closure_parameters: true + avoid_void_async: true + cascade_invocations: true + directives_ordering: true + omit_local_variable_types: true + prefer_const_constructors: true + prefer_const_constructors_in_immutables: true + prefer_const_declarations: true + prefer_final_fields: true + prefer_final_in_for_each: true + prefer_final_locals: true + prefer_initializing_formals: true + prefer_int_literals: true + prefer_interpolation_to_compose_strings: true + prefer_relative_imports: true + prefer_single_quotes: true + sort_constructors_first: true + sort_unnamed_constructors_first: true + unnecessary_lambdas: true + unnecessary_parenthesis: true + unnecessary_string_interpolations: true diff --git a/flutter_quill_extensions/lib/core/exceptions.dart b/flutter_quill_extensions/lib/core/exceptions.dart deleted file mode 100644 index 3967adb7..00000000 --- a/flutter_quill_extensions/lib/core/exceptions.dart +++ /dev/null @@ -1,12 +0,0 @@ -// import 'package:meta/meta.dart'; - -// @immutable -// class NetworkException implements Exception { -// const NetworkException({required this.message}); - -// final String message; - -// @override -// String toString() => -// 'Error while loading something from the network: $message'; -// } diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index a5c372ef..666f9177 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -27,10 +27,15 @@ import 'presentation/models/config/toolbar/buttons/image.dart'; import 'presentation/models/config/toolbar/buttons/media_button.dart'; import 'presentation/models/config/toolbar/buttons/video.dart'; +export '/logic/extensions/controller.dart'; export '/presentation/models/config/editor/webview.dart'; -export './logic/extensions/controller.dart'; +export 'logic/models/config/shared_configurations.dart'; +export 'presentation/embeds/editor/image/image.dart'; export 'presentation/embeds/editor/image/image_web.dart'; export 'presentation/embeds/editor/unknown.dart'; +export 'presentation/embeds/editor/video/video.dart'; +export 'presentation/embeds/editor/video/video_web.dart'; +export 'presentation/embeds/editor/webview.dart'; export 'presentation/embeds/embed_types.dart'; export 'presentation/embeds/embed_types/image.dart'; export 'presentation/embeds/embed_types/video.dart'; @@ -42,6 +47,11 @@ export 'presentation/embeds/toolbar/utils/image_video_utils.dart'; export 'presentation/embeds/toolbar/video_button/video_button.dart'; export 'presentation/embeds/utils.dart'; export 'presentation/models/config/editor/image/image.dart'; +// TODO: Temporary +// ignore: unused_import +export 'presentation/models/config/editor/image/image_web.dart'; +export 'presentation/models/config/editor/video/video.dart'; +export 'presentation/models/config/editor/video/video_web.dart'; export 'presentation/models/config/toolbar/buttons/camera.dart'; export 'presentation/models/config/toolbar/buttons/formula.dart'; export 'presentation/models/config/toolbar/buttons/image.dart'; @@ -111,9 +121,12 @@ class FlutterQuillEmbeds { /// Returns a list of embed builders specifically designed for web support. /// - /// [QuillEditorImageEmbedBuilderWeb] is the embed builder for handling + /// [QuillEditorWebImageEmbedBuilder] is the embed builder for handling /// images on the web. /// + /// [QuillEditorWebVideoEmbedBuilder] is the embed builder for handling + /// videos iframe on the web. + /// static List editorsWebBuilders( {QuillEditorWebImageEmbedConfigurations? imageEmbedConfigurations = const QuillEditorWebImageEmbedConfigurations(), @@ -122,7 +135,7 @@ class FlutterQuillEmbeds { if (!kIsWeb) { throw UnsupportedError( 'The editorsWebBuilders() is only for web, please use editorBuilders() ' - 'instead', + 'instead for other platforms', ); } return [ diff --git a/flutter_quill_extensions/lib/logic/extensions/controller.dart b/flutter_quill_extensions/lib/logic/extensions/controller.dart index 2318e5f6..234c418e 100644 --- a/flutter_quill_extensions/lib/logic/extensions/controller.dart +++ b/flutter_quill_extensions/lib/logic/extensions/controller.dart @@ -2,9 +2,16 @@ import 'package:flutter_quill/flutter_quill.dart'; import '../../presentation/embeds/editor/webview.dart'; +/// Extension functions on [QuillController] +/// that make it easier to insert the embed blocks +/// +/// and provide some other extra utilities extension QuillControllerExt on QuillController { int get index => selection.baseOffset; int get length => selection.extentOffset - index; + + /// Insert webview embed block, it requires [initialUrl] to load + /// the initial page void insertWebViewBlock({ required String initialUrl, }) { @@ -24,19 +31,32 @@ extension QuillControllerExt on QuillController { ); } + /// Insert image embed block, it requires the [imageSource] + /// + /// it could be local image on the system file + /// http image on the network + /// + /// image base 64 void insertImageBlock({ - required String imageUrl, + required String imageSource, }) { this ..skipRequestKeyboard = true ..replaceText( index, length, - BlockEmbed.image(imageUrl), + BlockEmbed.image(imageSource), null, ); } + /// Insert video embed block, it requires the [videoUrl] + /// + /// it could be the video url directly (.mp4) + /// either locally on file system + /// or http video on the network + /// + /// it also supports youtube video url void insertVideoBlock({ required String videoUrl, }) { diff --git a/flutter_quill_extensions/lib/logic/models/config/shared_configurations.dart b/flutter_quill_extensions/lib/logic/models/config/shared_configurations.dart index 307be978..6b4075a9 100644 --- a/flutter_quill_extensions/lib/logic/models/config/shared_configurations.dart +++ b/flutter_quill_extensions/lib/logic/models/config/shared_configurations.dart @@ -5,6 +5,33 @@ import 'package:meta/meta.dart' show immutable; import '../../services/image_picker/s_image_picker.dart'; import '../../services/image_saver/s_image_saver.dart'; +/// Configurations for Flutter Quill Extensions +/// that is shared between the toolbar and editor for the extensions package +/// +/// Example on how to setup it: +/// +/// ```dart +/// QuillProvider( +/// configurations: QuillConfigurations( +/// sharedConfigurations: const QuillSharedConfigurations( +/// extraConfigurations: { +/// QuillSharedExtensionsConfigurations.key: +/// QuillSharedExtensionsConfigurations( +/// // Feel free to explore it +/// ), +/// }, +/// ), +/// controller: _controller, +/// ), +/// child: const Column( +/// children: [ +/// // QuillToolbar +/// // QuillEditor +/// // ... +/// ], +// ), +/// ) +/// ``` @immutable class QuillSharedExtensionsConfigurations { const QuillSharedExtensionsConfigurations({ @@ -33,11 +60,18 @@ class QuillSharedExtensionsConfigurations { return const QuillSharedExtensionsConfigurations(); } + /// The key to be used in the `extraConfigurations` property + /// which can be found in the [QuillSharedConfigurations] + /// which lives in the [QuillConfigurations] + /// + /// which exists in the [QuillProvider] static const String key = 'quillSharedExtensionsConfigurations'; - /// Default to [ImagePickerService.defaultImpl] + /// Defaults to [ImagePickerService.defaultImpl] final ImagePickerService? _imagePickerService; + /// A getter method which returns the [ImagePickerService] that is provided + /// by the developer, if it can't be found then we will use default impl ImagePickerService get imagePickerService { return _imagePickerService ?? ImagePickerService.defaultImpl(); } @@ -45,6 +79,8 @@ class QuillSharedExtensionsConfigurations { /// Default to [ImageSaverService.defaultImpl] final ImageSaverService? _imageSaverService; + /// A getter method which returns the [ImageSaverService] that is provided + /// by the developer, if it can't be found then we will use default impl ImageSaverService get imageSaverService { return _imageSaverService ?? ImageSaverService.defaultImpl(); } diff --git a/flutter_quill_extensions/lib/logic/services/image_picker/s_image_picker.dart b/flutter_quill_extensions/lib/logic/services/image_picker/s_image_picker.dart index 9b9a43e4..23d19e2e 100644 --- a/flutter_quill_extensions/lib/logic/services/image_picker/s_image_picker.dart +++ b/flutter_quill_extensions/lib/logic/services/image_picker/s_image_picker.dart @@ -1,6 +1,7 @@ import 'image_picker.dart'; import 'packages/image_picker.dart'; +/// A service used for packing images in the extensions package class ImagePickerService extends ImagePickerInterface { const ImagePickerService( this._impl, diff --git a/flutter_quill_extensions/lib/logic/services/image_saver/s_image_saver.dart b/flutter_quill_extensions/lib/logic/services/image_saver/s_image_saver.dart index f11587fd..35b9ee34 100644 --- a/flutter_quill_extensions/lib/logic/services/image_saver/s_image_saver.dart +++ b/flutter_quill_extensions/lib/logic/services/image_saver/s_image_saver.dart @@ -2,6 +2,7 @@ import 'image_saver.dart'; import 'packages/gal.dart' show ImageSaverGalImpl; +/// A service used for saving images in the extensions package class ImageSaverService extends ImageSaverInterface { final ImageSaverInterface _impl; const ImageSaverService(this._impl); diff --git a/flutter_quill_extensions/lib/logic/utils/quill_utils.dart b/flutter_quill_extensions/lib/logic/utils/quill_image_utils.dart similarity index 100% rename from flutter_quill_extensions/lib/logic/utils/quill_utils.dart rename to flutter_quill_extensions/lib/logic/utils/quill_image_utils.dart diff --git a/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart b/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart index 0a10ba6a..c53796ef 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/embed_types/image.dart @@ -30,7 +30,7 @@ OnImageInsertCallback defaultOnImageInsertCallback() { return (imageUrl, controller) async { controller ..skipRequestKeyboard = true - ..insertImageBlock(imageUrl: imageUrl); + ..insertImageBlock(imageSource: imageUrl); }; } diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index ecbea806..12995793 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 0.6.1 +version: 0.6.2 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions @@ -45,9 +45,9 @@ dependencies: # In case you are working on changes for both libraries # Comment the dependency_overrides section when publishing the package, # then uncomment it back, this will be automated later -# dependency_overrides: -# flutter_quill: -# path: ../ +dependency_overrides: + flutter_quill: + path: ../ dev_dependencies: flutter_test: diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 158ce0f2..ac01b9bc 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.4 +* Update `README.md` +* Documentation comments. + ## 0.0.3 * Update the `README.md` and description diff --git a/flutter_quill_test/LICENSE b/flutter_quill_test/LICENSE index 19efa532..e82b91ed 100644 --- a/flutter_quill_test/LICENSE +++ b/flutter_quill_test/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) Flutter Quill Team +Copyright (c) 2023 Flutter Quill Team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/flutter_quill_test/README.md b/flutter_quill_test/README.md index d244e54b..ea602306 100644 --- a/flutter_quill_test/README.md +++ b/flutter_quill_test/README.md @@ -2,6 +2,23 @@ Test utilities for [flutter_quill](https://pub.dev/packages/flutter_quill) which includes methods to simplify interacting with the editor in test cases. +## Installation + +Run the command in your project root folder: +``` +dart pub add dev:flutter_quill_test +``` + +Example of how it will looks like: + +```yaml +dev_dependencies: + flutter_quill_test: any # Use latest Version + flutter_lints: any + flutter_test: + sdk: flutter +``` + ## Testing To aid in testing applications using the editor an extension to the flutter `WidgetTester` is provided which includes methods to simplify interacting with the editor in test cases. diff --git a/flutter_quill_test/analysis_options.yaml b/flutter_quill_test/analysis_options.yaml index 8f1b96e4..f1a38172 100644 --- a/flutter_quill_test/analysis_options.yaml +++ b/flutter_quill_test/analysis_options.yaml @@ -1,4 +1,4 @@ -include: package:lints/recommended.yaml +include: package:flutter_lints/flutter.yaml analyzer: errors: @@ -6,32 +6,31 @@ analyzer: unsafe_html: ignore linter: rules: - - always_declare_return_types - - always_put_required_named_parameters_first - - annotate_overrides - - avoid_empty_else - - avoid_escaping_inner_quotes - - avoid_print - - avoid_redundant_argument_values - - avoid_types_on_closure_parameters - - avoid_void_async - - cascade_invocations - - directives_ordering - - lines_longer_than_80_chars - - omit_local_variable_types - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - - prefer_initializing_formals - - prefer_int_literals - - prefer_interpolation_to_compose_strings - - prefer_relative_imports - - prefer_single_quotes - - sort_constructors_first - - sort_unnamed_constructors_first - - unnecessary_lambdas - - unnecessary_parenthesis - - unnecessary_string_interpolations + always_declare_return_types: true + always_put_required_named_parameters_first: true + annotate_overrides: true + avoid_empty_else: true + avoid_escaping_inner_quotes: true + avoid_print: true + avoid_redundant_argument_values: true + avoid_types_on_closure_parameters: true + avoid_void_async: true + cascade_invocations: true + directives_ordering: true + omit_local_variable_types: true + prefer_const_constructors: true + prefer_const_constructors_in_immutables: true + prefer_const_declarations: true + prefer_final_fields: true + prefer_final_in_for_each: true + prefer_final_locals: true + prefer_initializing_formals: true + prefer_int_literals: true + prefer_interpolation_to_compose_strings: true + prefer_relative_imports: true + prefer_single_quotes: true + sort_constructors_first: true + sort_unnamed_constructors_first: true + unnecessary_lambdas: true + unnecessary_parenthesis: true + unnecessary_string_interpolations: true diff --git a/flutter_quill_test/lib/src/test/widget_tester_extension.dart b/flutter_quill_test/lib/src/test/widget_tester_extension.dart index a3ef9f53..11e5f45b 100644 --- a/flutter_quill_test/lib/src/test/widget_tester_extension.dart +++ b/flutter_quill_test/lib/src/test/widget_tester_extension.dart @@ -2,21 +2,29 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_test/flutter_test.dart'; -/// Extends -extension QuillEnterText on WidgetTester { +/// Extensions on [WidgetTester] that have utilities that help +/// simplify interacting with the editor in test cases. +extension QuillWidgetTesterExt on WidgetTester { /// Give the QuillEditor widget specified by [finder] the focus. + /// Future quillGiveFocus(Finder finder) { return TestAsyncUtils.guard(() async { final editor = state( find.descendant( of: finder, - matching: find.byType(QuillEditor, skipOffstage: finder.skipOffstage), + matching: find.byType( + QuillEditor, + skipOffstage: finder.skipOffstage, + ), matchRoot: true, ), ); editor.widget.focusNode.requestFocus(); await pump(); - expect(editor.widget.focusNode.hasFocus, isTrue); + expect( + editor.widget.focusNode.hasFocus, + isTrue, + ); }); } @@ -26,6 +34,7 @@ extension QuillEnterText on WidgetTester { /// /// The widget specified by [finder] must be a [QuillEditor] or have a /// [QuillEditor] descendant. For example `find.byType(QuillEditor)`. + /// Future quillEnterText(Finder finder, String text) async { return TestAsyncUtils.guard(() async { await quillGiveFocus(finder); @@ -40,19 +49,24 @@ extension QuillEnterText on WidgetTester { /// The widget specified by [finder] must already have focus and be a /// [QuillEditor] or have a [QuillEditor] descendant. For example /// `find.byType(QuillEditor)`. + /// Future quillUpdateEditingValue(Finder finder, String text) async { return TestAsyncUtils.guard(() async { final editor = state( find.descendant( - of: finder, - matching: - find.byType(QuillRawEditor, skipOffstage: finder.skipOffstage), - matchRoot: true), + of: finder, + matching: + find.byType(QuillRawEditor, skipOffstage: finder.skipOffstage), + matchRoot: true, + ), ); - testTextInput.updateEditingValue(TextEditingValue( + testTextInput.updateEditingValue( + TextEditingValue( text: text, selection: TextSelection.collapsed( - offset: editor.textEditingValue.text.length))); + offset: editor.textEditingValue.text.length), + ), + ); await idle(); }); } diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index c8a535ff..e076d8df 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -26,12 +26,12 @@ environment: dependencies: flutter: sdk: flutter - flutter_quill: ^8.2.2 + flutter_quill: ^8.2.3 flutter_test: sdk: flutter dev_dependencies: - flutter_lints: ^2.0.0 + flutter_lints: ^3.0.1 # In case you are working on changes for both libraries # Comment the dependency_overrides section when publishing the package, diff --git a/flutter_quill_test/test/flutter_quill_test_test.dart b/flutter_quill_test/test/flutter_quill_test_test.dart index ab73b3a2..953946ba 100644 --- a/flutter_quill_test/test/flutter_quill_test_test.dart +++ b/flutter_quill_test/test/flutter_quill_test_test.dart @@ -1 +1,2 @@ +/// This will be empty for now void main() {} diff --git a/lib/src/core/utils/logger.dart b/lib/src/core/utils/logger.dart new file mode 100644 index 00000000..a0c5c805 --- /dev/null +++ b/lib/src/core/utils/logger.dart @@ -0,0 +1,68 @@ +import 'dart:async' show Zone; +import 'dart:developer' as dev show log; + +import 'package:flutter/foundation.dart' show kDebugMode; +import 'package:meta/meta.dart' show immutable; + +/// Simple logger for the quill libraries +/// +/// it log only if [kDebugMode] is true +/// so only for development mode and not in production +/// +@immutable +class QuillLogger { + const QuillLogger._(); + + static bool shouldLog() { + return kDebugMode; + } + + static void log( + T message, { + DateTime? time, + int? sequenceNumber, + int level = 0, + String name = '', + Zone? zone, + StackTrace? stackTrace, + }) { + if (!shouldLog()) { + return; + } + dev.log( + message.toString(), + time: time, + sequenceNumber: sequenceNumber, + level: level, + name: name, + zone: zone, + stackTrace: stackTrace, + ); + } + + static void error( + T message, { + DateTime? time, + int? sequenceNumber, + int level = 0, + String name = '', + Zone? zone, + Object? error, + StackTrace? stackTrace, + }) { + if (!shouldLog()) { + return; + } + + dev.log( + message.toString(), + time: time, + sequenceNumber: sequenceNumber, + level: level, + name: name, + zone: zone, + error: error, + stackTrace: stackTrace, + ); + } +} diff --git a/lib/src/widgets/proxy.dart b/lib/src/widgets/proxy.dart index 06f44191..e6475fdd 100644 --- a/lib/src/widgets/proxy.dart +++ b/lib/src/widgets/proxy.dart @@ -78,7 +78,7 @@ class RenderBaselineProxy extends RenderProxyBox { } class EmbedProxy extends SingleChildRenderObjectWidget { - const EmbedProxy(Widget child) : super(child: child); + const EmbedProxy(Widget child, {super.key}) : super(child: child); @override RenderEmbedProxy createRenderObject(BuildContext context) => diff --git a/lib/src/widgets/raw_editor/raw_editor.dart b/lib/src/widgets/raw_editor/raw_editor.dart index 8da91981..78419349 100644 --- a/lib/src/widgets/raw_editor/raw_editor.dart +++ b/lib/src/widgets/raw_editor/raw_editor.dart @@ -1164,9 +1164,10 @@ class QuillRawEditorState extends EditorState } Future _requestAutoFocusIfShould() async { + final focusManager = FocusScope.of(context); if (!_didAutoFocus && widget.autoFocus) { await Future.delayed(Duration.zero); // To avoid exceptions - FocusScope.of(context).autofocus(widget.focusNode); + focusManager.autofocus(widget.focusNode); _didAutoFocus = true; } } diff --git a/lib/src/widgets/style_widgets/checkbox_point.dart b/lib/src/widgets/style_widgets/checkbox_point.dart index 509db66f..cf57ea92 100644 --- a/lib/src/widgets/style_widgets/checkbox_point.dart +++ b/lib/src/widgets/style_widgets/checkbox_point.dart @@ -79,11 +79,11 @@ class QuillEditorCheckboxPointState extends State { if (context.requireQuillSharedConfigurations.animationConfigurations .checkBoxPointItem) { return Animate( - effects: [ - const SlideEffect( + effects: const [ + SlideEffect( duration: Duration(milliseconds: 70), ), - const ScaleEffect( + ScaleEffect( duration: Duration(milliseconds: 70), ) ], diff --git a/lib/src/widgets/text_line.dart b/lib/src/widgets/text_line.dart index b482ed79..de0c24bb 100644 --- a/lib/src/widgets/text_line.dart +++ b/lib/src/widgets/text_line.dart @@ -508,19 +508,19 @@ class _TextLineState extends State { class EditableTextLine extends RenderObjectWidget { const EditableTextLine( - this.line, - this.leading, - this.body, - this.indentWidth, - this.verticalSpacing, - this.textDirection, - this.textSelection, - this.color, - this.enableInteractiveSelection, - this.hasFocus, - this.devicePixelRatio, - this.cursorCont, - ); + this.line, + this.leading, + this.body, + this.indentWidth, + this.verticalSpacing, + this.textDirection, + this.textSelection, + this.color, + this.enableInteractiveSelection, + this.hasFocus, + this.devicePixelRatio, + this.cursorCont, + {super.key}); final Line line; final Widget? leading; diff --git a/lib/src/widgets/toolbar/base_toolbar.dart b/lib/src/widgets/toolbar/base_toolbar.dart index b422c713..573f37e1 100644 --- a/lib/src/widgets/toolbar/base_toolbar.dart +++ b/lib/src/widgets/toolbar/base_toolbar.dart @@ -102,12 +102,12 @@ class QuillToolbarDivider extends StatelessWidget { }); /// Provides a horizontal divider for vertical toolbar. - const QuillToolbarDivider.horizontal({Color? color, double? space}) - : this(Axis.horizontal, color: color, space: space); + const QuillToolbarDivider.horizontal({Key? key, Color? color, double? space}) + : this(Axis.horizontal, color: color, space: space, key: key); /// Provides a horizontal divider for horizontal toolbar. - const QuillToolbarDivider.vertical({Color? color, double? space}) - : this(Axis.vertical, color: color, space: space); + const QuillToolbarDivider.vertical({Key? key, Color? color, double? space}) + : this(Axis.vertical, color: color, space: space, key: key); /// The axis along which the toolbar is. final Axis axis; diff --git a/lib/src/widgets/toolbar/buttons/link_style.dart b/lib/src/widgets/toolbar/buttons/link_style.dart index 5234dbaf..a3c6a198 100644 --- a/lib/src/widgets/toolbar/buttons/link_style.dart +++ b/lib/src/widgets/toolbar/buttons/link_style.dart @@ -281,7 +281,7 @@ class _LinkDialogState extends State<_LinkDialog> { onChanged: _textChanged, controller: _textController, textInputAction: TextInputAction.next, - autofillHints: [ + autofillHints: const [ AutofillHints.name, AutofillHints.url, ], @@ -299,7 +299,7 @@ class _LinkDialogState extends State<_LinkDialog> { onChanged: _linkChanged, controller: _linkController, textInputAction: TextInputAction.done, - autofillHints: [AutofillHints.url], + autofillHints: const [AutofillHints.url], autocorrect: false, onEditingComplete: () { if (!_canPress()) { diff --git a/lib/src/widgets/utils/provider.dart b/lib/src/widgets/utils/provider.dart index 69340b36..6a9028e0 100644 --- a/lib/src/widgets/utils/provider.dart +++ b/lib/src/widgets/utils/provider.dart @@ -9,6 +9,7 @@ class QuillProvider extends InheritedWidget { const QuillProvider({ required this.configurations, required super.child, + super.key, }); /// Controller object which establishes a link between a rich text document @@ -67,6 +68,7 @@ class QuillToolbarProvider extends InheritedWidget { const QuillToolbarProvider({ required super.child, required this.toolbarConfigurations, + super.key, }); /// The configurations for the toolbar widget of flutter quill @@ -124,6 +126,7 @@ class QuillBaseToolbarProvider extends InheritedWidget { const QuillBaseToolbarProvider({ required super.child, required this.toolbarConfigurations, + super.key, }); /// The configurations for the toolbar widget of flutter quill @@ -181,6 +184,7 @@ class QuillEditorProvider extends InheritedWidget { const QuillEditorProvider({ required super.child, required this.editorConfigurations, + super.key, }); /// The configurations for the quill editor widget of flutter quill diff --git a/pubspec.yaml b/pubspec.yaml index 63bf0a6c..22ba0056 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.2.3 +version: 8.2.4 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill @@ -54,7 +54,7 @@ dependencies: flutter: uses-material-design: true dev_dependencies: - lints: ^3.0.0 + flutter_lints: ^3.0.1 flutter_test: sdk: flutter flutter_quill_test: ^0.0.2 From 4aad60419cff5a855de41d2a5d3deda47e7cce49 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Tue, 7 Nov 2023 02:00:15 +0300 Subject: [PATCH 073/210] Update the example, android example, and few changes --- example/android/app/build.gradle | 17 +++---- .../android/app/src/main/AndroidManifest.xml | 38 +++++++++------ .../com/example/example/MainActivity.kt | 3 +- example/android/build.gradle | 47 ++++++++++++++++++- example/android/gradle.properties | 3 ++ .../gradle/wrapper/gradle-wrapper.properties | 2 +- example/assets/sample_data.json | 47 ------------------- example/lib/pages/home_page.dart | 12 +++++ flutter_quill_test/pubspec.yaml | 2 +- lib/src/models/documents/document.dart | 4 +- lib/src/utils/color.dart | 2 +- lib/src/utils/delta.dart | 6 ++- lib/src/utils/embeds.dart | 2 +- lib/src/utils/extensions/build_context.dart | 3 +- lib/src/utils/font.dart | 2 +- lib/src/widgets/raw_editor/raw_editor.dart | 6 ++- lib/src/widgets/text_block.dart | 2 +- lib/src/widgets/text_selection.dart | 10 ++-- 18 files changed, 115 insertions(+), 93 deletions(-) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 118ee1d9..e574d1e8 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -24,16 +24,18 @@ if (flutterVersionName == null) { android { namespace "com.example.example" - compileSdkVersion flutter.compileSdkVersion + compileSdk flutter.compileSdkVersion ndkVersion flutter.ndkVersion + def javaVersion = JavaVersion.VERSION_17 + compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility javaVersion + targetCompatibility javaVersion } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = javaVersion.toString() } sourceSets { @@ -41,11 +43,8 @@ android { } defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.example" - // You can update the following values to match your application needs. - // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion flutter.minSdkVersion + minSdkVersion 24 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName @@ -53,8 +52,6 @@ android { buildTypes { release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } } diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 7285ab78..1d6e0b64 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,35 +1,45 @@ - + + + - + - - - + + + + + + + android:icon="@mipmap/ic_launcher" + android:label="example"> + android:name="io.flutter.embedding.android.NormalTheme" + android:resource="@style/NormalTheme" /> - - + + - - - - - - - - - \ No newline at end of file diff --git a/.github/workflows/welcome.yml b/.github/workflows/welcome.yml new file mode 100644 index 00000000..5d47fe9a --- /dev/null +++ b/.github/workflows/welcome.yml @@ -0,0 +1,18 @@ +name: 'Welcome New Contributors' + +on: + issues: + types: [opened] + pull_request_target: + types: [opened] + +jobs: + welcome-new-contributor: + runs-on: ubuntu-latest + steps: + - name: 'Greet the contributor' + uses: garg3133/welcome-new-contributors@v1.2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + issue-message: 'Hello there, on behalf the Flutter Quill Team I would like to thank you for opening your first issue. Your inputs and insights are valuable in shaping a stable and reliable version for all our users. Thank you for being part of the open-source community!' + pr-message: 'Hi there, thanks for opening your first Pull Request to this project!!' \ No newline at end of file diff --git a/packages/README.md b/packages/README.md new file mode 100644 index 00000000..6da077ab --- /dev/null +++ b/packages/README.md @@ -0,0 +1,6 @@ +# Flutter Quill Packages + +This folder contains packages that add more features to the [FlutterQuill](../README.md) +that might be outside of the packages main purpose + +This page will be updated soon. \ No newline at end of file From f3aa50ac1e817c04a610036e2c6a0941d8b93474 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Thu, 9 Nov 2023 02:42:50 +0300 Subject: [PATCH 082/210] Update welcome.yml --- .github/workflows/welcome.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/welcome.yml b/.github/workflows/welcome.yml index 5d47fe9a..54027d81 100644 --- a/.github/workflows/welcome.yml +++ b/.github/workflows/welcome.yml @@ -13,6 +13,6 @@ jobs: - name: 'Greet the contributor' uses: garg3133/welcome-new-contributors@v1.2 with: - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ secrets.BOT_ACCESS_TOKEN }} issue-message: 'Hello there, on behalf the Flutter Quill Team I would like to thank you for opening your first issue. Your inputs and insights are valuable in shaping a stable and reliable version for all our users. Thank you for being part of the open-source community!' pr-message: 'Hi there, thanks for opening your first Pull Request to this project!!' \ No newline at end of file From adae3a564838bb72fd32f987fc420f53aa969261 Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Thu, 9 Nov 2023 02:51:52 +0000 Subject: [PATCH 083/210] fix: fix typos in PR template --- .github/PULL_REQUEST_TEMPLATE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c4810500..3636b60a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -40,7 +40,7 @@ Closes #IssueNumber - [ ] I have tested these changes locally. - [ ] I have followed the code style and guidelines. - [ ] I have updated `CHANGELOG.md` with my changes in the next section -- [ ] I have run `dart format .`` on the project +- [ ] I have run `dart format .` on the project - [ ] I have run `dart fix --apply` on the project - [ ] I have run `flutter test` and `flutter analyze` and it passed successfully -- [ ] I have run `./before-push.sh` and everything is fine +- [ ] I have run `./scripts/before-push.sh` and everything is fine From 33b8cb2498ba81f3cceb08af48e3bbe274377d83 Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Thu, 9 Nov 2023 01:36:48 +0000 Subject: [PATCH 084/210] feat: allow customising iconButtonFactor --- doc/migration.md | 6 +++++- lib/src/models/config/toolbar/buttons/base.dart | 9 +++++++-- lib/src/widgets/toolbar/buttons/clear_format.dart | 9 ++++++++- lib/src/widgets/toolbar/buttons/color.dart | 8 +++++++- lib/src/widgets/toolbar/buttons/custom_button.dart | 5 ++++- lib/src/widgets/toolbar/buttons/history.dart | 6 ++++-- lib/src/widgets/toolbar/buttons/indent.dart | 11 ++++++++--- lib/src/widgets/toolbar/buttons/link_style.dart | 8 +++++++- lib/src/widgets/toolbar/buttons/link_style2.dart | 8 +++++++- lib/src/widgets/toolbar/buttons/search/search.dart | 9 ++++++++- lib/src/widgets/toolbar/buttons/select_alignment.dart | 10 ++++++++-- .../widgets/toolbar/buttons/select_header_style.dart | 10 ++++++++-- lib/src/widgets/toolbar/buttons/toggle_style.dart | 3 ++- 13 files changed, 83 insertions(+), 19 deletions(-) diff --git a/doc/migration.md b/doc/migration.md index 4de759f7..7a65b3ef 100644 --- a/doc/migration.md +++ b/doc/migration.md @@ -79,10 +79,14 @@ All the options have parent `QuillToolbarBaseButtonOptions` which have common th final IconData? iconData; /// To change the icon size pass a different value, by default will be - /// [kDefaultIconSize] + /// [kDefaultIconSize]. /// This will be used for all the buttons but you can override this final double globalIconSize; + /// The factor of how much larger the button is in relation to the icon, + /// by default it will be [kIconButtonFactor]. + final double globalIconButtonFactor; + /// To do extra logic after pressing the button final VoidCallback? afterButtonPressed; diff --git a/lib/src/models/config/toolbar/buttons/base.dart b/lib/src/models/config/toolbar/buttons/base.dart index 931b6fa3..b8f47d26 100644 --- a/lib/src/models/config/toolbar/buttons/base.dart +++ b/lib/src/models/config/toolbar/buttons/base.dart @@ -5,7 +5,7 @@ import 'package:flutter/widgets.dart' show BuildContext, IconData, Widget; import '../../../../../flutter_quill.dart' show QuillController, QuillProvider; import '../../../themes/quill_icon_theme.dart' show QuillIconTheme; -import '../../quill_configurations.dart' show kDefaultIconSize; +import '../../quill_configurations.dart' show kDefaultIconSize, kIconButtonFactor; @immutable class QuillToolbarBaseButtonExtraOptions extends Equatable { @@ -38,6 +38,7 @@ class QuillToolbarBaseButtonOptions extends Equatable { const QuillToolbarBaseButtonOptions({ this.iconData, this.globalIconSize = kDefaultIconSize, + this.globalIconButtonFactor = kIconButtonFactor, this.afterButtonPressed, this.tooltip, this.iconTheme, @@ -51,10 +52,14 @@ class QuillToolbarBaseButtonOptions extends Equatable { final IconData? iconData; /// To change the the icon size pass a different value, by default will be - /// [kDefaultIconSize] + /// [kDefaultIconSize]. /// this will be used for all the buttons but you can override this final double globalIconSize; + /// The factor of how much larger the button is in relation to the icon, + /// by default it will be [kIconButtonFactor]. + final double globalIconButtonFactor; + /// To do extra logic after pressing the button final VoidCallback? afterButtonPressed; diff --git a/lib/src/widgets/toolbar/buttons/clear_format.dart b/lib/src/widgets/toolbar/buttons/clear_format.dart index 2e2c4e9d..aed2feaf 100644 --- a/lib/src/widgets/toolbar/buttons/clear_format.dart +++ b/lib/src/widgets/toolbar/buttons/clear_format.dart @@ -27,6 +27,12 @@ class QuillToolbarClearFormatButton extends StatelessWidget { return iconSize ?? baseFontSize; } + double _iconButtonFactor(BuildContext context) { + final baseIconFactor = baseButtonExtraOptions(context).iconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor; + } + VoidCallback? _afterButtonPressed(BuildContext context) { return options.afterButtonPressed ?? baseButtonExtraOptions(context).afterButtonPressed; @@ -69,6 +75,7 @@ class QuillToolbarClearFormatButton extends StatelessWidget { final iconTheme = _iconTheme(context); final tooltip = _tooltip(context); final iconSize = _iconSize(context); + final iconButtonFactor = _iconButtonFactor(context); final iconData = _iconData(context); final childBuilder = @@ -105,7 +112,7 @@ class QuillToolbarClearFormatButton extends StatelessWidget { tooltip: tooltip, highlightElevation: 0, hoverElevation: 0, - size: iconSize * kIconButtonFactor, + size: iconSize * iconButtonFactor, icon: Icon(iconData, size: iconSize, color: iconColor), fillColor: fillColor, borderRadius: iconTheme?.borderRadius ?? 2, diff --git a/lib/src/widgets/toolbar/buttons/color.dart b/lib/src/widgets/toolbar/buttons/color.dart index 83da1e06..e1804cda 100644 --- a/lib/src/widgets/toolbar/buttons/color.dart +++ b/lib/src/widgets/toolbar/buttons/color.dart @@ -108,6 +108,12 @@ class QuillToolbarColorButtonState extends State { return iconSize ?? baseFontSize; } + double get iconButtonFactor { + final baseIconFactor = baseButtonExtraOptions.iconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor; + } + VoidCallback? get afterButtonPressed { return options.afterButtonPressed ?? baseButtonExtraOptions.afterButtonPressed; @@ -179,7 +185,7 @@ class QuillToolbarColorButtonState extends State { tooltip: tooltip, highlightElevation: 0, hoverElevation: 0, - size: iconSize * kIconButtonFactor, + size: iconSize * iconButtonFactor, icon: Icon(iconData, size: iconSize, color: widget.isBackground ? iconColorBackground : iconColor), diff --git a/lib/src/widgets/toolbar/buttons/custom_button.dart b/lib/src/widgets/toolbar/buttons/custom_button.dart index 50745e74..b958ec51 100644 --- a/lib/src/widgets/toolbar/buttons/custom_button.dart +++ b/lib/src/widgets/toolbar/buttons/custom_button.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import '../../../models/config/toolbar/configurations.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../base_toolbar.dart'; @@ -9,6 +10,7 @@ class CustomButton extends StatelessWidget { required this.icon, this.iconColor, this.iconSize = kDefaultIconSize, + this.iconButtonFactor = kIconButtonFactor, this.iconTheme, this.afterButtonPressed, this.tooltip, @@ -19,6 +21,7 @@ class CustomButton extends StatelessWidget { final IconData? icon; final Color? iconColor; final double iconSize; + final double iconButtonFactor; final QuillIconTheme? iconTheme; final VoidCallback? afterButtonPressed; final String? tooltip; @@ -31,7 +34,7 @@ class CustomButton extends StatelessWidget { return QuillToolbarIconButton( highlightElevation: 0, hoverElevation: 0, - size: iconSize * kIconButtonFactor, + size: iconSize * iconButtonFactor, icon: Icon(icon, size: iconSize, color: iconColor), tooltip: tooltip, borderRadius: iconTheme?.borderRadius ?? 2, diff --git a/lib/src/widgets/toolbar/buttons/history.dart b/lib/src/widgets/toolbar/buttons/history.dart index 5bae3bfd..102c8062 100644 --- a/lib/src/widgets/toolbar/buttons/history.dart +++ b/lib/src/widgets/toolbar/buttons/history.dart @@ -60,7 +60,9 @@ class QuillToolbarHistoryButtonState extends State { final childBuilder = options.childBuilder ?? baseButtonConfigurations.childBuilder; final iconSize = options.iconSize ?? - context.requireQuillToolbarBaseButtonOptions.globalIconSize; + baseButtonConfigurations.globalIconSize; + final iconButtonFactor = options.iconButtonFactor ?? + baseButtonConfigurations.iconButtonFactor; final iconTheme = options.iconTheme ?? baseButtonConfigurations.iconTheme; final afterButtonPressed = options.afterButtonPressed ?? @@ -96,7 +98,7 @@ class QuillToolbarHistoryButtonState extends State { tooltip: tooltip, highlightElevation: 0, hoverElevation: 0, - size: iconSize * kIconButtonFactor, + size: iconSize * iconButtonFactor, icon: Icon( iconData, size: iconSize, diff --git a/lib/src/widgets/toolbar/buttons/indent.dart b/lib/src/widgets/toolbar/buttons/indent.dart index 2c8cdf94..1acaa04c 100644 --- a/lib/src/widgets/toolbar/buttons/indent.dart +++ b/lib/src/widgets/toolbar/buttons/indent.dart @@ -8,8 +8,7 @@ import '../../controller.dart'; import '../base_toolbar.dart' show QuillToolbarBaseButtonOptions, - QuillToolbarIconButton, - kIconButtonFactor; + QuillToolbarIconButton; class QuillToolbarIndentButton extends StatefulWidget { const QuillToolbarIndentButton({ @@ -43,6 +42,12 @@ class QuillToolbarIndentButtonState extends State { return iconSize ?? baseFontSize; } + double get iconButtonFactor { + final baseIconFactor = baseButtonExtraOptions.iconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor; + } + VoidCallback? get afterButtonPressed { return options.afterButtonPressed ?? baseButtonExtraOptions.afterButtonPressed; @@ -107,7 +112,7 @@ class QuillToolbarIndentButtonState extends State { tooltip: tooltip, highlightElevation: 0, hoverElevation: 0, - size: iconSize * kIconButtonFactor, + size: iconSize * iconButtonFactor, icon: Icon(iconData, size: iconSize, color: iconColor), fillColor: iconFillColor, borderRadius: iconTheme?.borderRadius ?? 2, diff --git a/lib/src/widgets/toolbar/buttons/link_style.dart b/lib/src/widgets/toolbar/buttons/link_style.dart index a3c6a198..e301ebf2 100644 --- a/lib/src/widgets/toolbar/buttons/link_style.dart +++ b/lib/src/widgets/toolbar/buttons/link_style.dart @@ -67,6 +67,12 @@ class QuillToolbarLinkStyleButtonState return iconSize ?? baseFontSize; } + double get iconButtonFactor { + final baseIconFactor = baseButtonExtraOptions.iconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor; + } + VoidCallback? get afterButtonPressed { return options.afterButtonPressed ?? baseButtonExtraOptions.afterButtonPressed; @@ -134,7 +140,7 @@ class QuillToolbarLinkStyleButtonState tooltip: tooltip, highlightElevation: 0, hoverElevation: 0, - size: iconSize * kIconButtonFactor, + size: iconSize * iconButtonFactor, icon: Icon( iconData, size: iconSize, diff --git a/lib/src/widgets/toolbar/buttons/link_style2.dart b/lib/src/widgets/toolbar/buttons/link_style2.dart index 751c860b..18f81286 100644 --- a/lib/src/widgets/toolbar/buttons/link_style2.dart +++ b/lib/src/widgets/toolbar/buttons/link_style2.dart @@ -75,6 +75,12 @@ class _QuillToolbarLinkStyleButton2State return iconSize ?? baseFontSize; } + double get iconButtonFactor { + final baseIconFactor = baseButtonExtraOptions.iconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor; + } + VoidCallback? get afterButtonPressed { return options.afterButtonPressed ?? baseButtonExtraOptions.afterButtonPressed; @@ -142,7 +148,7 @@ class _QuillToolbarLinkStyleButton2State tooltip: tooltip, highlightElevation: 0, hoverElevation: 0, - size: iconSize * kIconButtonFactor, + size: iconSize * iconButtonFactor, icon: Icon( iconData, size: iconSize, diff --git a/lib/src/widgets/toolbar/buttons/search/search.dart b/lib/src/widgets/toolbar/buttons/search/search.dart index 0f8537f0..b263ad6d 100644 --- a/lib/src/widgets/toolbar/buttons/search/search.dart +++ b/lib/src/widgets/toolbar/buttons/search/search.dart @@ -27,6 +27,12 @@ class QuillToolbarSearchButton extends StatelessWidget { return iconSize ?? baseFontSize; } + double _iconButtonFactor(BuildContext context) { + final baseIconFactor = baseButtonExtraOptions(context).iconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor; + } + VoidCallback? _afterButtonPressed(BuildContext context) { return options.afterButtonPressed ?? baseButtonExtraOptions(context).afterButtonPressed; @@ -68,6 +74,7 @@ class QuillToolbarSearchButton extends StatelessWidget { final tooltip = _tooltip(context); final iconData = _iconData(context); final iconSize = _iconSize(context); + final iconButtonFactor = _iconButtonFactor(context); final afterButtonPressed = _afterButtonPressed(context); final childBuilder = @@ -112,7 +119,7 @@ class QuillToolbarSearchButton extends StatelessWidget { ), highlightElevation: 0, hoverElevation: 0, - size: iconSize * kIconButtonFactor, + size: iconSize * iconButtonFactor, fillColor: iconFillColor, borderRadius: iconTheme?.borderRadius ?? 2, onPressed: () => _sharedOnPressed(context), diff --git a/lib/src/widgets/toolbar/buttons/select_alignment.dart b/lib/src/widgets/toolbar/buttons/select_alignment.dart index fac78d85..b969b115 100644 --- a/lib/src/widgets/toolbar/buttons/select_alignment.dart +++ b/lib/src/widgets/toolbar/buttons/select_alignment.dart @@ -66,6 +66,12 @@ class QuillToolbarSelectAlignmentButtonState return iconSize ?? baseFontSize; } + double get _iconButtonFactor { + final baseIconFactor = baseButtonExtraOptions.iconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor; + } + VoidCallback? get _afterButtonPressed { return options.afterButtonPressed ?? baseButtonExtraOptions.afterButtonPressed; @@ -225,8 +231,8 @@ class QuillToolbarSelectAlignmentButtonState const EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0), child: ConstrainedBox( constraints: BoxConstraints.tightFor( - width: _iconSize * kIconButtonFactor, - height: _iconSize * kIconButtonFactor, + width: _iconSize * _iconButtonFactor, + height: _iconSize * _iconButtonFactor, ), child: UtilityWidgets.maybeTooltip( message: valueString[index] == Attribute.leftAlignment.value diff --git a/lib/src/widgets/toolbar/buttons/select_header_style.dart b/lib/src/widgets/toolbar/buttons/select_header_style.dart index 15a05597..7f252439 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style.dart @@ -61,6 +61,12 @@ class QuillToolbarSelectHeaderStyleButtonsState return iconSize ?? baseFontSize; } + double get iconButtonFactor { + final baseIconFactor = baseButtonExtraOptions.iconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor; + } + VoidCallback? get afterButtonPressed { return options.afterButtonPressed ?? baseButtonExtraOptions.afterButtonPressed; @@ -142,8 +148,8 @@ class QuillToolbarSelectHeaderStyleButtonsState padding: const EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0), child: ConstrainedBox( constraints: BoxConstraints.tightFor( - width: iconSize * kIconButtonFactor, - height: iconSize * kIconButtonFactor, + width: iconSize * iconButtonFactor, + height: iconSize * iconButtonFactor, ), child: UtilityWidgets.maybeTooltip( message: tooltip, diff --git a/lib/src/widgets/toolbar/buttons/toggle_style.dart b/lib/src/widgets/toolbar/buttons/toggle_style.dart index 439df53b..8e73226b 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style.dart @@ -212,6 +212,7 @@ Widget defaultToggleStyleButtonBuilder( VoidCallback? onPressed, VoidCallback? afterPressed, [ double iconSize = kDefaultIconSize, + double iconButtonFactor = kIconButtonFactor, QuillIconTheme? iconTheme, ]) { final theme = Theme.of(context); @@ -234,7 +235,7 @@ Widget defaultToggleStyleButtonBuilder( return QuillToolbarIconButton( highlightElevation: 0, hoverElevation: 0, - size: iconSize * kIconButtonFactor, + size: iconSize * iconButtonFactor, icon: Icon(icon, size: iconSize, color: iconColor), fillColor: fill, onPressed: onPressed, From 5eb122712bc612a6a7777b4ebb7b1a44238b0099 Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Thu, 9 Nov 2023 02:32:17 +0000 Subject: [PATCH 085/210] fix: fix runtime errors --- lib/src/models/config/toolbar/buttons/clear_format.dart | 2 ++ lib/src/models/config/toolbar/buttons/color.dart | 2 ++ lib/src/models/config/toolbar/buttons/history.dart | 2 ++ lib/src/models/config/toolbar/buttons/indent.dart | 2 ++ lib/src/models/config/toolbar/buttons/link_style.dart | 2 ++ lib/src/models/config/toolbar/buttons/link_style2.dart | 2 ++ lib/src/models/config/toolbar/buttons/search.dart | 2 ++ .../models/config/toolbar/buttons/select_alignment.dart | 2 ++ .../config/toolbar/buttons/select_header_style.dart | 2 ++ .../models/config/toolbar/buttons/toggle_check_list.dart | 2 ++ lib/src/models/config/toolbar/buttons/toggle_style.dart | 2 ++ lib/src/widgets/toolbar/buttons/clear_format.dart | 2 +- lib/src/widgets/toolbar/buttons/color.dart | 2 +- lib/src/widgets/toolbar/buttons/history.dart | 2 +- lib/src/widgets/toolbar/buttons/indent.dart | 2 +- lib/src/widgets/toolbar/buttons/link_style.dart | 2 +- lib/src/widgets/toolbar/buttons/link_style2.dart | 2 +- lib/src/widgets/toolbar/buttons/search/search.dart | 2 +- lib/src/widgets/toolbar/buttons/select_alignment.dart | 2 +- lib/src/widgets/toolbar/buttons/select_header_style.dart | 2 +- lib/src/widgets/toolbar/buttons/toggle_check_list.dart | 7 +++++++ lib/src/widgets/toolbar/buttons/toggle_style.dart | 8 ++++++++ 22 files changed, 46 insertions(+), 9 deletions(-) diff --git a/lib/src/models/config/toolbar/buttons/clear_format.dart b/lib/src/models/config/toolbar/buttons/clear_format.dart index f38dd52f..d34eef84 100644 --- a/lib/src/models/config/toolbar/buttons/clear_format.dart +++ b/lib/src/models/config/toolbar/buttons/clear_format.dart @@ -20,7 +20,9 @@ class QuillToolbarClearFormatButtonOptions super.iconTheme, super.tooltip, this.iconSize, + this.iconButtonFactor, }); final double? iconSize; + final double? iconButtonFactor; } diff --git a/lib/src/models/config/toolbar/buttons/color.dart b/lib/src/models/config/toolbar/buttons/color.dart index 19bac781..bff832e8 100644 --- a/lib/src/models/config/toolbar/buttons/color.dart +++ b/lib/src/models/config/toolbar/buttons/color.dart @@ -26,6 +26,7 @@ class QuillToolbarColorButtonOptions extends QuillToolbarBaseButtonOptions< const QuillToolbarColorButtonOptions({ this.dialogBarrierColor, this.iconSize, + this.iconButtonFactor, super.iconData, super.afterButtonPressed, super.childBuilder, @@ -36,6 +37,7 @@ class QuillToolbarColorButtonOptions extends QuillToolbarBaseButtonOptions< }); final double? iconSize; + final double? iconButtonFactor; /// By default will use the default `dialogBarrierColor` from /// [QuillSharedConfigurations] diff --git a/lib/src/models/config/toolbar/buttons/history.dart b/lib/src/models/config/toolbar/buttons/history.dart index eeceeda5..1f1bfaab 100644 --- a/lib/src/models/config/toolbar/buttons/history.dart +++ b/lib/src/models/config/toolbar/buttons/history.dart @@ -28,6 +28,7 @@ class QuillToolbarHistoryButtonOptions extends QuillToolbarBaseButtonOptions< super.tooltip, super.childBuilder, this.iconSize, + this.iconButtonFactor, }); /// If this true then it will be the undo button @@ -36,4 +37,5 @@ class QuillToolbarHistoryButtonOptions extends QuillToolbarBaseButtonOptions< /// By default will use [globalIconSize] final double? iconSize; + final double? iconButtonFactor; } diff --git a/lib/src/models/config/toolbar/buttons/indent.dart b/lib/src/models/config/toolbar/buttons/indent.dart index 30252088..66700c71 100644 --- a/lib/src/models/config/toolbar/buttons/indent.dart +++ b/lib/src/models/config/toolbar/buttons/indent.dart @@ -21,7 +21,9 @@ class QuillToolbarIndentButtonOptions extends QuillToolbarBaseButtonOptions { super.iconTheme, super.tooltip, this.iconSize, + this.iconButtonFactor, }); final double? iconSize; + final double? iconButtonFactor; } diff --git a/lib/src/models/config/toolbar/buttons/link_style.dart b/lib/src/models/config/toolbar/buttons/link_style.dart index 7e2b6717..e82d750e 100644 --- a/lib/src/models/config/toolbar/buttons/link_style.dart +++ b/lib/src/models/config/toolbar/buttons/link_style.dart @@ -22,6 +22,7 @@ class QuillToolbarLinkStyleButtonOptions extends QuillToolbarBaseButtonOptions< this.linkDialogAction, this.dialogBarrierColor, this.iconSize, + this.iconButtonFactor, super.iconData, super.globalIconSize, super.afterButtonPressed, @@ -32,6 +33,7 @@ class QuillToolbarLinkStyleButtonOptions extends QuillToolbarBaseButtonOptions< }); final double? iconSize; + final double? iconButtonFactor; final QuillDialogTheme? dialogTheme; final RegExp? linkRegExp; final LinkDialogAction? linkDialogAction; diff --git a/lib/src/models/config/toolbar/buttons/link_style2.dart b/lib/src/models/config/toolbar/buttons/link_style2.dart index d42eec96..75014143 100644 --- a/lib/src/models/config/toolbar/buttons/link_style2.dart +++ b/lib/src/models/config/toolbar/buttons/link_style2.dart @@ -17,6 +17,7 @@ class QuillToolbarLinkStyleButton2Options extends QuillToolbarBaseButtonOptions< QuillToolbarLinkStyleButton2ExtraOptions> { const QuillToolbarLinkStyleButton2Options({ this.iconSize, + this.iconButtonFactor, this.dialogTheme, this.constraints, this.addLinkLabel, @@ -36,6 +37,7 @@ class QuillToolbarLinkStyleButton2Options extends QuillToolbarBaseButtonOptions< }); final double? iconSize; + final double? iconButtonFactor; final QuillDialogTheme? dialogTheme; /// The constrains for dialog. diff --git a/lib/src/models/config/toolbar/buttons/search.dart b/lib/src/models/config/toolbar/buttons/search.dart index b4505408..6ba95f07 100644 --- a/lib/src/models/config/toolbar/buttons/search.dart +++ b/lib/src/models/config/toolbar/buttons/search.dart @@ -21,6 +21,7 @@ class QuillToolbarSearchButtonOptions extends QuillToolbarBaseButtonOptions { super.iconTheme, this.dialogTheme, this.iconSize, + this.iconButtonFactor, this.dialogBarrierColor, this.fillColor, this.customOnPressedCallback, @@ -28,6 +29,7 @@ class QuillToolbarSearchButtonOptions extends QuillToolbarBaseButtonOptions { final QuillDialogTheme? dialogTheme; final double? iconSize; + final double? iconButtonFactor; /// By default will be [dialogBarrierColor] from [QuillSharedConfigurations] final Color? dialogBarrierColor; diff --git a/lib/src/models/config/toolbar/buttons/select_alignment.dart b/lib/src/models/config/toolbar/buttons/select_alignment.dart index 19bb21bd..0a90d350 100644 --- a/lib/src/models/config/toolbar/buttons/select_alignment.dart +++ b/lib/src/models/config/toolbar/buttons/select_alignment.dart @@ -18,6 +18,7 @@ class QuillToolbarSelectAlignmentButtonOptions this.iconsData, this.tooltips, this.iconSize, + this.iconButtonFactor, super.afterButtonPressed, /// This will called on every select alignment button @@ -26,6 +27,7 @@ class QuillToolbarSelectAlignmentButtonOptions super.iconTheme, }); final double? iconSize; + final double? iconButtonFactor; /// Default to /// const QuillToolbarSelectAlignmentValues( diff --git a/lib/src/models/config/toolbar/buttons/select_header_style.dart b/lib/src/models/config/toolbar/buttons/select_header_style.dart index fd4298b7..6e70c9eb 100644 --- a/lib/src/models/config/toolbar/buttons/select_header_style.dart +++ b/lib/src/models/config/toolbar/buttons/select_header_style.dart @@ -25,6 +25,7 @@ class QuillToolbarSelectHeaderStyleButtonsOptions this.axis, this.attributes, this.iconSize, + this.iconButtonFactor, }); /// Default value: @@ -39,4 +40,5 @@ class QuillToolbarSelectHeaderStyleButtonsOptions /// By default we will the toolbar axis from [QuillToolbarConfigurations] final Axis? axis; final double? iconSize; + final double? iconButtonFactor; } diff --git a/lib/src/models/config/toolbar/buttons/toggle_check_list.dart b/lib/src/models/config/toolbar/buttons/toggle_check_list.dart index 7f4e98b1..54d456b9 100644 --- a/lib/src/models/config/toolbar/buttons/toggle_check_list.dart +++ b/lib/src/models/config/toolbar/buttons/toggle_check_list.dart @@ -22,6 +22,7 @@ class QuillToolbarToggleCheckListButtonOptions QuillToolbarToggleCheckListButtonExtraOptions> { const QuillToolbarToggleCheckListButtonOptions({ this.iconSize, + this.iconButtonFactor, this.fillColor, this.attribute = Attribute.unchecked, this.isShouldRequestKeyboard = false, @@ -34,6 +35,7 @@ class QuillToolbarToggleCheckListButtonOptions }); final double? iconSize; + final double? iconButtonFactor; final Color? fillColor; diff --git a/lib/src/models/config/toolbar/buttons/toggle_style.dart b/lib/src/models/config/toolbar/buttons/toggle_style.dart index 2ad9c1da..2c2ef1dd 100644 --- a/lib/src/models/config/toolbar/buttons/toggle_style.dart +++ b/lib/src/models/config/toolbar/buttons/toggle_style.dart @@ -22,6 +22,7 @@ class QuillToolbarToggleStyleButtonOptions const QuillToolbarToggleStyleButtonOptions({ super.iconData, this.iconSize, + this.iconButtonFactor, this.fillColor, super.tooltip, super.afterButtonPressed, @@ -31,5 +32,6 @@ class QuillToolbarToggleStyleButtonOptions }); final double? iconSize; + final double? iconButtonFactor; final Color? fillColor; } diff --git a/lib/src/widgets/toolbar/buttons/clear_format.dart b/lib/src/widgets/toolbar/buttons/clear_format.dart index aed2feaf..4d9ac51c 100644 --- a/lib/src/widgets/toolbar/buttons/clear_format.dart +++ b/lib/src/widgets/toolbar/buttons/clear_format.dart @@ -28,7 +28,7 @@ class QuillToolbarClearFormatButton extends StatelessWidget { } double _iconButtonFactor(BuildContext context) { - final baseIconFactor = baseButtonExtraOptions(context).iconButtonFactor; + final baseIconFactor = baseButtonExtraOptions(context).globalIconButtonFactor; final iconButtonFactor = options.iconButtonFactor; return iconButtonFactor ?? baseIconFactor; } diff --git a/lib/src/widgets/toolbar/buttons/color.dart b/lib/src/widgets/toolbar/buttons/color.dart index e1804cda..0e4c9e18 100644 --- a/lib/src/widgets/toolbar/buttons/color.dart +++ b/lib/src/widgets/toolbar/buttons/color.dart @@ -109,7 +109,7 @@ class QuillToolbarColorButtonState extends State { } double get iconButtonFactor { - final baseIconFactor = baseButtonExtraOptions.iconButtonFactor; + final baseIconFactor = baseButtonExtraOptions.globalIconButtonFactor; final iconButtonFactor = options.iconButtonFactor; return iconButtonFactor ?? baseIconFactor; } diff --git a/lib/src/widgets/toolbar/buttons/history.dart b/lib/src/widgets/toolbar/buttons/history.dart index 102c8062..089e0769 100644 --- a/lib/src/widgets/toolbar/buttons/history.dart +++ b/lib/src/widgets/toolbar/buttons/history.dart @@ -62,7 +62,7 @@ class QuillToolbarHistoryButtonState extends State { final iconSize = options.iconSize ?? baseButtonConfigurations.globalIconSize; final iconButtonFactor = options.iconButtonFactor ?? - baseButtonConfigurations.iconButtonFactor; + baseButtonConfigurations.globalIconButtonFactor; final iconTheme = options.iconTheme ?? baseButtonConfigurations.iconTheme; final afterButtonPressed = options.afterButtonPressed ?? diff --git a/lib/src/widgets/toolbar/buttons/indent.dart b/lib/src/widgets/toolbar/buttons/indent.dart index 1acaa04c..6c5561c5 100644 --- a/lib/src/widgets/toolbar/buttons/indent.dart +++ b/lib/src/widgets/toolbar/buttons/indent.dart @@ -43,7 +43,7 @@ class QuillToolbarIndentButtonState extends State { } double get iconButtonFactor { - final baseIconFactor = baseButtonExtraOptions.iconButtonFactor; + final baseIconFactor = baseButtonExtraOptions.globalIconButtonFactor; final iconButtonFactor = options.iconButtonFactor; return iconButtonFactor ?? baseIconFactor; } diff --git a/lib/src/widgets/toolbar/buttons/link_style.dart b/lib/src/widgets/toolbar/buttons/link_style.dart index e301ebf2..e96aabb8 100644 --- a/lib/src/widgets/toolbar/buttons/link_style.dart +++ b/lib/src/widgets/toolbar/buttons/link_style.dart @@ -68,7 +68,7 @@ class QuillToolbarLinkStyleButtonState } double get iconButtonFactor { - final baseIconFactor = baseButtonExtraOptions.iconButtonFactor; + final baseIconFactor = baseButtonExtraOptions.globalIconButtonFactor; final iconButtonFactor = options.iconButtonFactor; return iconButtonFactor ?? baseIconFactor; } diff --git a/lib/src/widgets/toolbar/buttons/link_style2.dart b/lib/src/widgets/toolbar/buttons/link_style2.dart index 18f81286..0ddf8f2f 100644 --- a/lib/src/widgets/toolbar/buttons/link_style2.dart +++ b/lib/src/widgets/toolbar/buttons/link_style2.dart @@ -76,7 +76,7 @@ class _QuillToolbarLinkStyleButton2State } double get iconButtonFactor { - final baseIconFactor = baseButtonExtraOptions.iconButtonFactor; + final baseIconFactor = baseButtonExtraOptions.globalIconButtonFactor; final iconButtonFactor = options.iconButtonFactor; return iconButtonFactor ?? baseIconFactor; } diff --git a/lib/src/widgets/toolbar/buttons/search/search.dart b/lib/src/widgets/toolbar/buttons/search/search.dart index b263ad6d..7e2e2886 100644 --- a/lib/src/widgets/toolbar/buttons/search/search.dart +++ b/lib/src/widgets/toolbar/buttons/search/search.dart @@ -28,7 +28,7 @@ class QuillToolbarSearchButton extends StatelessWidget { } double _iconButtonFactor(BuildContext context) { - final baseIconFactor = baseButtonExtraOptions(context).iconButtonFactor; + final baseIconFactor = baseButtonExtraOptions(context).globalIconButtonFactor; final iconButtonFactor = options.iconButtonFactor; return iconButtonFactor ?? baseIconFactor; } diff --git a/lib/src/widgets/toolbar/buttons/select_alignment.dart b/lib/src/widgets/toolbar/buttons/select_alignment.dart index b969b115..6104f9a1 100644 --- a/lib/src/widgets/toolbar/buttons/select_alignment.dart +++ b/lib/src/widgets/toolbar/buttons/select_alignment.dart @@ -67,7 +67,7 @@ class QuillToolbarSelectAlignmentButtonState } double get _iconButtonFactor { - final baseIconFactor = baseButtonExtraOptions.iconButtonFactor; + final baseIconFactor = baseButtonExtraOptions.globalIconButtonFactor; final iconButtonFactor = options.iconButtonFactor; return iconButtonFactor ?? baseIconFactor; } diff --git a/lib/src/widgets/toolbar/buttons/select_header_style.dart b/lib/src/widgets/toolbar/buttons/select_header_style.dart index 7f252439..3795d1dd 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style.dart @@ -62,7 +62,7 @@ class QuillToolbarSelectHeaderStyleButtonsState } double get iconButtonFactor { - final baseIconFactor = baseButtonExtraOptions.iconButtonFactor; + final baseIconFactor = baseButtonExtraOptions.globalIconButtonFactor; final iconButtonFactor = options.iconButtonFactor; return iconButtonFactor ?? baseIconFactor; } diff --git a/lib/src/widgets/toolbar/buttons/toggle_check_list.dart b/lib/src/widgets/toolbar/buttons/toggle_check_list.dart index b30a2243..18a65aea 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_check_list.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_check_list.dart @@ -93,6 +93,12 @@ class QuillToolbarToggleCheckListButtonState return iconSize ?? baseFontSize; } + double get iconButtonFactor { + final baseIconFactor = baseButtonExtraOptions.globalIconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor; + } + VoidCallback? get afterButtonPressed { return options.afterButtonPressed ?? baseButtonExtraOptions.afterButtonPressed; @@ -154,6 +160,7 @@ class QuillToolbarToggleCheckListButtonState _toggleAttribute, afterButtonPressed, iconSize, + iconButtonFactor, iconTheme, ), ); diff --git a/lib/src/widgets/toolbar/buttons/toggle_style.dart b/lib/src/widgets/toolbar/buttons/toggle_style.dart index 8e73226b..f105174c 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style.dart @@ -68,6 +68,13 @@ class QuillToolbarToggleStyleButtonState return iconSize ?? baseFontSize; } + double get iconButtonFactor { + final baseIconFactor = + context.requireQuillToolbarBaseButtonOptions.globalIconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor; + } + VoidCallback? get afterButtonPressed { return options.afterButtonPressed ?? context.requireQuillToolbarBaseButtonOptions.afterButtonPressed; @@ -159,6 +166,7 @@ class QuillToolbarToggleStyleButtonState _toggleAttribute, options.afterButtonPressed, iconSize, + iconButtonFactor, iconTheme, ), ); From 61eae95994475870e1c53ae03050bdc63868a8fe Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Thu, 9 Nov 2023 02:47:23 +0000 Subject: [PATCH 086/210] ref: dart format . --- lib/src/models/config/toolbar/buttons/base.dart | 3 ++- lib/src/widgets/toolbar/buttons/clear_format.dart | 3 ++- lib/src/widgets/toolbar/buttons/history.dart | 4 ++-- lib/src/widgets/toolbar/buttons/indent.dart | 4 +--- lib/src/widgets/toolbar/buttons/search/search.dart | 3 ++- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/src/models/config/toolbar/buttons/base.dart b/lib/src/models/config/toolbar/buttons/base.dart index b8f47d26..2eadbff8 100644 --- a/lib/src/models/config/toolbar/buttons/base.dart +++ b/lib/src/models/config/toolbar/buttons/base.dart @@ -5,7 +5,8 @@ import 'package:flutter/widgets.dart' show BuildContext, IconData, Widget; import '../../../../../flutter_quill.dart' show QuillController, QuillProvider; import '../../../themes/quill_icon_theme.dart' show QuillIconTheme; -import '../../quill_configurations.dart' show kDefaultIconSize, kIconButtonFactor; +import '../../quill_configurations.dart' + show kDefaultIconSize, kIconButtonFactor; @immutable class QuillToolbarBaseButtonExtraOptions extends Equatable { diff --git a/lib/src/widgets/toolbar/buttons/clear_format.dart b/lib/src/widgets/toolbar/buttons/clear_format.dart index 4d9ac51c..9e1b27c7 100644 --- a/lib/src/widgets/toolbar/buttons/clear_format.dart +++ b/lib/src/widgets/toolbar/buttons/clear_format.dart @@ -28,7 +28,8 @@ class QuillToolbarClearFormatButton extends StatelessWidget { } double _iconButtonFactor(BuildContext context) { - final baseIconFactor = baseButtonExtraOptions(context).globalIconButtonFactor; + final baseIconFactor = + baseButtonExtraOptions(context).globalIconButtonFactor; final iconButtonFactor = options.iconButtonFactor; return iconButtonFactor ?? baseIconFactor; } diff --git a/lib/src/widgets/toolbar/buttons/history.dart b/lib/src/widgets/toolbar/buttons/history.dart index 089e0769..e0c3f7cf 100644 --- a/lib/src/widgets/toolbar/buttons/history.dart +++ b/lib/src/widgets/toolbar/buttons/history.dart @@ -59,8 +59,8 @@ class QuillToolbarHistoryButtonState extends State { (options.isUndo ? Icons.undo_outlined : Icons.redo_outlined); final childBuilder = options.childBuilder ?? baseButtonConfigurations.childBuilder; - final iconSize = options.iconSize ?? - baseButtonConfigurations.globalIconSize; + final iconSize = + options.iconSize ?? baseButtonConfigurations.globalIconSize; final iconButtonFactor = options.iconButtonFactor ?? baseButtonConfigurations.globalIconButtonFactor; final iconTheme = options.iconTheme ?? baseButtonConfigurations.iconTheme; diff --git a/lib/src/widgets/toolbar/buttons/indent.dart b/lib/src/widgets/toolbar/buttons/indent.dart index 6c5561c5..9f3de303 100644 --- a/lib/src/widgets/toolbar/buttons/indent.dart +++ b/lib/src/widgets/toolbar/buttons/indent.dart @@ -6,9 +6,7 @@ import '../../../translations/toolbar.i18n.dart'; import '../../../utils/extensions/build_context.dart'; import '../../controller.dart'; import '../base_toolbar.dart' - show - QuillToolbarBaseButtonOptions, - QuillToolbarIconButton; + show QuillToolbarBaseButtonOptions, QuillToolbarIconButton; class QuillToolbarIndentButton extends StatefulWidget { const QuillToolbarIndentButton({ diff --git a/lib/src/widgets/toolbar/buttons/search/search.dart b/lib/src/widgets/toolbar/buttons/search/search.dart index 7e2e2886..2bfaeb38 100644 --- a/lib/src/widgets/toolbar/buttons/search/search.dart +++ b/lib/src/widgets/toolbar/buttons/search/search.dart @@ -28,7 +28,8 @@ class QuillToolbarSearchButton extends StatelessWidget { } double _iconButtonFactor(BuildContext context) { - final baseIconFactor = baseButtonExtraOptions(context).globalIconButtonFactor; + final baseIconFactor = + baseButtonExtraOptions(context).globalIconButtonFactor; final iconButtonFactor = options.iconButtonFactor; return iconButtonFactor ?? baseIconFactor; } From 3241af1b821e922c911e5d90c7d3134c8cca92cc Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Thu, 9 Nov 2023 02:48:50 +0000 Subject: [PATCH 087/210] ref: dart fix --apply --- lib/src/widgets/toolbar/buttons/custom_button.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/src/widgets/toolbar/buttons/custom_button.dart b/lib/src/widgets/toolbar/buttons/custom_button.dart index b958ec51..741a6e7e 100644 --- a/lib/src/widgets/toolbar/buttons/custom_button.dart +++ b/lib/src/widgets/toolbar/buttons/custom_button.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import '../../../models/config/toolbar/configurations.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../base_toolbar.dart'; From f179dd913b8c5c7bc74b7f3ac579360f8b040ed7 Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Thu, 9 Nov 2023 02:56:05 +0000 Subject: [PATCH 088/210] 8.3.0 --- CHANGELOG.md | 3 +++ pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9383c4b2..a2a037c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.3.0] +- Added a `iconButtonFactor` property to `QuillToolbarBaseButtonOptions` to customise how big the button is compared to its icon size (defaults to `kIconButtonFactor` which is the same as previous releases) + ## [8.2.6] - Organize `QuillRawEditor` code diff --git a/pubspec.yaml b/pubspec.yaml index fe135184..2eb967b1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.2.6 +version: 8.3.0 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From 4f5fa325418ebd92b082bd26df575ed109339757 Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Thu, 9 Nov 2023 03:30:14 +0000 Subject: [PATCH 089/210] fix: pass iconButtonFactor to childBuilder --- .../embeds/toolbar/camera_button/camera_button.dart | 1 + .../lib/presentation/embeds/toolbar/formula_button.dart | 9 +++++++++ .../embeds/toolbar/image_button/image_button.dart | 9 +++++++++ .../embeds/toolbar/media_button/media_button.dart | 1 + .../embeds/toolbar/video_button/video_button.dart | 1 + .../models/config/toolbar/buttons/camera.dart | 2 ++ .../models/config/toolbar/buttons/formula.dart | 2 ++ .../models/config/toolbar/buttons/image.dart | 2 ++ .../models/config/toolbar/buttons/video.dart | 2 ++ flutter_quill_extensions/pubspec.yaml | 2 +- lib/src/models/config/toolbar/buttons/font_family.dart | 4 ++++ lib/src/models/config/toolbar/buttons/font_size.dart | 4 ++++ lib/src/widgets/toolbar/buttons/clear_format.dart | 1 + lib/src/widgets/toolbar/buttons/font_size.dart | 8 ++++++++ lib/src/widgets/toolbar/buttons/history.dart | 1 + lib/src/widgets/toolbar/buttons/indent.dart | 1 + lib/src/widgets/toolbar/buttons/link_style.dart | 1 + lib/src/widgets/toolbar/buttons/link_style2.dart | 1 + lib/src/widgets/toolbar/buttons/search/search.dart | 9 +++++---- lib/src/widgets/toolbar/buttons/select_alignment.dart | 1 + lib/src/widgets/toolbar/buttons/select_header_style.dart | 1 + lib/src/widgets/toolbar/buttons/toggle_check_list.dart | 1 + 22 files changed, 59 insertions(+), 5 deletions(-) diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart index 43d74f04..be7d7a14 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/camera_button/camera_button.dart @@ -77,6 +77,7 @@ class QuillToolbarCameraButton extends StatelessWidget { iconData: options.iconData, fillColor: options.fillColor, iconSize: options.iconSize, + iconButtonFactor: options.iconButtonFactor, iconTheme: options.iconTheme, tooltip: options.tooltip, cameraConfigurations: options.cameraConfigurations, diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/formula_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/formula_button.dart index 4a0341d4..e821d689 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/formula_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/formula_button.dart @@ -19,6 +19,13 @@ class QuillToolbarFormulaButton extends StatelessWidget { return iconSize ?? baseFontSize; } + double _iconButtonFactor(BuildContext context) { + final baseIconFactor = + baseButtonExtraOptions(context).globalIconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor; + } + VoidCallback? _afterButtonPressed(BuildContext context) { return options.afterButtonPressed ?? baseButtonExtraOptions(context).afterButtonPressed; @@ -58,6 +65,7 @@ class QuillToolbarFormulaButton extends StatelessWidget { final tooltip = _tooltip(context); final iconSize = _iconSize(context); + final iconButtonFactor = _iconButtonFactor(context); final iconData = _iconData(context); final childBuilder = options.childBuilder ?? baseButtonExtraOptions(context).childBuilder; @@ -73,6 +81,7 @@ class QuillToolbarFormulaButton extends StatelessWidget { fillColor: iconFillColor, iconData: iconData, iconSize: iconSize, + iconButtonFactor: iconButtonFactor, iconTheme: iconTheme, tooltip: tooltip, ), diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart index 8c27c1e3..cba66090 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/image_button.dart @@ -27,6 +27,13 @@ class QuillToolbarImageButton extends StatelessWidget { return iconSize ?? baseFontSize; } + double _iconButtonFactor(BuildContext context) { + final baseIconFactor = + baseButtonExtraOptions(context).globalIconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor; + } + VoidCallback? _afterButtonPressed(BuildContext context) { return options.afterButtonPressed ?? baseButtonExtraOptions(context).afterButtonPressed; @@ -62,6 +69,7 @@ class QuillToolbarImageButton extends StatelessWidget { Widget build(BuildContext context) { final tooltip = _tooltip(context); final iconSize = _iconSize(context); + final iconButtonFactor = _iconButtonFactor(context); final iconData = _iconData(context); final childBuilder = options.childBuilder ?? baseButtonExtraOptions(context).childBuilder; @@ -72,6 +80,7 @@ class QuillToolbarImageButton extends StatelessWidget { afterButtonPressed: _afterButtonPressed(context), iconData: iconData, iconSize: iconSize, + iconButtonFactor: iconButtonFactor, dialogTheme: options.dialogTheme, fillColor: options.fillColor, iconTheme: options.iconTheme, diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button/media_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button/media_button.dart index fdebb485..5246e838 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button/media_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/media_button/media_button.dart @@ -102,6 +102,7 @@ // galleryButtonText: options.galleryButtonText, // iconTheme: iconTheme, // iconSize: iconSize, +// iconButtonFactor: iconButtonFactor, // hintText: options.hintText, // labelText: options.labelText, // submitButtonSize: options.submitButtonSize, diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart index 76b5a4d0..32b660f4 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/video_button.dart @@ -82,6 +82,7 @@ class QuillToolbarVideoButton extends StatelessWidget { dialogTheme: options.dialogTheme, fillColor: iconFillColor, iconSize: options.iconSize, + iconButtonFactor: options.iconButtonFactor, linkRegExp: options.linkRegExp, tooltip: options.tooltip, iconTheme: options.iconTheme, diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart index 3c4c21cb..dafdf1ab 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/camera.dart @@ -17,6 +17,7 @@ class QuillToolbarCameraButtonOptions extends QuillToolbarBaseButtonOptions< const QuillToolbarCameraButtonOptions({ this.cameraConfigurations = const QuillToolbarCameraConfigurations(), this.iconSize, + this.iconButtonFactor, this.fillColor, super.iconData, super.afterButtonPressed, @@ -27,6 +28,7 @@ class QuillToolbarCameraButtonOptions extends QuillToolbarBaseButtonOptions< }); final double? iconSize; + final double? iconButtonFactor; final Color? fillColor; diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/formula.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/formula.dart index 7d716251..638e794c 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/formula.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/formula.dart @@ -20,9 +20,11 @@ class QuillToolbarFormulaButtonOptions extends QuillToolbarBaseButtonOptions< super.childBuilder, this.fillColor, this.iconSize, + this.iconButtonFactor, }); final Color? fillColor; final double? iconSize; + final double? iconButtonFactor; } diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart index b0084eeb..d1e5efbd 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/image.dart @@ -20,6 +20,7 @@ class QuillToolbarImageButtonOptions extends QuillToolbarBaseButtonOptions< super.iconData, super.controller, this.iconSize, + this.iconButtonFactor, /// specifies the tooltip text for the image button. super.tooltip, @@ -33,6 +34,7 @@ class QuillToolbarImageButtonOptions extends QuillToolbarBaseButtonOptions< }); final double? iconSize; + final double? iconButtonFactor; final Color? fillColor; final QuillDialogTheme? dialogTheme; diff --git a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart index 17f80453..e7efba51 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/toolbar/buttons/video.dart @@ -19,6 +19,7 @@ class QuillToolbarVideoButtonOptions extends QuillToolbarBaseButtonOptions< this.dialogTheme, this.fillColor, this.iconSize, + this.iconButtonFactor, super.iconData, super.afterButtonPressed, super.tooltip, @@ -35,4 +36,5 @@ class QuillToolbarVideoButtonOptions extends QuillToolbarBaseButtonOptions< final Color? fillColor; final double? iconSize; + final double? iconButtonFactor; } diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 04fce298..97cd2782 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -26,7 +26,7 @@ dependencies: flutter: sdk: flutter - flutter_quill: ^8.2.5 + flutter_quill: ^8.3.0 http: ^1.1.0 photo_view: ^0.14.0 diff --git a/lib/src/models/config/toolbar/buttons/font_family.dart b/lib/src/models/config/toolbar/buttons/font_family.dart index 6b79685f..17d75c9c 100644 --- a/lib/src/models/config/toolbar/buttons/font_family.dart +++ b/lib/src/models/config/toolbar/buttons/font_family.dart @@ -55,6 +55,7 @@ class QuillToolbarFontFamilyButtonOptions extends QuillToolbarBaseButtonOptions< this.hoverElevation = 1, this.fillColor, this.iconSize, + this.iconButtonFactor, }); final Color? fillColor; @@ -82,6 +83,7 @@ class QuillToolbarFontFamilyButtonOptions extends QuillToolbarBaseButtonOptions< /// By default will use [globalIconSize] final double? iconSize; + final double? iconButtonFactor; QuillToolbarFontFamilyButtonOptions copyWith({ Color? fillColor, @@ -102,6 +104,7 @@ class QuillToolbarFontFamilyButtonOptions extends QuillToolbarBaseButtonOptions< EdgeInsets? itemPadding, Color? defaultItemColor, double? iconSize, + double? iconButtonFactor, // Add properties to override inherited properties QuillController? controller, IconData? iconData, @@ -130,6 +133,7 @@ class QuillToolbarFontFamilyButtonOptions extends QuillToolbarBaseButtonOptions< itemPadding: itemPadding ?? this.itemPadding, defaultItemColor: defaultItemColor ?? this.defaultItemColor, iconSize: iconSize ?? this.iconSize, + iconButtonFactor: iconButtonFactor ?? this.iconButtonFactor, fillColor: fillColor ?? this.fillColor, hoverElevation: hoverElevation ?? this.hoverElevation, highlightElevation: highlightElevation ?? this.highlightElevation, diff --git a/lib/src/models/config/toolbar/buttons/font_size.dart b/lib/src/models/config/toolbar/buttons/font_size.dart index e9d4d5e7..651ad350 100644 --- a/lib/src/models/config/toolbar/buttons/font_size.dart +++ b/lib/src/models/config/toolbar/buttons/font_size.dart @@ -30,6 +30,7 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions< QuillToolbarFontSizeButtonOptions, QuillToolbarFontSizeButtonExtraOptions> { const QuillToolbarFontSizeButtonOptions({ this.iconSize, + this.iconButtonFactor, this.fillColor, this.hoverElevation = 1, this.highlightElevation = 1, @@ -53,6 +54,7 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions< }); final double? iconSize; + final double? iconButtonFactor; final Color? fillColor; final double hoverElevation; final double highlightElevation; @@ -75,6 +77,7 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions< QuillToolbarFontSizeButtonOptions copyWith({ double? iconSize, + double? iconButtonFactor, Color? fillColor, double? hoverElevation, double? highlightElevation, @@ -97,6 +100,7 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions< }) { return QuillToolbarFontSizeButtonOptions( iconSize: iconSize ?? this.iconSize, + iconButtonFactor: iconButtonFactor ?? this.iconButtonFactor, fillColor: fillColor ?? this.fillColor, hoverElevation: hoverElevation ?? this.hoverElevation, highlightElevation: highlightElevation ?? this.highlightElevation, diff --git a/lib/src/widgets/toolbar/buttons/clear_format.dart b/lib/src/widgets/toolbar/buttons/clear_format.dart index 9e1b27c7..65f4d9dd 100644 --- a/lib/src/widgets/toolbar/buttons/clear_format.dart +++ b/lib/src/widgets/toolbar/buttons/clear_format.dart @@ -90,6 +90,7 @@ class QuillToolbarClearFormatButton extends StatelessWidget { controller: controller, iconData: iconData, iconSize: iconSize, + iconButtonFactor: iconButtonFactor, iconTheme: iconTheme, tooltip: tooltip, ), diff --git a/lib/src/widgets/toolbar/buttons/font_size.dart b/lib/src/widgets/toolbar/buttons/font_size.dart index a6ddf7e8..e58340d0 100644 --- a/lib/src/widgets/toolbar/buttons/font_size.dart +++ b/lib/src/widgets/toolbar/buttons/font_size.dart @@ -110,6 +110,13 @@ class QuillToolbarFontSizeButtonState return iconSize ?? baseFontSize; } + double get iconButtonFactor { + final baseIconFactor = + context.requireQuillToolbarBaseButtonOptions.globalIconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor; + } + VoidCallback? get afterButtonPressed { return options.afterButtonPressed ?? context.requireQuillToolbarBaseButtonOptions.afterButtonPressed; @@ -142,6 +149,7 @@ class QuillToolbarFontSizeButtonState options.copyWith( tooltip: tooltip, iconSize: iconSize, + iconButtonFactor: iconButtonFactor, iconTheme: iconTheme, afterButtonPressed: afterButtonPressed, controller: controller, diff --git a/lib/src/widgets/toolbar/buttons/history.dart b/lib/src/widgets/toolbar/buttons/history.dart index e0c3f7cf..e12b3f1b 100644 --- a/lib/src/widgets/toolbar/buttons/history.dart +++ b/lib/src/widgets/toolbar/buttons/history.dart @@ -76,6 +76,7 @@ class QuillToolbarHistoryButtonState extends State { controller: controller, iconData: iconData, iconSize: iconSize, + iconButtonFactor: iconButtonFactor, iconTheme: iconTheme, tooltip: tooltip, ), diff --git a/lib/src/widgets/toolbar/buttons/indent.dart b/lib/src/widgets/toolbar/buttons/indent.dart index 9f3de303..e28b4239 100644 --- a/lib/src/widgets/toolbar/buttons/indent.dart +++ b/lib/src/widgets/toolbar/buttons/indent.dart @@ -88,6 +88,7 @@ class QuillToolbarIndentButtonState extends State { afterButtonPressed: afterButtonPressed, iconData: iconData, iconSize: iconSize, + iconButtonFactor: iconButtonFactor, iconTheme: iconTheme, tooltip: tooltip, ), diff --git a/lib/src/widgets/toolbar/buttons/link_style.dart b/lib/src/widgets/toolbar/buttons/link_style.dart index e96aabb8..db41dc53 100644 --- a/lib/src/widgets/toolbar/buttons/link_style.dart +++ b/lib/src/widgets/toolbar/buttons/link_style.dart @@ -120,6 +120,7 @@ class QuillToolbarLinkStyleButtonState dialogTheme: options.dialogTheme, iconData: iconData, iconSize: iconSize, + iconButtonFactor: iconButtonFactor, tooltip: tooltip, linkDialogAction: options.linkDialogAction, linkRegExp: linkRegExp, diff --git a/lib/src/widgets/toolbar/buttons/link_style2.dart b/lib/src/widgets/toolbar/buttons/link_style2.dart index 0ddf8f2f..fd5e2422 100644 --- a/lib/src/widgets/toolbar/buttons/link_style2.dart +++ b/lib/src/widgets/toolbar/buttons/link_style2.dart @@ -125,6 +125,7 @@ class _QuillToolbarLinkStyleButton2State dialogBarrierColor: dialogBarrierColor, dialogTheme: options.dialogTheme, iconSize: iconSize, + iconButtonFactor: iconButtonFactor, constraints: options.constraints, tooltip: tooltip, iconTheme: iconTheme, diff --git a/lib/src/widgets/toolbar/buttons/search/search.dart b/lib/src/widgets/toolbar/buttons/search/search.dart index 2bfaeb38..500e56f5 100644 --- a/lib/src/widgets/toolbar/buttons/search/search.dart +++ b/lib/src/widgets/toolbar/buttons/search/search.dart @@ -89,10 +89,11 @@ class QuillToolbarSearchButton extends StatelessWidget { dialogBarrierColor: _dialogBarrierColor(context), dialogTheme: _dialogTheme(context), fillColor: options.fillColor, - iconData: _iconData(context), - iconSize: _iconSize(context), - tooltip: _tooltip(context), - iconTheme: _iconTheme(context), + iconData: iconData, + iconSize: iconSize, + iconButtonFactor: iconButtonFactor, + tooltip: tooltip, + iconTheme: iconTheme, ), QuillToolbarSearchButtonExtraOptions( controller: controller, diff --git a/lib/src/widgets/toolbar/buttons/select_alignment.dart b/lib/src/widgets/toolbar/buttons/select_alignment.dart index 6104f9a1..3418aeb4 100644 --- a/lib/src/widgets/toolbar/buttons/select_alignment.dart +++ b/lib/src/widgets/toolbar/buttons/select_alignment.dart @@ -214,6 +214,7 @@ class QuillToolbarSelectAlignmentButtonState QuillToolbarSelectAlignmentButtonOptions( afterButtonPressed: _afterButtonPressed, iconSize: _iconSize, + iconButtonFactor: _iconButtonFactor, iconTheme: _iconTheme, tooltips: _tooltips, iconsData: _iconsData, diff --git a/lib/src/widgets/toolbar/buttons/select_header_style.dart b/lib/src/widgets/toolbar/buttons/select_header_style.dart index 3795d1dd..865a619d 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style.dart @@ -132,6 +132,7 @@ class QuillToolbarSelectHeaderStyleButtonsState attributes: _attrbuites, axis: axis, iconSize: iconSize, + iconButtonFactor: iconButtonFactor, iconTheme: iconTheme, tooltip: tooltip, ), diff --git a/lib/src/widgets/toolbar/buttons/toggle_check_list.dart b/lib/src/widgets/toolbar/buttons/toggle_check_list.dart index 18a65aea..b1555877 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_check_list.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_check_list.dart @@ -135,6 +135,7 @@ class QuillToolbarToggleCheckListButtonState iconTheme: iconTheme, controller: controller, iconSize: iconSize, + iconButtonFactor: iconButtonFactor, tooltip: tooltip, iconData: iconData, ), From 1895de62a09b8c78a1e398428ee7aed90e546300 Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Thu, 9 Nov 2023 03:41:47 +0000 Subject: [PATCH 090/210] chore: temp dependency_overrides to pass analysis --- flutter_quill_extensions/pubspec.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 97cd2782..91ab0a48 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -46,6 +46,10 @@ dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^3.0.1 + +dependency_overrides: + flutter_quill: + path: ../ flutter: uses-material-design: true \ No newline at end of file From f6e238fd784cd18a949344cd406bfd2bb5a5ccfd Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Thu, 9 Nov 2023 03:44:54 +0000 Subject: [PATCH 091/210] Revert "chore: temp dependency_overrides to pass analysis" This reverts commit 6398a998d0f3c6e5f50117912d5a099ebcd57b56. --- flutter_quill_extensions/pubspec.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 91ab0a48..906fa828 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -47,9 +47,9 @@ dev_dependencies: sdk: flutter flutter_lints: ^3.0.1 -dependency_overrides: - flutter_quill: - path: ../ - +# dependency_overrides: +# flutter_quill: +# path: ../ + flutter: uses-material-design: true \ No newline at end of file From a27620950f36456b832cd61d120bb9c343882e8b Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Thu, 9 Nov 2023 03:48:26 +0000 Subject: [PATCH 092/210] chore: bump flutter_quill_extensions --- flutter_quill_extensions/CHANGELOG.md | 3 +++ flutter_quill_extensions/pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 3d352da1..e6116111 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.6.5 +- Support the new `iconButtonFactor` property + ## 0.6.4 - Update `QuillImageUtilities` - Add new extension on `QuillController` to access `QuillImageUtilities` instance easier diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 906fa828..f9c6dc7d 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 0.6.3 +version: 0.6.5 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions From 4b1e5d30783c4b224f423f93c129debc7059c47c Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Thu, 9 Nov 2023 12:08:28 +0000 Subject: [PATCH 093/210] chore: revert adding dependency_overrides to pubspec.yaml --- flutter_quill_extensions/pubspec.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index f9c6dc7d..3df390cd 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -47,9 +47,5 @@ dev_dependencies: sdk: flutter flutter_lints: ^3.0.1 -# dependency_overrides: -# flutter_quill: -# path: ../ - flutter: uses-material-design: true \ No newline at end of file From b6b756535a3f8d9ed9b254708d5e1474e5ea5164 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Thu, 9 Nov 2023 19:44:34 +0300 Subject: [PATCH 094/210] Update flutter_quill_extensions --- .pubignore | 3 +++ flutter_quill_extensions/.pubignore | 3 +++ flutter_quill_extensions/CHANGELOG.md | 4 +--- flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/.pubignore | 3 +++ scripts/disable_local_dev.sh | 8 +++++--- scripts/enable_local_dev.sh | 8 +++++--- 7 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 .pubignore create mode 100644 flutter_quill_extensions/.pubignore create mode 100644 flutter_quill_test/.pubignore diff --git a/.pubignore b/.pubignore new file mode 100644 index 00000000..92959320 --- /dev/null +++ b/.pubignore @@ -0,0 +1,3 @@ +# For local development +pubspec_overrides.yaml +pubspec_overrides.yaml.g \ No newline at end of file diff --git a/flutter_quill_extensions/.pubignore b/flutter_quill_extensions/.pubignore new file mode 100644 index 00000000..92959320 --- /dev/null +++ b/flutter_quill_extensions/.pubignore @@ -0,0 +1,3 @@ +# For local development +pubspec_overrides.yaml +pubspec_overrides.yaml.g \ No newline at end of file diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index e6116111..baf0e9e3 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,9 +1,7 @@ -## 0.6.5 -- Support the new `iconButtonFactor` property - ## 0.6.4 - Update `QuillImageUtilities` - Add new extension on `QuillController` to access `QuillImageUtilities` instance easier +- Support the new `iconButtonFactor` property ## 0.6.3 - Update `README.md` diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 3df390cd..03a3d162 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 0.6.5 +version: 0.6.4 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions diff --git a/flutter_quill_test/.pubignore b/flutter_quill_test/.pubignore new file mode 100644 index 00000000..92959320 --- /dev/null +++ b/flutter_quill_test/.pubignore @@ -0,0 +1,3 @@ +# For local development +pubspec_overrides.yaml +pubspec_overrides.yaml.g \ No newline at end of file diff --git a/scripts/disable_local_dev.sh b/scripts/disable_local_dev.sh index b0d80b57..def60bbb 100755 --- a/scripts/disable_local_dev.sh +++ b/scripts/disable_local_dev.sh @@ -1,18 +1,20 @@ #!/bin/bash +# Please make sure to run this script in the root directory of the repository and not inside sub-folders + echo "" -echo "Disable local development for flutter_quill:" +echo "Disable local development for flutter_quill..." rm pubspec_overrides.yaml echo "" -echo "Enable local development for flutter_quill_extensions:" +echo "Enable local development for flutter_quill_extensions..." rm flutter_quill_extensions/pubspec_overrides.yaml echo "" -echo "Enable local development for flutter_quill_test:" +echo "Enable local development for flutter_quill_test..." rm flutter_quill_test/pubspec_overrides.yaml echo "" diff --git a/scripts/enable_local_dev.sh b/scripts/enable_local_dev.sh index adafd237..6e2fda39 100755 --- a/scripts/enable_local_dev.sh +++ b/scripts/enable_local_dev.sh @@ -1,18 +1,20 @@ #!/bin/bash +# Please make sure to run this script in the root directory of the repository and not inside sub-folders + echo "" -echo "Enable local development for flutter_quill:" +echo "Enable local development for flutter_quill..." cp pubspec_overrides.yaml.g pubspec_overrides.yaml echo "" -echo "Enable local development for flutter_quill_extensions:" +echo "Enable local development for flutter_quill_extensions..." cp flutter_quill_extensions/pubspec_overrides.yaml.g flutter_quill_extensions/pubspec_overrides.yaml echo "" -echo "Enable local development for flutter_quill_test:" +echo "Enable local development for flutter_quill_test..." cp flutter_quill_test/pubspec_overrides.yaml.g flutter_quill_test/pubspec_overrides.yaml echo "" From 905512e8e44bfa7c330c64afbca4c2e1982c34e3 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Thu, 9 Nov 2023 23:34:04 +0300 Subject: [PATCH 095/210] Update CONTRIBUTING.md 1. Fix typo 2. Fix some steps 3. Correct the number order --- doc/CONTRIBUTING.md | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/doc/CONTRIBUTING.md b/doc/CONTRIBUTING.md index f6f8d9d9..fbbbf649 100644 --- a/doc/CONTRIBUTING.md +++ b/doc/CONTRIBUTING.md @@ -8,7 +8,7 @@ This page will be updated in the future. ## Steps to contributing -You will need GitHub account as well as git installed and configured with your GitHub account on your machine +You will need a GitHub account as well as Git installed and configured with your GitHub account on your machine 1. Fork the repository in GitHub 2. clone the forked repository using `git` @@ -16,45 +16,44 @@ You will need GitHub account as well as git installed and configured with your G ``` git remote add upstream git@github.com:singerdmx/flutter-quill.git ``` -4. Open the project with your favorite IDE, we suggest using [IntelliJ IDEA Community Edition](https://www.jetbrains.com/idea/download/) -5. Sync the project with Gradle -6. Create a new git branch and switch to it using: +4. Open the project with your favorite IDE, usually, we prefer to use Jetbrains IDEs, but since [VS Code](https://code.visualstudio.com) is more used and has more support for Dart, then we suggest using it if you want to. +5. Create a new git branch and switch to it using: ``` git checkout -b your-branch-name ``` The `your-branch-name` is your choice -7. Make your changes -8. If you are working on changes that depend on different library in the same repo, then in that directory copy `pubspec_overrides.yaml.g` which exists in all the libraries (`flutter_quill_test` and `flutter_quill_extensions` etc..) -to `pubspec_overrides.yaml` which will be ignored by `.gitignore` and it will be used by dart pub to override the libraries +6. Make your changes +7. If you are working on changes that depend on different libraries in the same repo, then in that directory copy `pubspec_overrides.yaml.g` which exists in all the libraries (`flutter_quill_test` and `flutter_quill_extensions` etc..) +to `pubspec_overrides.yaml` which will be ignored by `.gitignore` and will be used by dart pub to override the libraries ``` cp pubspec_overrides.yaml.g pubspec_overrides.yaml ``` - or save some time and the following script: + or save some time with the following script: ``` ./scripts/enable_local_dev.sh ``` -10. Test them in the [example](../example) and add changes in there if necessary -11. Mention the new changes in the [CHANGELOG.md](../CHANGELOG.md) in the next block -12. Run the following script if possible +8. Test them in the [example](../example) and add changes in there if necessary +9. Mention the new changes in the [CHANGELOG.md](../CHANGELOG.md) in the next block +10. Run the following script if possible ``` ./scripts/before-push.sh ``` -13. When you are done to send your pull request, run: +11. When you are done sending your pull request, run: ``` git add . git commit -m "Your commit message" git push origin your-branch-name ``` this will push the new branch to your forked repository -14. Now you can send your pull request either by following the link that you will get in the command line or open your +12. Now you can send your pull request either by following the link that you will get in the command line or open your forked repository, and you will find an option to send the pull request, you can also open the [Pull Requests](https://github.com/singerdmx/flutter-quill) tab and send new pull request -1. Please wait for the review, and we might ask you to make more changes, then run: +13. Please wait for the review, and we might ask you to make more changes, then run: ``` git add . git commit -m "Your new commit message" git push origin your-branch-name ``` -Thank you for your time and efforts to this open-source community project!! \ No newline at end of file +Thank you for your time and efforts in this open-source community project!! From e7e71f1cb2824d92da03a34fc3f15a33e5c35a0d Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Fri, 10 Nov 2023 01:29:37 +0300 Subject: [PATCH 096/210] Update QuillCustomButton (#1517) * Update QuillCustomButton * Update README.md --- CHANGELOG.md | 6 ++ README.md | 34 +++---- example/lib/pages/home_page.dart | 23 +++++ flutter_quill_test/CHANGELOG.md | 3 + flutter_quill_test/pubspec.yaml | 2 +- .../config/toolbar/base_configurations.dart | 3 +- .../config/toolbar/buttons/custom_button.dart | 32 ++++++ .../models/config/toolbar/configurations.dart | 10 +- .../models/themes/quill_custom_button.dart | 38 ++++---- .../toolbar/buttons/custom_button.dart | 97 ++++++++++++++----- lib/src/widgets/toolbar/toolbar.dart | 71 ++++++++------ pubspec.yaml | 2 +- test/bug_fix_test.dart | 8 +- 13 files changed, 227 insertions(+), 102 deletions(-) create mode 100644 lib/src/models/config/toolbar/buttons/custom_button.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index a2a037c6..2c73ec2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [8.4.0] +- **Breaking change**: Update the `QuillCustomButton` to have `QuillCustomButtonOptions`. We moved everything that is in the `QuillCustomButton` to `QuillCustomButtonOptions` but replaced the `iconData` with `icon` widget for more customizations +- **Breaking change**: the `customButtons` in the `QuillToolbarConfigurations` is now of type `List` +- Bug fixes with the new `8.0.0` update +- Update `README.md` + ## [8.3.0] - Added a `iconButtonFactor` property to `QuillToolbarBaseButtonOptions` to customise how big the button is compared to its icon size (defaults to `kIconButtonFactor` which is the same as previous releases) diff --git a/README.md b/README.md index 7d2892e2..9bc98324 100644 --- a/README.md +++ b/README.md @@ -199,17 +199,17 @@ To use your own fonts, update your [assets folder](https://github.com/singerdmx/ ### Custom Buttons -You may add custom buttons to the _end_ of the toolbar, via the `customButtons` option, which is a `List` of `QuillCustomButton`. +You may add custom buttons to the _end_ of the toolbar, via the `customButtons` option, which is a `List` of `QuillToolbarCustomButtonOptions`. -To add an Icon, we should use a new QuillCustomButton class +To add an Icon, we should use a new `QuillToolbarCustomButtonOptions` class ```dart - QuillCustomButton( - iconData: Icons.ac_unit, - onTap: () { - debugPrint('snowflake'); - } - ), + QuillToolbarCustomButtonOptions( + icon: const Icon(Icons.ac_unit), + tooltip: '', + onPressed: () {}, + afterButtonPressed: () {}, + ), ``` Each `QuillCustomButton` is used as part of the `customButtons` option as follows: @@ -218,21 +218,21 @@ Each `QuillCustomButton` is used as part of the `customButtons` option as follow QuillToolbar( configurations: QuillToolbarConfigurations( customButtons: [ - QuillCustomButton( - iconData: Icons.ac_unit, - onTap: () { + QuillToolbarCustomButtonOptions( + icon: const Icon(Icons.ac_unit), + onPressed: () { debugPrint('snowflake1'); }, ), - QuillCustomButton( - iconData: Icons.ac_unit, - onTap: () { + QuillToolbarCustomButtonOptions( + icon: const Icon(Icons.ac_unit), + onPressed: () { debugPrint('snowflake2'); }, ), - QuillCustomButton( - iconData: Icons.ac_unit, - onTap: () { + QuillToolbarCustomButtonOptions( + icon: const Icon(Icons.ac_unit), + onPressed: () { debugPrint('snowflake3'); }, ), diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index a1c71d06..538e8f40 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -457,9 +457,30 @@ class _HomePageState extends State { } QuillToolbar get quillToolbar { + final customButtons = [ + QuillToolbarCustomButtonOptions( + icon: const Icon(Icons.ac_unit), + onPressed: () { + debugPrint('snowflake1'); + }, + ), + QuillToolbarCustomButtonOptions( + icon: const Icon(Icons.ac_unit), + onPressed: () { + debugPrint('snowflake2'); + }, + ), + QuillToolbarCustomButtonOptions( + icon: const Icon(Icons.ac_unit), + onPressed: () { + debugPrint('snowflake3'); + }, + ), + ]; if (kIsWeb) { return QuillToolbar( configurations: QuillToolbarConfigurations( + customButtons: customButtons, embedButtons: FlutterQuillEmbeds.toolbarButtons( imageButtonOptions: QuillToolbarImageButtonOptions( imageButtonConfigurations: QuillToolbarImageConfigurations( @@ -482,6 +503,7 @@ class _HomePageState extends State { if (isDesktop()) { return QuillToolbar( configurations: QuillToolbarConfigurations( + customButtons: customButtons, embedButtons: FlutterQuillEmbeds.toolbarButtons( imageButtonOptions: QuillToolbarImageButtonOptions( imageButtonConfigurations: QuillToolbarImageConfigurations( @@ -502,6 +524,7 @@ class _HomePageState extends State { } return QuillToolbar( configurations: QuillToolbarConfigurations( + customButtons: customButtons, embedButtons: FlutterQuillEmbeds.toolbarButtons( videoButtonOptions: QuillToolbarVideoButtonOptions( videoConfigurations: QuillToolbarVideoConfigurations( diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index ac01b9bc..60aa40e3 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.0.4+1 +* Update `README.md` + ## 0.0.4 * Update `README.md` * Documentation comments. diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 1cb77744..8fa7094e 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 0.0.4 +version: 0.0.4+1 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test diff --git a/lib/src/models/config/toolbar/base_configurations.dart b/lib/src/models/config/toolbar/base_configurations.dart index 132fdc8d..1c4d1ff3 100644 --- a/lib/src/models/config/toolbar/base_configurations.dart +++ b/lib/src/models/config/toolbar/base_configurations.dart @@ -4,7 +4,6 @@ import 'package:flutter/widgets.dart' import '../../../widgets/toolbar/base_toolbar.dart'; import '../../structs/link_dialog_action.dart'; -import '../../themes/quill_custom_button.dart'; @immutable class QuillBaseToolbarConfigurations extends Equatable { @@ -41,7 +40,7 @@ class QuillBaseToolbarConfigurations extends Equatable { final Color? color; /// List of custom buttons - final List customButtons; + final List customButtons; /// The color to use when painting the toolbar section divider. /// diff --git a/lib/src/models/config/toolbar/buttons/custom_button.dart b/lib/src/models/config/toolbar/buttons/custom_button.dart new file mode 100644 index 00000000..9a862e83 --- /dev/null +++ b/lib/src/models/config/toolbar/buttons/custom_button.dart @@ -0,0 +1,32 @@ +import 'package:flutter/widgets.dart' show VoidCallback, Widget; + +import 'base.dart'; + +class QuillToolbarCustomButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarCustomButtonExtraOptions({ + required super.controller, + required super.context, + required super.onPressed, + }); +} + +class QuillToolbarCustomButtonOptions extends QuillToolbarBaseButtonOptions< + QuillToolbarBaseButtonOptions, QuillToolbarCustomButtonExtraOptions> { + const QuillToolbarCustomButtonOptions({ + this.icon, + this.iconButtonFactor, + this.iconSize, + super.afterButtonPressed, + super.tooltip, + super.iconTheme, + super.childBuilder, + super.controller, + this.onPressed, + }); + + final double? iconButtonFactor; + final double? iconSize; + final VoidCallback? onPressed; + final Widget? icon; +} diff --git a/lib/src/models/config/toolbar/configurations.dart b/lib/src/models/config/toolbar/configurations.dart index 00412042..c609cd80 100644 --- a/lib/src/models/config/toolbar/configurations.dart +++ b/lib/src/models/config/toolbar/configurations.dart @@ -2,15 +2,15 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' show Axis, Color, Decoration, Widget, WrapAlignment, WrapCrossAlignment; -import '../../../widgets/embeds.dart'; +import '../../../widgets/embeds.dart'; import '../../structs/link_dialog_action.dart'; -import '../../themes/quill_custom_button.dart'; import '../../themes/quill_dialog_theme.dart'; import '../../themes/quill_icon_theme.dart'; import 'buttons/base.dart'; import 'buttons/clear_format.dart'; import 'buttons/color.dart'; +import 'buttons/custom_button.dart'; import 'buttons/font_family.dart'; import 'buttons/font_size.dart'; import 'buttons/history.dart'; @@ -26,6 +26,7 @@ export './../../../widgets/toolbar/buttons/search/search_dialog.dart'; export './buttons/base.dart'; export './buttons/clear_format.dart'; export './buttons/color.dart'; +export './buttons/custom_button.dart'; export './buttons/font_family.dart'; export './buttons/font_size.dart'; export './buttons/history.dart'; @@ -211,7 +212,7 @@ class QuillToolbarConfigurations extends Equatable { final bool showSearchButton; final bool showSubscript; final bool showSuperscript; - final List customButtons; + final List customButtons; /// The decoration to use for the toolbar. final Decoration? decoration; @@ -284,6 +285,7 @@ class QuillToolbarButtonOptions extends Equatable { this.selectHeaderStyleButtons = const QuillToolbarSelectHeaderStyleButtonsOptions(), this.linkStyle = const QuillToolbarLinkStyleButtonOptions(), + this.customButtons = const QuillToolbarCustomButtonOptions(), }); /// The base configurations for all the buttons which will apply to all @@ -329,6 +331,8 @@ class QuillToolbarButtonOptions extends Equatable { final QuillToolbarLinkStyleButtonOptions linkStyle; + final QuillToolbarCustomButtonOptions customButtons; + @override List get props => [ base, diff --git a/lib/src/models/themes/quill_custom_button.dart b/lib/src/models/themes/quill_custom_button.dart index da1eb06d..111ab13e 100644 --- a/lib/src/models/themes/quill_custom_button.dart +++ b/lib/src/models/themes/quill_custom_button.dart @@ -1,26 +1,22 @@ -import 'package:flutter/material.dart'; +// import 'package:flutter/material.dart'; -import '../../widgets/toolbar/base_toolbar.dart'; +// import '../../widgets/toolbar/base_toolbar.dart'; -class QuillCustomButton extends QuillToolbarBaseButtonOptions { - const QuillCustomButton({ - super.iconData, - this.iconColor, - this.onTap, - super.tooltip, - this.iconSize, - this.child, - super.iconTheme, - }); +// class QuillCustomButton extends QuillToolbarBaseButtonOptions { +// const QuillCustomButton({ +// this.icon, +// this.onTap, +// super.tooltip, +// this.child, +// super.iconTheme, +// }); - ///The icon color; - final Color? iconColor; +// /// The icon widget +// final Widget? icon; - ///The function when the icon is tapped - final VoidCallback? onTap; +// /// The function when the icon is tapped +// final VoidCallback? onTap; - ///The customButton placeholder - final Widget? child; - - final double? iconSize; -} +// /// The customButton placeholder +// final Widget? child; +// } diff --git a/lib/src/widgets/toolbar/buttons/custom_button.dart b/lib/src/widgets/toolbar/buttons/custom_button.dart index 741a6e7e..0d736a10 100644 --- a/lib/src/widgets/toolbar/buttons/custom_button.dart +++ b/lib/src/widgets/toolbar/buttons/custom_button.dart @@ -1,43 +1,92 @@ import 'package:flutter/material.dart'; import '../../../models/themes/quill_icon_theme.dart'; +import '../../../utils/extensions/build_context.dart'; +import '../../controller.dart'; import '../base_toolbar.dart'; -class CustomButton extends StatelessWidget { - const CustomButton({ - required this.onPressed, - required this.icon, - this.iconColor, - this.iconSize = kDefaultIconSize, - this.iconButtonFactor = kIconButtonFactor, - this.iconTheme, - this.afterButtonPressed, - this.tooltip, +class QuillToolbarCustomButton extends StatelessWidget { + const QuillToolbarCustomButton({ + required this.options, + required this.controller, super.key, }); - final VoidCallback? onPressed; - final IconData? icon; - final Color? iconColor; - final double iconSize; - final double iconButtonFactor; - final QuillIconTheme? iconTheme; - final VoidCallback? afterButtonPressed; - final String? tooltip; + final QuillController controller; + final QuillToolbarCustomButtonOptions options; + + double _iconSize(BuildContext context) { + final baseFontSize = baseButtonExtraOptions(context).globalIconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize; + } + + double _iconButtonFactor(BuildContext context) { + final baseIconFactor = + baseButtonExtraOptions(context).globalIconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor; + } + + VoidCallback? _afterButtonPressed(BuildContext context) { + return options.afterButtonPressed ?? + baseButtonExtraOptions(context).afterButtonPressed; + } + + QuillIconTheme? _iconTheme(BuildContext context) { + return options.iconTheme ?? baseButtonExtraOptions(context).iconTheme; + } + + QuillToolbarBaseButtonOptions baseButtonExtraOptions(BuildContext context) { + return context.requireQuillToolbarBaseButtonOptions; + } + + String? _tooltip(BuildContext context) { + return options.tooltip ?? baseButtonExtraOptions(context).tooltip; + } + + void _onPressed(BuildContext context) { + options.onPressed?.call(); + _afterButtonPressed(context)?.call(); + } @override Widget build(BuildContext context) { - final theme = Theme.of(context); + final iconTheme = _iconTheme(context); + final tooltip = _tooltip(context); + final iconSize = _iconSize(context); + final iconButtonFactor = _iconButtonFactor(context); + + final childBuilder = + options.childBuilder ?? baseButtonExtraOptions(context).childBuilder; + final afterButtonPressed = _afterButtonPressed(context); - final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; + if (childBuilder != null) { + return childBuilder( + QuillToolbarCustomButtonOptions( + iconButtonFactor: iconButtonFactor, + iconSize: iconSize, + afterButtonPressed: afterButtonPressed, + controller: controller, + iconTheme: iconTheme, + tooltip: tooltip, + icon: options.icon, + ), + QuillToolbarCustomButtonExtraOptions( + context: context, + controller: controller, + onPressed: () => _onPressed(context), + ), + ); + } + + final theme = Theme.of(context); return QuillToolbarIconButton( - highlightElevation: 0, - hoverElevation: 0, size: iconSize * iconButtonFactor, - icon: Icon(icon, size: iconSize, color: iconColor), + icon: options.icon, tooltip: tooltip, borderRadius: iconTheme?.borderRadius ?? 2, - onPressed: onPressed, + onPressed: () => _onPressed(context), afterPressed: afterButtonPressed, fillColor: iconTheme?.iconUnselectedFillColor ?? theme.canvasColor, ); diff --git a/lib/src/widgets/toolbar/toolbar.dart b/lib/src/widgets/toolbar/toolbar.dart index 6749f0b5..1361e550 100644 --- a/lib/src/widgets/toolbar/toolbar.dart +++ b/lib/src/widgets/toolbar/toolbar.dart @@ -59,8 +59,6 @@ class QuillToolbar extends StatelessWidget { sectionDividerSpace: configurations.sectionDividerSpace, toolbarSize: configurations.toolbarSize, childrenBuilder: (context) { - final controller = context.requireQuillController; - final toolbarConfigurations = context.requireQuillToolbarConfigurations; @@ -192,7 +190,9 @@ class QuillToolbar extends StatelessWidget { ], if (configurations.showColorButton) ...[ QuillToolbarColorButton( - controller: controller, + controller: + toolbarConfigurations.buttonOptions.color.controller ?? + globalController, isBackground: false, options: toolbarConfigurations.buttonOptions.color, ), @@ -201,14 +201,18 @@ class QuillToolbar extends StatelessWidget { if (configurations.showBackgroundColorButton) ...[ QuillToolbarColorButton( options: toolbarConfigurations.buttonOptions.backgroundColor, - controller: controller, + controller: + toolbarConfigurations.buttonOptions.color.controller ?? + globalController, isBackground: true, ), spacerWidget, ], if (configurations.showClearFormat) ...[ QuillToolbarClearFormatButton( - controller: controller, + controller: toolbarConfigurations + .buttonOptions.clearFormat.controller ?? + globalController, options: toolbarConfigurations.buttonOptions.clearFormat, ), spacerWidget, @@ -216,7 +220,7 @@ class QuillToolbar extends StatelessWidget { if (theEmbedButtons != null) for (final builder in theEmbedButtons) builder( - controller, + globalController, globalIconSize, context.requireQuillToolbarBaseButtonOptions.iconTheme, configurations.dialogTheme), @@ -234,7 +238,9 @@ class QuillToolbar extends StatelessWidget { ), if (configurations.showAlignmentButtons) ...[ QuillToolbarSelectAlignmentButton( - controller: controller, + controller: toolbarConfigurations + .buttonOptions.selectAlignmentButtons.controller ?? + globalController, options: toolbarConfigurations .buttonOptions.selectAlignmentButtons, // tooltips: Map.of(buttonTooltips) @@ -274,7 +280,9 @@ class QuillToolbar extends StatelessWidget { ), if (configurations.showHeaderStyle) ...[ QuillToolbarSelectHeaderStyleButtons( - controller: controller, + controller: toolbarConfigurations + .buttonOptions.selectHeaderStyleButtons.controller ?? + globalController, options: toolbarConfigurations .buttonOptions.selectHeaderStyleButtons, ), @@ -379,14 +387,18 @@ class QuillToolbar extends StatelessWidget { ), if (configurations.showLink) ...[ QuillToolbarLinkStyleButton( - controller: controller, + controller: toolbarConfigurations + .buttonOptions.linkStyle.controller ?? + globalController, options: toolbarConfigurations.buttonOptions.linkStyle, ), spacerWidget, ], if (configurations.showSearchButton) ...[ QuillToolbarSearchButton( - controller: controller, + controller: + toolbarConfigurations.buttonOptions.search.controller ?? + globalController, options: toolbarConfigurations.buttonOptions.search, ), spacerWidget, @@ -399,27 +411,24 @@ class QuillToolbar extends StatelessWidget { space: configurations.sectionDividerSpace, ), for (final customButton in configurations.customButtons) - if (customButton.child != null) ...[ - InkWell( - onTap: customButton.onTap, - child: customButton.child, - ), - ] else ...[ - CustomButton( - onPressed: customButton.onTap, - icon: customButton.iconData ?? - context.quillToolbarBaseButtonOptions?.iconData, - iconColor: customButton.iconColor, - iconSize: customButton.iconSize ?? globalIconSize, - iconTheme: context - .requireQuillToolbarBaseButtonOptions.iconTheme, - afterButtonPressed: customButton.afterButtonPressed ?? - context.quillToolbarBaseButtonOptions - ?.afterButtonPressed, - tooltip: customButton.tooltip ?? - context.quillToolbarBaseButtonOptions?.tooltip, - ), - ], + QuillToolbarCustomButton( + options: customButton, + controller: customButton.controller ?? globalController, + ), + // if (customButton.child != null) ...[ + // InkWell( + // onTap: customButton.onTap, + // child: customButton.child, + // ), + // ] else ...[ + // QuillToolbarCustomButton( + // options: + // toolbarConfigurations.buttonOptions.customButtons, + // controller: toolbarConfigurations + // .buttonOptions.customButtons.controller ?? + // globalController, + // ), + // ], spacerWidget, ], ]; diff --git a/pubspec.yaml b/pubspec.yaml index 2eb967b1..8cbbdbc7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.3.0 +version: 8.4.0 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill diff --git a/test/bug_fix_test.dart b/test/bug_fix_test.dart index 041b7d2f..81849459 100644 --- a/test/bug_fix_test.dart +++ b/test/bug_fix_test.dart @@ -12,17 +12,21 @@ void main() { (tester) async { const tooltip = 'custom button'; + final controller = QuillController.basic(); + await tester.pumpWidget( MaterialApp( home: QuillProvider( configurations: QuillConfigurations( - controller: QuillController.basic(), + controller: controller, ), child: const QuillToolbar( configurations: QuillToolbarConfigurations( showRedo: false, customButtons: [ - QuillCustomButton(tooltip: tooltip), + QuillToolbarCustomButtonOptions( + tooltip: tooltip, + ) ], ), ), From 0632090f4407aa86bf0d447366feb38db306c62d Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Thu, 9 Nov 2023 20:11:33 +0300 Subject: [PATCH 097/210] Update QuillCustomButton --- .../models/themes/quill_custom_button.dart | 21 +++++++++++++++++++ .../toolbar/buttons/custom_button.dart | 1 + lib/src/widgets/toolbar/toolbar.dart | 17 +++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/lib/src/models/themes/quill_custom_button.dart b/lib/src/models/themes/quill_custom_button.dart index 111ab13e..eaac9d7b 100644 --- a/lib/src/models/themes/quill_custom_button.dart +++ b/lib/src/models/themes/quill_custom_button.dart @@ -2,6 +2,7 @@ // import '../../widgets/toolbar/base_toolbar.dart'; +<<<<<<< HEAD // class QuillCustomButton extends QuillToolbarBaseButtonOptions { // const QuillCustomButton({ // this.icon, @@ -20,3 +21,23 @@ // /// The customButton placeholder // final Widget? child; // } +======= +class QuillCustomButton extends QuillToolbarBaseButtonOptions { + const QuillCustomButton({ + this.icon, + this.onTap, + super.tooltip, + this.child, + super.iconTheme, + }); + + /// The icon widget + final Widget? icon; + + /// The function when the icon is tapped + final VoidCallback? onTap; + + /// The customButton placeholder + final Widget? child; +} +>>>>>>> ad642da (Update QuillCustomButton) diff --git a/lib/src/widgets/toolbar/buttons/custom_button.dart b/lib/src/widgets/toolbar/buttons/custom_button.dart index 0d736a10..c3e81077 100644 --- a/lib/src/widgets/toolbar/buttons/custom_button.dart +++ b/lib/src/widgets/toolbar/buttons/custom_button.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import '../../../models/config/toolbar/buttons/custom_button.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../../utils/extensions/build_context.dart'; import '../../controller.dart'; diff --git a/lib/src/widgets/toolbar/toolbar.dart b/lib/src/widgets/toolbar/toolbar.dart index 1361e550..6415969d 100644 --- a/lib/src/widgets/toolbar/toolbar.dart +++ b/lib/src/widgets/toolbar/toolbar.dart @@ -411,6 +411,7 @@ class QuillToolbar extends StatelessWidget { space: configurations.sectionDividerSpace, ), for (final customButton in configurations.customButtons) +<<<<<<< HEAD QuillToolbarCustomButton( options: customButton, controller: customButton.controller ?? globalController, @@ -429,6 +430,22 @@ class QuillToolbar extends StatelessWidget { // globalController, // ), // ], +======= + if (customButton.child != null) ...[ + InkWell( + onTap: customButton.onTap, + child: customButton.child, + ), + ] else ...[ + QuillToolbarCustomButton( + options: + toolbarConfigurations.buttonOptions.customButtons, + controller: toolbarConfigurations + .buttonOptions.customButtons.controller ?? + globalController, + ), + ], +>>>>>>> ad642da (Update QuillCustomButton) spacerWidget, ], ]; From 562f4c99e920da2d8c5200e869c0ad52c129ce20 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Thu, 9 Nov 2023 20:22:11 +0300 Subject: [PATCH 098/210] Fix test failures + New adjustments --- .../models/themes/quill_custom_button.dart | 43 ------------------- lib/src/widgets/toolbar/toolbar.dart | 17 -------- test/bug_fix_test.dart | 1 + 3 files changed, 1 insertion(+), 60 deletions(-) delete mode 100644 lib/src/models/themes/quill_custom_button.dart diff --git a/lib/src/models/themes/quill_custom_button.dart b/lib/src/models/themes/quill_custom_button.dart deleted file mode 100644 index eaac9d7b..00000000 --- a/lib/src/models/themes/quill_custom_button.dart +++ /dev/null @@ -1,43 +0,0 @@ -// import 'package:flutter/material.dart'; - -// import '../../widgets/toolbar/base_toolbar.dart'; - -<<<<<<< HEAD -// class QuillCustomButton extends QuillToolbarBaseButtonOptions { -// const QuillCustomButton({ -// this.icon, -// this.onTap, -// super.tooltip, -// this.child, -// super.iconTheme, -// }); - -// /// The icon widget -// final Widget? icon; - -// /// The function when the icon is tapped -// final VoidCallback? onTap; - -// /// The customButton placeholder -// final Widget? child; -// } -======= -class QuillCustomButton extends QuillToolbarBaseButtonOptions { - const QuillCustomButton({ - this.icon, - this.onTap, - super.tooltip, - this.child, - super.iconTheme, - }); - - /// The icon widget - final Widget? icon; - - /// The function when the icon is tapped - final VoidCallback? onTap; - - /// The customButton placeholder - final Widget? child; -} ->>>>>>> ad642da (Update QuillCustomButton) diff --git a/lib/src/widgets/toolbar/toolbar.dart b/lib/src/widgets/toolbar/toolbar.dart index 6415969d..1361e550 100644 --- a/lib/src/widgets/toolbar/toolbar.dart +++ b/lib/src/widgets/toolbar/toolbar.dart @@ -411,7 +411,6 @@ class QuillToolbar extends StatelessWidget { space: configurations.sectionDividerSpace, ), for (final customButton in configurations.customButtons) -<<<<<<< HEAD QuillToolbarCustomButton( options: customButton, controller: customButton.controller ?? globalController, @@ -430,22 +429,6 @@ class QuillToolbar extends StatelessWidget { // globalController, // ), // ], -======= - if (customButton.child != null) ...[ - InkWell( - onTap: customButton.onTap, - child: customButton.child, - ), - ] else ...[ - QuillToolbarCustomButton( - options: - toolbarConfigurations.buttonOptions.customButtons, - controller: toolbarConfigurations - .buttonOptions.customButtons.controller ?? - globalController, - ), - ], ->>>>>>> ad642da (Update QuillCustomButton) spacerWidget, ], ]; diff --git a/test/bug_fix_test.dart b/test/bug_fix_test.dart index 81849459..635b8dcc 100644 --- a/test/bug_fix_test.dart +++ b/test/bug_fix_test.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; +import 'package:flutter_quill/src/models/config/toolbar/buttons/custom_button.dart'; import 'package:flutter_quill_test/flutter_quill_test.dart'; import 'package:flutter_test/flutter_test.dart'; From a88678c0d50d8fcc8a3f926120f829a6eb3312c9 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+freshtechtips@users.noreply.github.com> Date: Thu, 9 Nov 2023 20:38:40 +0300 Subject: [PATCH 099/210] Update the example + Few more changes --- lib/flutter_quill.dart | 1 - lib/src/widgets/toolbar/buttons/custom_button.dart | 1 - test/bug_fix_test.dart | 1 - 3 files changed, 3 deletions(-) diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index a65afc7a..f70653ca 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -17,7 +17,6 @@ export 'src/models/structs/link_dialog_action.dart'; export 'src/models/structs/offset_value.dart'; export 'src/models/structs/optional_size.dart'; export 'src/models/structs/vertical_spacing.dart'; -export 'src/models/themes/quill_custom_button.dart'; export 'src/models/themes/quill_dialog_theme.dart'; export 'src/models/themes/quill_icon_theme.dart'; export 'src/utils/embeds.dart'; diff --git a/lib/src/widgets/toolbar/buttons/custom_button.dart b/lib/src/widgets/toolbar/buttons/custom_button.dart index c3e81077..0d736a10 100644 --- a/lib/src/widgets/toolbar/buttons/custom_button.dart +++ b/lib/src/widgets/toolbar/buttons/custom_button.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import '../../../models/config/toolbar/buttons/custom_button.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../../utils/extensions/build_context.dart'; import '../../controller.dart'; diff --git a/test/bug_fix_test.dart b/test/bug_fix_test.dart index 635b8dcc..81849459 100644 --- a/test/bug_fix_test.dart +++ b/test/bug_fix_test.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/src/models/config/toolbar/buttons/custom_button.dart'; import 'package:flutter_quill_test/flutter_quill_test.dart'; import 'package:flutter_test/flutter_test.dart'; From db406d4b019b2af709e3657e66c67cde0135b33b Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 10 Nov 2023 01:31:57 +0300 Subject: [PATCH 100/210] Update CHANGELOG and pubspec.yaml --- flutter_quill_test/CHANGELOG.md | 2 +- flutter_quill_test/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 60aa40e3..324c4355 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.0.4+1 +## 0.0.5 * Update `README.md` ## 0.0.4 diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 8fa7094e..daee56e5 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 0.0.4+1 +version: 0.0.5 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test From ebd2729f39603a39d6b93ffe36d145e4ac4e902c Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 10 Nov 2023 18:29:02 +0300 Subject: [PATCH 101/210] Fix platform checking logic (#1518) * Fix platform checking logic * Update _defaultOnTapOutside --- CHANGELOG.md | 1 + example/lib/pages/home_page.dart | 4 +- example/lib/pages/read_only_page.dart | 2 +- flutter_quill_extensions/CHANGELOG.md | 3 + .../embeds/editor/image/image.dart | 17 +- .../image_button/select_image_source.dart | 2 +- .../video_button/select_video_source.dart | 2 +- .../models/config/editor/image/image.dart | 10 +- lib/src/utils/platform.dart | 130 +++++++++++---- lib/src/widgets/cursor.dart | 2 +- lib/src/widgets/default_styles.dart | 2 +- lib/src/widgets/delegate.dart | 4 +- lib/src/widgets/editor/editor.dart | 23 ++- .../widgets/raw_editor/raw_editor_state.dart | 8 +- lib/src/widgets/text_line.dart | 6 +- pubspec.yaml | 1 + test/utils/platform_test.dart | 156 ++++++++++++++++++ test/widgets/controller_test.dart | 2 +- 18 files changed, 303 insertions(+), 72 deletions(-) create mode 100644 test/utils/platform_test.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c73ec2a..7dbb538f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - **Breaking change**: the `customButtons` in the `QuillToolbarConfigurations` is now of type `List` - Bug fixes with the new `8.0.0` update - Update `README.md` +- Improve the platform checking ## [8.3.0] - Added a `iconButtonFactor` property to `QuillToolbarBaseButtonOptions` to customise how big the button is compared to its icon size (defaults to `kIconButtonFactor` which is the same as previous releases) diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 538e8f40..379b4f2a 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -414,7 +414,7 @@ class _HomePageState extends State { placeholder: 'Add content', readOnly: _isReadOnly, autoFocus: false, - enableSelectionToolbar: isMobile(), + enableSelectionToolbar: isMobile(supportWeb: false), expands: false, padding: EdgeInsets.zero, onImagePaste: _onImagePaste, @@ -500,7 +500,7 @@ class _HomePageState extends State { // afterButtonPressed: _focusNode.requestFocus, ); } - if (isDesktop()) { + if (isDesktop(supportWeb: false)) { return QuillToolbar( configurations: QuillToolbarConfigurations( customButtons: customButtons, diff --git a/example/lib/pages/read_only_page.dart b/example/lib/pages/read_only_page.dart index 6f38741a..9670c152 100644 --- a/example/lib/pages/read_only_page.dart +++ b/example/lib/pages/read_only_page.dart @@ -23,7 +23,7 @@ class _ReadOnlyPageState extends State { @override Widget build(BuildContext context) { return DemoScaffold( - documentFilename: isDesktop() + documentFilename: isDesktop(supportWeb: false) ? 'assets/sample_data_nomedia.json' : 'sample_data_nomedia.json', builder: _buildContent, diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index baf0e9e3..2cb20ab3 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.6.5 +- Support the new improved platform checking of `flutter_quill` + ## 0.6.4 - Update `QuillImageUtilities` - Add new extension on `QuillController` to access `QuillImageUtilities` instance easier diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart index 0f40233a..7f3d6e94 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart @@ -41,7 +41,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { final style = node.style.attributes['style']; if (style != null) { - final attrs = base.isMobile() + final attrs = base.isMobile(supportWeb: false) ? base.parseKeyValuePairs(style.value.toString(), { Attribute.mobileWidth, Attribute.mobileHeight, @@ -56,21 +56,21 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { }); if (attrs.isNotEmpty) { final width = double.tryParse( - (base.isMobile() + (base.isMobile(supportWeb: false) ? attrs[Attribute.mobileWidth] : attrs[Attribute.width.key]) ?? '', ); final height = double.tryParse( - (base.isMobile() + (base.isMobile(supportWeb: false) ? attrs[Attribute.mobileHeight] : attrs[Attribute.height.key]) ?? '', ); - final alignment = base.getAlignment(base.isMobile() + final alignment = base.getAlignment(base.isMobile(supportWeb: false) ? attrs[Attribute.mobileAlignment] : attrs[Attribute.alignment]); - final margin = (base.isMobile() + final margin = (base.isMobile(supportWeb: false) ? double.tryParse(Attribute.mobileMargin) : double.tryParse(Attribute.margin)) ?? 0.0; @@ -106,7 +106,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { } if (!readOnly && - (base.isMobile() || + (base.isMobile(supportWeb: false) || configurations.forceUseMobileOptionMenuForImageClick)) { return GestureDetector( onTap: () { @@ -188,7 +188,8 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { getImageStyleString(controller), width: w, height: h, - isMobile: base.isMobile(), + isMobile: + base.isMobile(supportWeb: false), ); controller ..skipRequestKeyboard = true @@ -220,7 +221,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { if (!readOnly || isImageBase64(imageUrl)) { // To enforce using it on the desktop and other platforms // and that is up to the developer - if (!base.isMobile() && + if (!base.isMobile(supportWeb: false) && configurations.forceUseMobileOptionMenuForImageClick) { return _menuOptionsForReadonlyImage( context: context, diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart index 8753bb87..5d1cf4b2 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/image_button/select_image_source.dart @@ -28,7 +28,7 @@ class SelectImageSourceDialog extends StatelessWidget { 'Take a photo using your phone camera', ), leading: const Icon(Icons.camera), - enabled: !isDesktop(), + enabled: !isDesktop(supportWeb: false), onTap: () => Navigator.of(context).pop(InsertImageSource.camera), ), ListTile( diff --git a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/select_video_source.dart b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/select_video_source.dart index da2fb8ef..8e2d34d5 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/select_video_source.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/toolbar/video_button/select_video_source.dart @@ -28,7 +28,7 @@ class SelectVideoSourceDialog extends StatelessWidget { 'Record a video using your phone camera', ), leading: const Icon(Icons.camera), - enabled: !isDesktop(), + enabled: !isDesktop(supportWeb: false), onTap: () => Navigator.of(context).pop(InsertVideoSource.camera), ), ListTile( diff --git a/flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart b/flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart index f33913e7..3e159d0e 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart @@ -112,7 +112,11 @@ class QuillEditorImageEmbedConfigurations { static ImageEmbedBuilderOnRemovedCallback get defaultOnImageRemovedCallback { return (imageUrl) async { - final mobile = isMobile(); + if (isWeb()) { + return; + } + + final mobile = isMobile(supportWeb: false); // If the platform is not mobile, return void; // Since the mobile OS gives us a copy of the image @@ -134,10 +138,6 @@ class QuillEditorImageEmbedConfigurations { // it without // permission - if (isWeb()) { - return; - } - final dartIoImageFile = File(imageUrl); final isFileExists = await dartIoImageFile.exists(); diff --git a/lib/src/utils/platform.dart b/lib/src/utils/platform.dart index 73a89fcb..020cfae3 100644 --- a/lib/src/utils/platform.dart +++ b/lib/src/utils/platform.dart @@ -4,62 +4,113 @@ import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/foundation.dart' show kIsWeb, TargetPlatform, defaultTargetPlatform; -bool isWeb() { - return kIsWeb; +/// If you want to override the [kIsWeb] use [overrideIsWeb] +bool isWeb({bool? overrideIsWeb}) { + return overrideIsWeb ?? kIsWeb; } -bool isMobile([TargetPlatform? targetPlatform]) { - if (isWeb()) return false; - targetPlatform ??= defaultTargetPlatform; - return {TargetPlatform.iOS, TargetPlatform.android}.contains(targetPlatform); +/// [supportWeb] is a parameter that ask you if we should care about web support +/// if the value is true then we will return the result no matter if we are +/// on web or using a native app to run the flutter app +bool isMobile({ + required bool supportWeb, + TargetPlatform? platform, + bool? overrideIsWeb, +}) { + if (isWeb(overrideIsWeb: overrideIsWeb) && !supportWeb) return false; + platform ??= defaultTargetPlatform; + return {TargetPlatform.iOS, TargetPlatform.android}.contains(platform); } -bool isDesktop([TargetPlatform? targetPlatform]) { - if (isWeb()) return false; - targetPlatform ??= defaultTargetPlatform; +/// [supportWeb] is a parameter that ask you if we should care about web support +/// if the value is true then we will return the result no matter if we are +/// on web or using a native app to run the flutter app +bool isDesktop({ + required bool supportWeb, + TargetPlatform? platform, + bool? overrideIsWeb, +}) { + if (isWeb(overrideIsWeb: overrideIsWeb) && !supportWeb) return false; + platform ??= defaultTargetPlatform; return {TargetPlatform.macOS, TargetPlatform.linux, TargetPlatform.windows} - .contains(targetPlatform); + .contains(platform); } -bool isKeyboardOS([TargetPlatform? targetPlatform]) { - targetPlatform ??= defaultTargetPlatform; - return isDesktop(targetPlatform) || targetPlatform == TargetPlatform.fuchsia; +/// [supportWeb] is a parameter that ask you if we should care about web support +/// if the value is true then we will return the result no matter if we are +/// on web or using a native app to run the flutter app +bool isKeyboardOS({ + required bool supportWeb, + TargetPlatform? platform, + bool? overrideIsWeb, +}) { + platform ??= defaultTargetPlatform; + return isDesktop( + platform: platform, + supportWeb: supportWeb, + overrideIsWeb: overrideIsWeb) || + platform == TargetPlatform.fuchsia; } -bool isAppleOS([TargetPlatform? targetPlatform]) { - if (isWeb()) return false; - targetPlatform ??= defaultTargetPlatform; +/// [supportWeb] is a parameter that ask you if we should care about web support +/// if the value is true then we will return the result no matter if we are +/// on web or using a native app to run the flutter app +bool isAppleOS({ + required bool supportWeb, + TargetPlatform? platform, + bool? overrideIsWeb, +}) { + if (isWeb(overrideIsWeb: overrideIsWeb) && !supportWeb) return false; + platform ??= defaultTargetPlatform; return { TargetPlatform.macOS, TargetPlatform.iOS, - }.contains(targetPlatform); + }.contains(platform); } -bool isMacOS([TargetPlatform? targetPlatform]) { - if (isWeb()) return false; - targetPlatform ??= defaultTargetPlatform; - return TargetPlatform.macOS == targetPlatform; +/// [supportWeb] is a parameter that ask you if we should care about web support +/// if the value is true then we will return the result no matter if we are +/// on web or using a native app to run the flutter app +bool isMacOS({ + required bool supportWeb, + TargetPlatform? platform, + bool? overrideIsWeb, +}) { + if (isWeb(overrideIsWeb: overrideIsWeb) && !supportWeb) return false; + platform ??= defaultTargetPlatform; + return TargetPlatform.macOS == platform; } -bool isIOS([TargetPlatform? targetPlatform]) { - if (isWeb()) return false; - targetPlatform ??= defaultTargetPlatform; - return TargetPlatform.iOS == targetPlatform; +/// [supportWeb] is a parameter that ask you if we should care about web support +/// if the value is true then we will return the result no matter if we are +/// on web or using a native app to run the flutter app +bool isIOS({ + required bool supportWeb, + TargetPlatform? platform, + bool? overrideIsWeb, +}) { + if (isWeb(overrideIsWeb: overrideIsWeb) && !supportWeb) return false; + platform ??= defaultTargetPlatform; + return TargetPlatform.iOS == platform; } -bool isAndroid([TargetPlatform? targetPlatform]) { - if (isWeb()) return false; - targetPlatform ??= defaultTargetPlatform; - return TargetPlatform.android == targetPlatform; +/// [supportWeb] is a parameter that ask you if we should care about web support +/// if the value is true then we will return the result no matter if we are +/// on web or using a native app to run the flutter app +bool isAndroid({ + required bool supportWeb, + TargetPlatform? platform, + bool? overrideIsWeb, +}) { + if (isWeb(overrideIsWeb: overrideIsWeb) && !supportWeb) return false; + platform ??= defaultTargetPlatform; + return TargetPlatform.android == platform; } -bool isFlutterTest() { - if (isWeb()) return false; - return Platform.environment.containsKey('FLUTTER_TEST'); -} - -Future isIOSSimulator() async { - if (!isAppleOS()) { +Future isIOSSimulator({ + bool? overrideIsWeb, +}) async { + if (!isAppleOS(supportWeb: false, overrideIsWeb: overrideIsWeb)) { return false; } @@ -73,3 +124,10 @@ Future isIOSSimulator() async { } return false; } + +bool isFlutterTest({ + bool? overrideIsWeb, +}) { + if (isWeb(overrideIsWeb: overrideIsWeb)) return false; + return Platform.environment.containsKey('FLUTTER_TEST'); +} diff --git a/lib/src/widgets/cursor.dart b/lib/src/widgets/cursor.dart index 293b2ec6..929118b1 100644 --- a/lib/src/widgets/cursor.dart +++ b/lib/src/widgets/cursor.dart @@ -291,7 +291,7 @@ class CursorPainter { final caretHeight = editable!.getFullHeightForCaret(position); if (caretHeight != null) { - if (isAppleOS()) { + if (isAppleOS(supportWeb: true)) { // Center the caret vertically along the text. caretRect = Rect.fromLTWH( caretRect.left, diff --git a/lib/src/widgets/default_styles.dart b/lib/src/widgets/default_styles.dart index 6af846eb..5d5949f8 100644 --- a/lib/src/widgets/default_styles.dart +++ b/lib/src/widgets/default_styles.dart @@ -204,7 +204,7 @@ class DefaultStyles { ); const baseSpacing = VerticalSpacing(6, 0); String fontFamily; - if (isAppleOS(themeData.platform)) { + if (isAppleOS(platform: themeData.platform, supportWeb: true)) { fontFamily = 'Menlo'; } else { fontFamily = 'Roboto Mono'; diff --git a/lib/src/widgets/delegate.dart b/lib/src/widgets/delegate.dart index f595beff..5d021606 100644 --- a/lib/src/widgets/delegate.dart +++ b/lib/src/widgets/delegate.dart @@ -331,7 +331,9 @@ class EditorTextSelectionGestureDetectorBuilder { @protected void onDragSelectionEnd(DragEndDetails details) { renderEditor!.handleDragEnd(details); - if (isDesktop() && + // TODO: Should we care if the platform is desktop using native desktop app + // or the flutter app is running using web app?? + if (isDesktop(supportWeb: true) && delegate.selectionEnabled && shouldShowSelectionToolbar) { // added to show selection copy/paste toolbar after drag to select diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index 9d20a552..dea30332 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -215,7 +215,10 @@ class QuillEditorState extends State Color selectionColor; Radius? cursorRadius; - if (isAppleOS(theme.platform)) { + if (isAppleOS( + platform: theme.platform, + supportWeb: true, + )) { final cupertinoTheme = CupertinoTheme.of(context); textSelectionControls = cupertinoTextSelectionControls; paintCursorAboveText = true; @@ -257,7 +260,10 @@ class QuillEditorState extends State ? (configurations.contextMenuBuilder ?? QuillRawEditor.defaultContextMenuBuilder) : null, - showSelectionHandles: isMobile(theme.platform), + showSelectionHandles: isMobile( + platform: theme.platform, + supportWeb: true, + ), showCursor: configurations.showCursor, cursorStyle: CursorStyle( color: cursorColor, @@ -407,7 +413,10 @@ class _QuillEditorSelectionGestureDetectorBuilder } final platform = Theme.of(_state.context).platform; - if (isAppleOS(platform)) { + if (isAppleOS( + platform: platform, + supportWeb: true, + )) { renderEditor!.selectPositionAt( from: details.globalPosition, cause: SelectionChangedCause.longPress, @@ -480,7 +489,8 @@ class _QuillEditorSelectionGestureDetectorBuilder try { if (delegate.selectionEnabled && !_isPositionSelected(details)) { final platform = Theme.of(_state.context).platform; - if (isAppleOS(platform) || isDesktop()) { + if (isAppleOS(platform: platform, supportWeb: true) || + isDesktop(platform: platform, supportWeb: true)) { // added isDesktop() to enable extend selection in Windows platform switch (details.kind) { case PointerDeviceKind.mouse: @@ -544,7 +554,10 @@ class _QuillEditorSelectionGestureDetectorBuilder if (delegate.selectionEnabled) { final platform = Theme.of(_state.context).platform; - if (isAppleOS(platform)) { + if (isAppleOS( + platform: platform, + supportWeb: true, + )) { renderEditor!.selectPositionAt( from: details.globalPosition, cause: SelectionChangedCause.longPress, diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index 9c903ee2..0775686c 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -185,10 +185,6 @@ class QuillRawEditorState extends EditorState } void _defaultOnTapOutside(PointerDownEvent event) { - if (isWeb()) { - widget.focusNode.unfocus(); - } - /// The focus dropping behavior is only present on desktop platforms /// and mobile browsers. switch (defaultTargetPlatform) { @@ -322,7 +318,7 @@ class QuillRawEditorState extends EditorState // so if we ovveride the platform in material app theme data // it will not depend on it and doesn't change here but I don't think // we need to - final isDesktopMacOS = isMacOS(); + final isDesktopMacOS = isMacOS(supportWeb: true); return TextFieldTapRegion( enabled: widget.enableUnfocusOnTapOutside, @@ -859,7 +855,7 @@ class QuillRawEditorState extends EditorState _floatingCursorResetController = AnimationController(vsync: this); _floatingCursorResetController.addListener(onFloatingCursorResetTick); - if (isKeyboardOS()) { + if (isKeyboardOS(supportWeb: true)) { _keyboardVisible = true; } else if (!isWeb() && isFlutterTest()) { // treat tests like a keyboard OS diff --git a/lib/src/widgets/text_line.dart b/lib/src/widgets/text_line.dart index de0c24bb..0d1243d3 100644 --- a/lib/src/widgets/text_line.dart +++ b/lib/src/widgets/text_line.dart @@ -90,7 +90,7 @@ class _TextLineState extends State { // Desktop platforms (macOS, Linux, Windows): // only allow Meta (Control) + Click combinations - if (isDesktop()) { + if (isDesktop(supportWeb: false)) { return _metaOrControlPressed; } // Mobile platforms (ios, android): always allow but we install a @@ -434,7 +434,7 @@ class _TextLineState extends State { } if (isLink && canLaunchLinks) { - if (isDesktop() || widget.readOnly) { + if (isDesktop(supportWeb: true) || widget.readOnly) { _linkRecognizers[segment] = TapGestureRecognizer() ..onTap = () => _tapNodeLink(segment); } else { @@ -896,7 +896,7 @@ class RenderEditableTextLine extends RenderEditableBox { void _computeCaretPrototype() { // If the cursor is taller only on iOS and not AppleOS then we should check // only for iOS instead of AppleOS (macOS for example) - if (isIOS()) { + if (isIOS(supportWeb: true)) { _caretPrototype = Rect.fromLTWH(0, 0, cursorWidth, cursorHeight + 2); } else { _caretPrototype = Rect.fromLTWH(0, 2, cursorWidth, cursorHeight - 4.0); diff --git a/pubspec.yaml b/pubspec.yaml index 8cbbdbc7..18f2f9ce 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -55,6 +55,7 @@ dev_dependencies: flutter_test: sdk: flutter flutter_quill_test: ^0.0.4 + test: ^1.24.3 flutter: uses-material-design: true \ No newline at end of file diff --git a/test/utils/platform_test.dart b/test/utils/platform_test.dart new file mode 100644 index 00000000..aafda16e --- /dev/null +++ b/test/utils/platform_test.dart @@ -0,0 +1,156 @@ +import 'package:flutter/foundation.dart' show TargetPlatform; +import 'package:flutter_quill/src/utils/platform.dart'; +import 'package:test/test.dart'; + +void main() { + group('Test platform checking logic', () { + var platform = TargetPlatform.linux; + test('Check isDesktop()', () { + platform = TargetPlatform.android; + expect( + isDesktop( + platform: platform, + supportWeb: true, + ), + false, + ); + + for (final desktopPlatform in [ + TargetPlatform.macOS, + TargetPlatform.linux, + TargetPlatform.windows + ]) { + expect( + isDesktop( + supportWeb: false, + platform: desktopPlatform, + overrideIsWeb: false, + ), + true, + ); + + expect( + isDesktop( + supportWeb: false, + overrideIsWeb: true, + platform: desktopPlatform, + ), + false, + ); + + expect( + isDesktop( + supportWeb: true, + overrideIsWeb: true, + platform: desktopPlatform, + ), + true, + ); + } + }); + test('Check isMobile()', () { + platform = TargetPlatform.macOS; + expect( + isMobile( + platform: platform, + supportWeb: true, + ), + false, + ); + + for (final mobilePlatform in [ + TargetPlatform.android, + TargetPlatform.iOS, + ]) { + expect( + isMobile( + supportWeb: false, + platform: mobilePlatform, + overrideIsWeb: false, + ), + true, + ); + + expect( + isMobile( + supportWeb: false, + overrideIsWeb: true, + platform: mobilePlatform, + ), + false, + ); + + expect( + isMobile( + supportWeb: true, + overrideIsWeb: true, + platform: mobilePlatform, + ), + true, + ); + } + }); + test( + 'Check supportWeb parameter when using desktop platform on web', + () { + platform = TargetPlatform.macOS; + expect( + isDesktop( + platform: platform, + supportWeb: true, + ), + true, + ); + expect( + isDesktop( + platform: platform, + supportWeb: false, + overrideIsWeb: false, + ), + true, + ); + + expect( + isDesktop( + platform: platform, + supportWeb: false, + overrideIsWeb: true, + ), + false, + ); + }, + ); + + test( + 'Check supportWeb parameter when using mobile platform on web', + () { + platform = TargetPlatform.android; + expect( + isMobile( + platform: platform, + supportWeb: true, + overrideIsWeb: true, + ), + true, + ); + expect( + isMobile( + platform: platform, + supportWeb: false, + overrideIsWeb: false, + ), + true, + ); + + expect( + isMobile( + platform: platform, + supportWeb: false, + overrideIsWeb: true, + ), + false, + ); + }, + ); + }); +} diff --git a/test/widgets/controller_test.dart b/test/widgets/controller_test.dart index 3decfc47..930cdccf 100644 --- a/test/widgets/controller_test.dart +++ b/test/widgets/controller_test.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_test/flutter_test.dart'; +import 'package:test/test.dart'; void main() { const testDocumentContents = 'data'; From c769b144636acceea2b91742c73d3c5f362d3fd1 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 10 Nov 2023 23:22:48 +0300 Subject: [PATCH 102/210] Update flutter_quill_extensions part 2 (#1519) * Update flutter_quill_extensions part 2 --- CHANGELOG.md | 3 + README.md | 9 +- doc/CONTRIBUTING.md | 2 + doc/todo.md | 48 ++ example/assets/sample_data_testing.json | 21 +- example/lib/pages/home_page.dart | 7 +- example/lib/pages/read_only_page.dart | 4 +- example/pubspec.yaml | 1 + flutter_quill_extensions/CHANGELOG.md | 10 + flutter_quill_extensions/README.md | 8 +- .../lib/flutter_quill_extensions.dart | 20 +- .../embeds/editor/image/image.dart | 489 +++++++----------- .../embeds/editor/image/image_menu.dart | 195 +++++++ .../embeds/editor/image/image_web.dart | 5 +- .../lib/presentation/embeds/utils.dart | 11 +- .../presentation/embeds/widgets/image.dart | 82 ++- .../models/config/editor/image/image.dart | 2 + flutter_quill_extensions/pubspec.yaml | 2 +- lib/src/models/structs/optional_size.dart | 11 + lib/src/utils/string.dart | 7 +- lib/src/widgets/text_line.dart | 27 +- pubspec.yaml | 2 +- 22 files changed, 586 insertions(+), 380 deletions(-) create mode 100644 doc/todo.md create mode 100644 flutter_quill_extensions/lib/presentation/embeds/editor/image/image_menu.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dbb538f..0a9b7268 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [8.4.1] +- Add `copyWith` in `OptionalSize` class + ## [8.4.0] - **Breaking change**: Update the `QuillCustomButton` to have `QuillCustomButtonOptions`. We moved everything that is in the `QuillCustomButton` to `QuillCustomButtonOptions` but replaced the `iconData` with `icon` widget for more customizations - **Breaking change**: the `customButtons` in the `QuillToolbarConfigurations` is now of type `List` diff --git a/README.md b/README.md index 9bc98324..ae001b81 100644 --- a/README.md +++ b/README.md @@ -66,10 +66,13 @@ dependencies: git: https://github.com/singerdmx/flutter-quill.git ``` + +> +> Note: At this time, we are making too many changes to the library and you might see new version almost every day > > Using the latest version and reporting any issues you encounter on GitHub will greatly contribute to the improvement of the library. Your input and insights are valuable in shaping a stable and reliable version for all our users. Thank you for being part of the open-source community! > -> Please use the latest pre-release of [FlutterQuill Extensions] in order to work with the latest stable version of [FlutterQuill] +> If the latest version of [FlutterQuill Extensions] is pre-release, then please use it in order to work with the latest stable version of [FlutterQuill] > ## Usage @@ -297,7 +300,9 @@ Made with [contrib.rocks](https://contrib.rocks). We welcome contributions! -Please follow these guidelines when contributing to our project. See [CONTRIBUTING.md](./doc/CONTRIBUTING.md) for more details. +Please follow these guidelines when contributing to the project. See [CONTRIBUTING.md](./doc/CONTRIBUTING.md) for more details.
    + +You can check the [Todo](./doc/todo.md) list if you want to [Quill]: https://quilljs.com/docs/formats [Flutter]: https://github.com/flutter/flutter diff --git a/doc/CONTRIBUTING.md b/doc/CONTRIBUTING.md index fbbbf649..b3a51e4b 100644 --- a/doc/CONTRIBUTING.md +++ b/doc/CONTRIBUTING.md @@ -3,6 +3,8 @@ The contributions are more than welcome!
    This project will be better with the open-source community help +You can check the [Todo](./todo.md) list if you want to + There are no guidelines for now. This page will be updated in the future. diff --git a/doc/todo.md b/doc/todo.md new file mode 100644 index 00000000..ab746b7e --- /dev/null +++ b/doc/todo.md @@ -0,0 +1,48 @@ +# Todo + +This is a todo list page that added recently and will be updated soon. + +## Table of contents +- [Todo](#todo) + - [Table of contents](#table-of-contents) + - [Flutter Quill](#flutter-quill) + - [Features](#features) + - [Improvemenets](#improvemenets) + - [Bugs](#bugs) + - [Flutter Quill Extensions](#flutter-quill-extensions) + - [Features](#features-1) + - [Improvemenets](#improvemenets-1) + - [Bugs](#bugs-1) + +## Flutter Quill + +### Features + + 1. Add a method to set TextInputAction, fore more [info](https://github.com/singerdmx/flutter-quill/issues/1328) + 2. Add support for Text magnification feature, for more [info](https://github.com/singerdmx/flutter-quill/issues/1504) + 3. Provide a way to expose quills undo redo stacks, for more [info](https://github.com/singerdmx/flutter-quill/issues/1381) + +### Improvemenets + + 1. Improve the Raw Quill Editor, for more [info](https://github.com/singerdmx/flutter-quill/issues/1509) + 2. Provide more support to all the platforms + +### Bugs + +Empty for now. +Please go to the [issues](https://github.com/singerdmx/flutter-quill/issues) + + +## Flutter Quill Extensions + +### Features +1. Add support for cropping an image, fore more [info](https://github.com/singerdmx/flutter-quill/issues/1494) +2. Add support for copying images to the Clipboard + +### Improvemenets + +Please check the todos, this list will be updated soon. + +### Bugs + +Please check the todos, this list will be updated soon. \ No newline at end of file diff --git a/example/assets/sample_data_testing.json b/example/assets/sample_data_testing.json index bd725222..45cb311f 100644 --- a/example/assets/sample_data_testing.json +++ b/example/assets/sample_data_testing.json @@ -1,6 +1,25 @@ [ { - "insert": "Here is an image: \n" + "insert": "This is an asset image: \n" + }, + { + "insert": "\n" + }, + { + "insert": { + "image": "assets/images/1.png" + }, + "attributes": { + "width": "100", + "height": "100", + "style": "width:500px; height:350px;" + } + }, + { + "insert": "\n" + }, + { + "insert": "Here is a network image: \n" }, { "insert": "\n" diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 379b4f2a..c36e834c 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -397,7 +397,7 @@ class _HomePageState extends State { sizeSmall: TextStyle(fontSize: 9), ), embedBuilders: [ - ...FlutterQuillEmbeds.editorsWebBuilders(), + ...FlutterQuillEmbeds.editorWebBuilders(), TimeStampEmbedBuilderWidget() ], ), @@ -444,9 +444,8 @@ class _HomePageState extends State { ), embedBuilders: [ ...FlutterQuillEmbeds.editorBuilders( - imageEmbedConfigurations: const QuillEditorImageEmbedConfigurations( - forceUseMobileOptionMenuForImageClick: true, - ), + imageEmbedConfigurations: + const QuillEditorImageEmbedConfigurations(), ), TimeStampEmbedBuilderWidget() ], diff --git a/example/lib/pages/read_only_page.dart b/example/lib/pages/read_only_page.dart index 9670c152..5d4ff051 100644 --- a/example/lib/pages/read_only_page.dart +++ b/example/lib/pages/read_only_page.dart @@ -42,7 +42,7 @@ class _ReadOnlyPageState extends State { expands: false, padding: EdgeInsets.zero, embedBuilders: kIsWeb - ? FlutterQuillEmbeds.editorsWebBuilders() + ? FlutterQuillEmbeds.editorWebBuilders() : FlutterQuillEmbeds.editorBuilders(), scrollable: true, autoFocus: true, @@ -57,7 +57,7 @@ class _ReadOnlyPageState extends State { autoFocus: true, expands: false, padding: EdgeInsets.zero, - embedBuilders: FlutterQuillEmbeds.editorsWebBuilders(), + embedBuilders: FlutterQuillEmbeds.editorWebBuilders(), scrollable: true, ), scrollController: ScrollController(), diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 69411983..5ff55f23 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -41,6 +41,7 @@ flutter: uses-material-design: true assets: - assets/ + - assets/images/ fonts: - family: monospace diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 2cb20ab3..ffb6cd2c 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -1,5 +1,15 @@ ## 0.6.5 - Support the new improved platform checking of `flutter_quill` +- Update the Image embed builder logic +- Fix Save image button exception +- Feature: Image cropping for the image embed builder +- Add support for copying the image to the cliboard +- Add new static method in `FlutterQuillEmbeds` which is `defaultEditorBuilders` for minimal configurations +- Fix the image size logic (it's still missing a lot of things but we will work on that soon) +- Fix the zoom image functionality to support different image providers +- Fix typo in the function name `editorsWebBuilders`, now it's called `editorWebBuilders` +- Deprecated: The boolean property `forceUseMobileOptionMenuForImageClick` is now deprecated as we will not using it anymore and it will be removed in the next major release +- Update `README.md` ## 0.6.4 - Update `QuillImageUtilities` diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index d85e0f32..58c52729 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -17,7 +17,7 @@ Currently the support for **Web** is limitied. - [Usage](#usage) - [Embed Blocks](#embed-blocks) - [Custom Size Image for Mobile](#custom-size-image-for-mobile) - - [Custom Size Image for other platforms (excluding web)](#custom-size-image-for-other-platforms-excluding-web) + - [Custom Size Image for other platforms](#custom-size-image-for-other-platforms) - [Drag and drop feature](#drag-and-drop-feature) - [Features](#features) - [Contributing](#contributing) @@ -135,7 +135,7 @@ Define `mobileWidth`, `mobileHeight`, `mobileMargin`, `mobileAlignment` as follo } ``` -### Custom Size Image for other platforms (excluding web) +### Custom Size Image for other platforms Define `width`, `height`, `margin`, `alignment` as follows: @@ -150,9 +150,7 @@ Define `width`, `height`, `margin`, `alignment` as follows: } ``` -On mobile we will use `mobileWidth`, `mobileHeight`, on desktop will use `width`, `heigth` -on Web we will use the `width` and the `height` but the ones in the `attributes` -This may not clear but don't worry we will update it soon. + ### Drag and drop feature Currently the drag and drop feature is not offically supported but you can achieve this very easily in the following steps: diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index 666f9177..6d66c427 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -12,9 +12,7 @@ import 'presentation/embeds/editor/webview.dart'; import 'presentation/embeds/toolbar/camera_button/camera_button.dart'; import 'presentation/embeds/toolbar/formula_button.dart'; import 'presentation/embeds/toolbar/image_button/image_button.dart'; -// TODO: Temporary -// ignore: unused_import -import 'presentation/embeds/toolbar/media_button/media_button.dart'; + import 'presentation/embeds/toolbar/video_button/video_button.dart'; import 'presentation/models/config/editor/image/image.dart'; import 'presentation/models/config/editor/image/image_web.dart'; @@ -47,8 +45,7 @@ export 'presentation/embeds/toolbar/utils/image_video_utils.dart'; export 'presentation/embeds/toolbar/video_button/video_button.dart'; export 'presentation/embeds/utils.dart'; export 'presentation/models/config/editor/image/image.dart'; -// TODO: Temporary -// ignore: unused_import + export 'presentation/models/config/editor/image/image_web.dart'; export 'presentation/models/config/editor/video/video.dart'; export 'presentation/models/config/editor/video/video_web.dart'; @@ -72,7 +69,7 @@ class FlutterQuillEmbeds { /// /// **Note:** This method is not intended for web usage. /// For web-specific embeds, - /// use [editorsWebBuilders]. + /// use [editorWebBuilders]. /// /// /// The method returns a list of [EmbedBuilder] objects that can be used with @@ -127,7 +124,7 @@ class FlutterQuillEmbeds { /// [QuillEditorWebVideoEmbedBuilder] is the embed builder for handling /// videos iframe on the web. /// - static List editorsWebBuilders( + static List editorWebBuilders( {QuillEditorWebImageEmbedConfigurations? imageEmbedConfigurations = const QuillEditorWebImageEmbedConfigurations(), QuillEditorWebVideoEmbedConfigurations? videoEmbedConfigurations = @@ -150,6 +147,15 @@ class FlutterQuillEmbeds { ]; } + /// Returns a list of default embed builders for QuillEditor. + /// + /// It will use [editorWebBuilders] for web and [editorBuilders] for others + /// + /// It's not customizable with minimal configurations + static List defaultEditorBuilders() { + return kIsWeb ? editorWebBuilders() : editorBuilders(); + } + /// Returns a list of embed button builders to customize the toolbar buttons. /// /// If you don't want to show one of the buttons for soem reason, diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart index 7f3d6e94..3e6cac2c 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image.dart @@ -1,16 +1,12 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_quill/extensions.dart' as base; -import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/translations.dart'; +import 'package:flutter_quill/flutter_quill.dart' hide OptionalSize; +import '../../../../logic/models/config/shared_configurations.dart'; import '../../../models/config/editor/image/image.dart'; -import '../../embed_types/image.dart'; -import '../../utils.dart'; import '../../widgets/image.dart'; -import '../../widgets/image_resizer.dart'; -import '../../widgets/simple_dialog_item.dart'; +import 'image_menu.dart'; class QuillEditorImageEmbedBuilder extends EmbedBuilder { QuillEditorImageEmbedBuilder({ @@ -35,301 +31,214 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { ) { assert(!kIsWeb, 'Please provide image EmbedBuilder for Web'); - Widget image = const SizedBox.shrink(); - final imageUrl = standardizeImageUrl(node.value.data); - OptionalSize? imageSize; - final style = node.style.attributes['style']; + final imageSource = standardizeImageUrl(node.value.data); + final ((imageSize), margin, alignment) = _getImageAttributes(node); - if (style != null) { - final attrs = base.isMobile(supportWeb: false) - ? base.parseKeyValuePairs(style.value.toString(), { - Attribute.mobileWidth, - Attribute.mobileHeight, - Attribute.mobileMargin, - Attribute.mobileAlignment, - }) - : base.parseKeyValuePairs(style.value.toString(), { - Attribute.width.key, - Attribute.height.key, - Attribute.margin, - Attribute.alignment, - }); - if (attrs.isNotEmpty) { - final width = double.tryParse( - (base.isMobile(supportWeb: false) - ? attrs[Attribute.mobileWidth] - : attrs[Attribute.width.key]) ?? - '', - ); - final height = double.tryParse( - (base.isMobile(supportWeb: false) - ? attrs[Attribute.mobileHeight] - : attrs[Attribute.height.key]) ?? - '', - ); - final alignment = base.getAlignment(base.isMobile(supportWeb: false) - ? attrs[Attribute.mobileAlignment] - : attrs[Attribute.alignment]); - final margin = (base.isMobile(supportWeb: false) - ? double.tryParse(Attribute.mobileMargin) - : double.tryParse(Attribute.margin)) ?? - 0.0; + final width = imageSize.width; + final height = imageSize.height; - // assert( - // width != null && height != null, - // base.isMobile() - // ? 'mobileWidth and mobileHeight must be specified' - // : 'width and height must be specified', - // ); - imageSize = OptionalSize(width, height); - image = Padding( - padding: EdgeInsets.all(margin), - child: getImageWidgetByImageSource( - imageUrl, - width: width, - height: height, - alignment: alignment, - imageProviderBuilder: configurations.imageProviderBuilder, - imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder, - ), - ); - } - } - - if (imageSize == null) { - image = getImageWidgetByImageSource( - imageUrl, - imageProviderBuilder: configurations.imageProviderBuilder, - imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder, - ); - imageSize = OptionalSize((image as Image).width, image.height); - } - - if (!readOnly && - (base.isMobile(supportWeb: false) || - configurations.forceUseMobileOptionMenuForImageClick)) { - return GestureDetector( - onTap: () { - showDialog( - context: context, - builder: (context) { - final copyOption = SimpleDialogItem( - icon: Icons.copy_all_outlined, - color: Colors.cyanAccent, - text: 'Copy'.i18n, - onPressed: () { - final imageNode = - getEmbedNode(controller, controller.selection.start) - .value; - final imageUrl = imageNode.value.data; - controller.copiedImageUrl = ImageUrl( - imageUrl, - getImageStyleString(controller), - ); - Navigator.pop(context); - }, - ); - final removeOption = SimpleDialogItem( - icon: Icons.delete_forever_outlined, - color: Colors.red.shade200, - text: 'Remove'.i18n, - onPressed: () async { - Navigator.of(context).pop(); - - // Call the remove check callback if set - if (await configurations.shouldRemoveImageCallback - ?.call(imageUrl) == - false) { - return; - } - - final offset = getEmbedNode( - controller, - controller.selection.start, - ).offset; - controller.replaceText( - offset, - 1, - '', - TextSelection.collapsed(offset: offset), - ); - // Call the post remove callback if set - await configurations.onImageRemovedCallback.call(imageUrl); - }, - ); - return Padding( - padding: const EdgeInsets.fromLTRB(50, 0, 50, 0), - child: SimpleDialog( - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all( - Radius.circular(10), - ), - ), - children: [ - SimpleDialogItem( - icon: Icons.settings_outlined, - color: Colors.lightBlueAccent, - text: 'Resize'.i18n, - onPressed: () { - Navigator.pop(context); - showCupertinoModalPopup( - context: context, - builder: (context) { - final screenSize = MediaQuery.sizeOf(context); - return ImageResizer( - onImageResize: (w, h) { - final res = getEmbedNode( - controller, - controller.selection.start, - ); - - final attr = - base.replaceStyleStringWithSize( - getImageStyleString(controller), - width: w, - height: h, - isMobile: - base.isMobile(supportWeb: false), - ); - controller - ..skipRequestKeyboard = true - ..formatText( - res.offset, - 1, - StyleAttribute(attr), - ); - }, - imageWidth: imageSize?.width, - imageHeight: imageSize?.height, - maxWidth: screenSize.width, - maxHeight: screenSize.height, - ); - }, - ); - }, - ), - copyOption, - removeOption, - ]), - ); - }); - }, - child: image, - ); - } - - if (!readOnly || isImageBase64(imageUrl)) { - // To enforce using it on the desktop and other platforms - // and that is up to the developer - if (!base.isMobile(supportWeb: false) && - configurations.forceUseMobileOptionMenuForImageClick) { - return _menuOptionsForReadonlyImage( - context: context, - imageUrl: imageUrl, - image: image, - imageProviderBuilder: configurations.imageProviderBuilder, - imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder, - ); - } - return image; - } - - // We provide option menu for mobile platform excluding base64 image - return _menuOptionsForReadonlyImage( - context: context, - imageUrl: imageUrl, - image: image, + final image = getImageWidgetByImageSource( + imageSource, imageProviderBuilder: configurations.imageProviderBuilder, imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder, + alignment: alignment, + height: height, + width: width, + ); + + // OptionalSize? imageSize; + // final style = node.style.attributes['style']; + + // if (style != null) { + // final attrs = base.isMobile(supportWeb: false) + // ? base.parseKeyValuePairs(style.value.toString(), { + // Attribute.mobileWidth, + // Attribute.mobileHeight, + // Attribute.mobileMargin, + // Attribute.mobileAlignment, + // }) + // : base.parseKeyValuePairs(style.value.toString(), { + // Attribute.width.key, + // Attribute.height.key, + // Attribute.margin, + // Attribute.alignment, + // }); + // if (attrs.isNotEmpty) { + // final width = double.tryParse( + // (base.isMobile(supportWeb: false) + // ? attrs[Attribute.mobileWidth] + // : attrs[Attribute.width.key]) ?? + // '', + // ); + // final height = double.tryParse( + // (base.isMobile(supportWeb: false) + // ? attrs[Attribute.mobileHeight] + // : attrs[Attribute.height.key]) ?? + // '', + // ); + // final alignment = base.getAlignment(base.isMobile(supportWeb: false) + // ? attrs[Attribute.mobileAlignment] + // : attrs[Attribute.alignment]); + // final margin = (base.isMobile(supportWeb: false) + // ? double.tryParse(Attribute.mobileMargin) + // : double.tryParse(Attribute.margin)) ?? + // 0.0; + + // imageSize = OptionalSize(width, height); + // image = Padding( + // padding: EdgeInsets.all(margin), + // child: getImageWidgetByImageSource( + // imageSource, + // width: width, + // height: height, + // alignment: alignment, + // imageProviderBuilder: configurations.imageProviderBuilder, + // imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder, + // ), + // ); + // } + // } + + // if (imageSize == null) { + // image = getImageWidgetByImageSource( + // imageSource, + // imageProviderBuilder: configurations.imageProviderBuilder, + // imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder, + // ); + // imageSize = OptionalSize((image as Image).width, image.height); + // } + + final imageSaverService = + QuillSharedExtensionsConfigurations.get(context: context) + .imageSaverService; + return GestureDetector( + child: Builder( + builder: (context) { + if (margin != null) { + return Padding( + padding: EdgeInsets.all(margin), + child: image, + ); + } + return image; + }, + ), + onTap: () => showDialog( + context: context, + builder: (context) { + return ImageOptionsMenu( + controller: controller, + configurations: configurations, + imageSource: imageSource, + imageSize: imageSize, + isReadOnly: readOnly, + imageSaverService: imageSaverService, + ); + }, + ), ); } } -Widget _menuOptionsForReadonlyImage({ - required BuildContext context, - required String imageUrl, - required Widget image, - required ImageEmbedBuilderProviderBuilder? imageProviderBuilder, - required ImageEmbedBuilderErrorWidgetBuilder? imageErrorWidgetBuilder, -}) { - return GestureDetector( - onTap: () { - showDialog( - context: context, - builder: (_) { - final saveOption = SimpleDialogItem( - icon: Icons.save, - color: Colors.greenAccent, - text: 'Save'.i18n, - onPressed: () async { - imageUrl = appendFileExtensionToImageUrl(imageUrl); - final messenger = ScaffoldMessenger.of(context); - Navigator.of(context).pop(); +( + OptionalSize imageSize, + double? margin, + Alignment alignment, +) _getImageAttributes( + Node node, +) { + var imageSize = const OptionalSize(null, null); + var imageAlignment = Alignment.center; + double? imageMargin; + + // Usually double value + final heightValue = double.tryParse( + node.style.attributes[Attribute.height.key]?.value.toString() ?? ''); + final widthValue = double.tryParse( + node.style.attributes[Attribute.width.key]?.value.toString() ?? ''); + + if (heightValue != null) { + imageSize = imageSize.copyWith( + height: heightValue, + ); + } + if (widthValue != null) { + imageSize = imageSize.copyWith( + width: widthValue, + ); + } - final saveImageResult = await saveImage( - imageUrl: imageUrl, - context: context, - ); - final imageSavedSuccessfully = saveImageResult.isSuccess; + final cssStyle = node.style.attributes['style']; + + if (cssStyle != null) { + final attrs = base.isMobile(supportWeb: false) + ? base.parseKeyValuePairs(cssStyle.value.toString(), { + Attribute.mobileWidth, + Attribute.mobileHeight, + Attribute.mobileMargin, + Attribute.mobileAlignment, + }) + : base.parseKeyValuePairs(cssStyle.value.toString(), { + Attribute.width.key, + Attribute.height.key, + Attribute.margin, + Attribute.alignment, + }); + if (attrs.isEmpty) { + return (imageSize, imageMargin, imageAlignment); + } - messenger.clearSnackBars(); + // It css value as string but we will try to support it anyway - if (!imageSavedSuccessfully) { - messenger.showSnackBar(SnackBar( - content: Text( - 'Error while saving image'.i18n, - ))); - return; - } + // TODO: This could be improved much better + final cssHeightValue = double.tryParse( + (attrs[Attribute.height.key] ?? '').replaceFirst('px', '')); + final cssWidthValue = double.tryParse( + (attrs[Attribute.width.key] ?? '').replaceFirst('px', '')); - String message; - switch (saveImageResult.method) { - case SaveImageResultMethod.network: - message = 'Saved using the network'.i18n; - break; - case SaveImageResultMethod.localStorage: - message = 'Saved using the local storage'.i18n; - break; - } + if (cssHeightValue != null) { + imageSize = imageSize.copyWith(height: cssHeightValue); + } + if (cssWidthValue != null) { + imageSize = imageSize.copyWith(width: cssWidthValue); + } - messenger.showSnackBar( - SnackBar( - content: Text(message), - ), - ); - }, - ); - final zoomOption = SimpleDialogItem( - icon: Icons.zoom_in, - color: Colors.cyanAccent, - text: 'Zoom'.i18n, - onPressed: () { - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => ImageTapWrapper( - imageUrl: imageUrl, - imageProviderBuilder: imageProviderBuilder, - imageErrorWidgetBuilder: imageErrorWidgetBuilder, - ), - ), - ); - }, - ); - return Padding( - padding: const EdgeInsets.fromLTRB(50, 0, 50, 0), - child: SimpleDialog( - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all( - Radius.circular(10), - ), - ), - children: [saveOption, zoomOption], - ), - ); - }, - ); - }, - child: image, + imageAlignment = base.getAlignment(base.isMobile(supportWeb: false) + ? attrs[Attribute.mobileAlignment] + : attrs[Attribute.alignment]); + final margin = (base.isMobile(supportWeb: false) + ? double.tryParse(Attribute.mobileMargin) + : double.tryParse(Attribute.margin)); + if (margin != null) { + imageMargin = margin; + } + } + + return (imageSize, imageMargin, imageAlignment); +} + +@immutable +class OptionalSize { + const OptionalSize( + this.width, + this.height, ); + + /// If non-null, requires the child to have exactly this width. + /// If null, the child is free to choose its own width. + final double? width; + + /// If non-null, requires the child to have exactly this height. + /// If null, the child is free to choose its own height. + final double? height; + + OptionalSize copyWith({ + double? width, + double? height, + }) { + return OptionalSize( + width ?? this.width, + height ?? this.height, + ); + } } diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_menu.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_menu.dart new file mode 100644 index 00000000..6fc71864 --- /dev/null +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_menu.dart @@ -0,0 +1,195 @@ +import 'package:flutter/cupertino.dart' show showCupertinoModalPopup; +import 'package:flutter/material.dart'; +// import 'package:flutter/services.dart' show Clipboard, ClipboardData; +import 'package:flutter_quill/extensions.dart' + show isDesktop, isMobile, replaceStyleStringWithSize; +import 'package:flutter_quill/flutter_quill.dart' + show ImageUrl, QuillController, StyleAttribute, getEmbedNode; +import 'package:flutter_quill/translations.dart'; + +import '../../../../logic/services/image_saver/s_image_saver.dart'; +import '../../../models/config/editor/image/image.dart'; +import '../../utils.dart'; +import '../../widgets/image.dart' show ImageTapWrapper, getImageStyleString; +import '../../widgets/image_resizer.dart' show ImageResizer; +import 'image.dart' show OptionalSize; + +class ImageOptionsMenu extends StatelessWidget { + const ImageOptionsMenu({ + required this.controller, + required this.configurations, + required this.imageSource, + required this.imageSize, + required this.isReadOnly, + required this.imageSaverService, + super.key, + }); + + final QuillController controller; + final QuillEditorImageEmbedConfigurations configurations; + final String imageSource; + final OptionalSize imageSize; + final bool isReadOnly; + final ImageSaverService imageSaverService; + + @override + Widget build(BuildContext context) { + final materialTheme = Theme.of(context); + return Padding( + padding: const EdgeInsets.fromLTRB(50, 0, 50, 0), + child: SimpleDialog( + title: Text('Image'.i18n), + children: [ + if (!isReadOnly) + ListTile( + title: Text('Resize'.i18n), + leading: const Icon(Icons.settings_outlined), + onTap: () { + Navigator.pop(context); + showCupertinoModalPopup( + context: context, + builder: (context) { + final screenSize = MediaQuery.sizeOf(context); + return ImageResizer( + onImageResize: (w, h) { + final res = getEmbedNode( + controller, + controller.selection.start, + ); + + final attr = replaceStyleStringWithSize( + getImageStyleString(controller), + width: w, + height: h, + isMobile: isMobile(supportWeb: false), + ); + controller + ..skipRequestKeyboard = true + ..formatText( + res.offset, + 1, + StyleAttribute(attr), + ); + }, + imageWidth: imageSize.width, + imageHeight: imageSize.height, + maxWidth: screenSize.width, + maxHeight: screenSize.height, + ); + }, + ); + }, + ), + ListTile( + leading: const Icon(Icons.copy_all_outlined), + title: Text('Copy'.i18n), + onTap: () async { + final navigator = Navigator.of(context); + final imageNode = + getEmbedNode(controller, controller.selection.start).value; + final imageUrl = imageNode.value.data; + controller.copiedImageUrl = ImageUrl( + imageUrl, + getImageStyleString(controller), + ); + // TODO: Implement the copy image + // await Clipboard.setData( + // ClipboardData(text: '$imageUrl'), + // ); + navigator.pop(); + }, + ), + if (!isReadOnly) + ListTile( + leading: Icon( + Icons.delete_forever_outlined, + color: materialTheme.colorScheme.error, + ), + title: Text('Remove'.i18n), + onTap: () async { + Navigator.of(context).pop(); + + // Call the remove check callback if set + if (await configurations.shouldRemoveImageCallback + ?.call(imageSource) == + false) { + return; + } + + final offset = getEmbedNode( + controller, + controller.selection.start, + ).offset; + controller.replaceText( + offset, + 1, + '', + TextSelection.collapsed(offset: offset), + ); + // Call the post remove callback if set + await configurations.onImageRemovedCallback.call(imageSource); + }, + ), + ...[ + ListTile( + leading: const Icon(Icons.save), + title: Text('Save'.i18n), + enabled: !isDesktop(supportWeb: false), + onTap: () async { + final messenger = ScaffoldMessenger.of(context); + Navigator.of(context).pop(); + + final saveImageResult = await saveImage( + imageUrl: imageSource, + imageSaverService: imageSaverService, + ); + final imageSavedSuccessfully = saveImageResult.isSuccess; + + messenger.clearSnackBars(); + + if (!imageSavedSuccessfully) { + messenger.showSnackBar(SnackBar( + content: Text( + 'Error while saving image'.i18n, + ))); + return; + } + + String message; + switch (saveImageResult.method) { + case SaveImageResultMethod.network: + message = 'Saved using the network'.i18n; + break; + case SaveImageResultMethod.localStorage: + message = 'Saved using the local storage'.i18n; + break; + } + + messenger.showSnackBar( + SnackBar( + content: Text(message), + ), + ); + }, + ), + ListTile( + leading: const Icon(Icons.zoom_in), + title: Text('Zoom'.i18n), + onTap: () => Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => ImageTapWrapper( + imageUrl: imageSource, + imageProviderBuilder: configurations.imageProviderBuilder, + imageErrorWidgetBuilder: + configurations.imageErrorWidgetBuilder, + ), + ), + ), + ), + ], + ], + ), + ); + } +} diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart index 84d3cd84..b509eaaa 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart @@ -33,7 +33,7 @@ class QuillEditorWebImageEmbedBuilder extends EmbedBuilder { ) { assert(kIsWeb, 'ImageEmbedBuilderWeb is only for web platform'); - final (height, width, margin, alignment) = _getImageSizeForWeb(node); + final (height, width, margin, alignment) = _getImageWebAttributes(node); var imageSource = node.value.data.toString(); @@ -77,11 +77,12 @@ class QuillEditorWebImageEmbedBuilder extends EmbedBuilder { String width, String margin, String alignment, -) _getImageSizeForWeb( +) _getImageWebAttributes( Node node, ) { var height = 'auto'; var width = 'auto'; + // TODO: Add support for margin and alignment const margin = 'auto'; const alignment = 'center'; diff --git a/flutter_quill_extensions/lib/presentation/embeds/utils.dart b/flutter_quill_extensions/lib/presentation/embeds/utils.dart index f1331f84..d9ea1fea 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/utils.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/utils.dart @@ -1,8 +1,8 @@ import 'dart:io' show File; import 'package:flutter/foundation.dart' show immutable; -import 'package:flutter/widgets.dart' show BuildContext; -import '../../logic/models/config/shared_configurations.dart'; +import '../../logic/services/image_saver/s_image_saver.dart'; +import 'widgets/image.dart'; RegExp _base64 = RegExp( r'^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$', @@ -49,11 +49,8 @@ class SaveImageResult { Future saveImage({ required String imageUrl, - required BuildContext context, + required ImageSaverService imageSaverService, }) async { - final imageSaverService = - QuillSharedExtensionsConfigurations.get(context: context) - .imageSaverService; final imageFile = File(imageUrl); final hasPermission = await imageSaverService.hasAccess(); if (!hasPermission) { @@ -63,7 +60,7 @@ Future saveImage({ if (!imageExistsLocally) { try { await imageSaverService.saveImageFromNetwork( - Uri.parse(imageUrl), + Uri.parse(appendFileExtensionToImageUrl(imageUrl)), ); return const SaveImageResult( isSuccess: true, diff --git a/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart b/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart index a4f8f717..4dc4241c 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/widgets/image.dart @@ -28,6 +28,31 @@ String getImageStyleString(QuillController controller) { return s ?? ''; } +/// [imageProviderBuilder] To override the return value pass value to it +/// [imageSource] The source of the image in the quill delta json document +/// It could be http, file, network, asset, or base 64 image +ImageProvider getImageProviderByImageSource( + String imageSource, { + required ImageEmbedBuilderProviderBuilder? imageProviderBuilder, +}) { + if (imageProviderBuilder != null) { + return imageProviderBuilder(imageSource); + } + + if (isImageBase64(imageSource)) { + return MemoryImage(base64.decode(imageSource)); + } + + if (isHttpBasedUrl(imageSource)) { + return NetworkImage(imageSource); + } + if (imageSource.startsWith('assets')) { + // TODO: This impl needs to be improved + return AssetImage(imageSource); + } + return FileImage(File(imageSource)); +} + Image getImageWidgetByImageSource( String imageSource, { required ImageEmbedBuilderProviderBuilder? imageProviderBuilder, @@ -36,35 +61,11 @@ Image getImageWidgetByImageSource( double? height, AlignmentGeometry alignment = Alignment.center, }) { - if (isImageBase64(imageSource)) { - return Image.memory( - base64.decode(imageSource), - width: width, - height: height, - alignment: alignment, - ); - } - - if (imageProviderBuilder != null) { - return Image( - image: imageProviderBuilder(imageSource), - width: width, - height: height, - alignment: alignment, - errorBuilder: imageErrorWidgetBuilder, - ); - } - if (isHttpBasedUrl(imageSource)) { - return Image.network( + return Image( + image: getImageProviderByImageSource( imageSource, - width: width, - height: height, - alignment: alignment, - errorBuilder: imageErrorWidgetBuilder, - ); - } - return Image.file( - File(imageSource), + imageProviderBuilder: imageProviderBuilder, + ), width: width, height: height, alignment: alignment, @@ -110,20 +111,6 @@ class ImageTapWrapper extends StatelessWidget { final ImageEmbedBuilderProviderBuilder? imageProviderBuilder; final ImageEmbedBuilderErrorWidgetBuilder? imageErrorWidgetBuilder; - ImageProvider _imageProviderByUrl( - String imageUrl, { - required ImageEmbedBuilderProviderBuilder? customImageProviderBuilder, - }) { - if (customImageProviderBuilder != null) { - return customImageProviderBuilder(imageUrl); - } - if (isHttpBasedUrl(imageUrl)) { - return NetworkImage(imageUrl); - } - - return FileImage(File(imageUrl)); - } - @override Widget build(BuildContext context) { return Scaffold( @@ -134,9 +121,9 @@ class ImageTapWrapper extends StatelessWidget { child: Stack( children: [ PhotoView( - imageProvider: _imageProviderByUrl( + imageProvider: getImageProviderByImageSource( imageUrl, - customImageProviderBuilder: imageProviderBuilder, + imageProviderBuilder: imageProviderBuilder, ), errorBuilder: imageErrorWidgetBuilder, loadingBuilder: (context, event) { @@ -173,8 +160,11 @@ class ImageTapWrapper extends StatelessWidget { bottom: 0, left: 0, right: 0, - child: - Icon(Icons.close, color: Colors.grey[400], size: 28), + child: Icon( + Icons.close, + color: Colors.grey[400], + size: 28, + ), ) ], ), diff --git a/flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart b/flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart index 3e159d0e..518b61ed 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart @@ -12,6 +12,7 @@ import '../../../../embeds/embed_types/image.dart'; @immutable class QuillEditorImageEmbedConfigurations { const QuillEditorImageEmbedConfigurations({ + @Deprecated('This will be deleted in 0.7.0 as we will have one menu') this.forceUseMobileOptionMenuForImageClick = false, ImageEmbedBuilderOnRemovedCallback? onImageRemovedCallback, this.shouldRemoveImageCallback, @@ -161,6 +162,7 @@ class QuillEditorImageEmbedConfigurations { imageProviderBuilder: imageProviderBuilder ?? this.imageProviderBuilder, imageErrorWidgetBuilder: imageErrorWidgetBuilder ?? this.imageErrorWidgetBuilder, + // ignore: deprecated_member_use_from_same_package forceUseMobileOptionMenuForImageClick: forceUseMobileOptionMenuForImageClick ?? this.forceUseMobileOptionMenuForImageClick, diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 03a3d162..3df390cd 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 0.6.4 +version: 0.6.5 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions diff --git a/lib/src/models/structs/optional_size.dart b/lib/src/models/structs/optional_size.dart index 49d274c8..8362dee3 100644 --- a/lib/src/models/structs/optional_size.dart +++ b/lib/src/models/structs/optional_size.dart @@ -1,3 +1,4 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first import 'package:meta/meta.dart' show immutable; @immutable @@ -14,4 +15,14 @@ class OptionalSize { /// If non-null, requires the child to have exactly this height. /// If null, the child is free to choose its own height. final double? height; + + OptionalSize copyWith({ + double? width, + double? height, + }) { + return OptionalSize( + width ?? this.width, + height ?? this.height, + ); + } } diff --git a/lib/src/utils/string.dart b/lib/src/utils/string.dart index fe0207de..2975cf60 100644 --- a/lib/src/utils/string.dart +++ b/lib/src/utils/string.dart @@ -54,9 +54,10 @@ String replaceStyleStringWithSize( return sb.toString(); } -Alignment getAlignment(String? s) { +/// Get flutter [Alignment] value by [cssAlignment] +Alignment getAlignment(String? cssAlignment) { const defaultAlignment = Alignment.center; - if (s == null) { + if (cssAlignment == null) { return defaultAlignment; } @@ -70,7 +71,7 @@ Alignment getAlignment(String? s) { 'bottomLeft', 'bottomCenter', 'bottomRight' - ].indexOf(s); + ].indexOf(cssAlignment); if (index < 0) { return defaultAlignment; } diff --git a/lib/src/widgets/text_line.dart b/lib/src/widgets/text_line.dart index 0d1243d3..5f095dc7 100644 --- a/lib/src/widgets/text_line.dart +++ b/lib/src/widgets/text_line.dart @@ -143,15 +143,23 @@ class _TextLineState extends State { var embed = widget.line.children.single as Embed; // Creates correct node for custom embed if (embed.value.type == BlockEmbed.customType) { - embed = Embed(CustomBlockEmbed.fromJsonString(embed.value.data)); + embed = Embed( + CustomBlockEmbed.fromJsonString(embed.value.data), + ); } final embedBuilder = widget.embedBuilder(embed); if (embedBuilder.expanded) { // Creates correct node for custom embed final lineStyle = _getLineStyle(widget.styles); return EmbedProxy( - embedBuilder.build(context, widget.controller, embed, widget.readOnly, - false, lineStyle), + embedBuilder.build( + context, + widget.controller, + embed, + widget.readOnly, + false, + lineStyle, + ), ); } } @@ -167,12 +175,13 @@ class _TextLineState extends State { textScaleFactor: MediaQuery.textScaleFactorOf(context), ); return RichTextProxy( - textStyle: textSpan.style!, - textAlign: textAlign, - textDirection: widget.textDirection!, - strutStyle: strutStyle, - locale: Localizations.localeOf(context), - child: child); + textStyle: textSpan.style!, + textAlign: textAlign, + textDirection: widget.textDirection!, + strutStyle: strutStyle, + locale: Localizations.localeOf(context), + child: child, + ); } InlineSpan _getTextSpanForWholeLine(BuildContext context) { diff --git a/pubspec.yaml b/pubspec.yaml index 18f2f9ce..437590ff 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.4.0 +version: 8.4.1 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From 700f0038660e7242818f16d4e48a5fc8b9ac1fb9 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 10 Nov 2023 23:28:52 +0300 Subject: [PATCH 103/210] Update todo.md --- doc/todo.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/todo.md b/doc/todo.md index ab746b7e..7b8aa9b8 100644 --- a/doc/todo.md +++ b/doc/todo.md @@ -21,6 +21,7 @@ This is a todo list page that added recently and will be updated soon. 1. Add a method to set TextInputAction, fore more [info](https://github.com/singerdmx/flutter-quill/issues/1328) 2. Add support for Text magnification feature, for more [info](https://github.com/singerdmx/flutter-quill/issues/1504) 3. Provide a way to expose quills undo redo stacks, for more [info](https://github.com/singerdmx/flutter-quill/issues/1381) + 4. Add callback to the `QuillToolbarColorButton` for custom color picking logic ### Improvemenets From 2104514f6e7b64e49b34effb1e6fd0ac90720b0b Mon Sep 17 00:00:00 2001 From: Ellet Date: Sat, 11 Nov 2023 04:34:41 +0300 Subject: [PATCH 104/210] Update flutter_quill and flutter_quill_extensions (#1520) * Update flutter_quill and flutter_quill_extensions --- CHANGELOG.md | 8 + doc/todo.md | 1 + .../android/app/src/main/AndroidManifest.xml | 6 + example/lib/pages/home_page.dart | 44 ++- example/pubspec.yaml | 5 +- example/web/index.html | 5 + flutter_quill_extensions/CHANGELOG.md | 4 + .../embeds/editor/image/image.dart | 41 ++- .../embeds/editor/image/image_menu.dart | 9 +- .../toolbar/camera_button/camera_button.dart | 15 +- .../embeds/widgets/image_resizer.dart | 4 +- .../models/config/editor/image/image.dart | 18 +- flutter_quill_extensions/pubspec.yaml | 2 +- lib/flutter_quill.dart | 2 + .../models/config/editor/configurations.dart | 8 +- .../config/raw_editor/configurations.dart | 290 ++++++++++++++++++ lib/src/utils/extensions/build_context.dart | 2 +- lib/src/utils/string.dart | 4 +- lib/src/widgets/editor/editor.dart | 117 +++---- lib/src/widgets/raw_editor/raw_editor.dart | 250 +-------------- .../raw_editor/raw_editor_actions.dart | 18 +- .../widgets/raw_editor/raw_editor_state.dart | 178 +++++------ ...editor_state_selection_delegate_mixin.dart | 32 +- ..._editor_state_text_input_client_mixin.dart | 37 ++- .../widgets/toolbar/buttons/quill_icon.dart | 8 + .../toolbar/buttons/select_header_style.dart | 2 + lib/src/widgets/utils/provider.dart | 8 +- pubspec.yaml | 2 +- 28 files changed, 642 insertions(+), 478 deletions(-) create mode 100644 lib/src/models/config/raw_editor/configurations.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a9b7268..0cba5b33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [8.4.2] +- **Breaking change**: The `QuillRawEditor` configurations has been moved to a seperated class, also the `readOnly` has been renamed to `isReadOnly`, if you are using the `QuillEditor` you don't have to change anything +- Allow the developer to use override the `TextInputAction` in both `QuillRawEditor` and `QuillEditor` +- You can use now the `QuillRawEditor` without `QuillEditorProvider` +- Bug fixes +- Add implementation of image cropping in the `example` +- Update the `QuillToolbarIconButton` to use the material 3 buttons + ## [8.4.1] - Add `copyWith` in `OptionalSize` class diff --git a/doc/todo.md b/doc/todo.md index 7b8aa9b8..d31c9c73 100644 --- a/doc/todo.md +++ b/doc/todo.md @@ -27,6 +27,7 @@ This is a todo list page that added recently and will be updated soon. 1. Improve the Raw Quill Editor, for more [info](https://github.com/singerdmx/flutter-quill/issues/1509) 2. Provide more support to all the platforms + 3. Extract the shared properties between `QuillRawEditorConfigurations` and `QuillEditorConfigurations` ### Bugs diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 1d6e0b64..6176738c 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -42,6 +42,12 @@ + + + { ); } + /// When inserting an image + OnImageInsertCallback get onImageInsert { + return (image, controller) async { + final croppedFile = await ImageCropper().cropImage( + sourcePath: image, + aspectRatioPresets: [ + CropAspectRatioPreset.square, + CropAspectRatioPreset.ratio3x2, + CropAspectRatioPreset.original, + CropAspectRatioPreset.ratio4x3, + CropAspectRatioPreset.ratio16x9 + ], + uiSettings: [ + AndroidUiSettings( + toolbarTitle: 'Cropper', + toolbarColor: Colors.deepOrange, + toolbarWidgetColor: Colors.white, + initAspectRatio: CropAspectRatioPreset.original, + lockAspectRatio: false, + ), + IOSUiSettings( + title: 'Cropper', + ), + WebUiSettings( + context: context, + ), + ], + ); + final newImage = croppedFile?.path; + if (newImage == null) { + return; + } + controller.insertImageBlock(imageSource: newImage); + }; + } + QuillToolbar get quillToolbar { final customButtons = [ QuillToolbarCustomButtonOptions( @@ -481,13 +518,14 @@ class _HomePageState extends State { configurations: QuillToolbarConfigurations( customButtons: customButtons, embedButtons: FlutterQuillEmbeds.toolbarButtons( + cameraButtonOptions: const QuillToolbarCameraButtonOptions(), imageButtonOptions: QuillToolbarImageButtonOptions( imageButtonConfigurations: QuillToolbarImageConfigurations( onImageInsertedCallback: (image) async { _onImagePickCallback(File(image)); }, + onImageInsertCallback: onImageInsert, ), - // webImagePickImpl: _webImagePickImpl, ), ), buttonOptions: QuillToolbarButtonOptions( @@ -496,7 +534,6 @@ class _HomePageState extends State { ), ), ), - // afterButtonPressed: _focusNode.requestFocus, ); } if (isDesktop(supportWeb: false)) { @@ -504,6 +541,7 @@ class _HomePageState extends State { configurations: QuillToolbarConfigurations( customButtons: customButtons, embedButtons: FlutterQuillEmbeds.toolbarButtons( + cameraButtonOptions: const QuillToolbarCameraButtonOptions(), imageButtonOptions: QuillToolbarImageButtonOptions( imageButtonConfigurations: QuillToolbarImageConfigurations( onImageInsertedCallback: (image) async { @@ -525,6 +563,7 @@ class _HomePageState extends State { configurations: QuillToolbarConfigurations( customButtons: customButtons, embedButtons: FlutterQuillEmbeds.toolbarButtons( + cameraButtonOptions: const QuillToolbarCameraButtonOptions(), videoButtonOptions: QuillToolbarVideoButtonOptions( videoConfigurations: QuillToolbarVideoConfigurations( onVideoInsertedCallback: (video) => @@ -533,6 +572,7 @@ class _HomePageState extends State { ), imageButtonOptions: QuillToolbarImageButtonOptions( imageButtonConfigurations: QuillToolbarImageConfigurations( + onImageInsertCallback: onImageInsert, onImageInsertedCallback: (image) async { _onImagePickCallback(File(image)); }, diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 5ff55f23..ccdf1958 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -17,10 +17,11 @@ dependencies: path_provider: ^2.1.1 # filesystem_picker: ^4.0.0 file_picker: ^6.1.1 - flutter_quill: ^8.2.5 - flutter_quill_extensions: ^0.6.3 + flutter_quill: ^8.4.1 + flutter_quill_extensions: ^0.6.5 path: ^1.8.3 desktop_drop: ^0.4.4 + image_cropper: ^5.0.0 dependency_overrides: flutter_quill: diff --git a/example/web/index.html b/example/web/index.html index 45cf2ca3..1029dffd 100644 --- a/example/web/index.html +++ b/example/web/index.html @@ -32,6 +32,11 @@ example + + + + + diff --git a/example/windows/flutter/generated_plugin_registrant.cc b/example/windows/flutter/generated_plugin_registrant.cc index 9e89e3c8..ef6dc906 100644 --- a/example/windows/flutter/generated_plugin_registrant.cc +++ b/example/windows/flutter/generated_plugin_registrant.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { @@ -21,6 +22,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("GalPluginCApi")); PasteboardPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("PasteboardPlugin")); + SharePlusWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/example/windows/flutter/generated_plugins.cmake b/example/windows/flutter/generated_plugins.cmake index f3449e49..abc6f627 100644 --- a/example/windows/flutter/generated_plugins.cmake +++ b/example/windows/flutter/generated_plugins.cmake @@ -7,6 +7,7 @@ list(APPEND FLUTTER_PLUGIN_LIST file_selector_windows gal pasteboard + share_plus url_launcher_windows ) diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_menu.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_menu.dart index ea519af8..3b7f34bb 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_menu.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_menu.dart @@ -1,6 +1,6 @@ import 'package:flutter/cupertino.dart' show showCupertinoModalPopup; import 'package:flutter/material.dart'; -import 'package:flutter_quill/extensions.dart' show isDesktop, isMobile; +import 'package:flutter_quill/extensions.dart' show isMobile; import 'package:flutter_quill/flutter_quill.dart' show ImageUrl, QuillController, StyleAttribute, getEmbedNode; import 'package:flutter_quill/translations.dart'; @@ -133,7 +133,6 @@ class ImageOptionsMenu extends StatelessWidget { ListTile( leading: const Icon(Icons.save), title: Text(context.loc.save), - enabled: !isDesktop(supportWeb: false), onTap: () async { final messenger = ScaffoldMessenger.of(context); final localizations = context.loc; @@ -143,7 +142,7 @@ class ImageOptionsMenu extends StatelessWidget { imageUrl: imageSource, imageSaverService: imageSaverService, ); - final imageSavedSuccessfully = saveImageResult.isSuccess; + final imageSavedSuccessfully = saveImageResult.error == null; messenger.clearSnackBars(); diff --git a/flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart b/flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart index ed7e5abe..8d6646f0 100644 --- a/flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart +++ b/flutter_quill_extensions/lib/presentation/models/config/editor/image/image.dart @@ -101,6 +101,9 @@ class QuillEditorImageEmbedConfigurations { /// final ImageEmbedBuilderErrorWidgetBuilder? imageErrorWidgetBuilder; + /// What should happen when the image is pressed? + /// + /// By default will show `ImageOptionsMenu` dialog final VoidCallback? onImageClicked; static ImageEmbedBuilderOnRemovedCallback get defaultOnImageRemovedCallback { diff --git a/flutter_quill_extensions/lib/presentation/utils/utils.dart b/flutter_quill_extensions/lib/presentation/utils/utils.dart index fe25b7c4..00e986fd 100644 --- a/flutter_quill_extensions/lib/presentation/utils/utils.dart +++ b/flutter_quill_extensions/lib/presentation/utils/utils.dart @@ -45,9 +45,9 @@ enum SaveImageResultMethod { network, localStorage } @immutable class SaveImageResult { - const SaveImageResult({required this.isSuccess, required this.method}); + const SaveImageResult({required this.error, required this.method}); - final bool isSuccess; + final String? error; final SaveImageResultMethod method; } @@ -67,12 +67,12 @@ Future saveImage({ Uri.parse(appendFileExtensionToImageUrl(imageUrl)), ); return const SaveImageResult( - isSuccess: true, + error: null, method: SaveImageResultMethod.network, ); } catch (e) { - return const SaveImageResult( - isSuccess: false, + return SaveImageResult( + error: e.toString(), method: SaveImageResultMethod.network, ); } @@ -80,12 +80,12 @@ Future saveImage({ try { await imageSaverService.saveLocalImage(imageUrl); return const SaveImageResult( - isSuccess: true, + error: null, method: SaveImageResultMethod.localStorage, ); } catch (e) { - return const SaveImageResult( - isSuccess: false, + return SaveImageResult( + error: e.toString(), method: SaveImageResultMethod.localStorage, ); } diff --git a/lib/src/models/documents/nodes/embeddable.dart b/lib/src/models/documents/nodes/embeddable.dart index 1db18da8..24903315 100644 --- a/lib/src/models/documents/nodes/embeddable.dart +++ b/lib/src/models/documents/nodes/embeddable.dart @@ -1,4 +1,4 @@ -import 'dart:convert'; +import 'dart:convert' show jsonDecode, jsonEncode; /// An object which can be embedded into a Quill document. /// diff --git a/lib/src/utils/platform.dart b/lib/src/utils/platform.dart index 020cfae3..a06db05c 100644 --- a/lib/src/utils/platform.dart +++ b/lib/src/utils/platform.dart @@ -2,10 +2,12 @@ import 'dart:io' show Platform; import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/foundation.dart' - show kIsWeb, TargetPlatform, defaultTargetPlatform; + show TargetPlatform, defaultTargetPlatform, kIsWeb, visibleForTesting; /// If you want to override the [kIsWeb] use [overrideIsWeb] -bool isWeb({bool? overrideIsWeb}) { +bool isWeb({ + @visibleForTesting bool? overrideIsWeb, +}) { return overrideIsWeb ?? kIsWeb; } diff --git a/pubspec.yaml b/pubspec.yaml index c120d033..cb3ea9e7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,13 +13,13 @@ topics: screenshots: - description: 'Screenshot 1' - path: example/assets/images/1.png + path: example/assets/images/screenshot_1.png - description: 'Screenshot 2' - path: example/assets/images/2.png + path: example/assets/images/screenshot_2.png - description: 'Screenshot 3' - path: example/assets/images/3.png + path: example/assets/images/screenshot_3.png - description: 'Screenshot 4' - path: example/assets/images/4.png + path: example/assets/images/screenshot_4.png platforms: android: From 1dac7648352257d81b820cfba1850c96f0802247 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 14 Nov 2023 21:21:04 +0300 Subject: [PATCH 183/210] Prepare for publishing --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index cb3ea9e7..80a511af 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.5.3 +version: 0.6.10 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From f931d023de2f0b864182a62a0e3a5ef80ae05688 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 14 Nov 2023 21:30:09 +0300 Subject: [PATCH 184/210] Fix typos --- CHANGELOG.md | 802 +++++++++++++------------- flutter_quill_extensions/CHANGELOG.md | 132 ++--- 2 files changed, 467 insertions(+), 467 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b97d6959..2da2940c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,436 +3,436 @@ All notable changes to this project will be documented in this file. ## 8.5.4 -- The `mobileWidth`, `mobileHeight`, `mobileMargin` and `mobileAlignment` is now deprecated in `flutter_quill`, they are are now defined in `flutter_quill_extensions` -- Deprecate `replaceStyleStringWithSize` function which is in `string.dart` -- Deprecate `alignment`, and `margin` as they don't confirm to offical Quill JS +* The `mobileWidth`, `mobileHeight`, `mobileMargin` and `mobileAlignment` is now deprecated in `flutter_quill`, they are are now defined in `flutter_quill_extensions` +* Deprecate `replaceStyleStringWithSize` function which is in `string.dart` +* Deprecate `alignment`, and `margin` as they don't conform to official Quill JS ## 8.5.3 -- Update doc -- Update `README.md` and `CHANGELOG.md` -- Fix typos -- Use `immutable` when possible -- Update `.pubignore` +* Update doc +* Update `README.md` and `CHANGELOG.md` +* Fix typos +* Use `immutable` when possible +* Update `.pubignore` ## 8.5.2 -- Updated `README.md`. -- Feature: Added the ability to include a custom callback when the `QuillToolbarColorButton` is pressed. -- The `QuillToolbar` now implements `PreferredSizeWidget`, enabling usage in the AppBar, similar to `QuillBaseToolbar`. +* Updated `README.md`. +* Feature: Added the ability to include a custom callback when the `QuillToolbarColorButton` is pressed. +* The `QuillToolbar` now implements `PreferredSizeWidget`, enabling usage in the AppBar, similar to `QuillBaseToolbar`. ## 8.5.1 -- Updated `README.md`. +* Updated `README.md`. ## 8.5.0 -- Migrated to `flutter_localizations` for translations. -- Fixed: Translated all previously untranslated localizations. -- Fixed: Added translations for missing items. -- Fixed: Introduced default Chinese fallback translation. -- Removed: Unused parameters `items` in `QuillToolbarFontFamilyButtonOptions` and `QuillToolbarFontSizeButtonOptions`. -- Updated: Documentation. +* Migrated to `flutter_localizations` for translations. +* Fixed: Translated all previously untranslated localizations. +* Fixed: Added translations for missing items. +* Fixed: Introduced default Chinese fallback translation. +* Removed: Unused parameters `items` in `QuillToolbarFontFamilyButtonOptions` and `QuillToolbarFontSizeButtonOptions`. +* Updated: Documentation. ## 8.4.4 -- Updated `.pubignore` to ignore unnecessary files and folders. +* Updated `.pubignore` to ignore unnecessary files and folders. ## 8.4.3 -- Updated `CHANGELOG.md`. +* Updated `CHANGELOG.md`. ## 8.4.2 -- **Breaking change**: Configuration for `QuillRawEditor` has been moved to a separate class. Additionally, `readOnly` has been renamed to `isReadOnly`. If using `QuillEditor`, no action is required. -- Introduced the ability for developers to override `TextInputAction` in both `QuillRawEditor` and `QuillEditor`. -- Enabled using `QuillRawEditor` without `QuillEditorProvider`. -- Bug fixes. -- Added image cropping implementation in the example. +* **Breaking change**: Configuration for `QuillRawEditor` has been moved to a separate class. Additionally, `readOnly` has been renamed to `isReadOnly`. If using `QuillEditor`, no action is required. +* Introduced the ability for developers to override `TextInputAction` in both `QuillRawEditor` and `QuillEditor`. +* Enabled using `QuillRawEditor` without `QuillEditorProvider`. +* Bug fixes. +* Added image cropping implementation in the example. ## 8.4.1 -- Added `copyWith` in `OptionalSize` class. +* Added `copyWith` in `OptionalSize` class. ## 8.4.0 -- **Breaking change**: Updated `QuillCustomButton` to use `QuillCustomButtonOptions`. Moved all properties from `QuillCustomButton` to `QuillCustomButtonOptions`, replacing `iconData` with `icon` widget for increased customization. -- **Breaking change**: `customButtons` in `QuillToolbarConfigurations` is now of type `List`. -- Bug fixes following the `8.0.0` update. -- Updated `README.md`. -- Improved platform checking. +* **Breaking change**: Updated `QuillCustomButton` to use `QuillCustomButtonOptions`. Moved all properties from `QuillCustomButton` to `QuillCustomButtonOptions`, replacing `iconData` with `icon` widget for increased customization. +* **Breaking change**: `customButtons` in `QuillToolbarConfigurations` is now of type `List`. +* Bug fixes following the `8.0.0` update. +* Updated `README.md`. +* Improved platform checking. ## 8.3.0 -- Added `iconButtonFactor` property to `QuillToolbarBaseButtonOptions` for customizing button size relative to its icon size (defaults to `kIconButtonFactor`, consistent with previous releases). +* Added `iconButtonFactor` property to `QuillToolbarBaseButtonOptions` for customizing button size relative to its icon size (defaults to `kIconButtonFactor`, consistent with previous releases). ## 8.2.6 -- Organized `QuillRawEditor` code. +* Organized `QuillRawEditor` code. ## 8.2.5 -- Added `builder` property in `QuillEditorConfigurations`. +* Added `builder` property in `QuillEditorConfigurations`. ## 8.2.4 -- Adhered to Flutter best practices. -- Fixed auto-focus bug. +* Adhered to Flutter best practices. +* Fixed auto-focus bug. ## 8.2.3 -- Updated `README.md`. +* Updated `README.md`. ## 8.2.2 -- Moved `flutter_quill_test` to a separate package: [flutter_quill_test](https://pub.dev/packages/flutter_quill_test). +* Moved `flutter_quill_test` to a separate package: [flutter_quill_test](https://pub.dev/packages/flutter_quill_test). ## 8.2.1 -- Updated `README.md`. +* Updated `README.md`. ## 8.2.0 -- Added the option to add configurations for `flutter_quill_extensions` using `extraConfigurations`. +* Added the option to add configurations for `flutter_quill_extensions` using `extraConfigurations`. ## 8.1.11 -- Followed Dart best practices by using `lints` and removed `pedantic` and `platform` since they are not used. -- Fixed text direction bug. -- Updated `README.md`. +* Followed Dart best practices by using `lints` and removed `pedantic` and `platform` since they are not used. +* Fixed text direction bug. +* Updated `README.md`. ## 8.1.10 -- Secret for automated publishing to pub.dev. +* Secret for automated publishing to pub.dev. ## 8.1.9 -- Fixed automated publishing to pub.dev. +* Fixed automated publishing to pub.dev. ## 8.1.8 -- Fixed automated publishing to pub.dev. +* Fixed automated publishing to pub.dev. ## 8.1.7 -- Automated publishing to pub.dev. +* Automated publishing to pub.dev. ## 8.1.6 -- Fixed compatibility with `integration_test` by downgrading the minimum version of the platform package to 3.1.0. +* Fixed compatibility with `integration_test` by downgrading the minimum version of the platform package to 3.1.0. ## 8.1.5 -- Reversed background/font color toolbar button icons. +* Reversed background/font color toolbar button icons. ## 8.1.4 -- Reversed background/font color toolbar button tooltips. +* Reversed background/font color toolbar button tooltips. ## 8.1.3 -- Moved images to screenshots instead of `README.md`. +* Moved images to screenshots instead of `README.md`. ## 8.1.2 -- Fixed a bug related to the regexp of the insert link dialog. -- Required Dart 3 as the minimum version. -- Code cleanup. -- Added a spacer widget between each button in the `QuillToolbar`. +* Fixed a bug related to the regexp of the insert link dialog. +* Required Dart 3 as the minimum version. +* Code cleanup. +* Added a spacer widget between each button in the `QuillToolbar`. ## 8.1.1 -- Fixed null error in line.dart #1487(https://github.com/singerdmx/flutter-quill/issues/1487). +* Fixed null error in line.dart #1487(https://github.com/singerdmx/flutter*quill/issues/1487). ## 8.1.0 -- Fixed a word typo of `mirgration` to `migration` in the readme & migration document. -- Updated migration guide. -- Removed property `enableUnfocusOnTapOutside` in `QuillEditor` configurations and added `isOnTapOutsideEnabled` instead. -- Added a new callback called `onTapOutside` in the `QuillEditorConfigurations` to perform actions when tapping outside the editor. -- Fixed a bug that caused the web platform to not unfocus the editor when tapping outside of it. To override this, please pass a value to the `onTapOutside` callback. -- Removed the old property of `iconTheme`. Instead, pass `iconTheme` in the button options; you will find the `base` property inside it with `iconTheme`. +* Fixed a word typo of `mirgration` to `migration` in the readme & migration document. +* Updated migration guide. +* Removed property `enableUnfocusOnTapOutside` in `QuillEditor` configurations and added `isOnTapOutsideEnabled` instead. +* Added a new callback called `onTapOutside` in the `QuillEditorConfigurations` to perform actions when tapping outside the editor. +* Fixed a bug that caused the web platform to not unfocus the editor when tapping outside of it. To override this, please pass a value to the `onTapOutside` callback. +* Removed the old property of `iconTheme`. Instead, pass `iconTheme` in the button options; you will find the `base` property inside it with `iconTheme`. ## 8.0.0 -- If you have migrated recently, don't be alarmed by this update; it adds documentation, a migration guide, and marks the version as a more stable release. Although there are breaking changes (as reported by some developers), the major version was not changed due to time constraints during development. A single property was also renamed from `code` to `codeBlock` in the `elements` of the new `QuillEditorConfigurations` class. -- Updated the README for better readability. +* If you have migrated recently, don't be alarmed by this update; it adds documentation, a migration guide, and marks the version as a more stable release. Although there are breaking changes (as reported by some developers), the major version was not changed due to time constraints during development. A single property was also renamed from `code` to `codeBlock` in the `elements` of the new `QuillEditorConfigurations` class. +* Updated the README for better readability. ## 7.10.2 -- Removed line numbers from code blocks by default. You can still enable this feature thanks to the new configurations in the `QuillEditor`. Find the `elementOptions` property and enable `enableLineNumbers`. +* Removed line numbers from code blocks by default. You can still enable this feature thanks to the new configurations in the `QuillEditor`. Find the `elementOptions` property and enable `enableLineNumbers`. ## 7.10.1 -- Fixed issues and utilized the new parameters. -- No longer need to use `MaterialApp` for most toolbar button child builders. -- Compatibility with [fresh_quill_extensions](https://pub.dev/packages/fresh_quill_extensions), a temporary alternative to [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions). -- Updated most of the documentation in `README.md`. +* Fixed issues and utilized the new parameters. +* No longer need to use `MaterialApp` for most toolbar button child builders. +* Compatibility with [fresh_quill_extensions](https://pub.dev/packages/fresh_quill_extensions), a temporary alternative to [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions). +* Updated most of the documentation in `README.md`. ## 7.10.0 -- **Breaking change**: `QuillToolbar.basic()` can be accessed directly from `QuillToolbar()`, and the old `QuillToolbar` can be accessed from `QuillBaseToolbar`. -- Refactored Quill editor and toolbar configurations into a single class each. -- After changing checkbox list values, the controller will not request keyboard focus by default. -- Moved toolbar and editor configurations directly into the widget but still use inherited widgets internally. -- Fixes to some code after the refactoring. +* **Breaking change**: `QuillToolbar.basic()` can be accessed directly from `QuillToolbar()`, and the old `QuillToolbar` can be accessed from `QuillBaseToolbar`. +* Refactored Quill editor and toolbar configurations into a single class each. +* After changing checkbox list values, the controller will not request keyboard focus by default. +* Moved toolbar and editor configurations directly into the widget but still use inherited widgets internally. +* Fixes to some code after the refactoring. ## 7.1.14 -- Add indents change for multiline selection. +* Add indents change for multiline selection. ## 7.1.13 -- Add custom recognizer. +* Add custom recognizer. ## 7.1.12 -- Add superscript and subscript styles. +* Add superscript and subscript styles. ## 7.1.11 -- Add inserting indents for lines of list if text is selected. +* Add inserting indents for lines of list if text is selected. ## 7.1.10 -- Image embedding tweaks - - Add MediaButton which is intened to superseed the ImageButton and VideoButton. Only image selection is working. - - Implement image insert for web (image as base64) +* Image embedding tweaks + * Add MediaButton which is intened to superseed the ImageButton and VideoButton. Only image selection is working. + * Implement image insert for web (image as base64) ## 7.1.9 -- Editor tweaks PR from bambinoua(https://github.com/bambinoua). - - Shortcuts now working in Mac OS - - QuillDialogTheme is extended with new properties buttonStyle, linkDialogConstraints, imageDialogConstraints, isWrappable, runSpacing, - - Added LinkStyleButton2 with new LinkStyleDialog (similar to Quill implementation - - Conditinally use Row or Wrap for dialog's children. - - Update minimum Dart SDK version to 2.17.0 to use enum extensions. - - Use merging shortcuts and actions correclty (if the key combination is the same) +* Editor tweaks PR from bambinoua(https://github.com/bambinoua). + * Shortcuts now working in Mac OS + * QuillDialogTheme is extended with new properties buttonStyle, linkDialogConstraints, imageDialogConstraints, isWrappable, runSpacing, + * Added LinkStyleButton2 with new LinkStyleDialog (similar to Quill implementation + * Conditinally use Row or Wrap for dialog's children. + * Update minimum Dart SDK version to 2.17.0 to use enum extensions. + * Use merging shortcuts and actions correclty (if the key combination is the same) ## 7.1.8 -- Dropdown tweaks - - Add itemHeight, itemPadding, defaultItemColor for customization of dropdown items. - - Remove alignment property as useless. - - Fix bugs with max width when width property is null. +* Dropdown tweaks + * Add itemHeight, itemPadding, defaultItemColor for customization of dropdown items. + * Remove alignment property as useless. + * Fix bugs with max width when width property is null. ## 7.1.7 -- Toolbar tweaks. - - Implement tooltips for embed CameraButton, VideoButton, FormulaButton, ImageButton. - - Extends customization for SelectAlignmentButton, QuillFontFamilyButton, QuillFontSizeButton adding padding, text style, alignment, width. - - Add renderFontFamilies to QuillFontFamilyButton to show font faces in dropdown. - - Add AxisDivider and its named constructors for for use in parent project. - - Export ToolbarButtons enum to allow specify tooltips for SelectAlignmentButton. - - Export QuillFontFamilyButton, SearchButton as they were not exported before. - - Deprecate items property in QuillFontFamilyButton, QuillFontSizeButton as the it can be built usinr rawItemsMap. - - Make onSelection QuillFontFamilyButton, QuillFontSizeButton omittable as no need to execute callback outside if controller is passed to widget. +* Toolbar tweaks. + * Implement tooltips for embed CameraButton, VideoButton, FormulaButton, ImageButton. + * Extends customization for SelectAlignmentButton, QuillFontFamilyButton, QuillFontSizeButton adding padding, text style, alignment, width. + * Add renderFontFamilies to QuillFontFamilyButton to show font faces in dropdown. + * Add AxisDivider and its named constructors for for use in parent project. + * Export ToolbarButtons enum to allow specify tooltips for SelectAlignmentButton. + * Export QuillFontFamilyButton, SearchButton as they were not exported before. + * Deprecate items property in QuillFontFamilyButton, QuillFontSizeButton as the it can be built usinr rawItemsMap. + * Make onSelection QuillFontFamilyButton, QuillFontSizeButton omittable as no need to execute callback outside if controller is passed to widget. Now the package is more friendly for web projects. ## 7.1.6 -- Add enableUnfocusOnTapOutside field to RawEditor and Editor widgets. +* Add enableUnfocusOnTapOutside field to RawEditor and Editor widgets. ## 7.1.5 -- Add tooltips for toolbar buttons. +* Add tooltips for toolbar buttons. ## 7.1.4 -- Fix inserting tab character in lists. +* Fix inserting tab character in lists. ## 7.1.3 -- Fix ios cursor bug when word.length==1. +* Fix ios cursor bug when word.length==1. ## 7.1.2 -- Fix non scrollable editor exception, when tapped under content. +* Fix non scrollable editor exception, when tapped under content. ## 7.1.1 -- customLinkPrefixes parameter - makes possible to open links with custom protoco. +* customLinkPrefixes parameter * makes possible to open links with custom protoco. ## 7.1.0 -- Fix ordered list numeration with several lists in document. +* Fix ordered list numeration with several lists in document. ## 7.0.9 -- Use const constructor for EmbedBuilder. +* Use const constructor for EmbedBuilder. ## 7.0.8 -- Fix IME position bug with scroller. +* Fix IME position bug with scroller. ## 7.0.7 -- Add TextFieldTapRegion for contextMenu. +* Add TextFieldTapRegion for contextMenu. ## 7.0.6 -- Fix line style loss on new line from non string. +* Fix line style loss on new line from non string. ## 7.0.5 -- Fix IME position bug for Mac and Windows. -- Unfocus when tap outside editor. fix the bug that cant refocus in afterButtonPressed after click ToggleStyleButton on Mac. +* Fix IME position bug for Mac and Windows. +* Unfocus when tap outside editor. fix the bug that cant refocus in afterButtonPressed after click ToggleStyleButton on Mac. ## 7.0.4 -- Have text selection span full line height for uneven sized text. +* Have text selection span full line height for uneven sized text. ## 7.0.3 -- Fix ordered list numeration for lists with more than one level of list. +* Fix ordered list numeration for lists with more than one level of list. ## 7.0.2 -- Allow widgets to override widget span properties. +* Allow widgets to override widget span properties. ## 7.0.1 -- Update i18n_extension dependency to version 8.0.0. +* Update i18n_extension dependency to version 8.0.0. ## 7.0.0 -- Breaking change: Tuples are no longer used. They have been replaced with a number of data classes. +* Breaking change: Tuples are no longer used. They have been replaced with a number of data classes. ## 6.4.4 -- Increased compatibility with Flutter widget tests. +* Increased compatibility with Flutter widget tests. ## 6.4.3 -- Update dependencies (collection: 1.17.0, flutter_keyboard_visibility: 5.4.0, quiver: 3.2.1, tuple: 2.0.1, url_launcher: 6.1.9, characters: 1.2.1, i18n_extension: 7.0.0, device_info_plus: 8.1.0) +* Update dependencies (collection: 1.17.0, flutter_keyboard_visibility: 5.4.0, quiver: 3.2.1, tuple: 2.0.1, url_launcher: 6.1.9, characters: 1.2.1, i18n_extension: 7.0.0, device_info_plus: 8.1.0) ## 6.4.2 -- Replace `buildToolbar` with `contextMenuBuilder`. +* Replace `buildToolbar` with `contextMenuBuilder`. ## 6.4.1 -- Control the detect word boundary behaviour. +* Control the detect word boundary behaviour. ## 6.4.0 -- Use `axis` to make the toolbar vertical. -- Use `toolbarIconCrossAlignment` to align the toolbar icons on the cross axis. -- Breaking change: `QuillToolbar`'s parameter `toolbarHeight` was renamed to `toolbarSize`. +* Use `axis` to make the toolbar vertical. +* Use `toolbarIconCrossAlignment` to align the toolbar icons on the cross axis. +* Breaking change: `QuillToolbar`'s parameter `toolbarHeight` was renamed to `toolbarSize`. ## 6.3.5 -- Ability to add custom shortcuts. +* Ability to add custom shortcuts. ## 6.3.4 -- Update clipboard status prior to showing selected text overlay. +* Update clipboard status prior to showing selected text overlay. ## 6.3.3 -- Fixed handling of mac intents. +* Fixed handling of mac intents. ## 6.3.2 -- Added `unknownEmbedBuilder` to QuillEditor. -- Fix error style when input chinese japanese or korean. +* Added `unknownEmbedBuilder` to QuillEditor. +* Fix error style when input chinese japanese or korean. ## 6.3.1 -- Add color property to the basic factory function. +* Add color property to the basic factory function. ## 6.3.0 -- Support Flutter 3.7. +* Support Flutter 3.7. ## 6.2.2 -- Fix: nextLine getter null where no assertion. +* Fix: nextLine getter null where no assertion. ## 6.2.1 -- Revert "Align numerical and bullet lists along with text content". +* Revert "Align numerical and bullet lists along with text content". ## 6.2.0 -- Align numerical and bullet lists along with text content. +* Align numerical and bullet lists along with text content. ## 6.1.12 -- Apply i18n for default font dropdown option labels corresponding to 'Clear'. +* Apply i18n for default font dropdown option labels corresponding to 'Clear'. ## 6.1.11 -- Remove iOS hack for delaying focus calculation. +* Remove iOS hack for delaying focus calculation. ## 6.1.10 -- Delay focus calculation for iOS. +* Delay focus calculation for iOS. ## 6.1.9 -- Bump keyboard show up wait to 1 sec. +* Bump keyboard show up wait to 1 sec. ## 6.1.8 -- Recalculate focus when showing keyboard. +* Recalculate focus when showing keyboard. ## 6.1.7 -- Add czech localizations. +* Add czech localizations. ## 6.1.6 -- Upgrade i18n_extension to 6.0.0. +* Upgrade i18n_extension to 6.0.0. ## 6.1.5 -- Fix formatting exception. +* Fix formatting exception. ## 6.1.4 -- Add double quotes validation. +* Add double quotes validation. ## 6.1.3 -- Revert "fix order list numbering (##988)". +* Revert "fix order list numbering (##988)". ## 6.1.2 -- Add typing shortcuts. +* Add typing shortcuts. ## 6.1.1 -- Fix order list numbering. +* Fix order list numbering. ## 6.1.0 -- Add keyboard shortcuts for editor actions. +* Add keyboard shortcuts for editor actions. ## 6.0.10 -- Upgrade device info plus to ^7.0.0. +* Upgrade device info plus to ^7.0.0. ## 6.0.9 -- Don't throw showAutocorrectionPromptRect not implemented. The function is called with every keystroke as a user is typing. +* Don't throw showAutocorrectionPromptRect not implemented. The function is called with every keystroke as a user is typing. ## 6.0.8+1 -- Fixes null pointer when setting documents. +* Fixes null pointer when setting documents. ## 6.0.8 -- Make QuillController.document mutable. +* Make QuillController.document mutable. ## 6.0.7 -- Allow disabling of selection toolbar. +* Allow disabling of selection toolbar. ## 6.0.6+1 -- Revert 6.0.6. +* Revert 6.0.6. ## 6.0.6 -- Fix wrong custom embed key. +* Fix wrong custom embed key. ## 6.0.5 -- Fixes toolbar buttons stealing focus from editor. +* Fixes toolbar buttons stealing focus from editor. ## 6.0.4 -- Bug fix for Type 'Uint8List' not found. +* Bug fix for Type 'Uint8List' not found. ## 6.0.3 -- Add ability to paste images. +* Add ability to paste images. ## 6.0.2 -- Address Dart Analysis issues. +* Address Dart Analysis issues. ## 6.0.1 -- Changed translation country code (zh_HK -> zh_hk) to lower case, which is required for i18n_extension used in flutter_quill. -- Add localization in example's main to demonstrate translation. -- Issue Windows selection's copy / paste tool bar not shown ##861: add selection's copy / paste toolbar, escape to hide toolbar, mouse right click to show toolbar, ctrl-Y / ctrl-Z to undo / redo. -- Image and video displayed in Windows platform caused screen flickering while selecting text, a sample_data_nomedia.json asset is added for Desktop to demonstrate the added features. -- Known issue: keyboard action sometimes causes exception mentioned in Flutter's issue ##106475 (Windows Keyboard shortcuts stop working after modifier key repeat flutter/flutter##106475). -- Know issue: user needs to click the editor to get focus before toolbar is able to display. +* Changed translation country code (zh_HK -> zh_hk) to lower case, which is required for i18n_extension used in flutter_quill. +* Add localization in example's main to demonstrate translation. +* Issue Windows selection's copy / paste tool bar not shown ##861: add selection's copy / paste toolbar, escape to hide toolbar, mouse right click to show toolbar, ctrl-Y / ctrl-Z to undo / redo. +* Image and video displayed in Windows platform caused screen flickering while selecting text, a sample_data_nomedia.json asset is added for Desktop to demonstrate the added features. +* Known issue: keyboard action sometimes causes exception mentioned in Flutter's issue ##106475 (Windows Keyboard shortcuts stop working after modifier key repeat flutter/flutter##106475). +* Know issue: user needs to click the editor to get focus before toolbar is able to display. ## 6.0.0 BREAKING CHANGE -- Removed embed (image, video & formula) blocks from the package to reduce app size. +* Removed embed (image, video & formula) blocks from the package to reduce app size. These blocks have been moved to the package `flutter_quill_extensions`, migrate by filling the `embedBuilders` and `embedButtons` parameters as follows: @@ -452,927 +452,927 @@ QuillToolbar.basic( ## 5.4.2 -- Upgrade i18n_extension. +* Upgrade i18n_extension. ## 5.4.1 -- Update German Translation. +* Update German Translation. ## 5.4.0 -- Added Formula Button (for maths support). +* Added Formula Button (for maths support). ## 5.3.2 -- Add more font family. +* Add more font family. ## 5.3.1 -- Enable search when text is not empty. +* Enable search when text is not empty. ## 5.3.0 -- Added search function. +* Added search function. ## 5.2.11 -- Remove default small color. +* Remove default small color. ## 5.2.10 -- Don't wrap the QuillEditor's child in the EditorTextSelectionGestureDetector if selection is disabled. +* Don't wrap the QuillEditor's child in the EditorTextSelectionGestureDetector if selection is disabled. ## 5.2.9 -- Added option to modify SelectHeaderStyleButton options. -- Added option to click again on h1, h2, h3 button to go back to normal. +* Added option to modify SelectHeaderStyleButton options. +* Added option to click again on h1, h2, h3 button to go back to normal. ## 5.2.8 -- Remove tooltip for LinkStyleButton. -- Make link match regex case insensitive. +* Remove tooltip for LinkStyleButton. +* Make link match regex case insensitive. ## 5.2.7 -- Add locale to QuillEditor.basic. +* Add locale to QuillEditor.basic. ## 5.2.6 -- Fix keyboard pops up when resizing the image. +* Fix keyboard pops up when resizing the image. ## 5.2.5 -- Upgrade youtube_player_flutter_quill to 8.2.2. +* Upgrade youtube_player_flutter_quill to 8.2.2. ## 5.2.4 -- Upgrade youtube_player_flutter_quill to 8.2.1. +* Upgrade youtube_player_flutter_quill to 8.2.1. ## 5.2.3 -- Flutter Quill Doesn't Work On iOS 16 or Xcode 14 Betas (Stored properties cannot be marked potentially unavailable with '@available'). +* Flutter Quill Doesn't Work On iOS 16 or Xcode 14 Betas (Stored properties cannot be marked potentially unavailable with '@available'). ## 5.2.2 -- Fix Web Unsupported operation: Platform.\_operatingSystem error. +* Fix Web Unsupported operation: Platform.\_operatingSystem error. ## 5.2.1 -- Rename QuillCustomIcon to QuillCustomButton. +* Rename QuillCustomIcon to QuillCustomButton. ## 5.2.0 -- Support font family selection. +* Support font family selection. ## 5.1.1 -- Update README. +* Update README. ## 5.1.0 -- Added CustomBlockEmbed and customElementsEmbedBuilder. +* Added CustomBlockEmbed and customElementsEmbedBuilder. ## 5.0.5 -- Upgrade device_info_plus to 4.0.0. +* Upgrade device_info_plus to 4.0.0. ## 5.0.4 -- Added onVideoInit callback for video documents. +* Added onVideoInit callback for video documents. ## 5.0.3 -- Update dependencies. +* Update dependencies. ## 5.0.2 -- Keep cursor position on checkbox tap. +* Keep cursor position on checkbox tap. ## 5.0.1 -- Fix static analysis errors. +* Fix static analysis errors. ## 5.0.0 -- Flutter 3.0.0 support. +* Flutter 3.0.0 support. ## 4.2.3 -- Ignore color:inherit and convert double to int for level. +* Ignore color:inherit and convert double to int for level. ## 4.2.2 -- Add clear option to font size dropdown. +* Add clear option to font size dropdown. ## 4.2.1 -- Refactor font size dropdown. +* Refactor font size dropdown. ## 4.2.0 -- Ensure selectionOverlay is available for showToolbar. +* Ensure selectionOverlay is available for showToolbar. ## 4.1.9 -- Using properly iconTheme colors. +* Using properly iconTheme colors. ## 4.1.8 -- Update font size dropdown. +* Update font size dropdown. ## 4.1.7 -- Convert FontSize to a Map to allow for named Font Size. +* Convert FontSize to a Map to allow for named Font Size. ## 4.1.6 -- Update quill_dropdown_button.dart. +* Update quill_dropdown_button.dart. ## 4.1.5 -- Add Font Size dropdown to the toolbar. +* Add Font Size dropdown to the toolbar. ## 4.1.4 -- New borderRadius for iconTheme. +* New borderRadius for iconTheme. ## 4.1.3 -- Fix selection handles show/hide after paste, backspace, copy. +* Fix selection handles show/hide after paste, backspace, copy. ## 4.1.2 -- Add full support for hardware keyboards (Chromebook, Android tablets, etc) that don't alter screen UI. +* Add full support for hardware keyboards (Chromebook, Android tablets, etc) that don't alter screen UI. ## 4.1.1 -- Added textSelectionControls field in QuillEditor. +* Added textSelectionControls field in QuillEditor. ## 4.1.0 -- Added Node to linkActionPickerDelegate. +* Added Node to linkActionPickerDelegate. ## 4.0.12 -- Add Persian(fa) language. +* Add Persian(fa) language. ## 4.0.11 -- Fix cut selection error in multi-node line. +* Fix cut selection error in multi-node line. ## 4.0.10 -- Fix vertical caret position bug. +* Fix vertical caret position bug. ## 4.0.9 -- Request keyboard focus when no child is found. +* Request keyboard focus when no child is found. ## 4.0.8 -- Fix blank lines do not display when --web-renderer=html. +* Fix blank lines do not display when **web*renderer=html. ## 4.0.7 -- Refactor getPlainText (better handling of blank lines and lines with multiple markups. +* Refactor getPlainText (better handling of blank lines and lines with multiple markups. ## 4.0.6 -- Bug fix for copying text with new lines. +* Bug fix for copying text with new lines. ## 4.0.5 -- Fixed casting null to Tuple2 when link dialog is dismissed without any input (e.g. barrier dismissed). +* Fixed casting null to Tuple2 when link dialog is dismissed without any input (e.g. barrier dismissed). ## 4.0.4 -- Bug fix for text direction rtl. +* Bug fix for text direction rtl. ## 4.0.3 -- Support text direction rtl. +* Support text direction rtl. ## 4.0.2 -- Clear toggled style on selection change. +* Clear toggled style on selection change. ## 4.0.1 -- Fix copy/cut/paste/selectAll not working. +* Fix copy/cut/paste/selectAll not working. ## 4.0.0 -- Upgrade for Flutter 2.10. +* Upgrade for Flutter 2.10. ## 3.9.11 -- Added Indonesian translation. +* Added Indonesian translation. ## 3.9.10 -- Fix for undoing a modification ending with an indented line. +* Fix for undoing a modification ending with an indented line. ## 3.9.9 -- iOS: Save image whose filename does not end with image file extension. +* iOS: Save image whose filename does not end with image file extension. ## 3.9.8 -- Added Urdu translation. +* Added Urdu translation. ## 3.9.7 -- Fix for clicking on the Link button without any text on a new line crashes. +* Fix for clicking on the Link button without any text on a new line crashes. ## 3.9.6 -- Apply locale to QuillEditor(contents). +* Apply locale to QuillEditor(contents). ## 3.9.5 -- Fix image pasting. +* Fix image pasting. ## 3.9.4 -- Hiding dialog after selecting action for image. +* Hiding dialog after selecting action for image. ## 3.9.3 -- Update ImageResizer for Android. +* Update ImageResizer for Android. ## 3.9.2 -- Copy image with its style. +* Copy image with its style. ## 3.9.1 -- Support resizing image. +* Support resizing image. ## 3.9.0 -- Image menu options for copy/remove. +* Image menu options for copy/remove. ## 3.8.8 -- Update set textEditingValue. +* Update set textEditingValue. ## 3.8.7 -- Fix checkbox not toggled correctly in toolbar button. +* Fix checkbox not toggled correctly in toolbar button. ## 3.8.6 -- Fix cursor position changes when checking/unchecking the checkbox. +* Fix cursor position changes when checking/unchecking the checkbox. ## 3.8.5 -- Fix \_handleDragUpdate in \_TextSelectionHandleOverlayState. +* Fix \_handleDragUpdate in \_TextSelectionHandleOverlayState. ## 3.8.4 -- Fix link dialog layout. +* Fix link dialog layout. ## 3.8.3 -- Fix for errors on a non scrollable editor. +* Fix for errors on a non scrollable editor. ## 3.8.2 -- Fix certain keys not working on web when editor is a child of a scroll view. +* Fix certain keys not working on web when editor is a child of a scroll view. ## 3.8.1 -- Refactor \_QuillEditorState to QuillEditorState. +* Refactor \_QuillEditorState to QuillEditorState. ## 3.8.0 -- Support pasting with format. +* Support pasting with format. ## 3.7.3 -- Fix selection overlay for collapsed selection. +* Fix selection overlay for collapsed selection. ## 3.7.2 -- Reverted Embed toPlainText change. +* Reverted Embed toPlainText change. ## 3.7.1 -- Change Embed toPlainText to be empty string. +* Change Embed toPlainText to be empty string. ## 3.7.0 -- Replace Toolbar showHistory group with individual showRedo and showUndo. +* Replace Toolbar showHistory group with individual showRedo and showUndo. ## 3.6.5 -- Update Link dialogue for image/video. +* Update Link dialogue for image/video. ## 3.6.4 -- Link dialogue TextInputType.multiline. +* Link dialogue TextInputType.multiline. ## 3.6.3 -- Bug fix for link button text selection. +* Bug fix for link button text selection. ## 3.6.2 -- Improve link button. +* Improve link button. ## 3.6.1 -- Remove SnackBar 'What is entered is not a link'. +* Remove SnackBar 'What is entered is not a link'. ## 3.6.0 -- Allow link button to enter text. +* Allow link button to enter text. ## 3.5.3 -- Change link button behavior. +* Change link button behavior. ## 3.5.2 -- Bug fix for embed. +* Bug fix for embed. ## 3.5.1 -- Bug fix for platform util. +* Bug fix for platform util. ## 3.5.0 -- Removed redundant classes. +* Removed redundant classes. ## 3.4.4 -- Add more translations. +* Add more translations. ## 3.4.3 -- Preset link from attributes. +* Preset link from attributes. ## 3.4.2 -- Fix launch link edit mode. +* Fix launch link edit mode. ## 3.4.1 -- Placeholder effective in scrollable. +* Placeholder effective in scrollable. ## 3.4.0 -- Option to save image in read-only mode. +* Option to save image in read-only mode. ## 3.3.1 -- Pass any specified key in QuillEditor constructor to super. +* Pass any specified key in QuillEditor constructor to super. ## 3.3.0 -- Fixed Style toggle issue. +* Fixed Style toggle issue. ## 3.2.1 -- Added new translations. +* Added new translations. ## 3.2.0 -- Support multiple links insertion on the go. +* Support multiple links insertion on the go. ## 3.1.1 -- Add selection completed callback. +* Add selection completed callback. ## 3.1.0 -- Fixed image ontap functionality. +* Fixed image ontap functionality. ## 3.0.4 -- Add maxContentWidth constraint to editor. +* Add maxContentWidth constraint to editor. ## 3.0.3 -- Do not show caret on screen when the editor is not focused. +* Do not show caret on screen when the editor is not focused. ## 3.0.2 -- Fix launch link for read-only mode. +* Fix launch link for read-only mode. ## 3.0.1 -- Handle null value of Attribute.link. +* Handle null value of Attribute.link. ## 3.0.0 -- Launch link improvements. -- Removed QuillSimpleViewer. +* Launch link improvements. +* Removed QuillSimpleViewer. ## 2.5.2 -- Skip image when pasting. +* Skip image when pasting. ## 2.5.1 -- Bug fix for Desktop `Shift` + `Click` support. +* Bug fix for Desktop `Shift` + `Click` support. ## 2.5.0 -- Update checkbox list. +* Update checkbox list. ## 2.4.1 -- Desktop selection improvements. +* Desktop selection improvements. ## 2.4.0 -- Improve inline code style. +* Improve inline code style. ## 2.3.3 -- Improves selection rects to have consistent height regardless of individual segment text styles. +* Improves selection rects to have consistent height regardless of individual segment text styles. ## 2.3.2 -- Allow disabling floating cursor. +* Allow disabling floating cursor. ## 2.3.1 -- Preserve last newline character on delete. +* Preserve last newline character on delete. ## 2.3.0 -- Massive changes to support flutter 2.8. +* Massive changes to support flutter 2.8. ## 2.2.2 -- iOS - floating cursor. +* iOS - floating cursor. ## 2.2.1 -- Bug fix for imports supporting flutter 2.8. +* Bug fix for imports supporting flutter 2.8. ## 2.2.0 -- Support flutter 2.8. +* Support flutter 2.8. ## 2.1.1 -- Add methods of clearing editor and moving cursor. +* Add methods of clearing editor and moving cursor. ## 2.1.0 -- Add delete handler. +* Add delete handler. ## 2.0.23 -- Support custom replaceText handler. +* Support custom replaceText handler. ## 2.0.22 -- Fix attribute compare and fix font size parsing. +* Fix attribute compare and fix font size parsing. ## 2.0.21 -- Handle click on embed object. +* Handle click on embed object. ## 2.0.20 -- Improved UX/UI of Image widget. +* Improved UX/UI of Image widget. ## 2.0.19 -- When uploading a video, applying indicator. +* When uploading a video, applying indicator. ## 2.0.18 -- Make toolbar dividers optional. +* Make toolbar dividers optional. ## 2.0.17 -- Allow alignment of the toolbar icons to match WrapAlignment. +* Allow alignment of the toolbar icons to match WrapAlignment. ## 2.0.16 -- Add hide / show alignment buttons. +* Add hide / show alignment buttons. ## 2.0.15 -- Implement change cursor to SystemMouseCursors.click when hovering a link styled text. +* Implement change cursor to SystemMouseCursors.click when hovering a link styled text. ## 2.0.14 -- Enable customize the checkbox widget using DefaultListBlockStyle style. +* Enable customize the checkbox widget using DefaultListBlockStyle style. ## 2.0.13 -- Improve the scrolling performance by reducing the repaint areas. +* Improve the scrolling performance by reducing the repaint areas. ## 2.0.12 -- Fix the selection effect can't be seen as the textLine with background color. +* Fix the selection effect can't be seen as the textLine with background color. ## 2.0.11 -- Fix visibility of text selection handlers on scroll. +* Fix visibility of text selection handlers on scroll. ## 2.0.10 -- cursorConnt.color notify the text_line to repaint if it was disposed. +* cursorConnt.color notify the text_line to repaint if it was disposed. ## 2.0.9 -- Improve UX when trying to add a link. +* Improve UX when trying to add a link. ## 2.0.8 -- Adding translations to the toolbar. +* Adding translations to the toolbar. ## 2.0.7 -- Added theming options for toolbar icons and LinkDialog. +* Added theming options for toolbar icons and LinkDialog. ## 2.0.6 -- Avoid runtime error when placed inside TabBarView. +* Avoid runtime error when placed inside TabBarView. ## 2.0.5 -- Support inline code formatting. +* Support inline code formatting. ## 2.0.4 -- Enable history shortcuts for desktop. +* Enable history shortcuts for desktop. ## 2.0.3 -- Fix cursor when line contains image. +* Fix cursor when line contains image. ## 2.0.2 -- Address KeyboardListener class name conflict. +* Address KeyboardListener class name conflict. ## 2.0.1 -- Upgrade flutter_colorpicker to 0.5.0. +* Upgrade flutter_colorpicker to 0.5.0. ## 2.0.0 -- Text Alignment functions + Block Format standards. +* Text Alignment functions + Block Format standards. ## 1.9.6 -- Support putting QuillEditor inside a Scrollable view. +* Support putting QuillEditor inside a Scrollable view. ## 1.9.5 -- Skip image when pasting. +* Skip image when pasting. ## 1.9.4 -- Bug fix for cursor position when tapping at the end of line with image(s). +* Bug fix for cursor position when tapping at the end of line with image(s). ## 1.9.3 -- Bug fix when line only contains one image. +* Bug fix when line only contains one image. ## 1.9.2 -- Support for building custom inline styles. +* Support for building custom inline styles. ## 1.9.1 -- Cursor jumps to the most appropriate offset to display selection. +* Cursor jumps to the most appropriate offset to display selection. ## 1.9.0 -- Support inline image. +* Support inline image. ## 1.8.3 -- Updated quill_delta. +* Updated quill_delta. ## 1.8.2 -- Support mobile image alignment. +* Support mobile image alignment. ## 1.8.1 -- Support mobile custom size image. +* Support mobile custom size image. ## 1.8.0 -- Support entering link for image/video. +* Support entering link for image/video. ## 1.7.3 -- Bumps photo_view version. +* Bumps photo_view version. ## 1.7.2 -- Fix static analysis error. +* Fix static analysis error. ## 1.7.1 -- Support Youtube video. +* Support Youtube video. ## 1.7.0 -- Support video. +* Support video. ## 1.6.4 -- Bug fix for clear format button. +* Bug fix for clear format button. ## 1.6.3 -- Fixed dragging right handle scrolling issue. +* Fixed dragging right handle scrolling issue. ## 1.6.2 -- Fixed the position of the selection status drag handle. +* Fixed the position of the selection status drag handle. ## 1.6.1 -- Upgrade image_picker and flutter_colorpicker. +* Upgrade image_picker and flutter_colorpicker. ## 1.6.0 -- Support Multi Row Toolbar. +* Support Multi Row Toolbar. ## 1.5.0 -- Remove file_picker dependency. +* Remove file_picker dependency. ## 1.4.1 -- Remove filesystem_picker dependency. +* Remove filesystem_picker dependency. ## 1.4.0 -- Remove path_provider dependency. +* Remove path_provider dependency. ## 1.3.4 -- Add option to paintCursorAboveText. +* Add option to paintCursorAboveText. ## 1.3.3 -- Upgrade file_picker version. +* Upgrade file_picker version. ## 1.3.2 -- Fix copy/paste bug. +* Fix copy/paste bug. ## 1.3.1 -- New logo. +* New logo. ## 1.3.0 -- Support flutter 2.2.0. +* Support flutter 2.2.0. ## 1.2.2 -- Checkbox supports tapping. +* Checkbox supports tapping. ## 1.2.1 -- Indented position not holding while editing. +* Indented position not holding while editing. ## 1.2.0 -- Fix image button cancel causes crash. +* Fix image button cancel causes crash. ## 1.1.8 -- Fix height of empty line bug. +* Fix height of empty line bug. ## 1.1.7 -- Fix text selection in read-only mode. +* Fix text selection in read-only mode. ## 1.1.6 -- Remove universal_html dependency. +* Remove universal_html dependency. ## 1.1.5 -- Enable "Select", "Select All" and "Copy" in read-only mode. +* Enable "Select", "Select All" and "Copy" in read-only mode. ## 1.1.4 -- Fix text selection issue. +* Fix text selection issue. ## 1.1.3 -- Update example folder. +* Update example folder. ## 1.1.2 -- Add pedantic. +* Add pedantic. ## 1.1.1 -- Base64 image support. +* Base64 image support. ## 1.1.0 -- Support null safety. +* Support null safety. ## 1.0.9 -- Web support for raw editor and keyboard listener. +* Web support for raw editor and keyboard listener. ## 1.0.8 -- Support token attribute. +* Support token attribute. ## 1.0.7 -- Fix crash on web (dart:io). +* Fix crash on web (dart:io). ## 1.0.6 -- Add desktop support - WINDOWS, MACOS and LINUX. +* Add desktop support WINDOWS, MACOS and LINUX. ## 1.0.5 -- Bug fix: Can not insert newline when Bold is toggled ON. +* Bug fix: Can not insert newline when Bold is toggled ON. ## 1.0.4 -- Upgrade photo_view to ^0.11.0. +* Upgrade photo_view to ^0.11.0. ## 1.0.3 -- Fix issue that text is not displayed while typing WEB. +* Fix issue that text is not displayed while typing WEB. ## 1.0.2 -- Update toolbar in sample home page. +* Update toolbar in sample home page. ## 1.0.1 -- Fix static analysis errors. +* Fix static analysis errors. ## 1.0.0 -- Support flutter 2.0. +* Support flutter 2.0. ## 1.0.0-dev.2 -- Improve link handling for tel, mailto and etc. +* Improve link handling for tel, mailto and etc. ## 1.0.0-dev.1 -- Upgrade prerelease SDK & Bump for master. +* Upgrade prerelease SDK & Bump for master. ## 0.3.5 -- Fix for cursor focus issues when keyboard is on. +* Fix for cursor focus issues when keyboard is on. ## 0.3.4 -- Improve link handling for tel, mailto and etc. +* Improve link handling for tel, mailto and etc. ## 0.3.3 -- More fix on cursor focus issue when keyboard is on. +* More fix on cursor focus issue when keyboard is on. ## 0.3.2 -- Fix cursor focus issue when keyboard is on. +* Fix cursor focus issue when keyboard is on. ## 0.3.1 -- cursor focus when keyboard is on. +* cursor focus when keyboard is on. ## 0.3.0 -- Line Height calculated based on font size. +* Line Height calculated based on font size. ## 0.2.12 -- Support placeholder. +* Support placeholder. ## 0.2.11 -- Fix static analysis error. +* Fix static analysis error. ## 0.2.10 -- Update TextInputConfiguration autocorrect to true in stable branch. +* Update TextInputConfiguration autocorrect to true in stable branch. ## 0.2.9 -- Update TextInputConfiguration autocorrect to true. +* Update TextInputConfiguration autocorrect to true. ## 0.2.8 -- Support display local image besides network image in stable branch. +* Support display local image besides network image in stable branch. ## 0.2.7 -- Support display local image besides network image. +* Support display local image besides network image. ## 0.2.6 -- Fix cursor after pasting. +* Fix cursor after pasting. ## 0.2.5 -- Toggle text/background color button in toolbar. +* Toggle text/background color button in toolbar. ## 0.2.4 -- Support the use of custom icon size in toolbar. +* Support the use of custom icon size in toolbar. ## 0.2.3 -- Support custom styles and image on local device storage without uploading. +* Support custom styles and image on local device storage without uploading. ## 0.2.2 -- Update git repo. +* Update git repo. ## 0.2.1 -- Fix static analysis error. +* Fix static analysis error. ## 0.2.0 -- Add checked/unchecked list button in toolbar. +* Add checked/unchecked list button in toolbar. ## 0.1.8 -- Support font and size attributes. +* Support font and size attributes. ## 0.1.7 -- Support checked/unchecked list. +* Support checked/unchecked list. ## 0.1.6 -- Fix getExtentEndpointForSelection. +* Fix getExtentEndpointForSelection. ## 0.1.5 -- Support text alignment. +* Support text alignment. ## 0.1.4 -- Handle url with trailing spaces. +* Handle url with trailing spaces. ## 0.1.3 -- Handle cursor position change when undo/redo. +* Handle cursor position change when undo/redo. ## 0.1.2 -- Handle more text colors. +* Handle more text colors. ## 0.1.1 -- Fix cursor issue when undo. +* Fix cursor issue when undo. ## 0.1.0 -- Fix insert image. +* Fix insert image. ## 0.0.9 -- Handle rgba color. +* Handle rgba color. ## 0.0.8 -- Fix launching url. +* Fix launching url. ## 0.0.7 -- Handle multiple image inserts. +* Handle multiple image inserts. ## 0.0.6 -- More toolbar functionality. +* More toolbar functionality. ## 0.0.5 -- Update example. +* Update example. ## 0.0.4 -- Update example. +* Update example. ## 0.0.3 -- Update home page meta data. +* Update home page meta data. ## 0.0.2 -- Support image upload and launch url in read-only mode. +* Support image upload and launch url in read-only mode. ## 0.0.1 -- Rich text editor based on Quill Delta. +* Rich text editor based on Quill Delta. diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index fb438d6f..a1a9dc3e 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -3,134 +3,134 @@ All notable changes to this project will be documented in this file. ## 0.6.10 -- Update deprecated members from `flutter_quill` -- Update doc and `README.md` +* Update deprecated members from `flutter_quill` +* Update doc and `README.md` ## 0.6.9 -- Remove duplicated class -- Drop the support for `QuillEditorFormulaEmbedBuilder` for now as it's not usable, we are working on providing a fixes -- Fix bug with the zoom button +* Remove duplicated class +* Drop the support for `QuillEditorFormulaEmbedBuilder` for now as it's not usable, we are working on providing a fixes +* Fix bug with the zoom button ## 0.6.8 -- Feature: Allow the developer to override the `assetsPrefix` and default value is `assets`, you should define this correctly if you planning on using asset images in the `QuillEditor`, take a look at `QuillSharedExtensionsConfigurations` class for more info +* Feature: Allow the developer to override the `assetsPrefix` and default value is `assets`, you should define this correctly if you planning on using asset images in the `QuillEditor`, take a look at `QuillSharedExtensionsConfigurations` class for more info ## 0.6.7 -- Support the new localization system of `flutter_quill` +* Support the new localization system of `flutter_quill` ## 0.6.6 -- Add `onImageClicked` in the `QuillEditorImageEmbedConfigurations` -- Fix image resizing on mobile +* Add `onImageClicked` in the `QuillEditorImageEmbedConfigurations` +* Fix image resizing on mobile ## 0.6.5 -- Support the new improved platform checking of `flutter_quill` -- Update the Image embed builder logic -- Fix Save image button exception -- Feature: Image cropping for the image embed builder -- Add support for copying the image to the cliboard -- Add new static method in `FlutterQuillEmbeds` which is `defaultEditorBuilders` for minimal configurations -- Fix the image size logic (it's still missing a lot of things but we will work on that soon) -- Fix the zoom image functionality to support different image providers -- Fix typo in the function name `editorsWebBuilders`, now it's called `editorWebBuilders` -- Deprecated: The boolean property `forceUseMobileOptionMenuForImageClick` is now deprecated as we will not using it anymore and it will be removed in the next major release -- Update `README.md` +* Support the new improved platform checking of `flutter_quill` +* Update the Image embed builder logic +* Fix the Save image button exception +* Feature: Image cropping for the image embed builder +* Add support for copying the image to the clipboard +* Add a new static method in `FlutterQuillEmbeds` which is `defaultEditorBuilders` for minimal configurations +* Fix the image size logic (it's still missing a lot of things but we will work on that soon) +* Fix the zoom image functionality to support different image providers +* Fix the typo in the function name `editorsWebBuilders`, now it's called `editorWebBuilders` +* Deprecated: The boolean property `forceUseMobileOptionMenuForImageClick` is now deprecated as we will not using it anymore and it will be removed in the next major release +* Update `README.md` ## 0.6.4 -- Update `QuillImageUtilities` -- Add new extension on `QuillController` to access `QuillImageUtilities` instance easier -- Support the new `iconButtonFactor` property +* Update `QuillImageUtilities` +* Add new extension on `QuillController` to access `QuillImageUtilities` instance easier +* Support the new `iconButtonFactor` property ## 0.6.3 -- Update `README.md` +* Update `README.md` ## 0.6.2 -- Add more default exports +* Add more default exports ## 0.6.1 -- Fix bug on web that causing the project to not build +* Fix bug on web that causing the project to not build ## 0.6.0 -- This version is not stable yet as it doesn't have mirgration guide and missing some things and we might introduce more breaking changes very soon but we decided to publish it because the latest stable version is not compatible with latest stable version of `flutter_quill` +* This version is not stable yet as it doesn't have mirgration guide and missing some things and we might introduce more breaking changes very soon but we decided to publish it because the latest stable version is not compatible with latest stable version of `flutter_quill` ## 0.6.0-dev.6 -- Better support for web -- Smal fixes and updates +* Better support for web +* Smal fixes and updates ## 0.6.0-dev.5 -- Update the camera button +* Update the camera button ## 0.6.0-dev.4 -- Add more exports -- Update `README.md`` -- Fix save image bug -- Quick fixes +* Add more exports +* Update `README.md`` +* Fix save image bug +* Quick fixes ## 0.6.0-dev.3 -- Disable the camera option by default on desktop +* Disable the camera option by default on desktop ## 0.6.0-dev.2 -- Another breaking changes, we will add mirgrate guide soon. +* Another breaking changes, we will add mirgrate guide soon. ## 0.6.0-dev.1 -- Breaking Changes, we have refactored most of the functions and it got renamed +* Breaking Changes, we have refactored most of the functions and it got renamed ## 0.5.1 -- Provide a way to use custom image provider for the image widgets -- Provide a way to handle different errors in image widgets -- Two bug fixes related to pick the image and capture it using the camera -- Add support for image resizing on desktop platforms when forced using the mobile context menu -- Improve performance by reducing the number of widgets rebuilt by listening to media query for only the needed things, for example instead of using `MediaQuery.of(context).size`, now we are using `MediaQuery.sizeOf(context)` -- Fix warrning "The platformViewRegistry getter is deprecated and will be removed in a future release. Please import it from dart:ui_web instead." -- Add QuillImageUtilities class -- Small improvemenets -- Allow to use the mobile context menu on desktop by force using it -- Add the resizing option to the forced mobile context menu -- Add new custom style attrbuite for desktop and other platforms +* Provide a way to use custom image provider for the image widgets +* Provide a way to handle different errors in image widgets +* Two bug fixes related to pick the image and capture it using the camera +* Add support for image resizing on desktop platforms when forced using the mobile context menu +* Improve performance by reducing the number of widgets rebuilt by listening to media query for only the needed things, for example instead of using `MediaQuery.of(context).size`, now we are using `MediaQuery.sizeOf(context)` +* Fix warrning "The platformViewRegistry getter is deprecated and will be removed in a future release. Please import it from dart:ui_web instead." +* Add QuillImageUtilities class +* Small improvemenets +* Allow to use the mobile context menu on desktop by force using it +* Add the resizing option to the forced mobile context menu +* Add new custom style attrbuite for desktop and other platforms ## 0.5.0 -- Migrated from `gallery_saver` to `gal` for saving images -- Added callbacks for greater control of editing images +* Migrated from `gallery_saver` to `gal` for saving images +* Added callbacks for greater control of editing images ## 0.4.1 -- Updated dependencies to support image_picker 1.0 +* Updated dependencies to support image_picker 1.0 ## 0.4.0 -- Fix backspace around images [PR #1309](https://github.com/singerdmx/flutter-quill/pull/1309) -- Feat/link regexp [PR #1329](https://github.com/singerdmx/flutter-quill/pull/1329) +* Fix backspace around images [PR #1309](https://github.com/singerdmx/flutter-quill/pull/1309) +* Feat/link regexp [PR #1329](https://github.com/singerdmx/flutter-quill/pull/1329) ## 0.3.4 -- Resolve deprecated method use in the `video_player` package +* Resolve deprecated method use in the `video_player` package ## 0.3.3 -- Fix a prototype bug which was bring by [PR #1230](https://github.com/singerdmx/flutter-quill/pull/1230#issuecomment-1560597099) +* Fix a prototype bug which was bring by [PR #1230](https://github.com/singerdmx/flutter-quill/pull/1230#issuecomment*1560597099) ## 0.3.2 -- Updated dependencies to support intl 0.18 +* Updated dependencies to support intl 0.18 ## 0.3.1 -- Image embedding tweaks - - Add MediaButton which is intened to superseed the ImageButton and VideoButton. Only image selection is working. - - Implement image insert for web (image as base64) +* Image embedding tweaks + * Add MediaButton which is intened to superseed the ImageButton and VideoButton. Only image selection is working. + * Implement image insert for web (image as base64) ## 0.3.0 -- Added support for adding custom tooltips to toolbar buttons +* Added support for adding custom tooltips to toolbar buttons ## 0.2.0 -- Allow widgets to override widget span properties [b7951b0](https://github.com/singerdmx/flutter-quill/commit/b7951b02c9086ea42e7aad6d78e6c9b0297562e5) -- Remove tuples [3e9452e](https://github.com/singerdmx/flutter-quill/commit/3e9452e675e8734ff50364c5f7b5d34088d5ff05) -- Remove transparent color of ImageVideoUtils dialog [74544bd](https://github.com/singerdmx/flutter-quill/commit/74544bd945a9d212ca1e8d6b3053dbecee22b720) -- Migrate to `youtube_player_flutter` from `youtube_player_flutter_quill` -- Updates to forumla button [5228f38](https://github.com/singerdmx/flutter-quill/commit/5228f389ba6f37d61d445cfe138c19fcf8766d71) +* Allow widgets to override widget span properties [b7951b0](https://github.com/singerdmx/flutter-quill/commit/b7951b02c9086ea42e7aad6d78e6c9b0297562e5) +* Remove tuples [3e9452e](https://github.com/singerdmx/flutter-quill/commit/3e9452e675e8734ff50364c5f7b5d34088d5ff05) +* Remove transparent color of ImageVideoUtils dialog [74544bd](https://github.com/singerdmx/flutter-quill/commit/74544bd945a9d212ca1e8d6b3053dbecee22b720) +* Migrate to `youtube_player_flutter` from `youtube_player_flutter_quill` +* Updates to forumla button [5228f38](https://github.com/singerdmx/flutter-quill/commit/5228f389ba6f37d61d445cfe138c19fcf8766d71) ## 0.1.0 -- Initial release +* Initial release From 03a7101f262f71e6235af51a25601e7555d7af67 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 14 Nov 2023 21:37:43 +0300 Subject: [PATCH 185/210] Fix pub get failure --- flutter_quill_extensions/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index e55a1d14..e9633974 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 0.6.9 +version: 0.6.10 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions diff --git a/pubspec.yaml b/pubspec.yaml index 80a511af..eeac5712 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 0.6.10 +version: 8.5.4 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From 9ec7285c14a7ccb7e365b031be9599444f564306 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 14 Nov 2023 22:07:27 +0300 Subject: [PATCH 186/210] Update example and CI --- .github/workflows/main.yml | 4 ++++ .../lib/presentation/quill/quill_editor.dart | 22 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5bb0e047..a14d148b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -45,3 +45,7 @@ jobs: - name: Run flutter tests run: flutter test + + - name: Flutter Build web + run: flutter build web --release --verbose --dart-define=CI=true + working-directory: ./example diff --git a/example/lib/presentation/quill/quill_editor.dart b/example/lib/presentation/quill/quill_editor.dart index e7f67732..133f9997 100644 --- a/example/lib/presentation/quill/quill_editor.dart +++ b/example/lib/presentation/quill/quill_editor.dart @@ -1,4 +1,5 @@ import 'dart:io' as io show Directory, File; +import 'dart:ui' show FontFeature; import 'package:cached_network_image/cached_network_image.dart' show CachedNetworkImageProvider; @@ -32,6 +33,27 @@ class MyQuillEditor extends StatelessWidget { scrollController: scrollController, focusNode: focusNode, configurations: configurations.copyWith( + customStyles: const DefaultStyles( + h1: DefaultTextBlockStyle( + TextStyle( + fontSize: 32, + height: 1.15, + fontWeight: FontWeight.w300, + ), + VerticalSpacing(16, 0), + VerticalSpacing(0, 0), + null, + ), + sizeSmall: TextStyle(fontSize: 9), + subscript: TextStyle( + fontFamily: 'SF-UI-Display', + fontFeatures: [FontFeature.subscripts()], + ), + superscript: TextStyle( + fontFamily: 'SF-UI-Display', + fontFeatures: [FontFeature.superscripts()], + ), + ), scrollable: true, placeholder: 'Start writting your notes...', padding: const EdgeInsets.all(16), From 67a7803aa1ba16cd85ce167615e494c2098054c8 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 14 Nov 2023 22:11:31 +0300 Subject: [PATCH 187/210] Update CI --- .github/workflows/main.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a14d148b..7965169a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -46,6 +46,9 @@ jobs: - name: Run flutter tests run: flutter test - - name: Flutter Build web + - name: Flutter Build Web run: flutter build web --release --verbose --dart-define=CI=true working-directory: ./example + - name: Flutter Build Linux + run: flutter build linux --release --verbose --dart-define=CI=true + working-directory: ./example From aa6451ca529b6f5c4b484eff26f1fd2efb393223 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 14 Nov 2023 22:19:10 +0300 Subject: [PATCH 188/210] Update main.yml workflow --- .github/workflows/main.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7965169a..01ddc474 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,4 +1,4 @@ -name: flutter-quill CI +name: Flutter Quill CI on: push: @@ -15,6 +15,7 @@ jobs: - uses: subosito/flutter-action@v2 with: channel: 'stable' + cache: true - name: Check flutter version run: flutter --version @@ -46,9 +47,13 @@ jobs: - name: Run flutter tests run: flutter test - - name: Flutter Build Web + - name: Flutter build Web run: flutter build web --release --verbose --dart-define=CI=true working-directory: ./example - - name: Flutter Build Linux + + - name: Install flutter Linux prerequisites + run: sudo apt-get install clang cmake git ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev -y + + - name: Flutter build Linux run: flutter build linux --release --verbose --dart-define=CI=true working-directory: ./example From 26b40d86ab9afe5d8819a27a7920fc6b81e25ed4 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 14 Nov 2023 22:26:05 +0300 Subject: [PATCH 189/210] Update the compatible versions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9aad0a05..3db5e322 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ Compatible versions: | flutter_quill | flutter_quill_extensions | flutter_quill_test | |-------------------------|--------------------------|-------------------------| -| 8.5.2 | 0.6.9 | 0.0.5 | +| 8.5.x | 0.6.x | 0.0.5 | | 8.5.1 | 0.6.7 | 0.0.5 | | 8.5.0 | 0.6.7 | 0.0.5 | From 2694734bdb71f65a9bbdb973c6b4024af0b0a204 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 14 Nov 2023 22:30:47 +0300 Subject: [PATCH 190/210] Comment linux building --- .github/workflows/main.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 01ddc474..1ba516b2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -51,9 +51,9 @@ jobs: run: flutter build web --release --verbose --dart-define=CI=true working-directory: ./example - - name: Install flutter Linux prerequisites - run: sudo apt-get install clang cmake git ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev -y + # - name: Install flutter Linux prerequisites + # run: sudo apt-get install clang cmake git ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev -y - - name: Flutter build Linux - run: flutter build linux --release --verbose --dart-define=CI=true - working-directory: ./example + # - name: Flutter build Linux + # run: flutter build linux --release --verbose --dart-define=CI=true + # working-directory: ./example From 691b7aeb332b33263d5486a9833b2de6adf8fa5f Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 14 Nov 2023 23:52:10 +0300 Subject: [PATCH 191/210] Small changes --- example/android/app/src/main/AndroidManifest.xml | 2 +- .../lib/presentation/embeds/editor/image/image_web.dart | 3 ++- .../lib/presentation/embeds/editor/video/video_web.dart | 3 ++- flutter_quill_extensions/lib/presentation/utils/web_utils.dart | 2 ++ flutter_quill_extensions/pubspec.yaml | 3 +-- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 44cd71db..447ef189 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -3,7 +3,7 @@ - + diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart index 76dc6134..2ed5b967 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/image/image_web.dart @@ -56,7 +56,8 @@ class QuillEditorWebImageEmbedBuilder extends EmbedBuilder { ..style.height = height ..style.width = width ..style.margin = margin - ..style.alignSelf = alignment; + ..style.alignSelf = alignment + ..attributes['loading'] = 'lazy'; }); return ConstrainedBox( diff --git a/flutter_quill_extensions/lib/presentation/embeds/editor/video/video_web.dart b/flutter_quill_extensions/lib/presentation/embeds/editor/video/video_web.dart index 6111809d..abc821d0 100644 --- a/flutter_quill_extensions/lib/presentation/embeds/editor/video/video_web.dart +++ b/flutter_quill_extensions/lib/presentation/embeds/editor/video/video_web.dart @@ -50,7 +50,8 @@ class QuillEditorWebVideoEmbedBuilder extends EmbedBuilder { ..src = videoUrl ..style.border = 'none' ..style.margin = margin - ..style.alignSelf = alignment, + ..style.alignSelf = alignment + ..attributes['loading'] = 'lazy', ); return SizedBox( diff --git a/flutter_quill_extensions/lib/presentation/utils/web_utils.dart b/flutter_quill_extensions/lib/presentation/utils/web_utils.dart index 527f668e..b34d308f 100644 --- a/flutter_quill_extensions/lib/presentation/utils/web_utils.dart +++ b/flutter_quill_extensions/lib/presentation/utils/web_utils.dart @@ -18,6 +18,8 @@ import 'package:flutter_quill/flutter_quill.dart' show Attribute, Node; const margin = 'auto'; const alignment = 'center'; + // return (height, width, margin, alignment); + final cssStyle = node.style.attributes['style']; // Usually double value diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index e9633974..38065479 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -27,14 +27,13 @@ dependencies: sdk: flutter # Normal packages - flutter_quill: ^8.5.0 http: ^1.1.0 path: ^1.8.3 meta: ^1.9.1 universal_html: ^2.2.4 cross_file: ^0.3.3+6 - # math_keyboard: ^0.2.1 + flutter_quill: ^8.5.0 photo_view: ^0.14.0 # Plugins From 7352ae2e12107fa282602a112a1d2d9c8955282b Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 01:16:49 +0300 Subject: [PATCH 192/210] Update AndroidManifest.xml of the example --- example/android/app/src/main/AndroidManifest.xml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 447ef189..fcb9147b 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,9 +1,11 @@ - + - + @@ -44,7 +46,8 @@ + android:theme="@style/Theme.AppCompat.Light.NoActionBar" + tools:ignore="LockedOrientationActivity" /> Date: Wed, 15 Nov 2023 02:32:31 +0300 Subject: [PATCH 193/210] Update checkout to version 4 --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1ba516b2..aa72b67b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: channel: 'stable' From bd78a9b21567daa3823d0b1039390c9411b8ce2d Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 03:34:06 +0300 Subject: [PATCH 194/210] Update the example --- example/android/app/src/main/AndroidManifest.xml | 3 ++- example/lib/presentation/quill/quill_screen.dart | 5 ++++- example/lib/presentation/quill/quill_toolbar.dart | 14 +++++++++++++- lib/src/models/config/toolbar/configurations.dart | 4 ++-- lib/src/utils/platform.dart | 3 ++- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index fcb9147b..e047f006 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -5,7 +5,8 @@ + android:maxSdkVersion="32" + tools:ignore="ScopedStorage" /> diff --git a/example/lib/presentation/quill/quill_screen.dart b/example/lib/presentation/quill/quill_screen.dart index c091beb5..aab91c83 100644 --- a/example/lib/presentation/quill/quill_screen.dart +++ b/example/lib/presentation/quill/quill_screen.dart @@ -115,7 +115,10 @@ class _QuillScreenState extends State { ), child: Column( children: [ - if (!_isReadOnly) const MyQuillToolbar(), + if (!_isReadOnly) + MyQuillToolbar( + focusNode: _editorFocusNode, + ), Builder( builder: (context) { return Expanded( diff --git a/example/lib/presentation/quill/quill_toolbar.dart b/example/lib/presentation/quill/quill_toolbar.dart index a0f16677..b0257dc1 100644 --- a/example/lib/presentation/quill/quill_toolbar.dart +++ b/example/lib/presentation/quill/quill_toolbar.dart @@ -15,7 +15,12 @@ import '../settings/cubit/settings_cubit.dart'; import 'embeds/timestamp_embed.dart'; class MyQuillToolbar extends StatelessWidget { - const MyQuillToolbar({super.key}); + const MyQuillToolbar({ + required this.focusNode, + super.key, + }); + + final FocusNode focusNode; Future onImageInsertWithCropping( String image, @@ -211,6 +216,13 @@ class MyQuillToolbar extends StatelessWidget { } return QuillToolbar( configurations: QuillToolbarConfigurations( + showAlignmentButtons: true, + buttonOptions: QuillToolbarButtonOptions( + base: QuillToolbarBaseButtonOptions( + // Request editor focus when any button is pressed + afterButtonPressed: focusNode.requestFocus, + ), + ), customButtons: [ QuillToolbarCustomButtonOptions( icon: const Icon(Icons.add_alarm_rounded), diff --git a/lib/src/models/config/toolbar/configurations.dart b/lib/src/models/config/toolbar/configurations.dart index c609cd80..63d1a3c2 100644 --- a/lib/src/models/config/toolbar/configurations.dart +++ b/lib/src/models/config/toolbar/configurations.dart @@ -154,7 +154,7 @@ class QuillToolbarConfigurations extends Equatable { /// 'Nunito': 'nunito', /// 'Pacifico': 'pacifico', /// 'Roboto Mono': 'roboto-mono', - /// 'Clear'.i18n: 'Clear' + /// 'Clear'.loc: 'Clear' /// }; /// ``` final Map? fontFamilyValues; @@ -165,7 +165,7 @@ class QuillToolbarConfigurations extends Equatable { /// 'Small'.i18n: 'small', /// 'Large'.i18n: 'large', /// 'Huge'.i18n: 'huge', - /// 'Clear'.i18n: '0' + /// 'Clear'.loc: '0' /// } /// ``` final Map? fontSizesValues; diff --git a/lib/src/utils/platform.dart b/lib/src/utils/platform.dart index a06db05c..d248b369 100644 --- a/lib/src/utils/platform.dart +++ b/lib/src/utils/platform.dart @@ -4,7 +4,8 @@ import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/foundation.dart' show TargetPlatform, defaultTargetPlatform, kIsWeb, visibleForTesting; -/// If you want to override the [kIsWeb] use [overrideIsWeb] +/// If you want to override the [kIsWeb] use [overrideIsWeb] but it's only +/// for testing bool isWeb({ @visibleForTesting bool? overrideIsWeb, }) { From d80634007c0b5223befe5b11c8507e15d939eb42 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 19:47:47 +0300 Subject: [PATCH 195/210] Fix bug --- CHANGELOG.md | 3 +++ example/lib/main.dart | 2 +- .../widgets/toolbar/buttons/color/color.dart | 17 ++++++++++----- .../widgets/toolbar/buttons/link_style.dart | 21 ++++++++++++------- .../toolbar/buttons/search/search.dart | 15 +++++++++---- 5 files changed, 41 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2da2940c..2ba5417d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +## 8.5.5 +* Now you when opening dialogs by `QuillToolbar` you will not get an exception when you don't use `FlutterQuillLocalizations.delegate` in your `WidgetsApp`, `MaterialApp` or `CupertinoApp`. The fix is for `QuillToolbarSearchButton`, `QuillToolbarLinkStyleButton` and `QuillToolbarColorButton` buttons + ## 8.5.4 * The `mobileWidth`, `mobileHeight`, `mobileMargin` and `mobileAlignment` is now deprecated in `flutter_quill`, they are are now defined in `flutter_quill_extensions` * Deprecate `replaceStyleStringWithSize` function which is in `string.dart` diff --git a/example/lib/main.dart b/example/lib/main.dart index 3b53bca3..e263fb25 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -55,7 +55,7 @@ class MyApp extends StatelessWidget { GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, - FlutterQuillLocalizations.delegate, + // FlutterQuillLocalizations.delegate, ], supportedLocales: FlutterQuillLocalizations.supportedLocales, routes: { diff --git a/lib/src/widgets/toolbar/buttons/color/color.dart b/lib/src/widgets/toolbar/buttons/color/color.dart index 2986dfb5..cd45880d 100644 --- a/lib/src/widgets/toolbar/buttons/color/color.dart +++ b/lib/src/widgets/toolbar/buttons/color/color.dart @@ -2,11 +2,13 @@ import 'package:flutter/material.dart'; import '../../../../extensions/quill_provider.dart'; import '../../../../l10n/extensions/localizations.dart'; +import '../../../../l10n/widgets/localizations.dart'; import '../../../../models/documents/attribute.dart'; import '../../../../models/documents/style.dart'; import '../../../../models/themes/quill_icon_theme.dart'; import '../../../../utils/color.dart'; import '../../../controller.dart'; +import '../../../utils/provider.dart'; import '../../base_toolbar.dart'; import 'dialog.dart'; @@ -225,11 +227,16 @@ class QuillToolbarColorButtonState extends State { context: context, barrierColor: options.dialogBarrierColor ?? context.requireQuillSharedConfigurations.dialogBarrierColor, - builder: (context) => ColorPickerDialog( - isBackground: widget.isBackground, - onRequestChangeColor: _changeColor, - isToggledColor: _isToggledColor, - selectionStyle: _selectionStyle, + builder: (_) => QuillProvider.value( + value: context.requireQuillProvider, + child: FlutterQuillLocalizationsWidget( + child: ColorPickerDialog( + isBackground: widget.isBackground, + onRequestChangeColor: _changeColor, + isToggledColor: _isToggledColor, + selectionStyle: _selectionStyle, + ), + ), ), ); } diff --git a/lib/src/widgets/toolbar/buttons/link_style.dart b/lib/src/widgets/toolbar/buttons/link_style.dart index 19c63ad6..c87eb0e9 100644 --- a/lib/src/widgets/toolbar/buttons/link_style.dart +++ b/lib/src/widgets/toolbar/buttons/link_style.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import '../../../extensions/quill_provider.dart'; import '../../../l10n/extensions/localizations.dart'; +import '../../../l10n/widgets/localizations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/rules/insert.dart'; import '../../../models/structs/link_dialog_action.dart'; @@ -9,6 +10,7 @@ import '../../../models/themes/quill_dialog_theme.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../controller.dart'; import '../../link.dart'; +import '../../utils/provider.dart'; import '../base_toolbar.dart'; class QuillToolbarLinkStyleButton extends StatefulWidget { @@ -164,7 +166,7 @@ class QuillToolbarLinkStyleButtonState final value = await showDialog<_TextLink>( context: context, barrierColor: dialogBarrierColor, - builder: (ctx) { + builder: (_) { final link = _getLinkAttributeValue(); final index = controller.selection.start; @@ -179,12 +181,17 @@ class QuillToolbarLinkStyleButtonState final len = controller.selection.end - index; text ??= len == 0 ? '' : controller.document.getPlainText(index, len); - return _LinkDialog( - dialogTheme: options.dialogTheme, - link: link, - text: text, - linkRegExp: linkRegExp, - action: options.linkDialogAction, + return QuillProvider.value( + value: context.requireQuillProvider, + child: FlutterQuillLocalizationsWidget( + child: _LinkDialog( + dialogTheme: options.dialogTheme, + link: link, + text: text, + linkRegExp: linkRegExp, + action: options.linkDialogAction, + ), + ), ); }, ); diff --git a/lib/src/widgets/toolbar/buttons/search/search.dart b/lib/src/widgets/toolbar/buttons/search/search.dart index ceacdf8a..f800566b 100644 --- a/lib/src/widgets/toolbar/buttons/search/search.dart +++ b/lib/src/widgets/toolbar/buttons/search/search.dart @@ -2,9 +2,11 @@ import 'package:flutter/material.dart'; import '../../../../extensions/quill_provider.dart'; import '../../../../l10n/extensions/localizations.dart'; +import '../../../../l10n/widgets/localizations.dart'; import '../../../../models/themes/quill_dialog_theme.dart'; import '../../../../models/themes/quill_icon_theme.dart'; import '../../../controller.dart'; +import '../../../utils/provider.dart'; import '../../base_toolbar.dart'; class QuillToolbarSearchButton extends StatelessWidget { @@ -140,10 +142,15 @@ class QuillToolbarSearchButton extends StatelessWidget { await showDialog( barrierColor: _dialogBarrierColor(context), context: context, - builder: (_) => QuillToolbarSearchDialog( - controller: controller, - dialogTheme: _dialogTheme(context), - text: '', + builder: (_) => QuillProvider.value( + value: context.requireQuillProvider, + child: FlutterQuillLocalizationsWidget( + child: QuillToolbarSearchDialog( + controller: controller, + dialogTheme: _dialogTheme(context), + text: '', + ), + ), ), ); } From 763800f8e70628522dcc11e32d0bffe66d0298a5 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 20:13:17 +0300 Subject: [PATCH 196/210] Prepare for release --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index eeac5712..fce4127e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 8.5.4 +version: 8.5.5 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill From 22301937efdd8eca6612fcf180de803e09faa13e Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 20:16:56 +0300 Subject: [PATCH 197/210] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ba5417d..54ff7cdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file. ## 8.5.5 -* Now you when opening dialogs by `QuillToolbar` you will not get an exception when you don't use `FlutterQuillLocalizations.delegate` in your `WidgetsApp`, `MaterialApp` or `CupertinoApp`. The fix is for `QuillToolbarSearchButton`, `QuillToolbarLinkStyleButton` and `QuillToolbarColorButton` buttons +* Now when opening dialogs by `QuillToolbar` you will not get an exception when you don't use `FlutterQuillLocalizations.delegate` in your `WidgetsApp`, `MaterialApp`, or `CupertinoApp`. The fix is for `QuillToolbarSearchButton`, `QuillToolbarLinkStyleButton`, and `QuillToolbarColorButton` buttons ## 8.5.4 * The `mobileWidth`, `mobileHeight`, `mobileMargin` and `mobileAlignment` is now deprecated in `flutter_quill`, they are are now defined in `flutter_quill_extensions` From 70afb228d2cab906f95c8ff07f76374164aa42c2 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 20:17:33 +0300 Subject: [PATCH 198/210] Correct grammer in CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54ff7cdb..5e024d5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file. ## 8.5.5 -* Now when opening dialogs by `QuillToolbar` you will not get an exception when you don't use `FlutterQuillLocalizations.delegate` in your `WidgetsApp`, `MaterialApp`, or `CupertinoApp`. The fix is for `QuillToolbarSearchButton`, `QuillToolbarLinkStyleButton`, and `QuillToolbarColorButton` buttons +* Now when opening dialogs by `QuillToolbar` you will not get an exception when you don't use `FlutterQuillLocalizations.delegate` in your `WidgetsApp`, `MaterialApp`, or `CupertinoApp`. The fix is for the `QuillToolbarSearchButton`, `QuillToolbarLinkStyleButton`, and `QuillToolbarColorButton` buttons ## 8.5.4 * The `mobileWidth`, `mobileHeight`, `mobileMargin` and `mobileAlignment` is now deprecated in `flutter_quill`, they are are now defined in `flutter_quill_extensions` From 5f17888d80fda92f9dc992a8f99a7272b2eec42c Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 20:21:58 +0300 Subject: [PATCH 199/210] Update publish.yml --- .github/workflows/publish.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 83f33980..644aac7d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,15 +3,15 @@ name: Publish to pub.dev on: push: tags: - - 'v[0-9]+.[0-9]+.[0-9]+*' # tag pattern on pub.dev: 'v' + - 'v[0-9]+.[0-9]+.[0-9]+*' jobs: publish: permissions: - id-token: write # Required for authentication using OIDC + id-token: write runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: From c6fa7d4bc9da42050e4916b618c3f1419db8e7d9 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 22:19:36 +0300 Subject: [PATCH 200/210] Update bug template --- .github/ISSUE_TEMPLATE/1_bug.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/1_bug.yml b/.github/ISSUE_TEMPLATE/1_bug.yml index 8826b00c..7d705f2f 100644 --- a/.github/ISSUE_TEMPLATE/1_bug.yml +++ b/.github/ISSUE_TEMPLATE/1_bug.yml @@ -15,6 +15,14 @@ body: options: - label: I have searched the [existing issues](https://github.com/singerdmx/flutter-quill/issues) required: true + - type: input + attributes: + label: Flutter Quill Version + description: Please tell us which version of `flutter_quill` that you are using. + placeholder: | + 9.0.0 + validations: + required: true - type: textarea attributes: label: Steps to reproduce From cd5524fb8fce9209625d9aaab815757d1a1d9990 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 22:20:26 +0300 Subject: [PATCH 201/210] revert: Update bug template --- .github/ISSUE_TEMPLATE/1_bug.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/1_bug.yml b/.github/ISSUE_TEMPLATE/1_bug.yml index 7d705f2f..9c16baa2 100644 --- a/.github/ISSUE_TEMPLATE/1_bug.yml +++ b/.github/ISSUE_TEMPLATE/1_bug.yml @@ -15,14 +15,14 @@ body: options: - label: I have searched the [existing issues](https://github.com/singerdmx/flutter-quill/issues) required: true - - type: input - attributes: - label: Flutter Quill Version - description: Please tell us which version of `flutter_quill` that you are using. - placeholder: | - 9.0.0 - validations: - required: true + # - type: input + # attributes: + # label: Flutter Quill Version + # description: Please tell us which version of `flutter_quill` that you are using. + # placeholder: | + # 9.0.0 + # validations: + # required: true - type: textarea attributes: label: Steps to reproduce From 42f22b862de8adc5ff5766838865ae389131774b Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 22:21:00 +0300 Subject: [PATCH 202/210] Update bug template --- .github/ISSUE_TEMPLATE/1_bug.yml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/1_bug.yml b/.github/ISSUE_TEMPLATE/1_bug.yml index 9c16baa2..f00c47fe 100644 --- a/.github/ISSUE_TEMPLATE/1_bug.yml +++ b/.github/ISSUE_TEMPLATE/1_bug.yml @@ -15,14 +15,10 @@ body: options: - label: I have searched the [existing issues](https://github.com/singerdmx/flutter-quill/issues) required: true - # - type: input - # attributes: - # label: Flutter Quill Version - # description: Please tell us which version of `flutter_quill` that you are using. - # placeholder: | - # 9.0.0 - # validations: - # required: true + - type: input + attributes: + label: Flutter Quill Version + description: Please tell us which version of `flutter_quill` that you are using. - type: textarea attributes: label: Steps to reproduce From fd11cadb45fabd6c6f32858494593a36d7d8f70f Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 22:21:55 +0300 Subject: [PATCH 203/210] Update bug template --- .github/ISSUE_TEMPLATE/1_bug.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/1_bug.yml b/.github/ISSUE_TEMPLATE/1_bug.yml index f00c47fe..79213954 100644 --- a/.github/ISSUE_TEMPLATE/1_bug.yml +++ b/.github/ISSUE_TEMPLATE/1_bug.yml @@ -19,6 +19,9 @@ body: attributes: label: Flutter Quill Version description: Please tell us which version of `flutter_quill` that you are using. + placeholder: For example 9.0.0 + validations: + required: true - type: textarea attributes: label: Steps to reproduce From 2446c020e3017d9f196785ac0c7b2785b5cac287 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 22:28:16 +0300 Subject: [PATCH 204/210] Update bug report template --- .github/ISSUE_TEMPLATE/1_bug.yml | 42 +++++++++++++++++++++----------- example/pubspec.yaml | 4 +-- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/1_bug.yml b/.github/ISSUE_TEMPLATE/1_bug.yml index 79213954..975151b5 100644 --- a/.github/ISSUE_TEMPLATE/1_bug.yml +++ b/.github/ISSUE_TEMPLATE/1_bug.yml @@ -22,6 +22,16 @@ body: placeholder: For example 9.0.0 validations: required: true + - type: textarea + attributes: + label: Other Flutter Quill Packages Versions + description: If you are using any other packages like `flutter_quill_extensions` or `flutter_quill_test` please mention the versions here + placeholder: | + flutter_quill: ^8.5.5 + flutter_quill_extensions: ^0.6.10 + flutter_quill_test: ^0.0.5 + validations: + required: false - type: textarea attributes: label: Steps to reproduce @@ -80,6 +90,8 @@ body: [Upload media here] + validations: + required: false - type: textarea attributes: label: Logs @@ -103,19 +115,21 @@ body: ``` - - type: textarea - attributes: - label: Flutter Doctor output (optional) - description: | - Please provide the full output of running `flutter doctor -v` - if the issue is related on how the library use the Flutter Quill - value: | -
    Doctor output + validations: + required: false + # - type: textarea + # attributes: + # label: Flutter Doctor output (optional) + # description: | + # Please provide the full output of running `flutter doctor -v` + # if the issue is related on how the library use the Flutter Quill + # value: | + #
    Doctor output - ```console - [Paste your output here] - ``` + # ```console + # [Paste your output here] + # ``` -
    - # validations: - # required: true \ No newline at end of file + #
    + # validations: + # required: true \ No newline at end of file diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 18e40f9b..dc0df887 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -13,8 +13,8 @@ dependencies: cupertino_icons: ^1.0.6 # Flutter Quill Packages - flutter_quill: ^8.5.3 - flutter_quill_extensions: ^0.6.9 + flutter_quill: ^8.5.5 + flutter_quill_extensions: ^0.6.10 flutter_quill_test: ^0.0.5 quill_html_converter: ^0.0.1-experimental.1 From 7bf34de7b03a09cfbcda27e72a12d2ad931873b5 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 22:32:23 +0300 Subject: [PATCH 205/210] Update bug report template --- .github/ISSUE_TEMPLATE/1_bug.yml | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/1_bug.yml b/.github/ISSUE_TEMPLATE/1_bug.yml index 975151b5..df002fe7 100644 --- a/.github/ISSUE_TEMPLATE/1_bug.yml +++ b/.github/ISSUE_TEMPLATE/1_bug.yml @@ -90,8 +90,8 @@ body: [Upload media here] - validations: - required: false + validations: + required: false - type: textarea attributes: label: Logs @@ -115,21 +115,5 @@ body: ``` - validations: - required: false - # - type: textarea - # attributes: - # label: Flutter Doctor output (optional) - # description: | - # Please provide the full output of running `flutter doctor -v` - # if the issue is related on how the library use the Flutter Quill - # value: | - #
    Doctor output - - # ```console - # [Paste your output here] - # ``` - - #
    - # validations: - # required: true \ No newline at end of file + validations: + required: false \ No newline at end of file From 4058477837f62912fcba65d8a6c12ed854803b7b Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 22:33:50 +0300 Subject: [PATCH 206/210] Update bug report template --- .github/ISSUE_TEMPLATE/1_bug.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/1_bug.yml b/.github/ISSUE_TEMPLATE/1_bug.yml index df002fe7..b4c597dc 100644 --- a/.github/ISSUE_TEMPLATE/1_bug.yml +++ b/.github/ISSUE_TEMPLATE/1_bug.yml @@ -17,17 +17,16 @@ body: required: true - type: input attributes: - label: Flutter Quill Version + label: Flutter Quill version description: Please tell us which version of `flutter_quill` that you are using. placeholder: For example 9.0.0 validations: required: true - type: textarea attributes: - label: Other Flutter Quill Packages Versions + label: Other Flutter Quill packages versions description: If you are using any other packages like `flutter_quill_extensions` or `flutter_quill_test` please mention the versions here placeholder: | - flutter_quill: ^8.5.5 flutter_quill_extensions: ^0.6.10 flutter_quill_test: ^0.0.5 validations: From a0a0316b41c97712ef98cdaed70d34162d0cdcaa Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 23:01:23 +0300 Subject: [PATCH 207/210] Add new issue template --- .github/ISSUE_TEMPLATE/3_question.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/3_question.yml diff --git a/.github/ISSUE_TEMPLATE/3_question.yml b/.github/ISSUE_TEMPLATE/3_question.yml new file mode 100644 index 00000000..4a626204 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/3_question.yml @@ -0,0 +1,24 @@ +name: Ask a question +description: | + If you have any questions, feel free to ask +labels: 'help-wanted' +body: + - type: markdown + attributes: + value: | + Thank you for using Flutter Quill! + + - type: checkboxes + attributes: + label: Is there an existing issue for this? + options: + - label: I have searched the [existing issues](https://github.com/singerdmx/flutter-quill/issues) + required: true + - type: textarea + attributes: + label: The question + description: Please explain your question here + placeholder: | + How do I save the images of Quill Editor? + validations: + required: true \ No newline at end of file From bd3138bf4302f3c2fccdcd7f845e8c8928d47dea Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 15 Nov 2023 23:02:54 +0300 Subject: [PATCH 208/210] An attemp to fix the labels of question template --- .github/ISSUE_TEMPLATE/3_question.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/3_question.yml b/.github/ISSUE_TEMPLATE/3_question.yml index 4a626204..509ae635 100644 --- a/.github/ISSUE_TEMPLATE/3_question.yml +++ b/.github/ISSUE_TEMPLATE/3_question.yml @@ -1,7 +1,7 @@ name: Ask a question description: | If you have any questions, feel free to ask -labels: 'help-wanted' +labels: 'help wanted' body: - type: markdown attributes: From 56a05269529398b68a7b27708a03756ab3852c5b Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 16 Nov 2023 01:01:39 +0300 Subject: [PATCH 209/210] Update flutter_quill_extensions README.md --- flutter_quill_extensions/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index b6db052f..af85514f 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -39,6 +39,15 @@ dependencies: flutter_quill_extensions: ^ ``` +

    OR

    + +```yaml +dependencies: + flutter_quill_extensions: + git: https://github.com/singerdmx/flutter-quill.git + path: flutter_quill_extensions +``` + ## Platform Spesefic Configurations > From b6c119b15db1b34c2c0d010182b3209db55bd9c0 Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 16 Nov 2023 01:59:17 +0300 Subject: [PATCH 210/210] Format platform_test.dart --- test/utils/platform_test.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/utils/platform_test.dart b/test/utils/platform_test.dart index aafda16e..db4ee75a 100644 --- a/test/utils/platform_test.dart +++ b/test/utils/platform_test.dart @@ -23,8 +23,8 @@ void main() { expect( isDesktop( supportWeb: false, - platform: desktopPlatform, overrideIsWeb: false, + platform: desktopPlatform, ), true, ); @@ -64,8 +64,8 @@ void main() { ]) { expect( isMobile( - supportWeb: false, platform: mobilePlatform, + supportWeb: false, overrideIsWeb: false, ), true, @@ -73,9 +73,9 @@ void main() { expect( isMobile( + platform: mobilePlatform, supportWeb: false, overrideIsWeb: true, - platform: mobilePlatform, ), false, );

    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

    ($if@AwIx)Ow^&)KC!NX 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�TQg$HU#Zxw#P*zX~(F=%boq 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 z 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