From 35a9502d7e81f996b29219b9bc8ff9cb45d0279a Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 07:43:59 +0300 Subject: [PATCH] 1 --- CHANGELOG.md | 3 + .../lib/presentation/quill/quill_screen.dart | 8 +-- .../lib/presentation/quill/quill_toolbar.dart | 3 + .../lib/embeds/image/editor/image_embed.dart | 19 +++--- .../lib/embeds/image/editor/image_menu.dart | 57 +++++++--------- .../embeds/image/toolbar/image_button.dart | 13 ++-- .../image/toolbar/select_image_source.dart | 8 +-- .../embeds/video/toolbar/video_button.dart | 11 ++-- .../models/config/shared_configurations.dart | 2 +- lib/src/extensions/quill_provider.dart | 30 ++------- lib/src/l10n/widgets/localizations.dart | 2 +- .../models/config/editor/configurations.dart | 6 ++ lib/src/models/config/others/animations.dart | 46 ++++++------- .../models/config/quill_configurations.dart | 15 ++--- .../config/quill_shared_configurations.dart | 7 -- .../config/raw_editor/configurations.dart | 6 +- .../toolbar/toolbar_configurations.dart | 4 ++ lib/src/widgets/editor/editor.dart | 9 ++- .../raw_editor/raw_editor_actions.dart | 2 +- .../widgets/raw_editor/raw_editor_state.dart | 14 ++-- ...editor_state_selection_delegate_mixin.dart | 4 +- ..._editor_state_text_input_client_mixin.dart | 6 +- .../widgets/style_widgets/checkbox_point.dart | 17 ----- .../widgets/toolbar/buttons/color/color.dart | 19 +++--- .../widgets/toolbar/buttons/link_style.dart | 20 +++--- .../widgets/toolbar/buttons/link_style2.dart | 32 +++++---- .../toolbar/buttons/search/search.dart | 18 +++-- lib/src/widgets/toolbar/toolbar.dart | 6 +- pubspec.yaml | 3 +- test/bug_fix_test.dart | 50 ++++++-------- test/widgets/editor_test.dart | 66 ++++++++----------- 31 files changed, 212 insertions(+), 294 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a6cd7db..9d52f557 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev +* **Major Breaking change**: The `QuillProvider` is now optional, the `controller` parameter has been moved to the `QuillEditor` and `QuillToolbar` once again. + ## 8.6.4 * The default value of `keyboardAppearance` for the iOS will be the one from the App/System theme mode instead of always using the `Brightness.light` * Fix typos in `README.md` diff --git a/example/lib/presentation/quill/quill_screen.dart b/example/lib/presentation/quill/quill_screen.dart index aab91c83..1f504d2c 100644 --- a/example/lib/presentation/quill/quill_screen.dart +++ b/example/lib/presentation/quill/quill_screen.dart @@ -101,11 +101,9 @@ class _QuillScreenState extends State { ], ), body: QuillProvider( - configurations: QuillConfigurations( - controller: _controller, + configurations: const QuillConfigurations( sharedConfigurations: QuillSharedConfigurations( - animationConfigurations: QuillAnimationConfigurations.disableAll(), - extraConfigurations: const { + extraConfigurations: { QuillSharedExtensionsConfigurations.key: QuillSharedExtensionsConfigurations( assetsPrefix: 'assets', @@ -117,6 +115,7 @@ class _QuillScreenState extends State { children: [ if (!_isReadOnly) MyQuillToolbar( + controller: _controller, focusNode: _editorFocusNode, ), Builder( @@ -124,6 +123,7 @@ class _QuillScreenState extends State { return Expanded( child: MyQuillEditor( configurations: QuillEditorConfigurations( + controller: _controller, readOnly: _isReadOnly, ), scrollController: _editorScrollController, diff --git a/example/lib/presentation/quill/quill_toolbar.dart b/example/lib/presentation/quill/quill_toolbar.dart index f7aedf2a..0a9174c6 100644 --- a/example/lib/presentation/quill/quill_toolbar.dart +++ b/example/lib/presentation/quill/quill_toolbar.dart @@ -16,10 +16,12 @@ import 'embeds/timestamp_embed.dart'; class MyQuillToolbar extends StatelessWidget { const MyQuillToolbar({ + required this.controller, required this.focusNode, super.key, }); + final QuillController controller; final FocusNode focusNode; Future onImageInsertWithCropping( @@ -224,6 +226,7 @@ class MyQuillToolbar extends StatelessWidget { } return QuillToolbar( configurations: QuillToolbarConfigurations( + controller: controller, showAlignmentButtons: true, buttonOptions: QuillToolbarButtonOptions( base: QuillToolbarBaseButtonOptions( diff --git a/flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart b/flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart index 2ddc38db..ca223448 100644 --- a/flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart +++ b/flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart @@ -56,17 +56,14 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { onTap: configurations.onImageClicked ?? () => showDialog( context: context, - builder: (_) => QuillProvider.value( - value: context.requireQuillProvider, - child: FlutterQuillLocalizationsWidget( - child: ImageOptionsMenu( - controller: controller, - configurations: configurations, - imageSource: imageSource, - imageSize: imageSize, - isReadOnly: readOnly, - imageSaverService: imageSaverService, - ), + builder: (_) => FlutterQuillLocalizationsWidget( + child: ImageOptionsMenu( + controller: controller, + configurations: configurations, + imageSource: imageSource, + imageSize: imageSize, + isReadOnly: readOnly, + imageSaverService: imageSaverService, ), ), ), diff --git a/flutter_quill_extensions/lib/embeds/image/editor/image_menu.dart b/flutter_quill_extensions/lib/embeds/image/editor/image_menu.dart index 27c83ece..e6f0fcf6 100644 --- a/flutter_quill_extensions/lib/embeds/image/editor/image_menu.dart +++ b/flutter_quill_extensions/lib/embeds/image/editor/image_menu.dart @@ -1,13 +1,7 @@ import 'package:flutter/cupertino.dart' show showCupertinoModalPopup; import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart' - show - ImageUrl, - QuillController, - QuillProvider, - QuillProviderExt, - StyleAttribute, - getEmbedNode; + show ImageUrl, QuillController, StyleAttribute, getEmbedNode; import 'package:flutter_quill/translations.dart'; import '../../../models/config/editor/image/image.dart'; @@ -55,34 +49,31 @@ class ImageOptionsMenu extends StatelessWidget { context: context, builder: (modalContext) { final screenSize = MediaQuery.sizeOf(modalContext); - return QuillProvider.value( - value: context.requireQuillProvider, - child: FlutterQuillLocalizationsWidget( - child: ImageResizer( - onImageResize: (width, height) { - final res = getEmbedNode( - controller, - controller.selection.start, - ); + return FlutterQuillLocalizationsWidget( + child: ImageResizer( + onImageResize: (width, height) { + final res = getEmbedNode( + controller, + controller.selection.start, + ); - final attr = replaceStyleStringWithSize( - getImageStyleString(controller), - width: width, - height: height, + final attr = replaceStyleStringWithSize( + getImageStyleString(controller), + width: width, + height: height, + ); + controller + ..skipRequestKeyboard = true + ..formatText( + res.offset, + 1, + StyleAttribute(attr), ); - controller - ..skipRequestKeyboard = true - ..formatText( - res.offset, - 1, - StyleAttribute(attr), - ); - }, - imageWidth: imageSize.width, - imageHeight: imageSize.height, - maxWidth: screenSize.width, - maxHeight: screenSize.height, - ), + }, + imageWidth: imageSize.width, + imageHeight: imageSize.height, + maxWidth: screenSize.width, + maxHeight: screenSize.height, ), ); }, diff --git a/flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart b/flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart index fb00a656..06dcf805 100644 --- a/flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart +++ b/flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart @@ -172,14 +172,11 @@ class QuillToolbarImageButton extends StatelessWidget { Future _typeLink(BuildContext context) async { final value = await showDialog( context: context, - builder: (_) => QuillProvider.value( - value: context.requireQuillProvider, - child: FlutterQuillLocalizationsWidget( - child: TypeLinkDialog( - dialogTheme: options.dialogTheme, - linkRegExp: options.linkRegExp, - linkType: LinkType.image, - ), + builder: (_) => FlutterQuillLocalizationsWidget( + child: TypeLinkDialog( + dialogTheme: options.dialogTheme, + linkRegExp: options.linkRegExp, + linkType: LinkType.image, ), ), ); diff --git a/flutter_quill_extensions/lib/embeds/image/toolbar/select_image_source.dart b/flutter_quill_extensions/lib/embeds/image/toolbar/select_image_source.dart index 74de2c81..40b8de5d 100644 --- a/flutter_quill_extensions/lib/embeds/image/toolbar/select_image_source.dart +++ b/flutter_quill_extensions/lib/embeds/image/toolbar/select_image_source.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/extensions.dart' show isDesktop; -import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill/translations.dart'; import '../editor/image_embed_types.dart'; @@ -55,11 +54,8 @@ Future showSelectImageSourceDialog({ showDragHandle: true, context: context, constraints: const BoxConstraints(maxWidth: 640), - builder: (_) => QuillProvider.value( - value: context.requireQuillProvider, - child: const FlutterQuillLocalizationsWidget( - child: SelectImageSourceDialog(), - ), + builder: (_) => const FlutterQuillLocalizationsWidget( + child: SelectImageSourceDialog(), ), ); return imageSource; diff --git a/flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart b/flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart index f8b854b3..78011239 100644 --- a/flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart +++ b/flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart @@ -165,13 +165,10 @@ class QuillToolbarVideoButton extends StatelessWidget { Future _typeLink(BuildContext context) async { final value = await showDialog( context: context, - builder: (_) => QuillProvider.value( - value: context.requireQuillProvider, - child: FlutterQuillLocalizationsWidget( - child: TypeLinkDialog( - dialogTheme: options.dialogTheme, - linkType: LinkType.video, - ), + builder: (_) => FlutterQuillLocalizationsWidget( + child: TypeLinkDialog( + dialogTheme: options.dialogTheme, + linkType: LinkType.video, ), ), ); diff --git a/flutter_quill_extensions/lib/models/config/shared_configurations.dart b/flutter_quill_extensions/lib/models/config/shared_configurations.dart index 1badf553..a3162010 100644 --- a/flutter_quill_extensions/lib/models/config/shared_configurations.dart +++ b/flutter_quill_extensions/lib/models/config/shared_configurations.dart @@ -48,7 +48,7 @@ class QuillSharedExtensionsConfigurations { required BuildContext context, }) { final quillSharedExtensionsConfigurations = - context.requireQuillSharedConfigurations.extraConfigurations[key]; + context.quillSharedConfigurations?.extraConfigurations[key]; if (quillSharedExtensionsConfigurations != null) { if (quillSharedExtensionsConfigurations is! QuillSharedExtensionsConfigurations) { diff --git a/lib/src/extensions/quill_provider.dart b/lib/src/extensions/quill_provider.dart index 364cdf0b..29d251af 100644 --- a/lib/src/extensions/quill_provider.dart +++ b/lib/src/extensions/quill_provider.dart @@ -6,12 +6,6 @@ import '../../flutter_quill.dart'; /// Public shared extension extension QuillProviderExt on BuildContext { - /// return [QuillProvider] as not null - /// throw exception if it's not in the widget tree - QuillProvider get requireQuillProvider { - return QuillProvider.ofNotNull(this); - } - /// return nullable [QuillProvider] /// don't throw exception if it's not in the widget tree /// instead it will be null @@ -25,7 +19,8 @@ extension QuillProviderExt on BuildContext { /// don't throw exception if [QuillProvider] is not in the widget tree /// instead it will be null QuillController? get quilController { - return quillProvider?.configurations.controller; + return quillToolbarConfigurations?.controller ?? + quillEditorConfigurations?.controller; } /// return [QuillController] as not null @@ -33,15 +28,10 @@ extension QuillProviderExt on BuildContext { /// the provider widget first and then we will return the controller /// throw exception if [QuillProvider] is not in the widget tree QuillController get requireQuillController { - return requireQuillProvider.configurations.controller; - } - - /// return [QuillConfigurations] as not null - /// since the quill configurations is in the [QuillProvider] then we need to - /// get the provider widget first and then we will return quill configurations - /// throw exception if [QuillProvider] is not in the widget tree - QuillConfigurations get requireQuillConfigurations { - return requireQuillProvider.configurations; + return quillToolbarConfigurations?.controller ?? + quillEditorConfigurations?.controller ?? + (throw ArgumentError( + 'The quill provider is required, you must only call requireQuillController inside the QuillToolbar and QuillEditor')); } /// return nullable [QuillConfigurations] @@ -52,14 +42,6 @@ extension QuillProviderExt on BuildContext { return quillProvider?.configurations; } - /// return [QuillSharedConfigurations] as not null. Since the quill - /// shared configurations is in the [QuillProvider] then we need to get the - /// provider widget first and then we will return shared configurations - /// throw exception if [QuillProvider] is not in the widget tree - QuillSharedConfigurations get requireQuillSharedConfigurations { - return requireQuillConfigurations.sharedConfigurations; - } - /// return nullable [QuillSharedConfigurations] . Since the quill /// shared configurations is in the [QuillProvider] then we need to get the /// provider widget first and then we will return shared configurations diff --git a/lib/src/l10n/widgets/localizations.dart b/lib/src/l10n/widgets/localizations.dart index 7e40894d..85fe5ff2 100644 --- a/lib/src/l10n/widgets/localizations.dart +++ b/lib/src/l10n/widgets/localizations.dart @@ -19,7 +19,7 @@ class FlutterQuillLocalizationsWidget extends StatelessWidget { return child; } return Localizations( - locale: context.requireQuillSharedConfigurations.locale ?? + locale: context.quillSharedConfigurations?.locale ?? Localizations.localeOf(context), delegates: FlutterQuillLocalizations.localizationsDelegates, child: child, diff --git a/lib/src/models/config/editor/configurations.dart b/lib/src/models/config/editor/configurations.dart index c6e0f5de..a08ff076 100644 --- a/lib/src/models/config/editor/configurations.dart +++ b/lib/src/models/config/editor/configurations.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart' import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart' show experimental; +import '../../../widgets/controller.dart'; import '../../../widgets/default_styles.dart'; import '../../../widgets/delegate.dart'; import '../../../widgets/editor/editor.dart'; @@ -24,6 +25,7 @@ class QuillEditorConfigurations extends Equatable { /// Important note for the maintainers /// When editing this class please update the [copyWith] function too. const QuillEditorConfigurations({ + required this.controller, this.scrollable = true, this.padding = EdgeInsets.zero, this.autoFocus = false, @@ -74,6 +76,8 @@ class QuillEditorConfigurations extends Equatable { this.textInputAction = TextInputAction.newline, }); + final QuillController controller; + /// The text placeholder in the quill editor final String? placeholder; @@ -331,6 +335,7 @@ class QuillEditorConfigurations extends Equatable { // regenerate this function using extension in vs code or plugin in intellij QuillEditorConfigurations copyWith({ + QuillController? controller, String? placeholder, bool? readOnly, bool? scrollable, @@ -376,6 +381,7 @@ class QuillEditorConfigurations extends Equatable { TextInputAction? textInputAction, }) { return QuillEditorConfigurations( + controller: controller ?? this.controller, placeholder: placeholder ?? this.placeholder, readOnly: readOnly ?? this.readOnly, scrollable: scrollable ?? this.scrollable, diff --git a/lib/src/models/config/others/animations.dart b/lib/src/models/config/others/animations.dart index ce6bcb0c..42e08279 100644 --- a/lib/src/models/config/others/animations.dart +++ b/lib/src/models/config/others/animations.dart @@ -1,28 +1,28 @@ -import 'package:equatable/equatable.dart'; -import 'package:meta/meta.dart' show experimental, immutable; +// import 'package:equatable/equatable.dart'; +// import 'package:meta/meta.dart' show experimental, immutable; -@immutable -@experimental -class QuillAnimationConfigurations extends Equatable { - const QuillAnimationConfigurations({ - required this.checkBoxPointItem, - }); +// @immutable +// @experimental +// class QuillAnimationConfigurations extends Equatable { +// const QuillAnimationConfigurations({ +// required this.checkBoxPointItem, +// }); - factory QuillAnimationConfigurations.disableAll() => - const QuillAnimationConfigurations( - checkBoxPointItem: false, - ); +// factory QuillAnimationConfigurations.disableAll() => +// const QuillAnimationConfigurations( +// checkBoxPointItem: false, +// ); - factory QuillAnimationConfigurations.enableAll() => - const QuillAnimationConfigurations( - checkBoxPointItem: true, - ); +// factory QuillAnimationConfigurations.enableAll() => +// const QuillAnimationConfigurations( +// checkBoxPointItem: true, +// ); - /// This currently has issue which the whole checkbox list will rebuilt - /// and the animation will replay when some value changes - /// which is why disabled by default - final bool checkBoxPointItem; +// /// This currently has issue which the whole checkbox list will rebuilt +// /// and the animation will replay when some value changes +// /// which is why disabled by default +// final bool checkBoxPointItem; - @override - List get props => []; -} +// @override +// List get props => []; +// } diff --git a/lib/src/models/config/quill_configurations.dart b/lib/src/models/config/quill_configurations.dart index fd9d985f..b18f6396 100644 --- a/lib/src/models/config/quill_configurations.dart +++ b/lib/src/models/config/quill_configurations.dart @@ -10,17 +10,16 @@ export 'toolbar/toolbar_configurations.dart'; @immutable class QuillConfigurations extends Equatable { const QuillConfigurations({ - required this.controller, this.sharedConfigurations = const QuillSharedConfigurations(), }); - /// Controller object which establishes a link between a rich text document - /// and this editor. - /// - /// The controller is shared between [QuillEditorConfigurations] and - /// [QuillToolbarConfigurations] but to simplify things we will defined it - /// here, it should not be null - final QuillController controller; + // /// Controller object which establishes a link between a rich text document + // /// and this editor. + // /// + // /// The controller is shared between [QuillEditorConfigurations] and + // /// [QuillToolbarConfigurations] but to simplify things we will defined it + // /// here, it should not be null + // final QuillController controller; /// The shared configurations between [QuillEditorConfigurations] and /// [QuillToolbarConfigurations] so we don't duplicate things diff --git a/lib/src/models/config/quill_shared_configurations.dart b/lib/src/models/config/quill_shared_configurations.dart index fd34e8dd..0ee34c1b 100644 --- a/lib/src/models/config/quill_shared_configurations.dart +++ b/lib/src/models/config/quill_shared_configurations.dart @@ -15,9 +15,6 @@ class QuillSharedConfigurations extends Equatable { this.dialogBarrierColor = Colors.black54, this.dialogTheme, this.locale, - this.animationConfigurations = const QuillAnimationConfigurations( - checkBoxPointItem: false, - ), this.extraConfigurations = const {}, }); @@ -37,9 +34,6 @@ class QuillSharedConfigurations extends Equatable { /// `MaterialApp` or `WidgetsApp` final Locale? locale; - /// 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; @@ -48,6 +42,5 @@ class QuillSharedConfigurations extends Equatable { dialogBarrierColor, dialogTheme, locale, - animationConfigurations, ]; } diff --git a/lib/src/models/config/raw_editor/configurations.dart b/lib/src/models/config/raw_editor/configurations.dart index 2fe2866b..9d486e91 100644 --- a/lib/src/models/config/raw_editor/configurations.dart +++ b/lib/src/models/config/raw_editor/configurations.dart @@ -49,7 +49,7 @@ class QuillRawEditorConfigurations extends Equatable { this.showCursor = true, this.scrollable = true, this.padding = EdgeInsets.zero, - this.isReadOnly = false, + this.readOnly = false, this.placeholder, this.onLaunchUrl, this.contextMenuBuilder = defaultContextMenuBuilder, @@ -97,7 +97,7 @@ class QuillRawEditorConfigurations extends Equatable { /// by any shortcut or keyboard operation. The text is still selectable. /// /// Defaults to false. Must not be null. - final bool isReadOnly; + final bool readOnly; final String? placeholder; @@ -296,7 +296,7 @@ class QuillRawEditorConfigurations extends Equatable { @override List get props => [ - isReadOnly, + readOnly, placeholder, ]; } diff --git a/lib/src/models/config/toolbar/toolbar_configurations.dart b/lib/src/models/config/toolbar/toolbar_configurations.dart index e4ccf4ad..92b5b460 100644 --- a/lib/src/models/config/toolbar/toolbar_configurations.dart +++ b/lib/src/models/config/toolbar/toolbar_configurations.dart @@ -3,6 +3,7 @@ import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' show Axis, Widget, WrapAlignment, WrapCrossAlignment; +import '../../../widgets/controller.dart'; import '../../../widgets/embeds.dart'; import '../../themes/quill_dialog_theme.dart'; import '../../themes/quill_icon_theme.dart'; @@ -67,6 +68,7 @@ enum LinkStyleType { @immutable class QuillToolbarConfigurations extends QuillSharedToolbarProperties { const QuillToolbarConfigurations({ + required this.controller, super.toolbarSectionSpacing = kToolbarSectionSpacing, super.toolbarIconAlignment = WrapAlignment.center, super.toolbarIconCrossAlignment = WrapCrossAlignment.center, @@ -143,6 +145,8 @@ class QuillToolbarConfigurations extends QuillSharedToolbarProperties { return buttonOptions.base.globalIconSize * 2; } + final QuillController controller; + /// 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 diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index f0dfdf9a..361570e0 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -155,8 +155,7 @@ class QuillEditor extends StatefulWidget { factory QuillEditor.basic({ /// The configurations for the quill editor widget of flutter quill - QuillEditorConfigurations configurations = - const QuillEditorConfigurations(), + required QuillEditorConfigurations configurations, FocusNode? focusNode, ScrollController? scrollController, }) { @@ -257,13 +256,13 @@ class QuillEditorState extends State child: QuillRawEditor( key: _editorKey, configurations: QuillRawEditorConfigurations( - controller: context.requireQuillController, + controller: configurations.controller, focusNode: widget.focusNode, scrollController: widget.scrollController, scrollable: configurations.scrollable, scrollBottomInset: configurations.scrollBottomInset, padding: configurations.padding, - isReadOnly: configurations.readOnly, + readOnly: configurations.readOnly, placeholder: configurations.placeholder, onLaunchUrl: configurations.onLaunchUrl, contextMenuBuilder: showSelectionToolbar @@ -442,7 +441,7 @@ class _QuillEditorSelectionGestureDetectorBuilder } bool _isPositionSelected(TapUpDetails details) { - if (_state.context.requireQuillController.document.isEmpty()) { + if (_state.configurations.controller.document.isEmpty()) { return false; } final pos = renderEditor!.getPositionForOffset(details.globalPosition); diff --git a/lib/src/widgets/raw_editor/raw_editor_actions.dart b/lib/src/widgets/raw_editor/raw_editor_actions.dart index 54a7eba7..caed0f7c 100644 --- a/lib/src/widgets/raw_editor/raw_editor_actions.dart +++ b/lib/src/widgets/raw_editor/raw_editor_actions.dart @@ -76,7 +76,7 @@ class QuillEditorDeleteTextAction @override bool get isActionEnabled => - !state.widget.configurations.isReadOnly && + !state.widget.configurations.readOnly && state.textEditingValue.selection.isValid; } diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index dc13082f..ced4ab06 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -552,7 +552,7 @@ class QuillRawEditorState extends EditorState controller.document.queryChild(controller.selection.baseOffset); KeyEventResult insertTabCharacter() { - if (widget.configurations.isReadOnly) { + if (widget.configurations.readOnly) { return KeyEventResult.ignored; } controller.replaceText(controller.selection.baseOffset, 0, '\t', null); @@ -662,7 +662,7 @@ class QuillRawEditorState extends EditorState void _handleCheckboxTap(int offset, bool value) { final requestKeyboardFocusOnCheckListChanged = widget.configurations.requestKeyboardFocusOnCheckListChanged; - if (!widget.configurations.isReadOnly) { + if (!widget.configurations.readOnly) { _disableScrollControllerAnimateOnce = true; final currentSelection = controller.selection.copyWith(); final attribute = value ? Attribute.checked : Attribute.unchecked; @@ -737,7 +737,7 @@ class QuillRawEditorState extends EditorState indentLevelCounts: indentLevelCounts, clearIndents: clearIndents, onCheckboxTap: _handleCheckboxTap, - readOnly: widget.configurations.isReadOnly, + readOnly: widget.configurations.readOnly, customStyleBuilder: widget.configurations.customStyleBuilder, customLinkPrefixes: widget.configurations.customLinkPrefixes, ); @@ -767,7 +767,7 @@ class QuillRawEditorState extends EditorState customStyleBuilder: widget.configurations.customStyleBuilder, customRecognizerBuilder: widget.configurations.customRecognizerBuilder, styles: _styles!, - readOnly: widget.configurations.isReadOnly, + readOnly: widget.configurations.readOnly, controller: controller, linkActionPicker: _linkActionPicker, onLaunchUrl: widget.configurations.onLaunchUrl, @@ -968,7 +968,7 @@ class QuillRawEditorState extends EditorState if (!shouldCreateInputConnection) { closeConnectionIfNeeded(); } else { - if (oldWidget.configurations.isReadOnly && _hasFocus) { + if (oldWidget.configurations.readOnly && _hasFocus) { openConnectionIfNeeded(); } } @@ -1298,7 +1298,7 @@ class QuillRawEditorState extends EditorState _pastePlainText = controller.getPlainText(); _pasteStyleAndEmbed = controller.getAllIndividualSelectionStylesAndEmbed(); - if (widget.configurations.isReadOnly) { + if (widget.configurations.readOnly) { return; } final selection = textEditingValue.selection; @@ -1318,7 +1318,7 @@ class QuillRawEditorState extends EditorState /// Paste text from [Clipboard]. @override Future pasteText(SelectionChangedCause cause) async { - if (widget.configurations.isReadOnly) { + if (widget.configurations.readOnly) { return; } 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 46617573..53f0cd6f 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 @@ -171,7 +171,7 @@ mixin RawEditorStateSelectionDelegateMixin on EditorState @override bool get cutEnabled => widget.configurations.contextMenuBuilder != null && - !widget.configurations.isReadOnly; + !widget.configurations.readOnly; @override bool get copyEnabled => widget.configurations.contextMenuBuilder != null; @@ -179,7 +179,7 @@ mixin RawEditorStateSelectionDelegateMixin on EditorState @override bool get pasteEnabled => widget.configurations.contextMenuBuilder != null && - !widget.configurations.isReadOnly; + !widget.configurations.readOnly; @override bool get selectAllEnabled => widget.configurations.contextMenuBuilder != null; 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 f9698bd2..d41180ca 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 @@ -30,7 +30,7 @@ mixin RawEditorStateTextInputClientMixin on EditorState /// - cmd/ctrl+a to select all. /// - Changing the selection using a physical keyboard. bool get shouldCreateInputConnection => - kIsWeb || !widget.configurations.isReadOnly; + kIsWeb || !widget.configurations.readOnly; /// Returns `true` if there is open input connection. bool get hasConnection => @@ -58,9 +58,9 @@ mixin RawEditorStateTextInputClientMixin on EditorState this, TextInputConfiguration( inputType: TextInputType.multiline, - readOnly: widget.configurations.isReadOnly, + readOnly: widget.configurations.readOnly, inputAction: widget.configurations.textInputAction, - enableSuggestions: !widget.configurations.isReadOnly, + enableSuggestions: !widget.configurations.readOnly, keyboardAppearance: widget.configurations.keyboardAppearance ?? CupertinoTheme.maybeBrightnessOf(context) ?? Theme.of(context).brightness, diff --git a/lib/src/widgets/style_widgets/checkbox_point.dart b/lib/src/widgets/style_widgets/checkbox_point.dart index 5eb82686..860d5696 100644 --- a/lib/src/widgets/style_widgets/checkbox_point.dart +++ b/lib/src/widgets/style_widgets/checkbox_point.dart @@ -1,7 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_animate/flutter_animate.dart'; - -import '../../extensions/quill_provider.dart'; class QuillEditorCheckboxPoint extends StatefulWidget { const QuillEditorCheckboxPoint({ @@ -76,20 +73,6 @@ class QuillEditorCheckboxPointState extends State { ), ), ); - if (context.requireQuillSharedConfigurations.animationConfigurations - .checkBoxPointItem) { - return Animate( - effects: const [ - SlideEffect( - duration: Duration(milliseconds: 70), - ), - ScaleEffect( - duration: Duration(milliseconds: 70), - ) - ], - child: child, - ); - } return child; } } diff --git a/lib/src/widgets/toolbar/buttons/color/color.dart b/lib/src/widgets/toolbar/buttons/color/color.dart index cd45880d..1691d71c 100644 --- a/lib/src/widgets/toolbar/buttons/color/color.dart +++ b/lib/src/widgets/toolbar/buttons/color/color.dart @@ -8,7 +8,6 @@ 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'; @@ -226,16 +225,14 @@ class QuillToolbarColorButtonState extends State { showDialog( context: context, barrierColor: options.dialogBarrierColor ?? - context.requireQuillSharedConfigurations.dialogBarrierColor, - builder: (_) => QuillProvider.value( - value: context.requireQuillProvider, - child: FlutterQuillLocalizationsWidget( - child: ColorPickerDialog( - isBackground: widget.isBackground, - onRequestChangeColor: _changeColor, - isToggledColor: _isToggledColor, - selectionStyle: _selectionStyle, - ), + context.quillSharedConfigurations?.dialogBarrierColor ?? + Colors.black54, + builder: (_) => 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 c87eb0e9..e6d62e53 100644 --- a/lib/src/widgets/toolbar/buttons/link_style.dart +++ b/lib/src/widgets/toolbar/buttons/link_style.dart @@ -100,7 +100,8 @@ class QuillToolbarLinkStyleButtonState Color get dialogBarrierColor { return options.dialogBarrierColor ?? - context.requireQuillSharedConfigurations.dialogBarrierColor; + context.quillSharedConfigurations?.dialogBarrierColor ?? + Colors.black54; } RegExp? get linkRegExp { @@ -181,16 +182,13 @@ class QuillToolbarLinkStyleButtonState final len = controller.selection.end - index; text ??= len == 0 ? '' : controller.document.getPlainText(index, len); - return QuillProvider.value( - value: context.requireQuillProvider, - child: FlutterQuillLocalizationsWidget( - child: _LinkDialog( - dialogTheme: options.dialogTheme, - link: link, - text: text, - linkRegExp: linkRegExp, - action: options.linkDialogAction, - ), + return FlutterQuillLocalizationsWidget( + child: _LinkDialog( + dialogTheme: options.dialogTheme, + link: link, + text: text, + linkRegExp: linkRegExp, + action: options.linkDialogAction, ), ); }, diff --git a/lib/src/widgets/toolbar/buttons/link_style2.dart b/lib/src/widgets/toolbar/buttons/link_style2.dart index 517f7b5b..26f092ef 100644 --- a/lib/src/widgets/toolbar/buttons/link_style2.dart +++ b/lib/src/widgets/toolbar/buttons/link_style2.dart @@ -107,7 +107,8 @@ class _QuillToolbarLinkStyleButton2State Color get dialogBarrierColor { return options.dialogBarrierColor ?? - context.requireQuillSharedConfigurations.dialogBarrierColor; + context.quillSharedConfigurations?.dialogBarrierColor ?? + Colors.black54; } @override @@ -173,22 +174,19 @@ class _QuillToolbarLinkStyleButton2State final textLink = await showDialog( context: context, barrierColor: dialogBarrierColor, - builder: (_) => QuillProvider.value( - value: context.requireQuillProvider, - child: FlutterQuillLocalizationsWidget( - child: LinkStyleDialog( - dialogTheme: options.dialogTheme, - text: initialTextLink.text, - link: initialTextLink.link, - constraints: options.constraints, - addLinkLabel: options.addLinkLabel, - editLinkLabel: options.editLinkLabel, - linkColor: options.linkColor, - childrenSpacing: options.childrenSpacing, - autovalidateMode: options.autovalidateMode, - validationMessage: options.validationMessage, - buttonSize: options.buttonSize, - ), + builder: (_) => FlutterQuillLocalizationsWidget( + child: LinkStyleDialog( + dialogTheme: options.dialogTheme, + text: initialTextLink.text, + link: initialTextLink.link, + constraints: options.constraints, + addLinkLabel: options.addLinkLabel, + editLinkLabel: options.editLinkLabel, + linkColor: options.linkColor, + childrenSpacing: options.childrenSpacing, + autovalidateMode: options.autovalidateMode, + validationMessage: options.validationMessage, + buttonSize: options.buttonSize, ), ), ); diff --git a/lib/src/widgets/toolbar/buttons/search/search.dart b/lib/src/widgets/toolbar/buttons/search/search.dart index f800566b..7def9fba 100644 --- a/lib/src/widgets/toolbar/buttons/search/search.dart +++ b/lib/src/widgets/toolbar/buttons/search/search.dart @@ -63,12 +63,13 @@ class QuillToolbarSearchButton extends StatelessWidget { Color _dialogBarrierColor(BuildContext context) { return options.dialogBarrierColor ?? - context.requireQuillSharedConfigurations.dialogBarrierColor; + context.quillSharedConfigurations?.dialogBarrierColor ?? + Colors.black54; } QuillDialogTheme? _dialogTheme(BuildContext context) { return options.dialogTheme ?? - context.requireQuillSharedConfigurations.dialogTheme; + context.quillSharedConfigurations?.dialogTheme; } @override @@ -142,14 +143,11 @@ class QuillToolbarSearchButton extends StatelessWidget { await showDialog( barrierColor: _dialogBarrierColor(context), context: context, - builder: (_) => QuillProvider.value( - value: context.requireQuillProvider, - child: FlutterQuillLocalizationsWidget( - child: QuillToolbarSearchDialog( - controller: controller, - dialogTheme: _dialogTheme(context), - text: '', - ), + builder: (_) => FlutterQuillLocalizationsWidget( + child: QuillToolbarSearchDialog( + controller: controller, + dialogTheme: _dialogTheme(context), + text: '', ), ), ); diff --git a/lib/src/widgets/toolbar/toolbar.dart b/lib/src/widgets/toolbar/toolbar.dart index 8d7a6fc8..8d9fc9c5 100644 --- a/lib/src/widgets/toolbar/toolbar.dart +++ b/lib/src/widgets/toolbar/toolbar.dart @@ -9,8 +9,8 @@ import 'base_toolbar.dart'; class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { const QuillToolbar({ + required this.configurations, super.key, - this.configurations = const QuillToolbarConfigurations(), }); /// The configurations for the toolbar widget of flutter quill @@ -71,7 +71,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { toolbarConfigurations.buttonOptions.base.globalIconSize; final axis = toolbarConfigurations.axis; - final globalController = context.requireQuillController; + final globalController = configurations.controller; final spacerWidget = configurations.spacerWidget ?? const SizedBox.shrink(); @@ -270,7 +270,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { options: toolbarConfigurations.buttonOptions.direction, controller: toolbarConfigurations .buttonOptions.direction.controller ?? - context.requireQuillController, + globalController, ), spacerWidget, ], diff --git a/pubspec.yaml b/pubspec.yaml index bcd2b3f2..d4e53d69 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.6.4 +version: 9.0.0-dev homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ @@ -50,7 +50,6 @@ dependencies: characters: ^1.3.0 diff_match_patch: ^0.4.1 equatable: ^2.0.5 - flutter_animate: ^4.2.0+1 meta: ^1.9.1 # Plugins diff --git a/test/bug_fix_test.dart b/test/bug_fix_test.dart index 81849459..f6c2c4ed 100644 --- a/test/bug_fix_test.dart +++ b/test/bug_fix_test.dart @@ -16,19 +16,15 @@ void main() { await tester.pumpWidget( MaterialApp( - home: QuillProvider( - configurations: QuillConfigurations( + home: QuillToolbar( + configurations: QuillToolbarConfigurations( controller: controller, - ), - child: const QuillToolbar( - configurations: QuillToolbarConfigurations( - showRedo: false, - customButtons: [ - QuillToolbarCustomButtonOptions( - tooltip: tooltip, - ) - ], - ), + showRedo: false, + customButtons: const [ + QuillToolbarCustomButtonOptions( + tooltip: tooltip, + ) + ], ), ), ), @@ -64,7 +60,8 @@ void main() { controller = QuillController.basic(); editor = QuillEditor.basic( // ignore: avoid_redundant_argument_values - configurations: const QuillEditorConfigurations( + configurations: QuillEditorConfigurations( + controller: controller, // ignore: avoid_redundant_argument_values readOnly: false, ), @@ -78,12 +75,9 @@ void main() { testWidgets('Refocus editor after controller clears document', (tester) async { await tester.pumpWidget( - QuillProvider( - configurations: QuillConfigurations(controller: controller), - child: MaterialApp( - home: Column( - children: [editor], - ), + MaterialApp( + home: Column( + children: [editor], ), ), ); @@ -99,12 +93,9 @@ void main() { testWidgets('Refocus editor after removing block attribute', (tester) async { - await tester.pumpWidget(QuillProvider( - configurations: QuillConfigurations(controller: controller), - child: MaterialApp( - home: Column( - children: [editor], - ), + await tester.pumpWidget(MaterialApp( + home: Column( + children: [editor], ), )); await tester.quillEnterText(find.byType(QuillEditor), 'test\n'); @@ -120,12 +111,9 @@ void main() { testWidgets('Tap checkbox in unfocused editor', (tester) async { await tester.pumpWidget( - QuillProvider( - configurations: QuillConfigurations(controller: controller), - child: MaterialApp( - home: Column( - children: [editor], - ), + MaterialApp( + home: Column( + children: [editor], ), ), ); diff --git a/test/widgets/editor_test.dart b/test/widgets/editor_test.dart index f063e429..72db9c2b 100644 --- a/test/widgets/editor_test.dart +++ b/test/widgets/editor_test.dart @@ -21,15 +21,13 @@ void main() { group('QuillEditor', () { testWidgets('Keyboard entered text is stored in document', (tester) async { await tester.pumpWidget( - QuillProvider( - configurations: QuillConfigurations(controller: controller), - child: MaterialApp( - home: QuillEditor.basic( + MaterialApp( + home: QuillEditor.basic( + // ignore: avoid_redundant_argument_values + configurations: QuillEditorConfigurations( + controller: controller, // ignore: avoid_redundant_argument_values - configurations: const QuillEditorConfigurations( - // ignore: avoid_redundant_argument_values - readOnly: false, - ), + readOnly: false, ), ), ), @@ -43,24 +41,20 @@ void main() { String? latestUri; await tester.pumpWidget( MaterialApp( - home: QuillProvider( - configurations: QuillConfigurations( + home: QuillEditor( + focusNode: FocusNode(), + scrollController: ScrollController(), + configurations: QuillEditorConfigurations( controller: controller, - ), - child: QuillEditor( - focusNode: FocusNode(), - scrollController: ScrollController(), - configurations: QuillEditorConfigurations( - // ignore: avoid_redundant_argument_values - readOnly: false, - autoFocus: true, - expands: true, - contentInsertionConfiguration: ContentInsertionConfiguration( - onContentInserted: (content) { - latestUri = content.uri; - }, - allowedMimeTypes: ['image/gif'], - ), + // ignore: avoid_redundant_argument_values + readOnly: false, + autoFocus: true, + expands: true, + contentInsertionConfiguration: ContentInsertionConfiguration( + onContentInserted: (content) { + latestUri = content.uri; + }, + allowedMimeTypes: ['image/gif'], ), ), ), @@ -120,21 +114,17 @@ void main() { testWidgets('custom context menu builder', (tester) async { await tester.pumpWidget( MaterialApp( - home: QuillProvider( - configurations: QuillConfigurations( + home: QuillEditor( + focusNode: FocusNode(), + scrollController: ScrollController(), + // ignore: avoid_redundant_argument_values + configurations: QuillEditorConfigurations( controller: controller, - ), - child: QuillEditor( - focusNode: FocusNode(), - scrollController: ScrollController(), // ignore: avoid_redundant_argument_values - configurations: QuillEditorConfigurations( - // ignore: avoid_redundant_argument_values - readOnly: false, - autoFocus: true, - expands: true, - contextMenuBuilder: customBuilder, - ), + readOnly: false, + autoFocus: true, + expands: true, + contextMenuBuilder: customBuilder, ), ), ),