From 35a9502d7e81f996b29219b9bc8ff9cb45d0279a Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 07:43:59 +0300 Subject: [PATCH 01/86] 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 0a6cd7db3..9d52f5573 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 aab91c83a..1f504d2c1 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 f7aedf2af..0a9174c6b 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 2ddc38dbf..ca2234485 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 27c83ecef..e6f0fcf6b 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 fb00a6564..06dcf805a 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 74de2c819..40b8de5da 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 f8b854b3c..780112396 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 1badf5533..a31620107 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 364cdf0b8..29d251afd 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 7e40894da..85fe5ff21 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 c6e0f5de5..a08ff076f 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 ce6bcb0cb..42e082796 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 fd9d985f3..b18f63963 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 fd34e8dd0..0ee34c1be 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 2fe2866b8..9d486e912 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 e4ccf4ad2..92b5b4604 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 f0dfdf9a5..361570e01 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 54a7eba7a..caed0f7ce 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 dc13082f5..ced4ab06c 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 466175732..53f0cd6f6 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 f9698bd21..d41180ca9 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 5eb826863..860d5696f 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 cd45880db..1691d71cd 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 c87eb0e92..e6d62e537 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 517f7b5b1..26f092efc 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 f800566b2..7def9fbab 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 8d7a6fc8d..8d9fc9c5b 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 bcd2b3f22..d4e53d69b 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 818494592..f6c2c4edc 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 f063e4291..72db9c2b5 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, ), ), ), From 7207dbf5323b01e686026939c7865f7127bc7301 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 08:25:22 +0300 Subject: [PATCH 02/86] 2 --- .github/workflows/publish.yml | 21 +++++++++++++--- doc/translation.md | 2 +- flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 1 + ...slations.sh => regenerate_translations.sh} | 2 +- scripts/regenerate_versions.dart | 24 +++++++++++++++++++ version.dart | 1 + 8 files changed, 48 insertions(+), 7 deletions(-) rename scripts/{regenerate-translations.sh => regenerate_translations.sh} (93%) create mode 100644 scripts/regenerate_versions.dart create mode 100644 version.dart diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 87fec6831..bc01a66ca 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -27,15 +27,30 @@ jobs: # - run: dart tool/generate-code.dart - name: Re-generate the translations - run: ./scripts/regenerate-translations.sh - + run: ./scripts/regenerate_translations.sh + + - name: Re-generate the versions + run: dart ./scripts/regenerate_versions.dart # This is needed in order for the authentication to success # dart pub token add https://pub.dev --env-var PUB_TOKEN # Requests to "https://pub.dev" will now be authenticated using the secret token stored in the environment variable "PUB_TOKEN". - uses: dart-lang/setup-dart@v1 + ## dart-lang/setup-dart/.github/workflows/publish.yml@v1 # - name: Update the authorization requests to "https://pub.dev" to use the environment variable "PUB_TOKEN". # run: dart pub token add https://pub.dev --env-var PUB_TOKEN - - name: Publish + - name: Publish flutter_quill + run: flutter pub publish --force + + - name: Publish flutter_quill_extensions + run: flutter pub publish --force + working-directory: ./flutter_quill_extensions + + - name: Publish flutter_quill_test + run: flutter pub publish --force + working-directory: ./flutter_quill_test + + - name: Publish quill_html_converter run: flutter pub publish --force + working-directory: ./packages/quill_html_converter diff --git a/doc/translation.md b/doc/translation.md index 5bdaf542d..5d801ba80 100644 --- a/doc/translation.md +++ b/doc/translation.md @@ -56,7 +56,7 @@ flutter gen-l10n or: ``` -./scripts/regenerate-translations.sh +./scripts/regenerate_translations.sh ``` diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 254d628a2..6ceffb04e 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.8.0-dev +version: 9.0.0-dev homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 2c18005af..192633864 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.5 +version: 9.0.0-dev homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index d4e53d69b..2351f76fd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -65,6 +65,7 @@ dev_dependencies: flutter_quill_test: ^0.0.4 test: ^1.24.3 intl_translation: ^0.18.2 + yaml_edit: ^2.1.1 flutter: uses-material-design: true diff --git a/scripts/regenerate-translations.sh b/scripts/regenerate_translations.sh similarity index 93% rename from scripts/regenerate-translations.sh rename to scripts/regenerate_translations.sh index 1f7c26e52..8e1583bf0 100755 --- a/scripts/regenerate-translations.sh +++ b/scripts/regenerate_translations.sh @@ -1,7 +1,7 @@ #!/bin/bash # Important: make sure to run the script in the root folder of the repo: -# ./scripts/regenerate-translations.sh +# ./scripts/regenerate_translations.sh # otherwise the script could delete the wrong folder in rare cases echo "" diff --git a/scripts/regenerate_versions.dart b/scripts/regenerate_versions.dart new file mode 100644 index 000000000..b233c54b8 --- /dev/null +++ b/scripts/regenerate_versions.dart @@ -0,0 +1,24 @@ +import 'dart:io' show File; + +import 'package:yaml_edit/yaml_edit.dart'; + +// You must run this script in the root folder of the repo and not inside the scripts + +// ignore: unused_import +import '../version.dart'; + +Future main(List args) async { + await updatePubspecYamlFile('./pubspec.yaml'); + await updatePubspecYamlFile('./flutter_quill_extensions/pubspec.yaml'); + await updatePubspecYamlFile('./flutter_quill_test/pubspec.yaml'); + await updatePubspecYamlFile('./packages/quill_html_converter/pubspec.yaml'); +} + +Future updatePubspecYamlFile(String path) async { + final file = File(path); + final yaml = await file.readAsString(); + final yamlEditor = YamlEditor(yaml)..update(['version'], version); + await file.writeAsString(yamlEditor.toString()); + // ignore: avoid_print + print(yamlEditor.toString()); +} diff --git a/version.dart b/version.dart new file mode 100644 index 000000000..207b9df35 --- /dev/null +++ b/version.dart @@ -0,0 +1 @@ +const version = '9.0.0-dev'; From 798d9075d535cb90ef318b1023e1ccf574292568 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 08:29:47 +0300 Subject: [PATCH 03/86] 2+ --- .github/workflows/publish.yml | 44 ++++++++--------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index bc01a66ca..36a94a474 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -13,44 +13,20 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: subosito/flutter-action@v2 - with: - channel: 'stable' - - - name: Check flutter version - run: flutter --version - - - name: Install dependencies - run: flutter pub get - - # Here you can insert custom steps you need - # - run: dart tool/generate-code.dart - - - name: Re-generate the translations - run: ./scripts/regenerate_translations.sh - - - name: Re-generate the versions - run: dart ./scripts/regenerate_versions.dart - - # This is needed in order for the authentication to success - # dart pub token add https://pub.dev --env-var PUB_TOKEN - # Requests to "https://pub.dev" will now be authenticated using the secret token stored in the environment variable "PUB_TOKEN". - - uses: dart-lang/setup-dart@v1 - ## dart-lang/setup-dart/.github/workflows/publish.yml@v1 - # - name: Update the authorization requests to "https://pub.dev" to use the environment variable "PUB_TOKEN". - # run: dart pub token add https://pub.dev --env-var PUB_TOKEN - - name: Publish flutter_quill - run: flutter pub publish --force + uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 - name: Publish flutter_quill_extensions - run: flutter pub publish --force - working-directory: ./flutter_quill_extensions + uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 + with: + working-directory: ./flutter_quill_extensions - name: Publish flutter_quill_test - run: flutter pub publish --force - working-directory: ./flutter_quill_test + uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 + with: + working-directory: ./flutter_quill_test - name: Publish quill_html_converter - run: flutter pub publish --force - working-directory: ./packages/quill_html_converter + uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 + with: + working-directory: ./packages/quill_html_converter From 09fc229f66fa13e5078eeb5317bfd3d0181e4aaa Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 08:39:28 +0300 Subject: [PATCH 04/86] 2++ --- .github/workflows/publish.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 36a94a474..df07283d7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -13,6 +13,9 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Test + run: echo $HOME + - name: Publish flutter_quill uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 From 2c875528309f42f4a5fc8c144c659c6cae33e3bf Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 08:44:18 +0300 Subject: [PATCH 05/86] 2+++ --- .github/workflows/publish.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index df07283d7..36a94a474 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -13,9 +13,6 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Test - run: echo $HOME - - name: Publish flutter_quill uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 From d464443d488acfb1dd1f249da6ce8f8ee55d1645 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 08:53:17 +0300 Subject: [PATCH 06/86] 2++++ --- .github/workflows/publish.yml | 42 ++++++++++++++++++----------------- .github/workflows/s.yaml | 0 2 files changed, 22 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/s.yaml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 36a94a474..6e1497c9b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,30 +3,32 @@ name: Publish to pub.dev on: push: tags: - - 'v[0-9]+.[0-9]+.[0-9]+*' + - 'v[0-9]+.[0-9]+.[0-9]+*' jobs: + publish: permissions: - id-token: write - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Publish flutter_quill - uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 + id-token: write # Required for authentication using OIDC + uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 - - name: Publish flutter_quill_extensions - uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 - with: - working-directory: ./flutter_quill_extensions + publish_extensions: + permissions: + id-token: write # Required for authentication using OIDC + uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 + with: + working-directory: ./flutter_quill_extensions - - name: Publish flutter_quill_test - uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 - with: - working-directory: ./flutter_quill_test + publish_test: + permissions: + id-token: write # Required for authentication using OIDC + uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 + with: + working-directory: ./flutter_quill_test - - name: Publish quill_html_converter - uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 - with: - working-directory: ./packages/quill_html_converter + publish_html_converter: + permissions: + id-token: write # Required for authentication using OIDC + uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 + with: + working-directory: ./packages/quill_html_converter \ No newline at end of file diff --git a/.github/workflows/s.yaml b/.github/workflows/s.yaml new file mode 100644 index 000000000..e69de29bb From 2406cf0b88cdca0c510cc15eb85fe1ecd4db9424 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 08:54:42 +0300 Subject: [PATCH 07/86] Remove s.yaml file --- .github/workflows/s.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .github/workflows/s.yaml diff --git a/.github/workflows/s.yaml b/.github/workflows/s.yaml deleted file mode 100644 index e69de29bb..000000000 From 309655ebf3e23c4b6596e5d977fe7a9e7f77f4c5 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 08:56:42 +0300 Subject: [PATCH 08/86] 2+++++ --- .github/workflows/publish.yml | 61 ++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6e1497c9b..74e41839d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,32 +3,49 @@ name: Publish to pub.dev on: push: tags: - - 'v[0-9]+.[0-9]+.[0-9]+*' + - 'v[0-9]+.[0-9]+.[0-9]+*' jobs: - publish: permissions: - id-token: write # Required for authentication using OIDC - uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 + id-token: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 - publish_extensions: - permissions: - id-token: write # Required for authentication using OIDC - uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 - with: - working-directory: ./flutter_quill_extensions + - uses: subosito/flutter-action@v2 + with: + channel: 'stable' + cache: true + + - name: Check flutter version + run: flutter --version - publish_test: - permissions: - id-token: write # Required for authentication using OIDC - uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 - with: - working-directory: ./flutter_quill_test + - name: Install dependencies + run: flutter pub get - publish_html_converter: - permissions: - id-token: write # Required for authentication using OIDC - uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 - with: - working-directory: ./packages/quill_html_converter \ No newline at end of file + # Here you can insert custom steps you need + # - run: dart tool/generate-code.dart + + # This is needed in order for the authentication to success + # dart pub token add https://pub.dev --env-var PUB_TOKEN + # Requests to "https://pub.dev" will now be authenticated using the secret token stored in the environment variable "PUB_TOKEN". + - uses: dart-lang/setup-dart@v1 + ## dart-lang/setup-dart/.github/workflows/publish.yml@v1 + # - name: Update the authorization requests to "https://pub.dev" to use the environment variable "PUB_TOKEN". + # run: dart pub token add https://pub.dev --env-var PUB_TOKEN + + - name: Publish flutter_quill + run: flutter pub publish --force + + - name: Publish flutter_quill_extensions + run: flutter pub publish --force + working-directory: ./flutter_quill_extensions + + - name: Publish flutter_quill_test + run: flutter pub publish --force + working-directory: ./flutter_quill_test + + - name: Publish quill_html_converter + run: flutter pub publish --force + working-directory: ./packages/quill_html_converter From e3a706cc4fd385db59bcdacfa0bda76ef6214ea8 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 08:58:59 +0300 Subject: [PATCH 09/86] 2++++++ --- .github/workflows/publish.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 74e41839d..8a41a991f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,6 +20,9 @@ jobs: - name: Check flutter version run: flutter --version + + - name: Enable Local Dev + run: ./scripts/enable_local_dev.sh - name: Install dependencies run: flutter pub get From 8d6a180d281e6045c1bef9cbee3090d2dc18e62a Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 09:14:36 +0300 Subject: [PATCH 10/86] 2+++++++ --- .github/workflows/publish.yml | 6 +- CHANGELOG.md | 10 + flutter_quill_extensions/CHANGELOG.md | 1633 ++++++++++++++++- flutter_quill_extensions/pubspec.yaml | 4 +- flutter_quill_test/CHANGELOG.md | 1583 +++++++++++++++- flutter_quill_test/pubspec.yaml | 4 +- .../config/quill_shared_configurations.dart | 1 - lib/src/widgets/editor/editor.dart | 1 - .../widgets/toolbar/buttons/link_style.dart | 1 - .../widgets/toolbar/buttons/link_style2.dart | 1 - .../toolbar/buttons/search/search.dart | 1 - packages/quill_html_converter/CHANGELOG.md | 1588 +++++++++++++++- packages/quill_html_converter/pubspec.yaml | 4 +- pubspec.yaml | 2 +- scripts/regenerate_versions.dart | 25 +- version.dart | 2 +- 16 files changed, 4735 insertions(+), 131 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8a41a991f..45970dc53 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -43,12 +43,12 @@ jobs: - name: Publish flutter_quill_extensions run: flutter pub publish --force - working-directory: ./flutter_quill_extensions + working-directory: ./flutter_quill_extensions/ - name: Publish flutter_quill_test run: flutter pub publish --force - working-directory: ./flutter_quill_test + working-directory: ./flutter_quill_test/ - name: Publish quill_html_converter run: flutter pub publish --force - working-directory: ./packages/quill_html_converter + working-directory: ./packages/quill_html_converter/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d52f5573..e0bbc6ec8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,18 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-1 +* An attemp to fix CI automated publishing + ## 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. +* Flutter Quill Extensions; + * **Breaking Change**: Completly change the way how the source code structured to more basic and simple way, organize folders and file names, if you use the library +from `flutter_quill_extensions.dart` then there is nothing you need to do, but if you are using any other import then you need to re-imports +embed, this won't affect how quill js work + * Improvemenets to the image embed + * Add support for `margin` for web + * Add untranslated strings to the `quill_en.arb` ## 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` diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 5cf7f2802..e0bbc6ec8 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,157 +2,1586 @@ All notable changes to this project will be documented in this file. -## 0.8.0-dev -* **Breaking Change**: Completly change the way how the source code structured to more basic and simple way, organize folders and file names, if you use the library +## 9.0.0-dev-1 +* An attemp to fix CI automated publishing + +## 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. +* Flutter Quill Extensions; + * **Breaking Change**: Completly change the way how the source code structured to more basic and simple way, organize folders and file names, if you use the library from `flutter_quill_extensions.dart` then there is nothing you need to do, but if you are using any other import then you need to re-imports embed, this won't affect how quill js work -* Improvemenets to the image embed -* Add support for `margin` for web -* Add untranslated strings to the `quill_en.arb` + * Improvemenets to the image embed + * Add support for `margin` for web + * Add untranslated strings to the `quill_en.arb` + +## 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` + +## 8.6.3 +* Update the minimum flutter version to `3.16.0` + +## 8.6.2 +* Restore use of alternative QuillToolbarLinkStyleButton2 widget + +## 8.6.1 +* Temporary revert style bug fix + +## 8.6.0 +* **Breaking Change** Support [Flutter 3.16](https://medium.com/flutter/whats-new-in-flutter-3-16-dba6cb1015d1), please upgrade to the latest stable version of flutter to use this update +* **Breaking Change**: Remove Deprecated Fields +* **Breaking Change**: Extract the shared things between `QuillToolbarConfigurations` and `QuillBaseToolbarConfigurations` +* **Breaking Change**: You no longer need to use `QuillToolbarProvider` when using custom toolbar buttons, the example has been updated +* Bug fixes + +## 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 the `QuillToolbarSearchButton`, `QuillToolbarLinkStyleButton`, and `QuillToolbarColorButton` buttons + +## 8.5.4 +* The `mobileWidth`, `mobileHeight`, `mobileMargin`, and `mobileAlignment` is now deprecated in `flutter_quill`, they 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` + +## 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`. + +## 8.5.1 +* 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. + +## 8.4.4 +* Updated `.pubignore` to ignore unnecessary files and folders. + +## 8.4.3 +* 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. + +## 8.4.1 +* 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. + +## 8.3.0 +* 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. + +## 8.2.5 +* Added `builder` property in `QuillEditorConfigurations`. + +## 8.2.4 +* Adhered to Flutter best practices. +* Fixed auto-focus bug. + +## 8.2.3 +* Updated `README.md`. + +## 8.2.2 +* Moved `flutter_quill_test` to a separate package: [flutter_quill_test](https://pub.dev/packages/flutter_quill_test). + +## 8.2.1 +* Updated `README.md`. + +## 8.2.0 +* 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`. + +## 8.1.10 +* Secret for automated publishing to pub.dev. + +## 8.1.9 +* Fixed automated publishing to pub.dev. + +## 8.1.8 +* Fixed automated publishing to pub.dev. + +## 8.1.7 +* 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. + +## 8.1.5 +* Reversed background/font color toolbar button icons. + +## 8.1.4 +* Reversed background/font color toolbar button tooltips. + +## 8.1.3 +* 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`. + +## 8.1.1 +* 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`. + +## 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. + +## 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`. + +## 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`. + +## 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. + +## 7.9.0 +* Buttons Improvemenets +* Refactor all the button configurations that used in `QuillToolbar.basic()` but there are still few lefts +* **Breaking change**: Remove some configurations from the QuillToolbar and move them to the new `QuillProvider`, please notice this is a development version and this might be changed in the next few days, the stable release will be ready in less than 3 weeks +* Update `flutter_quill_extensions` and it will be published into pub.dev soon. +* Allow you to customize the search dialog by custom callback with child builder + +## 7.8.0 +* **Important note**: this is not test release yet, it works but need more test and changes and breaking changes, we don't have development version and it will help us if you try the latest version and report the issues in Github but if you want a stable version please use `7.4.16`. this refactoring process will not take long and should be done less than three weeks with the testing. +* We managed to refactor most of the buttons configurations and customizations in the `QuillProvider`, only three lefts then will start on refactoring the toolbar configurations +* Code improvemenets + +## 7.7.0 +* **Breaking change**: We have mirgrated more buttons in the toolbar configurations, you can do change them in the `QuillProvider` +* Important bug fixes + +## 7.6.1 +* Bug fixes + +## 7.6.0 +* **Breaking change**: To customize the buttons in the toolbar, you can do that in the `QuillProvider` + +## 7.5.0 +* **Breaking change**: The widgets `QuillEditor` and `QuillToolbar` are no longer have controller parameter, instead you need to make sure in the widget tree you have wrapped them with `QuillProvider` widget and provide the controller and the require configurations + +## 7.4.16 +* Update documentation and README.md + +## 7.4.15 +* Custom style attrbuites for platforms other than mobile (alignment, margin, width, height) +* Bug fixes and other improvemenets + +## 7.4.14 +* 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)` +* Add MediaButton for picking the images only since the video one is not ready +* A new feature which allows customizing the text selection in quill editor which is useful for custom theme design system for custom app widget + +## 7.4.13 +* Fixed tab editing when in readOnly mode. + +## 7.4.12 +* Update the minimum version of device_info_plus to 9.1.0. + +## 7.4.11 +* Add sw locale. + +## 7.4.10 +* Update translations. + +## 7.4.9 +* Style recognition fixes. + +## 7.4.8 +* Upgrade dependencies. + +## 7.4.7 +* Add Vietnamese and German translations. + +## 7.4.6 +* Fix more null errors in Leaf.retain [##1394](https://github.com/singerdmx/flutter-quill/issues/1394) and Line.delete [##1395](https://github.com/singerdmx/flutter-quill/issues/1395). + +## 7.4.5 +* Fix null error in Container.insert [##1392](https://github.com/singerdmx/flutter-quill/issues/1392). + +## 7.4.4 +* Fix extra padding on checklists [##1131](https://github.com/singerdmx/flutter-quill/issues/1131). + +## 7.4.3 +* Fixed a space input error on iPad. + +## 7.4.2 +* Fix bug with keepStyleOnNewLine for link. + +## 7.4.1 +* Fix toolbar dividers condition. + +## 7.4.0 +* Support Flutter version 3.13.0. + +## 7.3.3 +* Updated Dependencies conflicting. + +## 7.3.2 +* Added builder for custom button in _LinkDialog. + +## 7.3.1 +* Added case sensitive and whole word search parameters. +* Added wrap around. +* Moved search dialog to the bottom in order not to override the editor and the text found. +* Other minor search dialog enhancements. + +## 7.3.0 +* Add default attributes to basic factory. + +## 7.2.19 +* Feat/link regexp. + +## 7.2.18 +* Fix paste block text in words apply same style. + +## 7.2.17 +* Fix paste text mess up style. +* Add support copy/cut block text. + +## 7.2.16 +* Allow for custom context menu. + +## 7.2.15 +* Add flutter_quill.delta library which only exposes Delta datatype. + +## 7.2.14 +* Fix errors when the editor is used in the `screenshot` package. + +## 7.2.13 +* Fix around image can't delete line break. + +## 7.2.12 +* Add support for copy/cut select image and text together. + +## 7.2.11 +* Add affinity for localPosition. + +## 7.2.10 +* LINE._getPlainText queryChild inclusive=false. + +## 7.2.9 +* Add toPlainText method to `EmbedBuilder`. + +## 7.2.8 +* Add custom button widget in toolbar. + +## 7.2.7 +* Fix language code of Japan. + +## 7.2.6 +* Style custom toolbar buttons like builtins. + +## 7.2.5 +* Always use text cursor for editor on desktop. + +## 7.2.4 +* Fixed keepStyleOnNewLine. + +## 7.2.3 +* Get pixel ratio from view. + +## 7.2.2 +* Prevent operations on stale editor state. + +## 7.2.1 +* Add support for android keyboard content insertion. +* Enhance color picker, enter hex color and color palette option. + +## 7.2.0 +* Checkboxes, bullet points, and number points are now scaled based on the default paragraph font size. + +## 7.1.20 +* Pass linestyle to embedded block. + +## 7.1.19 +* Fix Rtl leading alignment problem. + +## 7.1.18 +* Support flutter latest version. + +## 7.1.17+1 +* Updates `device_info_plus` to version 9.0.0 to benefit from AGP 8 (see [changelog##900](https://pub.dev/packages/device_info_plus/changelog##900)). + +## 7.1.16 +* Fixed subscript key from 'sup' to 'sub'. + +## 7.1.15 +* Fixed a bug introduced in 7.1.7 where each section in `QuillToolbar` was displayed on its own line. + +## 7.1.14 +* Add indents change for multiline selection. + +## 7.1.13 + +* Add custom recognizer. + +## 7.1.12 + +* Add superscript and subscript styles. + +## 7.1.11 + +* 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) + +## 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) + +## 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. + +## 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. + +Now the package is more friendly for web projects. + +## 7.1.6 + +* Add enableUnfocusOnTapOutside field to RawEditor and Editor widgets. + +## 7.1.5 + +* Add tooltips for toolbar buttons. + +## 7.1.4 + +* Fix inserting tab character in lists. + +## 7.1.3 + +* Fix ios cursor bug when word.length==1. + +## 7.1.2 + +* Fix non scrollable editor exception, when tapped under content. + +## 7.1.1 + +* customLinkPrefixes parameter * makes possible to open links with custom protoco. + +## 7.1.0 + +* Fix ordered list numeration with several lists in document. + +## 7.0.9 + +* Use const constructor for EmbedBuilder. + +## 7.0.8 + +* Fix IME position bug with scroller. + +## 7.0.7 + +* Add TextFieldTapRegion for contextMenu. + +## 7.0.6 + +* 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. + +## 7.0.4 + +* 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. + +## 7.0.2 + +* Allow widgets to override widget span properties. + +## 7.0.1 + +* 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. + +## 6.4.4 + +* 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) + +## 6.4.2 + +* Replace `buildToolbar` with `contextMenuBuilder`. + +## 6.4.1 + +* 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`. + +## 6.3.5 + +* Ability to add custom shortcuts. + +## 6.3.4 + +* Update clipboard status prior to showing selected text overlay. + +## 6.3.3 + +* Fixed handling of mac intents. + +## 6.3.2 + +* Added `unknownEmbedBuilder` to QuillEditor. +* Fix error style when input chinese japanese or korean. + +## 6.3.1 + +* Add color property to the basic factory function. + +## 6.3.0 + +* Support Flutter 3.7. + +## 6.2.2 + +* Fix: nextLine getter null where no assertion. + +## 6.2.1 + +* Revert "Align numerical and bullet lists along with text content". + +## 6.2.0 + +* Align numerical and bullet lists along with text content. + +## 6.1.12 + +* Apply i18n for default font dropdown option labels corresponding to 'Clear'. + +## 6.1.11 + +* Remove iOS hack for delaying focus calculation. + +## 6.1.10 + +* Delay focus calculation for iOS. + +## 6.1.9 + +* Bump keyboard show up wait to 1 sec. + +## 6.1.8 + +* Recalculate focus when showing keyboard. + +## 6.1.7 + +* Add czech localizations. + +## 6.1.6 + +* Upgrade i18n_extension to 6.0.0. + +## 6.1.5 + +* Fix formatting exception. + +## 6.1.4 + +* Add double quotes validation. + +## 6.1.3 + +* Revert "fix order list numbering (##988)". + +## 6.1.2 + +* Add typing shortcuts. + +## 6.1.1 + +* Fix order list numbering. + +## 6.1.0 + +* Add keyboard shortcuts for editor actions. + +## 6.0.10 + +* 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. + +## 6.0.8+1 + +* Fixes null pointer when setting documents. + +## 6.0.8 + +* Make QuillController.document mutable. + +## 6.0.7 + +* Allow disabling of selection toolbar. + +## 6.0.6+1 + +* Revert 6.0.6. + +## 6.0.6 + +* Fix wrong custom embed key. + +## 6.0.5 + +* Fixes toolbar buttons stealing focus from editor. + +## 6.0.4 + +* Bug fix for Type 'Uint8List' not found. + +## 6.0.3 + +* Add ability to paste images. + +## 6.0.2 + +* 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. + +## 6.0.0 BREAKING CHANGE + +* 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: + +``` +import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; + +QuillEditor.basic( + controller: controller, + embedBuilders: FlutterQuillEmbeds.builders(), +); + +QuillToolbar.basic( + controller: controller, + embedButtons: FlutterQuillEmbeds.buttons(), +); +``` + +## 5.4.2 + +* Upgrade i18n_extension. + +## 5.4.1 + +* Update German Translation. + +## 5.4.0 + +* Added Formula Button (for maths support). + +## 5.3.2 + +* Add more font family. + +## 5.3.1 + +* Enable search when text is not empty. + +## 5.3.0 + +* Added search function. + +## 5.2.11 + +* Remove default small color. + +## 5.2.10 + +* 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. + +## 5.2.8 + +* Remove tooltip for LinkStyleButton. +* Make link match regex case insensitive. + +## 5.2.7 + +* Add locale to QuillEditor.basic. + +## 5.2.6 + +* Fix keyboard pops up when resizing the image. + +## 5.2.5 + +* Upgrade youtube_player_flutter_quill to 8.2.2. + +## 5.2.4 + +* 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'). + +## 5.2.2 + +* Fix Web Unsupported operation: Platform.\_operatingSystem error. + +## 5.2.1 + +* Rename QuillCustomIcon to QuillCustomButton. + +## 5.2.0 + +* Support font family selection. + +## 5.1.1 + +* Update README. + +## 5.1.0 + +* Added CustomBlockEmbed and customElementsEmbedBuilder. + +## 5.0.5 + +* Upgrade device_info_plus to 4.0.0. + +## 5.0.4 + +* Added onVideoInit callback for video documents. + +## 5.0.3 + +* Update dependencies. + +## 5.0.2 + +* Keep cursor position on checkbox tap. + +## 5.0.1 + +* Fix static analysis errors. + +## 5.0.0 + +* Flutter 3.0.0 support. + +## 4.2.3 + +* Ignore color:inherit and convert double to int for level. + +## 4.2.2 + +* Add clear option to font size dropdown. + +## 4.2.1 + +* Refactor font size dropdown. + +## 4.2.0 + +* Ensure selectionOverlay is available for showToolbar. + +## 4.1.9 + +* Using properly iconTheme colors. + +## 4.1.8 + +* Update font size dropdown. + +## 4.1.7 + +* Convert FontSize to a Map to allow for named Font Size. + +## 4.1.6 + +* Update quill_dropdown_button.dart. + +## 4.1.5 + +* Add Font Size dropdown to the toolbar. + +## 4.1.4 + +* New borderRadius for iconTheme. + +## 4.1.3 + +* 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. + +## 4.1.1 + +* Added textSelectionControls field in QuillEditor. + +## 4.1.0 + +* Added Node to linkActionPickerDelegate. + +## 4.0.12 + +* Add Persian(fa) language. + +## 4.0.11 + +* Fix cut selection error in multi-node line. + +## 4.0.10 + +* Fix vertical caret position bug. + +## 4.0.9 + +* Request keyboard focus when no child is found. + +## 4.0.8 + +* 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. + +## 4.0.6 + +* 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). + +## 4.0.4 + +* Bug fix for text direction rtl. + +## 4.0.3 + +* Support text direction rtl. + +## 4.0.2 + +* Clear toggled style on selection change. + +## 4.0.1 + +* Fix copy/cut/paste/selectAll not working. + +## 4.0.0 + +* Upgrade for Flutter 2.10. + +## 3.9.11 + +* Added Indonesian translation. + +## 3.9.10 + +* 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. + +## 3.9.8 + +* Added Urdu translation. + +## 3.9.7 + +* Fix for clicking on the Link button without any text on a new line crashes. + +## 3.9.6 + +* Apply locale to QuillEditor(contents). + +## 3.9.5 + +* Fix image pasting. + +## 3.9.4 + +* Hiding dialog after selecting action for image. + +## 3.9.3 + +* Update ImageResizer for Android. + +## 3.9.2 + +* Copy image with its style. + +## 3.9.1 + +* Support resizing image. + +## 3.9.0 + +* Image menu options for copy/remove. + +## 3.8.8 + +* Update set textEditingValue. + +## 3.8.7 + +* Fix checkbox not toggled correctly in toolbar button. + +## 3.8.6 + +* Fix cursor position changes when checking/unchecking the checkbox. + +## 3.8.5 + +* Fix \_handleDragUpdate in \_TextSelectionHandleOverlayState. + +## 3.8.4 + +* Fix link dialog layout. + +## 3.8.3 + +* 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. + +## 3.8.1 + +* Refactor \_QuillEditorState to QuillEditorState. + +## 3.8.0 + +* Support pasting with format. + +## 3.7.3 + +* Fix selection overlay for collapsed selection. + +## 3.7.2 + +* Reverted Embed toPlainText change. + +## 3.7.1 + +* Change Embed toPlainText to be empty string. + +## 3.7.0 + +* Replace Toolbar showHistory group with individual showRedo and showUndo. + +## 3.6.5 + +* Update Link dialogue for image/video. + +## 3.6.4 + +* Link dialogue TextInputType.multiline. + +## 3.6.3 + +* Bug fix for link button text selection. + +## 3.6.2 + +* Improve link button. + +## 3.6.1 + +* Remove SnackBar 'What is entered is not a link'. + +## 3.6.0 -## 0.7.2 -* Fix a bug when opening the link dialog for both video and image buttons -* Update `README.md` +* Allow link button to enter text. -## 0.7.1 -* Update the minimum flutter version to `3.16.0` +## 3.5.3 -## 0.7.0 -* The `FlutterQuillLocalizations.delegate` is no longer a requirement. -* Requiring `flutter_quill` version `8.6.0` as minimum +* Change link button behavior. -## 0.6.11 -* Support for the latest version of `flutter_quill` +## 3.5.2 -## 0.6.10 -* Update deprecated members from `flutter_quill` -* Update doc and `README.md` +* Bug fix for embed. -## 0.6.9 -* Remove duplicated class -* Drop the support for `QuillEditorFormulaEmbedBuilder` for now as it's not usable, we are working on providing fixes -* Fix a bug with the zoom button +## 3.5.1 -## 0.6.8 -* Feature: Allow the developer to override the `assetsPrefix` and the default value is `assets`, you should define this correctly if you planning on using asset images in the `QuillEditor`, take a look at the `QuillSharedExtensionsConfigurations` class for more info +* Bug fix for platform util. -## 0.6.7 -* Support the new localization system of `flutter_quill` +## 3.5.0 -## 0.6.6 -* Add `onImageClicked` in the `QuillEditorImageEmbedConfigurations` -* Fix image resizing on mobile +* Removed redundant classes. -## 0.6.5 -* 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` +## 3.4.4 -## 0.6.4 -* Update `QuillImageUtilities` -* Add a new extension on `QuillController` to access `QuillImageUtilities` instance easier -* Support the new `iconButtonFactor` property +* Add more translations. -## 0.6.3 -* Update `README.md` +## 3.4.3 -## 0.6.2 -* Add more default exports +* Preset link from attributes. -## 0.6.1 -* Fix a bug on the web that causing the project to not build +## 3.4.2 -## 0.6.0 -* This version is not stable yet as it doesn't have migration guide and missing some things we might introduce more breaking changes very soon but we decided to publish it because the latest stable version is not compatible with the latest stable version of `flutter_quill` +* Fix launch link edit mode. -## 0.6.0-dev.6 -* Better support for web -* Smal fixes and updates +## 3.4.1 -## 0.6.0-dev.5 -* Update the camera button +* Placeholder effective in scrollable. -## 0.6.0-dev.4 -* Add more exports -* Update `README.md`` -* Fix save image bug -* Quick fixes +## 3.4.0 -## 0.6.0-dev.3 -* Disable the camera option by default on the desktop +* Option to save image in read-only mode. -## 0.6.0-dev.2 -* Another breaking change, we will add a migration guide soon. +## 3.3.1 -## 0.6.0-dev.1 -* Breaking Changes, we have refactored most of the functions and it got renamed +* Pass any specified key in QuillEditor constructor to super. -## 0.5.1 +## 3.3.0 -* Provide a way to use a custom image provider for the image widgets -* Provide a way to handle different errors in image widgets -* Two bug fixes related to picking the image and capturing 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 warning "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 improvements -* Allow to use the mobile context menu on the desktop by force using it -* Add the resizing option to the forced mobile context menu -* Add new custom style attribute for desktop and other platforms +* Fixed Style toggle issue. + +## 3.2.1 + +* Added new translations. + +## 3.2.0 + +* Support multiple links insertion on the go. + +## 3.1.1 + +* Add selection completed callback. + +## 3.1.0 + +* Fixed image ontap functionality. + +## 3.0.4 + +* Add maxContentWidth constraint to editor. + +## 3.0.3 + +* Do not show caret on screen when the editor is not focused. + +## 3.0.2 + +* Fix launch link for read-only mode. + +## 3.0.1 + +* Handle null value of Attribute.link. + +## 3.0.0 + +* Launch link improvements. +* Removed QuillSimpleViewer. + +## 2.5.2 + +* Skip image when pasting. + +## 2.5.1 + +* Bug fix for Desktop `Shift` + `Click` support. + +## 2.5.0 + +* Update checkbox list. + +## 2.4.1 + +* Desktop selection improvements. + +## 2.4.0 + +* Improve inline code style. + +## 2.3.3 + +* Improves selection rects to have consistent height regardless of individual segment text styles. + +## 2.3.2 + +* Allow disabling floating cursor. + +## 2.3.1 + +* Preserve last newline character on delete. + +## 2.3.0 + +* Massive changes to support flutter 2.8. + +## 2.2.2 + +* iOS - floating cursor. + +## 2.2.1 + +* Bug fix for imports supporting flutter 2.8. + +## 2.2.0 + +* Support flutter 2.8. + +## 2.1.1 + +* Add methods of clearing editor and moving cursor. + +## 2.1.0 + +* Add delete handler. + +## 2.0.23 + +* Support custom replaceText handler. + +## 2.0.22 + +* Fix attribute compare and fix font size parsing. + +## 2.0.21 + +* Handle click on embed object. + +## 2.0.20 + +* Improved UX/UI of Image widget. + +## 2.0.19 + +* When uploading a video, applying indicator. + +## 2.0.18 + +* Make toolbar dividers optional. + +## 2.0.17 + +* Allow alignment of the toolbar icons to match WrapAlignment. + +## 2.0.16 + +* Add hide / show alignment buttons. + +## 2.0.15 + +* Implement change cursor to SystemMouseCursors.click when hovering a link styled text. + +## 2.0.14 + +* Enable customize the checkbox widget using DefaultListBlockStyle style. + +## 2.0.13 + +* 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. + +## 2.0.11 + +* Fix visibility of text selection handlers on scroll. + +## 2.0.10 + +* cursorConnt.color notify the text_line to repaint if it was disposed. + +## 2.0.9 + +* Improve UX when trying to add a link. + +## 2.0.8 + +* Adding translations to the toolbar. + +## 2.0.7 + +* Added theming options for toolbar icons and LinkDialog. + +## 2.0.6 + +* Avoid runtime error when placed inside TabBarView. + +## 2.0.5 + +* Support inline code formatting. + +## 2.0.4 + +* Enable history shortcuts for desktop. + +## 2.0.3 + +* Fix cursor when line contains image. + +## 2.0.2 + +* Address KeyboardListener class name conflict. + +## 2.0.1 + +* Upgrade flutter_colorpicker to 0.5.0. + +## 2.0.0 + +* Text Alignment functions + Block Format standards. + +## 1.9.6 + +* Support putting QuillEditor inside a Scrollable view. + +## 1.9.5 + +* Skip image when pasting. + +## 1.9.4 + +* 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. + +## 1.9.2 + +* Support for building custom inline styles. + +## 1.9.1 + +* Cursor jumps to the most appropriate offset to display selection. + +## 1.9.0 + +* Support inline image. + +## 1.8.3 + +* Updated quill_delta. + +## 1.8.2 + +* Support mobile image alignment. + +## 1.8.1 + +* Support mobile custom size image. + +## 1.8.0 + +* Support entering link for image/video. + +## 1.7.3 + +* Bumps photo_view version. + +## 1.7.2 + +* Fix static analysis error. + +## 1.7.1 + +* Support Youtube video. + +## 1.7.0 + +* Support video. + +## 1.6.4 + +* Bug fix for clear format button. -## 0.5.0 +## 1.6.3 -* Migrated from `gallery_saver` to `gal` for saving images -* Added callbacks for greater control of editing images +* Fixed dragging right handle scrolling issue. -## 0.4.1 +## 1.6.2 -* Updated dependencies to support image_picker 1.0 +* Fixed the position of the selection status drag handle. -## 0.4.0 +## 1.6.1 -* 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) +* Upgrade image_picker and flutter_colorpicker. + +## 1.6.0 + +* Support Multi Row Toolbar. + +## 1.5.0 + +* Remove file_picker dependency. + +## 1.4.1 + +* Remove filesystem_picker dependency. + +## 1.4.0 + +* Remove path_provider dependency. + +## 1.3.4 + +* Add option to paintCursorAboveText. + +## 1.3.3 + +* Upgrade file_picker version. + +## 1.3.2 + +* Fix copy/paste bug. + +## 1.3.1 + +* New logo. + +## 1.3.0 + +* Support flutter 2.2.0. + +## 1.2.2 + +* Checkbox supports tapping. + +## 1.2.1 + +* Indented position not holding while editing. + +## 1.2.0 + +* Fix image button cancel causes crash. + +## 1.1.8 + +* Fix height of empty line bug. + +## 1.1.7 + +* Fix text selection in read-only mode. + +## 1.1.6 + +* Remove universal_html dependency. + +## 1.1.5 + +* Enable "Select", "Select All" and "Copy" in read-only mode. + +## 1.1.4 + +* Fix text selection issue. + +## 1.1.3 + +* Update example folder. + +## 1.1.2 + +* Add pedantic. + +## 1.1.1 + +* Base64 image support. + +## 1.1.0 + +* Support null safety. + +## 1.0.9 + +* Web support for raw editor and keyboard listener. + +## 1.0.8 + +* Support token attribute. + +## 1.0.7 + +* Fix crash on web (dart:io). + +## 1.0.6 + +* Add desktop support WINDOWS, MACOS and LINUX. + +## 1.0.5 + +* Bug fix: Can not insert newline when Bold is toggled ON. + +## 1.0.4 + +* Upgrade photo_view to ^0.11.0. + +## 1.0.3 + +* Fix issue that text is not displayed while typing WEB. + +## 1.0.2 + +* Update toolbar in sample home page. + +## 1.0.1 + +* Fix static analysis errors. + +## 1.0.0 + +* Support flutter 2.0. + +## 1.0.0-dev.2 + +* Improve link handling for tel, mailto and etc. + +## 1.0.0-dev.1 + +* Upgrade prerelease SDK & Bump for master. + +## 0.3.5 + +* Fix for cursor focus issues when keyboard is on. ## 0.3.4 -* Resolve the deprecated method used in the `video_player` package +* Improve link handling for tel, mailto and etc. ## 0.3.3 -* Fix a prototype bug that was brought by [PR #1230](https://github.com/singerdmx/flutter-quill/pull/1230#issuecomment*1560597099) +* More fix on cursor focus issue when keyboard is on. ## 0.3.2 -* Updated dependencies to support intl 0.18 +* Fix cursor focus issue when keyboard is on. ## 0.3.1 -* Image embedding tweaks - * Add MediaButton which is intended to supersede the ImageButton and VideoButton. Only image selection is working. - * Implement image insert for web (image as base64) +* cursor focus when keyboard is on. ## 0.3.0 -* Added support for adding custom tooltips to toolbar buttons +* Line Height calculated based on font size. + +## 0.2.12 + +* Support placeholder. + +## 0.2.11 + +* Fix static analysis error. + +## 0.2.10 + +* Update TextInputConfiguration autocorrect to true in stable branch. + +## 0.2.9 + +* Update TextInputConfiguration autocorrect to true. + +## 0.2.8 + +* Support display local image besides network image in stable branch. + +## 0.2.7 + +* Support display local image besides network image. + +## 0.2.6 + +* Fix cursor after pasting. + +## 0.2.5 + +* Toggle text/background color button in toolbar. + +## 0.2.4 + +* Support the use of custom icon size in toolbar. + +## 0.2.3 + +* Support custom styles and image on local device storage without uploading. + +## 0.2.2 + +* Update git repo. + +## 0.2.1 + +* Fix static analysis error. ## 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 formula button [5228f38](https://github.com/singerdmx/flutter-quill/commit/5228f389ba6f37d61d445cfe138c19fcf8766d71) +* Add checked/unchecked list button in toolbar. + +## 0.1.8 + +* Support font and size attributes. + +## 0.1.7 + +* Support checked/unchecked list. + +## 0.1.6 + +* Fix getExtentEndpointForSelection. + +## 0.1.5 + +* Support text alignment. + +## 0.1.4 + +* Handle url with trailing spaces. + +## 0.1.3 + +* Handle cursor position change when undo/redo. + +## 0.1.2 + +* Handle more text colors. + +## 0.1.1 + +* Fix cursor issue when undo. ## 0.1.0 -* Initial release +* Fix insert image. + +## 0.0.9 + +* Handle rgba color. + +## 0.0.8 + +* Fix launching url. + +## 0.0.7 + +* Handle multiple image inserts. + +## 0.0.6 + +* More toolbar functionality. + +## 0.0.5 + +* Update example. + +## 0.0.4 + +* Update example. + +## 0.0.3 + +* Update home page meta data. + +## 0.0.2 + +* Support image upload and launch url in read-only mode. + +## 0.0.1 + +* Rich text editor based on Quill Delta. diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 6ceffb04e..cd6579ac5 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: 9.0.0-dev +version: 9.0.0-dev-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/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ @@ -35,7 +35,7 @@ dependencies: universal_html: ^2.2.4 cross_file: ^0.3.3+6 - flutter_quill: ^8.6.0 + flutter_quill: ^9.0.0-dev photo_view: ^0.14.0 # Plugins diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 324c4355e..e0bbc6ec8 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -1,16 +1,1587 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## 9.0.0-dev-1 +* An attemp to fix CI automated publishing + +## 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. +* Flutter Quill Extensions; + * **Breaking Change**: Completly change the way how the source code structured to more basic and simple way, organize folders and file names, if you use the library +from `flutter_quill_extensions.dart` then there is nothing you need to do, but if you are using any other import then you need to re-imports +embed, this won't affect how quill js work + * Improvemenets to the image embed + * Add support for `margin` for web + * Add untranslated strings to the `quill_en.arb` + +## 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` + +## 8.6.3 +* Update the minimum flutter version to `3.16.0` + +## 8.6.2 +* Restore use of alternative QuillToolbarLinkStyleButton2 widget + +## 8.6.1 +* Temporary revert style bug fix + +## 8.6.0 +* **Breaking Change** Support [Flutter 3.16](https://medium.com/flutter/whats-new-in-flutter-3-16-dba6cb1015d1), please upgrade to the latest stable version of flutter to use this update +* **Breaking Change**: Remove Deprecated Fields +* **Breaking Change**: Extract the shared things between `QuillToolbarConfigurations` and `QuillBaseToolbarConfigurations` +* **Breaking Change**: You no longer need to use `QuillToolbarProvider` when using custom toolbar buttons, the example has been updated +* Bug fixes + +## 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 the `QuillToolbarSearchButton`, `QuillToolbarLinkStyleButton`, and `QuillToolbarColorButton` buttons + +## 8.5.4 +* The `mobileWidth`, `mobileHeight`, `mobileMargin`, and `mobileAlignment` is now deprecated in `flutter_quill`, they 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` + +## 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`. + +## 8.5.1 +* 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. + +## 8.4.4 +* Updated `.pubignore` to ignore unnecessary files and folders. + +## 8.4.3 +* 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. + +## 8.4.1 +* 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. + +## 8.3.0 +* 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. + +## 8.2.5 +* Added `builder` property in `QuillEditorConfigurations`. + +## 8.2.4 +* Adhered to Flutter best practices. +* Fixed auto-focus bug. + +## 8.2.3 +* Updated `README.md`. + +## 8.2.2 +* Moved `flutter_quill_test` to a separate package: [flutter_quill_test](https://pub.dev/packages/flutter_quill_test). + +## 8.2.1 +* Updated `README.md`. + +## 8.2.0 +* 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`. + +## 8.1.10 +* Secret for automated publishing to pub.dev. + +## 8.1.9 +* Fixed automated publishing to pub.dev. + +## 8.1.8 +* Fixed automated publishing to pub.dev. + +## 8.1.7 +* 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. + +## 8.1.5 +* Reversed background/font color toolbar button icons. + +## 8.1.4 +* Reversed background/font color toolbar button tooltips. + +## 8.1.3 +* 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`. + +## 8.1.1 +* 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`. + +## 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. + +## 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`. + +## 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`. + +## 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. + +## 7.9.0 +* Buttons Improvemenets +* Refactor all the button configurations that used in `QuillToolbar.basic()` but there are still few lefts +* **Breaking change**: Remove some configurations from the QuillToolbar and move them to the new `QuillProvider`, please notice this is a development version and this might be changed in the next few days, the stable release will be ready in less than 3 weeks +* Update `flutter_quill_extensions` and it will be published into pub.dev soon. +* Allow you to customize the search dialog by custom callback with child builder + +## 7.8.0 +* **Important note**: this is not test release yet, it works but need more test and changes and breaking changes, we don't have development version and it will help us if you try the latest version and report the issues in Github but if you want a stable version please use `7.4.16`. this refactoring process will not take long and should be done less than three weeks with the testing. +* We managed to refactor most of the buttons configurations and customizations in the `QuillProvider`, only three lefts then will start on refactoring the toolbar configurations +* Code improvemenets + +## 7.7.0 +* **Breaking change**: We have mirgrated more buttons in the toolbar configurations, you can do change them in the `QuillProvider` +* Important bug fixes + +## 7.6.1 +* Bug fixes + +## 7.6.0 +* **Breaking change**: To customize the buttons in the toolbar, you can do that in the `QuillProvider` + +## 7.5.0 +* **Breaking change**: The widgets `QuillEditor` and `QuillToolbar` are no longer have controller parameter, instead you need to make sure in the widget tree you have wrapped them with `QuillProvider` widget and provide the controller and the require configurations + +## 7.4.16 +* Update documentation and README.md + +## 7.4.15 +* Custom style attrbuites for platforms other than mobile (alignment, margin, width, height) +* Bug fixes and other improvemenets + +## 7.4.14 +* 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)` +* Add MediaButton for picking the images only since the video one is not ready +* A new feature which allows customizing the text selection in quill editor which is useful for custom theme design system for custom app widget + +## 7.4.13 +* Fixed tab editing when in readOnly mode. + +## 7.4.12 +* Update the minimum version of device_info_plus to 9.1.0. + +## 7.4.11 +* Add sw locale. + +## 7.4.10 +* Update translations. + +## 7.4.9 +* Style recognition fixes. + +## 7.4.8 +* Upgrade dependencies. + +## 7.4.7 +* Add Vietnamese and German translations. + +## 7.4.6 +* Fix more null errors in Leaf.retain [##1394](https://github.com/singerdmx/flutter-quill/issues/1394) and Line.delete [##1395](https://github.com/singerdmx/flutter-quill/issues/1395). + +## 7.4.5 +* Fix null error in Container.insert [##1392](https://github.com/singerdmx/flutter-quill/issues/1392). + +## 7.4.4 +* Fix extra padding on checklists [##1131](https://github.com/singerdmx/flutter-quill/issues/1131). + +## 7.4.3 +* Fixed a space input error on iPad. + +## 7.4.2 +* Fix bug with keepStyleOnNewLine for link. + +## 7.4.1 +* Fix toolbar dividers condition. + +## 7.4.0 +* Support Flutter version 3.13.0. + +## 7.3.3 +* Updated Dependencies conflicting. + +## 7.3.2 +* Added builder for custom button in _LinkDialog. + +## 7.3.1 +* Added case sensitive and whole word search parameters. +* Added wrap around. +* Moved search dialog to the bottom in order not to override the editor and the text found. +* Other minor search dialog enhancements. + +## 7.3.0 +* Add default attributes to basic factory. + +## 7.2.19 +* Feat/link regexp. + +## 7.2.18 +* Fix paste block text in words apply same style. + +## 7.2.17 +* Fix paste text mess up style. +* Add support copy/cut block text. + +## 7.2.16 +* Allow for custom context menu. + +## 7.2.15 +* Add flutter_quill.delta library which only exposes Delta datatype. + +## 7.2.14 +* Fix errors when the editor is used in the `screenshot` package. + +## 7.2.13 +* Fix around image can't delete line break. + +## 7.2.12 +* Add support for copy/cut select image and text together. + +## 7.2.11 +* Add affinity for localPosition. + +## 7.2.10 +* LINE._getPlainText queryChild inclusive=false. + +## 7.2.9 +* Add toPlainText method to `EmbedBuilder`. + +## 7.2.8 +* Add custom button widget in toolbar. + +## 7.2.7 +* Fix language code of Japan. + +## 7.2.6 +* Style custom toolbar buttons like builtins. + +## 7.2.5 +* Always use text cursor for editor on desktop. + +## 7.2.4 +* Fixed keepStyleOnNewLine. + +## 7.2.3 +* Get pixel ratio from view. + +## 7.2.2 +* Prevent operations on stale editor state. + +## 7.2.1 +* Add support for android keyboard content insertion. +* Enhance color picker, enter hex color and color palette option. + +## 7.2.0 +* Checkboxes, bullet points, and number points are now scaled based on the default paragraph font size. + +## 7.1.20 +* Pass linestyle to embedded block. + +## 7.1.19 +* Fix Rtl leading alignment problem. + +## 7.1.18 +* Support flutter latest version. + +## 7.1.17+1 +* Updates `device_info_plus` to version 9.0.0 to benefit from AGP 8 (see [changelog##900](https://pub.dev/packages/device_info_plus/changelog##900)). + +## 7.1.16 +* Fixed subscript key from 'sup' to 'sub'. + +## 7.1.15 +* Fixed a bug introduced in 7.1.7 where each section in `QuillToolbar` was displayed on its own line. + +## 7.1.14 +* Add indents change for multiline selection. + +## 7.1.13 + +* Add custom recognizer. + +## 7.1.12 + +* Add superscript and subscript styles. + +## 7.1.11 + +* 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) + +## 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) + +## 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. + +## 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. + +Now the package is more friendly for web projects. + +## 7.1.6 + +* Add enableUnfocusOnTapOutside field to RawEditor and Editor widgets. + +## 7.1.5 + +* Add tooltips for toolbar buttons. + +## 7.1.4 + +* Fix inserting tab character in lists. + +## 7.1.3 + +* Fix ios cursor bug when word.length==1. + +## 7.1.2 + +* Fix non scrollable editor exception, when tapped under content. + +## 7.1.1 + +* customLinkPrefixes parameter * makes possible to open links with custom protoco. + +## 7.1.0 + +* Fix ordered list numeration with several lists in document. + +## 7.0.9 + +* Use const constructor for EmbedBuilder. + +## 7.0.8 + +* Fix IME position bug with scroller. + +## 7.0.7 + +* Add TextFieldTapRegion for contextMenu. + +## 7.0.6 + +* 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. + +## 7.0.4 + +* 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. + +## 7.0.2 + +* Allow widgets to override widget span properties. + +## 7.0.1 + +* 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. + +## 6.4.4 + +* 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) + +## 6.4.2 + +* Replace `buildToolbar` with `contextMenuBuilder`. + +## 6.4.1 + +* 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`. + +## 6.3.5 + +* Ability to add custom shortcuts. + +## 6.3.4 + +* Update clipboard status prior to showing selected text overlay. + +## 6.3.3 + +* Fixed handling of mac intents. + +## 6.3.2 + +* Added `unknownEmbedBuilder` to QuillEditor. +* Fix error style when input chinese japanese or korean. + +## 6.3.1 + +* Add color property to the basic factory function. + +## 6.3.0 + +* Support Flutter 3.7. + +## 6.2.2 + +* Fix: nextLine getter null where no assertion. + +## 6.2.1 + +* Revert "Align numerical and bullet lists along with text content". + +## 6.2.0 + +* Align numerical and bullet lists along with text content. + +## 6.1.12 + +* Apply i18n for default font dropdown option labels corresponding to 'Clear'. + +## 6.1.11 + +* Remove iOS hack for delaying focus calculation. + +## 6.1.10 + +* Delay focus calculation for iOS. + +## 6.1.9 + +* Bump keyboard show up wait to 1 sec. + +## 6.1.8 + +* Recalculate focus when showing keyboard. + +## 6.1.7 + +* Add czech localizations. + +## 6.1.6 + +* Upgrade i18n_extension to 6.0.0. + +## 6.1.5 + +* Fix formatting exception. + +## 6.1.4 + +* Add double quotes validation. + +## 6.1.3 + +* Revert "fix order list numbering (##988)". + +## 6.1.2 + +* Add typing shortcuts. + +## 6.1.1 + +* Fix order list numbering. + +## 6.1.0 + +* Add keyboard shortcuts for editor actions. + +## 6.0.10 + +* 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. + +## 6.0.8+1 + +* Fixes null pointer when setting documents. + +## 6.0.8 + +* Make QuillController.document mutable. + +## 6.0.7 + +* Allow disabling of selection toolbar. + +## 6.0.6+1 + +* Revert 6.0.6. + +## 6.0.6 + +* Fix wrong custom embed key. + +## 6.0.5 + +* Fixes toolbar buttons stealing focus from editor. + +## 6.0.4 + +* Bug fix for Type 'Uint8List' not found. + +## 6.0.3 + +* Add ability to paste images. + +## 6.0.2 + +* 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. + +## 6.0.0 BREAKING CHANGE + +* 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: + +``` +import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; + +QuillEditor.basic( + controller: controller, + embedBuilders: FlutterQuillEmbeds.builders(), +); + +QuillToolbar.basic( + controller: controller, + embedButtons: FlutterQuillEmbeds.buttons(), +); +``` + +## 5.4.2 + +* Upgrade i18n_extension. + +## 5.4.1 + +* Update German Translation. + +## 5.4.0 + +* Added Formula Button (for maths support). + +## 5.3.2 + +* Add more font family. + +## 5.3.1 + +* Enable search when text is not empty. + +## 5.3.0 + +* Added search function. + +## 5.2.11 + +* Remove default small color. + +## 5.2.10 + +* 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. + +## 5.2.8 + +* Remove tooltip for LinkStyleButton. +* Make link match regex case insensitive. + +## 5.2.7 + +* Add locale to QuillEditor.basic. + +## 5.2.6 + +* Fix keyboard pops up when resizing the image. + +## 5.2.5 + +* Upgrade youtube_player_flutter_quill to 8.2.2. + +## 5.2.4 + +* 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'). + +## 5.2.2 + +* Fix Web Unsupported operation: Platform.\_operatingSystem error. + +## 5.2.1 + +* Rename QuillCustomIcon to QuillCustomButton. + +## 5.2.0 + +* Support font family selection. + +## 5.1.1 + +* Update README. + +## 5.1.0 + +* Added CustomBlockEmbed and customElementsEmbedBuilder. + +## 5.0.5 + +* Upgrade device_info_plus to 4.0.0. + +## 5.0.4 + +* Added onVideoInit callback for video documents. + +## 5.0.3 + +* Update dependencies. + +## 5.0.2 + +* Keep cursor position on checkbox tap. + +## 5.0.1 + +* Fix static analysis errors. + +## 5.0.0 + +* Flutter 3.0.0 support. + +## 4.2.3 + +* Ignore color:inherit and convert double to int for level. + +## 4.2.2 + +* Add clear option to font size dropdown. + +## 4.2.1 + +* Refactor font size dropdown. + +## 4.2.0 + +* Ensure selectionOverlay is available for showToolbar. + +## 4.1.9 + +* Using properly iconTheme colors. + +## 4.1.8 + +* Update font size dropdown. + +## 4.1.7 + +* Convert FontSize to a Map to allow for named Font Size. + +## 4.1.6 + +* Update quill_dropdown_button.dart. + +## 4.1.5 + +* Add Font Size dropdown to the toolbar. + +## 4.1.4 + +* New borderRadius for iconTheme. + +## 4.1.3 + +* 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. + +## 4.1.1 + +* Added textSelectionControls field in QuillEditor. + +## 4.1.0 + +* Added Node to linkActionPickerDelegate. + +## 4.0.12 + +* Add Persian(fa) language. + +## 4.0.11 + +* Fix cut selection error in multi-node line. + +## 4.0.10 + +* Fix vertical caret position bug. + +## 4.0.9 + +* Request keyboard focus when no child is found. + +## 4.0.8 + +* 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. + +## 4.0.6 + +* 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). + +## 4.0.4 + +* Bug fix for text direction rtl. + +## 4.0.3 + +* Support text direction rtl. + +## 4.0.2 + +* Clear toggled style on selection change. + +## 4.0.1 + +* Fix copy/cut/paste/selectAll not working. + +## 4.0.0 + +* Upgrade for Flutter 2.10. + +## 3.9.11 + +* Added Indonesian translation. + +## 3.9.10 + +* 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. + +## 3.9.8 + +* Added Urdu translation. + +## 3.9.7 + +* Fix for clicking on the Link button without any text on a new line crashes. + +## 3.9.6 + +* Apply locale to QuillEditor(contents). + +## 3.9.5 + +* Fix image pasting. + +## 3.9.4 + +* Hiding dialog after selecting action for image. + +## 3.9.3 + +* Update ImageResizer for Android. + +## 3.9.2 + +* Copy image with its style. + +## 3.9.1 + +* Support resizing image. + +## 3.9.0 + +* Image menu options for copy/remove. + +## 3.8.8 + +* Update set textEditingValue. + +## 3.8.7 + +* Fix checkbox not toggled correctly in toolbar button. + +## 3.8.6 + +* Fix cursor position changes when checking/unchecking the checkbox. + +## 3.8.5 + +* Fix \_handleDragUpdate in \_TextSelectionHandleOverlayState. + +## 3.8.4 + +* Fix link dialog layout. + +## 3.8.3 + +* 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. + +## 3.8.1 + +* Refactor \_QuillEditorState to QuillEditorState. + +## 3.8.0 + +* Support pasting with format. + +## 3.7.3 + +* Fix selection overlay for collapsed selection. + +## 3.7.2 + +* Reverted Embed toPlainText change. + +## 3.7.1 + +* Change Embed toPlainText to be empty string. + +## 3.7.0 + +* Replace Toolbar showHistory group with individual showRedo and showUndo. + +## 3.6.5 + +* Update Link dialogue for image/video. + +## 3.6.4 + +* Link dialogue TextInputType.multiline. + +## 3.6.3 + +* Bug fix for link button text selection. + +## 3.6.2 + +* Improve link button. + +## 3.6.1 + +* Remove SnackBar 'What is entered is not a link'. + +## 3.6.0 + +* Allow link button to enter text. + +## 3.5.3 + +* Change link button behavior. + +## 3.5.2 + +* Bug fix for embed. + +## 3.5.1 + +* Bug fix for platform util. + +## 3.5.0 + +* Removed redundant classes. + +## 3.4.4 + +* Add more translations. + +## 3.4.3 + +* Preset link from attributes. + +## 3.4.2 + +* Fix launch link edit mode. + +## 3.4.1 + +* Placeholder effective in scrollable. + +## 3.4.0 + +* Option to save image in read-only mode. + +## 3.3.1 + +* Pass any specified key in QuillEditor constructor to super. + +## 3.3.0 + +* Fixed Style toggle issue. + +## 3.2.1 + +* Added new translations. + +## 3.2.0 + +* Support multiple links insertion on the go. + +## 3.1.1 + +* Add selection completed callback. + +## 3.1.0 + +* Fixed image ontap functionality. + +## 3.0.4 + +* Add maxContentWidth constraint to editor. + +## 3.0.3 + +* Do not show caret on screen when the editor is not focused. + +## 3.0.2 + +* Fix launch link for read-only mode. + +## 3.0.1 + +* Handle null value of Attribute.link. + +## 3.0.0 + +* Launch link improvements. +* Removed QuillSimpleViewer. + +## 2.5.2 + +* Skip image when pasting. + +## 2.5.1 + +* Bug fix for Desktop `Shift` + `Click` support. + +## 2.5.0 + +* Update checkbox list. + +## 2.4.1 + +* Desktop selection improvements. + +## 2.4.0 + +* Improve inline code style. + +## 2.3.3 + +* Improves selection rects to have consistent height regardless of individual segment text styles. + +## 2.3.2 + +* Allow disabling floating cursor. + +## 2.3.1 + +* Preserve last newline character on delete. + +## 2.3.0 + +* Massive changes to support flutter 2.8. + +## 2.2.2 + +* iOS - floating cursor. + +## 2.2.1 + +* Bug fix for imports supporting flutter 2.8. + +## 2.2.0 + +* Support flutter 2.8. + +## 2.1.1 + +* Add methods of clearing editor and moving cursor. + +## 2.1.0 + +* Add delete handler. + +## 2.0.23 + +* Support custom replaceText handler. + +## 2.0.22 + +* Fix attribute compare and fix font size parsing. + +## 2.0.21 + +* Handle click on embed object. + +## 2.0.20 + +* Improved UX/UI of Image widget. + +## 2.0.19 + +* When uploading a video, applying indicator. + +## 2.0.18 + +* Make toolbar dividers optional. + +## 2.0.17 + +* Allow alignment of the toolbar icons to match WrapAlignment. + +## 2.0.16 + +* Add hide / show alignment buttons. + +## 2.0.15 + +* Implement change cursor to SystemMouseCursors.click when hovering a link styled text. + +## 2.0.14 + +* Enable customize the checkbox widget using DefaultListBlockStyle style. + +## 2.0.13 + +* 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. + +## 2.0.11 + +* Fix visibility of text selection handlers on scroll. + +## 2.0.10 + +* cursorConnt.color notify the text_line to repaint if it was disposed. + +## 2.0.9 + +* Improve UX when trying to add a link. + +## 2.0.8 + +* Adding translations to the toolbar. + +## 2.0.7 + +* Added theming options for toolbar icons and LinkDialog. + +## 2.0.6 + +* Avoid runtime error when placed inside TabBarView. + +## 2.0.5 + +* Support inline code formatting. + +## 2.0.4 + +* Enable history shortcuts for desktop. + +## 2.0.3 + +* Fix cursor when line contains image. + +## 2.0.2 + +* Address KeyboardListener class name conflict. + +## 2.0.1 + +* Upgrade flutter_colorpicker to 0.5.0. + +## 2.0.0 + +* Text Alignment functions + Block Format standards. + +## 1.9.6 + +* Support putting QuillEditor inside a Scrollable view. + +## 1.9.5 + +* Skip image when pasting. + +## 1.9.4 + +* 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. + +## 1.9.2 + +* Support for building custom inline styles. + +## 1.9.1 + +* Cursor jumps to the most appropriate offset to display selection. + +## 1.9.0 + +* Support inline image. + +## 1.8.3 + +* Updated quill_delta. + +## 1.8.2 + +* Support mobile image alignment. + +## 1.8.1 + +* Support mobile custom size image. + +## 1.8.0 + +* Support entering link for image/video. + +## 1.7.3 + +* Bumps photo_view version. + +## 1.7.2 + +* Fix static analysis error. + +## 1.7.1 + +* Support Youtube video. + +## 1.7.0 + +* Support video. + +## 1.6.4 + +* Bug fix for clear format button. + +## 1.6.3 + +* Fixed dragging right handle scrolling issue. + +## 1.6.2 + +* Fixed the position of the selection status drag handle. + +## 1.6.1 + +* Upgrade image_picker and flutter_colorpicker. + +## 1.6.0 + +* Support Multi Row Toolbar. + +## 1.5.0 + +* Remove file_picker dependency. + +## 1.4.1 + +* Remove filesystem_picker dependency. + +## 1.4.0 + +* Remove path_provider dependency. + +## 1.3.4 + +* Add option to paintCursorAboveText. + +## 1.3.3 + +* Upgrade file_picker version. + +## 1.3.2 + +* Fix copy/paste bug. + +## 1.3.1 + +* New logo. + +## 1.3.0 + +* Support flutter 2.2.0. + +## 1.2.2 + +* Checkbox supports tapping. + +## 1.2.1 + +* Indented position not holding while editing. + +## 1.2.0 + +* Fix image button cancel causes crash. + +## 1.1.8 + +* Fix height of empty line bug. + +## 1.1.7 + +* Fix text selection in read-only mode. + +## 1.1.6 + +* Remove universal_html dependency. + +## 1.1.5 + +* Enable "Select", "Select All" and "Copy" in read-only mode. + +## 1.1.4 + +* Fix text selection issue. + +## 1.1.3 + +* Update example folder. + +## 1.1.2 + +* Add pedantic. + +## 1.1.1 + +* Base64 image support. + +## 1.1.0 + +* Support null safety. + +## 1.0.9 + +* Web support for raw editor and keyboard listener. + +## 1.0.8 + +* Support token attribute. + +## 1.0.7 + +* Fix crash on web (dart:io). + +## 1.0.6 + +* Add desktop support WINDOWS, MACOS and LINUX. + +## 1.0.5 + +* Bug fix: Can not insert newline when Bold is toggled ON. + +## 1.0.4 + +* Upgrade photo_view to ^0.11.0. + +## 1.0.3 + +* Fix issue that text is not displayed while typing WEB. + +## 1.0.2 + +* Update toolbar in sample home page. + +## 1.0.1 + +* Fix static analysis errors. + +## 1.0.0 + +* Support flutter 2.0. + +## 1.0.0-dev.2 + +* Improve link handling for tel, mailto and etc. + +## 1.0.0-dev.1 + +* Upgrade prerelease SDK & Bump for master. + +## 0.3.5 + +* Fix for cursor focus issues when keyboard is on. + +## 0.3.4 + +* Improve link handling for tel, mailto and etc. + +## 0.3.3 + +* More fix on cursor focus issue when keyboard is on. + +## 0.3.2 + +* Fix cursor focus issue when keyboard is on. + +## 0.3.1 + +* cursor focus when keyboard is on. + +## 0.3.0 + +* Line Height calculated based on font size. + +## 0.2.12 + +* Support placeholder. + +## 0.2.11 + +* Fix static analysis error. + +## 0.2.10 + +* Update TextInputConfiguration autocorrect to true in stable branch. + +## 0.2.9 + +* Update TextInputConfiguration autocorrect to true. + +## 0.2.8 + +* Support display local image besides network image in stable branch. + +## 0.2.7 + +* Support display local image besides network image. + +## 0.2.6 + +* Fix cursor after pasting. + +## 0.2.5 + +* Toggle text/background color button in toolbar. + +## 0.2.4 + +* Support the use of custom icon size in toolbar. + +## 0.2.3 + +* Support custom styles and image on local device storage without uploading. + +## 0.2.2 + +* Update git repo. + +## 0.2.1 + +* Fix static analysis error. + +## 0.2.0 + +* Add checked/unchecked list button in toolbar. + +## 0.1.8 + +* Support font and size attributes. + +## 0.1.7 + +* Support checked/unchecked list. + +## 0.1.6 + +* Fix getExtentEndpointForSelection. + +## 0.1.5 + +* Support text alignment. + +## 0.1.4 + +* Handle url with trailing spaces. + +## 0.1.3 + +* Handle cursor position change when undo/redo. + +## 0.1.2 + +* Handle more text colors. + +## 0.1.1 + +* Fix cursor issue when undo. + +## 0.1.0 + +* Fix insert image. + +## 0.0.9 + +* Handle rgba color. + +## 0.0.8 + +* Fix launching url. + +## 0.0.7 + +* Handle multiple image inserts. + +## 0.0.6 + +* More toolbar functionality. + ## 0.0.5 -* Update `README.md` + +* Update example. ## 0.0.4 -* Update `README.md` -* Documentation comments. + +* Update example. ## 0.0.3 -* Update the `README.md` and description + +* Update home page meta data. ## 0.0.2 -* Add `.test_config` to mark the package as testing package + +* Support image upload and launch url in read-only mode. ## 0.0.1 -* initial release. +* Rich text editor based on Quill Delta. diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 192633864..3975c8e14 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: 9.0.0-dev +version: 9.0.0-dev-1 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ @@ -28,7 +28,7 @@ environment: dependencies: flutter: sdk: flutter - flutter_quill: ^8.2.5 + flutter_quill: ^9.0.0-dev flutter_test: sdk: flutter diff --git a/lib/src/models/config/quill_shared_configurations.dart b/lib/src/models/config/quill_shared_configurations.dart index 0ee34c1be..2f62ea69f 100644 --- a/lib/src/models/config/quill_shared_configurations.dart +++ b/lib/src/models/config/quill_shared_configurations.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart' show Color, Colors, Locale; import '../themes/quill_dialog_theme.dart'; import './editor/configurations.dart' show QuillEditorConfigurations; -import 'others/animations.dart'; import 'toolbar/toolbar_configurations.dart' show QuillToolbarConfigurations; export './others/animations.dart'; diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index 361570e01..b0995b742 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -8,7 +8,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; -import '../../extensions/quill_provider.dart'; import '../../l10n/widgets/localizations.dart'; import '../../models/config/editor/configurations.dart'; import '../../models/config/raw_editor/configurations.dart'; diff --git a/lib/src/widgets/toolbar/buttons/link_style.dart b/lib/src/widgets/toolbar/buttons/link_style.dart index e6d62e537..2bc54fead 100644 --- a/lib/src/widgets/toolbar/buttons/link_style.dart +++ b/lib/src/widgets/toolbar/buttons/link_style.dart @@ -10,7 +10,6 @@ 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 { diff --git a/lib/src/widgets/toolbar/buttons/link_style2.dart b/lib/src/widgets/toolbar/buttons/link_style2.dart index 26f092efc..df834f23b 100644 --- a/lib/src/widgets/toolbar/buttons/link_style2.dart +++ b/lib/src/widgets/toolbar/buttons/link_style2.dart @@ -12,7 +12,6 @@ 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'; /// Alternative version of [QuillToolbarLinkStyleButton]. This widget has more diff --git a/lib/src/widgets/toolbar/buttons/search/search.dart b/lib/src/widgets/toolbar/buttons/search/search.dart index 7def9fbab..91cb622bc 100644 --- a/lib/src/widgets/toolbar/buttons/search/search.dart +++ b/lib/src/widgets/toolbar/buttons/search/search.dart @@ -6,7 +6,6 @@ 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 { diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index f3ed5bc79..e0bbc6ec8 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -1,3 +1,1587 @@ -## 0.0.1-experimental.1 +# Changelog -* initial release. +All notable changes to this project will be documented in this file. + +## 9.0.0-dev-1 +* An attemp to fix CI automated publishing + +## 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. +* Flutter Quill Extensions; + * **Breaking Change**: Completly change the way how the source code structured to more basic and simple way, organize folders and file names, if you use the library +from `flutter_quill_extensions.dart` then there is nothing you need to do, but if you are using any other import then you need to re-imports +embed, this won't affect how quill js work + * Improvemenets to the image embed + * Add support for `margin` for web + * Add untranslated strings to the `quill_en.arb` + +## 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` + +## 8.6.3 +* Update the minimum flutter version to `3.16.0` + +## 8.6.2 +* Restore use of alternative QuillToolbarLinkStyleButton2 widget + +## 8.6.1 +* Temporary revert style bug fix + +## 8.6.0 +* **Breaking Change** Support [Flutter 3.16](https://medium.com/flutter/whats-new-in-flutter-3-16-dba6cb1015d1), please upgrade to the latest stable version of flutter to use this update +* **Breaking Change**: Remove Deprecated Fields +* **Breaking Change**: Extract the shared things between `QuillToolbarConfigurations` and `QuillBaseToolbarConfigurations` +* **Breaking Change**: You no longer need to use `QuillToolbarProvider` when using custom toolbar buttons, the example has been updated +* Bug fixes + +## 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 the `QuillToolbarSearchButton`, `QuillToolbarLinkStyleButton`, and `QuillToolbarColorButton` buttons + +## 8.5.4 +* The `mobileWidth`, `mobileHeight`, `mobileMargin`, and `mobileAlignment` is now deprecated in `flutter_quill`, they 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` + +## 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`. + +## 8.5.1 +* 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. + +## 8.4.4 +* Updated `.pubignore` to ignore unnecessary files and folders. + +## 8.4.3 +* 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. + +## 8.4.1 +* 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. + +## 8.3.0 +* 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. + +## 8.2.5 +* Added `builder` property in `QuillEditorConfigurations`. + +## 8.2.4 +* Adhered to Flutter best practices. +* Fixed auto-focus bug. + +## 8.2.3 +* Updated `README.md`. + +## 8.2.2 +* Moved `flutter_quill_test` to a separate package: [flutter_quill_test](https://pub.dev/packages/flutter_quill_test). + +## 8.2.1 +* Updated `README.md`. + +## 8.2.0 +* 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`. + +## 8.1.10 +* Secret for automated publishing to pub.dev. + +## 8.1.9 +* Fixed automated publishing to pub.dev. + +## 8.1.8 +* Fixed automated publishing to pub.dev. + +## 8.1.7 +* 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. + +## 8.1.5 +* Reversed background/font color toolbar button icons. + +## 8.1.4 +* Reversed background/font color toolbar button tooltips. + +## 8.1.3 +* 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`. + +## 8.1.1 +* 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`. + +## 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. + +## 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`. + +## 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`. + +## 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. + +## 7.9.0 +* Buttons Improvemenets +* Refactor all the button configurations that used in `QuillToolbar.basic()` but there are still few lefts +* **Breaking change**: Remove some configurations from the QuillToolbar and move them to the new `QuillProvider`, please notice this is a development version and this might be changed in the next few days, the stable release will be ready in less than 3 weeks +* Update `flutter_quill_extensions` and it will be published into pub.dev soon. +* Allow you to customize the search dialog by custom callback with child builder + +## 7.8.0 +* **Important note**: this is not test release yet, it works but need more test and changes and breaking changes, we don't have development version and it will help us if you try the latest version and report the issues in Github but if you want a stable version please use `7.4.16`. this refactoring process will not take long and should be done less than three weeks with the testing. +* We managed to refactor most of the buttons configurations and customizations in the `QuillProvider`, only three lefts then will start on refactoring the toolbar configurations +* Code improvemenets + +## 7.7.0 +* **Breaking change**: We have mirgrated more buttons in the toolbar configurations, you can do change them in the `QuillProvider` +* Important bug fixes + +## 7.6.1 +* Bug fixes + +## 7.6.0 +* **Breaking change**: To customize the buttons in the toolbar, you can do that in the `QuillProvider` + +## 7.5.0 +* **Breaking change**: The widgets `QuillEditor` and `QuillToolbar` are no longer have controller parameter, instead you need to make sure in the widget tree you have wrapped them with `QuillProvider` widget and provide the controller and the require configurations + +## 7.4.16 +* Update documentation and README.md + +## 7.4.15 +* Custom style attrbuites for platforms other than mobile (alignment, margin, width, height) +* Bug fixes and other improvemenets + +## 7.4.14 +* 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)` +* Add MediaButton for picking the images only since the video one is not ready +* A new feature which allows customizing the text selection in quill editor which is useful for custom theme design system for custom app widget + +## 7.4.13 +* Fixed tab editing when in readOnly mode. + +## 7.4.12 +* Update the minimum version of device_info_plus to 9.1.0. + +## 7.4.11 +* Add sw locale. + +## 7.4.10 +* Update translations. + +## 7.4.9 +* Style recognition fixes. + +## 7.4.8 +* Upgrade dependencies. + +## 7.4.7 +* Add Vietnamese and German translations. + +## 7.4.6 +* Fix more null errors in Leaf.retain [##1394](https://github.com/singerdmx/flutter-quill/issues/1394) and Line.delete [##1395](https://github.com/singerdmx/flutter-quill/issues/1395). + +## 7.4.5 +* Fix null error in Container.insert [##1392](https://github.com/singerdmx/flutter-quill/issues/1392). + +## 7.4.4 +* Fix extra padding on checklists [##1131](https://github.com/singerdmx/flutter-quill/issues/1131). + +## 7.4.3 +* Fixed a space input error on iPad. + +## 7.4.2 +* Fix bug with keepStyleOnNewLine for link. + +## 7.4.1 +* Fix toolbar dividers condition. + +## 7.4.0 +* Support Flutter version 3.13.0. + +## 7.3.3 +* Updated Dependencies conflicting. + +## 7.3.2 +* Added builder for custom button in _LinkDialog. + +## 7.3.1 +* Added case sensitive and whole word search parameters. +* Added wrap around. +* Moved search dialog to the bottom in order not to override the editor and the text found. +* Other minor search dialog enhancements. + +## 7.3.0 +* Add default attributes to basic factory. + +## 7.2.19 +* Feat/link regexp. + +## 7.2.18 +* Fix paste block text in words apply same style. + +## 7.2.17 +* Fix paste text mess up style. +* Add support copy/cut block text. + +## 7.2.16 +* Allow for custom context menu. + +## 7.2.15 +* Add flutter_quill.delta library which only exposes Delta datatype. + +## 7.2.14 +* Fix errors when the editor is used in the `screenshot` package. + +## 7.2.13 +* Fix around image can't delete line break. + +## 7.2.12 +* Add support for copy/cut select image and text together. + +## 7.2.11 +* Add affinity for localPosition. + +## 7.2.10 +* LINE._getPlainText queryChild inclusive=false. + +## 7.2.9 +* Add toPlainText method to `EmbedBuilder`. + +## 7.2.8 +* Add custom button widget in toolbar. + +## 7.2.7 +* Fix language code of Japan. + +## 7.2.6 +* Style custom toolbar buttons like builtins. + +## 7.2.5 +* Always use text cursor for editor on desktop. + +## 7.2.4 +* Fixed keepStyleOnNewLine. + +## 7.2.3 +* Get pixel ratio from view. + +## 7.2.2 +* Prevent operations on stale editor state. + +## 7.2.1 +* Add support for android keyboard content insertion. +* Enhance color picker, enter hex color and color palette option. + +## 7.2.0 +* Checkboxes, bullet points, and number points are now scaled based on the default paragraph font size. + +## 7.1.20 +* Pass linestyle to embedded block. + +## 7.1.19 +* Fix Rtl leading alignment problem. + +## 7.1.18 +* Support flutter latest version. + +## 7.1.17+1 +* Updates `device_info_plus` to version 9.0.0 to benefit from AGP 8 (see [changelog##900](https://pub.dev/packages/device_info_plus/changelog##900)). + +## 7.1.16 +* Fixed subscript key from 'sup' to 'sub'. + +## 7.1.15 +* Fixed a bug introduced in 7.1.7 where each section in `QuillToolbar` was displayed on its own line. + +## 7.1.14 +* Add indents change for multiline selection. + +## 7.1.13 + +* Add custom recognizer. + +## 7.1.12 + +* Add superscript and subscript styles. + +## 7.1.11 + +* 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) + +## 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) + +## 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. + +## 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. + +Now the package is more friendly for web projects. + +## 7.1.6 + +* Add enableUnfocusOnTapOutside field to RawEditor and Editor widgets. + +## 7.1.5 + +* Add tooltips for toolbar buttons. + +## 7.1.4 + +* Fix inserting tab character in lists. + +## 7.1.3 + +* Fix ios cursor bug when word.length==1. + +## 7.1.2 + +* Fix non scrollable editor exception, when tapped under content. + +## 7.1.1 + +* customLinkPrefixes parameter * makes possible to open links with custom protoco. + +## 7.1.0 + +* Fix ordered list numeration with several lists in document. + +## 7.0.9 + +* Use const constructor for EmbedBuilder. + +## 7.0.8 + +* Fix IME position bug with scroller. + +## 7.0.7 + +* Add TextFieldTapRegion for contextMenu. + +## 7.0.6 + +* 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. + +## 7.0.4 + +* 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. + +## 7.0.2 + +* Allow widgets to override widget span properties. + +## 7.0.1 + +* 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. + +## 6.4.4 + +* 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) + +## 6.4.2 + +* Replace `buildToolbar` with `contextMenuBuilder`. + +## 6.4.1 + +* 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`. + +## 6.3.5 + +* Ability to add custom shortcuts. + +## 6.3.4 + +* Update clipboard status prior to showing selected text overlay. + +## 6.3.3 + +* Fixed handling of mac intents. + +## 6.3.2 + +* Added `unknownEmbedBuilder` to QuillEditor. +* Fix error style when input chinese japanese or korean. + +## 6.3.1 + +* Add color property to the basic factory function. + +## 6.3.0 + +* Support Flutter 3.7. + +## 6.2.2 + +* Fix: nextLine getter null where no assertion. + +## 6.2.1 + +* Revert "Align numerical and bullet lists along with text content". + +## 6.2.0 + +* Align numerical and bullet lists along with text content. + +## 6.1.12 + +* Apply i18n for default font dropdown option labels corresponding to 'Clear'. + +## 6.1.11 + +* Remove iOS hack for delaying focus calculation. + +## 6.1.10 + +* Delay focus calculation for iOS. + +## 6.1.9 + +* Bump keyboard show up wait to 1 sec. + +## 6.1.8 + +* Recalculate focus when showing keyboard. + +## 6.1.7 + +* Add czech localizations. + +## 6.1.6 + +* Upgrade i18n_extension to 6.0.0. + +## 6.1.5 + +* Fix formatting exception. + +## 6.1.4 + +* Add double quotes validation. + +## 6.1.3 + +* Revert "fix order list numbering (##988)". + +## 6.1.2 + +* Add typing shortcuts. + +## 6.1.1 + +* Fix order list numbering. + +## 6.1.0 + +* Add keyboard shortcuts for editor actions. + +## 6.0.10 + +* 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. + +## 6.0.8+1 + +* Fixes null pointer when setting documents. + +## 6.0.8 + +* Make QuillController.document mutable. + +## 6.0.7 + +* Allow disabling of selection toolbar. + +## 6.0.6+1 + +* Revert 6.0.6. + +## 6.0.6 + +* Fix wrong custom embed key. + +## 6.0.5 + +* Fixes toolbar buttons stealing focus from editor. + +## 6.0.4 + +* Bug fix for Type 'Uint8List' not found. + +## 6.0.3 + +* Add ability to paste images. + +## 6.0.2 + +* 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. + +## 6.0.0 BREAKING CHANGE + +* 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: + +``` +import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; + +QuillEditor.basic( + controller: controller, + embedBuilders: FlutterQuillEmbeds.builders(), +); + +QuillToolbar.basic( + controller: controller, + embedButtons: FlutterQuillEmbeds.buttons(), +); +``` + +## 5.4.2 + +* Upgrade i18n_extension. + +## 5.4.1 + +* Update German Translation. + +## 5.4.0 + +* Added Formula Button (for maths support). + +## 5.3.2 + +* Add more font family. + +## 5.3.1 + +* Enable search when text is not empty. + +## 5.3.0 + +* Added search function. + +## 5.2.11 + +* Remove default small color. + +## 5.2.10 + +* 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. + +## 5.2.8 + +* Remove tooltip for LinkStyleButton. +* Make link match regex case insensitive. + +## 5.2.7 + +* Add locale to QuillEditor.basic. + +## 5.2.6 + +* Fix keyboard pops up when resizing the image. + +## 5.2.5 + +* Upgrade youtube_player_flutter_quill to 8.2.2. + +## 5.2.4 + +* 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'). + +## 5.2.2 + +* Fix Web Unsupported operation: Platform.\_operatingSystem error. + +## 5.2.1 + +* Rename QuillCustomIcon to QuillCustomButton. + +## 5.2.0 + +* Support font family selection. + +## 5.1.1 + +* Update README. + +## 5.1.0 + +* Added CustomBlockEmbed and customElementsEmbedBuilder. + +## 5.0.5 + +* Upgrade device_info_plus to 4.0.0. + +## 5.0.4 + +* Added onVideoInit callback for video documents. + +## 5.0.3 + +* Update dependencies. + +## 5.0.2 + +* Keep cursor position on checkbox tap. + +## 5.0.1 + +* Fix static analysis errors. + +## 5.0.0 + +* Flutter 3.0.0 support. + +## 4.2.3 + +* Ignore color:inherit and convert double to int for level. + +## 4.2.2 + +* Add clear option to font size dropdown. + +## 4.2.1 + +* Refactor font size dropdown. + +## 4.2.0 + +* Ensure selectionOverlay is available for showToolbar. + +## 4.1.9 + +* Using properly iconTheme colors. + +## 4.1.8 + +* Update font size dropdown. + +## 4.1.7 + +* Convert FontSize to a Map to allow for named Font Size. + +## 4.1.6 + +* Update quill_dropdown_button.dart. + +## 4.1.5 + +* Add Font Size dropdown to the toolbar. + +## 4.1.4 + +* New borderRadius for iconTheme. + +## 4.1.3 + +* 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. + +## 4.1.1 + +* Added textSelectionControls field in QuillEditor. + +## 4.1.0 + +* Added Node to linkActionPickerDelegate. + +## 4.0.12 + +* Add Persian(fa) language. + +## 4.0.11 + +* Fix cut selection error in multi-node line. + +## 4.0.10 + +* Fix vertical caret position bug. + +## 4.0.9 + +* Request keyboard focus when no child is found. + +## 4.0.8 + +* 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. + +## 4.0.6 + +* 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). + +## 4.0.4 + +* Bug fix for text direction rtl. + +## 4.0.3 + +* Support text direction rtl. + +## 4.0.2 + +* Clear toggled style on selection change. + +## 4.0.1 + +* Fix copy/cut/paste/selectAll not working. + +## 4.0.0 + +* Upgrade for Flutter 2.10. + +## 3.9.11 + +* Added Indonesian translation. + +## 3.9.10 + +* 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. + +## 3.9.8 + +* Added Urdu translation. + +## 3.9.7 + +* Fix for clicking on the Link button without any text on a new line crashes. + +## 3.9.6 + +* Apply locale to QuillEditor(contents). + +## 3.9.5 + +* Fix image pasting. + +## 3.9.4 + +* Hiding dialog after selecting action for image. + +## 3.9.3 + +* Update ImageResizer for Android. + +## 3.9.2 + +* Copy image with its style. + +## 3.9.1 + +* Support resizing image. + +## 3.9.0 + +* Image menu options for copy/remove. + +## 3.8.8 + +* Update set textEditingValue. + +## 3.8.7 + +* Fix checkbox not toggled correctly in toolbar button. + +## 3.8.6 + +* Fix cursor position changes when checking/unchecking the checkbox. + +## 3.8.5 + +* Fix \_handleDragUpdate in \_TextSelectionHandleOverlayState. + +## 3.8.4 + +* Fix link dialog layout. + +## 3.8.3 + +* 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. + +## 3.8.1 + +* Refactor \_QuillEditorState to QuillEditorState. + +## 3.8.0 + +* Support pasting with format. + +## 3.7.3 + +* Fix selection overlay for collapsed selection. + +## 3.7.2 + +* Reverted Embed toPlainText change. + +## 3.7.1 + +* Change Embed toPlainText to be empty string. + +## 3.7.0 + +* Replace Toolbar showHistory group with individual showRedo and showUndo. + +## 3.6.5 + +* Update Link dialogue for image/video. + +## 3.6.4 + +* Link dialogue TextInputType.multiline. + +## 3.6.3 + +* Bug fix for link button text selection. + +## 3.6.2 + +* Improve link button. + +## 3.6.1 + +* Remove SnackBar 'What is entered is not a link'. + +## 3.6.0 + +* Allow link button to enter text. + +## 3.5.3 + +* Change link button behavior. + +## 3.5.2 + +* Bug fix for embed. + +## 3.5.1 + +* Bug fix for platform util. + +## 3.5.0 + +* Removed redundant classes. + +## 3.4.4 + +* Add more translations. + +## 3.4.3 + +* Preset link from attributes. + +## 3.4.2 + +* Fix launch link edit mode. + +## 3.4.1 + +* Placeholder effective in scrollable. + +## 3.4.0 + +* Option to save image in read-only mode. + +## 3.3.1 + +* Pass any specified key in QuillEditor constructor to super. + +## 3.3.0 + +* Fixed Style toggle issue. + +## 3.2.1 + +* Added new translations. + +## 3.2.0 + +* Support multiple links insertion on the go. + +## 3.1.1 + +* Add selection completed callback. + +## 3.1.0 + +* Fixed image ontap functionality. + +## 3.0.4 + +* Add maxContentWidth constraint to editor. + +## 3.0.3 + +* Do not show caret on screen when the editor is not focused. + +## 3.0.2 + +* Fix launch link for read-only mode. + +## 3.0.1 + +* Handle null value of Attribute.link. + +## 3.0.0 + +* Launch link improvements. +* Removed QuillSimpleViewer. + +## 2.5.2 + +* Skip image when pasting. + +## 2.5.1 + +* Bug fix for Desktop `Shift` + `Click` support. + +## 2.5.0 + +* Update checkbox list. + +## 2.4.1 + +* Desktop selection improvements. + +## 2.4.0 + +* Improve inline code style. + +## 2.3.3 + +* Improves selection rects to have consistent height regardless of individual segment text styles. + +## 2.3.2 + +* Allow disabling floating cursor. + +## 2.3.1 + +* Preserve last newline character on delete. + +## 2.3.0 + +* Massive changes to support flutter 2.8. + +## 2.2.2 + +* iOS - floating cursor. + +## 2.2.1 + +* Bug fix for imports supporting flutter 2.8. + +## 2.2.0 + +* Support flutter 2.8. + +## 2.1.1 + +* Add methods of clearing editor and moving cursor. + +## 2.1.0 + +* Add delete handler. + +## 2.0.23 + +* Support custom replaceText handler. + +## 2.0.22 + +* Fix attribute compare and fix font size parsing. + +## 2.0.21 + +* Handle click on embed object. + +## 2.0.20 + +* Improved UX/UI of Image widget. + +## 2.0.19 + +* When uploading a video, applying indicator. + +## 2.0.18 + +* Make toolbar dividers optional. + +## 2.0.17 + +* Allow alignment of the toolbar icons to match WrapAlignment. + +## 2.0.16 + +* Add hide / show alignment buttons. + +## 2.0.15 + +* Implement change cursor to SystemMouseCursors.click when hovering a link styled text. + +## 2.0.14 + +* Enable customize the checkbox widget using DefaultListBlockStyle style. + +## 2.0.13 + +* 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. + +## 2.0.11 + +* Fix visibility of text selection handlers on scroll. + +## 2.0.10 + +* cursorConnt.color notify the text_line to repaint if it was disposed. + +## 2.0.9 + +* Improve UX when trying to add a link. + +## 2.0.8 + +* Adding translations to the toolbar. + +## 2.0.7 + +* Added theming options for toolbar icons and LinkDialog. + +## 2.0.6 + +* Avoid runtime error when placed inside TabBarView. + +## 2.0.5 + +* Support inline code formatting. + +## 2.0.4 + +* Enable history shortcuts for desktop. + +## 2.0.3 + +* Fix cursor when line contains image. + +## 2.0.2 + +* Address KeyboardListener class name conflict. + +## 2.0.1 + +* Upgrade flutter_colorpicker to 0.5.0. + +## 2.0.0 + +* Text Alignment functions + Block Format standards. + +## 1.9.6 + +* Support putting QuillEditor inside a Scrollable view. + +## 1.9.5 + +* Skip image when pasting. + +## 1.9.4 + +* 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. + +## 1.9.2 + +* Support for building custom inline styles. + +## 1.9.1 + +* Cursor jumps to the most appropriate offset to display selection. + +## 1.9.0 + +* Support inline image. + +## 1.8.3 + +* Updated quill_delta. + +## 1.8.2 + +* Support mobile image alignment. + +## 1.8.1 + +* Support mobile custom size image. + +## 1.8.0 + +* Support entering link for image/video. + +## 1.7.3 + +* Bumps photo_view version. + +## 1.7.2 + +* Fix static analysis error. + +## 1.7.1 + +* Support Youtube video. + +## 1.7.0 + +* Support video. + +## 1.6.4 + +* Bug fix for clear format button. + +## 1.6.3 + +* Fixed dragging right handle scrolling issue. + +## 1.6.2 + +* Fixed the position of the selection status drag handle. + +## 1.6.1 + +* Upgrade image_picker and flutter_colorpicker. + +## 1.6.0 + +* Support Multi Row Toolbar. + +## 1.5.0 + +* Remove file_picker dependency. + +## 1.4.1 + +* Remove filesystem_picker dependency. + +## 1.4.0 + +* Remove path_provider dependency. + +## 1.3.4 + +* Add option to paintCursorAboveText. + +## 1.3.3 + +* Upgrade file_picker version. + +## 1.3.2 + +* Fix copy/paste bug. + +## 1.3.1 + +* New logo. + +## 1.3.0 + +* Support flutter 2.2.0. + +## 1.2.2 + +* Checkbox supports tapping. + +## 1.2.1 + +* Indented position not holding while editing. + +## 1.2.0 + +* Fix image button cancel causes crash. + +## 1.1.8 + +* Fix height of empty line bug. + +## 1.1.7 + +* Fix text selection in read-only mode. + +## 1.1.6 + +* Remove universal_html dependency. + +## 1.1.5 + +* Enable "Select", "Select All" and "Copy" in read-only mode. + +## 1.1.4 + +* Fix text selection issue. + +## 1.1.3 + +* Update example folder. + +## 1.1.2 + +* Add pedantic. + +## 1.1.1 + +* Base64 image support. + +## 1.1.0 + +* Support null safety. + +## 1.0.9 + +* Web support for raw editor and keyboard listener. + +## 1.0.8 + +* Support token attribute. + +## 1.0.7 + +* Fix crash on web (dart:io). + +## 1.0.6 + +* Add desktop support WINDOWS, MACOS and LINUX. + +## 1.0.5 + +* Bug fix: Can not insert newline when Bold is toggled ON. + +## 1.0.4 + +* Upgrade photo_view to ^0.11.0. + +## 1.0.3 + +* Fix issue that text is not displayed while typing WEB. + +## 1.0.2 + +* Update toolbar in sample home page. + +## 1.0.1 + +* Fix static analysis errors. + +## 1.0.0 + +* Support flutter 2.0. + +## 1.0.0-dev.2 + +* Improve link handling for tel, mailto and etc. + +## 1.0.0-dev.1 + +* Upgrade prerelease SDK & Bump for master. + +## 0.3.5 + +* Fix for cursor focus issues when keyboard is on. + +## 0.3.4 + +* Improve link handling for tel, mailto and etc. + +## 0.3.3 + +* More fix on cursor focus issue when keyboard is on. + +## 0.3.2 + +* Fix cursor focus issue when keyboard is on. + +## 0.3.1 + +* cursor focus when keyboard is on. + +## 0.3.0 + +* Line Height calculated based on font size. + +## 0.2.12 + +* Support placeholder. + +## 0.2.11 + +* Fix static analysis error. + +## 0.2.10 + +* Update TextInputConfiguration autocorrect to true in stable branch. + +## 0.2.9 + +* Update TextInputConfiguration autocorrect to true. + +## 0.2.8 + +* Support display local image besides network image in stable branch. + +## 0.2.7 + +* Support display local image besides network image. + +## 0.2.6 + +* Fix cursor after pasting. + +## 0.2.5 + +* Toggle text/background color button in toolbar. + +## 0.2.4 + +* Support the use of custom icon size in toolbar. + +## 0.2.3 + +* Support custom styles and image on local device storage without uploading. + +## 0.2.2 + +* Update git repo. + +## 0.2.1 + +* Fix static analysis error. + +## 0.2.0 + +* Add checked/unchecked list button in toolbar. + +## 0.1.8 + +* Support font and size attributes. + +## 0.1.7 + +* Support checked/unchecked list. + +## 0.1.6 + +* Fix getExtentEndpointForSelection. + +## 0.1.5 + +* Support text alignment. + +## 0.1.4 + +* Handle url with trailing spaces. + +## 0.1.3 + +* Handle cursor position change when undo/redo. + +## 0.1.2 + +* Handle more text colors. + +## 0.1.1 + +* Fix cursor issue when undo. + +## 0.1.0 + +* Fix insert image. + +## 0.0.9 + +* Handle rgba color. + +## 0.0.8 + +* Fix launching url. + +## 0.0.7 + +* Handle multiple image inserts. + +## 0.0.6 + +* More toolbar functionality. + +## 0.0.5 + +* Update example. + +## 0.0.4 + +* Update example. + +## 0.0.3 + +* Update home page meta data. + +## 0.0.2 + +* Support image upload and launch url in read-only mode. + +## 0.0.1 + +* Rich text editor based on Quill Delta. diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index f2e41adac..d51d874e6 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 0.0.1-experimental.1 +version: 9.0.0-dev-1 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ @@ -20,7 +20,7 @@ environment: dependencies: flutter: sdk: flutter - flutter_quill: ^8.5.1 + flutter_quill: ^9.0.0-dev vsc_quill_delta_to_html: ^1.0.3 html2md: ^1.3.1 # markdown: ^7.1.1 diff --git a/pubspec.yaml b/pubspec.yaml index 2351f76fd..142689768 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: 9.0.0-dev +version: 9.0.0-dev-1 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/scripts/regenerate_versions.dart b/scripts/regenerate_versions.dart index b233c54b8..588e3fcb4 100644 --- a/scripts/regenerate_versions.dart +++ b/scripts/regenerate_versions.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + import 'dart:io' show File; import 'package:yaml_edit/yaml_edit.dart'; @@ -8,10 +10,18 @@ import 'package:yaml_edit/yaml_edit.dart'; import '../version.dart'; Future main(List args) async { - await updatePubspecYamlFile('./pubspec.yaml'); - await updatePubspecYamlFile('./flutter_quill_extensions/pubspec.yaml'); - await updatePubspecYamlFile('./flutter_quill_test/pubspec.yaml'); - await updatePubspecYamlFile('./packages/quill_html_converter/pubspec.yaml'); + final packages = [ + './', + './flutter_quill_extensions', + './flutter_quill_test', + './packages/quill_html_converter' + ]; + for (final element in packages) { + await updatePubspecYamlFile('$element/pubspec.yaml'); + if (element != packages.first) { + updateChangelogMD(element); + } + } } Future updatePubspecYamlFile(String path) async { @@ -19,6 +29,11 @@ Future updatePubspecYamlFile(String path) async { final yaml = await file.readAsString(); final yamlEditor = YamlEditor(yaml)..update(['version'], version); await file.writeAsString(yamlEditor.toString()); - // ignore: avoid_print print(yamlEditor.toString()); } + +Future updateChangelogMD(String path) async { + final changeLog = await File('./CHANGELOG.md').readAsString(); + final currentFile = File('$path/CHANGELOG.md'); + await currentFile.writeAsString(changeLog); +} diff --git a/version.dart b/version.dart index 207b9df35..8bd3e0a0d 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev'; +const version = '9.0.0-dev-1'; From 086dcb7ea9e4cee9f14eb91b3d79b0fb29ac9fb1 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 09:19:10 +0300 Subject: [PATCH 11/86] 2++++++++ --- .pubignore | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.pubignore b/.pubignore index ffddfe1a6..15f51beec 100644 --- a/.pubignore +++ b/.pubignore @@ -10,7 +10,4 @@ example/.fvm/ example/build/ example/.dart_tool/ -scripts/ - \ No newline at end of file +scripts/ \ No newline at end of file From 4a6bc16b3f661d0958e005dfb42173e9bfc6ca5a Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 09:19:32 +0300 Subject: [PATCH 12/86] Update the version --- version.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.dart b/version.dart index 8bd3e0a0d..24c648ada 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev-1'; +const version = '9.0.0-dev-2'; From 6fa840bc45f9dba19e12d5f3456732c327e98734 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 09:20:20 +0300 Subject: [PATCH 13/86] 2+++++++++ --- CHANGELOG.md | 3 +++ flutter_quill_extensions/CHANGELOG.md | 3 +++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 3 +++ flutter_quill_test/pubspec.yaml | 2 +- packages/quill_html_converter/CHANGELOG.md | 3 +++ packages/quill_html_converter/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 8 files changed, 16 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0bbc6ec8..60b64f0f5 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-2 +* An attemp to fix CI automated publishing + ## 9.0.0-dev-1 * An attemp to fix CI automated publishing diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index e0bbc6ec8..60b64f0f5 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-2 +* An attemp to fix CI automated publishing + ## 9.0.0-dev-1 * An attemp to fix CI automated publishing diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index cd6579ac5..7453fe16d 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: 9.0.0-dev-1 +version: 9.0.0-dev-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/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index e0bbc6ec8..60b64f0f5 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-2 +* An attemp to fix CI automated publishing + ## 9.0.0-dev-1 * An attemp to fix CI automated publishing diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 3975c8e14..0fba29051 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: 9.0.0-dev-1 +version: 9.0.0-dev-2 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index e0bbc6ec8..60b64f0f5 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-2 +* An attemp to fix CI automated publishing + ## 9.0.0-dev-1 * An attemp to fix CI automated publishing diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index d51d874e6..60988ef20 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.0.0-dev-1 +version: 9.0.0-dev-2 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 142689768..6b3b23600 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: 9.0.0-dev-1 +version: 9.0.0-dev-2 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 44d2d40dcf68bab6bc1caf6341fc414271818205 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 09:29:47 +0300 Subject: [PATCH 14/86] 2++++++++++ --- flutter_quill_test/pubspec.yaml | 2 +- scripts/regenerate_versions.dart | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 0fba29051..06a457c05 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -28,7 +28,7 @@ environment: dependencies: flutter: sdk: flutter - flutter_quill: ^9.0.0-dev + flutter_quill: ^8.2.5 flutter_test: sdk: flutter diff --git a/scripts/regenerate_versions.dart b/scripts/regenerate_versions.dart index 588e3fcb4..ed73e523a 100644 --- a/scripts/regenerate_versions.dart +++ b/scripts/regenerate_versions.dart @@ -9,13 +9,14 @@ import 'package:yaml_edit/yaml_edit.dart'; // ignore: unused_import import '../version.dart'; +final packages = [ + './', + './flutter_quill_extensions', + './flutter_quill_test', + './packages/quill_html_converter' +]; + Future main(List args) async { - final packages = [ - './', - './flutter_quill_extensions', - './flutter_quill_test', - './packages/quill_html_converter' - ]; for (final element in packages) { await updatePubspecYamlFile('$element/pubspec.yaml'); if (element != packages.first) { From c9ac8ccd3e1eb40d2c7f75eb4e9373a852af3d39 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 09:34:19 +0300 Subject: [PATCH 15/86] 2+++++++++++ --- packages/quill_html_converter/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index 60988ef20..1517c5286 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -20,7 +20,7 @@ environment: dependencies: flutter: sdk: flutter - flutter_quill: ^9.0.0-dev + flutter_quill: ^7.10.2 vsc_quill_delta_to_html: ^1.0.3 html2md: ^1.3.1 # markdown: ^7.1.1 From 331f9c7a9770c28d27b09851067b9cb2b7001e9f Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 09:44:01 +0300 Subject: [PATCH 16/86] An attemp to fix CI Failure --- example/pubspec.yaml | 4 ++-- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 441cb8355..14d582af2 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.6.2 - flutter_quill_extensions: ^0.7.0 + flutter_quill: ^8.6.4 + flutter_quill_extensions: ^0.7.2 flutter_quill_test: ^0.0.5 quill_html_converter: ^0.0.1-experimental.1 diff --git a/pubspec.yaml b/pubspec.yaml index 6b3b23600..168bf22a9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -62,7 +62,7 @@ dev_dependencies: flutter_lints: ^3.0.1 flutter_test: sdk: flutter - flutter_quill_test: ^0.0.4 + flutter_quill_test: ^9.0.0-dev-2 test: ^1.24.3 intl_translation: ^0.18.2 yaml_edit: ^2.1.1 From dc944604921a15a8ba2957b953bd63b58c768383 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 09:45:39 +0300 Subject: [PATCH 17/86] An attemp to fix CI Failure --- flutter_quill_test/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 06a457c05..014bd8e41 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -28,7 +28,7 @@ environment: dependencies: flutter: sdk: flutter - flutter_quill: ^8.2.5 + flutter_quill: ^9.0.0-dev-2 flutter_test: sdk: flutter From 70d0fd26f7808132808bc7115cbc6d0c28581d55 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 09:52:11 +0300 Subject: [PATCH 18/86] An attemp to fix CI Failure --- .github/workflows/build.yml | 3 +++ .github/workflows/main.yml | 3 +++ flutter_quill_test/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 221b2359d..5fdd3e33b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,6 +17,9 @@ jobs: - name: Check flutter version run: flutter --version + + - name: Enable Local Dev + run: ./scripts/enable_local_dev.sh - name: Install dependencies run: flutter pub get diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d76a2f455..f006ccb39 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,6 +20,9 @@ jobs: - name: Check flutter version run: flutter --version + - name: Enable Local Dev + run: ./scripts/enable_local_dev.sh + - name: Install dependencies run: flutter pub get diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 014bd8e41..60ea133db 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -28,7 +28,7 @@ environment: dependencies: flutter: sdk: flutter - flutter_quill: ^9.0.0-dev-2 + flutter_quill: ^7.0.0 flutter_test: sdk: flutter From b513bf21b1e5d72bc7c4dae6fa5e3d1bad557e70 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 09:57:38 +0300 Subject: [PATCH 19/86] Add development notes --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- CONTRIBUTING.md | 2 +- doc/development_notes.md | 6 ++++++ scripts/{before-push.sh => before_push.sh} | 0 4 files changed, 8 insertions(+), 2 deletions(-) rename scripts/{before-push.sh => before_push.sh} (100%) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c62f265d1..b68f4c4dd 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -28,7 +28,7 @@ - [ ] I titled the PR using [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0). - [ ] I did not modify the `CHANGELOG.md` nor the plugin version in `pubspec.yaml` files. - [ ] All existing and new tests are passing. -- [ ] I have run the commands in `./scripts/before-push.sh` and it all passed successfully +- [ ] I have run the commands in `./scripts/before_push.sh` and it all passed successfully ## Breaking Change diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 85d81a00d..029923e73 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,7 +39,7 @@ to `pubspec_overrides.yaml` which will be ignored by `.gitignore` and will be us 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 + ./scripts/before_push.sh ``` 11. When you are done sending your pull request, run: ``` diff --git a/doc/development_notes.md b/doc/development_notes.md index 25633cdac..23d60db85 100644 --- a/doc/development_notes.md +++ b/doc/development_notes.md @@ -1,3 +1,9 @@ # Development notes - When updating the translations or localizations in the app, please take a look at the [Translation](./translation.md) page as it has important notes in order to work, if you also add a feature that adds new localizations then you need to the instructions of it in order for the translations to take effect +- Only update the `version.dart` and `CHANGELOG.md` at the root folder of the repo, then run the script: + + ```console + dart ./scripts/regenerate_versions.dart + ``` + You must mention the changes of the other packages in the repo in the root `CHANGELOG.md` only and the script will replace the `CHANGELOG.md` in the other packages with the root one, and change the version in `pubspec.yaml` with the one in `version.dart` in the root folder \ No newline at end of file diff --git a/scripts/before-push.sh b/scripts/before_push.sh similarity index 100% rename from scripts/before-push.sh rename to scripts/before_push.sh From b07448420fb2645fad4e34a5bda8e2060f0ba575 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 10:18:57 +0300 Subject: [PATCH 20/86] 3 --- .../formula/toolbar/formula_button.dart | 8 +--- .../embeds/image/toolbar/image_button.dart | 7 +--- .../others/camera_button/camera_button.dart | 7 +--- .../embeds/video/toolbar/video_button.dart | 5 +-- .../widgets/toolbar/buttons/clear_format.dart | 6 +-- .../widgets/toolbar/buttons/color/color.dart | 6 +-- .../toolbar/buttons/custom_button.dart | 6 +-- lib/src/widgets/toolbar/buttons/history.dart | 7 +--- lib/src/widgets/toolbar/buttons/indent.dart | 7 +--- .../widgets/toolbar/buttons/link_style.dart | 7 +--- .../widgets/toolbar/buttons/link_style2.dart | 7 +--- .../widgets/toolbar/buttons/quill_icon.dart | 42 +++++-------------- .../toolbar/buttons/search/search.dart | 7 +--- .../widgets/toolbar/buttons/toggle_style.dart | 13 +----- test/bug_fix_test.dart | 10 ++--- 15 files changed, 30 insertions(+), 115 deletions(-) diff --git a/flutter_quill_extensions/lib/embeds/formula/toolbar/formula_button.dart b/flutter_quill_extensions/lib/embeds/formula/toolbar/formula_button.dart index 935389f6b..8b642ed11 100644 --- a/flutter_quill_extensions/lib/embeds/formula/toolbar/formula_button.dart +++ b/flutter_quill_extensions/lib/embeds/formula/toolbar/formula_button.dart @@ -71,14 +71,11 @@ class QuillToolbarFormulaButton extends StatelessWidget { 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, iconButtonFactor: iconButtonFactor, @@ -96,12 +93,9 @@ class QuillToolbarFormulaButton extends StatelessWidget { 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), + isFilled: false, ); } 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 06dcf805a..9f9bcc1a2 100644 --- a/flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart +++ b/flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart @@ -101,8 +101,6 @@ class QuillToolbarImageButton extends StatelessWidget { final iconTheme = _iconTheme(context); final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; - final iconFillColor = iconTheme?.iconUnselectedFillColor ?? - (options.fillColor ?? theme.canvasColor); return QuillToolbarIconButton( icon: Icon( @@ -111,11 +109,8 @@ class QuillToolbarImageButton extends StatelessWidget { color: iconColor, ), tooltip: tooltip, - highlightElevation: 0, - hoverElevation: 0, size: iconSize * 1.77, - fillColor: iconFillColor, - borderRadius: iconTheme?.borderRadius ?? 2, + isFilled: false, onPressed: () => _sharedOnPressed(context), ); } diff --git a/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart b/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart index c62976cb4..f96f59af1 100644 --- a/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart +++ b/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart @@ -96,17 +96,12 @@ class QuillToolbarCameraButton extends StatelessWidget { 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, + isFilled: false, // isDesktop(supportWeb: false) ? null : onPressed: () => _sharedOnPressed(context), ); 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 780112396..56e047696 100644 --- a/flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart +++ b/flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart @@ -100,11 +100,8 @@ class QuillToolbarVideoButton extends StatelessWidget { 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, + isFilled: false, onPressed: () => _sharedOnPressed(context), ); } diff --git a/lib/src/widgets/toolbar/buttons/clear_format.dart b/lib/src/widgets/toolbar/buttons/clear_format.dart index e5f4afc7a..e25afa3d1 100644 --- a/lib/src/widgets/toolbar/buttons/clear_format.dart +++ b/lib/src/widgets/toolbar/buttons/clear_format.dart @@ -108,16 +108,12 @@ class QuillToolbarClearFormatButton extends StatelessWidget { final theme = Theme.of(context); final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; - final fillColor = iconTheme?.iconUnselectedFillColor ?? theme.canvasColor; return QuillToolbarIconButton( tooltip: tooltip, - highlightElevation: 0, - hoverElevation: 0, size: iconSize * iconButtonFactor, icon: Icon(iconData, size: iconSize, color: iconColor), - fillColor: fillColor, - borderRadius: iconTheme?.borderRadius ?? 2, + isFilled: false, onPressed: _sharedOnPressed, afterPressed: afterButtonPressed, ); diff --git a/lib/src/widgets/toolbar/buttons/color/color.dart b/lib/src/widgets/toolbar/buttons/color/color.dart index 1691d71cd..9f939f1d6 100644 --- a/lib/src/widgets/toolbar/buttons/color/color.dart +++ b/lib/src/widgets/toolbar/buttons/color/color.dart @@ -195,14 +195,12 @@ class QuillToolbarColorButtonState extends State { return QuillToolbarIconButton( tooltip: tooltip, - highlightElevation: 0, - hoverElevation: 0, size: iconSize * iconButtonFactor, icon: Icon(iconData, size: iconSize, color: widget.isBackground ? iconColorBackground : iconColor), - fillColor: widget.isBackground ? fillColorBackground : fillColor, - borderRadius: iconTheme?.borderRadius ?? 2, + // fillColor: widget.isBackground ? fillColorBackground : fillColor, + isFilled: false, onPressed: _showColorPicker, afterPressed: afterButtonPressed, ); diff --git a/lib/src/widgets/toolbar/buttons/custom_button.dart b/lib/src/widgets/toolbar/buttons/custom_button.dart index f306a440b..bbf6ad575 100644 --- a/lib/src/widgets/toolbar/buttons/custom_button.dart +++ b/lib/src/widgets/toolbar/buttons/custom_button.dart @@ -80,15 +80,13 @@ class QuillToolbarCustomButton extends StatelessWidget { ); } - final theme = Theme.of(context); return QuillToolbarIconButton( size: iconSize * iconButtonFactor, - icon: options.icon, + icon: options.icon ?? const SizedBox.shrink(), + isFilled: false, tooltip: tooltip, - borderRadius: iconTheme?.borderRadius ?? 2, onPressed: () => _onPressed(context), afterPressed: afterButtonPressed, - fillColor: iconTheme?.iconUnselectedFillColor ?? theme.canvasColor, ); } } diff --git a/lib/src/widgets/toolbar/buttons/history.dart b/lib/src/widgets/toolbar/buttons/history.dart index bbf7c54f8..3a4cf3c1b 100644 --- a/lib/src/widgets/toolbar/buttons/history.dart +++ b/lib/src/widgets/toolbar/buttons/history.dart @@ -93,12 +93,8 @@ class QuillToolbarHistoryButtonState extends State { } theme = Theme.of(context); - - final fillColor = iconTheme?.iconUnselectedFillColor ?? theme.canvasColor; return QuillToolbarIconButton( tooltip: tooltip, - highlightElevation: 0, - hoverElevation: 0, size: iconSize * iconButtonFactor, icon: Icon( iconData, @@ -107,8 +103,7 @@ class QuillToolbarHistoryButtonState extends State { ? iconTheme?.iconUnselectedColor ?? theme.iconTheme.color : iconTheme?.disabledIconColor ?? theme.disabledColor, ), - fillColor: fillColor, - borderRadius: iconTheme?.borderRadius ?? 2, + isFilled: false, onPressed: _updateHistory, afterPressed: afterButtonPressed, ); diff --git a/lib/src/widgets/toolbar/buttons/indent.dart b/lib/src/widgets/toolbar/buttons/indent.dart index 22c3eb29a..793dd0faa 100644 --- a/lib/src/widgets/toolbar/buttons/indent.dart +++ b/lib/src/widgets/toolbar/buttons/indent.dart @@ -107,16 +107,11 @@ class QuillToolbarIndentButtonState extends State { final theme = Theme.of(context); final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; - final iconFillColor = - iconTheme?.iconUnselectedFillColor ?? theme.canvasColor; return QuillToolbarIconButton( tooltip: tooltip, - highlightElevation: 0, - hoverElevation: 0, size: iconSize * iconButtonFactor, icon: Icon(iconData, size: iconSize, color: iconColor), - fillColor: iconFillColor, - borderRadius: iconTheme?.borderRadius ?? 2, + isFilled: false, onPressed: _sharedOnPressed, afterPressed: afterButtonPressed, ); diff --git a/lib/src/widgets/toolbar/buttons/link_style.dart b/lib/src/widgets/toolbar/buttons/link_style.dart index 2bc54fead..b4aacadc9 100644 --- a/lib/src/widgets/toolbar/buttons/link_style.dart +++ b/lib/src/widgets/toolbar/buttons/link_style.dart @@ -141,8 +141,6 @@ class QuillToolbarLinkStyleButtonState final theme = Theme.of(context); return QuillToolbarIconButton( tooltip: tooltip, - highlightElevation: 0, - hoverElevation: 0, size: iconSize * iconButtonFactor, icon: Icon( iconData, @@ -151,10 +149,7 @@ class QuillToolbarLinkStyleButtonState ? (iconTheme?.iconSelectedColor ?? theme.primaryIconTheme.color) : (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color), ), - fillColor: isToggled - ? (iconTheme?.iconSelectedFillColor ?? theme.primaryColor) - : (iconTheme?.iconUnselectedFillColor ?? theme.canvasColor), - borderRadius: iconTheme?.borderRadius ?? 2, + isFilled: isToggled, onPressed: () => _openLinkDialog(context), afterPressed: afterButtonPressed, ); diff --git a/lib/src/widgets/toolbar/buttons/link_style2.dart b/lib/src/widgets/toolbar/buttons/link_style2.dart index df834f23b..86e25103a 100644 --- a/lib/src/widgets/toolbar/buttons/link_style2.dart +++ b/lib/src/widgets/toolbar/buttons/link_style2.dart @@ -148,8 +148,6 @@ class _QuillToolbarLinkStyleButton2State final isToggled = _getLinkAttributeValue() != null; return QuillToolbarIconButton( tooltip: tooltip, - highlightElevation: 0, - hoverElevation: 0, size: iconSize * iconButtonFactor, icon: Icon( iconData, @@ -158,10 +156,7 @@ class _QuillToolbarLinkStyleButton2State ? (iconTheme?.iconSelectedColor ?? theme.primaryIconTheme.color) : (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color), ), - fillColor: isToggled - ? (iconTheme?.iconSelectedFillColor ?? theme.primaryColor) - : (iconTheme?.iconUnselectedFillColor ?? theme.canvasColor), - borderRadius: iconTheme?.borderRadius ?? 2, + isFilled: isToggled, onPressed: _openLinkDialog, afterPressed: afterButtonPressed, ); diff --git a/lib/src/widgets/toolbar/buttons/quill_icon.dart b/lib/src/widgets/toolbar/buttons/quill_icon.dart index d78494d0f..3370792e5 100644 --- a/lib/src/widgets/toolbar/buttons/quill_icon.dart +++ b/lib/src/widgets/toolbar/buttons/quill_icon.dart @@ -1,54 +1,32 @@ import 'package:flutter/material.dart'; -import '../../../utils/widgets.dart'; - class QuillToolbarIconButton extends StatelessWidget { const QuillToolbarIconButton({ required this.onPressed, + required this.icon, + required this.isFilled, this.afterPressed, - this.icon, this.size = 40, - this.fillColor, - this.hoverElevation = 1, - this.highlightElevation = 1, - this.borderRadius = 2, this.tooltip, super.key, }); final VoidCallback? onPressed; final VoidCallback? afterPressed; - final Widget? icon; + final Widget icon; final double size; - final Color? fillColor; - final double hoverElevation; - final double highlightElevation; - final double borderRadius; final String? tooltip; + final bool isFilled; @override Widget build(BuildContext context) { - return ConstrainedBox( - constraints: BoxConstraints.tightFor(width: size, height: size), - child: UtilityWidgets.maybeTooltip( - message: tooltip, - child: RawMaterialButton( - visualDensity: VisualDensity.compact, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(borderRadius), - ), - fillColor: fillColor, - elevation: 0, - hoverElevation: hoverElevation, - highlightElevation: hoverElevation, - onPressed: () { - onPressed?.call(); - afterPressed?.call(); - }, - child: icon, - ), - ), + if (isFilled) { + return IconButton.filled(onPressed: onPressed, icon: icon); + } + return IconButton( + onPressed: onPressed, + icon: icon, ); } } diff --git a/lib/src/widgets/toolbar/buttons/search/search.dart b/lib/src/widgets/toolbar/buttons/search/search.dart index 91cb622bc..8b568977d 100644 --- a/lib/src/widgets/toolbar/buttons/search/search.dart +++ b/lib/src/widgets/toolbar/buttons/search/search.dart @@ -111,8 +111,6 @@ class QuillToolbarSearchButton extends StatelessWidget { final theme = Theme.of(context); final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; - final iconFillColor = iconTheme?.iconUnselectedFillColor ?? - (options.fillColor ?? theme.canvasColor); return QuillToolbarIconButton( tooltip: tooltip, @@ -121,11 +119,8 @@ class QuillToolbarSearchButton extends StatelessWidget { size: iconSize, color: iconColor, ), - highlightElevation: 0, - hoverElevation: 0, size: iconSize * iconButtonFactor, - fillColor: iconFillColor, - borderRadius: iconTheme?.borderRadius ?? 2, + isFilled: false, onPressed: () => _sharedOnPressed(context), afterPressed: afterButtonPressed, ); diff --git a/lib/src/widgets/toolbar/buttons/toggle_style.dart b/lib/src/widgets/toolbar/buttons/toggle_style.dart index dabf225e0..e2928ef37 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style.dart @@ -241,22 +241,11 @@ Widget defaultToggleStyleButtonBuilder( .primaryIconTheme.color) //You can specify your own icon color : (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color) : (iconTheme?.disabledIconColor ?? theme.disabledColor); - final fill = isEnabled - ? isToggled == true - ? (iconTheme?.iconSelectedFillColor ?? - Theme.of(context).primaryColor) //Selected icon fill color - : (iconTheme?.iconUnselectedFillColor ?? - theme.canvasColor) //Unselected icon fill color : - : (iconTheme?.disabledIconFillColor ?? - (fillColor ?? theme.canvasColor)); //Disabled icon fill color return QuillToolbarIconButton( - highlightElevation: 0, - hoverElevation: 0, size: iconSize * iconButtonFactor, icon: Icon(icon, size: iconSize, color: iconColor), - fillColor: fill, + isFilled: isEnabled ? isToggled == true : false, onPressed: onPressed, afterPressed: afterPressed, - borderRadius: iconTheme?.borderRadius ?? 2, ); } diff --git a/test/bug_fix_test.dart b/test/bug_fix_test.dart index f6c2c4edc..2b804bae9 100644 --- a/test/bug_fix_test.dart +++ b/test/bug_fix_test.dart @@ -36,8 +36,8 @@ void main() { matchRoot: true, ); expect(builtinFinder, findsOneWidget); - final builtinButton = - builtinFinder.evaluate().first.widget as QuillToolbarIconButton; + // final builtinButton = + // builtinFinder.evaluate().first.widget as QuillToolbarIconButton; final customFinder = find.descendant( of: find.byType(QuillBaseToolbar), @@ -45,10 +45,10 @@ void main() { widget is QuillToolbarIconButton && widget.tooltip == tooltip), matchRoot: true); expect(customFinder, findsOneWidget); - final customButton = - customFinder.evaluate().first.widget as QuillToolbarIconButton; + // final customButton = + // customFinder.evaluate().first.widget as QuillToolbarIconButton; - expect(customButton.fillColor, equals(builtinButton.fillColor)); + // expect(customButton.fillColor, equals(builtinButton.fillColor)); }); }); From 08e55abb845a7065443c5702d02a6604bf7b0b2d Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 10:21:43 +0300 Subject: [PATCH 21/86] Rename button files --- .../raw_editor/raw_editor_actions.dart | 2 +- lib/src/widgets/toolbar/base_toolbar.dart | 32 +++++++++---------- ....dart => arrow_indicated_list_button.dart} | 0 ...r_format.dart => clear_format_button.dart} | 0 .../color/{color.dart => color_button.dart} | 2 +- .../color/{dialog.dart => color_dialog.dart} | 2 +- ..._button.dart => custom_button_button.dart} | 0 ...nt_family.dart => font_family_button.dart} | 0 .../{font_size.dart => font_size_button.dart} | 0 .../{history.dart => history_button.dart} | 0 .../{indent.dart => indent_button.dart} | 0 ...nk_style2.dart => link_style2_button.dart} | 0 ...link_style.dart => link_style_button.dart} | 0 ...quill_icon.dart => quill_icon_button.dart} | 0 .../{search.dart => search_button.dart} | 0 ...ment.dart => select_alignment_button.dart} | 0 ...e.dart => select_header_style_button.dart} | 0 ...ist.dart => toggle_check_list_button.dart} | 0 ...le_style.dart => toggle_style_button.dart} | 0 19 files changed, 19 insertions(+), 19 deletions(-) rename lib/src/widgets/toolbar/buttons/{arrow_indicated_list.dart => arrow_indicated_list_button.dart} (100%) rename lib/src/widgets/toolbar/buttons/{clear_format.dart => clear_format_button.dart} (100%) rename lib/src/widgets/toolbar/buttons/color/{color.dart => color_button.dart} (99%) rename lib/src/widgets/toolbar/buttons/color/{dialog.dart => color_dialog.dart} (99%) rename lib/src/widgets/toolbar/buttons/{custom_button.dart => custom_button_button.dart} (100%) rename lib/src/widgets/toolbar/buttons/{font_family.dart => font_family_button.dart} (100%) rename lib/src/widgets/toolbar/buttons/{font_size.dart => font_size_button.dart} (100%) rename lib/src/widgets/toolbar/buttons/{history.dart => history_button.dart} (100%) rename lib/src/widgets/toolbar/buttons/{indent.dart => indent_button.dart} (100%) rename lib/src/widgets/toolbar/buttons/{link_style2.dart => link_style2_button.dart} (100%) rename lib/src/widgets/toolbar/buttons/{link_style.dart => link_style_button.dart} (100%) rename lib/src/widgets/toolbar/buttons/{quill_icon.dart => quill_icon_button.dart} (100%) rename lib/src/widgets/toolbar/buttons/search/{search.dart => search_button.dart} (100%) rename lib/src/widgets/toolbar/buttons/{select_alignment.dart => select_alignment_button.dart} (100%) rename lib/src/widgets/toolbar/buttons/{select_header_style.dart => select_header_style_button.dart} (100%) rename lib/src/widgets/toolbar/buttons/{toggle_check_list.dart => toggle_check_list_button.dart} (100%) rename lib/src/widgets/toolbar/buttons/{toggle_style.dart => toggle_style_button.dart} (100%) diff --git a/lib/src/widgets/raw_editor/raw_editor_actions.dart b/lib/src/widgets/raw_editor/raw_editor_actions.dart index caed0f7ce..40580d70e 100644 --- a/lib/src/widgets/raw_editor/raw_editor_actions.dart +++ b/lib/src/widgets/raw_editor/raw_editor_actions.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import '../../models/documents/attribute.dart'; import '../editor/editor.dart'; -import '../toolbar/buttons/link_style2.dart'; +import '../toolbar/buttons/link_style2_button.dart'; import '../toolbar/buttons/search/search_dialog.dart'; import 'raw_editor_state.dart'; import 'raw_editor_text_boundaries.dart'; diff --git a/lib/src/widgets/toolbar/base_toolbar.dart b/lib/src/widgets/toolbar/base_toolbar.dart index 5767f0f2f..ba629f2c0 100644 --- a/lib/src/widgets/toolbar/base_toolbar.dart +++ b/lib/src/widgets/toolbar/base_toolbar.dart @@ -4,25 +4,25 @@ import '../../../flutter_quill.dart' show QuillBaseToolbarProvider, defaultToolbarSize; import '../../l10n/widgets/localizations.dart'; import '../../models/config/toolbar/base_toolbar_configurations.dart'; -import 'buttons/arrow_indicated_list.dart'; +import 'buttons/arrow_indicated_list_button.dart'; export '../../models/config/toolbar/buttons/base.dart'; export '../../models/config/toolbar/toolbar_configurations.dart'; -export 'buttons/clear_format.dart'; -export 'buttons/color/color.dart'; -export 'buttons/custom_button.dart'; -export 'buttons/font_family.dart'; -export 'buttons/font_size.dart'; -export 'buttons/history.dart'; -export 'buttons/indent.dart'; -export 'buttons/link_style.dart'; -export 'buttons/link_style2.dart'; -export 'buttons/quill_icon.dart'; -export 'buttons/search/search.dart'; -export 'buttons/select_alignment.dart'; -export 'buttons/select_header_style.dart'; -export 'buttons/toggle_check_list.dart'; -export 'buttons/toggle_style.dart'; +export 'buttons/clear_format_button.dart'; +export 'buttons/color/color_button.dart'; +export 'buttons/custom_button_button.dart'; +export 'buttons/font_family_button.dart'; +export 'buttons/font_size_button.dart'; +export 'buttons/history_button.dart'; +export 'buttons/indent_button.dart'; +export 'buttons/link_style2_button.dart'; +export 'buttons/link_style_button.dart'; +export 'buttons/quill_icon_button.dart'; +export 'buttons/search/search_button.dart'; +export 'buttons/select_alignment_button.dart'; +export 'buttons/select_header_style_button.dart'; +export 'buttons/toggle_check_list_button.dart'; +export 'buttons/toggle_style_button.dart'; typedef QuillBaseToolbarChildrenBuilder = List Function( BuildContext context, diff --git a/lib/src/widgets/toolbar/buttons/arrow_indicated_list.dart b/lib/src/widgets/toolbar/buttons/arrow_indicated_list_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/arrow_indicated_list.dart rename to lib/src/widgets/toolbar/buttons/arrow_indicated_list_button.dart diff --git a/lib/src/widgets/toolbar/buttons/clear_format.dart b/lib/src/widgets/toolbar/buttons/clear_format_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/clear_format.dart rename to lib/src/widgets/toolbar/buttons/clear_format_button.dart diff --git a/lib/src/widgets/toolbar/buttons/color/color.dart b/lib/src/widgets/toolbar/buttons/color/color_button.dart similarity index 99% rename from lib/src/widgets/toolbar/buttons/color/color.dart rename to lib/src/widgets/toolbar/buttons/color/color_button.dart index 9f939f1d6..8454290a5 100644 --- a/lib/src/widgets/toolbar/buttons/color/color.dart +++ b/lib/src/widgets/toolbar/buttons/color/color_button.dart @@ -9,7 +9,7 @@ import '../../../../models/themes/quill_icon_theme.dart'; import '../../../../utils/color.dart'; import '../../../controller.dart'; import '../../base_toolbar.dart'; -import 'dialog.dart'; +import 'color_dialog.dart'; /// Controls color styles. /// diff --git a/lib/src/widgets/toolbar/buttons/color/dialog.dart b/lib/src/widgets/toolbar/buttons/color/color_dialog.dart similarity index 99% rename from lib/src/widgets/toolbar/buttons/color/dialog.dart rename to lib/src/widgets/toolbar/buttons/color/color_dialog.dart index a9806f51c..3ce6bf814 100644 --- a/lib/src/widgets/toolbar/buttons/color/dialog.dart +++ b/lib/src/widgets/toolbar/buttons/color/color_dialog.dart @@ -4,7 +4,7 @@ import 'package:flutter_colorpicker/flutter_colorpicker.dart' import '../../../../../translations.dart'; import '../../../../models/documents/style.dart'; -import 'color.dart' show hexToColor; +import 'color_button.dart' show hexToColor; class ColorPickerDialog extends StatefulWidget { const ColorPickerDialog({ diff --git a/lib/src/widgets/toolbar/buttons/custom_button.dart b/lib/src/widgets/toolbar/buttons/custom_button_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/custom_button.dart rename to lib/src/widgets/toolbar/buttons/custom_button_button.dart diff --git a/lib/src/widgets/toolbar/buttons/font_family.dart b/lib/src/widgets/toolbar/buttons/font_family_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/font_family.dart rename to lib/src/widgets/toolbar/buttons/font_family_button.dart diff --git a/lib/src/widgets/toolbar/buttons/font_size.dart b/lib/src/widgets/toolbar/buttons/font_size_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/font_size.dart rename to lib/src/widgets/toolbar/buttons/font_size_button.dart diff --git a/lib/src/widgets/toolbar/buttons/history.dart b/lib/src/widgets/toolbar/buttons/history_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/history.dart rename to lib/src/widgets/toolbar/buttons/history_button.dart diff --git a/lib/src/widgets/toolbar/buttons/indent.dart b/lib/src/widgets/toolbar/buttons/indent_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/indent.dart rename to lib/src/widgets/toolbar/buttons/indent_button.dart diff --git a/lib/src/widgets/toolbar/buttons/link_style2.dart b/lib/src/widgets/toolbar/buttons/link_style2_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/link_style2.dart rename to lib/src/widgets/toolbar/buttons/link_style2_button.dart diff --git a/lib/src/widgets/toolbar/buttons/link_style.dart b/lib/src/widgets/toolbar/buttons/link_style_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/link_style.dart rename to lib/src/widgets/toolbar/buttons/link_style_button.dart diff --git a/lib/src/widgets/toolbar/buttons/quill_icon.dart b/lib/src/widgets/toolbar/buttons/quill_icon_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/quill_icon.dart rename to lib/src/widgets/toolbar/buttons/quill_icon_button.dart diff --git a/lib/src/widgets/toolbar/buttons/search/search.dart b/lib/src/widgets/toolbar/buttons/search/search_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/search/search.dart rename to lib/src/widgets/toolbar/buttons/search/search_button.dart diff --git a/lib/src/widgets/toolbar/buttons/select_alignment.dart b/lib/src/widgets/toolbar/buttons/select_alignment_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/select_alignment.dart rename to lib/src/widgets/toolbar/buttons/select_alignment_button.dart diff --git a/lib/src/widgets/toolbar/buttons/select_header_style.dart b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/select_header_style.dart rename to lib/src/widgets/toolbar/buttons/select_header_style_button.dart diff --git a/lib/src/widgets/toolbar/buttons/toggle_check_list.dart b/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/toggle_check_list.dart rename to lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart diff --git a/lib/src/widgets/toolbar/buttons/toggle_style.dart b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart similarity index 100% rename from lib/src/widgets/toolbar/buttons/toggle_style.dart rename to lib/src/widgets/toolbar/buttons/toggle_style_button.dart From 913c33cc80f65c9747974d00e6393176a00a4c74 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 10:57:28 +0300 Subject: [PATCH 22/86] Dropdown QuillToolbarSelectHeaderStyleButton --- .../l10n/generated/quill_localizations.dart | 24 ++ .../generated/quill_localizations_ar.dart | 12 + .../generated/quill_localizations_bg.dart | 12 + .../generated/quill_localizations_bn.dart | 12 + .../generated/quill_localizations_cs.dart | 12 + .../generated/quill_localizations_da.dart | 12 + .../generated/quill_localizations_de.dart | 12 + .../generated/quill_localizations_en.dart | 12 + .../generated/quill_localizations_es.dart | 12 + .../generated/quill_localizations_fa.dart | 12 + .../generated/quill_localizations_fr.dart | 12 + .../generated/quill_localizations_he.dart | 12 + .../generated/quill_localizations_hi.dart | 12 + .../generated/quill_localizations_id.dart | 12 + .../generated/quill_localizations_it.dart | 12 + .../generated/quill_localizations_ja.dart | 12 + .../generated/quill_localizations_ko.dart | 12 + .../generated/quill_localizations_ms.dart | 12 + .../generated/quill_localizations_nl.dart | 12 + .../generated/quill_localizations_no.dart | 12 + .../generated/quill_localizations_pl.dart | 12 + .../generated/quill_localizations_pt.dart | 12 + .../generated/quill_localizations_ru.dart | 12 + .../generated/quill_localizations_sr.dart | 12 + .../generated/quill_localizations_sw.dart | 12 + .../generated/quill_localizations_tk.dart | 12 + .../generated/quill_localizations_tr.dart | 12 + .../generated/quill_localizations_uk.dart | 12 + .../generated/quill_localizations_ur.dart | 12 + .../generated/quill_localizations_vi.dart | 12 + .../generated/quill_localizations_zh.dart | 12 + lib/src/l10n/quill_en.arb | 4 + lib/src/l10n/untranslated.json | 132 +++++++++ lib/src/widgets/toolbar/base_toolbar.dart | 2 +- .../toolbar/buttons/color/color_button.dart | 7 +- .../buttons/select_header_style_button.dart | 278 +++++------------- .../buttons/select_header_style_buttons.dart | 235 +++++++++++++++ .../buttons/toggle_check_list_button.dart | 2 +- lib/src/widgets/toolbar/toolbar.dart | 3 +- 39 files changed, 840 insertions(+), 207 deletions(-) create mode 100644 lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart diff --git a/lib/src/l10n/generated/quill_localizations.dart b/lib/src/l10n/generated/quill_localizations.dart index f4425f811..e81ddc023 100644 --- a/lib/src/l10n/generated/quill_localizations.dart +++ b/lib/src/l10n/generated/quill_localizations.dart @@ -421,6 +421,30 @@ abstract class FlutterQuillLocalizations { /// **'Header style'** String get headerStyle; + /// No description provided for @normal. + /// + /// In en, this message translates to: + /// **'Normal'** + String get normal; + + /// No description provided for @heading1. + /// + /// In en, this message translates to: + /// **'Heading 1'** + String get heading1; + + /// No description provided for @heading2. + /// + /// In en, this message translates to: + /// **'Heading 2'** + String get heading2; + + /// No description provided for @heading3. + /// + /// In en, this message translates to: + /// **'Heading 3'** + String get heading3; + /// No description provided for @numberedList. /// /// In en, this message translates to: diff --git a/lib/src/l10n/generated/quill_localizations_ar.dart b/lib/src/l10n/generated/quill_localizations_ar.dart index fc7b2dfc4..c8905ce79 100644 --- a/lib/src/l10n/generated/quill_localizations_ar.dart +++ b/lib/src/l10n/generated/quill_localizations_ar.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsAr extends FlutterQuillLocalizations { @override String get headerStyle => 'ستايل العنوان'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'قائمة مرقمة'; diff --git a/lib/src/l10n/generated/quill_localizations_bg.dart b/lib/src/l10n/generated/quill_localizations_bg.dart index a75b6ffab..6869b457c 100644 --- a/lib/src/l10n/generated/quill_localizations_bg.dart +++ b/lib/src/l10n/generated/quill_localizations_bg.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsBg extends FlutterQuillLocalizations { @override String get headerStyle => 'Стил на заглавието'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Номериран списък'; diff --git a/lib/src/l10n/generated/quill_localizations_bn.dart b/lib/src/l10n/generated/quill_localizations_bn.dart index 7ef340ef6..930d7d6c5 100644 --- a/lib/src/l10n/generated/quill_localizations_bn.dart +++ b/lib/src/l10n/generated/quill_localizations_bn.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsBn extends FlutterQuillLocalizations { @override String get headerStyle => 'হেডার স্টাইল'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'সংখ্যাযুক্ত তালিকা'; diff --git a/lib/src/l10n/generated/quill_localizations_cs.dart b/lib/src/l10n/generated/quill_localizations_cs.dart index a74f67564..e55d8c811 100644 --- a/lib/src/l10n/generated/quill_localizations_cs.dart +++ b/lib/src/l10n/generated/quill_localizations_cs.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsCs extends FlutterQuillLocalizations { @override String get headerStyle => 'Styl záhlaví'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Číslovaný seznam'; diff --git a/lib/src/l10n/generated/quill_localizations_da.dart b/lib/src/l10n/generated/quill_localizations_da.dart index 6e8825fc5..b969adbc6 100644 --- a/lib/src/l10n/generated/quill_localizations_da.dart +++ b/lib/src/l10n/generated/quill_localizations_da.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsDa extends FlutterQuillLocalizations { @override String get headerStyle => 'Header style'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Numbered list'; diff --git a/lib/src/l10n/generated/quill_localizations_de.dart b/lib/src/l10n/generated/quill_localizations_de.dart index 384b8ea33..ddbf7af2e 100644 --- a/lib/src/l10n/generated/quill_localizations_de.dart +++ b/lib/src/l10n/generated/quill_localizations_de.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsDe extends FlutterQuillLocalizations { @override String get headerStyle => 'Überschrift-Stil'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Nummerierte Liste'; diff --git a/lib/src/l10n/generated/quill_localizations_en.dart b/lib/src/l10n/generated/quill_localizations_en.dart index 1233f1cf3..8a6fa0dc0 100644 --- a/lib/src/l10n/generated/quill_localizations_en.dart +++ b/lib/src/l10n/generated/quill_localizations_en.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsEn extends FlutterQuillLocalizations { @override String get headerStyle => 'Header style'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Numbered list'; diff --git a/lib/src/l10n/generated/quill_localizations_es.dart b/lib/src/l10n/generated/quill_localizations_es.dart index 3c63865d1..a0b8c59dd 100644 --- a/lib/src/l10n/generated/quill_localizations_es.dart +++ b/lib/src/l10n/generated/quill_localizations_es.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsEs extends FlutterQuillLocalizations { @override String get headerStyle => 'Header style'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Numbered list'; diff --git a/lib/src/l10n/generated/quill_localizations_fa.dart b/lib/src/l10n/generated/quill_localizations_fa.dart index 32040119a..088cd13df 100644 --- a/lib/src/l10n/generated/quill_localizations_fa.dart +++ b/lib/src/l10n/generated/quill_localizations_fa.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsFa extends FlutterQuillLocalizations { @override String get headerStyle => 'سبک هدر'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'لیست شماره‌دار'; diff --git a/lib/src/l10n/generated/quill_localizations_fr.dart b/lib/src/l10n/generated/quill_localizations_fr.dart index b94451ff1..d7ce3c0a0 100644 --- a/lib/src/l10n/generated/quill_localizations_fr.dart +++ b/lib/src/l10n/generated/quill_localizations_fr.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsFr extends FlutterQuillLocalizations { @override String get headerStyle => "Style d'en-tête"; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Liste numérotée'; diff --git a/lib/src/l10n/generated/quill_localizations_he.dart b/lib/src/l10n/generated/quill_localizations_he.dart index 956c10f99..939375a0d 100644 --- a/lib/src/l10n/generated/quill_localizations_he.dart +++ b/lib/src/l10n/generated/quill_localizations_he.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsHe extends FlutterQuillLocalizations { @override String get headerStyle => 'סגנון הכותרת'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'רשימה ממוספרת'; diff --git a/lib/src/l10n/generated/quill_localizations_hi.dart b/lib/src/l10n/generated/quill_localizations_hi.dart index 3e2e738aa..69f19b371 100644 --- a/lib/src/l10n/generated/quill_localizations_hi.dart +++ b/lib/src/l10n/generated/quill_localizations_hi.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsHi extends FlutterQuillLocalizations { @override String get headerStyle => 'हेडर शैली'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'संख्याबद्ध सूची'; diff --git a/lib/src/l10n/generated/quill_localizations_id.dart b/lib/src/l10n/generated/quill_localizations_id.dart index 4d4d38c53..c664f6778 100644 --- a/lib/src/l10n/generated/quill_localizations_id.dart +++ b/lib/src/l10n/generated/quill_localizations_id.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsId extends FlutterQuillLocalizations { @override String get headerStyle => 'Gaya Header'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Daftar Bernomor'; diff --git a/lib/src/l10n/generated/quill_localizations_it.dart b/lib/src/l10n/generated/quill_localizations_it.dart index 2b8fe0703..74bf73898 100644 --- a/lib/src/l10n/generated/quill_localizations_it.dart +++ b/lib/src/l10n/generated/quill_localizations_it.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsIt extends FlutterQuillLocalizations { @override String get headerStyle => 'Stile intestazione'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Elenco numerato'; diff --git a/lib/src/l10n/generated/quill_localizations_ja.dart b/lib/src/l10n/generated/quill_localizations_ja.dart index 7a55d6b53..364a32145 100644 --- a/lib/src/l10n/generated/quill_localizations_ja.dart +++ b/lib/src/l10n/generated/quill_localizations_ja.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsJa extends FlutterQuillLocalizations { @override String get headerStyle => 'タイトルスタイル'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => '順序付きリスト'; diff --git a/lib/src/l10n/generated/quill_localizations_ko.dart b/lib/src/l10n/generated/quill_localizations_ko.dart index c8a6b5669..5a46e10ba 100644 --- a/lib/src/l10n/generated/quill_localizations_ko.dart +++ b/lib/src/l10n/generated/quill_localizations_ko.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsKo extends FlutterQuillLocalizations { @override String get headerStyle => 'Header style'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Numbered list'; diff --git a/lib/src/l10n/generated/quill_localizations_ms.dart b/lib/src/l10n/generated/quill_localizations_ms.dart index c443712f5..9b929a381 100644 --- a/lib/src/l10n/generated/quill_localizations_ms.dart +++ b/lib/src/l10n/generated/quill_localizations_ms.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsMs extends FlutterQuillLocalizations { @override String get headerStyle => 'Header style'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Numbered list'; diff --git a/lib/src/l10n/generated/quill_localizations_nl.dart b/lib/src/l10n/generated/quill_localizations_nl.dart index 65bc5b47c..5a0f6eb69 100644 --- a/lib/src/l10n/generated/quill_localizations_nl.dart +++ b/lib/src/l10n/generated/quill_localizations_nl.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsNl extends FlutterQuillLocalizations { @override String get headerStyle => 'Header style'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Numbered list'; diff --git a/lib/src/l10n/generated/quill_localizations_no.dart b/lib/src/l10n/generated/quill_localizations_no.dart index 087c69971..6d6b278cb 100644 --- a/lib/src/l10n/generated/quill_localizations_no.dart +++ b/lib/src/l10n/generated/quill_localizations_no.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsNo extends FlutterQuillLocalizations { @override String get headerStyle => 'Overskriftsstil'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Nummerert liste'; diff --git a/lib/src/l10n/generated/quill_localizations_pl.dart b/lib/src/l10n/generated/quill_localizations_pl.dart index 677ff5c82..0f6ce73c9 100644 --- a/lib/src/l10n/generated/quill_localizations_pl.dart +++ b/lib/src/l10n/generated/quill_localizations_pl.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsPl extends FlutterQuillLocalizations { @override String get headerStyle => 'Header style'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Numbered list'; diff --git a/lib/src/l10n/generated/quill_localizations_pt.dart b/lib/src/l10n/generated/quill_localizations_pt.dart index bec9b366c..d4184f113 100644 --- a/lib/src/l10n/generated/quill_localizations_pt.dart +++ b/lib/src/l10n/generated/quill_localizations_pt.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsPt extends FlutterQuillLocalizations { @override String get headerStyle => 'Header style'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Numbered list'; diff --git a/lib/src/l10n/generated/quill_localizations_ru.dart b/lib/src/l10n/generated/quill_localizations_ru.dart index 96a9314b8..0237b47bf 100644 --- a/lib/src/l10n/generated/quill_localizations_ru.dart +++ b/lib/src/l10n/generated/quill_localizations_ru.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsRu extends FlutterQuillLocalizations { @override String get headerStyle => 'Header style'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Numbered list'; diff --git a/lib/src/l10n/generated/quill_localizations_sr.dart b/lib/src/l10n/generated/quill_localizations_sr.dart index 1e89073e7..b1366486e 100644 --- a/lib/src/l10n/generated/quill_localizations_sr.dart +++ b/lib/src/l10n/generated/quill_localizations_sr.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsSr extends FlutterQuillLocalizations { @override String get headerStyle => 'Stil zaglavlja'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Numerisana lista'; diff --git a/lib/src/l10n/generated/quill_localizations_sw.dart b/lib/src/l10n/generated/quill_localizations_sw.dart index 640403607..c9d6e0eb6 100644 --- a/lib/src/l10n/generated/quill_localizations_sw.dart +++ b/lib/src/l10n/generated/quill_localizations_sw.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsSw extends FlutterQuillLocalizations { @override String get headerStyle => 'Mtindo wa Mada'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Orodha ya Nambari'; diff --git a/lib/src/l10n/generated/quill_localizations_tk.dart b/lib/src/l10n/generated/quill_localizations_tk.dart index 13e7b1d3c..ce9e3ca21 100644 --- a/lib/src/l10n/generated/quill_localizations_tk.dart +++ b/lib/src/l10n/generated/quill_localizations_tk.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsTk extends FlutterQuillLocalizations { @override String get headerStyle => 'Sözbaşy stili'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Sanly sanaw'; diff --git a/lib/src/l10n/generated/quill_localizations_tr.dart b/lib/src/l10n/generated/quill_localizations_tr.dart index e6c52e9a5..2c1e34d15 100644 --- a/lib/src/l10n/generated/quill_localizations_tr.dart +++ b/lib/src/l10n/generated/quill_localizations_tr.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsTr extends FlutterQuillLocalizations { @override String get headerStyle => 'Başlık Stili'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Numaralı Liste'; diff --git a/lib/src/l10n/generated/quill_localizations_uk.dart b/lib/src/l10n/generated/quill_localizations_uk.dart index f7a273a5a..8df86ed48 100644 --- a/lib/src/l10n/generated/quill_localizations_uk.dart +++ b/lib/src/l10n/generated/quill_localizations_uk.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsUk extends FlutterQuillLocalizations { @override String get headerStyle => 'Стиль заголовка'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Нумерований список'; diff --git a/lib/src/l10n/generated/quill_localizations_ur.dart b/lib/src/l10n/generated/quill_localizations_ur.dart index 79c665f56..ca0965399 100644 --- a/lib/src/l10n/generated/quill_localizations_ur.dart +++ b/lib/src/l10n/generated/quill_localizations_ur.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsUr extends FlutterQuillLocalizations { @override String get headerStyle => 'ہیڈر کا انداز'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'مرقم فہرست'; diff --git a/lib/src/l10n/generated/quill_localizations_vi.dart b/lib/src/l10n/generated/quill_localizations_vi.dart index 6f26695b0..ea53ab879 100644 --- a/lib/src/l10n/generated/quill_localizations_vi.dart +++ b/lib/src/l10n/generated/quill_localizations_vi.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsVi extends FlutterQuillLocalizations { @override String get headerStyle => 'Kiểu tiêu đề'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => 'Danh sách có số'; diff --git a/lib/src/l10n/generated/quill_localizations_zh.dart b/lib/src/l10n/generated/quill_localizations_zh.dart index 59ba0ce1e..8277c60b0 100644 --- a/lib/src/l10n/generated/quill_localizations_zh.dart +++ b/lib/src/l10n/generated/quill_localizations_zh.dart @@ -136,6 +136,18 @@ class FlutterQuillLocalizationsZh extends FlutterQuillLocalizations { @override String get headerStyle => '标题样式'; + @override + String get normal => 'Normal'; + + @override + String get heading1 => 'Heading 1'; + + @override + String get heading2 => 'Heading 2'; + + @override + String get heading3 => 'Heading 3'; + @override String get numberedList => '编号列表'; diff --git a/lib/src/l10n/quill_en.arb b/lib/src/l10n/quill_en.arb index 0d4d737f0..49bb30b4d 100644 --- a/lib/src/l10n/quill_en.arb +++ b/lib/src/l10n/quill_en.arb @@ -44,6 +44,10 @@ "justifyWinWidth": "Justify win width", "textDirection": "Text direction", "headerStyle": "Header style", + "normal": "Normal", + "heading1": "Heading 1", + "heading2": "Heading 2", + "heading3": "Heading 3", "numberedList": "Numbered list", "bulletList": "Bullet list", "checkedList": "Checked list", diff --git a/lib/src/l10n/untranslated.json b/lib/src/l10n/untranslated.json index d6c2ff3d2..d6a5a21ac 100644 --- a/lib/src/l10n/untranslated.json +++ b/lib/src/l10n/untranslated.json @@ -1,5 +1,9 @@ { "ar": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -9,6 +13,10 @@ ], "bg": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -18,6 +26,10 @@ ], "bn": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -27,6 +39,10 @@ ], "cs": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -36,6 +52,10 @@ ], "da": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -45,6 +65,10 @@ ], "de": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -54,6 +78,10 @@ ], "en_US": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -63,6 +91,10 @@ ], "es": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -72,6 +104,10 @@ ], "fa": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -81,6 +117,10 @@ ], "fr": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -90,6 +130,10 @@ ], "he": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -99,6 +143,10 @@ ], "hi": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -108,6 +156,10 @@ ], "id": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -117,6 +169,10 @@ ], "it": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -126,6 +182,10 @@ ], "ja": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -135,6 +195,10 @@ ], "ko": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -144,6 +208,10 @@ ], "ms": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -153,6 +221,10 @@ ], "nl": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -162,6 +234,10 @@ ], "no": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -171,6 +247,10 @@ ], "pl": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -180,6 +260,10 @@ ], "pt": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -189,6 +273,10 @@ ], "pt_BR": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -198,6 +286,10 @@ ], "ru": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -207,6 +299,10 @@ ], "sr": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -216,6 +312,10 @@ ], "sw": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -225,6 +325,10 @@ ], "tk": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -234,6 +338,10 @@ ], "tr": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -243,6 +351,10 @@ ], "uk": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -252,6 +364,10 @@ ], "ur": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -261,6 +377,10 @@ ], "vi": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -270,6 +390,10 @@ ], "zh": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -279,6 +403,10 @@ ], "zh_CN": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", @@ -288,6 +416,10 @@ ], "zh_HK": [ + "normal", + "heading1", + "heading2", + "heading3", "pickAPhotoFromYourGallery", "takeAPhotoUsingYourCamera", "pasteAPhotoUsingALink", diff --git a/lib/src/widgets/toolbar/base_toolbar.dart b/lib/src/widgets/toolbar/base_toolbar.dart index ba629f2c0..af412d35b 100644 --- a/lib/src/widgets/toolbar/base_toolbar.dart +++ b/lib/src/widgets/toolbar/base_toolbar.dart @@ -20,7 +20,7 @@ export 'buttons/link_style_button.dart'; export 'buttons/quill_icon_button.dart'; export 'buttons/search/search_button.dart'; export 'buttons/select_alignment_button.dart'; -export 'buttons/select_header_style_button.dart'; +export 'buttons/select_header_style_buttons.dart'; export 'buttons/toggle_check_list_button.dart'; export 'buttons/toggle_style_button.dart'; diff --git a/lib/src/widgets/toolbar/buttons/color/color_button.dart b/lib/src/widgets/toolbar/buttons/color/color_button.dart index 8454290a5..f5b2e032b 100644 --- a/lib/src/widgets/toolbar/buttons/color/color_button.dart +++ b/lib/src/widgets/toolbar/buttons/color/color_button.dart @@ -193,16 +193,13 @@ class QuillToolbarColorButtonState extends State { ); } - return QuillToolbarIconButton( + return IconButton( tooltip: tooltip, - size: iconSize * iconButtonFactor, + iconSize: iconSize * iconButtonFactor, icon: Icon(iconData, size: iconSize, color: widget.isBackground ? iconColorBackground : iconColor), - // fillColor: widget.isBackground ? fillColorBackground : fillColor, - isFilled: false, onPressed: _showColorPicker, - afterPressed: afterButtonPressed, ); } diff --git a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart index 791b81320..0f913204c 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart @@ -1,17 +1,19 @@ -import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; -import '../../../../extensions.dart'; -import '../../../extensions/quill_provider.dart'; -import '../../../l10n/extensions/localizations.dart'; +import '../../../../translations.dart'; +import '../../../models/config/toolbar/buttons/select_header_style.dart'; import '../../../models/documents/attribute.dart'; -import '../../../models/documents/style.dart'; -import '../../../models/themes/quill_icon_theme.dart'; import '../../controller.dart'; -import '../base_toolbar.dart'; -class QuillToolbarSelectHeaderStyleButtons extends StatefulWidget { - const QuillToolbarSelectHeaderStyleButtons({ +enum QuillToolbarSelectHeaderStyleButtonOptions { + normal, + headingOne, + headingTwo, + headingThree, +} + +class QuillToolbarSelectHeaderStyleButton extends StatefulWidget { + const QuillToolbarSelectHeaderStyleButton({ required this.controller, required this.options, super.key, @@ -21,215 +23,93 @@ class QuillToolbarSelectHeaderStyleButtons extends StatefulWidget { final QuillToolbarSelectHeaderStyleButtonsOptions options; @override - QuillToolbarSelectHeaderStyleButtonsState createState() => - QuillToolbarSelectHeaderStyleButtonsState(); + State createState() => + _QuillToolbarSelectHeaderStyleButtonState(); } -class QuillToolbarSelectHeaderStyleButtonsState - extends State { - Attribute? _selectedAttribute; - - Style get _selectionStyle => controller.getSelectionStyle(); - - final _valueToText = { - Attribute.header: 'N', - Attribute.h1: 'H1', - Attribute.h2: 'H2', - Attribute.h3: 'H3', - }; - +class _QuillToolbarSelectHeaderStyleButtonState + extends State { + var _selectedItem = QuillToolbarSelectHeaderStyleButtonOptions.normal; @override void initState() { super.initState(); - setState(() { - _selectedAttribute = _getHeaderValue(); - }); - controller.addListener(_didChangeEditingValue); - } - - QuillToolbarSelectHeaderStyleButtonsOptions get options { - return widget.options; - } - - QuillController get controller { - return widget.controller; - } - - double get iconSize { - final baseFontSize = baseButtonExtraOptions.globalIconSize; - final iconSize = options.iconSize; - 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; - } - - QuillIconTheme? get iconTheme { - return options.iconTheme ?? baseButtonExtraOptions.iconTheme; - } - - QuillToolbarBaseButtonOptions get baseButtonExtraOptions { - return context.requireQuillToolbarBaseButtonOptions; - } - - String get tooltip { - return options.tooltip ?? - baseButtonExtraOptions.tooltip ?? - context.loc.headerStyle; - } - - Axis get axis { - return options.axis ?? - context.quillToolbarConfigurations?.axis ?? - context.quillBaseToolbarConfigurations?.axis ?? - (throw ArgumentError( - 'There is no default value for the Axis of the toolbar')); - } - - void _sharedOnPressed(Attribute attribute) { - final attribute0 = - _selectedAttribute == attribute ? Attribute.header : attribute; - controller.formatSelection(attribute0); - afterButtonPressed?.call(); - } - - List get _attrbuites { - return options.attributes ?? - const [ - Attribute.header, - Attribute.h1, - Attribute.h2, - Attribute.h3, - ]; - } - - @override - Widget build(BuildContext context) { - assert( - _attrbuites.every( - (element) => _valueToText.keys.contains(element), - ), - 'All attributes must be one of them: header, h1, h2 or h3', - ); - - final style = TextStyle( - fontWeight: FontWeight.w600, - fontSize: iconSize * 0.7, - ); - - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions.childBuilder; - - final children = _attrbuites.map((attribute) { - if (childBuilder != null) { - return childBuilder( - QuillToolbarSelectHeaderStyleButtonsOptions( - afterButtonPressed: afterButtonPressed, - attributes: _attrbuites, - axis: axis, - iconSize: iconSize, - iconButtonFactor: iconButtonFactor, - iconTheme: iconTheme, - tooltip: tooltip, - ), - QuillToolbarSelectHeaderStyleButtonExtraOptions( - controller: controller, - context: context, - onPressed: () => _sharedOnPressed(attribute), - ), - ); - } - final theme = Theme.of(context); - final isSelected = _selectedAttribute == attribute; - return Padding( - padding: const EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0), - child: ConstrainedBox( - constraints: BoxConstraints.tightFor( - width: iconSize * iconButtonFactor, - height: iconSize * iconButtonFactor, - ), - child: UtilityWidgets.maybeTooltip( - message: tooltip, - child: RawMaterialButton( - hoverElevation: 0, - highlightElevation: 0, - elevation: 0, - visualDensity: VisualDensity.compact, - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(iconTheme?.borderRadius ?? 2)), - fillColor: isSelected - ? (iconTheme?.iconSelectedFillColor ?? theme.primaryColor) - : (iconTheme?.iconUnselectedFillColor ?? theme.canvasColor), - onPressed: () => _sharedOnPressed(attribute), - child: Text( - _valueToText[attribute] ?? - (throw ArgumentError.notNull( - 'attrbuite', - )), - style: style.copyWith( - color: isSelected - ? (iconTheme?.iconSelectedColor ?? - theme.primaryIconTheme.color) - : (iconTheme?.iconUnselectedColor ?? - theme.iconTheme.color), - ), - ), - ), - ), - ), - ); - }).toList(); - - return axis == Axis.horizontal - ? Row( - mainAxisSize: MainAxisSize.min, - children: children, - ) - : Column( - mainAxisSize: MainAxisSize.min, - children: children, - ); + widget.controller.addListener(_didChangeEditingValue); } void _didChangeEditingValue() { setState(() { - _selectedAttribute = _getHeaderValue(); + _selectedItem = _getOptionsItemByAttribute(_getHeaderValue()); }); } Attribute _getHeaderValue() { - final attr = controller.toolbarButtonToggler[Attribute.header.key]; + final attr = widget.controller.toolbarButtonToggler[Attribute.header.key]; if (attr != null) { // checkbox tapping causes controller.selection to go to offset 0 - controller.toolbarButtonToggler.remove(Attribute.header.key); + widget.controller.toolbarButtonToggler.remove(Attribute.header.key); return attr; } - return _selectionStyle.attributes[Attribute.header.key] ?? Attribute.header; - } - - @override - void didUpdateWidget( - covariant QuillToolbarSelectHeaderStyleButtons oldWidget) { - super.didUpdateWidget(oldWidget); - if (oldWidget.controller != controller) { - oldWidget.controller.removeListener(_didChangeEditingValue); - controller.addListener(_didChangeEditingValue); - _selectedAttribute = _getHeaderValue(); - } + return widget.controller + .getSelectionStyle() + .attributes[Attribute.header.key] ?? + Attribute.header; + } + + String _label(QuillToolbarSelectHeaderStyleButtonOptions value) { + final label = switch (value) { + QuillToolbarSelectHeaderStyleButtonOptions.normal => context.loc.normal, + QuillToolbarSelectHeaderStyleButtonOptions.headingOne => + context.loc.heading1, + QuillToolbarSelectHeaderStyleButtonOptions.headingTwo => + context.loc.heading2, + QuillToolbarSelectHeaderStyleButtonOptions.headingThree => + context.loc.heading3, + }; + return label; + } + + Attribute? getAttributeByOptionsItem( + QuillToolbarSelectHeaderStyleButtonOptions option) { + return switch (option) { + QuillToolbarSelectHeaderStyleButtonOptions.normal => Attribute.header, + QuillToolbarSelectHeaderStyleButtonOptions.headingOne => Attribute.h1, + QuillToolbarSelectHeaderStyleButtonOptions.headingTwo => Attribute.h2, + QuillToolbarSelectHeaderStyleButtonOptions.headingThree => Attribute.h3, + }; + } + + QuillToolbarSelectHeaderStyleButtonOptions _getOptionsItemByAttribute( + Attribute? attribute) { + return switch (attribute) { + Attribute.h1 => QuillToolbarSelectHeaderStyleButtonOptions.headingOne, + Attribute.h2 => QuillToolbarSelectHeaderStyleButtonOptions.headingTwo, + Attribute.h2 => QuillToolbarSelectHeaderStyleButtonOptions.headingThree, + Attribute() => QuillToolbarSelectHeaderStyleButtonOptions.normal, + null => QuillToolbarSelectHeaderStyleButtonOptions.normal, + }; } @override - void dispose() { - controller.removeListener(_didChangeEditingValue); - super.dispose(); + Widget build(BuildContext context) { + return DropdownButton( + value: _selectedItem, + items: QuillToolbarSelectHeaderStyleButtonOptions.values + .map( + (e) => DropdownMenuItem( + value: e, + child: Text(_label(e)), + onTap: () { + widget.controller.formatSelection(getAttributeByOptionsItem(e)); + }, + ), + ) + .toList(), + onChanged: (newItem) { + if (newItem == null) { + return; + } + setState(() => _selectedItem = newItem); + }, + ); } } diff --git a/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart b/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart new file mode 100644 index 000000000..791b81320 --- /dev/null +++ b/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart @@ -0,0 +1,235 @@ +import 'package:flutter/foundation.dart' show kIsWeb; +import 'package:flutter/material.dart'; + +import '../../../../extensions.dart'; +import '../../../extensions/quill_provider.dart'; +import '../../../l10n/extensions/localizations.dart'; +import '../../../models/documents/attribute.dart'; +import '../../../models/documents/style.dart'; +import '../../../models/themes/quill_icon_theme.dart'; +import '../../controller.dart'; +import '../base_toolbar.dart'; + +class QuillToolbarSelectHeaderStyleButtons extends StatefulWidget { + const QuillToolbarSelectHeaderStyleButtons({ + required this.controller, + required this.options, + super.key, + }); + + final QuillController controller; + final QuillToolbarSelectHeaderStyleButtonsOptions options; + + @override + QuillToolbarSelectHeaderStyleButtonsState createState() => + QuillToolbarSelectHeaderStyleButtonsState(); +} + +class QuillToolbarSelectHeaderStyleButtonsState + extends State { + Attribute? _selectedAttribute; + + Style get _selectionStyle => controller.getSelectionStyle(); + + final _valueToText = { + Attribute.header: 'N', + Attribute.h1: 'H1', + Attribute.h2: 'H2', + Attribute.h3: 'H3', + }; + + @override + void initState() { + super.initState(); + setState(() { + _selectedAttribute = _getHeaderValue(); + }); + controller.addListener(_didChangeEditingValue); + } + + QuillToolbarSelectHeaderStyleButtonsOptions get options { + return widget.options; + } + + QuillController get controller { + return widget.controller; + } + + double get iconSize { + final baseFontSize = baseButtonExtraOptions.globalIconSize; + final iconSize = options.iconSize; + 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; + } + + QuillIconTheme? get iconTheme { + return options.iconTheme ?? baseButtonExtraOptions.iconTheme; + } + + QuillToolbarBaseButtonOptions get baseButtonExtraOptions { + return context.requireQuillToolbarBaseButtonOptions; + } + + String get tooltip { + return options.tooltip ?? + baseButtonExtraOptions.tooltip ?? + context.loc.headerStyle; + } + + Axis get axis { + return options.axis ?? + context.quillToolbarConfigurations?.axis ?? + context.quillBaseToolbarConfigurations?.axis ?? + (throw ArgumentError( + 'There is no default value for the Axis of the toolbar')); + } + + void _sharedOnPressed(Attribute attribute) { + final attribute0 = + _selectedAttribute == attribute ? Attribute.header : attribute; + controller.formatSelection(attribute0); + afterButtonPressed?.call(); + } + + List get _attrbuites { + return options.attributes ?? + const [ + Attribute.header, + Attribute.h1, + Attribute.h2, + Attribute.h3, + ]; + } + + @override + Widget build(BuildContext context) { + assert( + _attrbuites.every( + (element) => _valueToText.keys.contains(element), + ), + 'All attributes must be one of them: header, h1, h2 or h3', + ); + + final style = TextStyle( + fontWeight: FontWeight.w600, + fontSize: iconSize * 0.7, + ); + + final childBuilder = + options.childBuilder ?? baseButtonExtraOptions.childBuilder; + + final children = _attrbuites.map((attribute) { + if (childBuilder != null) { + return childBuilder( + QuillToolbarSelectHeaderStyleButtonsOptions( + afterButtonPressed: afterButtonPressed, + attributes: _attrbuites, + axis: axis, + iconSize: iconSize, + iconButtonFactor: iconButtonFactor, + iconTheme: iconTheme, + tooltip: tooltip, + ), + QuillToolbarSelectHeaderStyleButtonExtraOptions( + controller: controller, + context: context, + onPressed: () => _sharedOnPressed(attribute), + ), + ); + } + final theme = Theme.of(context); + final isSelected = _selectedAttribute == attribute; + return Padding( + padding: const EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0), + child: ConstrainedBox( + constraints: BoxConstraints.tightFor( + width: iconSize * iconButtonFactor, + height: iconSize * iconButtonFactor, + ), + child: UtilityWidgets.maybeTooltip( + message: tooltip, + child: RawMaterialButton( + hoverElevation: 0, + highlightElevation: 0, + elevation: 0, + visualDensity: VisualDensity.compact, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(iconTheme?.borderRadius ?? 2)), + fillColor: isSelected + ? (iconTheme?.iconSelectedFillColor ?? theme.primaryColor) + : (iconTheme?.iconUnselectedFillColor ?? theme.canvasColor), + onPressed: () => _sharedOnPressed(attribute), + child: Text( + _valueToText[attribute] ?? + (throw ArgumentError.notNull( + 'attrbuite', + )), + style: style.copyWith( + color: isSelected + ? (iconTheme?.iconSelectedColor ?? + theme.primaryIconTheme.color) + : (iconTheme?.iconUnselectedColor ?? + theme.iconTheme.color), + ), + ), + ), + ), + ), + ); + }).toList(); + + return axis == Axis.horizontal + ? Row( + mainAxisSize: MainAxisSize.min, + children: children, + ) + : Column( + mainAxisSize: MainAxisSize.min, + children: children, + ); + } + + void _didChangeEditingValue() { + setState(() { + _selectedAttribute = _getHeaderValue(); + }); + } + + Attribute _getHeaderValue() { + final attr = controller.toolbarButtonToggler[Attribute.header.key]; + if (attr != null) { + // checkbox tapping causes controller.selection to go to offset 0 + controller.toolbarButtonToggler.remove(Attribute.header.key); + return attr; + } + return _selectionStyle.attributes[Attribute.header.key] ?? Attribute.header; + } + + @override + void didUpdateWidget( + covariant QuillToolbarSelectHeaderStyleButtons oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.controller != controller) { + oldWidget.controller.removeListener(_didChangeEditingValue); + controller.addListener(_didChangeEditingValue); + _selectedAttribute = _getHeaderValue(); + } + } + + @override + void dispose() { + controller.removeListener(_didChangeEditingValue); + super.dispose(); + } +} diff --git a/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart b/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart index 52ee2f1d9..01ec7f92c 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart @@ -9,7 +9,7 @@ import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../../utils/widgets.dart'; import '../../controller.dart'; -import 'toggle_style.dart'; +import 'toggle_style_button.dart'; class QuillToolbarToggleCheckListButton extends StatefulWidget { const QuillToolbarToggleCheckListButton({ diff --git a/lib/src/widgets/toolbar/toolbar.dart b/lib/src/widgets/toolbar/toolbar.dart index 8d9fc9c5b..b4c9a7d33 100644 --- a/lib/src/widgets/toolbar/toolbar.dart +++ b/lib/src/widgets/toolbar/toolbar.dart @@ -6,6 +6,7 @@ import '../../models/config/toolbar/base_toolbar_configurations.dart'; import '../../models/documents/attribute.dart'; import '../utils/provider.dart'; import 'base_toolbar.dart'; +import 'buttons/select_header_style_button.dart'; class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { const QuillToolbar({ @@ -286,7 +287,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { space: configurations.sectionDividerSpace, ), if (configurations.showHeaderStyle) ...[ - QuillToolbarSelectHeaderStyleButtons( + QuillToolbarSelectHeaderStyleButton( controller: toolbarConfigurations .buttonOptions.selectHeaderStyleButtons.controller ?? globalController, From 4b4c1489465f37595f5076b9ebe6f6bc8cffd5fe Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 11:09:48 +0300 Subject: [PATCH 23/86] Organize files --- CHANGELOG.md | 5 + .../lib/presentation/quill/quill_toolbar.dart | 8 +- lib/flutter_quill.dart | 15 +- lib/src/extensions/quill_provider.dart | 16 +- .../models/config/editor/configurations.dart | 10 +- .../models/config/quill_configurations.dart | 4 +- .../config/quill_shared_configurations.dart | 5 +- .../config/raw_editor/configurations.dart | 10 +- .../toolbar/base_toolbar_configurations.dart | 33 -- .../models/config/toolbar/buttons/color.dart | 2 +- .../config/toolbar/buttons/font_family.dart | 2 +- .../config/toolbar/buttons/font_size.dart | 4 +- .../toolbar/buttons/select_header_style.dart | 2 +- .../simple_toolbar_configurations.dart | 317 ++++++++++++++++++ .../toolbar/toolbar_configurations.dart | 312 +---------------- lib/src/models/documents/document.dart | 2 +- lib/src/models/documents/nodes/container.dart | 2 +- lib/src/models/documents/nodes/leaf.dart | 2 +- lib/src/models/documents/nodes/line.dart | 2 +- lib/src/models/documents/nodes/node.dart | 2 +- lib/src/utils/embeds.dart | 2 +- lib/src/widgets/editor/editor.dart | 12 +- lib/src/widgets/{ => others}/box.dart | 2 +- lib/src/widgets/{ => others}/controller.dart | 20 +- lib/src/widgets/{ => others}/cursor.dart | 2 +- .../widgets/{ => others}/default_styles.dart | 10 +- lib/src/widgets/{ => others}/delegate.dart | 8 +- lib/src/widgets/{ => others}/embeds.dart | 8 +- .../widgets/{ => others}/float_cursor.dart | 0 .../{ => others}/keyboard_listener.dart | 0 lib/src/widgets/{ => others}/link.dart | 6 +- lib/src/widgets/{ => others}/proxy.dart | 0 lib/src/widgets/{ => others}/text_block.dart | 20 +- lib/src/widgets/{ => others}/text_line.dart | 24 +- .../widgets/{ => others}/text_selection.dart | 4 +- .../quill_single_child_scroll_view.dart | 0 .../raw_editor/raw_editor_render_object.dart | 2 +- .../widgets/raw_editor/raw_editor_state.dart | 20 +- .../widgets/style_widgets/number_point.dart | 2 +- lib/src/widgets/toolbar/base_toolbar.dart | 12 +- .../toolbar/buttons/clear_format_button.dart | 2 +- .../toolbar/buttons/color/color_button.dart | 2 +- .../toolbar/buttons/custom_button_button.dart | 2 +- .../toolbar/buttons/font_family_button.dart | 2 +- .../toolbar/buttons/font_size_button.dart | 2 +- .../toolbar/buttons/history_button.dart | 2 +- .../toolbar/buttons/indent_button.dart | 2 +- .../toolbar/buttons/link_style2_button.dart | 4 +- .../toolbar/buttons/link_style_button.dart | 4 +- .../toolbar/buttons/search/search_button.dart | 2 +- .../toolbar/buttons/search/search_dialog.dart | 2 +- .../buttons/select_alignment_button.dart | 2 +- .../buttons/select_header_style_button.dart | 2 +- .../buttons/select_header_style_buttons.dart | 2 +- .../buttons/toggle_check_list_button.dart | 2 +- .../toolbar/buttons/toggle_style_button.dart | 2 +- .../{toolbar.dart => simple_toolbar.dart} | 73 ++-- lib/src/widgets/utils/provider.dart | 10 +- test/bug_fix_test.dart | 6 +- version.dart | 2 +- 60 files changed, 522 insertions(+), 514 deletions(-) delete mode 100644 lib/src/models/config/toolbar/base_toolbar_configurations.dart create mode 100644 lib/src/models/config/toolbar/simple_toolbar_configurations.dart rename lib/src/widgets/{ => others}/box.dart (98%) rename lib/src/widgets/{ => others}/controller.dart (96%) rename lib/src/widgets/{ => others}/cursor.dart (99%) rename lib/src/widgets/{ => others}/default_styles.dart (97%) rename lib/src/widgets/{ => others}/delegate.dart (98%) rename lib/src/widgets/{ => others}/embeds.dart (77%) rename lib/src/widgets/{ => others}/float_cursor.dart (100%) rename lib/src/widgets/{ => others}/keyboard_listener.dart (100%) rename lib/src/widgets/{ => others}/link.dart (97%) rename lib/src/widgets/{ => others}/proxy.dart (100%) rename lib/src/widgets/{ => others}/text_block.dart (97%) rename lib/src/widgets/{ => others}/text_line.dart (98%) rename lib/src/widgets/{ => others}/text_selection.dart (99%) rename lib/src/widgets/{ => raw_editor}/quill_single_child_scroll_view.dart (100%) rename lib/src/widgets/toolbar/{toolbar.dart => simple_toolbar.dart} (98%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60b64f0f5..4363db5a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-3 +* Breaking Changes: + * Rename `QuillToolbar` to `QuillSimpleToolbar` + * Rename `QuillBaseToolbar` to `QuillToolbar` + ## 9.0.0-dev-2 * An attemp to fix CI automated publishing diff --git a/example/lib/presentation/quill/quill_toolbar.dart b/example/lib/presentation/quill/quill_toolbar.dart index 0a9174c6b..bf79b5da3 100644 --- a/example/lib/presentation/quill/quill_toolbar.dart +++ b/example/lib/presentation/quill/quill_toolbar.dart @@ -100,8 +100,8 @@ class MyQuillToolbar extends StatelessWidget { if (state.useCustomQuillToolbar) { // For more info // https://github.com/singerdmx/flutter-quill/blob/master/doc/custom_toolbar.md - return QuillBaseToolbar( - configurations: QuillBaseToolbarConfigurations( + return QuillToolbar( + configurations: QuillToolbarConfigurations( toolbarSize: 15 * 2, multiRowsDisplay: false, buttonOptions: const QuillToolbarButtonOptions( @@ -224,8 +224,8 @@ class MyQuillToolbar extends StatelessWidget { ), ); } - return QuillToolbar( - configurations: QuillToolbarConfigurations( + return QuillSimpleToolbar( + configurations: QuillSimpleToolbarConfigurations( controller: controller, showAlignmentButtons: true, buttonOptions: QuillToolbarButtonOptions( diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index 2c3170615..6a98667f8 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -3,7 +3,7 @@ library flutter_quill; export 'src/extensions/quill_provider.dart'; export 'src/models/config/quill_configurations.dart'; export 'src/models/config/raw_editor/configurations.dart'; -export 'src/models/config/toolbar/base_toolbar_configurations.dart'; +export 'src/models/config/toolbar/toolbar_configurations.dart'; export 'src/models/documents/attribute.dart'; export 'src/models/documents/document.dart'; export 'src/models/documents/nodes/block.dart'; @@ -22,15 +22,16 @@ export 'src/models/structs/vertical_spacing.dart'; export 'src/models/themes/quill_dialog_theme.dart'; export 'src/models/themes/quill_icon_theme.dart'; export 'src/utils/embeds.dart'; -export 'src/widgets/controller.dart'; -export 'src/widgets/cursor.dart'; -export 'src/widgets/default_styles.dart'; +export 'src/widgets/others/controller.dart'; +export 'src/widgets/others/cursor.dart'; +export 'src/widgets/others/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/others/embeds.dart'; +export 'src/widgets/others/link.dart' + show LinkActionPickerDelegate, LinkMenuAction; export 'src/widgets/raw_editor/raw_editor.dart'; export 'src/widgets/raw_editor/raw_editor_state.dart'; export 'src/widgets/style_widgets/style_widgets.dart'; export 'src/widgets/toolbar/base_toolbar.dart'; -export 'src/widgets/toolbar/toolbar.dart'; +export 'src/widgets/toolbar/simple_toolbar.dart'; export 'src/widgets/utils/provider.dart'; diff --git a/lib/src/extensions/quill_provider.dart b/lib/src/extensions/quill_provider.dart index 29d251afd..e6fbc1650 100644 --- a/lib/src/extensions/quill_provider.dart +++ b/lib/src/extensions/quill_provider.dart @@ -68,39 +68,39 @@ extension QuillProviderExt on BuildContext { return QuillEditorProvider.of(this)?.editorConfigurations; } - /// return [QuillToolbarConfigurations] as not null . Since the quill + /// return [QuillSimpleToolbarConfigurations] as not null . Since the quill /// toolbar configurations is in the [QuillToolbarProvider] /// then we need to get the /// provider widget first and then we will return toolbar configurations /// throw exception if [QuillProvider] is not in the widget tree - QuillToolbarConfigurations get requireQuillToolbarConfigurations { + QuillSimpleToolbarConfigurations get requireQuillToolbarConfigurations { return QuillToolbarProvider.ofNotNull(this).toolbarConfigurations; } - /// return nullable [QuillToolbarConfigurations]. Since the quill + /// return nullable [QuillSimpleToolbarConfigurations]. Since the quill /// toolbar configurations is in the [QuillToolbarProvider] /// then we need to get the /// provider widget first and then we will return toolbar configurations /// don't throw exception if [QuillProvider] is not in the widget tree - QuillToolbarConfigurations? get quillToolbarConfigurations { + QuillSimpleToolbarConfigurations? get quillToolbarConfigurations { return QuillToolbarProvider.of(this)?.toolbarConfigurations; } - /// return [QuillBaseToolbarConfigurations] as not null . Since the quill + /// return [QuillToolbarConfigurations] as not null . Since the quill /// toolbar configurations is in the [QuillBaseToolbarProvider] /// then we need to get the /// provider widget first and then we will return toolbar configurations /// throw exception if [QuillBaseToolbarProvider] is not in the widget tree - QuillBaseToolbarConfigurations get requireQuillBaseToolbarConfigurations { + QuillToolbarConfigurations get requireQuillBaseToolbarConfigurations { return QuillBaseToolbarProvider.ofNotNull(this).toolbarConfigurations; } - /// return nullable [QuillBaseToolbarConfigurations]. Since the quill + /// return nullable [QuillToolbarConfigurations]. Since the quill /// toolbar configurations is in the [QuillBaseToolbarProvider] /// then we need to get the /// provider widget first and then we will return toolbar configurations /// don't throw exception if [QuillBaseToolbarProvider] is not in the widget tree - QuillBaseToolbarConfigurations? get quillBaseToolbarConfigurations { + QuillToolbarConfigurations? get quillBaseToolbarConfigurations { return QuillBaseToolbarProvider.of(this)?.toolbarConfigurations; } diff --git a/lib/src/models/config/editor/configurations.dart b/lib/src/models/config/editor/configurations.dart index a08ff076f..23d80e116 100644 --- a/lib/src/models/config/editor/configurations.dart +++ b/lib/src/models/config/editor/configurations.dart @@ -6,13 +6,13 @@ 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/others/controller.dart'; +import '../../../widgets/others/default_styles.dart'; +import '../../../widgets/others/delegate.dart'; import '../../../widgets/editor/editor.dart'; import '../../../widgets/editor/editor_builder.dart'; -import '../../../widgets/embeds.dart'; -import '../../../widgets/link.dart'; +import '../../../widgets/others/embeds.dart'; +import '../../../widgets/others/link.dart'; import '../../../widgets/raw_editor/raw_editor.dart'; import '../../themes/quill_dialog_theme.dart'; import 'element_options.dart'; diff --git a/lib/src/models/config/quill_configurations.dart b/lib/src/models/config/quill_configurations.dart index b18f63963..60b30aaf8 100644 --- a/lib/src/models/config/quill_configurations.dart +++ b/lib/src/models/config/quill_configurations.dart @@ -5,7 +5,7 @@ import '../../../flutter_quill.dart'; export './editor/configurations.dart'; export 'quill_shared_configurations.dart'; -export 'toolbar/toolbar_configurations.dart'; +export 'toolbar/simple_toolbar_configurations.dart'; @immutable class QuillConfigurations extends Equatable { @@ -22,7 +22,7 @@ class QuillConfigurations extends Equatable { // final QuillController controller; /// The shared configurations between [QuillEditorConfigurations] and - /// [QuillToolbarConfigurations] so we don't duplicate things + /// [QuillSimpleToolbarConfigurations] so we don't duplicate things final QuillSharedConfigurations sharedConfigurations; @override diff --git a/lib/src/models/config/quill_shared_configurations.dart b/lib/src/models/config/quill_shared_configurations.dart index 2f62ea69f..ddf5f7763 100644 --- a/lib/src/models/config/quill_shared_configurations.dart +++ b/lib/src/models/config/quill_shared_configurations.dart @@ -3,12 +3,13 @@ import 'package:flutter/material.dart' show Color, Colors, Locale; import '../themes/quill_dialog_theme.dart'; import './editor/configurations.dart' show QuillEditorConfigurations; -import 'toolbar/toolbar_configurations.dart' show QuillToolbarConfigurations; +import 'toolbar/simple_toolbar_configurations.dart' + show QuillSimpleToolbarConfigurations; export './others/animations.dart'; /// The shared configurations between [QuillEditorConfigurations] and -/// [QuillToolbarConfigurations] so we don't duplicate things +/// [QuillSimpleToolbarConfigurations] so we don't duplicate things class QuillSharedConfigurations extends Equatable { const QuillSharedConfigurations({ this.dialogBarrierColor = Colors.black54, diff --git a/lib/src/models/config/raw_editor/configurations.dart b/lib/src/models/config/raw_editor/configurations.dart index 9d486e912..1ddb9973b 100644 --- a/lib/src/models/config/raw_editor/configurations.dart +++ b/lib/src/models/config/raw_editor/configurations.dart @@ -25,11 +25,11 @@ import 'package:flutter/widgets.dart' Widget; import 'package:meta/meta.dart' show immutable; -import '../../../widgets/controller.dart'; -import '../../../widgets/cursor.dart'; -import '../../../widgets/default_styles.dart'; -import '../../../widgets/delegate.dart'; -import '../../../widgets/link.dart'; +import '../../../widgets/others/controller.dart'; +import '../../../widgets/others/cursor.dart'; +import '../../../widgets/others/default_styles.dart'; +import '../../../widgets/others/delegate.dart'; +import '../../../widgets/others/link.dart'; import '../../../widgets/raw_editor/raw_editor.dart'; import '../../../widgets/raw_editor/raw_editor_state.dart'; import '../../themes/quill_dialog_theme.dart'; diff --git a/lib/src/models/config/toolbar/base_toolbar_configurations.dart b/lib/src/models/config/toolbar/base_toolbar_configurations.dart deleted file mode 100644 index 3450a9ded..000000000 --- a/lib/src/models/config/toolbar/base_toolbar_configurations.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:flutter/widgets.dart' - show Axis, WrapAlignment, WrapCrossAlignment, immutable; - -import '../../../widgets/toolbar/base_toolbar.dart'; -import 'toolbar_shared_configurations.dart'; - -@immutable -class QuillBaseToolbarConfigurations extends QuillSharedToolbarProperties { - const QuillBaseToolbarConfigurations({ - required this.childrenBuilder, - super.axis = Axis.horizontal, - super.toolbarSize = kDefaultIconSize * 2, - super.toolbarSectionSpacing = kToolbarSectionSpacing, - super.toolbarIconAlignment = WrapAlignment.center, - super.toolbarIconCrossAlignment = WrapCrossAlignment.center, - super.color, - super.customButtons = const [], - super.sectionDividerColor, - super.sectionDividerSpace, - super.linkDialogAction, - super.multiRowsDisplay = true, - super.decoration, - - /// Note this only used when you using the quill toolbar buttons like - /// `QuillToolbarHistoryButton` inside it - super.buttonOptions = const QuillToolbarButtonOptions(), - }); - - final QuillBaseToolbarChildrenBuilder childrenBuilder; - - @override - List get props => []; -} diff --git a/lib/src/models/config/toolbar/buttons/color.dart b/lib/src/models/config/toolbar/buttons/color.dart index 7c722d98e..edb751424 100644 --- a/lib/src/models/config/toolbar/buttons/color.dart +++ b/lib/src/models/config/toolbar/buttons/color.dart @@ -1,6 +1,6 @@ import 'package:flutter/widgets.dart' show Color; -import '../../../../widgets/controller.dart'; +import '../../../../widgets/others/controller.dart'; import '../../quill_shared_configurations.dart' show QuillSharedConfigurations; import 'base.dart'; diff --git a/lib/src/models/config/toolbar/buttons/font_family.dart b/lib/src/models/config/toolbar/buttons/font_family.dart index 41319bbb9..5674232cf 100644 --- a/lib/src/models/config/toolbar/buttons/font_family.dart +++ b/lib/src/models/config/toolbar/buttons/font_family.dart @@ -61,7 +61,7 @@ class QuillToolbarFontFamilyButtonOptions extends QuillToolbarBaseButtonOptions< final double hoverElevation; final double highlightElevation; - /// By default it will be [fontFamilyValues] from [QuillToolbarConfigurations] + /// By default it will be [fontFamilyValues] from [QuillSimpleToolbarConfigurations] /// You can override this if you want final Map? rawItemsMap; final ValueChanged? onSelected; diff --git a/lib/src/models/config/toolbar/buttons/font_size.dart b/lib/src/models/config/toolbar/buttons/font_size.dart index 45464ecf8..5cebf9f6d 100644 --- a/lib/src/models/config/toolbar/buttons/font_size.dart +++ b/lib/src/models/config/toolbar/buttons/font_size.dart @@ -6,7 +6,7 @@ import 'package:flutter/material.dart' import 'package:flutter/widgets.dart' show Color, EdgeInsets, EdgeInsetsGeometry, TextOverflow, TextStyle; -import '../../../../widgets/controller.dart'; +import '../../../../widgets/others/controller.dart'; import '../../../documents/attribute.dart'; import '../../../themes/quill_icon_theme.dart'; import '../../quill_configurations.dart'; @@ -58,7 +58,7 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions< final double hoverElevation; final double highlightElevation; - /// By default it will be [fontSizesValues] from [QuillToolbarConfigurations] + /// By default it will be [fontSizesValues] from [QuillSimpleToolbarConfigurations] /// You can override this if you want final Map? rawItemsMap; final ValueChanged? onSelected; 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 6e70c9eb6..975b47702 100644 --- a/lib/src/models/config/toolbar/buttons/select_header_style.dart +++ b/lib/src/models/config/toolbar/buttons/select_header_style.dart @@ -37,7 +37,7 @@ class QuillToolbarSelectHeaderStyleButtonsOptions /// ] final List? attributes; - /// By default we will the toolbar axis from [QuillToolbarConfigurations] + /// By default we will the toolbar axis from [QuillSimpleToolbarConfigurations] final Axis? axis; final double? iconSize; final double? iconButtonFactor; diff --git a/lib/src/models/config/toolbar/simple_toolbar_configurations.dart b/lib/src/models/config/toolbar/simple_toolbar_configurations.dart new file mode 100644 index 000000000..e946a4f09 --- /dev/null +++ b/lib/src/models/config/toolbar/simple_toolbar_configurations.dart @@ -0,0 +1,317 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/foundation.dart' show immutable; +import 'package:flutter/widgets.dart' + show Axis, Widget, WrapAlignment, WrapCrossAlignment; + +import '../../../widgets/others/controller.dart'; +import '../../../widgets/others/embeds.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'; +import 'buttons/indent.dart'; +import 'buttons/link_style.dart'; +import 'buttons/link_style2.dart'; +import 'buttons/search.dart'; +import 'buttons/select_alignment.dart'; +import 'buttons/select_header_style.dart'; +import 'buttons/toggle_check_list.dart'; +import 'buttons/toggle_style.dart'; +import 'toolbar_shared_configurations.dart'; + +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'; +export './buttons/indent.dart'; +export './buttons/link_style.dart'; +export './buttons/link_style2.dart'; +export './buttons/search.dart'; +export './buttons/select_alignment.dart'; +export './buttons/select_header_style.dart'; +export './buttons/toggle_check_list.dart'; +export './buttons/toggle_style.dart'; + +/// The default size of the icon of a button. +const double kDefaultIconSize = 18; + +/// The default size for the toolbar (width, height) +const double defaultToolbarSize = kDefaultIconSize * 2; + +/// The factor of how much larger the button is in relation to the icon. +const double kIconButtonFactor = 1.77; + +/// The horizontal margin between the contents of each toolbar section. +const double kToolbarSectionSpacing = 4; + +enum LinkStyleType { + /// Defines the original [QuillToolbarLinkStyleButton]. + original, + + /// Defines the alternative [QuillToolbarLinkStyleButton2]. + alternative; + + bool get isOriginal => this == LinkStyleType.original; + bool get isAlternative => this == LinkStyleType.alternative; +} + +/// The configurations for the toolbar widget of flutter quill +@immutable +class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { + const QuillSimpleToolbarConfigurations({ + required this.controller, + super.toolbarSectionSpacing = kToolbarSectionSpacing, + super.toolbarIconAlignment = WrapAlignment.center, + super.toolbarIconCrossAlignment = WrapCrossAlignment.center, + super.buttonOptions = const QuillToolbarButtonOptions(), + super.multiRowsDisplay = true, + this.fontSizesValues, + this.showDividers = true, + this.showFontFamily = true, + this.showFontSize = true, + this.showBoldButton = true, + this.showItalicButton = true, + this.showSmallButton = false, + this.showUnderLineButton = true, + this.showStrikeThrough = true, + this.showInlineCode = true, + this.showColorButton = true, + this.showBackgroundColorButton = true, + this.showClearFormat = true, + this.showAlignmentButtons = false, + this.showLeftAlignment = true, + this.showCenterAlignment = true, + this.showRightAlignment = true, + this.showJustifyAlignment = true, + this.showHeaderStyle = true, + this.showListNumbers = true, + this.showListBullets = true, + this.showListCheck = true, + this.showCodeBlock = true, + this.showQuote = true, + this.showIndent = true, + this.showLink = true, + this.showUndo = true, + this.showRedo = true, + this.showDirection = false, + this.showSearchButton = true, + this.showSubscript = true, + this.showSuperscript = true, + this.linkStyleType = LinkStyleType.original, + super.customButtons = const [], + + /// The decoration to use for the toolbar. + super.decoration, + + /// Toolbar items to display for controls of embed blocks + this.embedButtons, + super.linkDialogAction, + + ///The theme to use for the icons in the toolbar, uses type [QuillIconTheme] + // this.iconTheme, + this.dialogTheme, + super.axis = Axis.horizontal, + super.color, + super.sectionDividerColor, + super.sectionDividerSpace, + this.spacerWidget, + + /// By default it will calculated based on the [globalIconSize] from + /// [base] in [QuillToolbarButtonOptions] + /// You can change it but the the change only apply if + /// the [multiRowsDisplay] is false, if [multiRowsDisplay] then the value + /// will be [kDefaultIconSize] * 2 + super.toolbarSize, + }) : _toolbarSize = toolbarSize; + + final double? _toolbarSize; + + /// The toolbar size, by default it will be `baseButtonOptions.iconSize * 2` + @override + double get toolbarSize { + final alternativeToolbarSize = _toolbarSize; + if (alternativeToolbarSize != null) { + return alternativeToolbarSize; + } + 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 + /// 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; + + /// By default it will be + /// ``` + /// { + /// 'Small'.i18n: 'small', + /// 'Large'.i18n: 'large', + /// 'Huge'.i18n: 'huge', + /// 'Clear'.loc: '0' + /// } + /// ``` + final Map? fontSizesValues; + + final bool showDividers; + final bool showFontFamily; + final bool showFontSize; + final bool showBoldButton; + final bool showItalicButton; + final bool showSmallButton; + final bool showUnderLineButton; + final bool showStrikeThrough; + final bool showInlineCode; + final bool showColorButton; + final bool showBackgroundColorButton; + final bool showClearFormat; + final bool showAlignmentButtons; + final bool showLeftAlignment; + final bool showCenterAlignment; + final bool showRightAlignment; + final bool showJustifyAlignment; + final bool showHeaderStyle; + final bool showListNumbers; + final bool showListBullets; + final bool showListCheck; + final bool showCodeBlock; + final bool showQuote; + final bool showIndent; + final bool showLink; + final bool showUndo; + final bool showRedo; + final bool showDirection; + final bool showSearchButton; + final bool showSubscript; + final bool showSuperscript; + + /// Toolbar items to display for controls of embed blocks + final List? embedButtons; + + // ///The theme to use for the icons in the toolbar, uses type [QuillIconTheme] + // final QuillIconTheme? iconTheme; + + ///The theme to use for the theming of the [LinkDialog()], + ///shown when embedding an image, for example + final QuillDialogTheme? dialogTheme; + + /// Defines which dialog is used for applying link attribute. + final LinkStyleType linkStyleType; + + @override + List get props => [ + buttonOptions, + multiRowsDisplay, + fontSizesValues, + toolbarSize, + axis, + ]; +} + +/// The configurations for the buttons of the toolbar widget of flutter quill +@immutable +class QuillToolbarButtonOptions extends Equatable { + const QuillToolbarButtonOptions({ + this.base = const QuillToolbarBaseButtonOptions(), + this.undoHistory = const QuillToolbarHistoryButtonOptions( + isUndo: true, + ), + this.redoHistory = const QuillToolbarHistoryButtonOptions( + isUndo: false, + ), + this.fontFamily = const QuillToolbarFontFamilyButtonOptions(), + this.fontSize = const QuillToolbarFontSizeButtonOptions(), + this.bold = const QuillToolbarToggleStyleButtonOptions(), + this.subscript = const QuillToolbarToggleStyleButtonOptions(), + this.superscript = const QuillToolbarToggleStyleButtonOptions(), + this.italic = const QuillToolbarToggleStyleButtonOptions(), + this.small = const QuillToolbarToggleStyleButtonOptions(), + this.underLine = const QuillToolbarToggleStyleButtonOptions(), + this.strikeThrough = const QuillToolbarToggleStyleButtonOptions(), + this.inlineCode = const QuillToolbarToggleStyleButtonOptions(), + this.direction = const QuillToolbarToggleStyleButtonOptions(), + this.listNumbers = const QuillToolbarToggleStyleButtonOptions(), + this.listBullets = const QuillToolbarToggleStyleButtonOptions(), + this.codeBlock = const QuillToolbarToggleStyleButtonOptions(), + this.quote = const QuillToolbarToggleStyleButtonOptions(), + this.toggleCheckList = const QuillToolbarToggleCheckListButtonOptions(), + this.indentIncrease = const QuillToolbarIndentButtonOptions(), + this.indentDecrease = const QuillToolbarIndentButtonOptions(), + this.color = const QuillToolbarColorButtonOptions(), + this.backgroundColor = const QuillToolbarColorButtonOptions(), + this.clearFormat = const QuillToolbarClearFormatButtonOptions(), + this.selectAlignmentButtons = + const QuillToolbarSelectAlignmentButtonOptions(), + this.search = const QuillToolbarSearchButtonOptions(), + this.selectHeaderStyleButtons = + const QuillToolbarSelectHeaderStyleButtonsOptions(), + this.linkStyle = const QuillToolbarLinkStyleButtonOptions(), + this.linkStyle2 = const QuillToolbarLinkStyleButton2Options(), + this.customButtons = const QuillToolbarCustomButtonOptions(), + }); + + /// The base configurations for all the buttons which will apply to all + /// but if the options overrided in the spesefic button options + /// then it will use that instead + final QuillToolbarBaseButtonOptions base; + final QuillToolbarHistoryButtonOptions undoHistory; + final QuillToolbarHistoryButtonOptions redoHistory; + final QuillToolbarFontFamilyButtonOptions fontFamily; + final QuillToolbarFontSizeButtonOptions fontSize; + final QuillToolbarToggleStyleButtonOptions bold; + final QuillToolbarToggleStyleButtonOptions subscript; + final QuillToolbarToggleStyleButtonOptions superscript; + final QuillToolbarToggleStyleButtonOptions italic; + final QuillToolbarToggleStyleButtonOptions small; + final QuillToolbarToggleStyleButtonOptions underLine; + final QuillToolbarToggleStyleButtonOptions strikeThrough; + final QuillToolbarToggleStyleButtonOptions inlineCode; + final QuillToolbarToggleStyleButtonOptions direction; + final QuillToolbarToggleStyleButtonOptions listNumbers; + final QuillToolbarToggleStyleButtonOptions listBullets; + final QuillToolbarToggleStyleButtonOptions codeBlock; + final QuillToolbarToggleStyleButtonOptions quote; + final QuillToolbarToggleCheckListButtonOptions toggleCheckList; + final QuillToolbarIndentButtonOptions indentIncrease; + final QuillToolbarIndentButtonOptions indentDecrease; + final QuillToolbarColorButtonOptions color; + final QuillToolbarColorButtonOptions backgroundColor; + final QuillToolbarClearFormatButtonOptions clearFormat; + + /// The reason we call this buttons in the end because this is responsible + /// for all the alignment buttons and not just one, you still + /// can customize the icons and tooltips + /// and you have child builder + final QuillToolbarSelectAlignmentButtonOptions selectAlignmentButtons; + + final QuillToolbarSearchButtonOptions search; + + /// The reason we call this buttons in the end because this is responsible + /// for all the header style buttons and not just one, you still + /// can customize it and you also have child builder + final QuillToolbarSelectHeaderStyleButtonsOptions selectHeaderStyleButtons; + + final QuillToolbarLinkStyleButtonOptions linkStyle; + final QuillToolbarLinkStyleButton2Options linkStyle2; + + final QuillToolbarCustomButtonOptions customButtons; + + @override + List get props => [ + base, + ]; +} diff --git a/lib/src/models/config/toolbar/toolbar_configurations.dart b/lib/src/models/config/toolbar/toolbar_configurations.dart index 92b5b4604..187a61176 100644 --- a/lib/src/models/config/toolbar/toolbar_configurations.dart +++ b/lib/src/models/config/toolbar/toolbar_configurations.dart @@ -1,317 +1,33 @@ -import 'package:equatable/equatable.dart'; -import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' - show Axis, Widget, WrapAlignment, WrapCrossAlignment; + show Axis, WrapAlignment, WrapCrossAlignment, immutable; -import '../../../widgets/controller.dart'; -import '../../../widgets/embeds.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'; -import 'buttons/indent.dart'; -import 'buttons/link_style.dart'; -import 'buttons/link_style2.dart'; -import 'buttons/search.dart'; -import 'buttons/select_alignment.dart'; -import 'buttons/select_header_style.dart'; -import 'buttons/toggle_check_list.dart'; -import 'buttons/toggle_style.dart'; +import '../../../widgets/toolbar/base_toolbar.dart'; import 'toolbar_shared_configurations.dart'; -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'; -export './buttons/indent.dart'; -export './buttons/link_style.dart'; -export './buttons/link_style2.dart'; -export './buttons/search.dart'; -export './buttons/select_alignment.dart'; -export './buttons/select_header_style.dart'; -export './buttons/toggle_check_list.dart'; -export './buttons/toggle_style.dart'; - -/// The default size of the icon of a button. -const double kDefaultIconSize = 18; - -/// The default size for the toolbar (width, height) -const double defaultToolbarSize = kDefaultIconSize * 2; - -/// The factor of how much larger the button is in relation to the icon. -const double kIconButtonFactor = 1.77; - -/// The horizontal margin between the contents of each toolbar section. -const double kToolbarSectionSpacing = 4; - -enum LinkStyleType { - /// Defines the original [QuillToolbarLinkStyleButton]. - original, - - /// Defines the alternative [QuillToolbarLinkStyleButton2]. - alternative; - - bool get isOriginal => this == LinkStyleType.original; - bool get isAlternative => this == LinkStyleType.alternative; -} - -/// The configurations for the toolbar widget of flutter quill @immutable class QuillToolbarConfigurations extends QuillSharedToolbarProperties { const QuillToolbarConfigurations({ - required this.controller, + required this.childrenBuilder, + super.axis = Axis.horizontal, + super.toolbarSize = kDefaultIconSize * 2, super.toolbarSectionSpacing = kToolbarSectionSpacing, super.toolbarIconAlignment = WrapAlignment.center, super.toolbarIconCrossAlignment = WrapCrossAlignment.center, - super.buttonOptions = const QuillToolbarButtonOptions(), - super.multiRowsDisplay = true, - this.fontSizesValues, - this.showDividers = true, - this.showFontFamily = true, - this.showFontSize = true, - this.showBoldButton = true, - this.showItalicButton = true, - this.showSmallButton = false, - this.showUnderLineButton = true, - this.showStrikeThrough = true, - this.showInlineCode = true, - this.showColorButton = true, - this.showBackgroundColorButton = true, - this.showClearFormat = true, - this.showAlignmentButtons = false, - this.showLeftAlignment = true, - this.showCenterAlignment = true, - this.showRightAlignment = true, - this.showJustifyAlignment = true, - this.showHeaderStyle = true, - this.showListNumbers = true, - this.showListBullets = true, - this.showListCheck = true, - this.showCodeBlock = true, - this.showQuote = true, - this.showIndent = true, - this.showLink = true, - this.showUndo = true, - this.showRedo = true, - this.showDirection = false, - this.showSearchButton = true, - this.showSubscript = true, - this.showSuperscript = true, - this.linkStyleType = LinkStyleType.original, - super.customButtons = const [], - - /// The decoration to use for the toolbar. - super.decoration, - - /// Toolbar items to display for controls of embed blocks - this.embedButtons, - super.linkDialogAction, - - ///The theme to use for the icons in the toolbar, uses type [QuillIconTheme] - // this.iconTheme, - this.dialogTheme, - super.axis = Axis.horizontal, super.color, + super.customButtons = const [], super.sectionDividerColor, super.sectionDividerSpace, - this.spacerWidget, - - /// By default it will calculated based on the [globalIconSize] from - /// [base] in [QuillToolbarButtonOptions] - /// You can change it but the the change only apply if - /// the [multiRowsDisplay] is false, if [multiRowsDisplay] then the value - /// will be [kDefaultIconSize] * 2 - super.toolbarSize, - }) : _toolbarSize = toolbarSize; - - final double? _toolbarSize; - - /// The toolbar size, by default it will be `baseButtonOptions.iconSize * 2` - @override - double get toolbarSize { - final alternativeToolbarSize = _toolbarSize; - if (alternativeToolbarSize != null) { - return alternativeToolbarSize; - } - 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 - /// 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; - - /// By default it will be - /// ``` - /// { - /// 'Small'.i18n: 'small', - /// 'Large'.i18n: 'large', - /// 'Huge'.i18n: 'huge', - /// 'Clear'.loc: '0' - /// } - /// ``` - final Map? fontSizesValues; - - final bool showDividers; - final bool showFontFamily; - final bool showFontSize; - final bool showBoldButton; - final bool showItalicButton; - final bool showSmallButton; - final bool showUnderLineButton; - final bool showStrikeThrough; - final bool showInlineCode; - final bool showColorButton; - final bool showBackgroundColorButton; - final bool showClearFormat; - final bool showAlignmentButtons; - final bool showLeftAlignment; - final bool showCenterAlignment; - final bool showRightAlignment; - final bool showJustifyAlignment; - final bool showHeaderStyle; - final bool showListNumbers; - final bool showListBullets; - final bool showListCheck; - final bool showCodeBlock; - final bool showQuote; - final bool showIndent; - final bool showLink; - final bool showUndo; - final bool showRedo; - final bool showDirection; - final bool showSearchButton; - final bool showSubscript; - final bool showSuperscript; - - /// Toolbar items to display for controls of embed blocks - final List? embedButtons; - - // ///The theme to use for the icons in the toolbar, uses type [QuillIconTheme] - // final QuillIconTheme? iconTheme; - - ///The theme to use for the theming of the [LinkDialog()], - ///shown when embedding an image, for example - final QuillDialogTheme? dialogTheme; - - /// Defines which dialog is used for applying link attribute. - final LinkStyleType linkStyleType; - - @override - List get props => [ - buttonOptions, - multiRowsDisplay, - fontSizesValues, - toolbarSize, - axis, - ]; -} + super.linkDialogAction, + super.multiRowsDisplay = true, + super.decoration, -/// The configurations for the buttons of the toolbar widget of flutter quill -@immutable -class QuillToolbarButtonOptions extends Equatable { - const QuillToolbarButtonOptions({ - this.base = const QuillToolbarBaseButtonOptions(), - this.undoHistory = const QuillToolbarHistoryButtonOptions( - isUndo: true, - ), - this.redoHistory = const QuillToolbarHistoryButtonOptions( - isUndo: false, - ), - this.fontFamily = const QuillToolbarFontFamilyButtonOptions(), - this.fontSize = const QuillToolbarFontSizeButtonOptions(), - this.bold = const QuillToolbarToggleStyleButtonOptions(), - this.subscript = const QuillToolbarToggleStyleButtonOptions(), - this.superscript = const QuillToolbarToggleStyleButtonOptions(), - this.italic = const QuillToolbarToggleStyleButtonOptions(), - this.small = const QuillToolbarToggleStyleButtonOptions(), - this.underLine = const QuillToolbarToggleStyleButtonOptions(), - this.strikeThrough = const QuillToolbarToggleStyleButtonOptions(), - this.inlineCode = const QuillToolbarToggleStyleButtonOptions(), - this.direction = const QuillToolbarToggleStyleButtonOptions(), - this.listNumbers = const QuillToolbarToggleStyleButtonOptions(), - this.listBullets = const QuillToolbarToggleStyleButtonOptions(), - this.codeBlock = const QuillToolbarToggleStyleButtonOptions(), - this.quote = const QuillToolbarToggleStyleButtonOptions(), - this.toggleCheckList = const QuillToolbarToggleCheckListButtonOptions(), - this.indentIncrease = const QuillToolbarIndentButtonOptions(), - this.indentDecrease = const QuillToolbarIndentButtonOptions(), - this.color = const QuillToolbarColorButtonOptions(), - this.backgroundColor = const QuillToolbarColorButtonOptions(), - this.clearFormat = const QuillToolbarClearFormatButtonOptions(), - this.selectAlignmentButtons = - const QuillToolbarSelectAlignmentButtonOptions(), - this.search = const QuillToolbarSearchButtonOptions(), - this.selectHeaderStyleButtons = - const QuillToolbarSelectHeaderStyleButtonsOptions(), - this.linkStyle = const QuillToolbarLinkStyleButtonOptions(), - this.linkStyle2 = const QuillToolbarLinkStyleButton2Options(), - this.customButtons = const QuillToolbarCustomButtonOptions(), + /// Note this only used when you using the quill toolbar buttons like + /// `QuillToolbarHistoryButton` inside it + super.buttonOptions = const QuillToolbarButtonOptions(), }); - /// The base configurations for all the buttons which will apply to all - /// but if the options overrided in the spesefic button options - /// then it will use that instead - final QuillToolbarBaseButtonOptions base; - final QuillToolbarHistoryButtonOptions undoHistory; - final QuillToolbarHistoryButtonOptions redoHistory; - final QuillToolbarFontFamilyButtonOptions fontFamily; - final QuillToolbarFontSizeButtonOptions fontSize; - final QuillToolbarToggleStyleButtonOptions bold; - final QuillToolbarToggleStyleButtonOptions subscript; - final QuillToolbarToggleStyleButtonOptions superscript; - final QuillToolbarToggleStyleButtonOptions italic; - final QuillToolbarToggleStyleButtonOptions small; - final QuillToolbarToggleStyleButtonOptions underLine; - final QuillToolbarToggleStyleButtonOptions strikeThrough; - final QuillToolbarToggleStyleButtonOptions inlineCode; - final QuillToolbarToggleStyleButtonOptions direction; - final QuillToolbarToggleStyleButtonOptions listNumbers; - final QuillToolbarToggleStyleButtonOptions listBullets; - final QuillToolbarToggleStyleButtonOptions codeBlock; - final QuillToolbarToggleStyleButtonOptions quote; - final QuillToolbarToggleCheckListButtonOptions toggleCheckList; - final QuillToolbarIndentButtonOptions indentIncrease; - final QuillToolbarIndentButtonOptions indentDecrease; - final QuillToolbarColorButtonOptions color; - final QuillToolbarColorButtonOptions backgroundColor; - final QuillToolbarClearFormatButtonOptions clearFormat; - - /// The reason we call this buttons in the end because this is responsible - /// for all the alignment buttons and not just one, you still - /// can customize the icons and tooltips - /// and you have child builder - final QuillToolbarSelectAlignmentButtonOptions selectAlignmentButtons; - - final QuillToolbarSearchButtonOptions search; - - /// The reason we call this buttons in the end because this is responsible - /// for all the header style buttons and not just one, you still - /// can customize it and you also have child builder - final QuillToolbarSelectHeaderStyleButtonsOptions selectHeaderStyleButtons; - - final QuillToolbarLinkStyleButtonOptions linkStyle; - final QuillToolbarLinkStyleButton2Options linkStyle2; - - final QuillToolbarCustomButtonOptions customButtons; + final QuillBaseToolbarChildrenBuilder childrenBuilder; @override - List get props => [ - base, - ]; + List get props => []; } diff --git a/lib/src/models/documents/document.dart b/lib/src/models/documents/document.dart index 4649765ff..1b4f96969 100644 --- a/lib/src/models/documents/document.dart +++ b/lib/src/models/documents/document.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import '../../widgets/embeds.dart'; +import '../../widgets/others/embeds.dart'; import '../quill_delta.dart'; import '../rules/rule.dart'; import '../structs/doc_change.dart'; diff --git a/lib/src/models/documents/nodes/container.dart b/lib/src/models/documents/nodes/container.dart index 605e472e4..5b5e0941b 100644 --- a/lib/src/models/documents/nodes/container.dart +++ b/lib/src/models/documents/nodes/container.dart @@ -1,6 +1,6 @@ import 'dart:collection'; -import '../../../widgets/embeds.dart'; +import '../../../widgets/others/embeds.dart'; import '../style.dart'; import 'leaf.dart'; import 'line.dart'; diff --git a/lib/src/models/documents/nodes/leaf.dart b/lib/src/models/documents/nodes/leaf.dart index 4f1fd3b0f..314bb4eed 100644 --- a/lib/src/models/documents/nodes/leaf.dart +++ b/lib/src/models/documents/nodes/leaf.dart @@ -1,6 +1,6 @@ import 'dart:math' as math; -import '../../../widgets/embeds.dart'; +import '../../../widgets/others/embeds.dart'; import '../../quill_delta.dart'; import '../style.dart'; import 'embeddable.dart'; diff --git a/lib/src/models/documents/nodes/line.dart b/lib/src/models/documents/nodes/line.dart index 75dfbde06..bc2920cb1 100644 --- a/lib/src/models/documents/nodes/line.dart +++ b/lib/src/models/documents/nodes/line.dart @@ -2,7 +2,7 @@ import 'dart:math' as math; import 'package:collection/collection.dart'; -import '../../../widgets/embeds.dart'; +import '../../../widgets/others/embeds.dart'; import '../../quill_delta.dart'; import '../../structs/offset_value.dart'; import '../attribute.dart'; diff --git a/lib/src/models/documents/nodes/node.dart b/lib/src/models/documents/nodes/node.dart index c196b47f8..4b9bcd7d9 100644 --- a/lib/src/models/documents/nodes/node.dart +++ b/lib/src/models/documents/nodes/node.dart @@ -1,6 +1,6 @@ import 'dart:collection'; -import '../../../widgets/embeds.dart'; +import '../../../widgets/others/embeds.dart'; import '../../quill_delta.dart'; import '../attribute.dart'; import '../style.dart'; diff --git a/lib/src/utils/embeds.dart b/lib/src/utils/embeds.dart index 7164f1d5a..973942bb1 100644 --- a/lib/src/utils/embeds.dart +++ b/lib/src/utils/embeds.dart @@ -2,7 +2,7 @@ import 'dart:math'; import '../models/documents/nodes/leaf.dart'; import '../models/structs/offset_value.dart'; -import '../widgets/controller.dart'; +import '../widgets/others/controller.dart'; OffsetValue getEmbedNode(QuillController controller, int offset) { var offset = controller.selection.start; diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index b0995b742..2fe82da09 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -16,13 +16,13 @@ import '../../models/documents/nodes/container.dart' as container_node; import '../../models/documents/nodes/leaf.dart'; import '../../models/structs/offset_value.dart'; import '../../utils/platform.dart'; -import '../box.dart'; -import '../cursor.dart'; -import '../delegate.dart'; -import '../embeds.dart'; -import '../float_cursor.dart'; +import '../others/box.dart'; +import '../others/cursor.dart'; +import '../others/delegate.dart'; +import '../others/embeds.dart'; +import '../others/float_cursor.dart'; import '../raw_editor/raw_editor.dart'; -import '../text_selection.dart'; +import '../others/text_selection.dart'; import '../utils/provider.dart'; import 'editor_builder.dart'; diff --git a/lib/src/widgets/box.dart b/lib/src/widgets/others/box.dart similarity index 98% rename from lib/src/widgets/box.dart rename to lib/src/widgets/others/box.dart index 8b4f5f007..85dc8dff0 100644 --- a/lib/src/widgets/box.dart +++ b/lib/src/widgets/others/box.dart @@ -1,6 +1,6 @@ import 'package:flutter/rendering.dart'; -import '../models/documents/nodes/container.dart'; +import '../../models/documents/nodes/container.dart'; /// A common interface to render boxes which represent a piece of rich text /// content. diff --git a/lib/src/widgets/controller.dart b/lib/src/widgets/others/controller.dart similarity index 96% rename from lib/src/widgets/controller.dart rename to lib/src/widgets/others/controller.dart index b48ab9ebc..0928cf88e 100644 --- a/lib/src/widgets/controller.dart +++ b/lib/src/widgets/others/controller.dart @@ -3,16 +3,16 @@ import 'dart:math' as math; import 'package:flutter/cupertino.dart'; import 'package:flutter/services.dart'; -import '../models/documents/attribute.dart'; -import '../models/documents/document.dart'; -import '../models/documents/nodes/embeddable.dart'; -import '../models/documents/nodes/leaf.dart'; -import '../models/documents/style.dart'; -import '../models/quill_delta.dart'; -import '../models/structs/doc_change.dart'; -import '../models/structs/image_url.dart'; -import '../models/structs/offset_value.dart'; -import '../utils/delta.dart'; +import '../../models/documents/attribute.dart'; +import '../../models/documents/document.dart'; +import '../../models/documents/nodes/embeddable.dart'; +import '../../models/documents/nodes/leaf.dart'; +import '../../models/documents/style.dart'; +import '../../models/quill_delta.dart'; +import '../../models/structs/doc_change.dart'; +import '../../models/structs/image_url.dart'; +import '../../models/structs/offset_value.dart'; +import '../../utils/delta.dart'; typedef ReplaceTextCallback = bool Function(int index, int len, Object? data); typedef DeleteCallback = void Function(int cursorPosition, bool forward); diff --git a/lib/src/widgets/cursor.dart b/lib/src/widgets/others/cursor.dart similarity index 99% rename from lib/src/widgets/cursor.dart rename to lib/src/widgets/others/cursor.dart index 929118b16..41513308b 100644 --- a/lib/src/widgets/cursor.dart +++ b/lib/src/widgets/others/cursor.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:flutter/widgets.dart'; -import '../utils/platform.dart'; +import '../../utils/platform.dart'; import 'box.dart'; /// Style properties of editing cursor. diff --git a/lib/src/widgets/default_styles.dart b/lib/src/widgets/others/default_styles.dart similarity index 97% rename from lib/src/widgets/default_styles.dart rename to lib/src/widgets/others/default_styles.dart index 5d5949f8b..575a52730 100644 --- a/lib/src/widgets/default_styles.dart +++ b/lib/src/widgets/others/default_styles.dart @@ -2,11 +2,11 @@ import 'dart:ui'; import 'package:flutter/material.dart'; -import '../models/documents/attribute.dart'; -import '../models/documents/style.dart'; -import '../models/structs/vertical_spacing.dart'; -import '../utils/platform.dart'; -import 'style_widgets/checkbox_point.dart'; +import '../../models/documents/attribute.dart'; +import '../../models/documents/style.dart'; +import '../../models/structs/vertical_spacing.dart'; +import '../../utils/platform.dart'; +import '../style_widgets/checkbox_point.dart'; class QuillStyles extends InheritedWidget { const QuillStyles({ diff --git a/lib/src/widgets/delegate.dart b/lib/src/widgets/others/delegate.dart similarity index 98% rename from lib/src/widgets/delegate.dart rename to lib/src/widgets/others/delegate.dart index 5d0216065..dff3709ac 100644 --- a/lib/src/widgets/delegate.dart +++ b/lib/src/widgets/others/delegate.dart @@ -3,10 +3,10 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; -import '../models/documents/attribute.dart'; -import '../models/documents/nodes/leaf.dart'; -import '../utils/platform.dart'; -import 'editor/editor.dart'; +import '../../models/documents/attribute.dart'; +import '../../models/documents/nodes/leaf.dart'; +import '../../utils/platform.dart'; +import '../editor/editor.dart'; import 'embeds.dart'; import 'text_selection.dart'; diff --git a/lib/src/widgets/embeds.dart b/lib/src/widgets/others/embeds.dart similarity index 77% rename from lib/src/widgets/embeds.dart rename to lib/src/widgets/others/embeds.dart index 87511204a..9b828d1bc 100644 --- a/lib/src/widgets/embeds.dart +++ b/lib/src/widgets/others/embeds.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; -import '../../extensions.dart'; -import '../models/documents/nodes/leaf.dart' as leaf; -import '../models/themes/quill_dialog_theme.dart'; -import '../models/themes/quill_icon_theme.dart'; +import '../../../extensions.dart'; +import '../../models/documents/nodes/leaf.dart' as leaf; +import '../../models/themes/quill_dialog_theme.dart'; +import '../../models/themes/quill_icon_theme.dart'; import 'controller.dart'; abstract class EmbedBuilder { diff --git a/lib/src/widgets/float_cursor.dart b/lib/src/widgets/others/float_cursor.dart similarity index 100% rename from lib/src/widgets/float_cursor.dart rename to lib/src/widgets/others/float_cursor.dart diff --git a/lib/src/widgets/keyboard_listener.dart b/lib/src/widgets/others/keyboard_listener.dart similarity index 100% rename from lib/src/widgets/keyboard_listener.dart rename to lib/src/widgets/others/keyboard_listener.dart diff --git a/lib/src/widgets/link.dart b/lib/src/widgets/others/link.dart similarity index 97% rename from lib/src/widgets/link.dart rename to lib/src/widgets/others/link.dart index 9e4ee354b..93d8c685e 100644 --- a/lib/src/widgets/link.dart +++ b/lib/src/widgets/others/link.dart @@ -2,9 +2,9 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import '../l10n/extensions/localizations.dart'; -import '../models/documents/attribute.dart'; -import '../models/documents/nodes/node.dart'; +import '../../l10n/extensions/localizations.dart'; +import '../../models/documents/attribute.dart'; +import '../../models/documents/nodes/node.dart'; const linkPrefixes = [ 'mailto:', // email diff --git a/lib/src/widgets/proxy.dart b/lib/src/widgets/others/proxy.dart similarity index 100% rename from lib/src/widgets/proxy.dart rename to lib/src/widgets/others/proxy.dart diff --git a/lib/src/widgets/text_block.dart b/lib/src/widgets/others/text_block.dart similarity index 97% rename from lib/src/widgets/text_block.dart rename to lib/src/widgets/others/text_block.dart index 1f70c9af7..a52ba4db2 100644 --- a/lib/src/widgets/text_block.dart +++ b/lib/src/widgets/others/text_block.dart @@ -1,22 +1,22 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; -import '../extensions/quill_provider.dart'; -import '../models/documents/attribute.dart'; -import '../models/documents/nodes/block.dart'; -import '../models/documents/nodes/line.dart'; -import '../models/structs/vertical_spacing.dart'; -import '../utils/delta.dart'; +import '../../extensions/quill_provider.dart'; +import '../../models/documents/attribute.dart'; +import '../../models/documents/nodes/block.dart'; +import '../../models/documents/nodes/line.dart'; +import '../../models/structs/vertical_spacing.dart'; +import '../../utils/delta.dart'; import 'box.dart'; import 'controller.dart'; import 'cursor.dart'; import 'default_styles.dart'; import 'delegate.dart'; -import 'editor/editor.dart'; +import '../editor/editor.dart'; import 'link.dart'; -import 'style_widgets/bullet_point.dart'; -import 'style_widgets/checkbox_point.dart'; -import 'style_widgets/number_point.dart'; +import '../style_widgets/bullet_point.dart'; +import '../style_widgets/checkbox_point.dart'; +import '../style_widgets/number_point.dart'; import 'text_line.dart'; import 'text_selection.dart'; diff --git a/lib/src/widgets/text_line.dart b/lib/src/widgets/others/text_line.dart similarity index 98% rename from lib/src/widgets/text_line.dart rename to lib/src/widgets/others/text_line.dart index c79e8da33..0067c9581 100644 --- a/lib/src/widgets/text_line.dart +++ b/lib/src/widgets/others/text_line.dart @@ -8,18 +8,18 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:url_launcher/url_launcher.dart'; -import '../models/documents/attribute.dart'; -import '../models/documents/nodes/container.dart' as container_node; -import '../models/documents/nodes/embeddable.dart'; -import '../models/documents/nodes/leaf.dart'; -import '../models/documents/nodes/leaf.dart' as leaf; -import '../models/documents/nodes/line.dart'; -import '../models/documents/nodes/node.dart'; -import '../models/documents/style.dart'; -import '../models/structs/vertical_spacing.dart'; -import '../utils/color.dart'; -import '../utils/font.dart'; -import '../utils/platform.dart'; +import '../../models/documents/attribute.dart'; +import '../../models/documents/nodes/container.dart' as container_node; +import '../../models/documents/nodes/embeddable.dart'; +import '../../models/documents/nodes/leaf.dart'; +import '../../models/documents/nodes/leaf.dart' as leaf; +import '../../models/documents/nodes/line.dart'; +import '../../models/documents/nodes/node.dart'; +import '../../models/documents/style.dart'; +import '../../models/structs/vertical_spacing.dart'; +import '../../utils/color.dart'; +import '../../utils/font.dart'; +import '../../utils/platform.dart'; import 'box.dart'; import 'controller.dart'; import 'cursor.dart'; diff --git a/lib/src/widgets/text_selection.dart b/lib/src/widgets/others/text_selection.dart similarity index 99% rename from lib/src/widgets/text_selection.dart rename to lib/src/widgets/others/text_selection.dart index c51d414df..8016201f0 100644 --- a/lib/src/widgets/text_selection.dart +++ b/lib/src/widgets/others/text_selection.dart @@ -6,8 +6,8 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; -import '../models/documents/nodes/node.dart'; -import 'editor/editor.dart'; +import '../../models/documents/nodes/node.dart'; +import '../editor/editor.dart'; TextSelection localSelection(Node node, TextSelection selection, fromParent) { final base = fromParent ? node.offset : node.documentOffset; diff --git a/lib/src/widgets/quill_single_child_scroll_view.dart b/lib/src/widgets/raw_editor/quill_single_child_scroll_view.dart similarity index 100% rename from lib/src/widgets/quill_single_child_scroll_view.dart rename to lib/src/widgets/raw_editor/quill_single_child_scroll_view.dart diff --git a/lib/src/widgets/raw_editor/raw_editor_render_object.dart b/lib/src/widgets/raw_editor/raw_editor_render_object.dart index 3338c1f22..fe61fd37d 100644 --- a/lib/src/widgets/raw_editor/raw_editor_render_object.dart +++ b/lib/src/widgets/raw_editor/raw_editor_render_object.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart' show ViewportOffset; import '../../models/documents/document.dart'; -import '../cursor.dart'; +import '../others/cursor.dart'; import '../editor/editor.dart'; class QuilRawEditorMultiChildRenderObject extends MultiChildRenderObjectWidget { diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index ced4ab06c..2eff57861 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -33,17 +33,17 @@ import '../../utils/cast.dart'; import '../../utils/delta.dart'; import '../../utils/embeds.dart'; import '../../utils/platform.dart'; -import '../controller.dart'; -import '../cursor.dart'; -import '../default_styles.dart'; +import '../others/controller.dart'; +import '../others/cursor.dart'; +import '../others/default_styles.dart'; import '../editor/editor.dart'; -import '../keyboard_listener.dart'; -import '../link.dart'; -import '../proxy.dart'; -import '../quill_single_child_scroll_view.dart'; -import '../text_block.dart'; -import '../text_line.dart'; -import '../text_selection.dart'; +import '../others/keyboard_listener.dart'; +import '../others/link.dart'; +import '../others/proxy.dart'; +import 'quill_single_child_scroll_view.dart'; +import '../others/text_block.dart'; +import '../others/text_line.dart'; +import '../others/text_selection.dart'; import 'raw_editor.dart'; import 'raw_editor_actions.dart'; import 'raw_editor_render_object.dart'; diff --git a/lib/src/widgets/style_widgets/number_point.dart b/lib/src/widgets/style_widgets/number_point.dart index 30b5590ec..9809f4ac7 100644 --- a/lib/src/widgets/style_widgets/number_point.dart +++ b/lib/src/widgets/style_widgets/number_point.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import '../../models/documents/attribute.dart'; -import '../text_block.dart'; +import '../others/text_block.dart'; class QuillEditorNumberPoint extends StatelessWidget { const QuillEditorNumberPoint({ diff --git a/lib/src/widgets/toolbar/base_toolbar.dart b/lib/src/widgets/toolbar/base_toolbar.dart index af412d35b..59efda0c5 100644 --- a/lib/src/widgets/toolbar/base_toolbar.dart +++ b/lib/src/widgets/toolbar/base_toolbar.dart @@ -3,11 +3,11 @@ import 'package:flutter/material.dart'; import '../../../flutter_quill.dart' show QuillBaseToolbarProvider, defaultToolbarSize; import '../../l10n/widgets/localizations.dart'; -import '../../models/config/toolbar/base_toolbar_configurations.dart'; +import '../../models/config/toolbar/toolbar_configurations.dart'; import 'buttons/arrow_indicated_list_button.dart'; export '../../models/config/toolbar/buttons/base.dart'; -export '../../models/config/toolbar/toolbar_configurations.dart'; +export '../../models/config/toolbar/simple_toolbar_configurations.dart'; export 'buttons/clear_format_button.dart'; export 'buttons/color/color_button.dart'; export 'buttons/custom_button_button.dart'; @@ -28,13 +28,13 @@ typedef QuillBaseToolbarChildrenBuilder = List Function( BuildContext context, ); -class QuillBaseToolbar extends StatelessWidget implements PreferredSizeWidget { - const QuillBaseToolbar({ +class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { + const QuillToolbar({ required this.configurations, super.key, }); - final QuillBaseToolbarConfigurations configurations; + final QuillToolbarConfigurations configurations; // We can't get the modified [toolbarSize] by the developer // but we tested the [QuillToolbar] on the [appBar] and I didn't notice @@ -90,7 +90,7 @@ class QuillBaseToolbar extends StatelessWidget implements PreferredSizeWidget { /// The divider which is used for separation of buttons in the toolbar. /// /// It can be used outside of this package, for example when user does not use -/// [QuillBaseToolbar.basic] and compose toolbar's children on its own. +/// [QuillToolbar.basic] and compose toolbar's children on its own. class QuillToolbarDivider extends StatelessWidget { const QuillToolbarDivider( this.axis, { diff --git a/lib/src/widgets/toolbar/buttons/clear_format_button.dart b/lib/src/widgets/toolbar/buttons/clear_format_button.dart index e25afa3d1..d903aa777 100644 --- a/lib/src/widgets/toolbar/buttons/clear_format_button.dart +++ b/lib/src/widgets/toolbar/buttons/clear_format_button.dart @@ -4,7 +4,7 @@ import '../../../extensions/quill_provider.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../controller.dart'; +import '../../others/controller.dart'; import '../base_toolbar.dart'; class QuillToolbarClearFormatButton extends StatelessWidget { diff --git a/lib/src/widgets/toolbar/buttons/color/color_button.dart b/lib/src/widgets/toolbar/buttons/color/color_button.dart index f5b2e032b..2965f8b25 100644 --- a/lib/src/widgets/toolbar/buttons/color/color_button.dart +++ b/lib/src/widgets/toolbar/buttons/color/color_button.dart @@ -7,7 +7,7 @@ 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 '../../../others/controller.dart'; import '../../base_toolbar.dart'; import 'color_dialog.dart'; diff --git a/lib/src/widgets/toolbar/buttons/custom_button_button.dart b/lib/src/widgets/toolbar/buttons/custom_button_button.dart index bbf6ad575..27c6cf14c 100644 --- a/lib/src/widgets/toolbar/buttons/custom_button_button.dart +++ b/lib/src/widgets/toolbar/buttons/custom_button_button.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import '../../../extensions/quill_provider.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../controller.dart'; +import '../../others/controller.dart'; import '../base_toolbar.dart'; class QuillToolbarCustomButton extends StatelessWidget { diff --git a/lib/src/widgets/toolbar/buttons/font_family_button.dart b/lib/src/widgets/toolbar/buttons/font_family_button.dart index fbfa954ea..40c62990c 100644 --- a/lib/src/widgets/toolbar/buttons/font_family_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_family_button.dart @@ -7,7 +7,7 @@ import '../../../models/config/toolbar/buttons/font_family.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../controller.dart'; +import '../../others/controller.dart'; class QuillToolbarFontFamilyButton extends StatefulWidget { QuillToolbarFontFamilyButton({ diff --git a/lib/src/widgets/toolbar/buttons/font_size_button.dart b/lib/src/widgets/toolbar/buttons/font_size_button.dart index 621fc5c7f..58dd04e92 100644 --- a/lib/src/widgets/toolbar/buttons/font_size_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_size_button.dart @@ -8,7 +8,7 @@ import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../../utils/font.dart'; -import '../../controller.dart'; +import '../../others/controller.dart'; class QuillToolbarFontSizeButton extends StatefulWidget { QuillToolbarFontSizeButton({ diff --git a/lib/src/widgets/toolbar/buttons/history_button.dart b/lib/src/widgets/toolbar/buttons/history_button.dart index 3a4cf3c1b..c4ac883f4 100644 --- a/lib/src/widgets/toolbar/buttons/history_button.dart +++ b/lib/src/widgets/toolbar/buttons/history_button.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import '../../../extensions/quill_provider.dart'; import '../../../l10n/extensions/localizations.dart'; -import '../../controller.dart'; +import '../../others/controller.dart'; import '../base_toolbar.dart'; class QuillToolbarHistoryButton extends StatefulWidget { diff --git a/lib/src/widgets/toolbar/buttons/indent_button.dart b/lib/src/widgets/toolbar/buttons/indent_button.dart index 793dd0faa..4d81b5c7e 100644 --- a/lib/src/widgets/toolbar/buttons/indent_button.dart +++ b/lib/src/widgets/toolbar/buttons/indent_button.dart @@ -4,7 +4,7 @@ import '../../../extensions/quill_provider.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/config/toolbar/buttons/indent.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../controller.dart'; +import '../../others/controller.dart'; import '../base_toolbar.dart' show QuillToolbarBaseButtonOptions, QuillToolbarIconButton; diff --git a/lib/src/widgets/toolbar/buttons/link_style2_button.dart b/lib/src/widgets/toolbar/buttons/link_style2_button.dart index 86e25103a..2eca0a81f 100644 --- a/lib/src/widgets/toolbar/buttons/link_style2_button.dart +++ b/lib/src/widgets/toolbar/buttons/link_style2_button.dart @@ -10,8 +10,8 @@ import '../../../l10n/widgets/localizations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/themes/quill_dialog_theme.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../controller.dart'; -import '../../link.dart'; +import '../../others/controller.dart'; +import '../../others/link.dart'; import '../base_toolbar.dart'; /// Alternative version of [QuillToolbarLinkStyleButton]. This widget has more diff --git a/lib/src/widgets/toolbar/buttons/link_style_button.dart b/lib/src/widgets/toolbar/buttons/link_style_button.dart index b4aacadc9..f08f36712 100644 --- a/lib/src/widgets/toolbar/buttons/link_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/link_style_button.dart @@ -8,8 +8,8 @@ import '../../../models/rules/insert.dart'; import '../../../models/structs/link_dialog_action.dart'; import '../../../models/themes/quill_dialog_theme.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../controller.dart'; -import '../../link.dart'; +import '../../others/controller.dart'; +import '../../others/link.dart'; import '../base_toolbar.dart'; class QuillToolbarLinkStyleButton extends StatefulWidget { diff --git a/lib/src/widgets/toolbar/buttons/search/search_button.dart b/lib/src/widgets/toolbar/buttons/search/search_button.dart index 8b568977d..437ed7917 100644 --- a/lib/src/widgets/toolbar/buttons/search/search_button.dart +++ b/lib/src/widgets/toolbar/buttons/search/search_button.dart @@ -5,7 +5,7 @@ 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 '../../../others/controller.dart'; import '../../base_toolbar.dart'; class QuillToolbarSearchButton extends StatelessWidget { diff --git a/lib/src/widgets/toolbar/buttons/search/search_dialog.dart b/lib/src/widgets/toolbar/buttons/search/search_dialog.dart index 2aa268c5a..65b2c4d4c 100644 --- a/lib/src/widgets/toolbar/buttons/search/search_dialog.dart +++ b/lib/src/widgets/toolbar/buttons/search/search_dialog.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import '../../../../l10n/extensions/localizations.dart'; import '../../../../models/documents/document.dart'; import '../../../../models/themes/quill_dialog_theme.dart'; -import '../../../controller.dart'; +import '../../../others/controller.dart'; @immutable class QuillToolbarSearchDialogChildBuilderExtraOptions { diff --git a/lib/src/widgets/toolbar/buttons/select_alignment_button.dart b/lib/src/widgets/toolbar/buttons/select_alignment_button.dart index c81dc1e1d..4d7f8bcaa 100644 --- a/lib/src/widgets/toolbar/buttons/select_alignment_button.dart +++ b/lib/src/widgets/toolbar/buttons/select_alignment_button.dart @@ -7,7 +7,7 @@ import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../../utils/widgets.dart'; -import '../../controller.dart'; +import '../../others/controller.dart'; import '../base_toolbar.dart'; class QuillToolbarSelectAlignmentButton extends StatefulWidget { diff --git a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart index 0f913204c..41dca31ae 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import '../../../../translations.dart'; import '../../../models/config/toolbar/buttons/select_header_style.dart'; import '../../../models/documents/attribute.dart'; -import '../../controller.dart'; +import '../../others/controller.dart'; enum QuillToolbarSelectHeaderStyleButtonOptions { normal, diff --git a/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart b/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart index 791b81320..5972baf20 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart @@ -7,7 +7,7 @@ import '../../../l10n/extensions/localizations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../controller.dart'; +import '../../others/controller.dart'; import '../base_toolbar.dart'; class QuillToolbarSelectHeaderStyleButtons extends StatefulWidget { diff --git a/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart b/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart index 01ec7f92c..db1980e5f 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart @@ -8,7 +8,7 @@ import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../../utils/widgets.dart'; -import '../../controller.dart'; +import '../../others/controller.dart'; import 'toggle_style_button.dart'; class QuillToolbarToggleCheckListButton extends StatefulWidget { diff --git a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart index e2928ef37..67982e28e 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart @@ -6,7 +6,7 @@ import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../../utils/widgets.dart'; -import '../../controller.dart'; +import '../../others/controller.dart'; import '../base_toolbar.dart'; typedef ToggleStyleButtonBuilder = Widget Function( diff --git a/lib/src/widgets/toolbar/toolbar.dart b/lib/src/widgets/toolbar/simple_toolbar.dart similarity index 98% rename from lib/src/widgets/toolbar/toolbar.dart rename to lib/src/widgets/toolbar/simple_toolbar.dart index b4c9a7d33..57644056e 100644 --- a/lib/src/widgets/toolbar/toolbar.dart +++ b/lib/src/widgets/toolbar/simple_toolbar.dart @@ -2,20 +2,21 @@ import 'package:flutter/material.dart'; import '../../extensions/quill_provider.dart'; import '../../l10n/extensions/localizations.dart'; -import '../../models/config/toolbar/base_toolbar_configurations.dart'; +import '../../models/config/toolbar/toolbar_configurations.dart'; import '../../models/documents/attribute.dart'; import '../utils/provider.dart'; import 'base_toolbar.dart'; import 'buttons/select_header_style_button.dart'; -class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { - const QuillToolbar({ +class QuillSimpleToolbar extends StatelessWidget + implements PreferredSizeWidget { + const QuillSimpleToolbar({ required this.configurations, super.key, }); /// The configurations for the toolbar widget of flutter quill - final QuillToolbarConfigurations configurations; + final QuillSimpleToolbarConfigurations configurations; @override Widget build(BuildContext context) { @@ -50,8 +51,8 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { return QuillToolbarProvider( toolbarConfigurations: configurations, - child: QuillBaseToolbar( - configurations: QuillBaseToolbarConfigurations( + child: QuillToolbar( + configurations: QuillToolbarConfigurations( color: configurations.color, decoration: configurations.decoration, toolbarSectionSpacing: configurations.toolbarSectionSpacing, @@ -126,6 +127,36 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { ), spacerWidget, ], + if (configurations.showItalicButton) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.italic, + options: toolbarConfigurations.buttonOptions.italic, + controller: + toolbarConfigurations.buttonOptions.italic.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showUnderLineButton) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.underline, + options: toolbarConfigurations.buttonOptions.underLine, + controller: toolbarConfigurations + .buttonOptions.underLine.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showInlineCode) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.inlineCode, + options: toolbarConfigurations.buttonOptions.inlineCode, + controller: toolbarConfigurations + .buttonOptions.inlineCode.controller ?? + globalController, + ), + spacerWidget, + ], if (configurations.showSubscript) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.subscript, @@ -146,16 +177,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { ), spacerWidget, ], - if (configurations.showItalicButton) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.italic, - options: toolbarConfigurations.buttonOptions.italic, - controller: - toolbarConfigurations.buttonOptions.italic.controller ?? - globalController, - ), - spacerWidget, - ], if (configurations.showSmallButton) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.small, @@ -166,16 +187,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { ), spacerWidget, ], - if (configurations.showUnderLineButton) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.underline, - options: toolbarConfigurations.buttonOptions.underLine, - controller: toolbarConfigurations - .buttonOptions.underLine.controller ?? - globalController, - ), - spacerWidget, - ], if (configurations.showStrikeThrough) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.strikeThrough, @@ -186,16 +197,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { ), spacerWidget, ], - if (configurations.showInlineCode) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.inlineCode, - options: toolbarConfigurations.buttonOptions.inlineCode, - controller: toolbarConfigurations - .buttonOptions.inlineCode.controller ?? - globalController, - ), - spacerWidget, - ], if (configurations.showColorButton) ...[ QuillToolbarColorButton( controller: diff --git a/lib/src/widgets/utils/provider.dart b/lib/src/widgets/utils/provider.dart index 773cbba33..4cd656362 100644 --- a/lib/src/widgets/utils/provider.dart +++ b/lib/src/widgets/utils/provider.dart @@ -3,7 +3,7 @@ import 'package:flutter/widgets.dart' show BuildContext, InheritedWidget, Widget; import '../../models/config/quill_configurations.dart'; -import '../../models/config/toolbar/base_toolbar_configurations.dart'; +import '../../models/config/toolbar/toolbar_configurations.dart'; class QuillProvider extends InheritedWidget { const QuillProvider({ @@ -72,7 +72,7 @@ class QuillToolbarProvider extends InheritedWidget { }); /// The configurations for the toolbar widget of flutter quill - final QuillToolbarConfigurations toolbarConfigurations; + final QuillSimpleToolbarConfigurations toolbarConfigurations; @override bool updateShouldNotify(covariant QuillToolbarProvider oldWidget) { @@ -130,7 +130,7 @@ class QuillBaseToolbarProvider extends InheritedWidget { }); /// The configurations for the toolbar widget of flutter quill - final QuillBaseToolbarConfigurations toolbarConfigurations; + final QuillToolbarConfigurations toolbarConfigurations; @override bool updateShouldNotify(covariant QuillBaseToolbarProvider oldWidget) { @@ -167,10 +167,10 @@ class QuillBaseToolbarProvider extends InheritedWidget { return provider; } - /// To pass the [QuillBaseToolbarConfigurations] instance as value + /// To pass the [QuillToolbarConfigurations] instance as value /// instead of creating new widget static QuillBaseToolbarProvider value({ - required QuillBaseToolbarConfigurations value, + required QuillToolbarConfigurations value, required Widget child, }) { return QuillBaseToolbarProvider( diff --git a/test/bug_fix_test.dart b/test/bug_fix_test.dart index 2b804bae9..5867f67c4 100644 --- a/test/bug_fix_test.dart +++ b/test/bug_fix_test.dart @@ -16,8 +16,8 @@ void main() { await tester.pumpWidget( MaterialApp( - home: QuillToolbar( - configurations: QuillToolbarConfigurations( + home: QuillSimpleToolbar( + configurations: QuillSimpleToolbarConfigurations( controller: controller, showRedo: false, customButtons: const [ @@ -40,7 +40,7 @@ void main() { // builtinFinder.evaluate().first.widget as QuillToolbarIconButton; final customFinder = find.descendant( - of: find.byType(QuillBaseToolbar), + of: find.byType(QuillToolbar), matching: find.byWidgetPredicate((widget) => widget is QuillToolbarIconButton && widget.tooltip == tooltip), matchRoot: true); diff --git a/version.dart b/version.dart index 24c648ada..a2833398e 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev-2'; +const version = '9.0.0-dev-3'; From 0d39d9d4e91c4e467a65996562b8779c541b5397 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 12:26:06 +0300 Subject: [PATCH 24/86] 3 --- .../lib/presentation/quill/quill_toolbar.dart | 24 ++++--- .../{base.dart => base_configurations.dart} | 0 ....dart => clear_format_configurations.dart} | 0 .../{color.dart => color_configurations.dart} | 2 +- ...dart => custom_button_configurations.dart} | 2 +- ...y.dart => font_family_configurations.dart} | 0 ...ize.dart => font_size_configurations.dart} | 0 ...story.dart => history_configurations.dart} | 0 ...indent.dart => indent_configurations.dart} | 2 +- ...2.dart => link_style2_configurations.dart} | 2 +- ...le.dart => link_style_configurations.dart} | 0 ...search.dart => search_configurations.dart} | 0 ...t => select_alignment_configurations.dart} | 2 +- ...> select_header_style_configurations.dart} | 0 ... => toggle_check_list_configurations.dart} | 0 ....dart => toggle_style_configurations.dart} | 2 +- .../simple_toolbar_configurations.dart | 66 ++++++++++--------- .../toolbar/toolbar_configurations.dart | 1 - .../toolbar_shared_configurations.dart | 4 -- lib/src/widgets/toolbar/base_toolbar.dart | 4 +- .../toolbar/buttons/font_family_button.dart | 2 +- .../toolbar/buttons/indent_button.dart | 2 +- .../buttons/select_alignment_buttons.dart | 54 +++++++++++++++ ...dart => select_alignment_old_buttons.dart} | 16 +++-- .../buttons/select_header_style_button.dart | 48 +++++++------- .../buttons/toggle_check_list_button.dart | 4 +- .../toolbar/buttons/toggle_style_button.dart | 13 +++- lib/src/widgets/toolbar/simple_toolbar.dart | 11 +--- 28 files changed, 159 insertions(+), 102 deletions(-) rename lib/src/models/config/toolbar/buttons/{base.dart => base_configurations.dart} (100%) rename lib/src/models/config/toolbar/buttons/{clear_format.dart => clear_format_configurations.dart} (100%) rename lib/src/models/config/toolbar/buttons/{color.dart => color_configurations.dart} (97%) rename lib/src/models/config/toolbar/buttons/{custom_button.dart => custom_button_configurations.dart} (95%) rename lib/src/models/config/toolbar/buttons/{font_family.dart => font_family_configurations.dart} (100%) rename lib/src/models/config/toolbar/buttons/{font_size.dart => font_size_configurations.dart} (100%) rename lib/src/models/config/toolbar/buttons/{history.dart => history_configurations.dart} (100%) rename lib/src/models/config/toolbar/buttons/{indent.dart => indent_configurations.dart} (94%) rename lib/src/models/config/toolbar/buttons/{link_style2.dart => link_style2_configurations.dart} (97%) rename lib/src/models/config/toolbar/buttons/{link_style.dart => link_style_configurations.dart} (100%) rename lib/src/models/config/toolbar/buttons/{search.dart => search_configurations.dart} (100%) rename lib/src/models/config/toolbar/buttons/{select_alignment.dart => select_alignment_configurations.dart} (98%) rename lib/src/models/config/toolbar/buttons/{select_header_style.dart => select_header_style_configurations.dart} (100%) rename lib/src/models/config/toolbar/buttons/{toggle_check_list.dart => toggle_check_list_configurations.dart} (100%) rename lib/src/models/config/toolbar/buttons/{toggle_style.dart => toggle_style_configurations.dart} (96%) create mode 100644 lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart rename lib/src/widgets/toolbar/buttons/{select_alignment_button.dart => select_alignment_old_buttons.dart} (95%) diff --git a/example/lib/presentation/quill/quill_toolbar.dart b/example/lib/presentation/quill/quill_toolbar.dart index bf79b5da3..303e65875 100644 --- a/example/lib/presentation/quill/quill_toolbar.dart +++ b/example/lib/presentation/quill/quill_toolbar.dart @@ -10,7 +10,6 @@ import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart' show getApplicationDocumentsDirectory; -import '../extensions/scaffold_messenger.dart'; import '../settings/cubit/settings_cubit.dart'; import 'embeds/timestamp_embed.dart'; @@ -106,12 +105,21 @@ class MyQuillToolbar extends StatelessWidget { multiRowsDisplay: false, buttonOptions: const QuillToolbarButtonOptions( base: QuillToolbarBaseButtonOptions( - globalIconSize: 30, + globalIconSize: 20, ), ), childrenBuilder: (context) { - final controller = context.requireQuillController; return [ + IconButton( + onPressed: () { + context.read().updateSettings( + state.copyWith(useCustomQuillToolbar: false)); + }, + icon: const Icon( + Icons.width_normal, + size: 16, + ), + ), QuillToolbarImageButton( controller: controller, options: const QuillToolbarImageButtonOptions(), @@ -238,7 +246,6 @@ class MyQuillToolbar extends StatelessWidget { QuillToolbarCustomButtonOptions( icon: const Icon(Icons.add_alarm_rounded), onPressed: () { - final controller = context.requireQuillController; controller.document .insert(controller.selection.extentOffset, '\n'); controller.updateSelection( @@ -282,13 +289,10 @@ class MyQuillToolbar extends StatelessWidget { }, ), QuillToolbarCustomButtonOptions( - icon: const Icon(Icons.ac_unit), + icon: const Icon(Icons.dashboard_customize), onPressed: () { - ScaffoldMessenger.of(context) - ..clearSnackBars() - ..showText( - 'Custom button!', - ); + context.read().updateSettings( + state.copyWith(useCustomQuillToolbar: true)); }, ), ], diff --git a/lib/src/models/config/toolbar/buttons/base.dart b/lib/src/models/config/toolbar/buttons/base_configurations.dart similarity index 100% rename from lib/src/models/config/toolbar/buttons/base.dart rename to lib/src/models/config/toolbar/buttons/base_configurations.dart diff --git a/lib/src/models/config/toolbar/buttons/clear_format.dart b/lib/src/models/config/toolbar/buttons/clear_format_configurations.dart similarity index 100% rename from lib/src/models/config/toolbar/buttons/clear_format.dart rename to lib/src/models/config/toolbar/buttons/clear_format_configurations.dart diff --git a/lib/src/models/config/toolbar/buttons/color.dart b/lib/src/models/config/toolbar/buttons/color_configurations.dart similarity index 97% rename from lib/src/models/config/toolbar/buttons/color.dart rename to lib/src/models/config/toolbar/buttons/color_configurations.dart index edb751424..04e45451c 100644 --- a/lib/src/models/config/toolbar/buttons/color.dart +++ b/lib/src/models/config/toolbar/buttons/color_configurations.dart @@ -2,7 +2,7 @@ import 'package:flutter/widgets.dart' show Color; import '../../../../widgets/others/controller.dart'; import '../../quill_shared_configurations.dart' show QuillSharedConfigurations; -import 'base.dart'; +import 'base_configurations.dart'; class QuillToolbarColorButtonExtraOptions extends QuillToolbarBaseButtonExtraOptions { diff --git a/lib/src/models/config/toolbar/buttons/custom_button.dart b/lib/src/models/config/toolbar/buttons/custom_button_configurations.dart similarity index 95% rename from lib/src/models/config/toolbar/buttons/custom_button.dart rename to lib/src/models/config/toolbar/buttons/custom_button_configurations.dart index 9a862e837..3c6f3d7b8 100644 --- a/lib/src/models/config/toolbar/buttons/custom_button.dart +++ b/lib/src/models/config/toolbar/buttons/custom_button_configurations.dart @@ -1,6 +1,6 @@ import 'package:flutter/widgets.dart' show VoidCallback, Widget; -import 'base.dart'; +import 'base_configurations.dart'; class QuillToolbarCustomButtonExtraOptions extends QuillToolbarBaseButtonExtraOptions { diff --git a/lib/src/models/config/toolbar/buttons/font_family.dart b/lib/src/models/config/toolbar/buttons/font_family_configurations.dart similarity index 100% rename from lib/src/models/config/toolbar/buttons/font_family.dart rename to lib/src/models/config/toolbar/buttons/font_family_configurations.dart diff --git a/lib/src/models/config/toolbar/buttons/font_size.dart b/lib/src/models/config/toolbar/buttons/font_size_configurations.dart similarity index 100% rename from lib/src/models/config/toolbar/buttons/font_size.dart rename to lib/src/models/config/toolbar/buttons/font_size_configurations.dart diff --git a/lib/src/models/config/toolbar/buttons/history.dart b/lib/src/models/config/toolbar/buttons/history_configurations.dart similarity index 100% rename from lib/src/models/config/toolbar/buttons/history.dart rename to lib/src/models/config/toolbar/buttons/history_configurations.dart diff --git a/lib/src/models/config/toolbar/buttons/indent.dart b/lib/src/models/config/toolbar/buttons/indent_configurations.dart similarity index 94% rename from lib/src/models/config/toolbar/buttons/indent.dart rename to lib/src/models/config/toolbar/buttons/indent_configurations.dart index 66700c71d..4328796ad 100644 --- a/lib/src/models/config/toolbar/buttons/indent.dart +++ b/lib/src/models/config/toolbar/buttons/indent_configurations.dart @@ -1,6 +1,6 @@ import 'package:flutter/foundation.dart'; -import 'base.dart'; +import 'base_configurations.dart'; class QuillToolbarIndentButtonExtraOptions extends QuillToolbarBaseButtonExtraOptions { diff --git a/lib/src/models/config/toolbar/buttons/link_style2.dart b/lib/src/models/config/toolbar/buttons/link_style2_configurations.dart similarity index 97% rename from lib/src/models/config/toolbar/buttons/link_style2.dart rename to lib/src/models/config/toolbar/buttons/link_style2_configurations.dart index 750141438..6c977f643 100644 --- a/lib/src/models/config/toolbar/buttons/link_style2.dart +++ b/lib/src/models/config/toolbar/buttons/link_style2_configurations.dart @@ -1,7 +1,7 @@ import 'package:flutter/widgets.dart'; import '../../../themes/quill_dialog_theme.dart'; -import 'base.dart'; +import 'base_configurations.dart'; class QuillToolbarLinkStyleButton2ExtraOptions extends QuillToolbarBaseButtonExtraOptions { diff --git a/lib/src/models/config/toolbar/buttons/link_style.dart b/lib/src/models/config/toolbar/buttons/link_style_configurations.dart similarity index 100% rename from lib/src/models/config/toolbar/buttons/link_style.dart rename to lib/src/models/config/toolbar/buttons/link_style_configurations.dart diff --git a/lib/src/models/config/toolbar/buttons/search.dart b/lib/src/models/config/toolbar/buttons/search_configurations.dart similarity index 100% rename from lib/src/models/config/toolbar/buttons/search.dart rename to lib/src/models/config/toolbar/buttons/search_configurations.dart diff --git a/lib/src/models/config/toolbar/buttons/select_alignment.dart b/lib/src/models/config/toolbar/buttons/select_alignment_configurations.dart similarity index 98% rename from lib/src/models/config/toolbar/buttons/select_alignment.dart rename to lib/src/models/config/toolbar/buttons/select_alignment_configurations.dart index 0a90d350b..7870e9a15 100644 --- a/lib/src/models/config/toolbar/buttons/select_alignment.dart +++ b/lib/src/models/config/toolbar/buttons/select_alignment_configurations.dart @@ -1,5 +1,5 @@ import 'package:flutter/widgets.dart' show IconData, immutable; -import 'base.dart'; +import 'base_configurations.dart'; class QuillToolbarSelectAlignmentButtonExtraOptions extends QuillToolbarBaseButtonExtraOptions { diff --git a/lib/src/models/config/toolbar/buttons/select_header_style.dart b/lib/src/models/config/toolbar/buttons/select_header_style_configurations.dart similarity index 100% rename from lib/src/models/config/toolbar/buttons/select_header_style.dart rename to lib/src/models/config/toolbar/buttons/select_header_style_configurations.dart diff --git a/lib/src/models/config/toolbar/buttons/toggle_check_list.dart b/lib/src/models/config/toolbar/buttons/toggle_check_list_configurations.dart similarity index 100% rename from lib/src/models/config/toolbar/buttons/toggle_check_list.dart rename to lib/src/models/config/toolbar/buttons/toggle_check_list_configurations.dart diff --git a/lib/src/models/config/toolbar/buttons/toggle_style.dart b/lib/src/models/config/toolbar/buttons/toggle_style_configurations.dart similarity index 96% rename from lib/src/models/config/toolbar/buttons/toggle_style.dart rename to lib/src/models/config/toolbar/buttons/toggle_style_configurations.dart index 0d58fdca9..4ea2ea0f0 100644 --- a/lib/src/models/config/toolbar/buttons/toggle_style.dart +++ b/lib/src/models/config/toolbar/buttons/toggle_style_configurations.dart @@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' show Color; -import 'base.dart'; +import 'base_configurations.dart'; class QuillToolbarToggleStyleButtonExtraOptions extends QuillToolbarBaseButtonExtraOptions diff --git a/lib/src/models/config/toolbar/simple_toolbar_configurations.dart b/lib/src/models/config/toolbar/simple_toolbar_configurations.dart index e946a4f09..62a53ab51 100644 --- a/lib/src/models/config/toolbar/simple_toolbar_configurations.dart +++ b/lib/src/models/config/toolbar/simple_toolbar_configurations.dart @@ -7,39 +7,39 @@ import '../../../widgets/others/controller.dart'; import '../../../widgets/others/embeds.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'; -import 'buttons/indent.dart'; -import 'buttons/link_style.dart'; -import 'buttons/link_style2.dart'; -import 'buttons/search.dart'; -import 'buttons/select_alignment.dart'; -import 'buttons/select_header_style.dart'; -import 'buttons/toggle_check_list.dart'; -import 'buttons/toggle_style.dart'; +import 'buttons/base_configurations.dart'; +import 'buttons/clear_format_configurations.dart'; +import 'buttons/color_configurations.dart'; +import 'buttons/custom_button_configurations.dart'; +import 'buttons/font_family_configurations.dart'; +import 'buttons/font_size_configurations.dart'; +import 'buttons/history_configurations.dart'; +import 'buttons/indent_configurations.dart'; +import 'buttons/link_style_configurations.dart'; +import 'buttons/link_style2_configurations.dart'; +import 'buttons/search_configurations.dart'; +import 'buttons/select_alignment_configurations.dart'; +import 'buttons/select_header_style_configurations.dart'; +import 'buttons/toggle_check_list_configurations.dart'; +import 'buttons/toggle_style_configurations.dart'; import 'toolbar_shared_configurations.dart'; 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'; -export './buttons/indent.dart'; -export './buttons/link_style.dart'; -export './buttons/link_style2.dart'; -export './buttons/search.dart'; -export './buttons/select_alignment.dart'; -export './buttons/select_header_style.dart'; -export './buttons/toggle_check_list.dart'; -export './buttons/toggle_style.dart'; +export 'buttons/base_configurations.dart'; +export 'buttons/clear_format_configurations.dart'; +export 'buttons/color_configurations.dart'; +export 'buttons/custom_button_configurations.dart'; +export 'buttons/font_family_configurations.dart'; +export 'buttons/font_size_configurations.dart'; +export 'buttons/history_configurations.dart'; +export 'buttons/indent_configurations.dart'; +export 'buttons/link_style_configurations.dart'; +export 'buttons/link_style2_configurations.dart'; +export 'buttons/search_configurations.dart'; +export 'buttons/select_alignment_configurations.dart'; +export 'buttons/select_header_style_configurations.dart'; +export 'buttons/toggle_check_list_configurations.dart'; +export 'buttons/toggle_style_configurations.dart'; /// The default size of the icon of a button. const double kDefaultIconSize = 18; @@ -73,6 +73,7 @@ class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { super.toolbarIconAlignment = WrapAlignment.center, super.toolbarIconCrossAlignment = WrapCrossAlignment.center, super.buttonOptions = const QuillToolbarButtonOptions(), + this.customButtons = const [], super.multiRowsDisplay = true, this.fontSizesValues, this.showDividers = true, @@ -107,7 +108,6 @@ class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { this.showSubscript = true, this.showSuperscript = true, this.linkStyleType = LinkStyleType.original, - super.customButtons = const [], /// The decoration to use for the toolbar. super.decoration, @@ -167,6 +167,9 @@ class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { /// ``` final Map? fontSizesValues; + /// List of custom buttons + final List customButtons; + final bool showDividers; final bool showFontFamily; final bool showFontSize; @@ -179,6 +182,7 @@ class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { final bool showColorButton; final bool showBackgroundColorButton; final bool showClearFormat; + final bool showAlignmentButtons; final bool showLeftAlignment; final bool showCenterAlignment; diff --git a/lib/src/models/config/toolbar/toolbar_configurations.dart b/lib/src/models/config/toolbar/toolbar_configurations.dart index 187a61176..15e675fd7 100644 --- a/lib/src/models/config/toolbar/toolbar_configurations.dart +++ b/lib/src/models/config/toolbar/toolbar_configurations.dart @@ -14,7 +14,6 @@ class QuillToolbarConfigurations extends QuillSharedToolbarProperties { super.toolbarIconAlignment = WrapAlignment.center, super.toolbarIconCrossAlignment = WrapCrossAlignment.center, super.color, - super.customButtons = const [], super.sectionDividerColor, super.sectionDividerSpace, super.linkDialogAction, diff --git a/lib/src/models/config/toolbar/toolbar_shared_configurations.dart b/lib/src/models/config/toolbar/toolbar_shared_configurations.dart index d563f4dfd..166a4a95c 100644 --- a/lib/src/models/config/toolbar/toolbar_shared_configurations.dart +++ b/lib/src/models/config/toolbar/toolbar_shared_configurations.dart @@ -13,7 +13,6 @@ abstract class QuillSharedToolbarProperties extends Equatable { this.toolbarIconAlignment = WrapAlignment.center, this.toolbarIconCrossAlignment = WrapCrossAlignment.center, this.color, - this.customButtons = const [], this.sectionDividerColor, this.sectionDividerSpace, this.linkDialogAction, @@ -36,9 +35,6 @@ abstract class QuillSharedToolbarProperties extends Equatable { /// is given. final Color? color; - /// List of custom buttons - final List customButtons; - /// The color to use when painting the toolbar section divider. /// /// If this is null, then the [DividerThemeData.color] is used. If that is diff --git a/lib/src/widgets/toolbar/base_toolbar.dart b/lib/src/widgets/toolbar/base_toolbar.dart index 59efda0c5..f8bf5a098 100644 --- a/lib/src/widgets/toolbar/base_toolbar.dart +++ b/lib/src/widgets/toolbar/base_toolbar.dart @@ -6,7 +6,7 @@ import '../../l10n/widgets/localizations.dart'; import '../../models/config/toolbar/toolbar_configurations.dart'; import 'buttons/arrow_indicated_list_button.dart'; -export '../../models/config/toolbar/buttons/base.dart'; +export '../../models/config/toolbar/buttons/base_configurations.dart'; export '../../models/config/toolbar/simple_toolbar_configurations.dart'; export 'buttons/clear_format_button.dart'; export 'buttons/color/color_button.dart'; @@ -19,7 +19,7 @@ export 'buttons/link_style2_button.dart'; export 'buttons/link_style_button.dart'; export 'buttons/quill_icon_button.dart'; export 'buttons/search/search_button.dart'; -export 'buttons/select_alignment_button.dart'; +export 'buttons/select_alignment_old_buttons.dart'; export 'buttons/select_header_style_buttons.dart'; export 'buttons/toggle_check_list_button.dart'; export 'buttons/toggle_style_button.dart'; diff --git a/lib/src/widgets/toolbar/buttons/font_family_button.dart b/lib/src/widgets/toolbar/buttons/font_family_button.dart index 40c62990c..b173a4f12 100644 --- a/lib/src/widgets/toolbar/buttons/font_family_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_family_button.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import '../../../../extensions.dart'; import '../../../extensions/quill_provider.dart'; import '../../../l10n/extensions/localizations.dart'; -import '../../../models/config/toolbar/buttons/font_family.dart'; +import '../../../models/config/toolbar/buttons/font_family_configurations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; diff --git a/lib/src/widgets/toolbar/buttons/indent_button.dart b/lib/src/widgets/toolbar/buttons/indent_button.dart index 4d81b5c7e..4a35a5710 100644 --- a/lib/src/widgets/toolbar/buttons/indent_button.dart +++ b/lib/src/widgets/toolbar/buttons/indent_button.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import '../../../extensions/quill_provider.dart'; import '../../../l10n/extensions/localizations.dart'; -import '../../../models/config/toolbar/buttons/indent.dart'; +import '../../../models/config/toolbar/buttons/indent_configurations.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../others/controller.dart'; import '../base_toolbar.dart' diff --git a/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart b/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart new file mode 100644 index 000000000..51fe901b2 --- /dev/null +++ b/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; + +import '../../../models/config/toolbar/buttons/select_alignment_configurations.dart'; +import '../../../models/config/toolbar/buttons/toggle_style_configurations.dart'; +import '../../../models/documents/attribute.dart'; +import '../../others/controller.dart'; +import 'toggle_style_button.dart'; + +enum _AlignmentOptions { + left(attribute: Attribute.leftAlignment), + center(attribute: Attribute.centerAlignment), + right(attribute: Attribute.rightAlignment), + justifyMinWidth(attribute: Attribute.justifyAlignment); + + const _AlignmentOptions({required this.attribute}); + + final Attribute attribute; +} + +class QuillToolbarSelectAlignmentButtons extends StatelessWidget { + const QuillToolbarSelectAlignmentButtons({ + required this.controller, + required this.options, + this.showLeftAlignment, + this.showCenterAlignment, + this.showRightAlignment, + this.showJustifyAlignment, + this.padding, + super.key, + }); + + final QuillController controller; + final QuillToolbarSelectAlignmentButtonOptions options; + + final bool? showLeftAlignment; + final bool? showCenterAlignment; + final bool? showRightAlignment; + final bool? showJustifyAlignment; + final EdgeInsetsGeometry? padding; + + @override + Widget build(BuildContext context) { + return Row( + mainAxisSize: MainAxisSize.min, + children: _AlignmentOptions.values + .map((e) => QuillToolbarToggleStyleButton( + options: const QuillToolbarToggleStyleButtonOptions(), + controller: controller, + attribute: e.attribute, + )) + .toList(), + ); + } +} diff --git a/lib/src/widgets/toolbar/buttons/select_alignment_button.dart b/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart similarity index 95% rename from lib/src/widgets/toolbar/buttons/select_alignment_button.dart rename to lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart index 4d7f8bcaa..6cb5617b0 100644 --- a/lib/src/widgets/toolbar/buttons/select_alignment_button.dart +++ b/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart @@ -10,8 +10,9 @@ import '../../../utils/widgets.dart'; import '../../others/controller.dart'; import '../base_toolbar.dart'; -class QuillToolbarSelectAlignmentButton extends StatefulWidget { - const QuillToolbarSelectAlignmentButton({ +@Deprecated('This button has been deprecated, use') +class QuillToolbarSelectAlignmentOldButtons extends StatefulWidget { + const QuillToolbarSelectAlignmentOldButtons({ required this.controller, required this.options, this.showLeftAlignment, @@ -32,12 +33,12 @@ class QuillToolbarSelectAlignmentButton extends StatefulWidget { final EdgeInsetsGeometry? padding; @override - QuillToolbarSelectAlignmentButtonState createState() => - QuillToolbarSelectAlignmentButtonState(); + QuillToolbarSelectAlignmentOldButtonsState createState() => + QuillToolbarSelectAlignmentOldButtonsState(); } -class QuillToolbarSelectAlignmentButtonState - extends State { +class QuillToolbarSelectAlignmentOldButtonsState + extends State { Attribute? _value; Style get _selectionStyle => controller.getSelectionStyle(); @@ -137,7 +138,8 @@ class QuillToolbarSelectAlignmentButtonState } @override - void didUpdateWidget(covariant QuillToolbarSelectAlignmentButton oldWidget) { + void didUpdateWidget( + covariant QuillToolbarSelectAlignmentOldButtons oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.controller != controller) { oldWidget.controller.removeListener(_didChangeEditingValue); diff --git a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart index 41dca31ae..4016147d8 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import '../../../../translations.dart'; -import '../../../models/config/toolbar/buttons/select_header_style.dart'; +import '../../../models/config/toolbar/buttons/select_header_style_configurations.dart'; import '../../../models/documents/attribute.dart'; import '../../others/controller.dart'; -enum QuillToolbarSelectHeaderStyleButtonOptions { +enum _HeaderStyleOptions { normal, headingOne, headingTwo, @@ -29,7 +29,7 @@ class QuillToolbarSelectHeaderStyleButton extends StatefulWidget { class _QuillToolbarSelectHeaderStyleButtonState extends State { - var _selectedItem = QuillToolbarSelectHeaderStyleButtonOptions.normal; + var _selectedItem = _HeaderStyleOptions.normal; @override void initState() { super.initState(); @@ -55,47 +55,43 @@ class _QuillToolbarSelectHeaderStyleButtonState Attribute.header; } - String _label(QuillToolbarSelectHeaderStyleButtonOptions value) { + String _label(_HeaderStyleOptions value) { final label = switch (value) { - QuillToolbarSelectHeaderStyleButtonOptions.normal => context.loc.normal, - QuillToolbarSelectHeaderStyleButtonOptions.headingOne => - context.loc.heading1, - QuillToolbarSelectHeaderStyleButtonOptions.headingTwo => - context.loc.heading2, - QuillToolbarSelectHeaderStyleButtonOptions.headingThree => - context.loc.heading3, + _HeaderStyleOptions.normal => context.loc.normal, + _HeaderStyleOptions.headingOne => context.loc.heading1, + _HeaderStyleOptions.headingTwo => context.loc.heading2, + _HeaderStyleOptions.headingThree => context.loc.heading3, }; return label; } - Attribute? getAttributeByOptionsItem( - QuillToolbarSelectHeaderStyleButtonOptions option) { + Attribute? getAttributeByOptionsItem(_HeaderStyleOptions option) { return switch (option) { - QuillToolbarSelectHeaderStyleButtonOptions.normal => Attribute.header, - QuillToolbarSelectHeaderStyleButtonOptions.headingOne => Attribute.h1, - QuillToolbarSelectHeaderStyleButtonOptions.headingTwo => Attribute.h2, - QuillToolbarSelectHeaderStyleButtonOptions.headingThree => Attribute.h3, + _HeaderStyleOptions.normal => Attribute.header, + _HeaderStyleOptions.headingOne => Attribute.h1, + _HeaderStyleOptions.headingTwo => Attribute.h2, + _HeaderStyleOptions.headingThree => Attribute.h3, }; } - QuillToolbarSelectHeaderStyleButtonOptions _getOptionsItemByAttribute( + _HeaderStyleOptions _getOptionsItemByAttribute( Attribute? attribute) { return switch (attribute) { - Attribute.h1 => QuillToolbarSelectHeaderStyleButtonOptions.headingOne, - Attribute.h2 => QuillToolbarSelectHeaderStyleButtonOptions.headingTwo, - Attribute.h2 => QuillToolbarSelectHeaderStyleButtonOptions.headingThree, - Attribute() => QuillToolbarSelectHeaderStyleButtonOptions.normal, - null => QuillToolbarSelectHeaderStyleButtonOptions.normal, + Attribute.h1 => _HeaderStyleOptions.headingOne, + Attribute.h2 => _HeaderStyleOptions.headingTwo, + Attribute.h2 => _HeaderStyleOptions.headingThree, + Attribute() => _HeaderStyleOptions.normal, + null => _HeaderStyleOptions.normal, }; } @override Widget build(BuildContext context) { - return DropdownButton( + return DropdownButton<_HeaderStyleOptions>( value: _selectedItem, - items: QuillToolbarSelectHeaderStyleButtonOptions.values + items: _HeaderStyleOptions.values .map( - (e) => DropdownMenuItem( + (e) => DropdownMenuItem<_HeaderStyleOptions>( value: e, child: Text(_label(e)), onTap: () { diff --git a/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart b/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart index db1980e5f..2776cbc2b 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import '../../../extensions/quill_provider.dart'; import '../../../l10n/extensions/localizations.dart'; -import '../../../models/config/toolbar/buttons/base.dart'; -import '../../../models/config/toolbar/buttons/toggle_check_list.dart'; +import '../../../models/config/toolbar/buttons/base_configurations.dart'; +import '../../../models/config/toolbar/buttons/toggle_check_list_configurations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; diff --git a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart index 67982e28e..4ed40f18b 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart @@ -85,7 +85,7 @@ class QuillToolbarToggleStyleButtonState context.requireQuillToolbarBaseButtonOptions.iconTheme; } - (String?, IconData) get _defaultTooltipAndIconData { + (String, IconData) get _defaultTooltipAndIconData { switch (widget.attribute.key) { case 'bold': return (context.loc.bold, Icons.format_bold); @@ -115,6 +115,14 @@ class QuillToolbarToggleStyleButtonState return (context.loc.codeBlock, Icons.code); case 'blockquote': return (context.loc.quote, Icons.format_quote); + case 'align': + return switch (widget.attribute.value) { + 'left' => (context.loc.alignLeft, Icons.format_align_left), + 'right' => (context.loc.alignRight, Icons.format_align_right), + 'center' => (context.loc.alignCenter, Icons.format_align_center), + Object() => (context.loc.alignCenter, Icons.format_align_center), + null => (context.loc.alignCenter, Icons.format_align_center), + }; default: throw ArgumentError( 'Could not find the default tooltip for ' @@ -203,7 +211,8 @@ class QuillToolbarToggleStyleButtonState bool _getIsToggled(Map attrs) { if (widget.attribute.key == Attribute.list.key || - widget.attribute.key == Attribute.script.key) { + widget.attribute.key == Attribute.script.key || + widget.attribute.key == Attribute.align.key) { final attribute = attrs[widget.attribute.key]; if (attribute == null) { return false; diff --git a/lib/src/widgets/toolbar/simple_toolbar.dart b/lib/src/widgets/toolbar/simple_toolbar.dart index 57644056e..094b65797 100644 --- a/lib/src/widgets/toolbar/simple_toolbar.dart +++ b/lib/src/widgets/toolbar/simple_toolbar.dart @@ -6,6 +6,7 @@ import '../../models/config/toolbar/toolbar_configurations.dart'; import '../../models/documents/attribute.dart'; import '../utils/provider.dart'; import 'base_toolbar.dart'; +import 'buttons/select_alignment_buttons.dart'; import 'buttons/select_header_style_button.dart'; class QuillSimpleToolbar extends StatelessWidget @@ -58,7 +59,6 @@ class QuillSimpleToolbar extends StatelessWidget toolbarSectionSpacing: configurations.toolbarSectionSpacing, toolbarIconAlignment: configurations.toolbarIconAlignment, toolbarIconCrossAlignment: configurations.toolbarIconCrossAlignment, - customButtons: configurations.customButtons, linkDialogAction: configurations.linkDialogAction, multiRowsDisplay: configurations.multiRowsDisplay, sectionDividerColor: configurations.sectionDividerColor, @@ -246,19 +246,12 @@ class QuillSimpleToolbar extends StatelessWidget space: configurations.sectionDividerSpace, ), if (configurations.showAlignmentButtons) ...[ - QuillToolbarSelectAlignmentButton( + QuillToolbarSelectAlignmentButtons( controller: toolbarConfigurations .buttonOptions.selectAlignmentButtons.controller ?? globalController, options: toolbarConfigurations .buttonOptions.selectAlignmentButtons, - // tooltips: Map.of(buttonTooltips) - // ..removeWhere((key, value) => ![ - // ToolbarButtons.leftAlignment, - // ToolbarButtons.centerAlignment, - // ToolbarButtons.rightAlignment, - // ToolbarButtons.justifyAlignment, - // ].contains(key)), showLeftAlignment: configurations.showLeftAlignment, showCenterAlignment: configurations.showCenterAlignment, showRightAlignment: configurations.showRightAlignment, From d67bd71ca487036b53f580a07b67d65f6bcecfc2 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 12:37:01 +0300 Subject: [PATCH 25/86] 3+ --- example/pubspec.yaml | 10 +- lib/flutter_quill.dart | 2 +- .../models/config/editor/configurations.dart | 4 +- .../simple_toolbar_configurations.dart | 4 +- lib/src/widgets/editor/editor.dart | 2 +- lib/src/widgets/others/text_block.dart | 8 +- .../raw_editor/raw_editor_render_object.dart | 2 +- .../widgets/raw_editor/raw_editor_state.dart | 4 +- .../buttons/select_alignment_old_buttons.dart | 514 +++++++++--------- 9 files changed, 271 insertions(+), 279 deletions(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 14d582af2..731d56459 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -24,10 +24,7 @@ dependencies: cross_file: ^0.3.3+6 cached_network_image: ^3.3.0 - gal_linux: - git: - url: https://github.com/freshtechtips/gal-linux.git - ref: main + gal_linux: ^0.0.1-dev # Bloc libraries bloc: ^8.1.2 @@ -60,11 +57,6 @@ dependency_overrides: quill_html_converter: path: ../packages/quill_html_converter - gal: - git: - url: https://github.com/natsuk4ze/gal.git - ref: plugin_platform_interface - dev_dependencies: flutter_test: diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index 6a98667f8..9d0b04868 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -22,10 +22,10 @@ export 'src/models/structs/vertical_spacing.dart'; export 'src/models/themes/quill_dialog_theme.dart'; export 'src/models/themes/quill_icon_theme.dart'; export 'src/utils/embeds.dart'; +export 'src/widgets/editor/editor.dart'; export 'src/widgets/others/controller.dart'; export 'src/widgets/others/cursor.dart'; export 'src/widgets/others/default_styles.dart'; -export 'src/widgets/editor/editor.dart'; export 'src/widgets/others/embeds.dart'; export 'src/widgets/others/link.dart' show LinkActionPickerDelegate, LinkMenuAction; diff --git a/lib/src/models/config/editor/configurations.dart b/lib/src/models/config/editor/configurations.dart index 23d80e116..ec793fa5e 100644 --- a/lib/src/models/config/editor/configurations.dart +++ b/lib/src/models/config/editor/configurations.dart @@ -6,11 +6,11 @@ import 'package:flutter/material.dart' import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart' show experimental; +import '../../../widgets/editor/editor.dart'; +import '../../../widgets/editor/editor_builder.dart'; import '../../../widgets/others/controller.dart'; import '../../../widgets/others/default_styles.dart'; import '../../../widgets/others/delegate.dart'; -import '../../../widgets/editor/editor.dart'; -import '../../../widgets/editor/editor_builder.dart'; import '../../../widgets/others/embeds.dart'; import '../../../widgets/others/link.dart'; import '../../../widgets/raw_editor/raw_editor.dart'; diff --git a/lib/src/models/config/toolbar/simple_toolbar_configurations.dart b/lib/src/models/config/toolbar/simple_toolbar_configurations.dart index 62a53ab51..bb75f4397 100644 --- a/lib/src/models/config/toolbar/simple_toolbar_configurations.dart +++ b/lib/src/models/config/toolbar/simple_toolbar_configurations.dart @@ -15,8 +15,8 @@ import 'buttons/font_family_configurations.dart'; import 'buttons/font_size_configurations.dart'; import 'buttons/history_configurations.dart'; import 'buttons/indent_configurations.dart'; -import 'buttons/link_style_configurations.dart'; import 'buttons/link_style2_configurations.dart'; +import 'buttons/link_style_configurations.dart'; import 'buttons/search_configurations.dart'; import 'buttons/select_alignment_configurations.dart'; import 'buttons/select_header_style_configurations.dart'; @@ -33,8 +33,8 @@ export 'buttons/font_family_configurations.dart'; export 'buttons/font_size_configurations.dart'; export 'buttons/history_configurations.dart'; export 'buttons/indent_configurations.dart'; -export 'buttons/link_style_configurations.dart'; export 'buttons/link_style2_configurations.dart'; +export 'buttons/link_style_configurations.dart'; export 'buttons/search_configurations.dart'; export 'buttons/select_alignment_configurations.dart'; export 'buttons/select_header_style_configurations.dart'; diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index 2fe82da09..ab07a9eaf 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -21,8 +21,8 @@ import '../others/cursor.dart'; import '../others/delegate.dart'; import '../others/embeds.dart'; import '../others/float_cursor.dart'; -import '../raw_editor/raw_editor.dart'; import '../others/text_selection.dart'; +import '../raw_editor/raw_editor.dart'; import '../utils/provider.dart'; import 'editor_builder.dart'; diff --git a/lib/src/widgets/others/text_block.dart b/lib/src/widgets/others/text_block.dart index a52ba4db2..a05d57442 100644 --- a/lib/src/widgets/others/text_block.dart +++ b/lib/src/widgets/others/text_block.dart @@ -7,16 +7,16 @@ import '../../models/documents/nodes/block.dart'; import '../../models/documents/nodes/line.dart'; import '../../models/structs/vertical_spacing.dart'; import '../../utils/delta.dart'; +import '../editor/editor.dart'; +import '../style_widgets/bullet_point.dart'; +import '../style_widgets/checkbox_point.dart'; +import '../style_widgets/number_point.dart'; import 'box.dart'; import 'controller.dart'; import 'cursor.dart'; import 'default_styles.dart'; import 'delegate.dart'; -import '../editor/editor.dart'; import 'link.dart'; -import '../style_widgets/bullet_point.dart'; -import '../style_widgets/checkbox_point.dart'; -import '../style_widgets/number_point.dart'; import 'text_line.dart'; import 'text_selection.dart'; diff --git a/lib/src/widgets/raw_editor/raw_editor_render_object.dart b/lib/src/widgets/raw_editor/raw_editor_render_object.dart index fe61fd37d..af99671fa 100644 --- a/lib/src/widgets/raw_editor/raw_editor_render_object.dart +++ b/lib/src/widgets/raw_editor/raw_editor_render_object.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart' show ViewportOffset; import '../../models/documents/document.dart'; -import '../others/cursor.dart'; import '../editor/editor.dart'; +import '../others/cursor.dart'; class QuilRawEditorMultiChildRenderObject extends MultiChildRenderObjectWidget { const QuilRawEditorMultiChildRenderObject({ diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index 2eff57861..30ccf446f 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -33,17 +33,17 @@ import '../../utils/cast.dart'; import '../../utils/delta.dart'; import '../../utils/embeds.dart'; import '../../utils/platform.dart'; +import '../editor/editor.dart'; import '../others/controller.dart'; import '../others/cursor.dart'; import '../others/default_styles.dart'; -import '../editor/editor.dart'; import '../others/keyboard_listener.dart'; import '../others/link.dart'; import '../others/proxy.dart'; -import 'quill_single_child_scroll_view.dart'; import '../others/text_block.dart'; import '../others/text_line.dart'; import '../others/text_selection.dart'; +import 'quill_single_child_scroll_view.dart'; import 'raw_editor.dart'; import 'raw_editor_actions.dart'; import 'raw_editor_render_object.dart'; diff --git a/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart b/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart index 6cb5617b0..9c4c5e31f 100644 --- a/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart +++ b/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart @@ -1,283 +1,283 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; +// import 'package:flutter/foundation.dart'; +// import 'package:flutter/material.dart'; -import '../../../extensions/quill_provider.dart'; -import '../../../l10n/extensions/localizations.dart'; -import '../../../models/documents/attribute.dart'; -import '../../../models/documents/style.dart'; -import '../../../models/themes/quill_icon_theme.dart'; -import '../../../utils/widgets.dart'; -import '../../others/controller.dart'; -import '../base_toolbar.dart'; +// import '../../../extensions/quill_provider.dart'; +// import '../../../l10n/extensions/localizations.dart'; +// import '../../../models/documents/attribute.dart'; +// import '../../../models/documents/style.dart'; +// import '../../../models/themes/quill_icon_theme.dart'; +// import '../../../utils/widgets.dart'; +// import '../../others/controller.dart'; +// import '../base_toolbar.dart'; -@Deprecated('This button has been deprecated, use') -class QuillToolbarSelectAlignmentOldButtons extends StatefulWidget { - const QuillToolbarSelectAlignmentOldButtons({ - required this.controller, - required this.options, - this.showLeftAlignment, - this.showCenterAlignment, - this.showRightAlignment, - this.showJustifyAlignment, - this.padding, - super.key, - }); +// @Deprecated('This button has been deprecated, use') +// class QuillToolbarSelectAlignmentOldButtons extends StatefulWidget { +// const QuillToolbarSelectAlignmentOldButtons({ +// required this.controller, +// required this.options, +// this.showLeftAlignment, +// this.showCenterAlignment, +// this.showRightAlignment, +// this.showJustifyAlignment, +// this.padding, +// super.key, +// }); - final QuillController controller; - final QuillToolbarSelectAlignmentButtonOptions options; +// final QuillController controller; +// final QuillToolbarSelectAlignmentButtonOptions options; - final bool? showLeftAlignment; - final bool? showCenterAlignment; - final bool? showRightAlignment; - final bool? showJustifyAlignment; - final EdgeInsetsGeometry? padding; +// final bool? showLeftAlignment; +// final bool? showCenterAlignment; +// final bool? showRightAlignment; +// final bool? showJustifyAlignment; +// final EdgeInsetsGeometry? padding; - @override - QuillToolbarSelectAlignmentOldButtonsState createState() => - QuillToolbarSelectAlignmentOldButtonsState(); -} +// @override +// QuillToolbarSelectAlignmentOldButtonsState createState() => +// QuillToolbarSelectAlignmentOldButtonsState(); +// } -class QuillToolbarSelectAlignmentOldButtonsState - extends State { - Attribute? _value; +// class QuillToolbarSelectAlignmentOldButtonsState +// extends State { +// Attribute? _value; - Style get _selectionStyle => controller.getSelectionStyle(); +// Style get _selectionStyle => controller.getSelectionStyle(); - @override - void initState() { - super.initState(); - setState(() { - _value = _selectionStyle.attributes[Attribute.align.key] ?? - Attribute.leftAlignment; - }); - controller.addListener(_didChangeEditingValue); - } +// @override +// void initState() { +// super.initState(); +// setState(() { +// _value = _selectionStyle.attributes[Attribute.align.key] ?? +// Attribute.leftAlignment; +// }); +// controller.addListener(_didChangeEditingValue); +// } - QuillToolbarSelectAlignmentButtonOptions get options { - return widget.options; - } +// QuillToolbarSelectAlignmentButtonOptions get options { +// return widget.options; +// } - QuillController get controller { - return widget.controller; - } +// QuillController get controller { +// return widget.controller; +// } - double get _iconSize { - final baseFontSize = baseButtonExtraOptions.globalIconSize; - final iconSize = options.iconSize; - return iconSize ?? baseFontSize; - } +// double get _iconSize { +// final baseFontSize = baseButtonExtraOptions.globalIconSize; +// final iconSize = options.iconSize; +// return iconSize ?? baseFontSize; +// } - double get _iconButtonFactor { - final baseIconFactor = baseButtonExtraOptions.globalIconButtonFactor; - final iconButtonFactor = options.iconButtonFactor; - return iconButtonFactor ?? baseIconFactor; - } +// double get _iconButtonFactor { +// final baseIconFactor = baseButtonExtraOptions.globalIconButtonFactor; +// final iconButtonFactor = options.iconButtonFactor; +// return iconButtonFactor ?? baseIconFactor; +// } - VoidCallback? get _afterButtonPressed { - return options.afterButtonPressed ?? - baseButtonExtraOptions.afterButtonPressed; - } +// VoidCallback? get _afterButtonPressed { +// return options.afterButtonPressed ?? +// baseButtonExtraOptions.afterButtonPressed; +// } - QuillIconTheme? get _iconTheme { - return options.iconTheme ?? baseButtonExtraOptions.iconTheme; - } +// QuillIconTheme? get _iconTheme { +// return options.iconTheme ?? baseButtonExtraOptions.iconTheme; +// } - QuillToolbarBaseButtonOptions get baseButtonExtraOptions { - return context.requireQuillToolbarBaseButtonOptions; - } +// QuillToolbarBaseButtonOptions get baseButtonExtraOptions { +// return context.requireQuillToolbarBaseButtonOptions; +// } - QuillSelectAlignmentValues get _iconsData { - final iconsData = options.iconsData; - if (iconsData != null) { - return iconsData; - } - final baseIconData = baseButtonExtraOptions.iconData; - if (baseIconData != null) { - return QuillSelectAlignmentValues( - leftAlignment: baseIconData, - centerAlignment: baseIconData, - rightAlignment: baseIconData, - justifyAlignment: baseIconData, - ); - } - return const QuillSelectAlignmentValues( - leftAlignment: Icons.format_align_left, - centerAlignment: Icons.format_align_center, - rightAlignment: Icons.format_align_right, - justifyAlignment: Icons.format_align_justify, - ); - } +// QuillSelectAlignmentValues get _iconsData { +// final iconsData = options.iconsData; +// if (iconsData != null) { +// return iconsData; +// } +// final baseIconData = baseButtonExtraOptions.iconData; +// if (baseIconData != null) { +// return QuillSelectAlignmentValues( +// leftAlignment: baseIconData, +// centerAlignment: baseIconData, +// rightAlignment: baseIconData, +// justifyAlignment: baseIconData, +// ); +// } +// return const QuillSelectAlignmentValues( +// leftAlignment: Icons.format_align_left, +// centerAlignment: Icons.format_align_center, +// rightAlignment: Icons.format_align_right, +// justifyAlignment: Icons.format_align_justify, +// ); +// } - QuillSelectAlignmentValues get _tooltips { - final tooltips = options.tooltips; - if (tooltips != null) { - return tooltips; - } - final baseToolTip = baseButtonExtraOptions.tooltip; - if (baseToolTip != null) { - return QuillSelectAlignmentValues( - leftAlignment: baseToolTip, - centerAlignment: baseToolTip, - rightAlignment: baseToolTip, - justifyAlignment: baseToolTip, - ); - } - return QuillSelectAlignmentValues( - leftAlignment: context.loc.alignLeft, - centerAlignment: context.loc.alignCenter, - rightAlignment: context.loc.alignRight, - justifyAlignment: context.loc.justifyWinWidth, - ); - } +// QuillSelectAlignmentValues get _tooltips { +// final tooltips = options.tooltips; +// if (tooltips != null) { +// return tooltips; +// } +// final baseToolTip = baseButtonExtraOptions.tooltip; +// if (baseToolTip != null) { +// return QuillSelectAlignmentValues( +// leftAlignment: baseToolTip, +// centerAlignment: baseToolTip, +// rightAlignment: baseToolTip, +// justifyAlignment: baseToolTip, +// ); +// } +// return QuillSelectAlignmentValues( +// leftAlignment: context.loc.alignLeft, +// centerAlignment: context.loc.alignCenter, +// rightAlignment: context.loc.alignRight, +// justifyAlignment: context.loc.justifyWinWidth, +// ); +// } - void _didChangeEditingValue() { - setState(() { - _value = _selectionStyle.attributes[Attribute.align.key] ?? - Attribute.leftAlignment; - }); - } +// void _didChangeEditingValue() { +// setState(() { +// _value = _selectionStyle.attributes[Attribute.align.key] ?? +// Attribute.leftAlignment; +// }); +// } - @override - void didUpdateWidget( - covariant QuillToolbarSelectAlignmentOldButtons oldWidget) { - super.didUpdateWidget(oldWidget); - if (oldWidget.controller != controller) { - oldWidget.controller.removeListener(_didChangeEditingValue); - controller.addListener(_didChangeEditingValue); - _value = _selectionStyle.attributes[Attribute.align.key] ?? - Attribute.leftAlignment; - } - } +// @override +// void didUpdateWidget( +// covariant QuillToolbarSelectAlignmentOldButtons oldWidget) { +// super.didUpdateWidget(oldWidget); +// if (oldWidget.controller != controller) { +// oldWidget.controller.removeListener(_didChangeEditingValue); +// controller.addListener(_didChangeEditingValue); +// _value = _selectionStyle.attributes[Attribute.align.key] ?? +// Attribute.leftAlignment; +// } +// } - @override - void dispose() { - controller.removeListener(_didChangeEditingValue); - super.dispose(); - } +// @override +// void dispose() { +// controller.removeListener(_didChangeEditingValue); +// super.dispose(); +// } - @override - Widget build(BuildContext context) { - final valueToText = { - if (widget.showLeftAlignment!) - Attribute.leftAlignment: Attribute.leftAlignment.value!, - if (widget.showCenterAlignment!) - Attribute.centerAlignment: Attribute.centerAlignment.value!, - if (widget.showRightAlignment!) - Attribute.rightAlignment: Attribute.rightAlignment.value!, - if (widget.showJustifyAlignment!) - Attribute.justifyAlignment: Attribute.justifyAlignment.value!, - }; +// @override +// Widget build(BuildContext context) { +// final valueToText = { +// if (widget.showLeftAlignment!) +// Attribute.leftAlignment: Attribute.leftAlignment.value!, +// if (widget.showCenterAlignment!) +// Attribute.centerAlignment: Attribute.centerAlignment.value!, +// if (widget.showRightAlignment!) +// Attribute.rightAlignment: Attribute.rightAlignment.value!, +// if (widget.showJustifyAlignment!) +// Attribute.justifyAlignment: Attribute.justifyAlignment.value!, +// }; - final valueAttribute = [ - if (widget.showLeftAlignment!) Attribute.leftAlignment, - if (widget.showCenterAlignment!) Attribute.centerAlignment, - if (widget.showRightAlignment!) Attribute.rightAlignment, - if (widget.showJustifyAlignment!) Attribute.justifyAlignment - ]; - final valueString = [ - if (widget.showLeftAlignment!) Attribute.leftAlignment.value!, - if (widget.showCenterAlignment!) Attribute.centerAlignment.value!, - if (widget.showRightAlignment!) Attribute.rightAlignment.value!, - if (widget.showJustifyAlignment!) Attribute.justifyAlignment.value!, - ]; - // final _valueToButtons = { - // if (widget.showLeftAlignment!) - // Attribute.leftAlignment: ToolbarButtons.leftAlignment, - // if (widget.showCenterAlignment!) - // Attribute.centerAlignment: ToolbarButtons.centerAlignment, - // if (widget.showRightAlignment!) - // Attribute.rightAlignment: ToolbarButtons.rightAlignment, - // if (widget.showJustifyAlignment!) - // Attribute.justifyAlignment: ToolbarButtons.justifyAlignment, - // }; +// final valueAttribute = [ +// if (widget.showLeftAlignment!) Attribute.leftAlignment, +// if (widget.showCenterAlignment!) Attribute.centerAlignment, +// if (widget.showRightAlignment!) Attribute.rightAlignment, +// if (widget.showJustifyAlignment!) Attribute.justifyAlignment +// ]; +// final valueString = [ +// if (widget.showLeftAlignment!) Attribute.leftAlignment.value!, +// if (widget.showCenterAlignment!) Attribute.centerAlignment.value!, +// if (widget.showRightAlignment!) Attribute.rightAlignment.value!, +// if (widget.showJustifyAlignment!) Attribute.justifyAlignment.value!, +// ]; +// // final _valueToButtons = { +// // if (widget.showLeftAlignment!) +// // Attribute.leftAlignment: ToolbarButtons.leftAlignment, +// // if (widget.showCenterAlignment!) +// // Attribute.centerAlignment: ToolbarButtons.centerAlignment, +// // if (widget.showRightAlignment!) +// // Attribute.rightAlignment: ToolbarButtons.rightAlignment, +// // if (widget.showJustifyAlignment!) +// // Attribute.justifyAlignment: ToolbarButtons.justifyAlignment, +// // }; - final buttonCount = ((widget.showLeftAlignment!) ? 1 : 0) + - ((widget.showCenterAlignment!) ? 1 : 0) + - ((widget.showRightAlignment!) ? 1 : 0) + - ((widget.showJustifyAlignment!) ? 1 : 0); +// final buttonCount = ((widget.showLeftAlignment!) ? 1 : 0) + +// ((widget.showCenterAlignment!) ? 1 : 0) + +// ((widget.showRightAlignment!) ? 1 : 0) + +// ((widget.showJustifyAlignment!) ? 1 : 0); - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions.childBuilder; +// final childBuilder = +// options.childBuilder ?? baseButtonExtraOptions.childBuilder; - void sharedOnPressed(int index) { - valueAttribute[index] == Attribute.leftAlignment - ? controller.formatSelection( - Attribute.clone(Attribute.align, null), - ) - : controller.formatSelection(valueAttribute[index]); - _afterButtonPressed?.call(); - } +// void sharedOnPressed(int index) { +// valueAttribute[index] == Attribute.leftAlignment +// ? controller.formatSelection( +// Attribute.clone(Attribute.align, null), +// ) +// : controller.formatSelection(valueAttribute[index]); +// _afterButtonPressed?.call(); +// } - return Row( - mainAxisSize: MainAxisSize.min, - children: List.generate(buttonCount, (index) { - if (childBuilder != null) { - return childBuilder( - QuillToolbarSelectAlignmentButtonOptions( - afterButtonPressed: _afterButtonPressed, - iconSize: _iconSize, - iconButtonFactor: _iconButtonFactor, - 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 * _iconButtonFactor, - height: _iconSize * _iconButtonFactor, - ), - child: UtilityWidgets.maybeTooltip( - message: valueString[index] == Attribute.leftAlignment.value - ? _tooltips.leftAlignment - : valueString[index] == Attribute.centerAlignment.value - ? _tooltips.centerAlignment - : valueString[index] == Attribute.rightAlignment.value - ? _tooltips.rightAlignment - : _tooltips.justifyAlignment, - child: RawMaterialButton( - hoverElevation: 0, - highlightElevation: 0, - elevation: 0, - visualDensity: VisualDensity.compact, - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(_iconTheme?.borderRadius ?? 2)), - fillColor: valueToText[_value] == valueString[index] - ? (_iconTheme?.iconSelectedFillColor ?? theme.primaryColor) - : (_iconTheme?.iconUnselectedFillColor ?? - theme.canvasColor), - onPressed: () => sharedOnPressed(index), - child: Icon( - valueString[index] == Attribute.leftAlignment.value - ? _iconsData.leftAlignment - : valueString[index] == Attribute.centerAlignment.value - ? _iconsData.centerAlignment - : valueString[index] == Attribute.rightAlignment.value - ? _iconsData.rightAlignment - : _iconsData.justifyAlignment, - size: _iconSize, - color: valueToText[_value] == valueString[index] - ? (_iconTheme?.iconSelectedColor ?? - theme.primaryIconTheme.color) - : (_iconTheme?.iconUnselectedColor ?? - theme.iconTheme.color), - ), - ), - ), - ), - ); - }), - ); - } -} +// return Row( +// mainAxisSize: MainAxisSize.min, +// children: List.generate(buttonCount, (index) { +// if (childBuilder != null) { +// return childBuilder( +// QuillToolbarSelectAlignmentButtonOptions( +// afterButtonPressed: _afterButtonPressed, +// iconSize: _iconSize, +// iconButtonFactor: _iconButtonFactor, +// 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 * _iconButtonFactor, +// height: _iconSize * _iconButtonFactor, +// ), +// child: UtilityWidgets.maybeTooltip( +// message: valueString[index] == Attribute.leftAlignment.value +// ? _tooltips.leftAlignment +// : valueString[index] == Attribute.centerAlignment.value +// ? _tooltips.centerAlignment +// : valueString[index] == Attribute.rightAlignment.value +// ? _tooltips.rightAlignment +// : _tooltips.justifyAlignment, +// child: RawMaterialButton( +// hoverElevation: 0, +// highlightElevation: 0, +// elevation: 0, +// visualDensity: VisualDensity.compact, +// shape: RoundedRectangleBorder( +// borderRadius: +// BorderRadius.circular(_iconTheme?.borderRadius ?? 2)), +// fillColor: valueToText[_value] == valueString[index] +// ? (_iconTheme?.iconSelectedFillColor ?? theme.primaryColor) +// : (_iconTheme?.iconUnselectedFillColor ?? +// theme.canvasColor), +// onPressed: () => sharedOnPressed(index), +// child: Icon( +// valueString[index] == Attribute.leftAlignment.value +// ? _iconsData.leftAlignment +// : valueString[index] == Attribute.centerAlignment.value +// ? _iconsData.centerAlignment +// : valueString[index] == Attribute.rightAlignment.value +// ? _iconsData.rightAlignment +// : _iconsData.justifyAlignment, +// size: _iconSize, +// color: valueToText[_value] == valueString[index] +// ? (_iconTheme?.iconSelectedColor ?? +// theme.primaryIconTheme.color) +// : (_iconTheme?.iconUnselectedColor ?? +// theme.iconTheme.color), +// ), +// ), +// ), +// ), +// ); +// }), +// ); +// } +// } From ec38dee3e3e355f8240a600dc062ad5ed36ffeb8 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 13:15:16 +0300 Subject: [PATCH 26/86] 3++ --- .../lib/presentation/quill/quill_screen.dart | 54 ++++++++----------- flutter_quill_extensions/README.md | 23 ++++++++ .../formula/toolbar/formula_button.dart | 3 +- .../lib/embeds/image/editor/image_embed.dart | 2 +- .../lib/embeds/image/editor/image_menu.dart | 30 +++++------ .../embeds/image/toolbar/image_button.dart | 3 +- .../others/camera_button/camera_button.dart | 3 +- .../embeds/video/toolbar/video_button.dart | 3 +- .../lib/flutter_quill_extensions.dart | 6 +-- .../l10n/generated/quill_localizations.dart | 4 +- .../generated/quill_localizations_ar.dart | 6 +-- .../generated/quill_localizations_bg.dart | 6 +-- .../generated/quill_localizations_bn.dart | 6 +-- .../generated/quill_localizations_cs.dart | 6 +-- .../generated/quill_localizations_da.dart | 6 +-- .../generated/quill_localizations_de.dart | 6 +-- .../generated/quill_localizations_en.dart | 6 +-- .../generated/quill_localizations_es.dart | 6 +-- .../generated/quill_localizations_fa.dart | 6 +-- .../generated/quill_localizations_fr.dart | 6 +-- .../generated/quill_localizations_he.dart | 6 +-- .../generated/quill_localizations_hi.dart | 6 +-- .../generated/quill_localizations_id.dart | 6 +-- .../generated/quill_localizations_it.dart | 6 +-- .../generated/quill_localizations_ja.dart | 6 +-- .../generated/quill_localizations_ko.dart | 6 +-- .../generated/quill_localizations_ms.dart | 6 +-- .../generated/quill_localizations_nl.dart | 6 +-- .../generated/quill_localizations_no.dart | 6 +-- .../generated/quill_localizations_pl.dart | 6 +-- .../generated/quill_localizations_pt.dart | 6 +-- .../generated/quill_localizations_ru.dart | 6 +-- .../generated/quill_localizations_sr.dart | 6 +-- .../generated/quill_localizations_sw.dart | 6 +-- .../generated/quill_localizations_tk.dart | 6 +-- .../generated/quill_localizations_tr.dart | 6 +-- .../generated/quill_localizations_uk.dart | 6 +-- .../generated/quill_localizations_ur.dart | 6 +-- .../generated/quill_localizations_vi.dart | 6 +-- .../generated/quill_localizations_zh.dart | 6 +-- lib/src/l10n/quill_en.arb | 4 +- .../simple_toolbar_configurations.dart | 2 +- .../toolbar/buttons/clear_format_button.dart | 3 +- .../toolbar/buttons/custom_button_button.dart | 1 - .../toolbar/buttons/history_button.dart | 3 +- .../toolbar/buttons/indent_button.dart | 3 +- .../toolbar/buttons/link_style2_button.dart | 3 +- .../toolbar/buttons/link_style_button.dart | 3 +- .../toolbar/buttons/quill_icon_button.dart | 7 +-- .../toolbar/buttons/search/search_button.dart | 3 +- .../toolbar/buttons/toggle_style_button.dart | 3 +- 51 files changed, 143 insertions(+), 203 deletions(-) diff --git a/example/lib/presentation/quill/quill_screen.dart b/example/lib/presentation/quill/quill_screen.dart index 1f504d2c1..0fc392fc4 100644 --- a/example/lib/presentation/quill/quill_screen.dart +++ b/example/lib/presentation/quill/quill_screen.dart @@ -3,7 +3,7 @@ import 'dart:convert' show jsonEncode; import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart' - show FlutterQuillEmbeds, QuillSharedExtensionsConfigurations; + show FlutterQuillEmbeds; import 'package:quill_html_converter/quill_html_converter.dart'; import 'package:share_plus/share_plus.dart' show Share; @@ -100,40 +100,28 @@ class _QuillScreenState extends State { const HomeScreenButton(), ], ), - body: QuillProvider( - configurations: const QuillConfigurations( - sharedConfigurations: QuillSharedConfigurations( - extraConfigurations: { - QuillSharedExtensionsConfigurations.key: - QuillSharedExtensionsConfigurations( - assetsPrefix: 'assets', - ), + body: Column( + children: [ + if (!_isReadOnly) + MyQuillToolbar( + controller: _controller, + focusNode: _editorFocusNode, + ), + Builder( + builder: (context) { + return Expanded( + child: MyQuillEditor( + configurations: QuillEditorConfigurations( + controller: _controller, + readOnly: _isReadOnly, + ), + scrollController: _editorScrollController, + focusNode: _editorFocusNode, + ), + ); }, ), - ), - child: Column( - children: [ - if (!_isReadOnly) - MyQuillToolbar( - controller: _controller, - focusNode: _editorFocusNode, - ), - Builder( - builder: (context) { - return Expanded( - child: MyQuillEditor( - configurations: QuillEditorConfigurations( - controller: _controller, - readOnly: _isReadOnly, - ), - scrollController: _editorScrollController, - focusNode: _editorFocusNode, - ), - ); - }, - ), - ], - ), + ], ), floatingActionButton: FloatingActionButton( child: Icon(_isReadOnly ? Icons.lock : Icons.edit), diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index 400d1e8af..b42c90def 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -16,6 +16,7 @@ to support embedding widgets like images, formulas, videos, and more. - [Embed Blocks](#embed-blocks) - [Element properties](#element-properties) - [Custom Element properties](#custom-element-properties) + - [Image Assets](#image-assets) - [Drag and drop feature](#drag-and-drop-feature) - [Features](#features) - [Contributing](#contributing) @@ -165,6 +166,28 @@ Define flutterAlignment` as follows: This works for all platforms except Web +### Image Assets + +If you want to use image assets in the Quill Editor, you need to make sure your assets folder is `assets` otherwise: + +```dart + QuillProvider( + configurations: const QuillConfigurations( + sharedConfigurations: QuillSharedConfigurations( + extraConfigurations: { + QuillSharedExtensionsConfigurations.key: + QuillSharedExtensionsConfigurations( + assetsPrefix: 'your-assets-folder-name', // Defaults to assets + ), + }, + ), + ), + child: ..., + ) +``` + +This info is needed by the package to check if it asset image to use the `AssetImage` provider + ### Drag and drop feature Currently, the drag-and-drop feature is not officially supported, but you can achieve this very easily in the following steps: diff --git a/flutter_quill_extensions/lib/embeds/formula/toolbar/formula_button.dart b/flutter_quill_extensions/lib/embeds/formula/toolbar/formula_button.dart index 8b642ed11..3be5075c1 100644 --- a/flutter_quill_extensions/lib/embeds/formula/toolbar/formula_button.dart +++ b/flutter_quill_extensions/lib/embeds/formula/toolbar/formula_button.dart @@ -91,9 +91,8 @@ class QuillToolbarFormulaButton extends StatelessWidget { } return QuillToolbarIconButton( - icon: Icon(iconData, size: iconSize, color: iconColor), + icon: Icon(iconData, size: iconSize * 1.77, color: iconColor), tooltip: tooltip, - size: iconSize * 1.77, onPressed: () => _sharedOnPressed(context), isFilled: false, ); 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 ca2234485..0bc0f8b41 100644 --- a/flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart +++ b/flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart @@ -30,7 +30,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { bool inline, TextStyle textStyle, ) { - assert(!kIsWeb, 'Please provide image EmbedBuilder for Web'); + // assert(!kIsWeb, 'Please provide image EmbedBuilder for Web'); final imageSource = standardizeImageUrl(node.value.data); final ((imageSize), margin, alignment) = getElementAttributes(node); 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 e6f0fcf6b..4bcf19b13 100644 --- a/flutter_quill_extensions/lib/embeds/image/editor/image_menu.dart +++ b/flutter_quill_extensions/lib/embeds/image/editor/image_menu.dart @@ -1,4 +1,5 @@ import 'package:flutter/cupertino.dart' show showCupertinoModalPopup; +import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart' show ImageUrl, QuillController, StyleAttribute, getEmbedNode; @@ -130,7 +131,7 @@ class ImageOptionsMenu extends StatelessWidget { await configurations.onImageRemovedCallback.call(imageSource); }, ), - ...[ + if (!kIsWeb) ListTile( leading: const Icon(Icons.save), title: Text(context.loc.save), @@ -172,23 +173,22 @@ class ImageOptionsMenu extends StatelessWidget { ); }, ), - ListTile( - leading: const Icon(Icons.zoom_in), - title: Text(context.loc.zoom), - onTap: () => Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (_) => ImageTapWrapper( - assetsPrefix: QuillSharedExtensionsConfigurations.get( - context: context) - .assetsPrefix, - imageUrl: imageSource, - configurations: configurations, - ), + ListTile( + leading: const Icon(Icons.zoom_in), + title: Text(context.loc.zoom), + onTap: () => Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (_) => ImageTapWrapper( + assetsPrefix: + QuillSharedExtensionsConfigurations.get(context: context) + .assetsPrefix, + imageUrl: imageSource, + configurations: configurations, ), ), ), - ], + ), ], ), ); 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 9f9bcc1a2..362b6ce8f 100644 --- a/flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart +++ b/flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart @@ -105,11 +105,10 @@ class QuillToolbarImageButton extends StatelessWidget { return QuillToolbarIconButton( icon: Icon( iconData, - size: iconSize, + size: iconSize * 1.77, color: iconColor, ), tooltip: tooltip, - size: iconSize * 1.77, isFilled: false, onPressed: () => _sharedOnPressed(context), ); diff --git a/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart b/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart index f96f59af1..4f7582037 100644 --- a/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart +++ b/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart @@ -98,9 +98,8 @@ class QuillToolbarCameraButton extends StatelessWidget { final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; return QuillToolbarIconButton( - icon: Icon(iconData, size: iconSize, color: iconColor), + icon: Icon(iconData, size: iconSize * 1.77, color: iconColor), tooltip: tooltip, - size: iconSize * 1.77, isFilled: false, // isDesktop(supportWeb: false) ? null : onPressed: () => _sharedOnPressed(context), 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 56e047696..3b6708b94 100644 --- a/flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart +++ b/flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart @@ -98,9 +98,8 @@ class QuillToolbarVideoButton extends StatelessWidget { } return QuillToolbarIconButton( - icon: Icon(iconData, size: iconSize, color: iconColor), + icon: Icon(iconData, size: iconSize * 1.77, color: iconColor), tooltip: tooltip, - size: iconSize * 1.77, isFilled: false, onPressed: () => _sharedOnPressed(context), ); diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index b3f7f3bd0..f63285547 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -113,8 +113,8 @@ class FlutterQuillEmbeds { /// videos iframe on the web. /// static List editorWebBuilders( - {QuillEditorWebImageEmbedConfigurations? imageEmbedConfigurations = - const QuillEditorWebImageEmbedConfigurations(), + {QuillEditorImageEmbedConfigurations? imageEmbedConfigurations = + const QuillEditorImageEmbedConfigurations(), QuillEditorWebVideoEmbedConfigurations? videoEmbedConfigurations = const QuillEditorWebVideoEmbedConfigurations()}) { if (!kIsWeb) { @@ -125,7 +125,7 @@ class FlutterQuillEmbeds { } return [ if (imageEmbedConfigurations != null) - QuillEditorWebImageEmbedBuilder( + QuillEditorImageEmbedBuilder( configurations: imageEmbedConfigurations, ), if (videoEmbedConfigurations != null) diff --git a/lib/src/l10n/generated/quill_localizations.dart b/lib/src/l10n/generated/quill_localizations.dart index e81ddc023..abd411abf 100644 --- a/lib/src/l10n/generated/quill_localizations.dart +++ b/lib/src/l10n/generated/quill_localizations.dart @@ -634,7 +634,7 @@ abstract class FlutterQuillLocalizations { /// No description provided for @takeAPhotoUsingYourCamera. /// /// In en, this message translates to: - /// **'Take a photo using your phone camera'** + /// **'Take a photo using your camera'** String get takeAPhotoUsingYourCamera; /// No description provided for @pasteAPhotoUsingALink. @@ -652,7 +652,7 @@ abstract class FlutterQuillLocalizations { /// No description provided for @recordAVideoUsingYourCamera. /// /// In en, this message translates to: - /// **'Record a video using your phone camera'** + /// **'Record a video using your camera'** String get recordAVideoUsingYourCamera; /// No description provided for @pasteAVideoUsingALink. diff --git a/lib/src/l10n/generated/quill_localizations_ar.dart b/lib/src/l10n/generated/quill_localizations_ar.dart index c8905ce79..b7211f5c4 100644 --- a/lib/src/l10n/generated/quill_localizations_ar.dart +++ b/lib/src/l10n/generated/quill_localizations_ar.dart @@ -243,8 +243,7 @@ class FlutterQuillLocalizationsAr extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -253,8 +252,7 @@ class FlutterQuillLocalizationsAr extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_bg.dart b/lib/src/l10n/generated/quill_localizations_bg.dart index 6869b457c..dd9a1bfec 100644 --- a/lib/src/l10n/generated/quill_localizations_bg.dart +++ b/lib/src/l10n/generated/quill_localizations_bg.dart @@ -245,8 +245,7 @@ class FlutterQuillLocalizationsBg extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -255,8 +254,7 @@ class FlutterQuillLocalizationsBg extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_bn.dart b/lib/src/l10n/generated/quill_localizations_bn.dart index 930d7d6c5..fb41d3c2c 100644 --- a/lib/src/l10n/generated/quill_localizations_bn.dart +++ b/lib/src/l10n/generated/quill_localizations_bn.dart @@ -245,8 +245,7 @@ class FlutterQuillLocalizationsBn extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -255,8 +254,7 @@ class FlutterQuillLocalizationsBn extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_cs.dart b/lib/src/l10n/generated/quill_localizations_cs.dart index e55d8c811..375fe13f4 100644 --- a/lib/src/l10n/generated/quill_localizations_cs.dart +++ b/lib/src/l10n/generated/quill_localizations_cs.dart @@ -245,8 +245,7 @@ class FlutterQuillLocalizationsCs extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -255,8 +254,7 @@ class FlutterQuillLocalizationsCs extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_da.dart b/lib/src/l10n/generated/quill_localizations_da.dart index b969adbc6..fc7926e87 100644 --- a/lib/src/l10n/generated/quill_localizations_da.dart +++ b/lib/src/l10n/generated/quill_localizations_da.dart @@ -243,8 +243,7 @@ class FlutterQuillLocalizationsDa extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -253,8 +252,7 @@ class FlutterQuillLocalizationsDa extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_de.dart b/lib/src/l10n/generated/quill_localizations_de.dart index ddbf7af2e..79e847b96 100644 --- a/lib/src/l10n/generated/quill_localizations_de.dart +++ b/lib/src/l10n/generated/quill_localizations_de.dart @@ -244,8 +244,7 @@ class FlutterQuillLocalizationsDe extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -254,8 +253,7 @@ class FlutterQuillLocalizationsDe extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_en.dart b/lib/src/l10n/generated/quill_localizations_en.dart index 8a6fa0dc0..192d8c6cf 100644 --- a/lib/src/l10n/generated/quill_localizations_en.dart +++ b/lib/src/l10n/generated/quill_localizations_en.dart @@ -245,8 +245,7 @@ class FlutterQuillLocalizationsEn extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -255,8 +254,7 @@ class FlutterQuillLocalizationsEn extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_es.dart b/lib/src/l10n/generated/quill_localizations_es.dart index a0b8c59dd..63c9a7669 100644 --- a/lib/src/l10n/generated/quill_localizations_es.dart +++ b/lib/src/l10n/generated/quill_localizations_es.dart @@ -244,8 +244,7 @@ class FlutterQuillLocalizationsEs extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -254,8 +253,7 @@ class FlutterQuillLocalizationsEs extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_fa.dart b/lib/src/l10n/generated/quill_localizations_fa.dart index 088cd13df..759674bfe 100644 --- a/lib/src/l10n/generated/quill_localizations_fa.dart +++ b/lib/src/l10n/generated/quill_localizations_fa.dart @@ -246,8 +246,7 @@ class FlutterQuillLocalizationsFa extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -256,8 +255,7 @@ class FlutterQuillLocalizationsFa extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_fr.dart b/lib/src/l10n/generated/quill_localizations_fr.dart index d7ce3c0a0..f0644c76a 100644 --- a/lib/src/l10n/generated/quill_localizations_fr.dart +++ b/lib/src/l10n/generated/quill_localizations_fr.dart @@ -247,8 +247,7 @@ class FlutterQuillLocalizationsFr extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -257,8 +256,7 @@ class FlutterQuillLocalizationsFr extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_he.dart b/lib/src/l10n/generated/quill_localizations_he.dart index 939375a0d..5fea7ff51 100644 --- a/lib/src/l10n/generated/quill_localizations_he.dart +++ b/lib/src/l10n/generated/quill_localizations_he.dart @@ -245,8 +245,7 @@ class FlutterQuillLocalizationsHe extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -255,8 +254,7 @@ class FlutterQuillLocalizationsHe extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_hi.dart b/lib/src/l10n/generated/quill_localizations_hi.dart index 69f19b371..103ded145 100644 --- a/lib/src/l10n/generated/quill_localizations_hi.dart +++ b/lib/src/l10n/generated/quill_localizations_hi.dart @@ -246,8 +246,7 @@ class FlutterQuillLocalizationsHi extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -256,8 +255,7 @@ class FlutterQuillLocalizationsHi extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_id.dart b/lib/src/l10n/generated/quill_localizations_id.dart index c664f6778..fbd1a0e36 100644 --- a/lib/src/l10n/generated/quill_localizations_id.dart +++ b/lib/src/l10n/generated/quill_localizations_id.dart @@ -247,8 +247,7 @@ class FlutterQuillLocalizationsId extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -257,8 +256,7 @@ class FlutterQuillLocalizationsId extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_it.dart b/lib/src/l10n/generated/quill_localizations_it.dart index 74bf73898..bf90ba95d 100644 --- a/lib/src/l10n/generated/quill_localizations_it.dart +++ b/lib/src/l10n/generated/quill_localizations_it.dart @@ -247,8 +247,7 @@ class FlutterQuillLocalizationsIt extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -257,8 +256,7 @@ class FlutterQuillLocalizationsIt extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_ja.dart b/lib/src/l10n/generated/quill_localizations_ja.dart index 364a32145..65569dd0e 100644 --- a/lib/src/l10n/generated/quill_localizations_ja.dart +++ b/lib/src/l10n/generated/quill_localizations_ja.dart @@ -242,8 +242,7 @@ class FlutterQuillLocalizationsJa extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -252,8 +251,7 @@ class FlutterQuillLocalizationsJa extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_ko.dart b/lib/src/l10n/generated/quill_localizations_ko.dart index 5a46e10ba..8cf56ecbb 100644 --- a/lib/src/l10n/generated/quill_localizations_ko.dart +++ b/lib/src/l10n/generated/quill_localizations_ko.dart @@ -242,8 +242,7 @@ class FlutterQuillLocalizationsKo extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -252,8 +251,7 @@ class FlutterQuillLocalizationsKo extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_ms.dart b/lib/src/l10n/generated/quill_localizations_ms.dart index 9b929a381..e561d2a42 100644 --- a/lib/src/l10n/generated/quill_localizations_ms.dart +++ b/lib/src/l10n/generated/quill_localizations_ms.dart @@ -245,8 +245,7 @@ class FlutterQuillLocalizationsMs extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -255,8 +254,7 @@ class FlutterQuillLocalizationsMs extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_nl.dart b/lib/src/l10n/generated/quill_localizations_nl.dart index 5a0f6eb69..3ddd6a551 100644 --- a/lib/src/l10n/generated/quill_localizations_nl.dart +++ b/lib/src/l10n/generated/quill_localizations_nl.dart @@ -247,8 +247,7 @@ class FlutterQuillLocalizationsNl extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -257,8 +256,7 @@ class FlutterQuillLocalizationsNl extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_no.dart b/lib/src/l10n/generated/quill_localizations_no.dart index 6d6b278cb..665761059 100644 --- a/lib/src/l10n/generated/quill_localizations_no.dart +++ b/lib/src/l10n/generated/quill_localizations_no.dart @@ -247,8 +247,7 @@ class FlutterQuillLocalizationsNo extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -257,8 +256,7 @@ class FlutterQuillLocalizationsNo extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_pl.dart b/lib/src/l10n/generated/quill_localizations_pl.dart index 0f6ce73c9..348521404 100644 --- a/lib/src/l10n/generated/quill_localizations_pl.dart +++ b/lib/src/l10n/generated/quill_localizations_pl.dart @@ -244,8 +244,7 @@ class FlutterQuillLocalizationsPl extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -254,8 +253,7 @@ class FlutterQuillLocalizationsPl extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_pt.dart b/lib/src/l10n/generated/quill_localizations_pt.dart index d4184f113..048cddec6 100644 --- a/lib/src/l10n/generated/quill_localizations_pt.dart +++ b/lib/src/l10n/generated/quill_localizations_pt.dart @@ -245,8 +245,7 @@ class FlutterQuillLocalizationsPt extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -255,8 +254,7 @@ class FlutterQuillLocalizationsPt extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_ru.dart b/lib/src/l10n/generated/quill_localizations_ru.dart index 0237b47bf..c2afd16fa 100644 --- a/lib/src/l10n/generated/quill_localizations_ru.dart +++ b/lib/src/l10n/generated/quill_localizations_ru.dart @@ -244,8 +244,7 @@ class FlutterQuillLocalizationsRu extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -254,8 +253,7 @@ class FlutterQuillLocalizationsRu extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_sr.dart b/lib/src/l10n/generated/quill_localizations_sr.dart index b1366486e..4b2e8c4e7 100644 --- a/lib/src/l10n/generated/quill_localizations_sr.dart +++ b/lib/src/l10n/generated/quill_localizations_sr.dart @@ -246,8 +246,7 @@ class FlutterQuillLocalizationsSr extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -256,8 +255,7 @@ class FlutterQuillLocalizationsSr extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_sw.dart b/lib/src/l10n/generated/quill_localizations_sw.dart index c9d6e0eb6..53d038871 100644 --- a/lib/src/l10n/generated/quill_localizations_sw.dart +++ b/lib/src/l10n/generated/quill_localizations_sw.dart @@ -244,8 +244,7 @@ class FlutterQuillLocalizationsSw extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -254,8 +253,7 @@ class FlutterQuillLocalizationsSw extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_tk.dart b/lib/src/l10n/generated/quill_localizations_tk.dart index ce9e3ca21..4018d3335 100644 --- a/lib/src/l10n/generated/quill_localizations_tk.dart +++ b/lib/src/l10n/generated/quill_localizations_tk.dart @@ -243,8 +243,7 @@ class FlutterQuillLocalizationsTk extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -253,8 +252,7 @@ class FlutterQuillLocalizationsTk extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_tr.dart b/lib/src/l10n/generated/quill_localizations_tr.dart index 2c1e34d15..fa6da123d 100644 --- a/lib/src/l10n/generated/quill_localizations_tr.dart +++ b/lib/src/l10n/generated/quill_localizations_tr.dart @@ -244,8 +244,7 @@ class FlutterQuillLocalizationsTr extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -254,8 +253,7 @@ class FlutterQuillLocalizationsTr extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_uk.dart b/lib/src/l10n/generated/quill_localizations_uk.dart index 8df86ed48..0c79a5700 100644 --- a/lib/src/l10n/generated/quill_localizations_uk.dart +++ b/lib/src/l10n/generated/quill_localizations_uk.dart @@ -246,8 +246,7 @@ class FlutterQuillLocalizationsUk extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -256,8 +255,7 @@ class FlutterQuillLocalizationsUk extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_ur.dart b/lib/src/l10n/generated/quill_localizations_ur.dart index ca0965399..c984f3187 100644 --- a/lib/src/l10n/generated/quill_localizations_ur.dart +++ b/lib/src/l10n/generated/quill_localizations_ur.dart @@ -248,8 +248,7 @@ class FlutterQuillLocalizationsUr extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -258,8 +257,7 @@ class FlutterQuillLocalizationsUr extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_vi.dart b/lib/src/l10n/generated/quill_localizations_vi.dart index ea53ab879..817a9701a 100644 --- a/lib/src/l10n/generated/quill_localizations_vi.dart +++ b/lib/src/l10n/generated/quill_localizations_vi.dart @@ -245,8 +245,7 @@ class FlutterQuillLocalizationsVi extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -255,8 +254,7 @@ class FlutterQuillLocalizationsVi extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/generated/quill_localizations_zh.dart b/lib/src/l10n/generated/quill_localizations_zh.dart index 8277c60b0..ca4c41d3b 100644 --- a/lib/src/l10n/generated/quill_localizations_zh.dart +++ b/lib/src/l10n/generated/quill_localizations_zh.dart @@ -242,8 +242,7 @@ class FlutterQuillLocalizationsZh extends FlutterQuillLocalizations { String get pickAPhotoFromYourGallery => 'Pick a photo from your gallery'; @override - String get takeAPhotoUsingYourCamera => - 'Take a photo using your phone camera'; + String get takeAPhotoUsingYourCamera => 'Take a photo using your camera'; @override String get pasteAPhotoUsingALink => 'Paste a photo using a link'; @@ -252,8 +251,7 @@ class FlutterQuillLocalizationsZh extends FlutterQuillLocalizations { String get pickAVideoFromYourGallery => 'Pick a video from your gallery'; @override - String get recordAVideoUsingYourCamera => - 'Record a video using your phone camera'; + String get recordAVideoUsingYourCamera => 'Record a video using your camera'; @override String get pasteAVideoUsingALink => 'Paste a video using a link'; diff --git a/lib/src/l10n/quill_en.arb b/lib/src/l10n/quill_en.arb index 49bb30b4d..58c6884c2 100644 --- a/lib/src/l10n/quill_en.arb +++ b/lib/src/l10n/quill_en.arb @@ -79,9 +79,9 @@ "caseSensitivityAndWholeWordSearch": "Case sensitivity and whole word search", "insertImage": "Insert image", "pickAPhotoFromYourGallery": "Pick a photo from your gallery", - "takeAPhotoUsingYourCamera": "Take a photo using your phone camera", + "takeAPhotoUsingYourCamera": "Take a photo using your camera", "pasteAPhotoUsingALink": "Paste a photo using a link", "pickAVideoFromYourGallery": "Pick a video from your gallery", - "recordAVideoUsingYourCamera": "Record a video using your phone camera", + "recordAVideoUsingYourCamera": "Record a video using your camera", "pasteAVideoUsingALink": "Paste a video using a link" } diff --git a/lib/src/models/config/toolbar/simple_toolbar_configurations.dart b/lib/src/models/config/toolbar/simple_toolbar_configurations.dart index bb75f4397..a8c95293b 100644 --- a/lib/src/models/config/toolbar/simple_toolbar_configurations.dart +++ b/lib/src/models/config/toolbar/simple_toolbar_configurations.dart @@ -48,7 +48,7 @@ const double kDefaultIconSize = 18; const double defaultToolbarSize = kDefaultIconSize * 2; /// The factor of how much larger the button is in relation to the icon. -const double kIconButtonFactor = 1.77; +const double kIconButtonFactor = 1.6; /// The horizontal margin between the contents of each toolbar section. const double kToolbarSectionSpacing = 4; diff --git a/lib/src/widgets/toolbar/buttons/clear_format_button.dart b/lib/src/widgets/toolbar/buttons/clear_format_button.dart index d903aa777..7dc2ecfdc 100644 --- a/lib/src/widgets/toolbar/buttons/clear_format_button.dart +++ b/lib/src/widgets/toolbar/buttons/clear_format_button.dart @@ -111,8 +111,7 @@ class QuillToolbarClearFormatButton extends StatelessWidget { return QuillToolbarIconButton( tooltip: tooltip, - size: iconSize * iconButtonFactor, - icon: Icon(iconData, size: iconSize, color: iconColor), + icon: Icon(iconData, size: iconSize * iconButtonFactor, color: iconColor), isFilled: false, onPressed: _sharedOnPressed, afterPressed: afterButtonPressed, diff --git a/lib/src/widgets/toolbar/buttons/custom_button_button.dart b/lib/src/widgets/toolbar/buttons/custom_button_button.dart index 27c6cf14c..c63dc6aec 100644 --- a/lib/src/widgets/toolbar/buttons/custom_button_button.dart +++ b/lib/src/widgets/toolbar/buttons/custom_button_button.dart @@ -81,7 +81,6 @@ class QuillToolbarCustomButton extends StatelessWidget { } return QuillToolbarIconButton( - size: iconSize * iconButtonFactor, icon: options.icon ?? const SizedBox.shrink(), isFilled: false, tooltip: tooltip, diff --git a/lib/src/widgets/toolbar/buttons/history_button.dart b/lib/src/widgets/toolbar/buttons/history_button.dart index c4ac883f4..3fceb0b8d 100644 --- a/lib/src/widgets/toolbar/buttons/history_button.dart +++ b/lib/src/widgets/toolbar/buttons/history_button.dart @@ -95,10 +95,9 @@ class QuillToolbarHistoryButtonState extends State { theme = Theme.of(context); return QuillToolbarIconButton( tooltip: tooltip, - size: iconSize * iconButtonFactor, icon: Icon( iconData, - size: iconSize, + size: iconSize * iconButtonFactor, color: _canPressed ? iconTheme?.iconUnselectedColor ?? theme.iconTheme.color : iconTheme?.disabledIconColor ?? theme.disabledColor, diff --git a/lib/src/widgets/toolbar/buttons/indent_button.dart b/lib/src/widgets/toolbar/buttons/indent_button.dart index 4a35a5710..d8e61a2ca 100644 --- a/lib/src/widgets/toolbar/buttons/indent_button.dart +++ b/lib/src/widgets/toolbar/buttons/indent_button.dart @@ -109,8 +109,7 @@ class QuillToolbarIndentButtonState extends State { final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; return QuillToolbarIconButton( tooltip: tooltip, - size: iconSize * iconButtonFactor, - icon: Icon(iconData, size: iconSize, color: iconColor), + icon: Icon(iconData, size: iconSize * iconButtonFactor, color: iconColor), isFilled: false, onPressed: _sharedOnPressed, afterPressed: afterButtonPressed, diff --git a/lib/src/widgets/toolbar/buttons/link_style2_button.dart b/lib/src/widgets/toolbar/buttons/link_style2_button.dart index 2eca0a81f..c97d2129e 100644 --- a/lib/src/widgets/toolbar/buttons/link_style2_button.dart +++ b/lib/src/widgets/toolbar/buttons/link_style2_button.dart @@ -148,10 +148,9 @@ class _QuillToolbarLinkStyleButton2State final isToggled = _getLinkAttributeValue() != null; return QuillToolbarIconButton( tooltip: tooltip, - size: iconSize * iconButtonFactor, icon: Icon( iconData, - size: iconSize, + size: iconSize * iconButtonFactor, color: isToggled ? (iconTheme?.iconSelectedColor ?? theme.primaryIconTheme.color) : (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color), diff --git a/lib/src/widgets/toolbar/buttons/link_style_button.dart b/lib/src/widgets/toolbar/buttons/link_style_button.dart index f08f36712..265e4e75e 100644 --- a/lib/src/widgets/toolbar/buttons/link_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/link_style_button.dart @@ -141,10 +141,9 @@ class QuillToolbarLinkStyleButtonState final theme = Theme.of(context); return QuillToolbarIconButton( tooltip: tooltip, - size: iconSize * iconButtonFactor, icon: Icon( iconData, - size: iconSize, + size: iconSize * iconButtonFactor, color: isToggled ? (iconTheme?.iconSelectedColor ?? theme.primaryIconTheme.color) : (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color), diff --git a/lib/src/widgets/toolbar/buttons/quill_icon_button.dart b/lib/src/widgets/toolbar/buttons/quill_icon_button.dart index 3370792e5..78c4eaf54 100644 --- a/lib/src/widgets/toolbar/buttons/quill_icon_button.dart +++ b/lib/src/widgets/toolbar/buttons/quill_icon_button.dart @@ -6,7 +6,6 @@ class QuillToolbarIconButton extends StatelessWidget { required this.icon, required this.isFilled, this.afterPressed, - this.size = 40, this.tooltip, super.key, }); @@ -15,7 +14,6 @@ class QuillToolbarIconButton extends StatelessWidget { final VoidCallback? afterPressed; final Widget icon; - final double size; final String? tooltip; final bool isFilled; @@ -25,7 +23,10 @@ class QuillToolbarIconButton extends StatelessWidget { return IconButton.filled(onPressed: onPressed, icon: icon); } return IconButton( - onPressed: onPressed, + onPressed: () { + onPressed?.call(); + afterPressed?.call(); + }, icon: icon, ); } diff --git a/lib/src/widgets/toolbar/buttons/search/search_button.dart b/lib/src/widgets/toolbar/buttons/search/search_button.dart index 437ed7917..2ef2f8627 100644 --- a/lib/src/widgets/toolbar/buttons/search/search_button.dart +++ b/lib/src/widgets/toolbar/buttons/search/search_button.dart @@ -116,10 +116,9 @@ class QuillToolbarSearchButton extends StatelessWidget { tooltip: tooltip, icon: Icon( iconData, - size: iconSize, + size: iconSize * iconButtonFactor, color: iconColor, ), - size: iconSize * iconButtonFactor, isFilled: false, onPressed: () => _sharedOnPressed(context), afterPressed: afterButtonPressed, diff --git a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart index 4ed40f18b..75a8066d4 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart @@ -251,8 +251,7 @@ Widget defaultToggleStyleButtonBuilder( : (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color) : (iconTheme?.disabledIconColor ?? theme.disabledColor); return QuillToolbarIconButton( - size: iconSize * iconButtonFactor, - icon: Icon(icon, size: iconSize, color: iconColor), + icon: Icon(icon, size: iconSize * iconButtonFactor, color: iconColor), isFilled: isEnabled ? isToggled == true : false, onPressed: onPressed, afterPressed: afterPressed, From 8d3215fbe44cd3a316b7dda54a5a33c24e87806e Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 13:21:39 +0300 Subject: [PATCH 27/86] Fix tests --- test/bug_fix_test.dart | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/test/bug_fix_test.dart b/test/bug_fix_test.dart index 5867f67c4..fb135f127 100644 --- a/test/bug_fix_test.dart +++ b/test/bug_fix_test.dart @@ -16,15 +16,17 @@ void main() { await tester.pumpWidget( MaterialApp( - home: QuillSimpleToolbar( - configurations: QuillSimpleToolbarConfigurations( - controller: controller, - showRedo: false, - customButtons: const [ - QuillToolbarCustomButtonOptions( - tooltip: tooltip, - ) - ], + home: Scaffold( + body: QuillSimpleToolbar( + configurations: QuillSimpleToolbarConfigurations( + controller: controller, + showRedo: false, + customButtons: const [ + QuillToolbarCustomButtonOptions( + tooltip: tooltip, + ) + ], + ), ), ), ), From 2cb886bcd166270a8969035172b1bf784b84da8d Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 13:24:18 +0300 Subject: [PATCH 28/86] Fix analysis warrning --- .../lib/embeds/image/editor/image_embed.dart | 1 - 1 file changed, 1 deletion(-) 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 0bc0f8b41..12f8f28aa 100644 --- a/flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart +++ b/flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart @@ -1,4 +1,3 @@ -import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart' hide OptionalSize; import 'package:flutter_quill/translations.dart'; From daa597f1b63667eab3f26406c2cacd229af928d7 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 14:20:36 +0300 Subject: [PATCH 29/86] Replace pasteboard with super_cliboard --- README.md | 14 +++++++-- example/android/app/build.gradle | 2 +- .../android/app/src/main/AndroidManifest.xml | 16 +++++++--- example/android/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../flutter/generated_plugin_registrant.cc | 12 +++++--- example/linux/flutter/generated_plugins.cmake | 3 +- .../Flutter/GeneratedPluginRegistrant.swift | 6 ++-- example/macos/Podfile.lock | 16 ++++++---- .../flutter/generated_plugin_registrant.cc | 9 ++++-- .../windows/flutter/generated_plugins.cmake | 3 +- .../widgets/raw_editor/raw_editor_state.dart | 30 ++++++++++--------- pubspec.yaml | 2 +- 13 files changed, 77 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index afdff9447..058f5c8b2 100644 --- a/README.md +++ b/README.md @@ -94,17 +94,27 @@ dependencies: > 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! > -Compatible versions: + ## Usage +Before using the package, we must inform you the package use the following plugins: + ``` + url_launcher + flutter_keyboard_visibility + device_info_plus + super_clipboard + ``` + +All of them doesn't require any platform spesefic setup, except [super_clipboard](https://pub.dev/packages/super_clipboard) which needs some setup on Android only, it's optional but to support copying images and pasting them into editor then you must setup it, open the page in pub.dev and read the `README.md` to get the instructions. + First, you need to instantiate a controller ```dart diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index d2bb91174..aa36e402b 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -24,7 +24,7 @@ if (flutterVersionName == null) { android { namespace "com.example.example" - compileSdk flutter.compileSdkVersion + compileSdkVersion flutter.compileSdkVersion ndkVersion flutter.ndkVersion compileOptions { diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index e047f006d..bf856053a 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,10 +1,11 @@ - + - @@ -43,7 +44,7 @@ - + + + + diff --git a/example/android/build.gradle b/example/android/build.gradle index d88cfa132..f86105d78 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.1.4' + classpath 'com.android.tools.build:gradle:8.2.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 5e6b54271..aa49780cd 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip diff --git a/example/linux/flutter/generated_plugin_registrant.cc b/example/linux/flutter/generated_plugin_registrant.cc index fe311fa2d..12dc8c820 100644 --- a/example/linux/flutter/generated_plugin_registrant.cc +++ b/example/linux/flutter/generated_plugin_registrant.cc @@ -8,7 +8,8 @@ #include #include -#include +#include +#include #include void fl_register_plugins(FlPluginRegistry* registry) { @@ -18,9 +19,12 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); file_selector_plugin_register_with_registrar(file_selector_linux_registrar); - g_autoptr(FlPluginRegistrar) pasteboard_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "PasteboardPlugin"); - pasteboard_plugin_register_with_registrar(pasteboard_registrar); + g_autoptr(FlPluginRegistrar) irondash_engine_context_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "IrondashEngineContextPlugin"); + irondash_engine_context_plugin_register_with_registrar(irondash_engine_context_registrar); + g_autoptr(FlPluginRegistrar) super_native_extensions_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "SuperNativeExtensionsPlugin"); + super_native_extensions_plugin_register_with_registrar(super_native_extensions_registrar); g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); diff --git a/example/linux/flutter/generated_plugins.cmake b/example/linux/flutter/generated_plugins.cmake index 3f7f250e4..b75263bb2 100644 --- a/example/linux/flutter/generated_plugins.cmake +++ b/example/linux/flutter/generated_plugins.cmake @@ -5,7 +5,8 @@ list(APPEND FLUTTER_PLUGIN_LIST desktop_drop file_selector_linux - pasteboard + irondash_engine_context + super_native_extensions url_launcher_linux ) diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index 6b3c06b5f..bf1bbe800 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,10 +9,11 @@ import desktop_drop import device_info_plus import file_selector_macos import gal -import pasteboard +import irondash_engine_context import path_provider_foundation import share_plus import sqflite +import super_native_extensions import url_launcher_macos import video_player_avfoundation @@ -21,10 +22,11 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin")) - PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin")) + IrondashEngineContextPlugin.register(with: registry.registrar(forPlugin: "IrondashEngineContextPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) + SuperNativeExtensionsPlugin.register(with: registry.registrar(forPlugin: "SuperNativeExtensionsPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) } diff --git a/example/macos/Podfile.lock b/example/macos/Podfile.lock index 01dc23931..a562380ae 100644 --- a/example/macos/Podfile.lock +++ b/example/macos/Podfile.lock @@ -12,7 +12,7 @@ PODS: - gal (1.0.0): - Flutter - FlutterMacOS - - pasteboard (0.0.1): + - irondash_engine_context (0.0.1): - FlutterMacOS - path_provider_foundation (0.0.1): - Flutter @@ -22,6 +22,8 @@ PODS: - sqflite (0.0.2): - FlutterMacOS - FMDB (>= 2.7.5) + - super_native_extensions (0.0.1): + - FlutterMacOS - url_launcher_macos (0.0.1): - FlutterMacOS - video_player_avfoundation (0.0.1): @@ -34,10 +36,11 @@ DEPENDENCIES: - file_selector_macos (from `Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - gal (from `Flutter/ephemeral/.symlinks/plugins/gal/darwin`) - - pasteboard (from `Flutter/ephemeral/.symlinks/plugins/pasteboard/macos`) + - irondash_engine_context (from `Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos`) - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`) + - super_native_extensions (from `Flutter/ephemeral/.symlinks/plugins/super_native_extensions/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - video_player_avfoundation (from `Flutter/ephemeral/.symlinks/plugins/video_player_avfoundation/darwin`) @@ -56,14 +59,16 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral gal: :path: Flutter/ephemeral/.symlinks/plugins/gal/darwin - pasteboard: - :path: Flutter/ephemeral/.symlinks/plugins/pasteboard/macos + irondash_engine_context: + :path: Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos path_provider_foundation: :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin share_plus: :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos sqflite: :path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos + super_native_extensions: + :path: Flutter/ephemeral/.symlinks/plugins/super_native_extensions/macos url_launcher_macos: :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos video_player_avfoundation: @@ -76,10 +81,11 @@ SPEC CHECKSUMS: FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a gal: 61e868295d28fe67ffa297fae6dacebf56fd53e1 - pasteboard: 9b69dba6fedbb04866be632205d532fe2f6b1d99 + irondash_engine_context: da62996ee25616d2f01bbeb85dc115d813359478 path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 share_plus: 76dd39142738f7a68dd57b05093b5e8193f220f7 sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea + super_native_extensions: 85efee3a7495b46b04befcfc86ed12069264ebf3 url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95 video_player_avfoundation: e9e6f9cae7d7a6d9b43519b0aab382bca60fcfd1 diff --git a/example/windows/flutter/generated_plugin_registrant.cc b/example/windows/flutter/generated_plugin_registrant.cc index ef6dc9060..084810413 100644 --- a/example/windows/flutter/generated_plugin_registrant.cc +++ b/example/windows/flutter/generated_plugin_registrant.cc @@ -9,8 +9,9 @@ #include #include #include -#include +#include #include +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { @@ -20,10 +21,12 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("FileSelectorWindows")); GalPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("GalPluginCApi")); - PasteboardPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("PasteboardPlugin")); + IrondashEngineContextPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("IrondashEngineContextPluginCApi")); SharePlusWindowsPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); + SuperNativeExtensionsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SuperNativeExtensionsPluginCApi")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/example/windows/flutter/generated_plugins.cmake b/example/windows/flutter/generated_plugins.cmake index abc6f6272..f568d1445 100644 --- a/example/windows/flutter/generated_plugins.cmake +++ b/example/windows/flutter/generated_plugins.cmake @@ -6,8 +6,9 @@ list(APPEND FLUTTER_PLUGIN_LIST desktop_drop file_selector_windows gal - pasteboard + irondash_engine_context share_plus + super_native_extensions url_launcher_windows ) diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index 30ccf446f..4b11d9675 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -18,7 +18,7 @@ import 'package:flutter/services.dart' TextInputControl; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart' show KeyboardVisibilityController; -import 'package:pasteboard/pasteboard.dart' show Pasteboard; +import 'package:super_clipboard/super_clipboard.dart'; import '../../models/documents/attribute.dart'; import '../../models/documents/document.dart'; @@ -1381,23 +1381,25 @@ class QuillRawEditorState extends EditorState final onImagePaste = widget.configurations.onImagePaste; if (onImagePaste != null) { - final image = await Pasteboard.image; - - if (image == null) { + final reader = await ClipboardReader.readClipboard(); + if (!reader.canProvide(Formats.png)) { return; } + reader.getFile(Formats.png, (value) async { + final image = value; - final imageUrl = await onImagePaste(image); - if (imageUrl == null) { - return; - } + final imageUrl = await onImagePaste(await image.readAll()); + if (imageUrl == null) { + return; + } - controller.replaceText( - textEditingValue.selection.end, - 0, - BlockEmbed.image(imageUrl), - null, - ); + controller.replaceText( + textEditingValue.selection.end, + 0, + BlockEmbed.image(imageUrl), + null, + ); + }); } } diff --git a/pubspec.yaml b/pubspec.yaml index 168bf22a9..8695aa68d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -56,7 +56,7 @@ dependencies: url_launcher: ^6.1.14 flutter_keyboard_visibility: ^5.4.1 device_info_plus: ^9.1.0 - pasteboard: ^0.2.0 + super_clipboard: ^0.7.3 dev_dependencies: flutter_lints: ^3.0.1 From 026b58aa0df9a9ce98be36ab46a2fdc4842d3a5c Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 14:50:43 +0300 Subject: [PATCH 30/86] 3+++ --- CHANGELOG.md | 4 ++++ .../lib/presentation/quill/quill_toolbar.dart | 2 +- flutter_quill_extensions/README.md | 3 +-- .../lib/embeds/image/editor/image_menu.dart | 15 +++++++++------ flutter_quill_extensions/lib/utils/utils.dart | 16 +++++++++++++++- flutter_quill_extensions/pubspec.yaml | 3 ++- 6 files changed, 32 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4363db5a7..7132f0725 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ All notable changes to this project will be documented in this file. * Breaking Changes: * Rename `QuillToolbar` to `QuillSimpleToolbar` * Rename `QuillBaseToolbar` to `QuillToolbar` + * Replace `pasteboard` with `rich_cliboard` +* Fix a bug in the example when inserting an image from url +* Flutter Quill Extensions: + * Add support for copying the image to the system cliboard ## 9.0.0-dev-2 * An attemp to fix CI automated publishing diff --git a/example/lib/presentation/quill/quill_toolbar.dart b/example/lib/presentation/quill/quill_toolbar.dart index 303e65875..79c38ce1f 100644 --- a/example/lib/presentation/quill/quill_toolbar.dart +++ b/example/lib/presentation/quill/quill_toolbar.dart @@ -66,7 +66,7 @@ class MyQuillToolbar extends StatelessWidget { } Future onImageInsert(String image, QuillController controller) async { - if (isWeb()) { + if (isWeb() || isHttpBasedUrl(image)) { controller.insertImageBlock(imageSource: image); return; } diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index b42c90def..4158462c5 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -53,8 +53,7 @@ dependencies: > > 1. We are using the [`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. +> For this to work, you need to add the appropriate configurations > 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 to follow the instructions 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 4bcf19b13..bc1e1414b 100644 --- a/flutter_quill_extensions/lib/embeds/image/editor/image_menu.dart +++ b/flutter_quill_extensions/lib/embeds/image/editor/image_menu.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart' show ImageUrl, QuillController, StyleAttribute, getEmbedNode; import 'package:flutter_quill/translations.dart'; +import 'package:super_clipboard/super_clipboard.dart'; import '../../../models/config/editor/image/image.dart'; import '../../../models/config/shared_configurations.dart'; @@ -88,15 +89,17 @@ class ImageOptionsMenu extends StatelessWidget { final navigator = Navigator.of(context); final imageNode = getEmbedNode(controller, controller.selection.start).value; - final imageUrl = imageNode.value.data; + final image = imageNode.value.data; controller.copiedImageUrl = ImageUrl( - imageUrl, + image, getImageStyleString(controller), ); - // TODO: Implement the copy image - // await Clipboard.setData( - // ClipboardData(), - // ); + + final data = await convertImageToUint8List(image); + if (data != null) { + final item = DataWriterItem()..add(Formats.png(data)); + await ClipboardWriter.instance.write([item]); + } navigator.pop(); }, ), diff --git a/flutter_quill_extensions/lib/utils/utils.dart b/flutter_quill_extensions/lib/utils/utils.dart index 12c802a11..b54970330 100644 --- a/flutter_quill_extensions/lib/utils/utils.dart +++ b/flutter_quill_extensions/lib/utils/utils.dart @@ -1,6 +1,8 @@ import 'dart:io' show File; -import 'package:flutter/foundation.dart' show immutable; +import 'package:cross_file/cross_file.dart'; +import 'package:flutter/foundation.dart' show Uint8List, immutable; +import 'package:http/http.dart' as http; import '../embeds/widgets/image.dart'; import '../services/image_saver/s_image_saver.dart'; @@ -48,6 +50,18 @@ class SaveImageResult { final SaveImageResultMethod method; } +Future convertImageToUint8List(String image) async { + if (isHttpBasedUrl(image)) { + final response = await http.get(Uri.parse(image)); + if (response.statusCode == 200) { + return Uint8List.fromList(response.bodyBytes); + } + return null; + } + final file = XFile(image); + return await file.readAsBytes(); +} + Future saveImage({ required String imageUrl, required ImageSaverService imageSaverService, diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 7453fe16d..0fb58c4db 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -41,9 +41,10 @@ dependencies: # Plugins video_player: ^2.8.1 youtube_player_flutter: ^8.1.2 + url_launcher: ^6.2.1 + super_clipboard: ^0.7.3 gal: ^2.1.3 image_picker: ^1.0.4 - url_launcher: ^6.2.1 dev_dependencies: flutter_test: From 59ada7fb3417d1539914455ae436718240346653 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 14:52:45 +0300 Subject: [PATCH 31/86] Update version --- flutter_quill_extensions/CHANGELOG.md | 9 +++++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 9 +++++++++ flutter_quill_test/pubspec.yaml | 2 +- packages/quill_html_converter/CHANGELOG.md | 9 +++++++++ packages/quill_html_converter/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 7 files changed, 31 insertions(+), 4 deletions(-) diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 60b64f0f5..7132f0725 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,6 +2,15 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-3 +* Breaking Changes: + * Rename `QuillToolbar` to `QuillSimpleToolbar` + * Rename `QuillBaseToolbar` to `QuillToolbar` + * Replace `pasteboard` with `rich_cliboard` +* Fix a bug in the example when inserting an image from url +* Flutter Quill Extensions: + * Add support for copying the image to the system cliboard + ## 9.0.0-dev-2 * An attemp to fix CI automated publishing diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 0fb58c4db..4caf7e9bf 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: 9.0.0-dev-2 +version: 9.0.0-dev-3 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 60b64f0f5..7132f0725 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -2,6 +2,15 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-3 +* Breaking Changes: + * Rename `QuillToolbar` to `QuillSimpleToolbar` + * Rename `QuillBaseToolbar` to `QuillToolbar` + * Replace `pasteboard` with `rich_cliboard` +* Fix a bug in the example when inserting an image from url +* Flutter Quill Extensions: + * Add support for copying the image to the system cliboard + ## 9.0.0-dev-2 * An attemp to fix CI automated publishing diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 60ea133db..477d4dcd9 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: 9.0.0-dev-2 +version: 9.0.0-dev-3 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index 60b64f0f5..7132f0725 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -2,6 +2,15 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-3 +* Breaking Changes: + * Rename `QuillToolbar` to `QuillSimpleToolbar` + * Rename `QuillBaseToolbar` to `QuillToolbar` + * Replace `pasteboard` with `rich_cliboard` +* Fix a bug in the example when inserting an image from url +* Flutter Quill Extensions: + * Add support for copying the image to the system cliboard + ## 9.0.0-dev-2 * An attemp to fix CI automated publishing diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index 1517c5286..995ceaddd 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.0.0-dev-2 +version: 9.0.0-dev-3 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 8695aa68d..b528c9e6a 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: 9.0.0-dev-2 +version: 9.0.0-dev-3 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 879202546dd8014b678c93a2f0eeb470a7a9571b Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 20:09:17 +0300 Subject: [PATCH 32/86] 3++++ --- .../quill/samples/quill_images_sample.dart | 6 +- flutter_quill_extensions/CHANGELOG.md | 1 + .../lib/embeds/image/editor/image_embed.dart | 5 +- .../lib/embeds/video/editor/video_embed.dart | 5 +- .../element_utils/element_shared_utils.dart | 73 +++++++++++++++++-- .../utils/element_utils/element_utils.dart | 23 ++++-- flutter_quill_extensions/lib/utils/utils.dart | 9 ++- 7 files changed, 98 insertions(+), 24 deletions(-) diff --git a/example/lib/presentation/quill/samples/quill_images_sample.dart b/example/lib/presentation/quill/samples/quill_images_sample.dart index 9dadcd2ca..0395af1e8 100644 --- a/example/lib/presentation/quill/samples/quill_images_sample.dart +++ b/example/lib/presentation/quill/samples/quill_images_sample.dart @@ -5,11 +5,7 @@ final quillImagesSample = [ {'insert': '\n'}, { 'insert': {'image': Assets.images.screenshot1.path}, - 'attributes': { - 'width': '200', - 'height': '500', - 'style': 'width:500px; height:350px; margin: 20px;' - } + 'attributes': {'style': 'width: 40vh; height:350px; margin: 20px;'} }, {'insert': '\n'}, {'insert': 'Here is a network image: \n'}, diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 7132f0725..02eb65c64 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. * Fix a bug in the example when inserting an image from url * Flutter Quill Extensions: * Add support for copying the image to the system cliboard + * Add support for other CSS units like (vh, vw) and more ## 9.0.0-dev-2 * An attemp to fix CI automated publishing 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 12f8f28aa..ee0a8f9a2 100644 --- a/flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart +++ b/flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart @@ -32,7 +32,10 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { // assert(!kIsWeb, 'Please provide image EmbedBuilder for Web'); final imageSource = standardizeImageUrl(node.value.data); - final ((imageSize), margin, alignment) = getElementAttributes(node); + final ((imageSize), margin, alignment) = getElementAttributes( + node, + context, + ); final width = imageSize.width; final height = imageSize.height; diff --git a/flutter_quill_extensions/lib/embeds/video/editor/video_embed.dart b/flutter_quill_extensions/lib/embeds/video/editor/video_embed.dart index 831da538b..fd1cd8fc5 100644 --- a/flutter_quill_extensions/lib/embeds/video/editor/video_embed.dart +++ b/flutter_quill_extensions/lib/embeds/video/editor/video_embed.dart @@ -37,7 +37,10 @@ class QuillEditorVideoEmbedBuilder extends EmbedBuilder { readOnly: readOnly, ); } - final ((elementSize), margin, alignment) = getElementAttributes(node); + final ((elementSize), margin, alignment) = getElementAttributes( + node, + context, + ); final width = elementSize.width; final height = elementSize.height; diff --git a/flutter_quill_extensions/lib/utils/element_utils/element_shared_utils.dart b/flutter_quill_extensions/lib/utils/element_utils/element_shared_utils.dart index 927a97e18..8632fba0f 100644 --- a/flutter_quill_extensions/lib/utils/element_utils/element_shared_utils.dart +++ b/flutter_quill_extensions/lib/utils/element_utils/element_shared_utils.dart @@ -1,3 +1,5 @@ +import 'package:flutter/widgets.dart' show BuildContext, MediaQuery; + Map parseCssString(String cssString) { final result = {}; final declarations = cssString.split(';'); @@ -14,16 +16,71 @@ Map parseCssString(String cssString) { return result; } -double? parseCssPropertyAsDouble(String value) { +enum _CssUnit { + px('px'), + percentage('%'), + viewportWidth('vw'), + viewportHeight('vh'), + em('em'), + rem('rem'), + invalid('invalid'); + + const _CssUnit(this.cssName); + + final String cssName; +} + +double? parseCssPropertyAsDouble( + String value, { + required BuildContext context, +}) { if (value.trim().isEmpty) { return null; } - final list = [ - 'px', - // '%', 'vw', 'vh', 'em', 'rem' - ]; - for (final element in list) { - value = value.replaceFirst(element, ''); + + // Try to parse it in case it's a valid double already + var doubleValue = double.tryParse(value); + + if (doubleValue != null) { + return doubleValue; + } + + // If not then if it's a css numberic value then we will try to parse it + final unit = _CssUnit.values + .where((element) => value.endsWith(element.cssName)) + .firstOrNull; + if (unit == null) { + return null; + } + value = value.replaceFirst(unit.cssName, ''); + doubleValue = double.tryParse(value); + if (doubleValue != null) { + switch (unit) { + case _CssUnit.px: + // Do nothing + break; + case _CssUnit.percentage: + // Not supported yet + doubleValue = null; + break; + case _CssUnit.viewportWidth: + doubleValue = (doubleValue / 100) * MediaQuery.sizeOf(context).width; + break; + case _CssUnit.viewportHeight: + doubleValue = (doubleValue / 100) * MediaQuery.sizeOf(context).height; + break; + case _CssUnit.em: + doubleValue = MediaQuery.textScalerOf(context).scale(doubleValue); + break; + case _CssUnit.rem: + // Not fully supported yet + doubleValue = MediaQuery.textScalerOf(context).scale(doubleValue); + break; + case _CssUnit.invalid: + // Ignore + doubleValue = null; + break; + } } - return double.tryParse(value); + return doubleValue; } diff --git a/flutter_quill_extensions/lib/utils/element_utils/element_utils.dart b/flutter_quill_extensions/lib/utils/element_utils/element_utils.dart index 24bd166e7..64db01aef 100644 --- a/flutter_quill_extensions/lib/utils/element_utils/element_utils.dart +++ b/flutter_quill_extensions/lib/utils/element_utils/element_utils.dart @@ -1,5 +1,5 @@ import 'package:flutter/foundation.dart' show immutable; -import 'package:flutter/widgets.dart' show Alignment; +import 'package:flutter/widgets.dart' show Alignment, BuildContext; import 'package:flutter_quill/extensions.dart'; import 'package:flutter_quill/flutter_quill.dart' show Attribute, Node; @@ -18,15 +18,20 @@ enum ExtraElementProperties { Alignment alignment, ) getElementAttributes( Node node, + BuildContext context, ) { var elementSize = const ElementSize(null, null); var elementAlignment = Alignment.center; double? elementMargin; final heightValue = parseCssPropertyAsDouble( - node.style.attributes[Attribute.height.key]?.value.toString() ?? ''); + node.style.attributes[Attribute.height.key]?.value.toString() ?? '', + context: context, + ); final widthValue = parseCssPropertyAsDouble( - node.style.attributes[Attribute.width.key]?.value.toString() ?? ''); + node.style.attributes[Attribute.width.key]?.value.toString() ?? '', + context: context, + ); if (heightValue != null) { elementSize = elementSize.copyWith( @@ -47,10 +52,14 @@ enum ExtraElementProperties { final cssAttrs = parseCssString(cssStyle.value.toString()); // todo: This could be improved much better - final cssHeightValue = - parseCssPropertyAsDouble((cssAttrs[Attribute.height.key]) ?? ''); - final cssWidthValue = - parseCssPropertyAsDouble((cssAttrs[Attribute.width.key]) ?? ''); + final cssHeightValue = parseCssPropertyAsDouble( + (cssAttrs[Attribute.height.key]) ?? '', + context: context, + ); + final cssWidthValue = parseCssPropertyAsDouble( + (cssAttrs[Attribute.width.key]) ?? '', + context: context, + ); // cssHeightValue != null && elementSize.height == null if (cssHeightValue != null) { diff --git a/flutter_quill_extensions/lib/utils/utils.dart b/flutter_quill_extensions/lib/utils/utils.dart index b54970330..fc620e9b7 100644 --- a/flutter_quill_extensions/lib/utils/utils.dart +++ b/flutter_quill_extensions/lib/utils/utils.dart @@ -58,8 +58,13 @@ Future convertImageToUint8List(String image) async { } return null; } - final file = XFile(image); - return await file.readAsBytes(); + // TODO: Add support for all image providers like AssetImage + try { + final file = XFile(image); + return await file.readAsBytes(); + } catch (e) { + return null; + } } Future saveImage({ From 5afa35e02d43437b046f31a5d28825be411c78e5 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 5 Dec 2023 20:20:03 +0300 Subject: [PATCH 33/86] Regenerate versions --- flutter_quill_extensions/CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 02eb65c64..7132f0725 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -10,7 +10,6 @@ All notable changes to this project will be documented in this file. * Fix a bug in the example when inserting an image from url * Flutter Quill Extensions: * Add support for copying the image to the system cliboard - * Add support for other CSS units like (vh, vw) and more ## 9.0.0-dev-2 * An attemp to fix CI automated publishing From 25435c9bccd7904e097acbec6191741d4d5016dc Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 6 Dec 2023 09:35:04 +0300 Subject: [PATCH 34/86] 3+++++ --- CHANGELOG.md | 4 + .../lib/presentation/quill/quill_screen.dart | 15 +- .../lib/presentation/quill/quill_toolbar.dart | 128 +++++++--------- .../presentation/simple/simple_screen.dart | 35 +++++ .../formula/toolbar/formula_button.dart | 4 +- .../embeds/image/toolbar/image_button.dart | 4 +- .../others/camera_button/camera_button.dart | 19 ++- .../others/media_button/media_button.dart | 4 +- .../video/toolbar/select_video_source.dart | 3 +- .../embeds/video/toolbar/video_button.dart | 14 +- lib/flutter_quill.dart | 3 +- .../extensions/quill_configurations_ext.dart | 93 ++++++++++++ ...troller.dart => quill_controller_ext.dart} | 4 +- lib/src/extensions/quill_provider.dart | 142 ------------------ lib/src/l10n/widgets/localizations.dart | 2 +- .../models/config/editor/configurations.dart | 4 + .../toolbar/buttons/base_configurations.dart | 2 +- .../buttons/history_configurations.dart | 5 - .../simple_toolbar_configurations.dart | 13 +- .../toolbar/toolbar_configurations.dart | 13 +- .../toolbar_shared_configurations.dart | 4 + lib/src/widgets/others/text_block.dart | 2 +- lib/src/widgets/toolbar/base_toolbar.dart | 13 +- .../toolbar/buttons/clear_format_button.dart | 4 +- .../toolbar/buttons/color/color_button.dart | 9 +- .../toolbar/buttons/custom_button_button.dart | 4 +- .../toolbar/buttons/font_family_button.dart | 31 ++-- .../toolbar/buttons/font_size_button.dart | 11 +- .../toolbar/buttons/history_button.dart | 18 ++- .../toolbar/buttons/indent_button.dart | 4 +- .../toolbar/buttons/link_style2_button.dart | 4 +- .../toolbar/buttons/link_style_button.dart | 4 +- .../toolbar/buttons/search/search_button.dart | 4 +- .../buttons/select_alignment_buttons.dart | 3 +- .../buttons/select_alignment_old_buttons.dart | 2 +- .../buttons/select_header_style_button.dart | 2 +- .../buttons/select_header_style_buttons.dart | 6 +- .../buttons/toggle_check_list_button.dart | 4 +- .../toolbar/buttons/toggle_style_button.dart | 9 +- lib/src/widgets/toolbar/simple_toolbar.dart | 6 +- lib/src/widgets/utils/provider.dart | 59 -------- 41 files changed, 339 insertions(+), 375 deletions(-) create mode 100644 example/lib/presentation/simple/simple_screen.dart create mode 100644 lib/src/extensions/quill_configurations_ext.dart rename lib/src/extensions/{quill_controller.dart => quill_controller_ext.dart} (82%) delete mode 100644 lib/src/extensions/quill_provider.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 7132f0725..849261e54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-4 +* The options parameter in all of the buttons is no longer required which can be useful to create custom toolbar with minimal efforts +* Toolbar buttons fixes in both `flutter_quill` and `flutter_quill_extensions` + ## 9.0.0-dev-3 * Breaking Changes: * Rename `QuillToolbar` to `QuillSimpleToolbar` diff --git a/example/lib/presentation/quill/quill_screen.dart b/example/lib/presentation/quill/quill_screen.dart index 0fc392fc4..7f34cc305 100644 --- a/example/lib/presentation/quill/quill_screen.dart +++ b/example/lib/presentation/quill/quill_screen.dart @@ -3,7 +3,7 @@ import 'dart:convert' show jsonEncode; import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart' - show FlutterQuillEmbeds; + show FlutterQuillEmbeds, QuillSharedExtensionsConfigurations; import 'package:quill_html_converter/quill_html_converter.dart'; import 'package:share_plus/share_plus.dart' show Share; @@ -106,12 +106,14 @@ class _QuillScreenState extends State { MyQuillToolbar( controller: _controller, focusNode: _editorFocusNode, + sharedConfigurations: _sharedConfigurations, ), Builder( builder: (context) { return Expanded( child: MyQuillEditor( configurations: QuillEditorConfigurations( + sharedConfigurations: _sharedConfigurations, controller: _controller, readOnly: _isReadOnly, ), @@ -129,4 +131,15 @@ class _QuillScreenState extends State { ), ); } + + QuillSharedConfigurations get _sharedConfigurations { + return const QuillSharedConfigurations( + extraConfigurations: { + QuillSharedExtensionsConfigurations.key: + QuillSharedExtensionsConfigurations( + assetsPrefix: 'your-assets-folder-name', // Defaults to assets + ), + }, + ); + } } diff --git a/example/lib/presentation/quill/quill_toolbar.dart b/example/lib/presentation/quill/quill_toolbar.dart index 79c38ce1f..4c0f3124d 100644 --- a/example/lib/presentation/quill/quill_toolbar.dart +++ b/example/lib/presentation/quill/quill_toolbar.dart @@ -17,11 +17,14 @@ class MyQuillToolbar extends StatelessWidget { const MyQuillToolbar({ required this.controller, required this.focusNode, + required this.sharedConfigurations, super.key, }); final QuillController controller; final FocusNode focusNode; + // TODO: Use it + final QuillSharedConfigurations sharedConfigurations; Future onImageInsertWithCropping( String image, @@ -101,132 +104,103 @@ class MyQuillToolbar extends StatelessWidget { // https://github.com/singerdmx/flutter-quill/blob/master/doc/custom_toolbar.md return QuillToolbar( configurations: QuillToolbarConfigurations( - toolbarSize: 15 * 2, + toolbarSize: 20 * 2, multiRowsDisplay: false, buttonOptions: const QuillToolbarButtonOptions( base: QuillToolbarBaseButtonOptions( globalIconSize: 20, + globalIconButtonFactor: 1.4, ), ), childrenBuilder: (context) { return [ IconButton( - onPressed: () { - context.read().updateSettings( - state.copyWith(useCustomQuillToolbar: false)); - }, + onPressed: () => context + .read() + .updateSettings( + state.copyWith(useCustomQuillToolbar: false)), icon: const Icon( Icons.width_normal, - size: 16, ), ), - QuillToolbarImageButton( - controller: controller, - options: const QuillToolbarImageButtonOptions(), - ), QuillToolbarHistoryButton( + isUndo: true, controller: controller, - options: - const QuillToolbarHistoryButtonOptions(isUndo: true), ), QuillToolbarHistoryButton( + isUndo: false, controller: controller, - options: - const QuillToolbarHistoryButtonOptions(isUndo: false), ), QuillToolbarToggleStyleButton( - attribute: Attribute.bold, + options: const QuillToolbarToggleStyleButtonOptions(), controller: controller, - options: QuillToolbarToggleStyleButtonOptions( - childBuilder: (options, extraOptions) { - if (extraOptions.isToggled) { - return IconButton.filled( - onPressed: extraOptions.onPressed, - icon: Icon(options.iconData), - ); - } - return IconButton( - onPressed: extraOptions.onPressed, - icon: Icon(options.iconData), - ); - }, - ), + attribute: Attribute.bold, ), QuillToolbarToggleStyleButton( - attribute: Attribute.italic, + options: const QuillToolbarToggleStyleButtonOptions(), controller: controller, - options: const QuillToolbarToggleStyleButtonOptions( - iconData: Icons.format_italic, - ), + attribute: Attribute.italic, ), QuillToolbarToggleStyleButton( - attribute: Attribute.underline, controller: controller, - options: const QuillToolbarToggleStyleButtonOptions( - iconData: Icons.format_underline, - iconSize: 20, - ), + attribute: Attribute.underline, ), QuillToolbarClearFormatButton( controller: controller, - options: const QuillToolbarClearFormatButtonOptions( - iconData: Icons.format_clear, - ), ), - VerticalDivider( - indent: 12, - endIndent: 12, - color: Colors.grey.shade400, + const VerticalDivider(), + QuillToolbarImageButton( + controller: controller, ), - QuillToolbarSelectHeaderStyleButtons( + QuillToolbarCameraButton( + controller: controller, + ), + QuillToolbarVideoButton( + controller: controller, + ), + const VerticalDivider(), + QuillToolbarColorButton( + controller: controller, + isBackground: false, + ), + QuillToolbarColorButton( + controller: controller, + isBackground: true, + ), + const VerticalDivider(), + QuillToolbarSelectHeaderStyleButton( + controller: controller, + ), + const VerticalDivider(), + QuillToolbarToggleCheckListButton( controller: controller, - options: const QuillToolbarSelectHeaderStyleButtonsOptions( - iconSize: 20, - ), ), QuillToolbarToggleStyleButton( - attribute: Attribute.ol, controller: controller, - options: const QuillToolbarToggleStyleButtonOptions( - iconData: Icons.format_list_numbered, - iconSize: 39, - ), + attribute: Attribute.list, ), QuillToolbarToggleStyleButton( - attribute: Attribute.ul, controller: controller, - options: const QuillToolbarToggleStyleButtonOptions( - iconData: Icons.format_list_bulleted, - ), + attribute: Attribute.ul, ), QuillToolbarToggleStyleButton( - attribute: Attribute.blockQuote, controller: controller, - options: const QuillToolbarToggleStyleButtonOptions( - iconData: Icons.format_quote, - iconSize: 15, - ), + attribute: Attribute.inlineCode, ), - VerticalDivider( - indent: 12, - endIndent: 12, - color: Colors.grey.shade400, + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.blockQuote, ), QuillToolbarIndentButton( - controller: controller, - isIncrease: true, - options: const QuillToolbarIndentButtonOptions( - iconData: Icons.format_indent_increase, - iconSize: 20, - )), + controller: controller, + isIncrease: true, + ), QuillToolbarIndentButton( controller: controller, isIncrease: false, - options: const QuillToolbarIndentButtonOptions( - iconData: Icons.format_indent_decrease, - iconSize: 20, - ), ), + const VerticalDivider(), + QuillToolbarLinkStyleButton(controller: controller), ]; }, ), diff --git a/example/lib/presentation/simple/simple_screen.dart b/example/lib/presentation/simple/simple_screen.dart new file mode 100644 index 000000000..0393fcf7c --- /dev/null +++ b/example/lib/presentation/simple/simple_screen.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_quill/flutter_quill.dart'; + +class SimpleScreen extends StatefulWidget { + const SimpleScreen({super.key}); + + @override + State createState() => _SimpleScreenState(); +} + +class _SimpleScreenState extends State { + final _controller = QuillController.basic(); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(), + body: Column( + children: [ + QuillToolbar.simple( + QuillSimpleToolbarConfigurations(controller: _controller), + ), + Expanded( + child: QuillEditor.basic( + configurations: QuillEditorConfigurations( + controller: _controller, + padding: const EdgeInsets.all(16), + ), + ), + ), + ], + ), + ); + } +} diff --git a/flutter_quill_extensions/lib/embeds/formula/toolbar/formula_button.dart b/flutter_quill_extensions/lib/embeds/formula/toolbar/formula_button.dart index 3be5075c1..84dfdb367 100644 --- a/flutter_quill_extensions/lib/embeds/formula/toolbar/formula_button.dart +++ b/flutter_quill_extensions/lib/embeds/formula/toolbar/formula_button.dart @@ -6,7 +6,7 @@ import '../../../models/config/toolbar/buttons/formula.dart'; class QuillToolbarFormulaButton extends StatelessWidget { const QuillToolbarFormulaButton({ required this.controller, - required this.options, + this.options = const QuillToolbarFormulaButtonOptions(), super.key, }); @@ -91,7 +91,7 @@ class QuillToolbarFormulaButton extends StatelessWidget { } return QuillToolbarIconButton( - icon: Icon(iconData, size: iconSize * 1.77, color: iconColor), + icon: Icon(iconData, size: iconSize * iconButtonFactor, color: iconColor), tooltip: tooltip, onPressed: () => _sharedOnPressed(context), isFilled: false, 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 362b6ce8f..f943dabd4 100644 --- a/flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart +++ b/flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart @@ -14,7 +14,7 @@ import 'select_image_source.dart'; class QuillToolbarImageButton extends StatelessWidget { const QuillToolbarImageButton({ required this.controller, - required this.options, + this.options = const QuillToolbarImageButtonOptions(), super.key, }); @@ -105,7 +105,7 @@ class QuillToolbarImageButton extends StatelessWidget { return QuillToolbarIconButton( icon: Icon( iconData, - size: iconSize * 1.77, + size: iconButtonFactor * iconSize, color: iconColor, ), tooltip: tooltip, diff --git a/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart b/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart index 4f7582037..70ef09907 100644 --- a/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart +++ b/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart @@ -3,7 +3,7 @@ import 'package:flutter_quill/flutter_quill.dart' show QuillController, QuillIconTheme, - QuillProviderExt, + QuillSimpleToolbarExt, QuillToolbarBaseButtonOptions, QuillToolbarIconButton; import 'package:flutter_quill/translations.dart'; @@ -17,7 +17,7 @@ import 'select_camera_action.dart'; class QuillToolbarCameraButton extends StatelessWidget { const QuillToolbarCameraButton({ required this.controller, - required this.options, + this.options = const QuillToolbarCameraButtonOptions(), super.key, }); @@ -30,6 +30,13 @@ class QuillToolbarCameraButton 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; @@ -69,6 +76,7 @@ class QuillToolbarCameraButton extends StatelessWidget { final tooltip = _tooltip(context); final iconSize = _iconSize(context); final iconData = _iconData(context); + final iconButtonFactor = _iconButtonFactor(context); final childBuilder = options.childBuilder ?? baseButtonExtraOptions(context).childBuilder; @@ -80,7 +88,7 @@ class QuillToolbarCameraButton extends StatelessWidget { iconData: options.iconData, fillColor: options.fillColor, iconSize: options.iconSize, - iconButtonFactor: options.iconButtonFactor, + iconButtonFactor: iconButtonFactor, iconTheme: options.iconTheme, tooltip: options.tooltip, cameraConfigurations: options.cameraConfigurations, @@ -98,7 +106,7 @@ class QuillToolbarCameraButton extends StatelessWidget { final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; return QuillToolbarIconButton( - icon: Icon(iconData, size: iconSize * 1.77, color: iconColor), + icon: Icon(iconData, size: iconButtonFactor * iconSize, color: iconColor), tooltip: tooltip, isFilled: false, // isDesktop(supportWeb: false) ? null : @@ -114,7 +122,8 @@ class QuillToolbarCameraButton extends StatelessWidget { } final cameraAction = await showDialog( context: context, - builder: (ctx) => const SelectCameraActionDialog(), + builder: (ctx) => const FlutterQuillLocalizationsWidget( + child: SelectCameraActionDialog()), ); return cameraAction; diff --git a/flutter_quill_extensions/lib/embeds/others/media_button/media_button.dart b/flutter_quill_extensions/lib/embeds/others/media_button/media_button.dart index 5246e8381..132c7bcd0 100644 --- a/flutter_quill_extensions/lib/embeds/others/media_button/media_button.dart +++ b/flutter_quill_extensions/lib/embeds/others/media_button/media_button.dart @@ -20,7 +20,7 @@ // class QuillToolbarMediaButton extends StatelessWidget { // QuillToolbarMediaButton({ // required this.controller, -// required this.options, +// this.options, // super.key, // }) : assert(options.type == QuillMediaType.image, // 'Video selection is not supported yet'); @@ -135,7 +135,7 @@ // tooltip: tooltip, // highlightElevation: 0, // hoverElevation: 0, -// size: iconSize * 1.77, +// size: iconSize * iconButtonFactor, // fillColor: iconFillColor, // borderRadius: iconTheme?.borderRadius ?? 2, // onPressed: () => _sharedOnPressed(context), diff --git a/flutter_quill_extensions/lib/embeds/video/toolbar/select_video_source.dart b/flutter_quill_extensions/lib/embeds/video/toolbar/select_video_source.dart index f4c030c9f..d8ddb7747 100644 --- a/flutter_quill_extensions/lib/embeds/video/toolbar/select_video_source.dart +++ b/flutter_quill_extensions/lib/embeds/video/toolbar/select_video_source.dart @@ -52,7 +52,8 @@ Future showSelectVideoSourceDialog({ showDragHandle: true, context: context, constraints: const BoxConstraints(maxWidth: 640), - builder: (context) => const SelectVideoSourceDialog(), + builder: (context) => + const FlutterQuillLocalizationsWidget(child: SelectVideoSourceDialog()), ); 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 3b6708b94..748759784 100644 --- a/flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart +++ b/flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart @@ -13,8 +13,8 @@ import 'select_video_source.dart'; class QuillToolbarVideoButton extends StatelessWidget { const QuillToolbarVideoButton({ - required this.options, required this.controller, + this.options = const QuillToolbarVideoButtonOptions(), super.key, }); @@ -28,6 +28,13 @@ class QuillToolbarVideoButton 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; @@ -67,6 +74,7 @@ class QuillToolbarVideoButton 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; @@ -83,7 +91,7 @@ class QuillToolbarVideoButton extends StatelessWidget { dialogTheme: options.dialogTheme, fillColor: iconFillColor, iconSize: options.iconSize, - iconButtonFactor: options.iconButtonFactor, + iconButtonFactor: iconButtonFactor, linkRegExp: options.linkRegExp, tooltip: options.tooltip, iconTheme: options.iconTheme, @@ -98,7 +106,7 @@ class QuillToolbarVideoButton extends StatelessWidget { } return QuillToolbarIconButton( - icon: Icon(iconData, size: iconSize * 1.77, color: iconColor), + icon: Icon(iconData, size: iconSize * iconButtonFactor, color: iconColor), tooltip: tooltip, isFilled: false, onPressed: () => _sharedOnPressed(context), diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index 9d0b04868..5ea179f4c 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -1,6 +1,6 @@ library flutter_quill; -export 'src/extensions/quill_provider.dart'; +export 'src/extensions/quill_configurations_ext.dart'; export 'src/models/config/quill_configurations.dart'; export 'src/models/config/raw_editor/configurations.dart'; export 'src/models/config/toolbar/toolbar_configurations.dart'; @@ -33,5 +33,6 @@ export 'src/widgets/raw_editor/raw_editor.dart'; export 'src/widgets/raw_editor/raw_editor_state.dart'; export 'src/widgets/style_widgets/style_widgets.dart'; export 'src/widgets/toolbar/base_toolbar.dart'; +export 'src/widgets/toolbar/buttons/select_header_style_button.dart'; export 'src/widgets/toolbar/simple_toolbar.dart'; export 'src/widgets/utils/provider.dart'; diff --git a/lib/src/extensions/quill_configurations_ext.dart b/lib/src/extensions/quill_configurations_ext.dart new file mode 100644 index 000000000..f926f76eb --- /dev/null +++ b/lib/src/extensions/quill_configurations_ext.dart @@ -0,0 +1,93 @@ +import 'package:flutter/widgets.dart' show BuildContext; + +import '../../flutter_quill.dart'; + +extension QuillControllerExt on BuildContext { + /// return nullable [QuillController] + QuillController? get quilController { + return quillSimpleToolbarConfigurations?.controller ?? + quillEditorConfigurations?.controller; + } + + /// return [QuillController] as not null + QuillController get requireQuillController { + return quillSimpleToolbarConfigurations?.controller ?? + quillEditorConfigurations?.controller ?? + (throw ArgumentError( + 'The quill provider is required, you must only call requireQuillController inside the QuillToolbar and QuillEditor')); + } +} + +extension QuillSharedExt on BuildContext { + /// return nullable [QuillSharedConfigurations] + QuillSharedConfigurations? get quillSharedConfigurations { + return quillSimpleToolbarConfigurations?.sharedConfigurations ?? + quillEditorConfigurations?.sharedConfigurations; + } +} + +extension QuillEditorExt on BuildContext { + /// return [QuillEditorConfigurations] as not null + QuillEditorConfigurations get requireQuillEditorConfigurations { + return QuillEditorProvider.ofNotNull(this).editorConfigurations; + } + + /// return nullable [QuillEditorConfigurations] + QuillEditorConfigurations? get quillEditorConfigurations { + return QuillEditorProvider.of(this)?.editorConfigurations; + } + + /// return nullable [QuillToolbarBaseButtonOptions]. Since the quill + /// quill editor block options is in the [QuillEditorProvider] then we need to + /// get the provider widget first and then we will return block options + /// throw exception if [QuillEditorProvider] is not in the widget tree + QuillEditorElementOptions? get quillEditorElementOptions { + return quillEditorConfigurations?.elementOptions; + } + + /// return [QuillToolbarBaseButtonOptions] as not null. Since the quill + /// quill editor block options is in the [QuillEditorProvider] then we need to + /// get the provider widget first and then we will return block options + /// don't throw exception if [QuillEditorProvider] is not in the widget tree + QuillEditorElementOptions get requireQuillEditorElementOptions { + return requireQuillEditorConfigurations.elementOptions; + } +} + +extension QuillSimpleToolbarExt on BuildContext { + /// return [QuillSimpleToolbarConfigurations] as not null + QuillSimpleToolbarConfigurations get requireQuillSimpleToolbarConfigurations { + return QuillToolbarProvider.ofNotNull(this).toolbarConfigurations; + } + + /// return nullable [QuillSimpleToolbarConfigurations] + QuillSimpleToolbarConfigurations? get quillSimpleToolbarConfigurations { + return QuillToolbarProvider.of(this)?.toolbarConfigurations; + } + + /// return nullable [QuillToolbarBaseButtonOptions]. + QuillToolbarBaseButtonOptions? get quillToolbarBaseButtonOptions { + return quillSimpleToolbarConfigurations?.buttonOptions.base; + } + + /// return [QuillToolbarBaseButtonOptions] as not null. + QuillToolbarBaseButtonOptions get requireQuillToolbarBaseButtonOptions { + return quillSimpleToolbarConfigurations?.buttonOptions.base ?? + quillToolbarConfigurations?.buttonOptions.base ?? + (throw ArgumentError( + "The buttonOptions is required and it's null because the toolbar configurations is.", + )); + } +} + +extension QuillToolbarExt on BuildContext { + /// return [QuillToolbarConfigurations] as not null + QuillToolbarConfigurations get requireQuillToolbarConfigurations { + return QuillBaseToolbarProvider.ofNotNull(this).toolbarConfigurations; + } + + /// return nullable [QuillToolbarConfigurations]. + QuillToolbarConfigurations? get quillToolbarConfigurations { + return QuillBaseToolbarProvider.of(this)?.toolbarConfigurations; + } +} diff --git a/lib/src/extensions/quill_controller.dart b/lib/src/extensions/quill_controller_ext.dart similarity index 82% rename from lib/src/extensions/quill_controller.dart rename to lib/src/extensions/quill_controller_ext.dart index ca7c36998..3ae3e8470 100644 --- a/lib/src/extensions/quill_controller.dart +++ b/lib/src/extensions/quill_controller_ext.dart @@ -1,7 +1,7 @@ import 'package:flutter/widgets.dart' show BuildContext; -import '../../flutter_quill.dart' show QuillController, QuillProvider; -import 'quill_provider.dart'; +import '../../flutter_quill.dart' show QuillController; +import 'quill_configurations_ext.dart'; extension QuillControllerNullableExt on QuillController? { /// Simple logic to use the current passed controller if not null diff --git a/lib/src/extensions/quill_provider.dart b/lib/src/extensions/quill_provider.dart deleted file mode 100644 index e6fbc1650..000000000 --- a/lib/src/extensions/quill_provider.dart +++ /dev/null @@ -1,142 +0,0 @@ -import 'package:flutter/widgets.dart' show BuildContext; - -import '../../flutter_quill.dart'; - -// TODO: The comments of this file is outdated and needs to be updated - -/// Public shared extension -extension QuillProviderExt on BuildContext { - /// return nullable [QuillProvider] - /// don't throw exception if it's not in the widget tree - /// instead it will be null - QuillProvider? get quillProvider { - return QuillProvider.of(this); - } - - /// return nullable [QuillController] - /// since the quill controller is in the [QuillProvider] then we need to get - /// the provider widget first and then we will return the controller - /// don't throw exception if [QuillProvider] is not in the widget tree - /// instead it will be null - QuillController? get quilController { - return quillToolbarConfigurations?.controller ?? - quillEditorConfigurations?.controller; - } - - /// return [QuillController] as not null - /// since the quill controller is in the [QuillProvider] then we need to get - /// 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 quillToolbarConfigurations?.controller ?? - quillEditorConfigurations?.controller ?? - (throw ArgumentError( - 'The quill provider is required, you must only call requireQuillController inside the QuillToolbar and QuillEditor')); - } - - /// return nullable [QuillConfigurations] - /// since the quill configurations is in the [QuillProvider] then we need to - /// get the provider widget first and then we will return quill configurations - /// don't throw exception if [QuillProvider] is not in the widget tree - QuillConfigurations? get quillConfigurations { - return quillProvider?.configurations; - } - - /// 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 - /// don't throw exception if [QuillProvider] is not in the widget tree - QuillSharedConfigurations? get quillSharedConfigurations { - return quillConfigurations?.sharedConfigurations; - } - - /// return [QuillEditorConfigurations] as not null . Since the quill - /// editor configurations is in the [QuillEditorProvider] - /// then we need to get the - /// provider widget first and then we will return editor configurations - /// throw exception if [QuillProvider] is not in the widget tree - QuillEditorConfigurations get requireQuillEditorConfigurations { - return QuillEditorProvider.ofNotNull(this).editorConfigurations; - } - - /// return nullable [QuillEditorConfigurations]. Since the quill - /// editor configurations is in the [QuillEditorProvider] - /// then we need to get the - /// provider widget first and then we will return editor configurations - /// don't throw exception if [QuillProvider] is not in the widget tree - QuillEditorConfigurations? get quillEditorConfigurations { - return QuillEditorProvider.of(this)?.editorConfigurations; - } - - /// return [QuillSimpleToolbarConfigurations] as not null . Since the quill - /// toolbar configurations is in the [QuillToolbarProvider] - /// then we need to get the - /// provider widget first and then we will return toolbar configurations - /// throw exception if [QuillProvider] is not in the widget tree - QuillSimpleToolbarConfigurations get requireQuillToolbarConfigurations { - return QuillToolbarProvider.ofNotNull(this).toolbarConfigurations; - } - - /// return nullable [QuillSimpleToolbarConfigurations]. Since the quill - /// toolbar configurations is in the [QuillToolbarProvider] - /// then we need to get the - /// provider widget first and then we will return toolbar configurations - /// don't throw exception if [QuillProvider] is not in the widget tree - QuillSimpleToolbarConfigurations? get quillToolbarConfigurations { - return QuillToolbarProvider.of(this)?.toolbarConfigurations; - } - - /// return [QuillToolbarConfigurations] as not null . Since the quill - /// toolbar configurations is in the [QuillBaseToolbarProvider] - /// then we need to get the - /// provider widget first and then we will return toolbar configurations - /// throw exception if [QuillBaseToolbarProvider] is not in the widget tree - QuillToolbarConfigurations get requireQuillBaseToolbarConfigurations { - return QuillBaseToolbarProvider.ofNotNull(this).toolbarConfigurations; - } - - /// return nullable [QuillToolbarConfigurations]. Since the quill - /// toolbar configurations is in the [QuillBaseToolbarProvider] - /// then we need to get the - /// provider widget first and then we will return toolbar configurations - /// don't throw exception if [QuillBaseToolbarProvider] is not in the widget tree - QuillToolbarConfigurations? get quillBaseToolbarConfigurations { - return QuillBaseToolbarProvider.of(this)?.toolbarConfigurations; - } - - /// return nullable [QuillToolbarBaseButtonOptions]. Since the quill - /// toolbar base button options is in the [QuillProvider] then we need to - /// get the provider widget first and then we will return base button - /// don't throw exception if [QuillProvider] is not in the widget tree - QuillToolbarBaseButtonOptions? get quillToolbarBaseButtonOptions { - return quillToolbarConfigurations?.buttonOptions.base; - } - - /// return [QuillToolbarBaseButtonOptions] as not null. Since the quill - /// toolbar base button options is in the [QuillProvider] then we need to - /// get the provider widget first and then we will return base button - /// throw exception if [QuillProvider] is not in the widget tree - QuillToolbarBaseButtonOptions get requireQuillToolbarBaseButtonOptions { - return quillToolbarConfigurations?.buttonOptions.base ?? - quillBaseToolbarConfigurations?.buttonOptions.base ?? - (throw ArgumentError( - "The buttonOptions is required and it's null because the toolbar configurations is.", - )); - } - - /// return nullable [QuillToolbarBaseButtonOptions]. Since the quill - /// quill editor block options is in the [QuillEditorProvider] then we need to - /// get the provider widget first and then we will return block options - /// throw exception if [QuillEditorProvider] is not in the widget tree - QuillEditorElementOptions? get quillEditorElementOptions { - return quillEditorConfigurations?.elementOptions; - } - - /// return [QuillToolbarBaseButtonOptions] as not null. Since the quill - /// quill editor block options is in the [QuillEditorProvider] then we need to - /// get the provider widget first and then we will return block options - /// don't throw exception if [QuillEditorProvider] is not in the widget tree - QuillEditorElementOptions get requireQuillEditorElementOptions { - return requireQuillEditorConfigurations.elementOptions; - } -} diff --git a/lib/src/l10n/widgets/localizations.dart b/lib/src/l10n/widgets/localizations.dart index 85fe5ff21..57277b6b0 100644 --- a/lib/src/l10n/widgets/localizations.dart +++ b/lib/src/l10n/widgets/localizations.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; -import '../../extensions/quill_provider.dart'; +import '../../extensions/quill_configurations_ext.dart'; import '../extensions/localizations.dart'; class FlutterQuillLocalizationsWidget extends StatelessWidget { diff --git a/lib/src/models/config/editor/configurations.dart b/lib/src/models/config/editor/configurations.dart index ec793fa5e..55151b1b5 100644 --- a/lib/src/models/config/editor/configurations.dart +++ b/lib/src/models/config/editor/configurations.dart @@ -15,6 +15,7 @@ import '../../../widgets/others/embeds.dart'; import '../../../widgets/others/link.dart'; import '../../../widgets/raw_editor/raw_editor.dart'; import '../../themes/quill_dialog_theme.dart'; +import '../quill_shared_configurations.dart'; import 'element_options.dart'; export 'element_options.dart'; @@ -26,6 +27,7 @@ class QuillEditorConfigurations extends Equatable { /// When editing this class please update the [copyWith] function too. const QuillEditorConfigurations({ required this.controller, + this.sharedConfigurations = const QuillSharedConfigurations(), this.scrollable = true, this.padding = EdgeInsets.zero, this.autoFocus = false, @@ -76,6 +78,8 @@ class QuillEditorConfigurations extends Equatable { this.textInputAction = TextInputAction.newline, }); + final QuillSharedConfigurations sharedConfigurations; + final QuillController controller; /// The text placeholder in the quill editor diff --git a/lib/src/models/config/toolbar/buttons/base_configurations.dart b/lib/src/models/config/toolbar/buttons/base_configurations.dart index 4b7b8ab12..be77a833b 100644 --- a/lib/src/models/config/toolbar/buttons/base_configurations.dart +++ b/lib/src/models/config/toolbar/buttons/base_configurations.dart @@ -3,7 +3,7 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show VoidCallback, immutable; import 'package:flutter/widgets.dart' show BuildContext, IconData, Widget; -import '../../../../../flutter_quill.dart' show QuillController, QuillProvider; +import '../../../../../flutter_quill.dart' show QuillController; import '../../../themes/quill_icon_theme.dart' show QuillIconTheme; import '../../quill_configurations.dart' show kDefaultIconSize, kIconButtonFactor; diff --git a/lib/src/models/config/toolbar/buttons/history_configurations.dart b/lib/src/models/config/toolbar/buttons/history_configurations.dart index 1f1bfaabf..5766c3802 100644 --- a/lib/src/models/config/toolbar/buttons/history_configurations.dart +++ b/lib/src/models/config/toolbar/buttons/history_configurations.dart @@ -20,7 +20,6 @@ class QuillToolbarHistoryButtonExtraOptions class QuillToolbarHistoryButtonOptions extends QuillToolbarBaseButtonOptions< QuillToolbarHistoryButtonOptions, QuillToolbarHistoryButtonExtraOptions> { const QuillToolbarHistoryButtonOptions({ - required this.isUndo, super.iconData, super.controller, super.iconTheme, @@ -31,10 +30,6 @@ class QuillToolbarHistoryButtonOptions extends QuillToolbarBaseButtonOptions< this.iconButtonFactor, }); - /// If this true then it will be the undo button - /// otherwise it will be redo - final bool isUndo; - /// By default will use [globalIconSize] final double? iconSize; final double? iconButtonFactor; diff --git a/lib/src/models/config/toolbar/simple_toolbar_configurations.dart b/lib/src/models/config/toolbar/simple_toolbar_configurations.dart index a8c95293b..1ed627e95 100644 --- a/lib/src/models/config/toolbar/simple_toolbar_configurations.dart +++ b/lib/src/models/config/toolbar/simple_toolbar_configurations.dart @@ -1,3 +1,4 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' @@ -69,11 +70,13 @@ enum LinkStyleType { class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { const QuillSimpleToolbarConfigurations({ required this.controller, + super.sharedConfigurations, super.toolbarSectionSpacing = kToolbarSectionSpacing, super.toolbarIconAlignment = WrapAlignment.center, super.toolbarIconCrossAlignment = WrapCrossAlignment.center, super.buttonOptions = const QuillToolbarButtonOptions(), this.customButtons = const [], + this.fontFamilyValues, super.multiRowsDisplay = true, this.fontSizesValues, this.showDividers = true, @@ -145,6 +148,8 @@ class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { return buttonOptions.base.globalIconSize * 2; } + final Map? fontFamilyValues; + final QuillController controller; /// A widget that will placed between each button in the toolbar @@ -231,12 +236,8 @@ class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { class QuillToolbarButtonOptions extends Equatable { const QuillToolbarButtonOptions({ this.base = const QuillToolbarBaseButtonOptions(), - this.undoHistory = const QuillToolbarHistoryButtonOptions( - isUndo: true, - ), - this.redoHistory = const QuillToolbarHistoryButtonOptions( - isUndo: false, - ), + this.undoHistory = const QuillToolbarHistoryButtonOptions(), + this.redoHistory = const QuillToolbarHistoryButtonOptions(), this.fontFamily = const QuillToolbarFontFamilyButtonOptions(), this.fontSize = const QuillToolbarFontSizeButtonOptions(), this.bold = const QuillToolbarToggleStyleButtonOptions(), diff --git a/lib/src/models/config/toolbar/toolbar_configurations.dart b/lib/src/models/config/toolbar/toolbar_configurations.dart index 15e675fd7..5969e23c7 100644 --- a/lib/src/models/config/toolbar/toolbar_configurations.dart +++ b/lib/src/models/config/toolbar/toolbar_configurations.dart @@ -1,3 +1,4 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first import 'package:flutter/widgets.dart' show Axis, WrapAlignment, WrapCrossAlignment, immutable; @@ -7,7 +8,7 @@ import 'toolbar_shared_configurations.dart'; @immutable class QuillToolbarConfigurations extends QuillSharedToolbarProperties { const QuillToolbarConfigurations({ - required this.childrenBuilder, + this.childrenBuilder, super.axis = Axis.horizontal, super.toolbarSize = kDefaultIconSize * 2, super.toolbarSectionSpacing = kToolbarSectionSpacing, @@ -25,8 +26,16 @@ class QuillToolbarConfigurations extends QuillSharedToolbarProperties { super.buttonOptions = const QuillToolbarButtonOptions(), }); - final QuillBaseToolbarChildrenBuilder childrenBuilder; + final QuillBaseToolbarChildrenBuilder? childrenBuilder; @override List get props => []; + + QuillToolbarConfigurations copyWith({ + QuillBaseToolbarChildrenBuilder? childrenBuilder, + }) { + return QuillToolbarConfigurations( + childrenBuilder: childrenBuilder ?? this.childrenBuilder, + ); + } } diff --git a/lib/src/models/config/toolbar/toolbar_shared_configurations.dart b/lib/src/models/config/toolbar/toolbar_shared_configurations.dart index 166a4a95c..aff603a52 100644 --- a/lib/src/models/config/toolbar/toolbar_shared_configurations.dart +++ b/lib/src/models/config/toolbar/toolbar_shared_configurations.dart @@ -4,9 +4,11 @@ import 'package:flutter/widgets.dart' import '../../../widgets/toolbar/base_toolbar.dart'; import '../../structs/link_dialog_action.dart'; +import '../quill_shared_configurations.dart'; abstract class QuillSharedToolbarProperties extends Equatable { const QuillSharedToolbarProperties({ + this.sharedConfigurations = const QuillSharedConfigurations(), this.toolbarSize, this.axis = Axis.horizontal, this.toolbarSectionSpacing = kToolbarSectionSpacing, @@ -53,4 +55,6 @@ abstract class QuillSharedToolbarProperties extends Equatable { /// If you want change spesefic buttons or all of them /// then you came to the right place final QuillToolbarButtonOptions buttonOptions; + + final QuillSharedConfigurations sharedConfigurations; } diff --git a/lib/src/widgets/others/text_block.dart b/lib/src/widgets/others/text_block.dart index a05d57442..878064804 100644 --- a/lib/src/widgets/others/text_block.dart +++ b/lib/src/widgets/others/text_block.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; -import '../../extensions/quill_provider.dart'; +import '../../extensions/quill_configurations_ext.dart'; import '../../models/documents/attribute.dart'; import '../../models/documents/nodes/block.dart'; import '../../models/documents/nodes/line.dart'; diff --git a/lib/src/widgets/toolbar/base_toolbar.dart b/lib/src/widgets/toolbar/base_toolbar.dart index f8bf5a098..6d535b1ac 100644 --- a/lib/src/widgets/toolbar/base_toolbar.dart +++ b/lib/src/widgets/toolbar/base_toolbar.dart @@ -3,8 +3,10 @@ import 'package:flutter/material.dart'; import '../../../flutter_quill.dart' show QuillBaseToolbarProvider, defaultToolbarSize; import '../../l10n/widgets/localizations.dart'; +import '../../models/config/toolbar/simple_toolbar_configurations.dart'; import '../../models/config/toolbar/toolbar_configurations.dart'; import 'buttons/arrow_indicated_list_button.dart'; +import 'simple_toolbar.dart'; export '../../models/config/toolbar/buttons/base_configurations.dart'; export '../../models/config/toolbar/simple_toolbar_configurations.dart'; @@ -34,6 +36,13 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { super.key, }); + static QuillSimpleToolbar simple( + QuillSimpleToolbarConfigurations configurations) { + return QuillSimpleToolbar( + configurations: configurations, + ); + } + final QuillToolbarConfigurations configurations; // We can't get the modified [toolbarSize] by the developer @@ -60,7 +69,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { crossAxisAlignment: configurations.toolbarIconCrossAlignment, runSpacing: 4, spacing: configurations.toolbarSectionSpacing, - children: configurations.childrenBuilder(context), + children: configurations.childrenBuilder?.call(context) ?? [], ); } return Container( @@ -77,7 +86,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { ), child: QuillToolbarArrowIndicatedButtonList( axis: configurations.axis, - buttons: configurations.childrenBuilder(context), + buttons: configurations.childrenBuilder?.call(context) ?? [], ), ); }, diff --git a/lib/src/widgets/toolbar/buttons/clear_format_button.dart b/lib/src/widgets/toolbar/buttons/clear_format_button.dart index 7dc2ecfdc..bf1ba0962 100644 --- a/lib/src/widgets/toolbar/buttons/clear_format_button.dart +++ b/lib/src/widgets/toolbar/buttons/clear_format_button.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../../../extensions/quill_provider.dart'; +import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/themes/quill_icon_theme.dart'; @@ -10,7 +10,7 @@ import '../base_toolbar.dart'; class QuillToolbarClearFormatButton extends StatelessWidget { const QuillToolbarClearFormatButton({ required QuillController controller, - required this.options, + this.options = const QuillToolbarClearFormatButtonOptions(), super.key, }) : _controller = controller; diff --git a/lib/src/widgets/toolbar/buttons/color/color_button.dart b/lib/src/widgets/toolbar/buttons/color/color_button.dart index 2965f8b25..ff2dce6b6 100644 --- a/lib/src/widgets/toolbar/buttons/color/color_button.dart +++ b/lib/src/widgets/toolbar/buttons/color/color_button.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../../../../extensions/quill_provider.dart'; +import '../../../../extensions/quill_configurations_ext.dart'; import '../../../../l10n/extensions/localizations.dart'; import '../../../../l10n/widgets/localizations.dart'; import '../../../../models/documents/attribute.dart'; @@ -196,9 +196,10 @@ class QuillToolbarColorButtonState extends State { return IconButton( tooltip: tooltip, iconSize: iconSize * iconButtonFactor, - icon: Icon(iconData, - size: iconSize, - color: widget.isBackground ? iconColorBackground : iconColor), + icon: Icon( + iconData, + color: widget.isBackground ? iconColorBackground : iconColor, + ), onPressed: _showColorPicker, ); } diff --git a/lib/src/widgets/toolbar/buttons/custom_button_button.dart b/lib/src/widgets/toolbar/buttons/custom_button_button.dart index c63dc6aec..27145d344 100644 --- a/lib/src/widgets/toolbar/buttons/custom_button_button.dart +++ b/lib/src/widgets/toolbar/buttons/custom_button_button.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; -import '../../../extensions/quill_provider.dart'; +import '../../../extensions/quill_configurations_ext.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../others/controller.dart'; import '../base_toolbar.dart'; class QuillToolbarCustomButton extends StatelessWidget { const QuillToolbarCustomButton({ - required this.options, required this.controller, + this.options = const QuillToolbarCustomButtonOptions(), super.key, }); diff --git a/lib/src/widgets/toolbar/buttons/font_family_button.dart b/lib/src/widgets/toolbar/buttons/font_family_button.dart index b173a4f12..dc23f92fa 100644 --- a/lib/src/widgets/toolbar/buttons/font_family_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_family_button.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import '../../../../extensions.dart'; -import '../../../extensions/quill_provider.dart'; +import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/config/toolbar/buttons/font_family_configurations.dart'; import '../../../models/documents/attribute.dart'; @@ -11,9 +11,9 @@ import '../../others/controller.dart'; class QuillToolbarFontFamilyButton extends StatefulWidget { QuillToolbarFontFamilyButton({ - required this.options, required this.controller, required this.defaultDispalyText, + this.options = const QuillToolbarFontFamilyButtonOptions(), super.key, }) : assert(options.rawItemsMap?.isNotEmpty ?? (true)), assert( @@ -86,19 +86,20 @@ class QuillToolbarFontFamilyButtonState } Map get rawItemsMap { - // context.requireQuillToolbarConfigurations.buttonOptions; - final rawItemsMap = options.rawItemsMap ?? - { - 'Sans Serif': 'sans-serif', - 'Serif': 'serif', - 'Monospace': 'monospace', - 'Ibarra Real Nova': 'ibarra-real-nova', - 'SquarePeg': 'square-peg', - 'Nunito': 'nunito', - 'Pacifico': 'pacifico', - 'Roboto Mono': 'roboto-mono', - context.loc.clear: 'Clear' - }; + final rawItemsMap = + context.quillSimpleToolbarConfigurations?.fontFamilyValues ?? + options.rawItemsMap ?? + { + 'Sans Serif': 'sans-serif', + 'Serif': 'serif', + 'Monospace': 'monospace', + 'Ibarra Real Nova': 'ibarra-real-nova', + 'SquarePeg': 'square-peg', + 'Nunito': 'nunito', + 'Pacifico': 'pacifico', + 'Roboto Mono': 'roboto-mono', + context.loc.clear: 'Clear' + }; return rawItemsMap; } diff --git a/lib/src/widgets/toolbar/buttons/font_size_button.dart b/lib/src/widgets/toolbar/buttons/font_size_button.dart index 58dd04e92..0debeba72 100644 --- a/lib/src/widgets/toolbar/buttons/font_size_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_size_button.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import '../../../../extensions.dart'; -import '../../../extensions/quill_provider.dart'; +import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/config/quill_configurations.dart'; import '../../../models/documents/attribute.dart'; @@ -12,9 +12,9 @@ import '../../others/controller.dart'; class QuillToolbarFontSizeButton extends StatefulWidget { QuillToolbarFontSizeButton({ - required this.options, required this.controller, required this.defaultDisplayText, + this.options = const QuillToolbarFontSizeButtonOptions(), super.key, }) : assert(options.rawItemsMap?.isNotEmpty ?? true), assert(options.initialValue == null || @@ -43,7 +43,7 @@ class QuillToolbarFontSizeButtonState Map get rawItemsMap { final fontSizes = options.rawItemsMap ?? - context.requireQuillToolbarConfigurations.fontSizesValues ?? + context.quillSimpleToolbarConfigurations?.fontSizesValues ?? { context.loc.small: 'small', context.loc.large: 'large', @@ -112,10 +112,9 @@ class QuillToolbarFontSizeButtonState } double get iconSize { - final baseFontSize = - context.requireQuillToolbarBaseButtonOptions.globalIconSize; + final baseFontSize = context.quillToolbarBaseButtonOptions?.globalIconSize; final iconSize = options.iconSize; - return iconSize ?? baseFontSize; + return iconSize ?? baseFontSize ?? kDefaultIconSize; } double get iconButtonFactor { diff --git a/lib/src/widgets/toolbar/buttons/history_button.dart b/lib/src/widgets/toolbar/buttons/history_button.dart index 3fceb0b8d..4346a6e37 100644 --- a/lib/src/widgets/toolbar/buttons/history_button.dart +++ b/lib/src/widgets/toolbar/buttons/history_button.dart @@ -1,17 +1,22 @@ import 'package:flutter/material.dart'; -import '../../../extensions/quill_provider.dart'; +import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../others/controller.dart'; import '../base_toolbar.dart'; class QuillToolbarHistoryButton extends StatefulWidget { const QuillToolbarHistoryButton({ - required this.options, required this.controller, + required this.isUndo, + this.options = const QuillToolbarHistoryButtonOptions(), super.key, }); + /// If this true then it will be the undo button + /// otherwise it will be redo + final bool isUndo; + final QuillToolbarHistoryButtonOptions options; final QuillController controller; @@ -53,10 +58,10 @@ class QuillToolbarHistoryButtonState extends State { context.requireQuillToolbarBaseButtonOptions; final tooltip = options.tooltip ?? baseButtonConfigurations.tooltip ?? - (options.isUndo ? context.loc.undo : context.loc.redo); + (widget.isUndo ? context.loc.undo : context.loc.redo); final iconData = options.iconData ?? baseButtonConfigurations.iconData ?? - (options.isUndo ? Icons.undo_outlined : Icons.redo_outlined); + (widget.isUndo ? Icons.undo_outlined : Icons.redo_outlined); final childBuilder = options.childBuilder ?? baseButtonConfigurations.childBuilder; final iconSize = @@ -71,7 +76,6 @@ class QuillToolbarHistoryButtonState extends State { if (childBuilder != null) { return childBuilder( QuillToolbarHistoryButtonOptions( - isUndo: options.isUndo, afterButtonPressed: afterButtonPressed, controller: controller, iconData: iconData, @@ -115,7 +119,7 @@ class QuillToolbarHistoryButtonState extends State { } void _updateCanPressed() { - if (options.isUndo) { + if (widget.isUndo) { _canPressed = controller.hasUndo; return; } @@ -123,7 +127,7 @@ class QuillToolbarHistoryButtonState extends State { } void _updateHistory() { - if (options.isUndo) { + if (widget.isUndo) { if (controller.hasUndo) { controller.undo(); } diff --git a/lib/src/widgets/toolbar/buttons/indent_button.dart b/lib/src/widgets/toolbar/buttons/indent_button.dart index d8e61a2ca..f82097b16 100644 --- a/lib/src/widgets/toolbar/buttons/indent_button.dart +++ b/lib/src/widgets/toolbar/buttons/indent_button.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../../../extensions/quill_provider.dart'; +import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/config/toolbar/buttons/indent_configurations.dart'; import '../../../models/themes/quill_icon_theme.dart'; @@ -12,7 +12,7 @@ class QuillToolbarIndentButton extends StatefulWidget { const QuillToolbarIndentButton({ required this.controller, required this.isIncrease, - required this.options, + this.options = const QuillToolbarIndentButtonOptions(), super.key, }); diff --git a/lib/src/widgets/toolbar/buttons/link_style2_button.dart b/lib/src/widgets/toolbar/buttons/link_style2_button.dart index c97d2129e..a663d8647 100644 --- a/lib/src/widgets/toolbar/buttons/link_style2_button.dart +++ b/lib/src/widgets/toolbar/buttons/link_style2_button.dart @@ -4,7 +4,7 @@ import 'package:url_launcher/link.dart'; import '../../../../extensions.dart' show UtilityWidgets, AutoFormatMultipleLinksRule; -import '../../../extensions/quill_provider.dart'; +import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../l10n/widgets/localizations.dart'; import '../../../models/documents/attribute.dart'; @@ -20,7 +20,7 @@ import '../base_toolbar.dart'; class QuillToolbarLinkStyleButton2 extends StatefulWidget { QuillToolbarLinkStyleButton2({ required this.controller, - required this.options, + this.options = const QuillToolbarLinkStyleButton2Options(), super.key, }) : assert(options.addLinkLabel == null || (options.addLinkLabel?.isNotEmpty ?? true)), diff --git a/lib/src/widgets/toolbar/buttons/link_style_button.dart b/lib/src/widgets/toolbar/buttons/link_style_button.dart index 265e4e75e..82ad93452 100644 --- a/lib/src/widgets/toolbar/buttons/link_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/link_style_button.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../../../extensions/quill_provider.dart'; +import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../l10n/widgets/localizations.dart'; import '../../../models/documents/attribute.dart'; @@ -15,7 +15,7 @@ import '../base_toolbar.dart'; class QuillToolbarLinkStyleButton extends StatefulWidget { const QuillToolbarLinkStyleButton({ required this.controller, - required this.options, + this.options = const QuillToolbarLinkStyleButtonOptions(), super.key, }); diff --git a/lib/src/widgets/toolbar/buttons/search/search_button.dart b/lib/src/widgets/toolbar/buttons/search/search_button.dart index 2ef2f8627..ed8f634c3 100644 --- a/lib/src/widgets/toolbar/buttons/search/search_button.dart +++ b/lib/src/widgets/toolbar/buttons/search/search_button.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../../../../extensions/quill_provider.dart'; +import '../../../../extensions/quill_configurations_ext.dart'; import '../../../../l10n/extensions/localizations.dart'; import '../../../../l10n/widgets/localizations.dart'; import '../../../../models/themes/quill_dialog_theme.dart'; @@ -11,7 +11,7 @@ import '../../base_toolbar.dart'; class QuillToolbarSearchButton extends StatelessWidget { const QuillToolbarSearchButton({ required QuillController controller, - required this.options, + this.options = const QuillToolbarSearchButtonOptions(), super.key, }) : _controller = controller; diff --git a/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart b/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart index 51fe901b2..c76224b0f 100644 --- a/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart +++ b/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart @@ -20,7 +20,7 @@ enum _AlignmentOptions { class QuillToolbarSelectAlignmentButtons extends StatelessWidget { const QuillToolbarSelectAlignmentButtons({ required this.controller, - required this.options, + this.options = const QuillToolbarSelectAlignmentButtonOptions(), this.showLeftAlignment, this.showCenterAlignment, this.showRightAlignment, @@ -44,7 +44,6 @@ class QuillToolbarSelectAlignmentButtons extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: _AlignmentOptions.values .map((e) => QuillToolbarToggleStyleButton( - options: const QuillToolbarToggleStyleButtonOptions(), controller: controller, attribute: e.attribute, )) diff --git a/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart b/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart index 9c4c5e31f..ed5913893 100644 --- a/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart +++ b/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart @@ -14,7 +14,7 @@ // class QuillToolbarSelectAlignmentOldButtons extends StatefulWidget { // const QuillToolbarSelectAlignmentOldButtons({ // required this.controller, -// required this.options, +// this.options, // this.showLeftAlignment, // this.showCenterAlignment, // this.showRightAlignment, diff --git a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart index 4016147d8..32140602f 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart @@ -15,7 +15,7 @@ enum _HeaderStyleOptions { class QuillToolbarSelectHeaderStyleButton extends StatefulWidget { const QuillToolbarSelectHeaderStyleButton({ required this.controller, - required this.options, + this.options = const QuillToolbarSelectHeaderStyleButtonsOptions(), super.key, }); diff --git a/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart b/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart index 5972baf20..b1d3dd2c3 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart @@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import '../../../../extensions.dart'; -import '../../../extensions/quill_provider.dart'; +import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; @@ -13,7 +13,7 @@ import '../base_toolbar.dart'; class QuillToolbarSelectHeaderStyleButtons extends StatefulWidget { const QuillToolbarSelectHeaderStyleButtons({ required this.controller, - required this.options, + this.options = const QuillToolbarSelectHeaderStyleButtonsOptions(), super.key, }); @@ -88,8 +88,8 @@ class QuillToolbarSelectHeaderStyleButtonsState Axis get axis { return options.axis ?? + context.quillSimpleToolbarConfigurations?.axis ?? context.quillToolbarConfigurations?.axis ?? - context.quillBaseToolbarConfigurations?.axis ?? (throw ArgumentError( 'There is no default value for the Axis of the toolbar')); } diff --git a/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart b/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart index 2776cbc2b..866882481 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../../../extensions/quill_provider.dart'; +import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/config/toolbar/buttons/base_configurations.dart'; import '../../../models/config/toolbar/buttons/toggle_check_list_configurations.dart'; @@ -13,8 +13,8 @@ import 'toggle_style_button.dart'; class QuillToolbarToggleCheckListButton extends StatefulWidget { const QuillToolbarToggleCheckListButton({ - required this.options, required this.controller, + this.options = const QuillToolbarToggleCheckListButtonOptions(), super.key, }); diff --git a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart index 75a8066d4..2ea43f97b 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../../../extensions/quill_provider.dart'; +import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; @@ -23,9 +23,9 @@ typedef ToggleStyleButtonBuilder = Widget Function( class QuillToolbarToggleStyleButton extends StatefulWidget { const QuillToolbarToggleStyleButton({ - required this.options, required this.controller, required this.attribute, + this.options = const QuillToolbarToggleStyleButtonOptions(), super.key, }); @@ -62,10 +62,9 @@ class QuillToolbarToggleStyleButtonState } double get iconSize { - final baseFontSize = - context.requireQuillToolbarBaseButtonOptions.globalIconSize; + final baseFontSize = context.quillToolbarBaseButtonOptions?.globalIconSize; final iconSize = options.iconSize; - return iconSize ?? baseFontSize; + return iconSize ?? baseFontSize ?? kDefaultIconSize; } double get iconButtonFactor { diff --git a/lib/src/widgets/toolbar/simple_toolbar.dart b/lib/src/widgets/toolbar/simple_toolbar.dart index 094b65797..f27bcd680 100644 --- a/lib/src/widgets/toolbar/simple_toolbar.dart +++ b/lib/src/widgets/toolbar/simple_toolbar.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../../extensions/quill_provider.dart'; +import '../../extensions/quill_configurations_ext.dart'; import '../../l10n/extensions/localizations.dart'; import '../../models/config/toolbar/toolbar_configurations.dart'; import '../../models/documents/attribute.dart'; @@ -67,7 +67,7 @@ class QuillSimpleToolbar extends StatelessWidget toolbarSize: configurations.toolbarSize, childrenBuilder: (context) { final toolbarConfigurations = - context.requireQuillToolbarConfigurations; + context.requireQuillSimpleToolbarConfigurations; final globalIconSize = toolbarConfigurations.buttonOptions.base.globalIconSize; @@ -81,6 +81,7 @@ class QuillSimpleToolbar extends StatelessWidget return [ if (configurations.showUndo) ...[ QuillToolbarHistoryButton( + isUndo: true, options: toolbarConfigurations.buttonOptions.undoHistory, controller: toolbarConfigurations .buttonOptions.undoHistory.controller ?? @@ -90,6 +91,7 @@ class QuillSimpleToolbar extends StatelessWidget ], if (configurations.showRedo) ...[ QuillToolbarHistoryButton( + isUndo: false, options: toolbarConfigurations.buttonOptions.redoHistory, controller: toolbarConfigurations .buttonOptions.redoHistory.controller ?? diff --git a/lib/src/widgets/utils/provider.dart b/lib/src/widgets/utils/provider.dart index 4cd656362..f7fbc02ce 100644 --- a/lib/src/widgets/utils/provider.dart +++ b/lib/src/widgets/utils/provider.dart @@ -5,65 +5,6 @@ import 'package:flutter/widgets.dart' import '../../models/config/quill_configurations.dart'; import '../../models/config/toolbar/toolbar_configurations.dart'; -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 - /// and this editor. - /// - /// Must not be null. - final QuillConfigurations configurations; - - @override - bool updateShouldNotify(covariant QuillProvider oldWidget) { - return oldWidget.configurations != configurations; - } - - static QuillProvider? of(BuildContext context) { - return context.dependOnInheritedWidgetOfExactType(); - } - - static QuillProvider ofNotNull(BuildContext context) { - final provider = of(context); - if (provider == null) { - if (kDebugMode) { - debugPrint( - 'The quill provider must be provided in the widget tree.', - ); - } - throw ArgumentError.checkNotNull( - 'You are using a widget in the Flutter quill library that require ' - 'The Quill provider widget to be in the parent widget tree ' - 'because ' - 'The provider is $provider. Please make sure to wrap this widget' - ' with' - ' QuillProvider widget. ' - 'You might using QuillEditor and QuillToolbar so make sure to' - ' wrap them with the quill provider widget and setup the required ' - 'configurations', - 'QuillProvider', - ); - } - return provider; - } - - /// To pass the [QuillProvider] instance as value instead of creating new - /// widget - static QuillProvider value({ - required QuillProvider value, - required Widget child, - }) { - return QuillProvider( - configurations: value.configurations, - child: child, - ); - } -} - class QuillToolbarProvider extends InheritedWidget { const QuillToolbarProvider({ required super.child, From 0c4c6cd77563de8521b4b44bd49278c7360d43da Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 6 Dec 2023 09:36:35 +0300 Subject: [PATCH 35/86] Prepare 9.0.0-dev-4 --- flutter_quill_extensions/CHANGELOG.md | 4 ++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 4 ++++ flutter_quill_test/pubspec.yaml | 2 +- lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart | 1 - packages/quill_html_converter/CHANGELOG.md | 4 ++++ packages/quill_html_converter/pubspec.yaml | 2 +- pubspec.yaml | 2 +- version.dart | 2 +- 9 files changed, 17 insertions(+), 6 deletions(-) diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 7132f0725..849261e54 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-4 +* The options parameter in all of the buttons is no longer required which can be useful to create custom toolbar with minimal efforts +* Toolbar buttons fixes in both `flutter_quill` and `flutter_quill_extensions` + ## 9.0.0-dev-3 * Breaking Changes: * Rename `QuillToolbar` to `QuillSimpleToolbar` diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 4caf7e9bf..aa8f82773 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: 9.0.0-dev-3 +version: 9.0.0-dev-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/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 7132f0725..849261e54 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-4 +* The options parameter in all of the buttons is no longer required which can be useful to create custom toolbar with minimal efforts +* Toolbar buttons fixes in both `flutter_quill` and `flutter_quill_extensions` + ## 9.0.0-dev-3 * Breaking Changes: * Rename `QuillToolbar` to `QuillSimpleToolbar` diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 477d4dcd9..e0b37648a 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: 9.0.0-dev-3 +version: 9.0.0-dev-4 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart b/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart index c76224b0f..af5c383a5 100644 --- a/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart +++ b/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import '../../../models/config/toolbar/buttons/select_alignment_configurations.dart'; -import '../../../models/config/toolbar/buttons/toggle_style_configurations.dart'; import '../../../models/documents/attribute.dart'; import '../../others/controller.dart'; import 'toggle_style_button.dart'; diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index 7132f0725..849261e54 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-4 +* The options parameter in all of the buttons is no longer required which can be useful to create custom toolbar with minimal efforts +* Toolbar buttons fixes in both `flutter_quill` and `flutter_quill_extensions` + ## 9.0.0-dev-3 * Breaking Changes: * Rename `QuillToolbar` to `QuillSimpleToolbar` diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index 995ceaddd..0ce0ffe1b 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.0.0-dev-3 +version: 9.0.0-dev-4 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index b528c9e6a..0fff6388f 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: 9.0.0-dev-3 +version: 9.0.0-dev-4 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/version.dart b/version.dart index a2833398e..3fd9df73d 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev-3'; +const version = '9.0.0-dev-4'; From 9727fea996aa44f5d6d28106c673097c79c2649f Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 6 Dec 2023 10:14:59 +0300 Subject: [PATCH 36/86] 4 --- CHANGELOG.md | 6 + .../lib/presentation/quill/quill_screen.dart | 1 - .../lib/presentation/quill/quill_toolbar.dart | 188 ++-- example/pubspec.yaml | 2 - .../others/camera_button/camera_button.dart | 11 +- .../camera_button/select_camera_action.dart | 56 +- flutter_quill_extensions/pubspec.yaml | 1 + .../toolbar/toolbar_configurations.dart | 26 +- lib/src/widgets/toolbar/base_toolbar.dart | 82 +- lib/src/widgets/toolbar/simple_toolbar.dart | 831 ++++++++++-------- version.dart | 2 +- 11 files changed, 593 insertions(+), 613 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 849261e54..14612cdd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,15 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-5 +* The `QuillToolbar` is now accepting only `child` with no configurations so you can customize everything you wants, the `QuillToolbar.simple()` or `QuillSimpleToolbar` implements a simple toolbar that is based on `QuillToolbar`, you are free to use it but it just an example and not standard +* Flutter Quill Extensions: + * Improve the camera button + ## 9.0.0-dev-4 * The options parameter in all of the buttons is no longer required which can be useful to create custom toolbar with minimal efforts * Toolbar buttons fixes in both `flutter_quill` and `flutter_quill_extensions` +* The `QuillProvider` has been dropped and no longer used, the providers will be used only internally from now on and we will not using them as much as possible ## 9.0.0-dev-3 * Breaking Changes: diff --git a/example/lib/presentation/quill/quill_screen.dart b/example/lib/presentation/quill/quill_screen.dart index 7f34cc305..86ea834ff 100644 --- a/example/lib/presentation/quill/quill_screen.dart +++ b/example/lib/presentation/quill/quill_screen.dart @@ -106,7 +106,6 @@ class _QuillScreenState extends State { MyQuillToolbar( controller: _controller, focusNode: _editorFocusNode, - sharedConfigurations: _sharedConfigurations, ), Builder( builder: (context) { diff --git a/example/lib/presentation/quill/quill_toolbar.dart b/example/lib/presentation/quill/quill_toolbar.dart index 4c0f3124d..e7b02fe1e 100644 --- a/example/lib/presentation/quill/quill_toolbar.dart +++ b/example/lib/presentation/quill/quill_toolbar.dart @@ -17,14 +17,11 @@ class MyQuillToolbar extends StatelessWidget { const MyQuillToolbar({ required this.controller, required this.focusNode, - required this.sharedConfigurations, super.key, }); final QuillController controller; final FocusNode focusNode; - // TODO: Use it - final QuillSharedConfigurations sharedConfigurations; Future onImageInsertWithCropping( String image, @@ -104,105 +101,106 @@ class MyQuillToolbar extends StatelessWidget { // https://github.com/singerdmx/flutter-quill/blob/master/doc/custom_toolbar.md return QuillToolbar( configurations: QuillToolbarConfigurations( - toolbarSize: 20 * 2, - multiRowsDisplay: false, buttonOptions: const QuillToolbarButtonOptions( base: QuillToolbarBaseButtonOptions( globalIconSize: 20, globalIconButtonFactor: 1.4, ), ), - childrenBuilder: (context) { - return [ - IconButton( - onPressed: () => context - .read() - .updateSettings( - state.copyWith(useCustomQuillToolbar: false)), - icon: const Icon( - Icons.width_normal, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + IconButton( + onPressed: () => context + .read() + .updateSettings( + state.copyWith(useCustomQuillToolbar: false)), + icon: const Icon( + Icons.width_normal, + ), ), - ), - QuillToolbarHistoryButton( - isUndo: true, - controller: controller, - ), - QuillToolbarHistoryButton( - isUndo: false, - controller: controller, - ), - QuillToolbarToggleStyleButton( - options: const QuillToolbarToggleStyleButtonOptions(), - controller: controller, - attribute: Attribute.bold, - ), - QuillToolbarToggleStyleButton( - options: const QuillToolbarToggleStyleButtonOptions(), - controller: controller, - attribute: Attribute.italic, - ), - QuillToolbarToggleStyleButton( - controller: controller, - attribute: Attribute.underline, - ), - QuillToolbarClearFormatButton( - controller: controller, - ), - const VerticalDivider(), - QuillToolbarImageButton( - controller: controller, - ), - QuillToolbarCameraButton( - controller: controller, - ), - QuillToolbarVideoButton( - controller: controller, - ), - const VerticalDivider(), - QuillToolbarColorButton( - controller: controller, - isBackground: false, - ), - QuillToolbarColorButton( - controller: controller, - isBackground: true, - ), - const VerticalDivider(), - QuillToolbarSelectHeaderStyleButton( - controller: controller, - ), - const VerticalDivider(), - QuillToolbarToggleCheckListButton( - controller: controller, - ), - QuillToolbarToggleStyleButton( - controller: controller, - attribute: Attribute.list, - ), - QuillToolbarToggleStyleButton( - controller: controller, - attribute: Attribute.ul, - ), - QuillToolbarToggleStyleButton( - controller: controller, - attribute: Attribute.inlineCode, - ), - QuillToolbarToggleStyleButton( - controller: controller, - attribute: Attribute.blockQuote, - ), - QuillToolbarIndentButton( - controller: controller, - isIncrease: true, - ), - QuillToolbarIndentButton( - controller: controller, - isIncrease: false, - ), - const VerticalDivider(), - QuillToolbarLinkStyleButton(controller: controller), - ]; - }, + QuillToolbarHistoryButton( + isUndo: true, + controller: controller, + ), + QuillToolbarHistoryButton( + isUndo: false, + controller: controller, + ), + QuillToolbarToggleStyleButton( + options: const QuillToolbarToggleStyleButtonOptions(), + controller: controller, + attribute: Attribute.bold, + ), + QuillToolbarToggleStyleButton( + options: const QuillToolbarToggleStyleButtonOptions(), + controller: controller, + attribute: Attribute.italic, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.underline, + ), + QuillToolbarClearFormatButton( + controller: controller, + ), + const VerticalDivider(), + QuillToolbarImageButton( + controller: controller, + ), + QuillToolbarCameraButton( + controller: controller, + ), + QuillToolbarVideoButton( + controller: controller, + ), + const VerticalDivider(), + QuillToolbarColorButton( + controller: controller, + isBackground: false, + ), + QuillToolbarColorButton( + controller: controller, + isBackground: true, + ), + const VerticalDivider(), + QuillToolbarSelectHeaderStyleButton( + controller: controller, + ), + const VerticalDivider(), + QuillToolbarToggleCheckListButton( + controller: controller, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.ol, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.ul, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.inlineCode, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.blockQuote, + ), + QuillToolbarIndentButton( + controller: controller, + isIncrease: true, + ), + QuillToolbarIndentButton( + controller: controller, + isIncrease: false, + ), + const VerticalDivider(), + QuillToolbarLinkStyleButton(controller: controller), + ], + ), + ), ), ); } diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 731d56459..bf3192add 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -24,8 +24,6 @@ dependencies: cross_file: ^0.3.3+6 cached_network_image: ^3.3.0 - gal_linux: ^0.0.1-dev - # Bloc libraries bloc: ^8.1.2 flutter_bloc: ^8.1.3 diff --git a/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart b/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart index 70ef09907..ef7ad3da5 100644 --- a/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart +++ b/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart @@ -120,10 +120,8 @@ class QuillToolbarCameraButton extends StatelessWidget { if (customCallback != null) { return await customCallback(context); } - final cameraAction = await showDialog( + final cameraAction = await showSelectCameraActionDialog( context: context, - builder: (ctx) => const FlutterQuillLocalizationsWidget( - child: SelectCameraActionDialog()), ); return cameraAction; @@ -171,12 +169,5 @@ class QuillToolbarCameraButton extends StatelessWidget { 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), - // }; } } diff --git a/flutter_quill_extensions/lib/embeds/others/camera_button/select_camera_action.dart b/flutter_quill_extensions/lib/embeds/others/camera_button/select_camera_action.dart index bd6527db7..c20670280 100644 --- a/flutter_quill_extensions/lib/embeds/others/camera_button/select_camera_action.dart +++ b/flutter_quill_extensions/lib/embeds/others/camera_button/select_camera_action.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_quill/extensions.dart'; import 'package:flutter_quill/translations.dart'; import 'camera_types.dart'; @@ -8,27 +9,46 @@ class SelectCameraActionDialog extends StatelessWidget { @override Widget build(BuildContext context) { - return AlertDialog( - contentPadding: EdgeInsets.zero, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - TextButton.icon( - icon: const Icon( - Icons.camera, + return SizedBox( + height: 150, + width: double.infinity, + child: SingleChildScrollView( + child: Column( + children: [ + ListTile( + title: Text(context.loc.photo), + subtitle: Text( + context.loc.takeAPhotoUsingYourCamera, + ), + leading: const Icon(Icons.photo_sharp), + enabled: !isDesktop(supportWeb: false), + onTap: () => Navigator.of(context).pop(CameraAction.image), ), - label: Text(context.loc.photo), - onPressed: () => Navigator.pop(context, CameraAction.image), - ), - TextButton.icon( - icon: const Icon( - Icons.video_call, + ListTile( + title: Text(context.loc.video), + subtitle: Text( + context.loc.recordAVideoUsingYourCamera, + ), + leading: const Icon(Icons.camera), + enabled: !isDesktop(supportWeb: false), + onTap: () => Navigator.of(context).pop(CameraAction.video), ), - label: Text(context.loc.video), - onPressed: () => Navigator.pop(context, CameraAction.video), - ) - ], + ], + ), ), ); } } + +Future showSelectCameraActionDialog({ + required BuildContext context, +}) async { + final imageSource = await showModalBottomSheet( + showDragHandle: true, + context: context, + constraints: const BoxConstraints(maxWidth: 640), + builder: (context) => const FlutterQuillLocalizationsWidget( + child: SelectCameraActionDialog()), + ); + return imageSource; +} diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index aa8f82773..4048ccc82 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -44,6 +44,7 @@ dependencies: url_launcher: ^6.2.1 super_clipboard: ^0.7.3 gal: ^2.1.3 + gal_linux: ^0.0.1-dev-3 image_picker: ^1.0.4 dev_dependencies: diff --git a/lib/src/models/config/toolbar/toolbar_configurations.dart b/lib/src/models/config/toolbar/toolbar_configurations.dart index 5969e23c7..2e974a7ce 100644 --- a/lib/src/models/config/toolbar/toolbar_configurations.dart +++ b/lib/src/models/config/toolbar/toolbar_configurations.dart @@ -1,6 +1,6 @@ // ignore_for_file: public_member_api_docs, sort_constructors_first import 'package:flutter/widgets.dart' - show Axis, WrapAlignment, WrapCrossAlignment, immutable; + show Axis, Widget, WrapAlignment, WrapCrossAlignment, immutable; import '../../../widgets/toolbar/base_toolbar.dart'; import 'toolbar_shared_configurations.dart'; @@ -8,34 +8,16 @@ import 'toolbar_shared_configurations.dart'; @immutable class QuillToolbarConfigurations extends QuillSharedToolbarProperties { const QuillToolbarConfigurations({ - this.childrenBuilder, - super.axis = Axis.horizontal, - super.toolbarSize = kDefaultIconSize * 2, - super.toolbarSectionSpacing = kToolbarSectionSpacing, - super.toolbarIconAlignment = WrapAlignment.center, - super.toolbarIconCrossAlignment = WrapCrossAlignment.center, - super.color, - super.sectionDividerColor, - super.sectionDividerSpace, - super.linkDialogAction, - super.multiRowsDisplay = true, - super.decoration, + required this.child, + super.sharedConfigurations, /// Note this only used when you using the quill toolbar buttons like /// `QuillToolbarHistoryButton` inside it super.buttonOptions = const QuillToolbarButtonOptions(), }); - final QuillBaseToolbarChildrenBuilder? childrenBuilder; + final Widget child; @override List get props => []; - - QuillToolbarConfigurations copyWith({ - QuillBaseToolbarChildrenBuilder? childrenBuilder, - }) { - return QuillToolbarConfigurations( - childrenBuilder: childrenBuilder ?? this.childrenBuilder, - ); - } } diff --git a/lib/src/widgets/toolbar/base_toolbar.dart b/lib/src/widgets/toolbar/base_toolbar.dart index 6d535b1ac..c22113050 100644 --- a/lib/src/widgets/toolbar/base_toolbar.dart +++ b/lib/src/widgets/toolbar/base_toolbar.dart @@ -5,7 +5,6 @@ import '../../../flutter_quill.dart' import '../../l10n/widgets/localizations.dart'; import '../../models/config/toolbar/simple_toolbar_configurations.dart'; import '../../models/config/toolbar/toolbar_configurations.dart'; -import 'buttons/arrow_indicated_list_button.dart'; import 'simple_toolbar.dart'; export '../../models/config/toolbar/buttons/base_configurations.dart'; @@ -56,90 +55,11 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { @override Widget build(BuildContext context) { - final toolbarSize = configurations.toolbarSize; return FlutterQuillLocalizationsWidget( child: QuillBaseToolbarProvider( toolbarConfigurations: configurations, - child: Builder( - builder: (context) { - if (configurations.multiRowsDisplay) { - return Wrap( - direction: configurations.axis, - alignment: configurations.toolbarIconAlignment, - crossAxisAlignment: configurations.toolbarIconCrossAlignment, - runSpacing: 4, - spacing: configurations.toolbarSectionSpacing, - children: configurations.childrenBuilder?.call(context) ?? [], - ); - } - return Container( - decoration: configurations.decoration ?? - BoxDecoration( - color: - configurations.color ?? Theme.of(context).canvasColor, - ), - constraints: BoxConstraints.tightFor( - height: - configurations.axis == Axis.horizontal ? toolbarSize : null, - width: - configurations.axis == Axis.vertical ? toolbarSize : null, - ), - child: QuillToolbarArrowIndicatedButtonList( - axis: configurations.axis, - buttons: configurations.childrenBuilder?.call(context) ?? [], - ), - ); - }, - ), + child: configurations.child, ), ); } } - -/// The divider which is used for separation of buttons in the toolbar. -/// -/// It can be used outside of this package, for example when user does not use -/// [QuillToolbar.basic] and compose toolbar's children on its own. -class QuillToolbarDivider extends StatelessWidget { - const QuillToolbarDivider( - this.axis, { - super.key, - this.color, - this.space, - }); - - /// Provides a horizontal divider for vertical toolbar. - 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({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; - - /// The color to use when painting this divider's line. - final Color? color; - - /// The divider's space (width or height) depending of [axis]. - final double? space; - - @override - Widget build(BuildContext context) { - // Vertical toolbar requires horizontal divider, and vice versa - return axis == Axis.vertical - ? Divider( - height: space, - color: color, - indent: 12, - endIndent: 12, - ) - : VerticalDivider( - width: space, - color: color, - indent: 12, - endIndent: 12, - ); - } -} diff --git a/lib/src/widgets/toolbar/simple_toolbar.dart b/lib/src/widgets/toolbar/simple_toolbar.dart index f27bcd680..867409640 100644 --- a/lib/src/widgets/toolbar/simple_toolbar.dart +++ b/lib/src/widgets/toolbar/simple_toolbar.dart @@ -6,6 +6,7 @@ import '../../models/config/toolbar/toolbar_configurations.dart'; import '../../models/documents/attribute.dart'; import '../utils/provider.dart'; import 'base_toolbar.dart'; +import 'buttons/arrow_indicated_list_button.dart'; import 'buttons/select_alignment_buttons.dart'; import 'buttons/select_header_style_button.dart'; @@ -50,400 +51,416 @@ class QuillSimpleToolbar extends StatelessWidget configurations.showLink || configurations.showSearchButton ]; - return QuillToolbarProvider( - toolbarConfigurations: configurations, - child: QuillToolbar( - configurations: QuillToolbarConfigurations( - color: configurations.color, - decoration: configurations.decoration, - toolbarSectionSpacing: configurations.toolbarSectionSpacing, - toolbarIconAlignment: configurations.toolbarIconAlignment, - toolbarIconCrossAlignment: configurations.toolbarIconCrossAlignment, - linkDialogAction: configurations.linkDialogAction, - multiRowsDisplay: configurations.multiRowsDisplay, - sectionDividerColor: configurations.sectionDividerColor, - axis: configurations.axis, - sectionDividerSpace: configurations.sectionDividerSpace, - toolbarSize: configurations.toolbarSize, - childrenBuilder: (context) { - final toolbarConfigurations = - context.requireQuillSimpleToolbarConfigurations; + List childrenBuilder(context) { + final toolbarConfigurations = + context.requireQuillSimpleToolbarConfigurations; - final globalIconSize = - toolbarConfigurations.buttonOptions.base.globalIconSize; + final globalIconSize = + toolbarConfigurations.buttonOptions.base.globalIconSize; - final axis = toolbarConfigurations.axis; - final globalController = configurations.controller; + final axis = toolbarConfigurations.axis; + final globalController = configurations.controller; - final spacerWidget = - configurations.spacerWidget ?? const SizedBox.shrink(); + final spacerWidget = + configurations.spacerWidget ?? const SizedBox.shrink(); - return [ - if (configurations.showUndo) ...[ - QuillToolbarHistoryButton( - isUndo: true, - options: toolbarConfigurations.buttonOptions.undoHistory, - controller: toolbarConfigurations - .buttonOptions.undoHistory.controller ?? - globalController, - ), - spacerWidget, - ], - if (configurations.showRedo) ...[ - QuillToolbarHistoryButton( - isUndo: false, - options: toolbarConfigurations.buttonOptions.redoHistory, - controller: toolbarConfigurations - .buttonOptions.redoHistory.controller ?? - globalController, - ), - spacerWidget, - ], - if (configurations.showFontFamily) ...[ - QuillToolbarFontFamilyButton( - options: toolbarConfigurations.buttonOptions.fontFamily, - controller: toolbarConfigurations - .buttonOptions.fontFamily.controller ?? - globalController, - defaultDispalyText: context.loc.font, - ), - spacerWidget, - ], - if (configurations.showFontSize) ...[ - QuillToolbarFontSizeButton( - options: toolbarConfigurations.buttonOptions.fontSize, + return [ + if (configurations.showUndo) ...[ + QuillToolbarHistoryButton( + isUndo: true, + options: toolbarConfigurations.buttonOptions.undoHistory, + controller: + toolbarConfigurations.buttonOptions.undoHistory.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showRedo) ...[ + QuillToolbarHistoryButton( + isUndo: false, + options: toolbarConfigurations.buttonOptions.redoHistory, + controller: + toolbarConfigurations.buttonOptions.redoHistory.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showFontFamily) ...[ + QuillToolbarFontFamilyButton( + options: toolbarConfigurations.buttonOptions.fontFamily, + controller: + toolbarConfigurations.buttonOptions.fontFamily.controller ?? + globalController, + defaultDispalyText: context.loc.font, + ), + spacerWidget, + ], + if (configurations.showFontSize) ...[ + QuillToolbarFontSizeButton( + options: toolbarConfigurations.buttonOptions.fontSize, + controller: + toolbarConfigurations.buttonOptions.fontFamily.controller ?? + globalController, + defaultDisplayText: context.loc.fontSize, + ), + spacerWidget, + ], + if (configurations.showBoldButton) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.bold, + options: toolbarConfigurations.buttonOptions.bold, + controller: toolbarConfigurations.buttonOptions.bold.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showItalicButton) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.italic, + options: toolbarConfigurations.buttonOptions.italic, + controller: toolbarConfigurations.buttonOptions.italic.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showUnderLineButton) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.underline, + options: toolbarConfigurations.buttonOptions.underLine, + controller: + toolbarConfigurations.buttonOptions.underLine.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showInlineCode) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.inlineCode, + options: toolbarConfigurations.buttonOptions.inlineCode, + controller: + toolbarConfigurations.buttonOptions.inlineCode.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showSubscript) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.subscript, + options: toolbarConfigurations.buttonOptions.subscript, + controller: + toolbarConfigurations.buttonOptions.subscript.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showSuperscript) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.superscript, + options: toolbarConfigurations.buttonOptions.superscript, + controller: + toolbarConfigurations.buttonOptions.superscript.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showSmallButton) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.small, + options: toolbarConfigurations.buttonOptions.small, + controller: toolbarConfigurations.buttonOptions.small.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showStrikeThrough) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.strikeThrough, + options: toolbarConfigurations.buttonOptions.strikeThrough, + controller: + toolbarConfigurations.buttonOptions.strikeThrough.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showColorButton) ...[ + QuillToolbarColorButton( + controller: toolbarConfigurations.buttonOptions.color.controller ?? + globalController, + isBackground: false, + options: toolbarConfigurations.buttonOptions.color, + ), + spacerWidget, + ], + if (configurations.showBackgroundColorButton) ...[ + QuillToolbarColorButton( + options: toolbarConfigurations.buttonOptions.backgroundColor, + controller: toolbarConfigurations.buttonOptions.color.controller ?? + globalController, + isBackground: true, + ), + spacerWidget, + ], + if (configurations.showClearFormat) ...[ + QuillToolbarClearFormatButton( + controller: + toolbarConfigurations.buttonOptions.clearFormat.controller ?? + globalController, + options: toolbarConfigurations.buttonOptions.clearFormat, + ), + spacerWidget, + ], + if (theEmbedButtons != null) + for (final builder in theEmbedButtons) + builder( + globalController, + globalIconSize, + context.requireQuillToolbarBaseButtonOptions.iconTheme, + configurations.dialogTheme), + if (configurations.showDividers && + isButtonGroupShown[0] && + (isButtonGroupShown[1] || + isButtonGroupShown[2] || + isButtonGroupShown[3] || + isButtonGroupShown[4] || + isButtonGroupShown[5])) + QuillToolbarDivider( + axis, + color: configurations.sectionDividerColor, + space: configurations.sectionDividerSpace, + ), + if (configurations.showAlignmentButtons) ...[ + QuillToolbarSelectAlignmentButtons( + controller: toolbarConfigurations + .buttonOptions.selectAlignmentButtons.controller ?? + globalController, + options: toolbarConfigurations.buttonOptions.selectAlignmentButtons, + showLeftAlignment: configurations.showLeftAlignment, + showCenterAlignment: configurations.showCenterAlignment, + showRightAlignment: configurations.showRightAlignment, + showJustifyAlignment: configurations.showJustifyAlignment, + ), + spacerWidget, + ], + if (configurations.showDirection) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.rtl, + options: toolbarConfigurations.buttonOptions.direction, + controller: + toolbarConfigurations.buttonOptions.direction.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showDividers && + isButtonGroupShown[1] && + (isButtonGroupShown[2] || + isButtonGroupShown[3] || + isButtonGroupShown[4] || + isButtonGroupShown[5])) + QuillToolbarDivider( + axis, + color: configurations.sectionDividerColor, + space: configurations.sectionDividerSpace, + ), + if (configurations.showHeaderStyle) ...[ + QuillToolbarSelectHeaderStyleButton( + controller: toolbarConfigurations + .buttonOptions.selectHeaderStyleButtons.controller ?? + globalController, + options: + toolbarConfigurations.buttonOptions.selectHeaderStyleButtons, + ), + spacerWidget, + ], + if (configurations.showDividers && + configurations.showHeaderStyle && + isButtonGroupShown[2] && + (isButtonGroupShown[3] || + isButtonGroupShown[4] || + isButtonGroupShown[5])) + QuillToolbarDivider( + axis, + color: configurations.sectionDividerColor, + space: configurations.sectionDividerSpace, + ), + if (configurations.showListNumbers) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.ol, + options: toolbarConfigurations.buttonOptions.listNumbers, + controller: + toolbarConfigurations.buttonOptions.listNumbers.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showListBullets) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.ul, + options: toolbarConfigurations.buttonOptions.listBullets, + controller: + toolbarConfigurations.buttonOptions.listBullets.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showListCheck) ...[ + QuillToolbarToggleCheckListButton( + options: toolbarConfigurations.buttonOptions.toggleCheckList, + controller: toolbarConfigurations + .buttonOptions.toggleCheckList.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showCodeBlock) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.codeBlock, + options: toolbarConfigurations.buttonOptions.codeBlock, + controller: + toolbarConfigurations.buttonOptions.codeBlock.controller ?? + globalController, + ), + spacerWidget, + ], + if (configurations.showDividers && + isButtonGroupShown[3] && + (isButtonGroupShown[4] || isButtonGroupShown[5])) ...[ + QuillToolbarDivider( + axis, + color: configurations.sectionDividerColor, + space: configurations.sectionDividerSpace, + ), + ], + if (configurations.showQuote) ...[ + QuillToolbarToggleStyleButton( + options: toolbarConfigurations.buttonOptions.quote, + controller: toolbarConfigurations.buttonOptions.quote.controller ?? + globalController, + attribute: Attribute.blockQuote, + ), + spacerWidget, + ], + if (configurations.showIndent) ...[ + QuillToolbarIndentButton( + controller: + toolbarConfigurations.buttonOptions.indentIncrease.controller ?? + globalController, + isIncrease: true, + options: toolbarConfigurations.buttonOptions.indentIncrease, + ), + spacerWidget, + ], + if (configurations.showIndent) ...[ + QuillToolbarIndentButton( + controller: + toolbarConfigurations.buttonOptions.indentDecrease.controller ?? + globalController, + isIncrease: false, + options: toolbarConfigurations.buttonOptions.indentDecrease, + ), + spacerWidget, + ], + if (configurations.showDividers && + isButtonGroupShown[4] && + isButtonGroupShown[5]) + QuillToolbarDivider( + axis, + color: configurations.sectionDividerColor, + space: configurations.sectionDividerSpace, + ), + if (configurations.showLink) ...[ + toolbarConfigurations.linkStyleType.isOriginal + ? QuillToolbarLinkStyleButton( controller: toolbarConfigurations - .buttonOptions.fontFamily.controller ?? + .buttonOptions.linkStyle.controller ?? globalController, - defaultDisplayText: context.loc.fontSize, - ), - spacerWidget, - ], - if (configurations.showBoldButton) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.bold, - options: toolbarConfigurations.buttonOptions.bold, - controller: - toolbarConfigurations.buttonOptions.bold.controller ?? - globalController, - ), - spacerWidget, - ], - if (configurations.showItalicButton) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.italic, - options: toolbarConfigurations.buttonOptions.italic, - controller: - toolbarConfigurations.buttonOptions.italic.controller ?? - globalController, - ), - spacerWidget, - ], - if (configurations.showUnderLineButton) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.underline, - options: toolbarConfigurations.buttonOptions.underLine, - controller: toolbarConfigurations - .buttonOptions.underLine.controller ?? - globalController, - ), - spacerWidget, - ], - if (configurations.showInlineCode) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.inlineCode, - options: toolbarConfigurations.buttonOptions.inlineCode, - controller: toolbarConfigurations - .buttonOptions.inlineCode.controller ?? - globalController, - ), - spacerWidget, - ], - if (configurations.showSubscript) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.subscript, - options: toolbarConfigurations.buttonOptions.subscript, + options: toolbarConfigurations.buttonOptions.linkStyle, + ) + : QuillToolbarLinkStyleButton2( controller: toolbarConfigurations - .buttonOptions.subscript.controller ?? + .buttonOptions.linkStyle2.controller ?? globalController, + options: toolbarConfigurations.buttonOptions.linkStyle2, ), - spacerWidget, - ], - if (configurations.showSuperscript) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.superscript, - options: toolbarConfigurations.buttonOptions.superscript, - controller: toolbarConfigurations - .buttonOptions.superscript.controller ?? - globalController, - ), - spacerWidget, - ], - if (configurations.showSmallButton) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.small, - options: toolbarConfigurations.buttonOptions.small, - controller: - toolbarConfigurations.buttonOptions.small.controller ?? - globalController, - ), - spacerWidget, - ], - if (configurations.showStrikeThrough) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.strikeThrough, - options: toolbarConfigurations.buttonOptions.strikeThrough, - controller: toolbarConfigurations - .buttonOptions.strikeThrough.controller ?? - globalController, - ), - spacerWidget, - ], - if (configurations.showColorButton) ...[ - QuillToolbarColorButton( - controller: - toolbarConfigurations.buttonOptions.color.controller ?? - globalController, - isBackground: false, - options: toolbarConfigurations.buttonOptions.color, - ), - spacerWidget, - ], - if (configurations.showBackgroundColorButton) ...[ - QuillToolbarColorButton( - options: toolbarConfigurations.buttonOptions.backgroundColor, - controller: - toolbarConfigurations.buttonOptions.color.controller ?? - globalController, - isBackground: true, - ), - spacerWidget, - ], - if (configurations.showClearFormat) ...[ - QuillToolbarClearFormatButton( - controller: toolbarConfigurations - .buttonOptions.clearFormat.controller ?? - globalController, - options: toolbarConfigurations.buttonOptions.clearFormat, - ), - spacerWidget, - ], - if (theEmbedButtons != null) - for (final builder in theEmbedButtons) - builder( - globalController, - globalIconSize, - context.requireQuillToolbarBaseButtonOptions.iconTheme, - configurations.dialogTheme), - if (configurations.showDividers && - isButtonGroupShown[0] && - (isButtonGroupShown[1] || - isButtonGroupShown[2] || - isButtonGroupShown[3] || - isButtonGroupShown[4] || - isButtonGroupShown[5])) - QuillToolbarDivider( - axis, - color: configurations.sectionDividerColor, - space: configurations.sectionDividerSpace, - ), - if (configurations.showAlignmentButtons) ...[ - QuillToolbarSelectAlignmentButtons( - controller: toolbarConfigurations - .buttonOptions.selectAlignmentButtons.controller ?? - globalController, - options: toolbarConfigurations - .buttonOptions.selectAlignmentButtons, - showLeftAlignment: configurations.showLeftAlignment, - showCenterAlignment: configurations.showCenterAlignment, - showRightAlignment: configurations.showRightAlignment, - showJustifyAlignment: configurations.showJustifyAlignment, - ), - spacerWidget, - ], - if (configurations.showDirection) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.rtl, - options: toolbarConfigurations.buttonOptions.direction, - controller: toolbarConfigurations - .buttonOptions.direction.controller ?? - globalController, - ), - spacerWidget, - ], - if (configurations.showDividers && - isButtonGroupShown[1] && - (isButtonGroupShown[2] || - isButtonGroupShown[3] || - isButtonGroupShown[4] || - isButtonGroupShown[5])) - QuillToolbarDivider( - axis, - color: configurations.sectionDividerColor, - space: configurations.sectionDividerSpace, - ), - if (configurations.showHeaderStyle) ...[ - QuillToolbarSelectHeaderStyleButton( - controller: toolbarConfigurations - .buttonOptions.selectHeaderStyleButtons.controller ?? - globalController, - options: toolbarConfigurations - .buttonOptions.selectHeaderStyleButtons, - ), - spacerWidget, - ], - if (configurations.showDividers && - configurations.showHeaderStyle && - isButtonGroupShown[2] && - (isButtonGroupShown[3] || - isButtonGroupShown[4] || - isButtonGroupShown[5])) - QuillToolbarDivider( - axis, - color: configurations.sectionDividerColor, - space: configurations.sectionDividerSpace, - ), - if (configurations.showListNumbers) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.ol, - options: toolbarConfigurations.buttonOptions.listNumbers, - controller: toolbarConfigurations - .buttonOptions.listNumbers.controller ?? - globalController, - ), - spacerWidget, - ], - if (configurations.showListBullets) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.ul, - options: toolbarConfigurations.buttonOptions.listBullets, - controller: toolbarConfigurations - .buttonOptions.listBullets.controller ?? - globalController, - ), - spacerWidget, - ], - if (configurations.showListCheck) ...[ - QuillToolbarToggleCheckListButton( - options: toolbarConfigurations.buttonOptions.toggleCheckList, - controller: toolbarConfigurations - .buttonOptions.toggleCheckList.controller ?? - globalController, - ), - spacerWidget, - ], - if (configurations.showCodeBlock) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.codeBlock, - options: toolbarConfigurations.buttonOptions.codeBlock, - controller: toolbarConfigurations - .buttonOptions.codeBlock.controller ?? - globalController, - ), - spacerWidget, - ], - if (configurations.showDividers && - isButtonGroupShown[3] && - (isButtonGroupShown[4] || isButtonGroupShown[5])) ...[ - QuillToolbarDivider( - axis, - color: configurations.sectionDividerColor, - space: configurations.sectionDividerSpace, - ), - ], - if (configurations.showQuote) ...[ - QuillToolbarToggleStyleButton( - options: toolbarConfigurations.buttonOptions.quote, - controller: - toolbarConfigurations.buttonOptions.quote.controller ?? - globalController, - attribute: Attribute.blockQuote, - ), - spacerWidget, - ], - if (configurations.showIndent) ...[ - QuillToolbarIndentButton( - controller: toolbarConfigurations - .buttonOptions.indentIncrease.controller ?? - globalController, - isIncrease: true, - options: toolbarConfigurations.buttonOptions.indentIncrease, - ), - spacerWidget, - ], - if (configurations.showIndent) ...[ - QuillToolbarIndentButton( - controller: toolbarConfigurations - .buttonOptions.indentDecrease.controller ?? - globalController, - isIncrease: false, - options: toolbarConfigurations.buttonOptions.indentDecrease, - ), - spacerWidget, - ], - if (configurations.showDividers && - isButtonGroupShown[4] && - isButtonGroupShown[5]) - QuillToolbarDivider( - axis, - color: configurations.sectionDividerColor, - space: configurations.sectionDividerSpace, + spacerWidget, + ], + if (configurations.showSearchButton) ...[ + QuillToolbarSearchButton( + controller: toolbarConfigurations.buttonOptions.search.controller ?? + globalController, + options: toolbarConfigurations.buttonOptions.search, + ), + spacerWidget, + ], + if (configurations.customButtons.isNotEmpty) ...[ + if (configurations.showDividers) + QuillToolbarDivider( + axis, + color: configurations.sectionDividerColor, + space: configurations.sectionDividerSpace, + ), + for (final customButton in configurations.customButtons) + 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, + ], + ]; + } + + return QuillToolbarProvider( + toolbarConfigurations: configurations, + child: QuillToolbar( + configurations: QuillToolbarConfigurations( + buttonOptions: configurations.buttonOptions, + child: Builder( + builder: (context) { + if (configurations.multiRowsDisplay) { + return Wrap( + direction: configurations.axis, + alignment: configurations.toolbarIconAlignment, + crossAxisAlignment: configurations.toolbarIconCrossAlignment, + runSpacing: 4, + spacing: configurations.toolbarSectionSpacing, + children: childrenBuilder(context), + ); + } + return Container( + decoration: configurations.decoration ?? + BoxDecoration( + color: + configurations.color ?? Theme.of(context).canvasColor, + ), + constraints: BoxConstraints.tightFor( + height: configurations.axis == Axis.horizontal + ? configurations.toolbarSize + : null, + width: configurations.axis == Axis.vertical + ? configurations.toolbarSize + : null, ), - if (configurations.showLink) ...[ - toolbarConfigurations.linkStyleType.isOriginal - ? QuillToolbarLinkStyleButton( - controller: toolbarConfigurations - .buttonOptions.linkStyle.controller ?? - globalController, - options: toolbarConfigurations.buttonOptions.linkStyle, - ) - : QuillToolbarLinkStyleButton2( - controller: toolbarConfigurations - .buttonOptions.linkStyle2.controller ?? - globalController, - options: toolbarConfigurations.buttonOptions.linkStyle2, - ), - spacerWidget, - ], - if (configurations.showSearchButton) ...[ - QuillToolbarSearchButton( - controller: - toolbarConfigurations.buttonOptions.search.controller ?? - globalController, - options: toolbarConfigurations.buttonOptions.search, + child: QuillToolbarArrowIndicatedButtonList( + axis: configurations.axis, + buttons: childrenBuilder(context), ), - spacerWidget, - ], - if (configurations.customButtons.isNotEmpty) ...[ - if (configurations.showDividers) - QuillToolbarDivider( - axis, - color: configurations.sectionDividerColor, - space: configurations.sectionDividerSpace, - ), - for (final customButton in configurations.customButtons) - 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, - ], - ]; - }, + ); + }, + ), ), ), ); @@ -454,3 +471,51 @@ class QuillSimpleToolbar extends StatelessWidget ? const Size.fromHeight(defaultToolbarSize) : const Size.fromWidth(defaultToolbarSize); } + +/// The divider which is used for separation of buttons in the toolbar. +/// +/// It can be used outside of this package, for example when user does not use +/// [QuillToolbar.basic] and compose toolbar's children on its own. +class QuillToolbarDivider extends StatelessWidget { + const QuillToolbarDivider( + this.axis, { + super.key, + this.color, + this.space, + }); + + /// Provides a horizontal divider for vertical toolbar. + 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({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; + + /// The color to use when painting this divider's line. + final Color? color; + + /// The divider's space (width or height) depending of [axis]. + final double? space; + + @override + Widget build(BuildContext context) { + // Vertical toolbar requires horizontal divider, and vice versa + return axis == Axis.vertical + ? Divider( + height: space, + color: color, + indent: 12, + endIndent: 12, + ) + : VerticalDivider( + width: space, + color: color, + indent: 12, + endIndent: 12, + ); + } +} diff --git a/version.dart b/version.dart index 3fd9df73d..5b59c4d6b 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev-4'; +const version = '9.0.0-dev-5'; From 8daccaeec63e95f7d9897a3c9b0e7034c504f3e0 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 6 Dec 2023 10:15:53 +0300 Subject: [PATCH 37/86] Fix analysis warrnings --- lib/src/models/config/toolbar/toolbar_configurations.dart | 3 +-- lib/src/widgets/toolbar/simple_toolbar.dart | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/src/models/config/toolbar/toolbar_configurations.dart b/lib/src/models/config/toolbar/toolbar_configurations.dart index 2e974a7ce..29bfc4e8f 100644 --- a/lib/src/models/config/toolbar/toolbar_configurations.dart +++ b/lib/src/models/config/toolbar/toolbar_configurations.dart @@ -1,6 +1,5 @@ // ignore_for_file: public_member_api_docs, sort_constructors_first -import 'package:flutter/widgets.dart' - show Axis, Widget, WrapAlignment, WrapCrossAlignment, immutable; +import 'package:flutter/widgets.dart' show Widget, immutable; import '../../../widgets/toolbar/base_toolbar.dart'; import 'toolbar_shared_configurations.dart'; diff --git a/lib/src/widgets/toolbar/simple_toolbar.dart b/lib/src/widgets/toolbar/simple_toolbar.dart index 867409640..a1da0762e 100644 --- a/lib/src/widgets/toolbar/simple_toolbar.dart +++ b/lib/src/widgets/toolbar/simple_toolbar.dart @@ -1,7 +1,5 @@ import 'package:flutter/material.dart'; -import '../../extensions/quill_configurations_ext.dart'; -import '../../l10n/extensions/localizations.dart'; import '../../models/config/toolbar/toolbar_configurations.dart'; import '../../models/documents/attribute.dart'; import '../utils/provider.dart'; From 90645f1267718af198a8c76491c64e3d276270bf Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 6 Dec 2023 10:48:55 +0300 Subject: [PATCH 38/86] Fix tests --- .../raw_editor_context_menu_items.dart | 160 +++++++ .../widgets/raw_editor/raw_editor_state.dart | 406 +++++++++++------- lib/src/widgets/toolbar/simple_toolbar.dart | 4 +- 3 files changed, 405 insertions(+), 165 deletions(-) create mode 100644 lib/src/widgets/raw_editor/raw_editor_context_menu_items.dart diff --git a/lib/src/widgets/raw_editor/raw_editor_context_menu_items.dart b/lib/src/widgets/raw_editor/raw_editor_context_menu_items.dart new file mode 100644 index 000000000..39541e6cf --- /dev/null +++ b/lib/src/widgets/raw_editor/raw_editor_context_menu_items.dart @@ -0,0 +1,160 @@ +// import 'package:flutter/widgets.dart' show TextSelectionDelegate; + +// class QuillEditorTextSelectionDelegate implements TextSelectionDelegate { +// /// Copy current selection to [Clipboard]. +// @override +// void copySelection(SelectionChangedCause cause) { +// controller.copiedImageUrl = null; +// _pastePlainText = controller.getPlainText(); +// _pasteStyleAndEmbed = controller.getAllIndividualSelectionStylesAndEmbed(); + +// final selection = textEditingValue.selection; +// final text = textEditingValue.text; +// if (selection.isCollapsed) { +// return; +// } +// Clipboard.setData(ClipboardData(text: selection.textInside(text))); + +// if (cause == SelectionChangedCause.toolbar) { +// bringIntoView(textEditingValue.selection.extent); + +// // Collapse the selection and hide the toolbar and handles. +// userUpdateTextEditingValue( +// TextEditingValue( +// text: textEditingValue.text, +// selection: +// TextSelection.collapsed(offset: textEditingValue.selection.end), +// ), +// SelectionChangedCause.toolbar, +// ); +// } +// } + +// /// Cut current selection to [Clipboard]. +// @override +// void cutSelection(SelectionChangedCause cause) { +// controller.copiedImageUrl = null; +// _pastePlainText = controller.getPlainText(); +// _pasteStyleAndEmbed = controller.getAllIndividualSelectionStylesAndEmbed(); + +// if (widget.configurations.readOnly) { +// return; +// } +// final selection = textEditingValue.selection; +// final text = textEditingValue.text; +// if (selection.isCollapsed) { +// return; +// } +// Clipboard.setData(ClipboardData(text: selection.textInside(text))); +// _replaceText(ReplaceTextIntent(textEditingValue, '', selection, cause)); + +// if (cause == SelectionChangedCause.toolbar) { +// bringIntoView(textEditingValue.selection.extent); +// hideToolbar(); +// } +// } + +// /// Paste text from [Clipboard]. +// @override +// Future pasteText(SelectionChangedCause cause) async { +// if (widget.configurations.readOnly) { +// return; +// } + +// if (controller.copiedImageUrl != null) { +// final index = textEditingValue.selection.baseOffset; +// final length = textEditingValue.selection.extentOffset - index; +// final copied = controller.copiedImageUrl!; +// controller.replaceText( +// index, +// length, +// BlockEmbed.image(copied.url), +// null, +// ); +// if (copied.styleString.isNotEmpty) { +// controller.formatText( +// getEmbedNode(controller, index + 1).offset, +// 1, +// StyleAttribute(copied.styleString), +// ); +// } +// controller.copiedImageUrl = null; +// await Clipboard.setData( +// const ClipboardData(text: ''), +// ); +// return; +// } + +// final selection = textEditingValue.selection; +// if (!selection.isValid) { +// return; +// } +// // Snapshot the input before using `await`. +// // See https://github.com/flutter/flutter/issues/11427 +// final text = await Clipboard.getData(Clipboard.kTextPlain); +// if (text != null) { +// _replaceText( +// ReplaceTextIntent( +// textEditingValue, +// text.text!, +// selection, +// cause, +// ), +// ); + +// bringIntoView(textEditingValue.selection.extent); + +// // Collapse the selection and hide the toolbar and handles. +// userUpdateTextEditingValue( +// TextEditingValue( +// text: textEditingValue.text, +// selection: TextSelection.collapsed( +// offset: textEditingValue.selection.end, +// ), +// ), +// cause, +// ); + +// return; +// } + +// final onImagePaste = widget.configurations.onImagePaste; +// if (onImagePaste != null) { +// final reader = await ClipboardReader.readClipboard(); +// if (!reader.canProvide(Formats.png)) { +// return; +// } +// reader.getFile(Formats.png, (value) async { +// final image = value; + +// final imageUrl = await onImagePaste(await image.readAll()); +// if (imageUrl == null) { +// return; +// } + +// controller.replaceText( +// textEditingValue.selection.end, +// 0, +// BlockEmbed.image(imageUrl), +// null, +// ); +// }); +// } +// } + +// /// Select the entire text value. +// @override +// void selectAll(SelectionChangedCause cause) { +// userUpdateTextEditingValue( +// textEditingValue.copyWith( +// selection: TextSelection( +// baseOffset: 0, extentOffset: textEditingValue.text.length), +// ), +// cause, +// ); + +// if (cause == SelectionChangedCause.toolbar) { +// bringIntoView(textEditingValue.selection.extent); +// } +// } +// } diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index 4b11d9675..702f312c5 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -10,11 +10,12 @@ import 'package:flutter/rendering.dart' show RenderAbstractViewport; import 'package:flutter/scheduler.dart' show SchedulerBinding; import 'package:flutter/services.dart' show - LogicalKeyboardKey, - RawKeyDownEvent, - HardwareKeyboard, Clipboard, ClipboardData, + HardwareKeyboard, + LogicalKeyboardKey, + RawKeyDownEvent, + SystemChannels, TextInputControl; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart' show KeyboardVisibilityController; @@ -119,10 +120,186 @@ class QuillRawEditorState extends EditorState /// platform's default selection menu for [QuillRawEditor]. /// /// Copied from [EditableTextState]. + // List get contextMenuButtonItems { + // return EditableText.getEditableButtonItems( + // clipboardStatus: _clipboardStatus.value, + // onLiveTextInput: null, + // onCopy: copyEnabled + // ? () => copySelection(SelectionChangedCause.toolbar) + // : null, + // onCut: + // cutEnabled ? () => cutSelection(SelectionChangedCause.toolbar) : null, + // onPaste: + // pasteEnabled ? () => pasteText(SelectionChangedCause.toolbar) : null, + // onSelectAll: selectAllEnabled + // ? () => selectAll(SelectionChangedCause.toolbar) + // : null, + // onLookUp: null, + // onSearchWeb: null, + // onShare: null, + // ); + // } + + /// Copy current selection to [Clipboard]. + @override + void copySelection(SelectionChangedCause cause) { + controller.copiedImageUrl = null; + _pastePlainText = controller.getPlainText(); + _pasteStyleAndEmbed = controller.getAllIndividualSelectionStylesAndEmbed(); + + final selection = textEditingValue.selection; + final text = textEditingValue.text; + if (selection.isCollapsed) { + return; + } + Clipboard.setData(ClipboardData(text: selection.textInside(text))); + + if (cause == SelectionChangedCause.toolbar) { + bringIntoView(textEditingValue.selection.extent); + + // Collapse the selection and hide the toolbar and handles. + userUpdateTextEditingValue( + TextEditingValue( + text: textEditingValue.text, + selection: + TextSelection.collapsed(offset: textEditingValue.selection.end), + ), + SelectionChangedCause.toolbar, + ); + } + } + + /// Cut current selection to [Clipboard]. + @override + void cutSelection(SelectionChangedCause cause) { + controller.copiedImageUrl = null; + _pastePlainText = controller.getPlainText(); + _pasteStyleAndEmbed = controller.getAllIndividualSelectionStylesAndEmbed(); + + if (widget.configurations.readOnly) { + return; + } + final selection = textEditingValue.selection; + final text = textEditingValue.text; + if (selection.isCollapsed) { + return; + } + Clipboard.setData(ClipboardData(text: selection.textInside(text))); + _replaceText(ReplaceTextIntent(textEditingValue, '', selection, cause)); + + if (cause == SelectionChangedCause.toolbar) { + bringIntoView(textEditingValue.selection.extent); + hideToolbar(); + } + } + + /// Paste text from [Clipboard]. + @override + Future pasteText(SelectionChangedCause cause) async { + if (widget.configurations.readOnly) { + return; + } + + if (controller.copiedImageUrl != null) { + final index = textEditingValue.selection.baseOffset; + final length = textEditingValue.selection.extentOffset - index; + final copied = controller.copiedImageUrl!; + controller.replaceText( + index, + length, + BlockEmbed.image(copied.url), + null, + ); + if (copied.styleString.isNotEmpty) { + controller.formatText( + getEmbedNode(controller, index + 1).offset, + 1, + StyleAttribute(copied.styleString), + ); + } + controller.copiedImageUrl = null; + await Clipboard.setData( + const ClipboardData(text: ''), + ); + return; + } + + final selection = textEditingValue.selection; + if (!selection.isValid) { + return; + } + // Snapshot the input before using `await`. + // See https://github.com/flutter/flutter/issues/11427 + final text = await Clipboard.getData(Clipboard.kTextPlain); + if (text != null) { + _replaceText( + ReplaceTextIntent( + textEditingValue, + text.text!, + selection, + cause, + ), + ); + + bringIntoView(textEditingValue.selection.extent); + + // Collapse the selection and hide the toolbar and handles. + userUpdateTextEditingValue( + TextEditingValue( + text: textEditingValue.text, + selection: TextSelection.collapsed( + offset: textEditingValue.selection.end, + ), + ), + cause, + ); + + return; + } + + final onImagePaste = widget.configurations.onImagePaste; + if (onImagePaste != null) { + final reader = await ClipboardReader.readClipboard(); + if (!reader.canProvide(Formats.png)) { + return; + } + reader.getFile(Formats.png, (value) async { + final image = value; + + final imageUrl = await onImagePaste(await image.readAll()); + if (imageUrl == null) { + return; + } + + controller.replaceText( + textEditingValue.selection.end, + 0, + BlockEmbed.image(imageUrl), + null, + ); + }); + } + } + + /// Select the entire text value. + @override + void selectAll(SelectionChangedCause cause) { + userUpdateTextEditingValue( + textEditingValue.copyWith( + selection: TextSelection( + baseOffset: 0, extentOffset: textEditingValue.text.length), + ), + cause, + ); + + if (cause == SelectionChangedCause.toolbar) { + bringIntoView(textEditingValue.selection.extent); + } + } + List get contextMenuButtonItems { return EditableText.getEditableButtonItems( clipboardStatus: _clipboardStatus.value, - onLiveTextInput: null, onCopy: copyEnabled ? () => copySelection(SelectionChangedCause.toolbar) : null, @@ -133,12 +310,70 @@ class QuillRawEditorState extends EditorState onSelectAll: selectAllEnabled ? () => selectAll(SelectionChangedCause.toolbar) : null, - onLookUp: null, - onSearchWeb: null, - onShare: null, + onLookUp: lookUpEnabled + ? () => lookUpSelection(SelectionChangedCause.toolbar) + : null, + onSearchWeb: searchWebEnabled + ? () => searchWebForSelection(SelectionChangedCause.toolbar) + : null, + onShare: shareEnabled + ? () => shareSelection(SelectionChangedCause.toolbar) + : null, + onLiveTextInput: liveTextInputEnabled ? () {} : null, ); } + /// Look up the current selection, + /// as in the "Look Up" edit menu button on iOS. + /// + /// Currently this is only implemented for iOS. + /// + /// Throws an error if the selection is empty or collapsed. + Future lookUpSelection(SelectionChangedCause cause) async { + final text = textEditingValue.selection.textInside(textEditingValue.text); + if (text.isEmpty) { + return; + } + await SystemChannels.platform.invokeMethod( + 'LookUp.invoke', + text, + ); + } + + /// Launch a web search on the current selection, + /// as in the "Search Web" edit menu button on iOS. + /// + /// Currently this is only implemented for iOS. + /// + /// When 'obscureText' is true or the selection is empty, + /// this function will not do anything + Future searchWebForSelection(SelectionChangedCause cause) async { + final text = textEditingValue.selection.textInside(textEditingValue.text); + if (text.isNotEmpty) { + await SystemChannels.platform.invokeMethod( + 'SearchWeb.invoke', + text, + ); + } + } + + /// Launch the share interface for the current selection, + /// as in the "Share" edit menu button on iOS. + /// + /// Currently this is only implemented for iOS. + /// + /// When 'obscureText' is true or the selection is empty, + /// this function will not do anything + Future shareSelection(SelectionChangedCause cause) async { + final text = textEditingValue.selection.textInside(textEditingValue.text); + if (text.isNotEmpty) { + await SystemChannels.platform.invokeMethod( + 'Share.invoke', + text, + ); + } + } + /// Returns the anchor points for the default context menu. /// /// Copied from [EditableTextState]. @@ -1262,163 +1497,6 @@ class QuillRawEditorState extends EditorState ); } - /// Copy current selection to [Clipboard]. - @override - void copySelection(SelectionChangedCause cause) { - controller.copiedImageUrl = null; - _pastePlainText = controller.getPlainText(); - _pasteStyleAndEmbed = controller.getAllIndividualSelectionStylesAndEmbed(); - - final selection = textEditingValue.selection; - final text = textEditingValue.text; - if (selection.isCollapsed) { - return; - } - Clipboard.setData(ClipboardData(text: selection.textInside(text))); - - if (cause == SelectionChangedCause.toolbar) { - bringIntoView(textEditingValue.selection.extent); - - // Collapse the selection and hide the toolbar and handles. - userUpdateTextEditingValue( - TextEditingValue( - text: textEditingValue.text, - selection: - TextSelection.collapsed(offset: textEditingValue.selection.end), - ), - SelectionChangedCause.toolbar, - ); - } - } - - /// Cut current selection to [Clipboard]. - @override - void cutSelection(SelectionChangedCause cause) { - controller.copiedImageUrl = null; - _pastePlainText = controller.getPlainText(); - _pasteStyleAndEmbed = controller.getAllIndividualSelectionStylesAndEmbed(); - - if (widget.configurations.readOnly) { - return; - } - final selection = textEditingValue.selection; - final text = textEditingValue.text; - if (selection.isCollapsed) { - return; - } - Clipboard.setData(ClipboardData(text: selection.textInside(text))); - _replaceText(ReplaceTextIntent(textEditingValue, '', selection, cause)); - - if (cause == SelectionChangedCause.toolbar) { - bringIntoView(textEditingValue.selection.extent); - hideToolbar(); - } - } - - /// Paste text from [Clipboard]. - @override - Future pasteText(SelectionChangedCause cause) async { - if (widget.configurations.readOnly) { - return; - } - - if (controller.copiedImageUrl != null) { - final index = textEditingValue.selection.baseOffset; - final length = textEditingValue.selection.extentOffset - index; - final copied = controller.copiedImageUrl!; - controller.replaceText( - index, - length, - BlockEmbed.image(copied.url), - null, - ); - if (copied.styleString.isNotEmpty) { - controller.formatText( - getEmbedNode(controller, index + 1).offset, - 1, - StyleAttribute(copied.styleString), - ); - } - controller.copiedImageUrl = null; - await Clipboard.setData( - const ClipboardData(text: ''), - ); - return; - } - - final selection = textEditingValue.selection; - if (!selection.isValid) { - return; - } - // Snapshot the input before using `await`. - // See https://github.com/flutter/flutter/issues/11427 - final text = await Clipboard.getData(Clipboard.kTextPlain); - if (text != null) { - _replaceText( - ReplaceTextIntent( - textEditingValue, - text.text!, - selection, - cause, - ), - ); - - bringIntoView(textEditingValue.selection.extent); - - // Collapse the selection and hide the toolbar and handles. - userUpdateTextEditingValue( - TextEditingValue( - text: textEditingValue.text, - selection: TextSelection.collapsed( - offset: textEditingValue.selection.end, - ), - ), - cause, - ); - - return; - } - - final onImagePaste = widget.configurations.onImagePaste; - if (onImagePaste != null) { - final reader = await ClipboardReader.readClipboard(); - if (!reader.canProvide(Formats.png)) { - return; - } - reader.getFile(Formats.png, (value) async { - final image = value; - - final imageUrl = await onImagePaste(await image.readAll()); - if (imageUrl == null) { - return; - } - - controller.replaceText( - textEditingValue.selection.end, - 0, - BlockEmbed.image(imageUrl), - null, - ); - }); - } - } - - /// Select the entire text value. - @override - void selectAll(SelectionChangedCause cause) { - userUpdateTextEditingValue( - textEditingValue.copyWith( - selection: TextSelection( - baseOffset: 0, extentOffset: textEditingValue.text.length), - ), - cause, - ); - - if (cause == SelectionChangedCause.toolbar) { - bringIntoView(textEditingValue.selection.extent); - } - } - @override bool get wantKeepAlive => widget.configurations.focusNode.hasFocus; diff --git a/lib/src/widgets/toolbar/simple_toolbar.dart b/lib/src/widgets/toolbar/simple_toolbar.dart index a1da0762e..c21912f75 100644 --- a/lib/src/widgets/toolbar/simple_toolbar.dart +++ b/lib/src/widgets/toolbar/simple_toolbar.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import '../../../flutter_quill.dart'; +import '../../../translations.dart'; import '../../models/config/toolbar/toolbar_configurations.dart'; import '../../models/documents/attribute.dart'; import '../utils/provider.dart'; @@ -49,7 +51,7 @@ class QuillSimpleToolbar extends StatelessWidget configurations.showLink || configurations.showSearchButton ]; - List childrenBuilder(context) { + List childrenBuilder(BuildContext context) { final toolbarConfigurations = context.requireQuillSimpleToolbarConfigurations; From d7ef182f33fce986cda74ff2b0ff7ad1a74bc403 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 6 Dec 2023 10:51:43 +0300 Subject: [PATCH 39/86] Fix import warrnings --- lib/src/widgets/toolbar/simple_toolbar.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/widgets/toolbar/simple_toolbar.dart b/lib/src/widgets/toolbar/simple_toolbar.dart index c21912f75..483667f2d 100644 --- a/lib/src/widgets/toolbar/simple_toolbar.dart +++ b/lib/src/widgets/toolbar/simple_toolbar.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import '../../../flutter_quill.dart'; import '../../../translations.dart'; +import '../../extensions/quill_configurations_ext.dart'; import '../../models/config/toolbar/toolbar_configurations.dart'; import '../../models/documents/attribute.dart'; import '../utils/provider.dart'; From c5c8083b450764ba8f9b4283323d0546fa7f55b7 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 6 Dec 2023 11:05:28 +0300 Subject: [PATCH 40/86] 4+ --- .../models/config/editor/configurations.dart | 1 - lib/src/widgets/editor/editor.dart | 27 -- lib/src/widgets/others/delegate.dart | 1 + lib/src/widgets/raw_editor/raw_editor.dart | 38 ++- .../raw_editor_context_menu_items.dart | 160 ---------- .../widgets/raw_editor/raw_editor_state.dart | 7 +- ...editor_state_selection_delegate_mixin.dart | 2 +- ..._editor_state_text_input_client_mixin.dart | 1 + lib/src/widgets/toolbar/base_toolbar.dart | 1 - .../buttons/select_alignment_old_buttons.dart | 283 ------------------ .../buttons/select_header_style_button.dart | 6 +- 11 files changed, 48 insertions(+), 479 deletions(-) delete mode 100644 lib/src/widgets/raw_editor/raw_editor_context_menu_items.dart delete mode 100644 lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart diff --git a/lib/src/models/config/editor/configurations.dart b/lib/src/models/config/editor/configurations.dart index 55151b1b5..c41787b43 100644 --- a/lib/src/models/config/editor/configurations.dart +++ b/lib/src/models/config/editor/configurations.dart @@ -6,7 +6,6 @@ import 'package:flutter/material.dart' import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart' show experimental; -import '../../../widgets/editor/editor.dart'; import '../../../widgets/editor/editor_builder.dart'; import '../../../widgets/others/controller.dart'; import '../../../widgets/others/default_styles.dart'; diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index ab07a9eaf..3964cd643 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -14,7 +14,6 @@ import '../../models/config/raw_editor/configurations.dart'; import '../../models/documents/document.dart'; import '../../models/documents/nodes/container.dart' as container_node; import '../../models/documents/nodes/leaf.dart'; -import '../../models/structs/offset_value.dart'; import '../../utils/platform.dart'; import '../others/box.dart'; import '../others/cursor.dart'; @@ -26,32 +25,6 @@ import '../raw_editor/raw_editor.dart'; import '../utils/provider.dart'; import 'editor_builder.dart'; -/// Base interface for the editor state which defines contract used by -/// various mixins. -abstract class EditorState extends State - implements TextSelectionDelegate { - ScrollController get scrollController; - - RenderEditor get renderEditor; - - EditorTextSelectionOverlay? get selectionOverlay; - - List get pasteStyleAndEmbed; - - String get pastePlainText; - - /// Controls the floating cursor animation when it is released. - /// The floating cursor is animated to merge with the regular cursor. - AnimationController get floatingCursorResetController; - - /// Returns true if the editor has been marked as needing to be rebuilt. - bool get dirty; - - bool showToolbar(); - - void requestKeyboard(); -} - /// Base interface for editable render objects. abstract class RenderAbstractEditor implements TextLayoutMetrics { TextSelection selectWordAtPosition(TextPosition position); diff --git a/lib/src/widgets/others/delegate.dart b/lib/src/widgets/others/delegate.dart index dff3709ac..b34874d05 100644 --- a/lib/src/widgets/others/delegate.dart +++ b/lib/src/widgets/others/delegate.dart @@ -7,6 +7,7 @@ import '../../models/documents/attribute.dart'; import '../../models/documents/nodes/leaf.dart'; import '../../utils/platform.dart'; import '../editor/editor.dart'; +import '../raw_editor/raw_editor.dart'; import 'embeds.dart'; import 'text_selection.dart'; diff --git a/lib/src/widgets/raw_editor/raw_editor.dart b/lib/src/widgets/raw_editor/raw_editor.dart index c0ecf52db..4e11d707e 100644 --- a/lib/src/widgets/raw_editor/raw_editor.dart +++ b/lib/src/widgets/raw_editor/raw_editor.dart @@ -1,8 +1,18 @@ import 'package:flutter/widgets.dart' - show BuildContext, State, StatefulWidget, Widget; + show + AnimationController, + BuildContext, + ScrollController, + State, + StatefulWidget, + TextSelectionDelegate, + Widget; import 'package:meta/meta.dart' show immutable; import '../../models/config/raw_editor/configurations.dart'; +import '../../models/structs/offset_value.dart'; +import '../editor/editor.dart'; +import '../others/text_selection.dart'; import 'raw_editor_state.dart'; class QuillRawEditor extends StatefulWidget { @@ -49,3 +59,29 @@ class QuillEditorGlyphHeights { final double startGlyphHeight; final double endGlyphHeight; } + +/// Base interface for the editor state which defines contract used by +/// various mixins. +abstract class EditorState extends State + implements TextSelectionDelegate { + ScrollController get scrollController; + + RenderEditor get renderEditor; + + EditorTextSelectionOverlay? get selectionOverlay; + + List get pasteStyleAndEmbed; + + String get pastePlainText; + + /// Controls the floating cursor animation when it is released. + /// The floating cursor is animated to merge with the regular cursor. + AnimationController get floatingCursorResetController; + + /// Returns true if the editor has been marked as needing to be rebuilt. + bool get dirty; + + bool showToolbar(); + + void requestKeyboard(); +} diff --git a/lib/src/widgets/raw_editor/raw_editor_context_menu_items.dart b/lib/src/widgets/raw_editor/raw_editor_context_menu_items.dart deleted file mode 100644 index 39541e6cf..000000000 --- a/lib/src/widgets/raw_editor/raw_editor_context_menu_items.dart +++ /dev/null @@ -1,160 +0,0 @@ -// import 'package:flutter/widgets.dart' show TextSelectionDelegate; - -// class QuillEditorTextSelectionDelegate implements TextSelectionDelegate { -// /// Copy current selection to [Clipboard]. -// @override -// void copySelection(SelectionChangedCause cause) { -// controller.copiedImageUrl = null; -// _pastePlainText = controller.getPlainText(); -// _pasteStyleAndEmbed = controller.getAllIndividualSelectionStylesAndEmbed(); - -// final selection = textEditingValue.selection; -// final text = textEditingValue.text; -// if (selection.isCollapsed) { -// return; -// } -// Clipboard.setData(ClipboardData(text: selection.textInside(text))); - -// if (cause == SelectionChangedCause.toolbar) { -// bringIntoView(textEditingValue.selection.extent); - -// // Collapse the selection and hide the toolbar and handles. -// userUpdateTextEditingValue( -// TextEditingValue( -// text: textEditingValue.text, -// selection: -// TextSelection.collapsed(offset: textEditingValue.selection.end), -// ), -// SelectionChangedCause.toolbar, -// ); -// } -// } - -// /// Cut current selection to [Clipboard]. -// @override -// void cutSelection(SelectionChangedCause cause) { -// controller.copiedImageUrl = null; -// _pastePlainText = controller.getPlainText(); -// _pasteStyleAndEmbed = controller.getAllIndividualSelectionStylesAndEmbed(); - -// if (widget.configurations.readOnly) { -// return; -// } -// final selection = textEditingValue.selection; -// final text = textEditingValue.text; -// if (selection.isCollapsed) { -// return; -// } -// Clipboard.setData(ClipboardData(text: selection.textInside(text))); -// _replaceText(ReplaceTextIntent(textEditingValue, '', selection, cause)); - -// if (cause == SelectionChangedCause.toolbar) { -// bringIntoView(textEditingValue.selection.extent); -// hideToolbar(); -// } -// } - -// /// Paste text from [Clipboard]. -// @override -// Future pasteText(SelectionChangedCause cause) async { -// if (widget.configurations.readOnly) { -// return; -// } - -// if (controller.copiedImageUrl != null) { -// final index = textEditingValue.selection.baseOffset; -// final length = textEditingValue.selection.extentOffset - index; -// final copied = controller.copiedImageUrl!; -// controller.replaceText( -// index, -// length, -// BlockEmbed.image(copied.url), -// null, -// ); -// if (copied.styleString.isNotEmpty) { -// controller.formatText( -// getEmbedNode(controller, index + 1).offset, -// 1, -// StyleAttribute(copied.styleString), -// ); -// } -// controller.copiedImageUrl = null; -// await Clipboard.setData( -// const ClipboardData(text: ''), -// ); -// return; -// } - -// final selection = textEditingValue.selection; -// if (!selection.isValid) { -// return; -// } -// // Snapshot the input before using `await`. -// // See https://github.com/flutter/flutter/issues/11427 -// final text = await Clipboard.getData(Clipboard.kTextPlain); -// if (text != null) { -// _replaceText( -// ReplaceTextIntent( -// textEditingValue, -// text.text!, -// selection, -// cause, -// ), -// ); - -// bringIntoView(textEditingValue.selection.extent); - -// // Collapse the selection and hide the toolbar and handles. -// userUpdateTextEditingValue( -// TextEditingValue( -// text: textEditingValue.text, -// selection: TextSelection.collapsed( -// offset: textEditingValue.selection.end, -// ), -// ), -// cause, -// ); - -// return; -// } - -// final onImagePaste = widget.configurations.onImagePaste; -// if (onImagePaste != null) { -// final reader = await ClipboardReader.readClipboard(); -// if (!reader.canProvide(Formats.png)) { -// return; -// } -// reader.getFile(Formats.png, (value) async { -// final image = value; - -// final imageUrl = await onImagePaste(await image.readAll()); -// if (imageUrl == null) { -// return; -// } - -// controller.replaceText( -// textEditingValue.selection.end, -// 0, -// BlockEmbed.image(imageUrl), -// null, -// ); -// }); -// } -// } - -// /// Select the entire text value. -// @override -// void selectAll(SelectionChangedCause cause) { -// userUpdateTextEditingValue( -// textEditingValue.copyWith( -// selection: TextSelection( -// baseOffset: 0, extentOffset: textEditingValue.text.length), -// ), -// cause, -// ); - -// if (cause == SelectionChangedCause.toolbar) { -// bringIntoView(textEditingValue.selection.extent); -// } -// } -// } diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index 702f312c5..897658cca 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -116,10 +116,6 @@ class QuillRawEditorState extends EditorState .call(content); } - /// Returns the [ContextMenuButtonItem]s representing the buttons in this - /// platform's default selection menu for [QuillRawEditor]. - /// - /// Copied from [EditableTextState]. // List get contextMenuButtonItems { // return EditableText.getEditableButtonItems( // clipboardStatus: _clipboardStatus.value, @@ -297,6 +293,9 @@ class QuillRawEditorState extends EditorState } } + /// Returns the [ContextMenuButtonItem]s representing the buttons in this + /// platform's default selection menu for [QuillRawEditor]. + /// Copied from [EditableTextState]. List get contextMenuButtonItems { return EditableText.getEditableButtonItems( clipboardStatus: _clipboardStatus.value, 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 53f0cd6f6..2b5bfa10c 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 @@ -8,7 +8,7 @@ import '../../models/documents/nodes/embeddable.dart'; import '../../models/documents/nodes/leaf.dart'; import '../../models/documents/style.dart'; import '../../utils/delta.dart'; -import '../editor/editor.dart'; +import 'raw_editor.dart'; mixin RawEditorStateSelectionDelegateMixin on EditorState implements TextSelectionDelegate { 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 d41180ca9..2c6a08daa 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 @@ -10,6 +10,7 @@ import 'package:flutter/services.dart'; import '../../models/documents/document.dart'; import '../../utils/delta.dart'; import '../editor/editor.dart'; +import 'raw_editor.dart'; mixin RawEditorStateTextInputClientMixin on EditorState implements TextInputClient { diff --git a/lib/src/widgets/toolbar/base_toolbar.dart b/lib/src/widgets/toolbar/base_toolbar.dart index c22113050..33e0f1271 100644 --- a/lib/src/widgets/toolbar/base_toolbar.dart +++ b/lib/src/widgets/toolbar/base_toolbar.dart @@ -20,7 +20,6 @@ export 'buttons/link_style2_button.dart'; export 'buttons/link_style_button.dart'; export 'buttons/quill_icon_button.dart'; export 'buttons/search/search_button.dart'; -export 'buttons/select_alignment_old_buttons.dart'; export 'buttons/select_header_style_buttons.dart'; export 'buttons/toggle_check_list_button.dart'; export 'buttons/toggle_style_button.dart'; diff --git a/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart b/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart deleted file mode 100644 index ed5913893..000000000 --- a/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart +++ /dev/null @@ -1,283 +0,0 @@ -// import 'package:flutter/foundation.dart'; -// import 'package:flutter/material.dart'; - -// import '../../../extensions/quill_provider.dart'; -// import '../../../l10n/extensions/localizations.dart'; -// import '../../../models/documents/attribute.dart'; -// import '../../../models/documents/style.dart'; -// import '../../../models/themes/quill_icon_theme.dart'; -// import '../../../utils/widgets.dart'; -// import '../../others/controller.dart'; -// import '../base_toolbar.dart'; - -// @Deprecated('This button has been deprecated, use') -// class QuillToolbarSelectAlignmentOldButtons extends StatefulWidget { -// const QuillToolbarSelectAlignmentOldButtons({ -// required this.controller, -// this.options, -// this.showLeftAlignment, -// this.showCenterAlignment, -// this.showRightAlignment, -// this.showJustifyAlignment, -// this.padding, -// super.key, -// }); - -// final QuillController controller; -// final QuillToolbarSelectAlignmentButtonOptions options; - -// final bool? showLeftAlignment; -// final bool? showCenterAlignment; -// final bool? showRightAlignment; -// final bool? showJustifyAlignment; -// final EdgeInsetsGeometry? padding; - -// @override -// QuillToolbarSelectAlignmentOldButtonsState createState() => -// QuillToolbarSelectAlignmentOldButtonsState(); -// } - -// class QuillToolbarSelectAlignmentOldButtonsState -// extends State { -// Attribute? _value; - -// Style get _selectionStyle => controller.getSelectionStyle(); - -// @override -// void initState() { -// super.initState(); -// setState(() { -// _value = _selectionStyle.attributes[Attribute.align.key] ?? -// Attribute.leftAlignment; -// }); -// controller.addListener(_didChangeEditingValue); -// } - -// QuillToolbarSelectAlignmentButtonOptions get options { -// return widget.options; -// } - -// QuillController get controller { -// return widget.controller; -// } - -// double get _iconSize { -// final baseFontSize = baseButtonExtraOptions.globalIconSize; -// final iconSize = options.iconSize; -// 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; -// } - -// QuillIconTheme? get _iconTheme { -// return options.iconTheme ?? baseButtonExtraOptions.iconTheme; -// } - -// QuillToolbarBaseButtonOptions get baseButtonExtraOptions { -// return context.requireQuillToolbarBaseButtonOptions; -// } - -// QuillSelectAlignmentValues get _iconsData { -// final iconsData = options.iconsData; -// if (iconsData != null) { -// return iconsData; -// } -// final baseIconData = baseButtonExtraOptions.iconData; -// if (baseIconData != null) { -// return QuillSelectAlignmentValues( -// leftAlignment: baseIconData, -// centerAlignment: baseIconData, -// rightAlignment: baseIconData, -// justifyAlignment: baseIconData, -// ); -// } -// return const QuillSelectAlignmentValues( -// leftAlignment: Icons.format_align_left, -// centerAlignment: Icons.format_align_center, -// rightAlignment: Icons.format_align_right, -// justifyAlignment: Icons.format_align_justify, -// ); -// } - -// QuillSelectAlignmentValues get _tooltips { -// final tooltips = options.tooltips; -// if (tooltips != null) { -// return tooltips; -// } -// final baseToolTip = baseButtonExtraOptions.tooltip; -// if (baseToolTip != null) { -// return QuillSelectAlignmentValues( -// leftAlignment: baseToolTip, -// centerAlignment: baseToolTip, -// rightAlignment: baseToolTip, -// justifyAlignment: baseToolTip, -// ); -// } -// return QuillSelectAlignmentValues( -// leftAlignment: context.loc.alignLeft, -// centerAlignment: context.loc.alignCenter, -// rightAlignment: context.loc.alignRight, -// justifyAlignment: context.loc.justifyWinWidth, -// ); -// } - -// void _didChangeEditingValue() { -// setState(() { -// _value = _selectionStyle.attributes[Attribute.align.key] ?? -// Attribute.leftAlignment; -// }); -// } - -// @override -// void didUpdateWidget( -// covariant QuillToolbarSelectAlignmentOldButtons oldWidget) { -// super.didUpdateWidget(oldWidget); -// if (oldWidget.controller != controller) { -// oldWidget.controller.removeListener(_didChangeEditingValue); -// controller.addListener(_didChangeEditingValue); -// _value = _selectionStyle.attributes[Attribute.align.key] ?? -// Attribute.leftAlignment; -// } -// } - -// @override -// void dispose() { -// controller.removeListener(_didChangeEditingValue); -// super.dispose(); -// } - -// @override -// Widget build(BuildContext context) { -// final valueToText = { -// if (widget.showLeftAlignment!) -// Attribute.leftAlignment: Attribute.leftAlignment.value!, -// if (widget.showCenterAlignment!) -// Attribute.centerAlignment: Attribute.centerAlignment.value!, -// if (widget.showRightAlignment!) -// Attribute.rightAlignment: Attribute.rightAlignment.value!, -// if (widget.showJustifyAlignment!) -// Attribute.justifyAlignment: Attribute.justifyAlignment.value!, -// }; - -// final valueAttribute = [ -// if (widget.showLeftAlignment!) Attribute.leftAlignment, -// if (widget.showCenterAlignment!) Attribute.centerAlignment, -// if (widget.showRightAlignment!) Attribute.rightAlignment, -// if (widget.showJustifyAlignment!) Attribute.justifyAlignment -// ]; -// final valueString = [ -// if (widget.showLeftAlignment!) Attribute.leftAlignment.value!, -// if (widget.showCenterAlignment!) Attribute.centerAlignment.value!, -// if (widget.showRightAlignment!) Attribute.rightAlignment.value!, -// if (widget.showJustifyAlignment!) Attribute.justifyAlignment.value!, -// ]; -// // final _valueToButtons = { -// // if (widget.showLeftAlignment!) -// // Attribute.leftAlignment: ToolbarButtons.leftAlignment, -// // if (widget.showCenterAlignment!) -// // Attribute.centerAlignment: ToolbarButtons.centerAlignment, -// // if (widget.showRightAlignment!) -// // Attribute.rightAlignment: ToolbarButtons.rightAlignment, -// // if (widget.showJustifyAlignment!) -// // Attribute.justifyAlignment: ToolbarButtons.justifyAlignment, -// // }; - -// final buttonCount = ((widget.showLeftAlignment!) ? 1 : 0) + -// ((widget.showCenterAlignment!) ? 1 : 0) + -// ((widget.showRightAlignment!) ? 1 : 0) + -// ((widget.showJustifyAlignment!) ? 1 : 0); - -// final childBuilder = -// options.childBuilder ?? baseButtonExtraOptions.childBuilder; - -// void sharedOnPressed(int index) { -// valueAttribute[index] == Attribute.leftAlignment -// ? controller.formatSelection( -// Attribute.clone(Attribute.align, null), -// ) -// : controller.formatSelection(valueAttribute[index]); -// _afterButtonPressed?.call(); -// } - -// return Row( -// mainAxisSize: MainAxisSize.min, -// children: List.generate(buttonCount, (index) { -// if (childBuilder != null) { -// return childBuilder( -// QuillToolbarSelectAlignmentButtonOptions( -// afterButtonPressed: _afterButtonPressed, -// iconSize: _iconSize, -// iconButtonFactor: _iconButtonFactor, -// 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 * _iconButtonFactor, -// height: _iconSize * _iconButtonFactor, -// ), -// child: UtilityWidgets.maybeTooltip( -// message: valueString[index] == Attribute.leftAlignment.value -// ? _tooltips.leftAlignment -// : valueString[index] == Attribute.centerAlignment.value -// ? _tooltips.centerAlignment -// : valueString[index] == Attribute.rightAlignment.value -// ? _tooltips.rightAlignment -// : _tooltips.justifyAlignment, -// child: RawMaterialButton( -// hoverElevation: 0, -// highlightElevation: 0, -// elevation: 0, -// visualDensity: VisualDensity.compact, -// shape: RoundedRectangleBorder( -// borderRadius: -// BorderRadius.circular(_iconTheme?.borderRadius ?? 2)), -// fillColor: valueToText[_value] == valueString[index] -// ? (_iconTheme?.iconSelectedFillColor ?? theme.primaryColor) -// : (_iconTheme?.iconUnselectedFillColor ?? -// theme.canvasColor), -// onPressed: () => sharedOnPressed(index), -// child: Icon( -// valueString[index] == Attribute.leftAlignment.value -// ? _iconsData.leftAlignment -// : valueString[index] == Attribute.centerAlignment.value -// ? _iconsData.centerAlignment -// : valueString[index] == Attribute.rightAlignment.value -// ? _iconsData.rightAlignment -// : _iconsData.justifyAlignment, -// size: _iconSize, -// color: valueToText[_value] == valueString[index] -// ? (_iconTheme?.iconSelectedColor ?? -// theme.primaryIconTheme.color) -// : (_iconTheme?.iconUnselectedColor ?? -// theme.iconTheme.color), -// ), -// ), -// ), -// ), -// ); -// }), -// ); -// } -// } diff --git a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart index 32140602f..59f66d8d7 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart @@ -37,8 +37,12 @@ class _QuillToolbarSelectHeaderStyleButtonState } void _didChangeEditingValue() { + final newSelectedItem = _getOptionsItemByAttribute(_getHeaderValue()); + if (newSelectedItem == _selectedItem) { + return; + } setState(() { - _selectedItem = _getOptionsItemByAttribute(_getHeaderValue()); + _selectedItem = newSelectedItem; }); } From 21a192fedc79339efca95320fb3162fb8a3791e9 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 6 Dec 2023 12:10:10 +0300 Subject: [PATCH 41/86] 4++ --- doc/migration.md | 431 +----------------- doc/migration/7_8.md | 429 +++++++++++++++++ doc/migration/8_9.md | 83 ++++ .../presentation/simple/simple_screen.dart | 11 + .../lib/embeds/widgets/image.dart | 1 - .../utils/element_utils/element_utils.dart | 1 - lib/flutter_quill.dart | 2 +- .../extensions/quill_configurations_ext.dart | 8 +- lib/src/extensions/uri_ext.dart | 11 + ...ations.dart => editor_configurations.dart} | 0 .../models/config/quill_configurations.dart | 2 +- .../config/quill_shared_configurations.dart | 2 +- ...ns.dart => raw_editor_configurations.dart} | 0 lib/src/models/rules/insert.dart | 4 +- lib/src/widgets/editor/editor.dart | 26 +- lib/src/widgets/others/delegate.dart | 2 - lib/src/widgets/others/proxy.dart | 3 +- lib/src/widgets/others/text_line.dart | 3 +- lib/src/widgets/raw_editor/raw_editor.dart | 2 +- lib/src/widgets/toolbar/base_toolbar.dart | 4 +- .../toolbar/buttons/link_style_button.dart | 2 +- lib/src/widgets/toolbar/simple_toolbar.dart | 2 +- lib/src/widgets/utils/provider.dart | 38 +- 23 files changed, 576 insertions(+), 491 deletions(-) create mode 100644 doc/migration/7_8.md create mode 100644 doc/migration/8_9.md create mode 100644 lib/src/extensions/uri_ext.dart rename lib/src/models/config/editor/{configurations.dart => editor_configurations.dart} (100%) rename lib/src/models/config/raw_editor/{configurations.dart => raw_editor_configurations.dart} (100%) diff --git a/doc/migration.md b/doc/migration.md index 8c3a175c2..e7b3908f4 100644 --- a/doc/migration.md +++ b/doc/migration.md @@ -5,435 +5,12 @@ Here you can find the migration guide between different versions, you can contri - [Migration guide](#migration-guide) - [from 7.0.0 to 8.0.0](#from-700-to-800) + - [from 8.0.0 to 9.0.0](#from-800-to-900) ## from 7.0.0 to 8.0.0 -We have refactored a lot of the base code to allow you to customize everything you want, and it allows us to add new configurations very easily using inherited widgets without passing configurations all over the constructors everywhere which will be very hard to test, fix bugs, and maintain +Open [this](./migration/7_8.md) md file -1. Passing the controller +## from 8.0.0 to 9.0.0 -The controller code (should be the same) -```dart -QuillController _controller = QuillController.basic(); -``` - -**Old code**: -```dart - -Column( - children: [ - QuillToolbar.basic(controller: _controller), - Expanded( - child: QuillEditor.basic( - controller: _controller, - readOnly: false, // true for view only mode - ), - ) - ], -) - -``` - -**New code**: - -```dart -QuillProvider( - configurations: QuillConfigurations( - controller: _controller, - sharedConfigurations: const QuillSharedConfigurations(), - ), - child: Column( - children: [ - const QuillToolbar(), - Expanded( - child: QuillEditor.basic( - configurations: const QuillEditorConfigurations( - readOnly: false, // true for view only mode - ), - ), - ) - ], - ), -) -``` - -The `QuillProvider` is an inherited widget that allows you to pass configurations once and use them in the children of it. here we are passing the `_controller` once in the configurations of `QuillProvider` and the `QuillToolbar` and `QuillEditor` will get the `QuillConfigurations` internally, if it doesn't exist you will get an exception. - -we also added the `sharedConfigurations` which allow you to configure shared things like the `Local` so you don't have to define them twice, we have removed those from the `QuillToolbar` and `QuillEditor` - -2. Regarding The QuillToolbar buttons, we have renamed almost all the buttons, examples: - - `QuillHistory` to `QuillToolbarHistoryButton` - - `IndentButton` to `QuillToolbarIndentButton` - -and they usually have two parameters, `controller` and `options`, for example the type for the buttons - - `QuillToolbarHistoryButton` have `QuillToolbarHistoryButtonOptions` - - `QuillToolbarIndentButton` have `QuillToolbarIndentButtonOptions` - - `QuillToolbarClearFormatButton` have `QuillToolbarClearFormatButtonOptions` - -All the options have parent `QuillToolbarBaseButtonOptions` which have common things like - -```dart - /// By default it will use Icon data from Icons that come from material - /// library for each button, to change this, please pass a different value - /// If there is no Icon in this button then pass null in the child class - final IconData? iconData; - - /// To change the icon size pass a different value, by default will be - /// [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; - - /// By default it will use the default tooltip which already localized - final String? tooltip; - - /// Use custom theme - final QuillIconTheme? iconTheme; - - /// If you want to dispaly a differnet widget based using a builder - final QuillToolbarButtonOptionsChildBuilder childBuilder; - - /// By default it will be from the one in [QuillProvider] - /// To override it you must pass not null controller - /// if you wish to use the controller in the [childBuilder], please use the - /// one from the extraOptions since it will be not null and will be the one - /// which will be used from the quill toolbar - final QuillController? controller; -``` - -The `QuillToolbarBaseButtonOptions is`: -```dart -/// The [T] is the option for the button, usually should reference itself -/// it's used in [childBuilder] so the developer can customize this when using it -/// The [I] is an extra option for the button, usually for its state -@immutable -class QuillToolbarBaseButtonOptions extends Equatable -``` - -Example for the clear format button: - -```dart -class QuillToolbarClearFormatButtonExtraOptions - extends QuillToolbarBaseButtonExtraOptions { - const QuillToolbarClearFormatButtonExtraOptions({ - required super.controller, - required super.context, - required super.onPressed, - }); -} - -class QuillToolbarClearFormatButtonOptions - extends QuillToolbarBaseButtonOptions { - const QuillToolbarClearFormatButtonOptions({ - super.iconData, - super.afterButtonPressed, - super.childBuilder, - super.controller, - super.iconTheme, - super.tooltip, - this.iconSize, - }); - - final double? iconSize; -} - -``` - -The base for extra options: -```dart -@immutable -class QuillToolbarBaseButtonExtraOptions extends Equatable { - const QuillToolbarBaseButtonExtraOptions({ - required this.controller, - required this.context, - required this.onPressed, - }); - - /// If you need the not null controller for some usage in the [childBuilder] - /// Then please use this instead of the one in the [options] - final QuillController controller; - - /// If the child builder you must use this when the widget is tapped or pressed - /// in order to do what it expected to do - final VoidCallback? onPressed; - - final BuildContext context; - @override - List get props => [ - controller, - ]; -} -``` - -which usually share common things, it also add an extra property which was not exist, which is `childBuilder` which allow to rendering of custom widget based on the state of the button and the options it - -```dart -QuillToolbar( - configurations: QuillToolbarConfigurations( - buttonOptions: QuillToolbarButtonOptions( - clearFormat: QuillToolbarClearFormatButtonOptions( - childBuilder: (options, extraOptions) { - return IconButton.filled( - onPressed: extraOptions.onPressed, - icon: const Icon( - CupertinoIcons.clear // or options.iconData - ), - ); - }, - ), - ), - ), -), -``` - -the `extraOptions` usually contains the state variables and the events that you need to trigger like the `onPressed`, it also has the end context and the controller that will be used -while the `options` has the custom controller for each button and it's nullable because there could be no custom controller so we will just use the global one - -3. The `QuillToolbar` and `QuillToolbar.basic()` factory constructor - -since the basic factory constructor has more options than the original `QuillToolbar` which doesn't make much sense, at least to some developers, we have refactored the `QuillToolbar.basic()` to a different widget called the `QuillToolbar` and the `QuillToolbar` has been renamed to `QuillBaseToolbar` which is the base for `QuillToolbar` or any custom toolbar, sure you can create custom toolbar from scratch by just using the `controller` but if you want more support from the library use the `QuillBaseToolbar` - -the children widgets of the new `QuillToolbar` and `QuillEditor` access to their configurations by another two inherited widgets -since `QuillToolbar` and `QuillEditor` take the configuration class and provide them internally using `QuillToolbarProvider` and `QuillEditorProvider` -however the `QuillBaseToolbar` has a little bit different configurations so it has a different provider called `QuillBaseToolbarProvider` and it also already provided by default - -But there is one **note**: -> If you are using the toolbar buttons like `QuillToolbarHistoryButton`, `QuillToolbarToggleStyleButton` somewhere like the the custom toolbar (using `QuillBaseToolbar` or any custom widget) 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 of a custom toolbar: - -```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; // new extension which is a little bit shorter to access the quill provider then the controller - - // there are many options, feel free to explore them all!! - 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), - ), - ), - ) - ], - ), -) -``` - -4. The `QuillEditor` and `QuillEditor.basic()` - -since the `QuillEditor.basic()` is a lighter version than the original `QuillEditor` since it has fewer required configurations we didn't change much, other than the configuration class, but we must inform you if you plan on sending pull request or you are a maintainer and when you add new property or change anything in `QuillEditorConfigurations` please regenerate the `copyWith` (using IDE extension or plugin) otherwise the `QuilEditor.basic()` will not apply some configurations - -we have disabled the line numbers in the code block by default, you can enable them again using the following: - -```dart -QuillEditor.basic( - configurations: const QuillEditorConfigurations( - elementOptions: QuillEditorElementOptions( - codeBlock: QuillEditorCodeBlockElementOptions( - enableLineNumbers: true, - ), - ), - ), -) -``` - -5. `QuillCustomButton`: - -We have renamed the property `icon` to `iconData` to indicate it an icon data and not an icon widget -```dart - QuillCustomButton( - iconData: Icons.ac_unit, - onTap: () { - debugPrint('snowflake'); - } - ), -``` - -6. Using custom local for both `QuillEditor` and `QuillToolbar` - -We have added shared configurations property for shared things -```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(), - ), - ) - ], - ), -) -``` - -7. Image size for all platforms - -We have added new properties `width`, `height`, `margin`, `alignment` for all platforms other than mobile and web for the images for example - -```dart -{ - "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" - } -} -``` - -8. Other Improvements - -You don't need anything to get this done, we have used const more when possible, removed unused events, flutter best practices, converted to stateless widgets when possible, and used better ways to listen for changes example: - - instead of - -```dart -MediaQuery.of(context).size; -``` - -we will use -```dart -MediaQuery.sizeOf(context); -``` -We also minimized the number of rebuilds using more efficient logic and there is more. - -9. More options - -We have added more options in the extension package, for all the buttons, configurations, animations, enable and disable things - -If you are facing any issues or questions feel free to ask us on GitHub issues +Open [this](./migration/8_9.md) md file \ No newline at end of file diff --git a/doc/migration/7_8.md b/doc/migration/7_8.md new file mode 100644 index 000000000..e797ca30b --- /dev/null +++ b/doc/migration/7_8.md @@ -0,0 +1,429 @@ +We have refactored a lot of the base code to allow you to customize everything you want, and it allows us to add new configurations very easily using inherited widgets without passing configurations all over the constructors everywhere which will be very hard to test, fix bugs, and maintain + +1. Passing the controller + +The controller code (should be the same) +```dart +QuillController _controller = QuillController.basic(); +``` + +**Old code**: +```dart + +Column( + children: [ + QuillToolbar.basic(controller: _controller), + Expanded( + child: QuillEditor.basic( + controller: _controller, + readOnly: false, // true for view only mode + ), + ) + ], +) + +``` + +**New code**: + +```dart +QuillProvider( + configurations: QuillConfigurations( + controller: _controller, + sharedConfigurations: const QuillSharedConfigurations(), + ), + child: Column( + children: [ + const QuillToolbar(), + Expanded( + child: QuillEditor.basic( + configurations: const QuillEditorConfigurations( + readOnly: false, // true for view only mode + ), + ), + ) + ], + ), +) +``` + +The `QuillProvider` is an inherited widget that allows you to pass configurations once and use them in the children of it. here we are passing the `_controller` once in the configurations of `QuillProvider` and the `QuillToolbar` and `QuillEditor` will get the `QuillConfigurations` internally, if it doesn't exist you will get an exception. + +we also added the `sharedConfigurations` which allow you to configure shared things like the `Local` so you don't have to define them twice, we have removed those from the `QuillToolbar` and `QuillEditor` + +2. Regarding The QuillToolbar buttons, we have renamed almost all the buttons, examples: + - `QuillHistory` to `QuillToolbarHistoryButton` + - `IndentButton` to `QuillToolbarIndentButton` + +and they usually have two parameters, `controller` and `options`, for example the type for the buttons + - `QuillToolbarHistoryButton` have `QuillToolbarHistoryButtonOptions` + - `QuillToolbarIndentButton` have `QuillToolbarIndentButtonOptions` + - `QuillToolbarClearFormatButton` have `QuillToolbarClearFormatButtonOptions` + +All the options have parent `QuillToolbarBaseButtonOptions` which have common things like + +```dart + /// By default it will use Icon data from Icons that come from material + /// library for each button, to change this, please pass a different value + /// If there is no Icon in this button then pass null in the child class + final IconData? iconData; + + /// To change the icon size pass a different value, by default will be + /// [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; + + /// By default it will use the default tooltip which already localized + final String? tooltip; + + /// Use custom theme + final QuillIconTheme? iconTheme; + + /// If you want to dispaly a differnet widget based using a builder + final QuillToolbarButtonOptionsChildBuilder childBuilder; + + /// By default it will be from the one in [QuillProvider] + /// To override it you must pass not null controller + /// if you wish to use the controller in the [childBuilder], please use the + /// one from the extraOptions since it will be not null and will be the one + /// which will be used from the quill toolbar + final QuillController? controller; +``` + +The `QuillToolbarBaseButtonOptions is`: +```dart +/// The [T] is the option for the button, usually should reference itself +/// it's used in [childBuilder] so the developer can customize this when using it +/// The [I] is an extra option for the button, usually for its state +@immutable +class QuillToolbarBaseButtonOptions extends Equatable +``` + +Example for the clear format button: + +```dart +class QuillToolbarClearFormatButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarClearFormatButtonExtraOptions({ + required super.controller, + required super.context, + required super.onPressed, + }); +} + +class QuillToolbarClearFormatButtonOptions + extends QuillToolbarBaseButtonOptions { + const QuillToolbarClearFormatButtonOptions({ + super.iconData, + super.afterButtonPressed, + super.childBuilder, + super.controller, + super.iconTheme, + super.tooltip, + this.iconSize, + }); + + final double? iconSize; +} + +``` + +The base for extra options: +```dart +@immutable +class QuillToolbarBaseButtonExtraOptions extends Equatable { + const QuillToolbarBaseButtonExtraOptions({ + required this.controller, + required this.context, + required this.onPressed, + }); + + /// If you need the not null controller for some usage in the [childBuilder] + /// Then please use this instead of the one in the [options] + final QuillController controller; + + /// If the child builder you must use this when the widget is tapped or pressed + /// in order to do what it expected to do + final VoidCallback? onPressed; + + final BuildContext context; + @override + List get props => [ + controller, + ]; +} +``` + +which usually share common things, it also add an extra property which was not exist, which is `childBuilder` which allow to rendering of custom widget based on the state of the button and the options it + +```dart +QuillToolbar( + configurations: QuillToolbarConfigurations( + buttonOptions: QuillToolbarButtonOptions( + clearFormat: QuillToolbarClearFormatButtonOptions( + childBuilder: (options, extraOptions) { + return IconButton.filled( + onPressed: extraOptions.onPressed, + icon: const Icon( + CupertinoIcons.clear // or options.iconData + ), + ); + }, + ), + ), + ), +), +``` + +the `extraOptions` usually contains the state variables and the events that you need to trigger like the `onPressed`, it also has the end context and the controller that will be used +while the `options` has the custom controller for each button and it's nullable because there could be no custom controller so we will just use the global one + +3. The `QuillToolbar` and `QuillToolbar.basic()` factory constructor + +since the basic factory constructor has more options than the original `QuillToolbar` which doesn't make much sense, at least to some developers, we have refactored the `QuillToolbar.basic()` to a different widget called the `QuillToolbar` and the `QuillToolbar` has been renamed to `QuillBaseToolbar` which is the base for `QuillToolbar` or any custom toolbar, sure you can create custom toolbar from scratch by just using the `controller` but if you want more support from the library use the `QuillBaseToolbar` + +the children widgets of the new `QuillToolbar` and `QuillEditor` access to their configurations by another two inherited widgets +since `QuillToolbar` and `QuillEditor` take the configuration class and provide them internally using `QuillToolbarProvider` and `QuillEditorProvider` +however the `QuillBaseToolbar` has a little bit different configurations so it has a different provider called `QuillBaseToolbarProvider` and it also already provided by default + +But there is one **note**: +> If you are using the toolbar buttons like `QuillToolbarHistoryButton`, `QuillToolbarToggleStyleButton` somewhere like the the custom toolbar (using `QuillBaseToolbar` or any custom widget) 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 of a custom toolbar: + +```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; // new extension which is a little bit shorter to access the quill provider then the controller + + // there are many options, feel free to explore them all!! + 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), + ), + ), + ) + ], + ), +) +``` + +4. The `QuillEditor` and `QuillEditor.basic()` + +since the `QuillEditor.basic()` is a lighter version than the original `QuillEditor` since it has fewer required configurations we didn't change much, other than the configuration class, but we must inform you if you plan on sending pull request or you are a maintainer and when you add new property or change anything in `QuillEditorConfigurations` please regenerate the `copyWith` (using IDE extension or plugin) otherwise the `QuilEditor.basic()` will not apply some configurations + +we have disabled the line numbers in the code block by default, you can enable them again using the following: + +```dart +QuillEditor.basic( + configurations: const QuillEditorConfigurations( + elementOptions: QuillEditorElementOptions( + codeBlock: QuillEditorCodeBlockElementOptions( + enableLineNumbers: true, + ), + ), + ), +) +``` + +5. `QuillCustomButton`: + +We have renamed the property `icon` to `iconData` to indicate it an icon data and not an icon widget +```dart + QuillCustomButton( + iconData: Icons.ac_unit, + onTap: () { + debugPrint('snowflake'); + } + ), +``` + +6. Using custom local for both `QuillEditor` and `QuillToolbar` + +We have added shared configurations property for shared things +```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(), + ), + ) + ], + ), +) +``` + +7. Image size for all platforms + +We have added new properties `width`, `height`, `margin`, `alignment` for all platforms other than mobile and web for the images for example + +```dart +{ + "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" + } +} +``` + +8. Other Improvements + +You don't need anything to get this done, we have used const more when possible, removed unused events, flutter best practices, converted to stateless widgets when possible, and used better ways to listen for changes example: + + instead of + +```dart +MediaQuery.of(context).size; +``` + +we will use +```dart +MediaQuery.sizeOf(context); +``` +We also minimized the number of rebuilds using more efficient logic and there is more. + +9. More options + +We have added more options in the extension package, for all the buttons, configurations, animations, enable and disable things + +If you are facing any issues or questions feel free to ask us on GitHub issues diff --git a/doc/migration/8_9.md b/doc/migration/8_9.md new file mode 100644 index 000000000..ade5124b0 --- /dev/null +++ b/doc/migration/8_9.md @@ -0,0 +1,83 @@ +1. Removing the `QuillProvider` + +We got a lot of feedbacks about `QuillProvider`, while the provider help removing duplicate lines for simple usage, for more advance usage it become very messy +So from now on we will use providers for the `QuillToolbar` and `QuillEditor` only internally, you don't need it anymore + +Instead you will need to pass the configurations directly in the `QuillToolbar` and `QuillEditor` + +**Old code**: + +```dart +QuillProvider( + configurations: QuillConfigurations( + controller: _controller, + sharedConfigurations: const QuillSharedConfigurations(), + ), + child: Column( + children: [ + const QuillToolbar(), + Expanded( + child: QuillEditor.basic( + configurations: const QuillEditorConfigurations( + readOnly: false, // true for view only mode + ), + ), + ) + ], + ), +) +``` + +**New code**: + +```dart + +Column( + children: [ + QuillToolbar.simple( + QuillSimpleToolbarConfigurations(controller: _controller)), + Expanded( + child: QuillEditor.basic( + configurations: QuillEditorConfigurations(controller: _controller), + ), + ) + ], +) + +``` + +2. Refactoring the Base Toolbar + +From now on, the `QuillToolbar` will be a widget that only provides the things that the buttons needs like localizations and `QuillToolbarProvider` +So you can define your own toolbar from scratch just like in Quill JS + +The `QuillToolbar` is now accepting only `child` with no configurations so you can customize everything you wants, the `QuillToolbar.simple()` or `QuillSimpleToolbar` implements a simple toolbar that is based on `QuillToolbar`, you are free to use it but it just an example and not standard + +1. Source Code Structure + +Completly changed the way how the source code structured to more basic and simple way, organize folders and file names, if you use the library +from `flutter_quill_extensions.dart` then there is nothing you need to do, but if you are using any other import then you need to re-imports + +4. Change the version system + +For [more details](https://github.com/singerdmx/flutter-quill/discussions/1560) + +5. Dependencies changes + + 1. Add `gal_linux` in `flutter_quill_extensions` + 2. Replace `pasteboard` with `rich_cliboard` + 3. Remove `flutter_animate` + +6. Optional options for the buttons + +All the buttons from now on, have optional options parameter + +7. Improve Flutter Quill Extensions + +Bug fixes and new features, the extensions package keep getting better thanks to the community. + +8. Migrate to Material 3 + +We have migrated all of the buttons to material 3, removed a lot of old parameters, if you want to customize one or all the buttons to replacing it with completly different widget with the same state use the `base` in the button options for all or the button name for one + +We have also replaced the header style buttons with one dropdown button as a default, replaced the alignment buttons with less code and a lot more \ No newline at end of file diff --git a/example/lib/presentation/simple/simple_screen.dart b/example/lib/presentation/simple/simple_screen.dart index 0393fcf7c..2fc3a1383 100644 --- a/example/lib/presentation/simple/simple_screen.dart +++ b/example/lib/presentation/simple/simple_screen.dart @@ -13,6 +13,17 @@ class _SimpleScreenState extends State { @override Widget build(BuildContext context) { + return Column( + children: [ + QuillToolbar.simple( + QuillSimpleToolbarConfigurations(controller: _controller)), + Expanded( + child: QuillEditor.basic( + configurations: QuillEditorConfigurations(controller: _controller), + ), + ) + ], + ); return Scaffold( appBar: AppBar(), body: Column( diff --git a/flutter_quill_extensions/lib/embeds/widgets/image.dart b/flutter_quill_extensions/lib/embeds/widgets/image.dart index d072f202b..03168b60f 100644 --- a/flutter_quill_extensions/lib/embeds/widgets/image.dart +++ b/flutter_quill_extensions/lib/embeds/widgets/image.dart @@ -50,7 +50,6 @@ ImageProvider getImageProviderByImageSource( } if (imageSource.startsWith(assetsPrefix)) { - // TODO: This impl could be improved return AssetImage(imageSource); } return FileImage(File(imageSource)); diff --git a/flutter_quill_extensions/lib/utils/element_utils/element_utils.dart b/flutter_quill_extensions/lib/utils/element_utils/element_utils.dart index 64db01aef..6be7c1635 100644 --- a/flutter_quill_extensions/lib/utils/element_utils/element_utils.dart +++ b/flutter_quill_extensions/lib/utils/element_utils/element_utils.dart @@ -51,7 +51,6 @@ enum ExtraElementProperties { final cssAttrs = parseCssString(cssStyle.value.toString()); - // todo: This could be improved much better final cssHeightValue = parseCssPropertyAsDouble( (cssAttrs[Attribute.height.key]) ?? '', context: context, diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index 5ea179f4c..54f4eaec2 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -2,7 +2,7 @@ library flutter_quill; export 'src/extensions/quill_configurations_ext.dart'; export 'src/models/config/quill_configurations.dart'; -export 'src/models/config/raw_editor/configurations.dart'; +export 'src/models/config/raw_editor/raw_editor_configurations.dart'; export 'src/models/config/toolbar/toolbar_configurations.dart'; export 'src/models/documents/attribute.dart'; export 'src/models/documents/document.dart'; diff --git a/lib/src/extensions/quill_configurations_ext.dart b/lib/src/extensions/quill_configurations_ext.dart index f926f76eb..a7da7df35 100644 --- a/lib/src/extensions/quill_configurations_ext.dart +++ b/lib/src/extensions/quill_configurations_ext.dart @@ -57,12 +57,12 @@ extension QuillEditorExt on BuildContext { extension QuillSimpleToolbarExt on BuildContext { /// return [QuillSimpleToolbarConfigurations] as not null QuillSimpleToolbarConfigurations get requireQuillSimpleToolbarConfigurations { - return QuillToolbarProvider.ofNotNull(this).toolbarConfigurations; + return QuillSimpleToolbarProvider.ofNotNull(this).toolbarConfigurations; } /// return nullable [QuillSimpleToolbarConfigurations] QuillSimpleToolbarConfigurations? get quillSimpleToolbarConfigurations { - return QuillToolbarProvider.of(this)?.toolbarConfigurations; + return QuillSimpleToolbarProvider.of(this)?.toolbarConfigurations; } /// return nullable [QuillToolbarBaseButtonOptions]. @@ -83,11 +83,11 @@ extension QuillSimpleToolbarExt on BuildContext { extension QuillToolbarExt on BuildContext { /// return [QuillToolbarConfigurations] as not null QuillToolbarConfigurations get requireQuillToolbarConfigurations { - return QuillBaseToolbarProvider.ofNotNull(this).toolbarConfigurations; + return QuillToolbarProvider.ofNotNull(this).toolbarConfigurations; } /// return nullable [QuillToolbarConfigurations]. QuillToolbarConfigurations? get quillToolbarConfigurations { - return QuillBaseToolbarProvider.of(this)?.toolbarConfigurations; + return QuillToolbarProvider.of(this)?.toolbarConfigurations; } } diff --git a/lib/src/extensions/uri_ext.dart b/lib/src/extensions/uri_ext.dart new file mode 100644 index 000000000..b548a29c6 --- /dev/null +++ b/lib/src/extensions/uri_ext.dart @@ -0,0 +1,11 @@ +extension UriExt on Uri { + bool isHttpBasedUrl() { + final uri = this; + return uri.isScheme('HTTP') || uri.isScheme('HTTPS'); + } + + bool isHttpsBasedUrl() { + final uri = this; + return uri.isScheme('HTTPS'); + } +} diff --git a/lib/src/models/config/editor/configurations.dart b/lib/src/models/config/editor/editor_configurations.dart similarity index 100% rename from lib/src/models/config/editor/configurations.dart rename to lib/src/models/config/editor/editor_configurations.dart diff --git a/lib/src/models/config/quill_configurations.dart b/lib/src/models/config/quill_configurations.dart index 60b30aaf8..b673ba39e 100644 --- a/lib/src/models/config/quill_configurations.dart +++ b/lib/src/models/config/quill_configurations.dart @@ -3,7 +3,7 @@ import 'package:flutter/foundation.dart' show immutable; import '../../../flutter_quill.dart'; -export './editor/configurations.dart'; +export 'editor/editor_configurations.dart'; export 'quill_shared_configurations.dart'; export 'toolbar/simple_toolbar_configurations.dart'; diff --git a/lib/src/models/config/quill_shared_configurations.dart b/lib/src/models/config/quill_shared_configurations.dart index ddf5f7763..beadc4327 100644 --- a/lib/src/models/config/quill_shared_configurations.dart +++ b/lib/src/models/config/quill_shared_configurations.dart @@ -2,7 +2,7 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart' show Color, Colors, Locale; import '../themes/quill_dialog_theme.dart'; -import './editor/configurations.dart' show QuillEditorConfigurations; +import 'editor/editor_configurations.dart' show QuillEditorConfigurations; import 'toolbar/simple_toolbar_configurations.dart' show QuillSimpleToolbarConfigurations; diff --git a/lib/src/models/config/raw_editor/configurations.dart b/lib/src/models/config/raw_editor/raw_editor_configurations.dart similarity index 100% rename from lib/src/models/config/raw_editor/configurations.dart rename to lib/src/models/config/raw_editor/raw_editor_configurations.dart diff --git a/lib/src/models/rules/insert.dart b/lib/src/models/rules/insert.dart index daf3c1100..f57cb910b 100644 --- a/lib/src/models/rules/insert.dart +++ b/lib/src/models/rules/insert.dart @@ -1,5 +1,6 @@ import 'package:meta/meta.dart' show immutable; +import '../../extensions/uri_ext.dart'; import '../../models/documents/document.dart'; import '../documents/attribute.dart'; import '../documents/nodes/embeddable.dart'; @@ -520,8 +521,7 @@ class AutoFormatLinksRule extends InsertRule { try { final cand = (prev.data as String).split('\n').last.split(' ').last; final link = Uri.parse(cand); - // TODO: Can be improved a little - if (!['https', 'http'].contains(link.scheme)) { + if (!link.isHttpBasedUrl()) { return null; } final attributes = prev.attributes ?? {}; diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index 3964cd643..68665809c 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -9,8 +9,8 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import '../../l10n/widgets/localizations.dart'; -import '../../models/config/editor/configurations.dart'; -import '../../models/config/raw_editor/configurations.dart'; +import '../../models/config/editor/editor_configurations.dart'; +import '../../models/config/raw_editor/raw_editor_configurations.dart'; import '../../models/documents/document.dart'; import '../../models/documents/nodes/container.dart' as container_node; import '../../models/documents/nodes/leaf.dart'; @@ -1209,28 +1209,6 @@ class RenderEditor extends RenderEditableContainerBox @override Rect getLocalRectForCaret(TextPosition position) { final targetChild = childAtPosition(position); - // TODO: There is a bug here - // The provided text position is not in the current node - // 'package:flutter_quill/src/widgets/text_block.dart': - // text_block.dart:1 - // Failed assertion: line 604 pos 12: - // 'container.containsOffset(position.offset)' - // When the exception was thrown, this was the stack - // #2 RenderEditableTextBlock.globalToLocalPosition - // text_block.dart:604 - // #3 RenderEditor.getLocalRectForCaret - // editor.dart:1230 - // #4 RawEditorStateTextInputClientMixin._updateComposingRectIfNeeded - // raw_editor_state_text_input_client_mixin.dart:85 - // #5 RawEditorStateTextInputClientMixin.openConnectionIfNeeded - // raw_editor_state_text_input_client_mixin.dart:70 - // #6 RawEditorState.requestKeyboard - // raw_editor.dart:1428 - // #7 QuillEditorState._requestKeyboard - // editor.dart:379 - // #8 _QuillEditorSelectionGestureDetectorBuilder.onSingleTapUp - // editor.dart:538 - // #9 _EditorTextSelectionGestureDetectorState._handleTapUp final localPosition = targetChild.globalToLocalPosition(position); final childLocalRect = targetChild.getLocalRectForCaret(localPosition); diff --git a/lib/src/widgets/others/delegate.dart b/lib/src/widgets/others/delegate.dart index b34874d05..3bf19cdc5 100644 --- a/lib/src/widgets/others/delegate.dart +++ b/lib/src/widgets/others/delegate.dart @@ -332,8 +332,6 @@ class EditorTextSelectionGestureDetectorBuilder { @protected void onDragSelectionEnd(DragEndDetails details) { renderEditor!.handleDragEnd(details); - // 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) { diff --git a/lib/src/widgets/others/proxy.dart b/lib/src/widgets/others/proxy.dart index 698497f44..6039a009b 100644 --- a/lib/src/widgets/others/proxy.dart +++ b/lib/src/widgets/others/proxy.dart @@ -136,8 +136,7 @@ class RichTextProxy extends SingleChildRenderObjectWidget { required this.textDirection, required this.locale, required this.strutStyle, - // TODO: This might needs to be updated, previous value was 1.0 using `textScaleFactor` - this.textScaler = const TextScaler.linear(1), + required this.textScaler, this.textWidthBasis = TextWidthBasis.parent, this.textHeightBehavior, super.key, diff --git a/lib/src/widgets/others/text_line.dart b/lib/src/widgets/others/text_line.dart index 0067c9581..3a155333f 100644 --- a/lib/src/widgets/others/text_line.dart +++ b/lib/src/widgets/others/text_line.dart @@ -175,11 +175,12 @@ class _TextLineState extends State { textScaler: MediaQuery.textScalerOf(context), ); return RichTextProxy( - textStyle: textSpan.style!, + textStyle: textSpan.style ?? const TextStyle(), textAlign: textAlign, textDirection: widget.textDirection!, strutStyle: strutStyle, locale: Localizations.localeOf(context), + textScaler: MediaQuery.textScalerOf(context), child: child, ); } diff --git a/lib/src/widgets/raw_editor/raw_editor.dart b/lib/src/widgets/raw_editor/raw_editor.dart index 4e11d707e..b69b75154 100644 --- a/lib/src/widgets/raw_editor/raw_editor.dart +++ b/lib/src/widgets/raw_editor/raw_editor.dart @@ -9,7 +9,7 @@ import 'package:flutter/widgets.dart' Widget; import 'package:meta/meta.dart' show immutable; -import '../../models/config/raw_editor/configurations.dart'; +import '../../models/config/raw_editor/raw_editor_configurations.dart'; import '../../models/structs/offset_value.dart'; import '../editor/editor.dart'; import '../others/text_selection.dart'; diff --git a/lib/src/widgets/toolbar/base_toolbar.dart b/lib/src/widgets/toolbar/base_toolbar.dart index 33e0f1271..5b798219c 100644 --- a/lib/src/widgets/toolbar/base_toolbar.dart +++ b/lib/src/widgets/toolbar/base_toolbar.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import '../../../flutter_quill.dart' - show QuillBaseToolbarProvider, defaultToolbarSize; + show QuillToolbarProvider, defaultToolbarSize; import '../../l10n/widgets/localizations.dart'; import '../../models/config/toolbar/simple_toolbar_configurations.dart'; import '../../models/config/toolbar/toolbar_configurations.dart'; @@ -55,7 +55,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { @override Widget build(BuildContext context) { return FlutterQuillLocalizationsWidget( - child: QuillBaseToolbarProvider( + child: QuillToolbarProvider( toolbarConfigurations: configurations, child: configurations.child, ), diff --git a/lib/src/widgets/toolbar/buttons/link_style_button.dart b/lib/src/widgets/toolbar/buttons/link_style_button.dart index 82ad93452..e52533d11 100644 --- a/lib/src/widgets/toolbar/buttons/link_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/link_style_button.dart @@ -155,7 +155,7 @@ class QuillToolbarLinkStyleButtonState } Future _openLinkDialog(BuildContext context) async { - // TODO: Add a custom call back to customize this just like in the search + // TODO: Add a custom call back to customize this just like in the search dialog // button final value = await showDialog<_TextLink>( context: context, diff --git a/lib/src/widgets/toolbar/simple_toolbar.dart b/lib/src/widgets/toolbar/simple_toolbar.dart index 483667f2d..0bec7cc19 100644 --- a/lib/src/widgets/toolbar/simple_toolbar.dart +++ b/lib/src/widgets/toolbar/simple_toolbar.dart @@ -423,7 +423,7 @@ class QuillSimpleToolbar extends StatelessWidget ]; } - return QuillToolbarProvider( + return QuillSimpleToolbarProvider( toolbarConfigurations: configurations, child: QuillToolbar( configurations: QuillToolbarConfigurations( diff --git a/lib/src/widgets/utils/provider.dart b/lib/src/widgets/utils/provider.dart index f7fbc02ce..ab3e29032 100644 --- a/lib/src/widgets/utils/provider.dart +++ b/lib/src/widgets/utils/provider.dart @@ -5,8 +5,8 @@ import 'package:flutter/widgets.dart' import '../../models/config/quill_configurations.dart'; import '../../models/config/toolbar/toolbar_configurations.dart'; -class QuillToolbarProvider extends InheritedWidget { - const QuillToolbarProvider({ +class QuillSimpleToolbarProvider extends InheritedWidget { + const QuillSimpleToolbarProvider({ required super.child, required this.toolbarConfigurations, super.key, @@ -16,16 +16,17 @@ class QuillToolbarProvider extends InheritedWidget { final QuillSimpleToolbarConfigurations toolbarConfigurations; @override - bool updateShouldNotify(covariant QuillToolbarProvider oldWidget) { + bool updateShouldNotify(covariant QuillSimpleToolbarProvider oldWidget) { return oldWidget.toolbarConfigurations != toolbarConfigurations; } - static QuillToolbarProvider? of(BuildContext context) { + static QuillSimpleToolbarProvider? of(BuildContext context) { /// The configurations for the quill editor widget of flutter quill - return context.dependOnInheritedWidgetOfExactType(); + return context + .dependOnInheritedWidgetOfExactType(); } - static QuillToolbarProvider ofNotNull(BuildContext context) { + static QuillSimpleToolbarProvider ofNotNull(BuildContext context) { final provider = of(context); if (provider == null) { if (kDebugMode) { @@ -49,13 +50,13 @@ class QuillToolbarProvider extends InheritedWidget { return provider; } - /// To pass the [QuillToolbarProvider] instance as value instead of creating + /// To pass the [QuillSimpleToolbarProvider] instance as value instead of creating /// new widget - static QuillToolbarProvider value({ - required QuillToolbarProvider value, + static QuillSimpleToolbarProvider value({ + required QuillSimpleToolbarProvider value, required Widget child, }) { - return QuillToolbarProvider( + return QuillSimpleToolbarProvider( toolbarConfigurations: value.toolbarConfigurations, child: child, ); @@ -63,8 +64,8 @@ class QuillToolbarProvider extends InheritedWidget { } // Not really needed -class QuillBaseToolbarProvider extends InheritedWidget { - const QuillBaseToolbarProvider({ +class QuillToolbarProvider extends InheritedWidget { + const QuillToolbarProvider({ required super.child, required this.toolbarConfigurations, super.key, @@ -74,17 +75,16 @@ class QuillBaseToolbarProvider extends InheritedWidget { final QuillToolbarConfigurations toolbarConfigurations; @override - bool updateShouldNotify(covariant QuillBaseToolbarProvider oldWidget) { + bool updateShouldNotify(covariant QuillToolbarProvider oldWidget) { return oldWidget.toolbarConfigurations != toolbarConfigurations; } - static QuillBaseToolbarProvider? of(BuildContext context) { + static QuillToolbarProvider? of(BuildContext context) { /// The configurations for the quill editor widget of flutter quill - return context - .dependOnInheritedWidgetOfExactType(); + return context.dependOnInheritedWidgetOfExactType(); } - static QuillBaseToolbarProvider ofNotNull(BuildContext context) { + static QuillToolbarProvider ofNotNull(BuildContext context) { final provider = of(context); if (provider == null) { if (kDebugMode) { @@ -110,11 +110,11 @@ class QuillBaseToolbarProvider extends InheritedWidget { /// To pass the [QuillToolbarConfigurations] instance as value /// instead of creating new widget - static QuillBaseToolbarProvider value({ + static QuillToolbarProvider value({ required QuillToolbarConfigurations value, required Widget child, }) { - return QuillBaseToolbarProvider( + return QuillToolbarProvider( toolbarConfigurations: value, child: child, ); From 9be1a55fbfc52a6a719771083f2ae358c2567443 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 6 Dec 2023 12:13:25 +0300 Subject: [PATCH 42/86] Prepare for release dev 6 --- example/lib/presentation/simple/simple_screen.dart | 11 ----------- flutter_quill_extensions/CHANGELOG.md | 6 ++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 6 ++++++ flutter_quill_test/pubspec.yaml | 2 +- packages/quill_html_converter/CHANGELOG.md | 6 ++++++ packages/quill_html_converter/pubspec.yaml | 2 +- pubspec.yaml | 2 +- scripts/regenerate_versions.sh | 3 +++ version.dart | 2 +- 10 files changed, 26 insertions(+), 16 deletions(-) create mode 100755 scripts/regenerate_versions.sh diff --git a/example/lib/presentation/simple/simple_screen.dart b/example/lib/presentation/simple/simple_screen.dart index 2fc3a1383..0393fcf7c 100644 --- a/example/lib/presentation/simple/simple_screen.dart +++ b/example/lib/presentation/simple/simple_screen.dart @@ -13,17 +13,6 @@ class _SimpleScreenState extends State { @override Widget build(BuildContext context) { - return Column( - children: [ - QuillToolbar.simple( - QuillSimpleToolbarConfigurations(controller: _controller)), - Expanded( - child: QuillEditor.basic( - configurations: QuillEditorConfigurations(controller: _controller), - ), - ) - ], - ); return Scaffold( appBar: AppBar(), body: Column( diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 849261e54..14612cdd2 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,9 +2,15 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-5 +* The `QuillToolbar` is now accepting only `child` with no configurations so you can customize everything you wants, the `QuillToolbar.simple()` or `QuillSimpleToolbar` implements a simple toolbar that is based on `QuillToolbar`, you are free to use it but it just an example and not standard +* Flutter Quill Extensions: + * Improve the camera button + ## 9.0.0-dev-4 * The options parameter in all of the buttons is no longer required which can be useful to create custom toolbar with minimal efforts * Toolbar buttons fixes in both `flutter_quill` and `flutter_quill_extensions` +* The `QuillProvider` has been dropped and no longer used, the providers will be used only internally from now on and we will not using them as much as possible ## 9.0.0-dev-3 * Breaking Changes: diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 4048ccc82..c80463aa3 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: 9.0.0-dev-4 +version: 9.0.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/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 849261e54..14612cdd2 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -2,9 +2,15 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-5 +* The `QuillToolbar` is now accepting only `child` with no configurations so you can customize everything you wants, the `QuillToolbar.simple()` or `QuillSimpleToolbar` implements a simple toolbar that is based on `QuillToolbar`, you are free to use it but it just an example and not standard +* Flutter Quill Extensions: + * Improve the camera button + ## 9.0.0-dev-4 * The options parameter in all of the buttons is no longer required which can be useful to create custom toolbar with minimal efforts * Toolbar buttons fixes in both `flutter_quill` and `flutter_quill_extensions` +* The `QuillProvider` has been dropped and no longer used, the providers will be used only internally from now on and we will not using them as much as possible ## 9.0.0-dev-3 * Breaking Changes: diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index e0b37648a..e936801db 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: 9.0.0-dev-4 +version: 9.0.0-dev-6 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index 849261e54..14612cdd2 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -2,9 +2,15 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-5 +* The `QuillToolbar` is now accepting only `child` with no configurations so you can customize everything you wants, the `QuillToolbar.simple()` or `QuillSimpleToolbar` implements a simple toolbar that is based on `QuillToolbar`, you are free to use it but it just an example and not standard +* Flutter Quill Extensions: + * Improve the camera button + ## 9.0.0-dev-4 * The options parameter in all of the buttons is no longer required which can be useful to create custom toolbar with minimal efforts * Toolbar buttons fixes in both `flutter_quill` and `flutter_quill_extensions` +* The `QuillProvider` has been dropped and no longer used, the providers will be used only internally from now on and we will not using them as much as possible ## 9.0.0-dev-3 * Breaking Changes: diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index 0ce0ffe1b..4f5d6e553 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.0.0-dev-4 +version: 9.0.0-dev-6 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 0fff6388f..9f99953bc 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: 9.0.0-dev-4 +version: 9.0.0-dev-6 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/scripts/regenerate_versions.sh b/scripts/regenerate_versions.sh new file mode 100755 index 000000000..379020442 --- /dev/null +++ b/scripts/regenerate_versions.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +dart ./scripts/regenerate_versions.dart \ No newline at end of file diff --git a/version.dart b/version.dart index 5b59c4d6b..123f4db07 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev-5'; +const version = '9.0.0-dev-6'; From 1705bff43e419d60021b77787e1c7bac5b535389 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 6 Dec 2023 12:14:32 +0300 Subject: [PATCH 43/86] Prepare for release dev 5 --- flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/pubspec.yaml | 2 +- packages/quill_html_converter/pubspec.yaml | 2 +- pubspec.yaml | 2 +- version.dart | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index c80463aa3..9d96edaf0 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: 9.0.0-dev-6 +version: 9.0.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/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index e936801db..2283a901b 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: 9.0.0-dev-6 +version: 9.0.0-dev-5 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index 4f5d6e553..dd996a3f8 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.0.0-dev-6 +version: 9.0.0-dev-5 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 9f99953bc..a57fa2262 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: 9.0.0-dev-6 +version: 9.0.0-dev-5 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/version.dart b/version.dart index 123f4db07..5b59c4d6b 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev-6'; +const version = '9.0.0-dev-5'; From ec2d28c1bcb2d5a38cb352574118d250d9744a3d Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 6 Dec 2023 12:48:46 +0300 Subject: [PATCH 44/86] Bug fixes --- CHANGELOG.md | 3 + .../lib/presentation/quill/quill_editor.dart | 8 +- .../lib/presentation/quill/quill_screen.dart | 11 +- .../lib/presentation/quill/quill_toolbar.dart | 188 +++++++++--------- .../presentation/simple/simple_screen.dart | 3 +- flutter_quill_extensions/README.md | 22 +- .../lib/embeds/image/editor/image_embed.dart | 4 +- .../lib/embeds/image/editor/image_menu.dart | 2 +- .../embeds/image/toolbar/image_button.dart | 2 +- .../others/camera_button/camera_button.dart | 2 +- .../embeds/video/toolbar/video_button.dart | 2 +- .../models/config/shared_configurations.dart | 53 ++--- lib/src/extensions/quill_controller_ext.dart | 2 +- .../config/editor/editor_configurations.dart | 8 + .../config/quill_shared_configurations.dart | 4 - .../toolbar/buttons/base_configurations.dart | 3 +- .../toolbar/toolbar_configurations.dart | 6 +- lib/src/widgets/toolbar/base_toolbar.dart | 9 +- lib/src/widgets/toolbar/simple_toolbar.dart | 64 +++--- lib/src/widgets/utils/provider.dart | 6 +- 20 files changed, 189 insertions(+), 213 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14612cdd2..b91fce56f 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-6 +* Move the `child` from `QuillToolbarConfigurations` into `QuillToolbar` directly + ## 9.0.0-dev-5 * The `QuillToolbar` is now accepting only `child` with no configurations so you can customize everything you wants, the `QuillToolbar.simple()` or `QuillSimpleToolbar` implements a simple toolbar that is based on `QuillToolbar`, you are free to use it but it just an example and not standard * Flutter Quill Extensions: diff --git a/example/lib/presentation/quill/quill_editor.dart b/example/lib/presentation/quill/quill_editor.dart index 06f7eb766..6acc968d5 100644 --- a/example/lib/presentation/quill/quill_editor.dart +++ b/example/lib/presentation/quill/quill_editor.dart @@ -33,6 +33,12 @@ class MyQuillEditor extends StatelessWidget { scrollController: scrollController, focusNode: focusNode, configurations: configurations.copyWith( + extraConfigurations: { + QuillEditorExtensionsConfigurations.key: + const QuillEditorExtensionsConfigurations( + assetsPrefix: 'dsadsasda', // Defaults to assets + ), + }, customStyles: const DefaultStyles( h1: DefaultTextBlockStyle( TextStyle( @@ -99,7 +105,7 @@ class MyQuillEditor extends StatelessWidget { return getImageProviderByImageSource( imageUrl, imageProviderBuilder: null, - assetsPrefix: QuillSharedExtensionsConfigurations.get( + assetsPrefix: QuillEditorExtensionsConfigurations.get( context: context) .assetsPrefix, ); diff --git a/example/lib/presentation/quill/quill_screen.dart b/example/lib/presentation/quill/quill_screen.dart index 86ea834ff..ef8935249 100644 --- a/example/lib/presentation/quill/quill_screen.dart +++ b/example/lib/presentation/quill/quill_screen.dart @@ -3,7 +3,7 @@ import 'dart:convert' show jsonEncode; import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart' - show FlutterQuillEmbeds, QuillSharedExtensionsConfigurations; + show FlutterQuillEmbeds; import 'package:quill_html_converter/quill_html_converter.dart'; import 'package:share_plus/share_plus.dart' show Share; @@ -133,12 +133,7 @@ class _QuillScreenState extends State { QuillSharedConfigurations get _sharedConfigurations { return const QuillSharedConfigurations( - extraConfigurations: { - QuillSharedExtensionsConfigurations.key: - QuillSharedExtensionsConfigurations( - assetsPrefix: 'your-assets-folder-name', // Defaults to assets - ), - }, - ); + // locale: Locale('en'), + ); } } diff --git a/example/lib/presentation/quill/quill_toolbar.dart b/example/lib/presentation/quill/quill_toolbar.dart index e7b02fe1e..f7c22b1be 100644 --- a/example/lib/presentation/quill/quill_toolbar.dart +++ b/example/lib/presentation/quill/quill_toolbar.dart @@ -100,106 +100,106 @@ class MyQuillToolbar extends StatelessWidget { // For more info // https://github.com/singerdmx/flutter-quill/blob/master/doc/custom_toolbar.md return QuillToolbar( - configurations: QuillToolbarConfigurations( - buttonOptions: const QuillToolbarButtonOptions( + configurations: const QuillToolbarConfigurations( + buttonOptions: QuillToolbarButtonOptions( base: QuillToolbarBaseButtonOptions( globalIconSize: 20, globalIconButtonFactor: 1.4, ), ), - child: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Row( - children: [ - IconButton( - onPressed: () => context - .read() - .updateSettings( - state.copyWith(useCustomQuillToolbar: false)), - icon: const Icon( - Icons.width_normal, - ), - ), - QuillToolbarHistoryButton( - isUndo: true, - controller: controller, - ), - QuillToolbarHistoryButton( - isUndo: false, - controller: controller, - ), - QuillToolbarToggleStyleButton( - options: const QuillToolbarToggleStyleButtonOptions(), - controller: controller, - attribute: Attribute.bold, - ), - QuillToolbarToggleStyleButton( - options: const QuillToolbarToggleStyleButtonOptions(), - controller: controller, - attribute: Attribute.italic, - ), - QuillToolbarToggleStyleButton( - controller: controller, - attribute: Attribute.underline, - ), - QuillToolbarClearFormatButton( - controller: controller, - ), - const VerticalDivider(), - QuillToolbarImageButton( - controller: controller, - ), - QuillToolbarCameraButton( - controller: controller, - ), - QuillToolbarVideoButton( - controller: controller, - ), - const VerticalDivider(), - QuillToolbarColorButton( - controller: controller, - isBackground: false, - ), - QuillToolbarColorButton( - controller: controller, - isBackground: true, - ), - const VerticalDivider(), - QuillToolbarSelectHeaderStyleButton( - controller: controller, - ), - const VerticalDivider(), - QuillToolbarToggleCheckListButton( - controller: controller, - ), - QuillToolbarToggleStyleButton( - controller: controller, - attribute: Attribute.ol, - ), - QuillToolbarToggleStyleButton( - controller: controller, - attribute: Attribute.ul, - ), - QuillToolbarToggleStyleButton( - controller: controller, - attribute: Attribute.inlineCode, - ), - QuillToolbarToggleStyleButton( - controller: controller, - attribute: Attribute.blockQuote, - ), - QuillToolbarIndentButton( - controller: controller, - isIncrease: true, - ), - QuillToolbarIndentButton( - controller: controller, - isIncrease: false, + ), + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + IconButton( + onPressed: () => context + .read() + .updateSettings( + state.copyWith(useCustomQuillToolbar: false)), + icon: const Icon( + Icons.width_normal, ), - const VerticalDivider(), - QuillToolbarLinkStyleButton(controller: controller), - ], - ), + ), + QuillToolbarHistoryButton( + isUndo: true, + controller: controller, + ), + QuillToolbarHistoryButton( + isUndo: false, + controller: controller, + ), + QuillToolbarToggleStyleButton( + options: const QuillToolbarToggleStyleButtonOptions(), + controller: controller, + attribute: Attribute.bold, + ), + QuillToolbarToggleStyleButton( + options: const QuillToolbarToggleStyleButtonOptions(), + controller: controller, + attribute: Attribute.italic, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.underline, + ), + QuillToolbarClearFormatButton( + controller: controller, + ), + const VerticalDivider(), + QuillToolbarImageButton( + controller: controller, + ), + QuillToolbarCameraButton( + controller: controller, + ), + QuillToolbarVideoButton( + controller: controller, + ), + const VerticalDivider(), + QuillToolbarColorButton( + controller: controller, + isBackground: false, + ), + QuillToolbarColorButton( + controller: controller, + isBackground: true, + ), + const VerticalDivider(), + QuillToolbarSelectHeaderStyleButton( + controller: controller, + ), + const VerticalDivider(), + QuillToolbarToggleCheckListButton( + controller: controller, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.ol, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.ul, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.inlineCode, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.blockQuote, + ), + QuillToolbarIndentButton( + controller: controller, + isIncrease: true, + ), + QuillToolbarIndentButton( + controller: controller, + isIncrease: false, + ), + const VerticalDivider(), + QuillToolbarLinkStyleButton(controller: controller), + ], ), ), ); diff --git a/example/lib/presentation/simple/simple_screen.dart b/example/lib/presentation/simple/simple_screen.dart index 0393fcf7c..a49d48ba0 100644 --- a/example/lib/presentation/simple/simple_screen.dart +++ b/example/lib/presentation/simple/simple_screen.dart @@ -18,7 +18,8 @@ class _SimpleScreenState extends State { body: Column( children: [ QuillToolbar.simple( - QuillSimpleToolbarConfigurations(controller: _controller), + configurations: + QuillSimpleToolbarConfigurations(controller: _controller), ), Expanded( child: QuillEditor.basic( diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index 4158462c5..441277f08 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -170,19 +170,17 @@ This works for all platforms except Web If you want to use image assets in the Quill Editor, you need to make sure your assets folder is `assets` otherwise: ```dart - QuillProvider( - configurations: const QuillConfigurations( - sharedConfigurations: QuillSharedConfigurations( - extraConfigurations: { - QuillSharedExtensionsConfigurations.key: - QuillSharedExtensionsConfigurations( - assetsPrefix: 'your-assets-folder-name', // Defaults to assets - ), - }, - ), + QuillEditor.basic( + configurations: const QuillEditorConfigurations( + // ... + extraConfigurations: { + QuillEditorExtensionsConfigurations.key: + QuillEditorExtensionsConfigurations( + assetsPrefix: 'your-assets-folder-name', // Defaults to assets ), - child: ..., - ) + }, + ), + ) ``` This info is needed by the package to check if it asset image to use the `AssetImage` provider 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 ee0a8f9a2..0fc025eaf 100644 --- a/flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart +++ b/flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart @@ -47,12 +47,12 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { alignment: alignment, height: height, width: width, - assetsPrefix: QuillSharedExtensionsConfigurations.get(context: context) + assetsPrefix: QuillEditorExtensionsConfigurations.get(context: context) .assetsPrefix, ); final imageSaverService = - QuillSharedExtensionsConfigurations.get(context: context) + QuillEditorExtensionsConfigurations.get(context: context) .imageSaverService; return GestureDetector( onTap: configurations.onImageClicked ?? 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 bc1e1414b..a7d57cb37 100644 --- a/flutter_quill_extensions/lib/embeds/image/editor/image_menu.dart +++ b/flutter_quill_extensions/lib/embeds/image/editor/image_menu.dart @@ -184,7 +184,7 @@ class ImageOptionsMenu extends StatelessWidget { MaterialPageRoute( builder: (_) => ImageTapWrapper( assetsPrefix: - QuillSharedExtensionsConfigurations.get(context: context) + QuillEditorExtensionsConfigurations.get(context: context) .assetsPrefix, imageUrl: imageSource, configurations: configurations, 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 f943dabd4..5baeecdde 100644 --- a/flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart +++ b/flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart @@ -116,7 +116,7 @@ class QuillToolbarImageButton extends StatelessWidget { Future _onPressedHandler(BuildContext context) async { final imagePickerService = - QuillSharedExtensionsConfigurations.get(context: context) + QuillEditorExtensionsConfigurations.get(context: context) .imagePickerService; final onRequestPickImage = diff --git a/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart b/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart index ef7ad3da5..74cbee389 100644 --- a/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart +++ b/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart @@ -132,7 +132,7 @@ class QuillToolbarCameraButton extends StatelessWidget { QuillController controller, ) async { final imagePickerService = - QuillSharedExtensionsConfigurations.get(context: context) + QuillEditorExtensionsConfigurations.get(context: context) .imagePickerService; final cameraAction = await _getCameraAction(context); 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 748759784..c2093c940 100644 --- a/flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart +++ b/flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart @@ -115,7 +115,7 @@ class QuillToolbarVideoButton extends StatelessWidget { Future _onPressedHandler(BuildContext context) async { final imagePickerService = - QuillSharedExtensionsConfigurations.get(context: context) + QuillEditorExtensionsConfigurations.get(context: context) .imagePickerService; final onRequestPickVideo = options.videoConfigurations.onRequestPickVideo; diff --git a/flutter_quill_extensions/lib/models/config/shared_configurations.dart b/flutter_quill_extensions/lib/models/config/shared_configurations.dart index a31620107..381d0160b 100644 --- a/flutter_quill_extensions/lib/models/config/shared_configurations.dart +++ b/flutter_quill_extensions/lib/models/config/shared_configurations.dart @@ -5,37 +5,10 @@ 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 -/// // ... -/// ], -// ), -/// ) -/// ``` -/// +/// Configurations for Flutter Quill Editor Extensions @immutable -class QuillSharedExtensionsConfigurations { - const QuillSharedExtensionsConfigurations({ +class QuillEditorExtensionsConfigurations { + const QuillEditorExtensionsConfigurations({ ImagePickerService? imagePickerService, ImageSaverService? imageSaverService, this.assetsPrefix = 'assets', @@ -44,30 +17,28 @@ class QuillSharedExtensionsConfigurations { /// 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({ + factory QuillEditorExtensionsConfigurations.get({ required BuildContext context, }) { - final quillSharedExtensionsConfigurations = - context.quillSharedConfigurations?.extraConfigurations[key]; - if (quillSharedExtensionsConfigurations != null) { - if (quillSharedExtensionsConfigurations - is! QuillSharedExtensionsConfigurations) { + final value = context.quillEditorConfigurations?.extraConfigurations[key]; + if (value != null) { + if (value is! QuillEditorExtensionsConfigurations) { throw ArgumentError( 'The value of key `$key` should be of type ' - 'QuillSharedExtensionsConfigurations', + '$key', ); } - return quillSharedExtensionsConfigurations; + return value; } - return const QuillSharedExtensionsConfigurations(); + return const QuillEditorExtensionsConfigurations(); } /// 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'; + /// which exists in the [QuillEditorConfigurations] + static const String key = 'QuillEditorExtensionsConfigurations'; /// Defaults to [ImagePickerService.defaultImpl] final ImagePickerService? _imagePickerService; diff --git a/lib/src/extensions/quill_controller_ext.dart b/lib/src/extensions/quill_controller_ext.dart index 3ae3e8470..49c09f976 100644 --- a/lib/src/extensions/quill_controller_ext.dart +++ b/lib/src/extensions/quill_controller_ext.dart @@ -5,7 +5,7 @@ import 'quill_configurations_ext.dart'; extension QuillControllerNullableExt on QuillController? { /// Simple logic to use the current passed controller if not null - /// if null then we will have to use the default one from [QuillProvider] + /// if null then we will have to use the default one /// using the [context] QuillController notNull(BuildContext context) { final controller = this; diff --git a/lib/src/models/config/editor/editor_configurations.dart b/lib/src/models/config/editor/editor_configurations.dart index c41787b43..97904f660 100644 --- a/lib/src/models/config/editor/editor_configurations.dart +++ b/lib/src/models/config/editor/editor_configurations.dart @@ -75,10 +75,14 @@ class QuillEditorConfigurations extends Equatable { this.builder, this.magnifierConfiguration, this.textInputAction = TextInputAction.newline, + this.extraConfigurations = const {}, }); final QuillSharedConfigurations sharedConfigurations; + /// Store custom configurations in here and use it in the widget tree + final Map extraConfigurations; + final QuillController controller; /// The text placeholder in the quill editor @@ -338,6 +342,8 @@ class QuillEditorConfigurations extends Equatable { // regenerate this function using extension in vs code or plugin in intellij QuillEditorConfigurations copyWith({ + QuillSharedConfigurations? sharedConfigurations, + Map? extraConfigurations, QuillController? controller, String? placeholder, bool? readOnly, @@ -384,6 +390,8 @@ class QuillEditorConfigurations extends Equatable { TextInputAction? textInputAction, }) { return QuillEditorConfigurations( + sharedConfigurations: sharedConfigurations ?? this.sharedConfigurations, + extraConfigurations: extraConfigurations ?? this.extraConfigurations, controller: controller ?? this.controller, placeholder: placeholder ?? this.placeholder, readOnly: readOnly ?? this.readOnly, diff --git a/lib/src/models/config/quill_shared_configurations.dart b/lib/src/models/config/quill_shared_configurations.dart index beadc4327..8bf224dab 100644 --- a/lib/src/models/config/quill_shared_configurations.dart +++ b/lib/src/models/config/quill_shared_configurations.dart @@ -15,7 +15,6 @@ class QuillSharedConfigurations extends Equatable { this.dialogBarrierColor = Colors.black54, this.dialogTheme, this.locale, - this.extraConfigurations = const {}, }); // This is just example or showcase of this major update to make the library @@ -34,9 +33,6 @@ class QuillSharedConfigurations extends Equatable { /// `MaterialApp` or `WidgetsApp` final Locale? locale; - /// Store custom configurations in here and use it in the widget tree - final Map extraConfigurations; - @override List get props => [ dialogBarrierColor, diff --git a/lib/src/models/config/toolbar/buttons/base_configurations.dart b/lib/src/models/config/toolbar/buttons/base_configurations.dart index be77a833b..91058591c 100644 --- a/lib/src/models/config/toolbar/buttons/base_configurations.dart +++ b/lib/src/models/config/toolbar/buttons/base_configurations.dart @@ -1,4 +1,3 @@ -// ignore_for_file: public_member_api_docs, sort_constructors_first import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show VoidCallback, immutable; import 'package:flutter/widgets.dart' show BuildContext, IconData, Widget; @@ -82,7 +81,7 @@ class QuillToolbarBaseButtonOptions extends Equatable { /// If you want to dispaly a differnet widget based using a builder final QuillToolbarButtonOptionsChildBuilder childBuilder; - /// By default it will be from the one in [QuillProvider] + /// By default it will be from the one in [QuillEditor] or [QuillToolbar] /// To override it you must pass not null controller /// if you wish to use the controller in the [childBuilder], please use the /// one from the extraOptions since it will be not null and will be the one diff --git a/lib/src/models/config/toolbar/toolbar_configurations.dart b/lib/src/models/config/toolbar/toolbar_configurations.dart index 29bfc4e8f..4e318c5c9 100644 --- a/lib/src/models/config/toolbar/toolbar_configurations.dart +++ b/lib/src/models/config/toolbar/toolbar_configurations.dart @@ -1,5 +1,4 @@ -// ignore_for_file: public_member_api_docs, sort_constructors_first -import 'package:flutter/widgets.dart' show Widget, immutable; +import 'package:flutter/widgets.dart' show immutable; import '../../../widgets/toolbar/base_toolbar.dart'; import 'toolbar_shared_configurations.dart'; @@ -7,7 +6,6 @@ import 'toolbar_shared_configurations.dart'; @immutable class QuillToolbarConfigurations extends QuillSharedToolbarProperties { const QuillToolbarConfigurations({ - required this.child, super.sharedConfigurations, /// Note this only used when you using the quill toolbar buttons like @@ -15,8 +13,6 @@ class QuillToolbarConfigurations extends QuillSharedToolbarProperties { super.buttonOptions = const QuillToolbarButtonOptions(), }); - final Widget child; - @override List get props => []; } diff --git a/lib/src/widgets/toolbar/base_toolbar.dart b/lib/src/widgets/toolbar/base_toolbar.dart index 5b798219c..c849eda72 100644 --- a/lib/src/widgets/toolbar/base_toolbar.dart +++ b/lib/src/widgets/toolbar/base_toolbar.dart @@ -30,17 +30,20 @@ typedef QuillBaseToolbarChildrenBuilder = List Function( class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { const QuillToolbar({ - required this.configurations, + required this.child, + this.configurations = const QuillToolbarConfigurations(), super.key, }); static QuillSimpleToolbar simple( - QuillSimpleToolbarConfigurations configurations) { + {required QuillSimpleToolbarConfigurations configurations}) { return QuillSimpleToolbar( configurations: configurations, ); } + final Widget child; + final QuillToolbarConfigurations configurations; // We can't get the modified [toolbarSize] by the developer @@ -57,7 +60,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { return FlutterQuillLocalizationsWidget( child: QuillToolbarProvider( toolbarConfigurations: configurations, - child: configurations.child, + child: child, ), ); } diff --git a/lib/src/widgets/toolbar/simple_toolbar.dart b/lib/src/widgets/toolbar/simple_toolbar.dart index 0bec7cc19..9794b3127 100644 --- a/lib/src/widgets/toolbar/simple_toolbar.dart +++ b/lib/src/widgets/toolbar/simple_toolbar.dart @@ -428,39 +428,39 @@ class QuillSimpleToolbar extends StatelessWidget child: QuillToolbar( configurations: QuillToolbarConfigurations( buttonOptions: configurations.buttonOptions, - child: Builder( - builder: (context) { - if (configurations.multiRowsDisplay) { - return Wrap( - direction: configurations.axis, - alignment: configurations.toolbarIconAlignment, - crossAxisAlignment: configurations.toolbarIconCrossAlignment, - runSpacing: 4, - spacing: configurations.toolbarSectionSpacing, - children: childrenBuilder(context), - ); - } - return Container( - decoration: configurations.decoration ?? - BoxDecoration( - color: - configurations.color ?? Theme.of(context).canvasColor, - ), - constraints: BoxConstraints.tightFor( - height: configurations.axis == Axis.horizontal - ? configurations.toolbarSize - : null, - width: configurations.axis == Axis.vertical - ? configurations.toolbarSize - : null, - ), - child: QuillToolbarArrowIndicatedButtonList( - axis: configurations.axis, - buttons: childrenBuilder(context), - ), + ), + child: Builder( + builder: (context) { + if (configurations.multiRowsDisplay) { + return Wrap( + direction: configurations.axis, + alignment: configurations.toolbarIconAlignment, + crossAxisAlignment: configurations.toolbarIconCrossAlignment, + runSpacing: 4, + spacing: configurations.toolbarSectionSpacing, + children: childrenBuilder(context), ); - }, - ), + } + return Container( + decoration: configurations.decoration ?? + BoxDecoration( + color: + configurations.color ?? Theme.of(context).canvasColor, + ), + constraints: BoxConstraints.tightFor( + height: configurations.axis == Axis.horizontal + ? configurations.toolbarSize + : null, + width: configurations.axis == Axis.vertical + ? configurations.toolbarSize + : null, + ), + child: QuillToolbarArrowIndicatedButtonList( + axis: configurations.axis, + buttons: childrenBuilder(context), + ), + ); + }, ), ), ); diff --git a/lib/src/widgets/utils/provider.dart b/lib/src/widgets/utils/provider.dart index ab3e29032..57f9cf15f 100644 --- a/lib/src/widgets/utils/provider.dart +++ b/lib/src/widgets/utils/provider.dart @@ -44,7 +44,7 @@ class QuillSimpleToolbarProvider extends InheritedWidget { 'You might using QuillToolbar so make sure to' ' wrap them with the quill provider widget and setup the required ' 'configurations', - 'QuillProvider', + 'QuillSimpleToolbarProvider', ); } return provider; @@ -102,7 +102,7 @@ class QuillToolbarProvider extends InheritedWidget { 'You might using QuillBaseToolbar so make sure to' ' wrap them with the quill provider widget and setup the required ' 'configurations', - 'QuillProvider', + 'QuillToolbarProvider', ); } return provider; @@ -159,7 +159,7 @@ class QuillEditorProvider extends InheritedWidget { 'You might using QuillEditor so make sure to' ' wrap them with the quill provider widget and setup the required ' 'configurations', - 'QuillProvider', + 'QuillEditorProvider', ); } return provider; From 5e6115d137df20647464d13542565c99600c99d5 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 6 Dec 2023 14:47:54 +0300 Subject: [PATCH 45/86] Bug fixes --- CHANGELOG.md | 3 +++ .../{quill_editor.dart => my_quill_editor.dart} | 11 +++-------- ...quill_toolbar.dart => my_quill_toolbar.dart} | 0 .../lib/presentation/quill/quill_screen.dart | 16 +++++++++++----- flutter_quill_extensions/README.md | 16 +++++++++------- .../lib/embeds/image/editor/image_embed.dart | 5 +++-- .../embeds/image/editor/image_embed_types.dart | 1 + .../lib/embeds/image/editor/image_menu.dart | 2 +- .../lib/embeds/image/toolbar/image_button.dart | 2 +- .../others/camera_button/camera_button.dart | 2 +- .../lib/embeds/video/toolbar/video_button.dart | 2 +- .../lib/embeds/widgets/image.dart | 6 +++++- .../models/config/shared_configurations.dart | 17 +++++++++-------- .../config/editor/editor_configurations.dart | 6 ------ .../config/quill_shared_configurations.dart | 4 ++++ 15 files changed, 52 insertions(+), 41 deletions(-) rename example/lib/presentation/quill/{quill_editor.dart => my_quill_editor.dart} (93%) rename example/lib/presentation/quill/{quill_toolbar.dart => my_quill_toolbar.dart} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index b91fce56f..a07d0fde8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file. ## 9.0.0-dev-6 * Move the `child` from `QuillToolbarConfigurations` into `QuillToolbar` directly +* Bug fixes +* Flutter Quill Extensions: + * **Breaking Change**: The `imageProviderBuilder`is now providing the context and image url ## 9.0.0-dev-5 * The `QuillToolbar` is now accepting only `child` with no configurations so you can customize everything you wants, the `QuillToolbar.simple()` or `QuillSimpleToolbar` implements a simple toolbar that is based on `QuillToolbar`, you are free to use it but it just an example and not standard diff --git a/example/lib/presentation/quill/quill_editor.dart b/example/lib/presentation/quill/my_quill_editor.dart similarity index 93% rename from example/lib/presentation/quill/quill_editor.dart rename to example/lib/presentation/quill/my_quill_editor.dart index 6acc968d5..390f08577 100644 --- a/example/lib/presentation/quill/quill_editor.dart +++ b/example/lib/presentation/quill/my_quill_editor.dart @@ -33,12 +33,6 @@ class MyQuillEditor extends StatelessWidget { scrollController: scrollController, focusNode: focusNode, configurations: configurations.copyWith( - extraConfigurations: { - QuillEditorExtensionsConfigurations.key: - const QuillEditorExtensionsConfigurations( - assetsPrefix: 'dsadsasda', // Defaults to assets - ), - }, customStyles: const DefaultStyles( h1: DefaultTextBlockStyle( TextStyle( @@ -88,7 +82,7 @@ class MyQuillEditor extends StatelessWidget { 'Error while loading an image: ${error.toString()}', ); }, - imageProviderBuilder: (imageUrl) { + imageProviderBuilder: (context, imageUrl) { // cached_network_image is supported // only for Android, iOS and web @@ -105,7 +99,8 @@ class MyQuillEditor extends StatelessWidget { return getImageProviderByImageSource( imageUrl, imageProviderBuilder: null, - assetsPrefix: QuillEditorExtensionsConfigurations.get( + context: context, + assetsPrefix: QuillSharedExtensionsConfigurations.get( context: context) .assetsPrefix, ); diff --git a/example/lib/presentation/quill/quill_toolbar.dart b/example/lib/presentation/quill/my_quill_toolbar.dart similarity index 100% rename from example/lib/presentation/quill/quill_toolbar.dart rename to example/lib/presentation/quill/my_quill_toolbar.dart diff --git a/example/lib/presentation/quill/quill_screen.dart b/example/lib/presentation/quill/quill_screen.dart index ef8935249..0cf6eea0b 100644 --- a/example/lib/presentation/quill/quill_screen.dart +++ b/example/lib/presentation/quill/quill_screen.dart @@ -3,15 +3,15 @@ import 'dart:convert' show jsonEncode; import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart' - show FlutterQuillEmbeds; + show FlutterQuillEmbeds, QuillSharedExtensionsConfigurations; import 'package:quill_html_converter/quill_html_converter.dart'; import 'package:share_plus/share_plus.dart' show Share; import '../extensions/scaffold_messenger.dart'; import '../shared/widgets/home_screen_button.dart'; -import 'quill_editor.dart'; -import 'quill_toolbar.dart'; +import 'my_quill_editor.dart'; +import 'my_quill_toolbar.dart'; @immutable class QuillScreenArgs { @@ -133,7 +133,13 @@ class _QuillScreenState extends State { QuillSharedConfigurations get _sharedConfigurations { return const QuillSharedConfigurations( - // locale: Locale('en'), - ); + // locale: Locale('en'), + extraConfigurations: { + QuillSharedExtensionsConfigurations.key: + QuillSharedExtensionsConfigurations( + assetsPrefix: 'assets', // Defaults to assets + ), + }, + ); } } diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index 441277f08..26d2fb02e 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -170,17 +170,19 @@ This works for all platforms except Web If you want to use image assets in the Quill Editor, you need to make sure your assets folder is `assets` otherwise: ```dart - QuillEditor.basic( - configurations: const QuillEditorConfigurations( - // ... +QuillEditor.basic( + configurations: const QuillEditorConfigurations( + // ... + sharedConfigurations: QuillSharedConfigurations( extraConfigurations: { - QuillEditorExtensionsConfigurations.key: - QuillEditorExtensionsConfigurations( - assetsPrefix: 'your-assets-folder-name', // Defaults to assets + QuillSharedExtensionsConfigurations.key: + QuillSharedExtensionsConfigurations( + assetsPrefix: 'your-assets-folder-name', // Defaults to `assets` ), }, ), - ) + ), +); ``` This info is needed by the package to check if it asset image to use the `AssetImage` provider 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 0fc025eaf..ecdefe2d7 100644 --- a/flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart +++ b/flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart @@ -41,18 +41,19 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { final height = imageSize.height; final image = getImageWidgetByImageSource( + context: context, imageSource, imageProviderBuilder: configurations.imageProviderBuilder, imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder, alignment: alignment, height: height, width: width, - assetsPrefix: QuillEditorExtensionsConfigurations.get(context: context) + assetsPrefix: QuillSharedExtensionsConfigurations.get(context: context) .assetsPrefix, ); final imageSaverService = - QuillEditorExtensionsConfigurations.get(context: context) + QuillSharedExtensionsConfigurations.get(context: context) .imageSaverService; return GestureDetector( onTap: configurations.onImageClicked ?? diff --git a/flutter_quill_extensions/lib/embeds/image/editor/image_embed_types.dart b/flutter_quill_extensions/lib/embeds/image/editor/image_embed_types.dart index 44d2dfaa1..c25036755 100644 --- a/flutter_quill_extensions/lib/embeds/image/editor/image_embed_types.dart +++ b/flutter_quill_extensions/lib/embeds/image/editor/image_embed_types.dart @@ -76,6 +76,7 @@ typedef ImageEmbedBuilderOnRemovedCallback = Future Function( ); typedef ImageEmbedBuilderProviderBuilder = ImageProvider Function( + BuildContext context, String imageUrl, ); 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 a7d57cb37..bc1e1414b 100644 --- a/flutter_quill_extensions/lib/embeds/image/editor/image_menu.dart +++ b/flutter_quill_extensions/lib/embeds/image/editor/image_menu.dart @@ -184,7 +184,7 @@ class ImageOptionsMenu extends StatelessWidget { MaterialPageRoute( builder: (_) => ImageTapWrapper( assetsPrefix: - QuillEditorExtensionsConfigurations.get(context: context) + QuillSharedExtensionsConfigurations.get(context: context) .assetsPrefix, imageUrl: imageSource, configurations: configurations, 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 5baeecdde..f943dabd4 100644 --- a/flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart +++ b/flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart @@ -116,7 +116,7 @@ class QuillToolbarImageButton extends StatelessWidget { Future _onPressedHandler(BuildContext context) async { final imagePickerService = - QuillEditorExtensionsConfigurations.get(context: context) + QuillSharedExtensionsConfigurations.get(context: context) .imagePickerService; final onRequestPickImage = diff --git a/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart b/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart index 74cbee389..ef7ad3da5 100644 --- a/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart +++ b/flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart @@ -132,7 +132,7 @@ class QuillToolbarCameraButton extends StatelessWidget { QuillController controller, ) async { final imagePickerService = - QuillEditorExtensionsConfigurations.get(context: context) + QuillSharedExtensionsConfigurations.get(context: context) .imagePickerService; final cameraAction = await _getCameraAction(context); 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 c2093c940..748759784 100644 --- a/flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart +++ b/flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart @@ -115,7 +115,7 @@ class QuillToolbarVideoButton extends StatelessWidget { Future _onPressedHandler(BuildContext context) async { final imagePickerService = - QuillEditorExtensionsConfigurations.get(context: context) + QuillSharedExtensionsConfigurations.get(context: context) .imagePickerService; final onRequestPickVideo = options.videoConfigurations.onRequestPickVideo; diff --git a/flutter_quill_extensions/lib/embeds/widgets/image.dart b/flutter_quill_extensions/lib/embeds/widgets/image.dart index 03168b60f..c2d4f240b 100644 --- a/flutter_quill_extensions/lib/embeds/widgets/image.dart +++ b/flutter_quill_extensions/lib/embeds/widgets/image.dart @@ -36,9 +36,10 @@ ImageProvider getImageProviderByImageSource( String imageSource, { required ImageEmbedBuilderProviderBuilder? imageProviderBuilder, required String assetsPrefix, + required BuildContext context, }) { if (imageProviderBuilder != null) { - return imageProviderBuilder(imageSource); + return imageProviderBuilder(context, imageSource); } if (isImageBase64(imageSource)) { @@ -57,6 +58,7 @@ ImageProvider getImageProviderByImageSource( Image getImageWidgetByImageSource( String imageSource, { + required BuildContext context, required ImageEmbedBuilderProviderBuilder? imageProviderBuilder, required ImageErrorWidgetBuilder? imageErrorWidgetBuilder, required String assetsPrefix, @@ -66,6 +68,7 @@ Image getImageWidgetByImageSource( }) { return Image( image: getImageProviderByImageSource( + context: context, imageSource, imageProviderBuilder: imageProviderBuilder, assetsPrefix: assetsPrefix, @@ -126,6 +129,7 @@ class ImageTapWrapper extends StatelessWidget { children: [ PhotoView( imageProvider: getImageProviderByImageSource( + context: context, imageUrl, imageProviderBuilder: configurations.imageProviderBuilder, assetsPrefix: assetsPrefix, diff --git a/flutter_quill_extensions/lib/models/config/shared_configurations.dart b/flutter_quill_extensions/lib/models/config/shared_configurations.dart index 381d0160b..402260b81 100644 --- a/flutter_quill_extensions/lib/models/config/shared_configurations.dart +++ b/flutter_quill_extensions/lib/models/config/shared_configurations.dart @@ -5,10 +5,11 @@ 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 Editor Extensions +/// Configurations for Flutter Editor Extensions +/// shared between toolbar and editor @immutable -class QuillEditorExtensionsConfigurations { - const QuillEditorExtensionsConfigurations({ +class QuillSharedExtensionsConfigurations { + const QuillSharedExtensionsConfigurations({ ImagePickerService? imagePickerService, ImageSaverService? imageSaverService, this.assetsPrefix = 'assets', @@ -17,12 +18,12 @@ class QuillEditorExtensionsConfigurations { /// Get the instance from the widget tree in [QuillSharedConfigurations] /// if it doesn't exists, we will create new one with default options - factory QuillEditorExtensionsConfigurations.get({ + factory QuillSharedExtensionsConfigurations.get({ required BuildContext context, }) { - final value = context.quillEditorConfigurations?.extraConfigurations[key]; + final value = context.quillSharedConfigurations?.extraConfigurations[key]; if (value != null) { - if (value is! QuillEditorExtensionsConfigurations) { + if (value is! QuillSharedExtensionsConfigurations) { throw ArgumentError( 'The value of key `$key` should be of type ' '$key', @@ -30,7 +31,7 @@ class QuillEditorExtensionsConfigurations { } return value; } - return const QuillEditorExtensionsConfigurations(); + return const QuillSharedExtensionsConfigurations(); } /// The key to be used in the `extraConfigurations` property @@ -38,7 +39,7 @@ class QuillEditorExtensionsConfigurations { /// which lives in the [QuillConfigurations] /// /// which exists in the [QuillEditorConfigurations] - static const String key = 'QuillEditorExtensionsConfigurations'; + static const String key = 'QuillSharedExtensionsConfigurations'; /// Defaults to [ImagePickerService.defaultImpl] final ImagePickerService? _imagePickerService; diff --git a/lib/src/models/config/editor/editor_configurations.dart b/lib/src/models/config/editor/editor_configurations.dart index 97904f660..b96886c31 100644 --- a/lib/src/models/config/editor/editor_configurations.dart +++ b/lib/src/models/config/editor/editor_configurations.dart @@ -75,14 +75,10 @@ class QuillEditorConfigurations extends Equatable { this.builder, this.magnifierConfiguration, this.textInputAction = TextInputAction.newline, - this.extraConfigurations = const {}, }); final QuillSharedConfigurations sharedConfigurations; - /// Store custom configurations in here and use it in the widget tree - final Map extraConfigurations; - final QuillController controller; /// The text placeholder in the quill editor @@ -343,7 +339,6 @@ class QuillEditorConfigurations extends Equatable { QuillEditorConfigurations copyWith({ QuillSharedConfigurations? sharedConfigurations, - Map? extraConfigurations, QuillController? controller, String? placeholder, bool? readOnly, @@ -391,7 +386,6 @@ class QuillEditorConfigurations extends Equatable { }) { return QuillEditorConfigurations( sharedConfigurations: sharedConfigurations ?? this.sharedConfigurations, - extraConfigurations: extraConfigurations ?? this.extraConfigurations, controller: controller ?? this.controller, placeholder: placeholder ?? this.placeholder, readOnly: readOnly ?? this.readOnly, diff --git a/lib/src/models/config/quill_shared_configurations.dart b/lib/src/models/config/quill_shared_configurations.dart index 8bf224dab..beadc4327 100644 --- a/lib/src/models/config/quill_shared_configurations.dart +++ b/lib/src/models/config/quill_shared_configurations.dart @@ -15,6 +15,7 @@ class QuillSharedConfigurations extends Equatable { this.dialogBarrierColor = Colors.black54, this.dialogTheme, this.locale, + this.extraConfigurations = const {}, }); // This is just example or showcase of this major update to make the library @@ -33,6 +34,9 @@ class QuillSharedConfigurations extends Equatable { /// `MaterialApp` or `WidgetsApp` final Locale? locale; + /// Store custom configurations in here and use it in the widget tree + final Map extraConfigurations; + @override List get props => [ dialogBarrierColor, From 3be21fbac91b4dc880767c3ae845ad98bdb8c9d0 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 6 Dec 2023 21:09:20 +0300 Subject: [PATCH 46/86] Prepare dev version 6 --- CHANGELOG.md | 1 + .../lib/presentation/quill/quill_screen.dart | 13 +++++++++++++ flutter_quill_extensions/CHANGELOG.md | 7 +++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 7 +++++++ flutter_quill_test/pubspec.yaml | 2 +- .../extensions/quill_configurations_ext.dart | 12 ++++++------ .../models/config/editor/element_options.dart | 9 +++++++++ .../editor/elements/list/ordered_list.dart | 14 ++++++++++++++ .../editor/elements/list/unordered_list.dart | 14 ++++++++++++++ .../toolbar/buttons/indent_configurations.dart | 3 ++- .../widgets/style_widgets/bullet_point.dart | 10 +++++++++- .../widgets/style_widgets/number_point.dart | 9 ++++++++- .../buttons/select_header_style_button.dart | 1 + .../toolbar/buttons/toggle_style_button.dart | 10 +++++----- lib/src/widgets/utils/provider.dart | 18 +++++++++--------- packages/quill_html_converter/CHANGELOG.md | 7 +++++++ packages/quill_html_converter/pubspec.yaml | 2 +- pubspec.yaml | 2 +- version.dart | 2 +- 20 files changed, 117 insertions(+), 28 deletions(-) create mode 100644 lib/src/models/config/editor/elements/list/ordered_list.dart create mode 100644 lib/src/models/config/editor/elements/list/unordered_list.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index a07d0fde8..4102bf777 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ## 9.0.0-dev-6 * Move the `child` from `QuillToolbarConfigurations` into `QuillToolbar` directly * Bug fixes +* Add the ability to change the background and font color of the ol/ul elements dots and numbers * Flutter Quill Extensions: * **Breaking Change**: The `imageProviderBuilder`is now providing the context and image url diff --git a/example/lib/presentation/quill/quill_screen.dart b/example/lib/presentation/quill/quill_screen.dart index 0cf6eea0b..e032cb446 100644 --- a/example/lib/presentation/quill/quill_screen.dart +++ b/example/lib/presentation/quill/quill_screen.dart @@ -115,6 +115,19 @@ class _QuillScreenState extends State { sharedConfigurations: _sharedConfigurations, controller: _controller, readOnly: _isReadOnly, + elementOptions: const QuillEditorElementOptions( + codeBlock: QuillEditorCodeBlockElementOptions( + enableLineNumbers: true, + ), + // orderedList: QuillEditorOrderedListElementOptions( + // backgroundColor: Colors.amber, + // fontColor: Colors.black, + // ), + // unorderedList: QuillEditorUnOrderedListElementOptions( + // backgroundColor: Colors.green, + // fontColor: Colors.red, + // ), + ), ), scrollController: _editorScrollController, focusNode: _editorFocusNode, diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 14612cdd2..4102bf777 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-6 +* Move the `child` from `QuillToolbarConfigurations` into `QuillToolbar` directly +* Bug fixes +* Add the ability to change the background and font color of the ol/ul elements dots and numbers +* Flutter Quill Extensions: + * **Breaking Change**: The `imageProviderBuilder`is now providing the context and image url + ## 9.0.0-dev-5 * The `QuillToolbar` is now accepting only `child` with no configurations so you can customize everything you wants, the `QuillToolbar.simple()` or `QuillSimpleToolbar` implements a simple toolbar that is based on `QuillToolbar`, you are free to use it but it just an example and not standard * Flutter Quill Extensions: diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 9d96edaf0..c80463aa3 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: 9.0.0-dev-5 +version: 9.0.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/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 14612cdd2..4102bf777 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-6 +* Move the `child` from `QuillToolbarConfigurations` into `QuillToolbar` directly +* Bug fixes +* Add the ability to change the background and font color of the ol/ul elements dots and numbers +* Flutter Quill Extensions: + * **Breaking Change**: The `imageProviderBuilder`is now providing the context and image url + ## 9.0.0-dev-5 * The `QuillToolbar` is now accepting only `child` with no configurations so you can customize everything you wants, the `QuillToolbar.simple()` or `QuillSimpleToolbar` implements a simple toolbar that is based on `QuillToolbar`, you are free to use it but it just an example and not standard * Flutter Quill Extensions: diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 2283a901b..e936801db 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: 9.0.0-dev-5 +version: 9.0.0-dev-6 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/lib/src/extensions/quill_configurations_ext.dart b/lib/src/extensions/quill_configurations_ext.dart index a7da7df35..5ca2e5e17 100644 --- a/lib/src/extensions/quill_configurations_ext.dart +++ b/lib/src/extensions/quill_configurations_ext.dart @@ -29,12 +29,12 @@ extension QuillSharedExt on BuildContext { extension QuillEditorExt on BuildContext { /// return [QuillEditorConfigurations] as not null QuillEditorConfigurations get requireQuillEditorConfigurations { - return QuillEditorProvider.ofNotNull(this).editorConfigurations; + return QuillEditorProvider.of(this).editorConfigurations; } /// return nullable [QuillEditorConfigurations] QuillEditorConfigurations? get quillEditorConfigurations { - return QuillEditorProvider.of(this)?.editorConfigurations; + return QuillEditorProvider.maybeOf(this)?.editorConfigurations; } /// return nullable [QuillToolbarBaseButtonOptions]. Since the quill @@ -57,12 +57,12 @@ extension QuillEditorExt on BuildContext { extension QuillSimpleToolbarExt on BuildContext { /// return [QuillSimpleToolbarConfigurations] as not null QuillSimpleToolbarConfigurations get requireQuillSimpleToolbarConfigurations { - return QuillSimpleToolbarProvider.ofNotNull(this).toolbarConfigurations; + return QuillSimpleToolbarProvider.of(this).toolbarConfigurations; } /// return nullable [QuillSimpleToolbarConfigurations] QuillSimpleToolbarConfigurations? get quillSimpleToolbarConfigurations { - return QuillSimpleToolbarProvider.of(this)?.toolbarConfigurations; + return QuillSimpleToolbarProvider.maybeOf(this)?.toolbarConfigurations; } /// return nullable [QuillToolbarBaseButtonOptions]. @@ -83,11 +83,11 @@ extension QuillSimpleToolbarExt on BuildContext { extension QuillToolbarExt on BuildContext { /// return [QuillToolbarConfigurations] as not null QuillToolbarConfigurations get requireQuillToolbarConfigurations { - return QuillToolbarProvider.ofNotNull(this).toolbarConfigurations; + return QuillToolbarProvider.of(this).toolbarConfigurations; } /// return nullable [QuillToolbarConfigurations]. QuillToolbarConfigurations? get quillToolbarConfigurations { - return QuillToolbarProvider.of(this)?.toolbarConfigurations; + return QuillToolbarProvider.maybeOf(this)?.toolbarConfigurations; } } diff --git a/lib/src/models/config/editor/element_options.dart b/lib/src/models/config/editor/element_options.dart index a2c20171e..f083f692e 100644 --- a/lib/src/models/config/editor/element_options.dart +++ b/lib/src/models/config/editor/element_options.dart @@ -2,16 +2,25 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show immutable; import 'elements/code_block.dart'; +import 'elements/list/ordered_list.dart'; +import 'elements/list/unordered_list.dart'; export 'elements/code_block.dart'; +export 'elements/list/ordered_list.dart'; +export 'elements/list/unordered_list.dart'; @immutable class QuillEditorElementOptions extends Equatable { const QuillEditorElementOptions({ this.codeBlock = const QuillEditorCodeBlockElementOptions(), + this.orderedList = const QuillEditorOrderedListElementOptions(), + this.unorderedList = const QuillEditorUnOrderedListElementOptions(), }); final QuillEditorCodeBlockElementOptions codeBlock; + + final QuillEditorOrderedListElementOptions orderedList; + final QuillEditorUnOrderedListElementOptions unorderedList; @override List get props => [ codeBlock, diff --git a/lib/src/models/config/editor/elements/list/ordered_list.dart b/lib/src/models/config/editor/elements/list/ordered_list.dart new file mode 100644 index 000000000..b48252991 --- /dev/null +++ b/lib/src/models/config/editor/elements/list/ordered_list.dart @@ -0,0 +1,14 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/foundation.dart' show immutable; +import 'package:flutter/widgets.dart' show Color; + +@immutable +class QuillEditorOrderedListElementOptions extends Equatable { + const QuillEditorOrderedListElementOptions( + {this.backgroundColor, this.fontColor}); + + final Color? backgroundColor; + final Color? fontColor; + @override + List get props => []; +} diff --git a/lib/src/models/config/editor/elements/list/unordered_list.dart b/lib/src/models/config/editor/elements/list/unordered_list.dart new file mode 100644 index 000000000..3fe570eb2 --- /dev/null +++ b/lib/src/models/config/editor/elements/list/unordered_list.dart @@ -0,0 +1,14 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/foundation.dart' show immutable; +import 'package:flutter/widgets.dart' show Color; + +@immutable +class QuillEditorUnOrderedListElementOptions extends Equatable { + const QuillEditorUnOrderedListElementOptions( + {this.backgroundColor, this.fontColor}); + + final Color? backgroundColor; + final Color? fontColor; + @override + List get props => []; +} diff --git a/lib/src/models/config/toolbar/buttons/indent_configurations.dart b/lib/src/models/config/toolbar/buttons/indent_configurations.dart index 4328796ad..559217e7b 100644 --- a/lib/src/models/config/toolbar/buttons/indent_configurations.dart +++ b/lib/src/models/config/toolbar/buttons/indent_configurations.dart @@ -12,7 +12,8 @@ class QuillToolbarIndentButtonExtraOptions } @immutable -class QuillToolbarIndentButtonOptions extends QuillToolbarBaseButtonOptions { +class QuillToolbarIndentButtonOptions extends QuillToolbarBaseButtonOptions< + QuillToolbarIndentButtonOptions, QuillToolbarIndentButtonExtraOptions> { const QuillToolbarIndentButtonOptions({ super.iconData, super.afterButtonPressed, diff --git a/lib/src/widgets/style_widgets/bullet_point.dart b/lib/src/widgets/style_widgets/bullet_point.dart index 1dd1b4cf5..629c68e6d 100644 --- a/lib/src/widgets/style_widgets/bullet_point.dart +++ b/lib/src/widgets/style_widgets/bullet_point.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import '../../extensions/quill_configurations_ext.dart'; + class QuillEditorBulletPoint extends StatelessWidget { const QuillEditorBulletPoint({ required this.style, @@ -18,7 +20,13 @@ class QuillEditorBulletPoint extends StatelessWidget { alignment: AlignmentDirectional.topEnd, width: width, padding: EdgeInsetsDirectional.only(end: padding), - child: Text('•', style: style), + color: context.quillEditorElementOptions?.unorderedList.backgroundColor, + child: Text( + '•', + style: style.copyWith( + color: context.quillEditorElementOptions?.unorderedList.fontColor, + ), + ), ); } } diff --git a/lib/src/widgets/style_widgets/number_point.dart b/lib/src/widgets/style_widgets/number_point.dart index 9809f4ac7..307a8ebe2 100644 --- a/lib/src/widgets/style_widgets/number_point.dart +++ b/lib/src/widgets/style_widgets/number_point.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import '../../extensions/quill_configurations_ext.dart'; import '../../models/documents/attribute.dart'; import '../others/text_block.dart'; @@ -67,7 +68,13 @@ class QuillEditorNumberPoint extends StatelessWidget { alignment: AlignmentDirectional.topEnd, width: width, padding: EdgeInsetsDirectional.only(end: padding), - child: Text(withDot ? '$s.' : s, style: style), + color: context.quillEditorElementOptions?.orderedList.backgroundColor, + child: Text( + withDot ? '$s.' : s, + style: style.copyWith( + color: context.quillEditorElementOptions?.orderedList.fontColor, + ), + ), ); } diff --git a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart index 59f66d8d7..189146a8e 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart @@ -20,6 +20,7 @@ class QuillToolbarSelectHeaderStyleButton extends StatefulWidget { }); final QuillController controller; + // TODO: Needs to be reviewed final QuillToolbarSelectHeaderStyleButtonsOptions options; @override diff --git a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart index 2ea43f97b..345f339d9 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart @@ -76,12 +76,12 @@ class QuillToolbarToggleStyleButtonState VoidCallback? get afterButtonPressed { return options.afterButtonPressed ?? - context.requireQuillToolbarBaseButtonOptions.afterButtonPressed; + context.quillToolbarBaseButtonOptions?.afterButtonPressed; } QuillIconTheme? get iconTheme { return options.iconTheme ?? - context.requireQuillToolbarBaseButtonOptions.iconTheme; + context.quillToolbarBaseButtonOptions?.iconTheme; } (String, IconData) get _defaultTooltipAndIconData { @@ -132,13 +132,13 @@ class QuillToolbarToggleStyleButtonState String? get tooltip { return options.tooltip ?? - context.requireQuillToolbarBaseButtonOptions.tooltip ?? + context.quillToolbarBaseButtonOptions?.tooltip ?? _defaultTooltipAndIconData.$1; } IconData get iconData { return options.iconData ?? - context.requireQuillToolbarBaseButtonOptions.iconData ?? + context.quillToolbarBaseButtonOptions?.iconData ?? _defaultTooltipAndIconData.$2; } @@ -150,7 +150,7 @@ class QuillToolbarToggleStyleButtonState @override Widget build(BuildContext context) { final childBuilder = options.childBuilder ?? - context.requireQuillToolbarBaseButtonOptions.childBuilder; + context.quillToolbarBaseButtonOptions?.childBuilder; if (childBuilder != null) { return childBuilder( QuillToolbarToggleStyleButtonOptions( diff --git a/lib/src/widgets/utils/provider.dart b/lib/src/widgets/utils/provider.dart index 57f9cf15f..c0d40e73a 100644 --- a/lib/src/widgets/utils/provider.dart +++ b/lib/src/widgets/utils/provider.dart @@ -20,14 +20,14 @@ class QuillSimpleToolbarProvider extends InheritedWidget { return oldWidget.toolbarConfigurations != toolbarConfigurations; } - static QuillSimpleToolbarProvider? of(BuildContext context) { + static QuillSimpleToolbarProvider? maybeOf(BuildContext context) { /// The configurations for the quill editor widget of flutter quill return context .dependOnInheritedWidgetOfExactType(); } - static QuillSimpleToolbarProvider ofNotNull(BuildContext context) { - final provider = of(context); + static QuillSimpleToolbarProvider of(BuildContext context) { + final provider = maybeOf(context); if (provider == null) { if (kDebugMode) { debugPrint( @@ -79,13 +79,13 @@ class QuillToolbarProvider extends InheritedWidget { return oldWidget.toolbarConfigurations != toolbarConfigurations; } - static QuillToolbarProvider? of(BuildContext context) { + static QuillToolbarProvider? maybeOf(BuildContext context) { /// The configurations for the quill editor widget of flutter quill return context.dependOnInheritedWidgetOfExactType(); } - static QuillToolbarProvider ofNotNull(BuildContext context) { - final provider = of(context); + static QuillToolbarProvider of(BuildContext context) { + final provider = maybeOf(context); if (provider == null) { if (kDebugMode) { debugPrint( @@ -136,13 +136,13 @@ class QuillEditorProvider extends InheritedWidget { return oldWidget.editorConfigurations != editorConfigurations; } - static QuillEditorProvider? of(BuildContext context) { + static QuillEditorProvider? maybeOf(BuildContext context) { /// The configurations for the quill editor widget of flutter quill return context.dependOnInheritedWidgetOfExactType(); } - static QuillEditorProvider ofNotNull(BuildContext context) { - final provider = of(context); + static QuillEditorProvider of(BuildContext context) { + final provider = maybeOf(context); if (provider == null) { if (kDebugMode) { debugPrint( diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index 14612cdd2..4102bf777 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-6 +* Move the `child` from `QuillToolbarConfigurations` into `QuillToolbar` directly +* Bug fixes +* Add the ability to change the background and font color of the ol/ul elements dots and numbers +* Flutter Quill Extensions: + * **Breaking Change**: The `imageProviderBuilder`is now providing the context and image url + ## 9.0.0-dev-5 * The `QuillToolbar` is now accepting only `child` with no configurations so you can customize everything you wants, the `QuillToolbar.simple()` or `QuillSimpleToolbar` implements a simple toolbar that is based on `QuillToolbar`, you are free to use it but it just an example and not standard * Flutter Quill Extensions: diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index dd996a3f8..4f5d6e553 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.0.0-dev-5 +version: 9.0.0-dev-6 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index a57fa2262..9f99953bc 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: 9.0.0-dev-5 +version: 9.0.0-dev-6 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/version.dart b/version.dart index 5b59c4d6b..123f4db07 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev-5'; +const version = '9.0.0-dev-6'; From 6066f2f7144622319d57e3fa975f9a59dfce7877 Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 7 Dec 2023 13:54:29 +0300 Subject: [PATCH 47/86] Link pattern bug fixes --- CHANGELOG.md | 6 ++++ .../lib/presentation/quill/quill_screen.dart | 16 ++++----- .../lib/embeds/others/image_video_utils.dart | 36 +++++++++++++------ .../lib/utils/patterns.dart | 17 +++++++++ flutter_quill_extensions/lib/utils/utils.dart | 7 ++-- .../widgets/style_widgets/number_point.dart | 8 ++++- version.dart | 2 +- 7 files changed, 66 insertions(+), 26 deletions(-) create mode 100644 flutter_quill_extensions/lib/utils/patterns.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 4102bf777..b52dd226b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-7 +* Fix a bug in chaning the background/font color of ol/ul list +* Flutter Quill Extensions: + * Fix link bug in the video url + * Fix patterns + ## 9.0.0-dev-6 * Move the `child` from `QuillToolbarConfigurations` into `QuillToolbar` directly * Bug fixes diff --git a/example/lib/presentation/quill/quill_screen.dart b/example/lib/presentation/quill/quill_screen.dart index e032cb446..712a334ab 100644 --- a/example/lib/presentation/quill/quill_screen.dart +++ b/example/lib/presentation/quill/quill_screen.dart @@ -119,14 +119,14 @@ class _QuillScreenState extends State { codeBlock: QuillEditorCodeBlockElementOptions( enableLineNumbers: true, ), - // orderedList: QuillEditorOrderedListElementOptions( - // backgroundColor: Colors.amber, - // fontColor: Colors.black, - // ), - // unorderedList: QuillEditorUnOrderedListElementOptions( - // backgroundColor: Colors.green, - // fontColor: Colors.red, - // ), + orderedList: QuillEditorOrderedListElementOptions( + backgroundColor: Colors.amber, + fontColor: Colors.black, + ), + unorderedList: QuillEditorUnOrderedListElementOptions( + backgroundColor: Colors.green, + fontColor: Colors.red, + ), ), ), scrollController: _editorScrollController, diff --git a/flutter_quill_extensions/lib/embeds/others/image_video_utils.dart b/flutter_quill_extensions/lib/embeds/others/image_video_utils.dart index 03514f1b3..808f7517f 100644 --- a/flutter_quill_extensions/lib/embeds/others/image_video_utils.dart +++ b/flutter_quill_extensions/lib/embeds/others/image_video_utils.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart' show QuillDialogTheme; import 'package:flutter_quill/translations.dart'; +import '../../utils/patterns.dart'; + enum LinkType { video, image, @@ -28,7 +30,7 @@ class TypeLinkDialog extends StatefulWidget { class TypeLinkDialogState extends State { late String _link; late TextEditingController _controller; - late RegExp _linkRegExp; + RegExp? _linkRegExp; @override void initState() { @@ -36,15 +38,7 @@ class TypeLinkDialogState extends State { _link = widget.link ?? ''; _controller = TextEditingController(text: _link); - final defaultLinkNonSecureRegExp = RegExp( - r'https?://.*?\.(?:png|jpe?g|gif|bmp|webp|tiff?)', - caseSensitive: false, - ); // Not secure - // final defaultLinkRegExp = RegExp( - // r'https://.*?\.(?:png|jpe?g|gif|bmp|webp|tiff?)', - // caseSensitive: false, - // ); // Secure - _linkRegExp = widget.linkRegExp ?? defaultLinkNonSecureRegExp; + _linkRegExp = widget.linkRegExp; } @override @@ -102,8 +96,28 @@ class TypeLinkDialogState extends State { Navigator.pop(context, _link.trim()); } + RegExp get linkRegExp { + final customRegExp = _linkRegExp; + if (customRegExp != null) { + return customRegExp; + } + switch (widget.linkType) { + case LinkType.video: + if (youtubeRegExp.hasMatch(_link)) { + return youtubeRegExp; + } + return videoRegExp; + case LinkType.image: + return imageRegExp; + } + } + bool _canPress() { - return _link.isNotEmpty && _linkRegExp.hasMatch(_link); + if (_link.isEmpty) { + return false; + } + if (widget.linkType == LinkType.image) {} + return _link.isNotEmpty && linkRegExp.hasMatch(_link); } } diff --git a/flutter_quill_extensions/lib/utils/patterns.dart b/flutter_quill_extensions/lib/utils/patterns.dart new file mode 100644 index 000000000..53c1650d6 --- /dev/null +++ b/flutter_quill_extensions/lib/utils/patterns.dart @@ -0,0 +1,17 @@ +RegExp base64RegExp = RegExp( + r'^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$', +); + +final imageRegExp = RegExp( + r'https?://.*?\.(?:png|jpe?g|gif|bmp|webp|tiff?)', + caseSensitive: false, +); + +final videoRegExp = RegExp( + r'\bhttps?://\S+\.(mp4|mov|avi|mkv|flv|wmv|webm)\b', + caseSensitive: false, +); +final youtubeRegExp = RegExp( + r'^((?:https?:)?\/\/)?((?:www|m)\.)?((?:youtube(-nocookie)?\.com|youtu.be))(\/(?:[\w\-]+\?v=|embed\/|live\/|v\/)?)([\w\-]+)(\S+)?$', + caseSensitive: false, +); diff --git a/flutter_quill_extensions/lib/utils/utils.dart b/flutter_quill_extensions/lib/utils/utils.dart index fc620e9b7..37f5f0205 100644 --- a/flutter_quill_extensions/lib/utils/utils.dart +++ b/flutter_quill_extensions/lib/utils/utils.dart @@ -6,13 +6,10 @@ import 'package:http/http.dart' as http; import '../embeds/widgets/image.dart'; import '../services/image_saver/s_image_saver.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})$', -); +import 'patterns.dart'; bool isBase64(String str) { - return _base64.hasMatch(str); + return base64RegExp.hasMatch(str); } bool isHttpBasedUrl(String url) { diff --git a/lib/src/widgets/style_widgets/number_point.dart b/lib/src/widgets/style_widgets/number_point.dart index 307a8ebe2..398dd3945 100644 --- a/lib/src/widgets/style_widgets/number_point.dart +++ b/lib/src/widgets/style_widgets/number_point.dart @@ -37,7 +37,13 @@ class QuillEditorNumberPoint extends StatelessWidget { alignment: AlignmentDirectional.topEnd, width: width, padding: EdgeInsetsDirectional.only(end: padding), - child: Text(withDot ? '$s.' : s, style: style), + color: context.quillEditorElementOptions?.orderedList.backgroundColor, + child: Text( + withDot ? '$s.' : s, + style: style.copyWith( + color: context.quillEditorElementOptions?.orderedList.fontColor, + ), + ), ); } if (attrs.containsKey(Attribute.indent.key)) { diff --git a/version.dart b/version.dart index 123f4db07..78f02741d 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev-6'; +const version = '9.0.0-dev-7'; From 64ea5efc399260d671976a0e1136154ce1b52003 Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 7 Dec 2023 15:28:50 +0300 Subject: [PATCH 48/86] Prepare dev version 7 --- flutter_quill_extensions/CHANGELOG.md | 6 ++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 6 ++++++ flutter_quill_test/pubspec.yaml | 4 ++-- packages/quill_html_converter/CHANGELOG.md | 6 ++++++ packages/quill_html_converter/pubspec.yaml | 2 +- pubspec.yaml | 4 ++-- 7 files changed, 24 insertions(+), 6 deletions(-) diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 4102bf777..b52dd226b 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-7 +* Fix a bug in chaning the background/font color of ol/ul list +* Flutter Quill Extensions: + * Fix link bug in the video url + * Fix patterns + ## 9.0.0-dev-6 * Move the `child` from `QuillToolbarConfigurations` into `QuillToolbar` directly * Bug fixes diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index c80463aa3..ea0fcdd92 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: 9.0.0-dev-6 +version: 9.0.0-dev-7 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 4102bf777..b52dd226b 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-7 +* Fix a bug in chaning the background/font color of ol/ul list +* Flutter Quill Extensions: + * Fix link bug in the video url + * Fix patterns + ## 9.0.0-dev-6 * Move the `child` from `QuillToolbarConfigurations` into `QuillToolbar` directly * Bug fixes diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index e936801db..7e442cc7a 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: 9.0.0-dev-6 +version: 9.0.0-dev-7 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ @@ -28,7 +28,7 @@ environment: dependencies: flutter: sdk: flutter - flutter_quill: ^7.0.0 + flutter_quill: ^9.0.0-dev-6 flutter_test: sdk: flutter diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index 4102bf777..b52dd226b 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-7 +* Fix a bug in chaning the background/font color of ol/ul list +* Flutter Quill Extensions: + * Fix link bug in the video url + * Fix patterns + ## 9.0.0-dev-6 * Move the `child` from `QuillToolbarConfigurations` into `QuillToolbar` directly * Bug fixes diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index 4f5d6e553..1264fccb1 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.0.0-dev-6 +version: 9.0.0-dev-7 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 9f99953bc..e421ba8b8 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: 9.0.0-dev-6 +version: 9.0.0-dev-7 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ @@ -62,7 +62,7 @@ dev_dependencies: flutter_lints: ^3.0.1 flutter_test: sdk: flutter - flutter_quill_test: ^9.0.0-dev-2 + flutter_quill_test: ^9.0.0-dev-6 test: ^1.24.3 intl_translation: ^0.18.2 yaml_edit: ^2.1.1 From 5fcda94b59502d808d40ce353c631aa0b2d6873d Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 7 Dec 2023 20:35:52 +0300 Subject: [PATCH 49/86] 5 --- CHANGELOG.md | 2 + README.md | 8 +- doc/todo.md | 11 +- .../lib/presentation/quill/quill_screen.dart | 31 +- example/pubspec.yaml | 1 + flutter_quill_extensions/CHANGELOG.md | 2 + .../image/editor/image_embed_types.dart | 2 +- .../lib/embeds/video/video.dart | 2 +- .../{controller.dart => controller_ext.dart} | 0 .../lib/flutter_quill_extensions.dart | 2 +- flutter_quill_test/CHANGELOG.md | 2 + lib/flutter_quill.dart | 4 +- lib/markdown_quill.dart | 5 + .../config/editor/editor_configurations.dart | 4 +- .../raw_editor/raw_editor_configurations.dart | 2 +- .../toolbar/buttons/color_configurations.dart | 2 +- .../buttons/font_size_configurations.dart | 2 +- .../simple_toolbar_configurations.dart | 4 +- lib/src/models/documents/document.dart | 3 +- lib/src/models/documents/nodes/container.dart | 2 +- lib/src/models/documents/nodes/leaf.dart | 2 +- lib/src/models/documents/nodes/line.dart | 2 +- lib/src/models/documents/nodes/node.dart | 2 +- .../custom_quill_attributes.dart | 11 + .../quill_markdown/delta_to_markdown.dart | 359 +++++++++++++++ .../embeddable_table_syntax.dart | 116 +++++ .../quill_markdown/markdown_to_delta.dart | 424 ++++++++++++++++++ lib/src/packages/quill_markdown/utils.dart | 59 +++ lib/src/utils/embeds.dart | 2 +- lib/src/widgets/editor/editor.dart | 2 +- lib/src/widgets/others/delegate.dart | 2 +- lib/src/widgets/{others => quill}/embeds.dart | 2 +- .../quill_controller.dart} | 46 +- .../widgets/{others => quill}/text_block.dart | 14 +- .../widgets/{others => quill}/text_line.dart | 22 +- .../widgets/raw_editor/raw_editor_state.dart | 66 ++- .../widgets/style_widgets/number_point.dart | 2 +- .../toolbar/buttons/clear_format_button.dart | 2 +- .../toolbar/buttons/color/color_button.dart | 2 +- .../toolbar/buttons/custom_button_button.dart | 2 +- .../toolbar/buttons/font_family_button.dart | 2 +- .../toolbar/buttons/font_size_button.dart | 2 +- .../toolbar/buttons/history_button.dart | 2 +- .../toolbar/buttons/indent_button.dart | 2 +- .../toolbar/buttons/link_style2_button.dart | 2 +- .../toolbar/buttons/link_style_button.dart | 2 +- .../toolbar/buttons/search/search_button.dart | 2 +- .../toolbar/buttons/search/search_dialog.dart | 2 +- .../buttons/select_alignment_buttons.dart | 2 +- .../buttons/select_header_style_button.dart | 2 +- .../buttons/select_header_style_buttons.dart | 2 +- .../buttons/toggle_check_list_button.dart | 2 +- .../toolbar/buttons/toggle_style_button.dart | 2 +- packages/quill_html_converter/CHANGELOG.md | 2 + .../lib/quill_html_converter.dart | 32 -- packages/quill_html_converter/pubspec.yaml | 7 +- pubspec.yaml | 5 + 57 files changed, 1185 insertions(+), 117 deletions(-) rename flutter_quill_extensions/lib/extensions/{controller.dart => controller_ext.dart} (100%) create mode 100644 lib/markdown_quill.dart create mode 100644 lib/src/packages/quill_markdown/custom_quill_attributes.dart create mode 100644 lib/src/packages/quill_markdown/delta_to_markdown.dart create mode 100644 lib/src/packages/quill_markdown/embeddable_table_syntax.dart create mode 100644 lib/src/packages/quill_markdown/markdown_to_delta.dart create mode 100644 lib/src/packages/quill_markdown/utils.dart rename lib/src/widgets/{others => quill}/embeds.dart (96%) rename lib/src/widgets/{others/controller.dart => quill/quill_controller.dart} (90%) rename lib/src/widgets/{others => quill}/text_block.dart (98%) rename lib/src/widgets/{others => quill}/text_line.dart (99%) diff --git a/CHANGELOG.md b/CHANGELOG.md index b52dd226b..52b9aadd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. ## 9.0.0-dev-7 * Fix a bug in chaning the background/font color of ol/ul list +* Better support for pasting HTML contents from external websites to the editor +* The experimental support of converting the HTML from `quill_html_converter` is now built-in in the `flutter_quill` and removed from there (Breaking change for `quill_html_converter`) * Flutter Quill Extensions: * Fix link bug in the video url * Fix patterns diff --git a/README.md b/README.md index 058f5c8b2..750f7a74f 100644 --- a/README.md +++ b/README.md @@ -238,11 +238,13 @@ To see how to use the extension package, please take a look at the [README](./fl Having your document stored in Quill Delta format is sometimes not enough. Often you'll need to convert it to other formats such as HTML to publish it, or send an email. +**Note**: This package support converting from HTML back to Quill delta but it's experimental and used internally when pasting Html content from the cliboard to the Quill Editor + You have two options: -1. Using [quill_html_converter](./packages/quill_html_converter/) to convert to/from HTML, the package can convert the Quill delta to HTML well -(it uses [vsc_quill_delta_to_html](https://pub.dev/packages/vsc_quill_delta_to_html)) but the converting from HTML back to Quill delta is experimental -2. Another option is to use +1. Using [quill_html_converter](./packages/quill_html_converter/) to convert to HTML, the package can convert the Quill delta to HTML well +(it uses [vsc_quill_delta_to_html](https://pub.dev/packages/vsc_quill_delta_to_html)), it just a handy extension to do it more quickly +1. Another option is to use [vsc_quill_delta_to_html](https://pub.dev/packages/vsc_quill_delta_to_html) to convert your document to HTML. This package has full support for all Quill operations—including images, videos, formulas, diff --git a/doc/todo.md b/doc/todo.md index 4f38ed016..813a90669 100644 --- a/doc/todo.md +++ b/doc/todo.md @@ -29,6 +29,10 @@ This is a todo list page that added recently and will be updated soon. - Extract the shared properties between `QuillRawEditorConfigurations` and `QuillEditorConfigurations` - The todo in the this [commit](https://github.com/singerdmx/flutter-quill/commit/79597ea6425357795c0663588ac079665241f23a) needs to be checked - use `maybeOf` and of instead `ofNotNull` in the providers to follow flutter offical convenstion, completly rework the providers and update the build context extensions + - Add line through to the text when the check point checked is true + - Change the color of the numbers and dots in ol/ul to match the ones in the item list + - Fix the bugs of the font family and font size + - Try to update Quill Html Converter ### Bugs @@ -39,12 +43,7 @@ Please go to the [issues](https://github.com/singerdmx/flutter-quill/issues) ## Flutter Quill Extensions ### Features -- 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 +### Bugs \ No newline at end of file diff --git a/example/lib/presentation/quill/quill_screen.dart b/example/lib/presentation/quill/quill_screen.dart index 712a334ab..51908827e 100644 --- a/example/lib/presentation/quill/quill_screen.dart +++ b/example/lib/presentation/quill/quill_screen.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart' show FlutterQuillEmbeds, QuillSharedExtensionsConfigurations; - import 'package:quill_html_converter/quill_html_converter.dart'; import 'package:share_plus/share_plus.dart' show Share; @@ -46,6 +45,18 @@ class _QuillScreenState extends State { _controller.document = widget.args.document; } + // Future _init() async { + // final reader = await ClipboardReader.readClipboard(); + // if (reader.canProvide(Formats.htmlText)) { + // final html = await reader.readValue(Formats.htmlText); + // if (html == null) { + // return; + // } + // final delta = DeltaHtmlExt.fromHtml(html); + // _controller.document = Document.fromDelta(delta); + // } + // } + @override void dispose() { _controller.dispose(); @@ -65,7 +76,7 @@ class _QuillScreenState extends State { onPressed: () { final html = _controller.document.toDelta().toHtml(); _controller.document = - Document.fromDelta(DeltaHtmlExt.fromHtml(html)); + Document.fromDelta(QuillController.fromHtml(html)); }, icon: const Icon(Icons.html), ), @@ -119,14 +130,14 @@ class _QuillScreenState extends State { codeBlock: QuillEditorCodeBlockElementOptions( enableLineNumbers: true, ), - orderedList: QuillEditorOrderedListElementOptions( - backgroundColor: Colors.amber, - fontColor: Colors.black, - ), - unorderedList: QuillEditorUnOrderedListElementOptions( - backgroundColor: Colors.green, - fontColor: Colors.red, - ), + // orderedList: QuillEditorOrderedListElementOptions( + // backgroundColor: Colors.amber, + // fontColor: Colors.black, + // ), + // unorderedList: QuillEditorUnOrderedListElementOptions( + // backgroundColor: Colors.green, + // fontColor: Colors.red, + // ), ), ), scrollController: _editorScrollController, diff --git a/example/pubspec.yaml b/example/pubspec.yaml index bf3192add..b3d2e15c1 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -44,6 +44,7 @@ dependencies: file_picker: ^6.1.1 # For sharing text share_plus: ^7.2.1 + super_clipboard: ^0.7.3 dependency_overrides: flutter_quill: diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index b52dd226b..52b9aadd2 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. ## 9.0.0-dev-7 * Fix a bug in chaning the background/font color of ol/ul list +* Better support for pasting HTML contents from external websites to the editor +* The experimental support of converting the HTML from `quill_html_converter` is now built-in in the `flutter_quill` and removed from there (Breaking change for `quill_html_converter`) * Flutter Quill Extensions: * Fix link bug in the video url * Fix patterns diff --git a/flutter_quill_extensions/lib/embeds/image/editor/image_embed_types.dart b/flutter_quill_extensions/lib/embeds/image/editor/image_embed_types.dart index c25036755..e2036da14 100644 --- a/flutter_quill_extensions/lib/embeds/image/editor/image_embed_types.dart +++ b/flutter_quill_extensions/lib/embeds/image/editor/image_embed_types.dart @@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart' show BuildContext; import 'package:flutter_quill/flutter_quill.dart'; import 'package:meta/meta.dart' show immutable; -import '../../../extensions/controller.dart'; +import '../../../extensions/controller_ext.dart'; import '../../../services/image_picker/s_image_picker.dart'; /// When request picking an image, for example when the image button toolbar diff --git a/flutter_quill_extensions/lib/embeds/video/video.dart b/flutter_quill_extensions/lib/embeds/video/video.dart index b2e1ca24e..2acd4246c 100644 --- a/flutter_quill_extensions/lib/embeds/video/video.dart +++ b/flutter_quill_extensions/lib/embeds/video/video.dart @@ -2,7 +2,7 @@ import 'package:flutter/widgets.dart' show BuildContext; import 'package:flutter_quill/flutter_quill.dart'; import 'package:meta/meta.dart' show immutable; -import '../../extensions/controller.dart'; +import '../../extensions/controller_ext.dart'; import '../../services/image_picker/s_image_picker.dart'; /// When request picking an video, for example when the video button toolbar diff --git a/flutter_quill_extensions/lib/extensions/controller.dart b/flutter_quill_extensions/lib/extensions/controller_ext.dart similarity index 100% rename from flutter_quill_extensions/lib/extensions/controller.dart rename to flutter_quill_extensions/lib/extensions/controller_ext.dart diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index f63285547..d7492043c 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -36,7 +36,7 @@ export 'embeds/video/editor/video_embed.dart'; export 'embeds/video/editor/video_web_embed.dart'; export 'embeds/video/toolbar/video_button.dart'; export 'embeds/video/video.dart'; -export 'extensions/controller.dart'; +export 'extensions/controller_ext.dart'; export 'models/config/editor/image/image.dart'; export 'models/config/editor/image/image_web.dart'; export 'models/config/editor/video/video.dart'; diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index b52dd226b..52b9aadd2 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. ## 9.0.0-dev-7 * Fix a bug in chaning the background/font color of ol/ul list +* Better support for pasting HTML contents from external websites to the editor +* The experimental support of converting the HTML from `quill_html_converter` is now built-in in the `flutter_quill` and removed from there (Breaking change for `quill_html_converter`) * Flutter Quill Extensions: * Fix link bug in the video url * Fix patterns diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index 54f4eaec2..15e58183e 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -23,10 +23,10 @@ export 'src/models/themes/quill_dialog_theme.dart'; export 'src/models/themes/quill_icon_theme.dart'; export 'src/utils/embeds.dart'; export 'src/widgets/editor/editor.dart'; -export 'src/widgets/others/controller.dart'; +export 'src/widgets/quill/quill_controller.dart'; export 'src/widgets/others/cursor.dart'; export 'src/widgets/others/default_styles.dart'; -export 'src/widgets/others/embeds.dart'; +export 'src/widgets/quill/embeds.dart'; export 'src/widgets/others/link.dart' show LinkActionPickerDelegate, LinkMenuAction; export 'src/widgets/raw_editor/raw_editor.dart'; diff --git a/lib/markdown_quill.dart b/lib/markdown_quill.dart new file mode 100644 index 000000000..cca0aa1c9 --- /dev/null +++ b/lib/markdown_quill.dart @@ -0,0 +1,5 @@ +library quill_markdown; + +export 'src/packages/quill_markdown/delta_to_markdown.dart'; +export 'src/packages/quill_markdown/embeddable_table_syntax.dart'; +export 'src/packages/quill_markdown/markdown_to_delta.dart'; diff --git a/lib/src/models/config/editor/editor_configurations.dart b/lib/src/models/config/editor/editor_configurations.dart index b96886c31..029f5a48d 100644 --- a/lib/src/models/config/editor/editor_configurations.dart +++ b/lib/src/models/config/editor/editor_configurations.dart @@ -7,10 +7,10 @@ import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart' show experimental; import '../../../widgets/editor/editor_builder.dart'; -import '../../../widgets/others/controller.dart'; +import '../../../widgets/quill/quill_controller.dart'; import '../../../widgets/others/default_styles.dart'; import '../../../widgets/others/delegate.dart'; -import '../../../widgets/others/embeds.dart'; +import '../../../widgets/quill/embeds.dart'; import '../../../widgets/others/link.dart'; import '../../../widgets/raw_editor/raw_editor.dart'; import '../../themes/quill_dialog_theme.dart'; diff --git a/lib/src/models/config/raw_editor/raw_editor_configurations.dart b/lib/src/models/config/raw_editor/raw_editor_configurations.dart index 1ddb9973b..03744e9e4 100644 --- a/lib/src/models/config/raw_editor/raw_editor_configurations.dart +++ b/lib/src/models/config/raw_editor/raw_editor_configurations.dart @@ -25,7 +25,7 @@ import 'package:flutter/widgets.dart' Widget; import 'package:meta/meta.dart' show immutable; -import '../../../widgets/others/controller.dart'; +import '../../../widgets/quill/quill_controller.dart'; import '../../../widgets/others/cursor.dart'; import '../../../widgets/others/default_styles.dart'; import '../../../widgets/others/delegate.dart'; diff --git a/lib/src/models/config/toolbar/buttons/color_configurations.dart b/lib/src/models/config/toolbar/buttons/color_configurations.dart index 04e45451c..b3c08c251 100644 --- a/lib/src/models/config/toolbar/buttons/color_configurations.dart +++ b/lib/src/models/config/toolbar/buttons/color_configurations.dart @@ -1,6 +1,6 @@ import 'package:flutter/widgets.dart' show Color; -import '../../../../widgets/others/controller.dart'; +import '../../../../widgets/quill/quill_controller.dart'; import '../../quill_shared_configurations.dart' show QuillSharedConfigurations; import 'base_configurations.dart'; diff --git a/lib/src/models/config/toolbar/buttons/font_size_configurations.dart b/lib/src/models/config/toolbar/buttons/font_size_configurations.dart index 5cebf9f6d..ec3c66825 100644 --- a/lib/src/models/config/toolbar/buttons/font_size_configurations.dart +++ b/lib/src/models/config/toolbar/buttons/font_size_configurations.dart @@ -6,7 +6,7 @@ import 'package:flutter/material.dart' import 'package:flutter/widgets.dart' show Color, EdgeInsets, EdgeInsetsGeometry, TextOverflow, TextStyle; -import '../../../../widgets/others/controller.dart'; +import '../../../../widgets/quill/quill_controller.dart'; import '../../../documents/attribute.dart'; import '../../../themes/quill_icon_theme.dart'; import '../../quill_configurations.dart'; diff --git a/lib/src/models/config/toolbar/simple_toolbar_configurations.dart b/lib/src/models/config/toolbar/simple_toolbar_configurations.dart index 1ed627e95..300547360 100644 --- a/lib/src/models/config/toolbar/simple_toolbar_configurations.dart +++ b/lib/src/models/config/toolbar/simple_toolbar_configurations.dart @@ -4,8 +4,8 @@ import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' show Axis, Widget, WrapAlignment, WrapCrossAlignment; -import '../../../widgets/others/controller.dart'; -import '../../../widgets/others/embeds.dart'; +import '../../../widgets/quill/quill_controller.dart'; +import '../../../widgets/quill/embeds.dart'; import '../../themes/quill_dialog_theme.dart'; import '../../themes/quill_icon_theme.dart'; import 'buttons/base_configurations.dart'; diff --git a/lib/src/models/documents/document.dart b/lib/src/models/documents/document.dart index 1b4f96969..e0efbdf8e 100644 --- a/lib/src/models/documents/document.dart +++ b/lib/src/models/documents/document.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import '../../widgets/others/embeds.dart'; +import '../../widgets/quill/embeds.dart'; import '../quill_delta.dart'; import '../rules/rule.dart'; import '../structs/doc_change.dart'; @@ -402,6 +402,7 @@ class Document { throw ArgumentError.value(doc, 'Document Delta cannot be empty.'); } + // print(doc.last.data.runtimeType); assert((doc.last.data as String).endsWith('\n')); var offset = 0; diff --git a/lib/src/models/documents/nodes/container.dart b/lib/src/models/documents/nodes/container.dart index 5b5e0941b..f5f1900d3 100644 --- a/lib/src/models/documents/nodes/container.dart +++ b/lib/src/models/documents/nodes/container.dart @@ -1,6 +1,6 @@ import 'dart:collection'; -import '../../../widgets/others/embeds.dart'; +import '../../../widgets/quill/embeds.dart'; import '../style.dart'; import 'leaf.dart'; import 'line.dart'; diff --git a/lib/src/models/documents/nodes/leaf.dart b/lib/src/models/documents/nodes/leaf.dart index 314bb4eed..115f7058b 100644 --- a/lib/src/models/documents/nodes/leaf.dart +++ b/lib/src/models/documents/nodes/leaf.dart @@ -1,6 +1,6 @@ import 'dart:math' as math; -import '../../../widgets/others/embeds.dart'; +import '../../../widgets/quill/embeds.dart'; import '../../quill_delta.dart'; import '../style.dart'; import 'embeddable.dart'; diff --git a/lib/src/models/documents/nodes/line.dart b/lib/src/models/documents/nodes/line.dart index bc2920cb1..d202ba08a 100644 --- a/lib/src/models/documents/nodes/line.dart +++ b/lib/src/models/documents/nodes/line.dart @@ -2,7 +2,7 @@ import 'dart:math' as math; import 'package:collection/collection.dart'; -import '../../../widgets/others/embeds.dart'; +import '../../../widgets/quill/embeds.dart'; import '../../quill_delta.dart'; import '../../structs/offset_value.dart'; import '../attribute.dart'; diff --git a/lib/src/models/documents/nodes/node.dart b/lib/src/models/documents/nodes/node.dart index 4b9bcd7d9..3b78603c6 100644 --- a/lib/src/models/documents/nodes/node.dart +++ b/lib/src/models/documents/nodes/node.dart @@ -1,6 +1,6 @@ import 'dart:collection'; -import '../../../widgets/others/embeds.dart'; +import '../../../widgets/quill/embeds.dart'; import '../../quill_delta.dart'; import '../attribute.dart'; import '../style.dart'; diff --git a/lib/src/packages/quill_markdown/custom_quill_attributes.dart b/lib/src/packages/quill_markdown/custom_quill_attributes.dart new file mode 100644 index 000000000..bb62ddbd4 --- /dev/null +++ b/lib/src/packages/quill_markdown/custom_quill_attributes.dart @@ -0,0 +1,11 @@ +import 'package:flutter_quill/flutter_quill.dart'; + +/// Custom attribute to save the language of codeblock +class CodeBlockLanguageAttribute extends Attribute { + /// @nodoc + const CodeBlockLanguageAttribute(String? value) + : super(attrKey, AttributeScope.ignore, value); + + /// attribute key + static const attrKey = 'x-md-codeblock-lang'; +} diff --git a/lib/src/packages/quill_markdown/delta_to_markdown.dart b/lib/src/packages/quill_markdown/delta_to_markdown.dart new file mode 100644 index 000000000..cfeb97f62 --- /dev/null +++ b/lib/src/packages/quill_markdown/delta_to_markdown.dart @@ -0,0 +1,359 @@ +import 'dart:convert'; +import 'dart:ui'; + +import 'package:collection/collection.dart'; +import 'package:flutter_quill/flutter_quill.dart'; +import './custom_quill_attributes.dart'; +import './utils.dart'; + +class _AttributeHandler { + _AttributeHandler({ + this.beforeContent, + this.afterContent, + }); + + final void Function( + Attribute attribute, + Node node, + StringSink output, + )? beforeContent; + + final void Function( + Attribute attribute, + Node node, + StringSink output, + )? afterContent; +} + +/// Outputs [Embed] element as markdown. +typedef EmbedToMarkdown = void Function(Embed embed, StringSink out); + +extension on Object? { + T? asNullable() { + final self = this; + return self == null ? null : self as T; + } +} + +/// Convertor from [Delta] to quill Markdown string. +class DeltaToMarkdown extends Converter + implements _NodeVisitor { + /// + DeltaToMarkdown({ + Map? customEmbedHandlers, + }) { + if (customEmbedHandlers != null) { + _embedHandlers.addAll(customEmbedHandlers); + } + } + + @override + String convert(Delta input) { + final newDelta = transform(input); + + final quillDocument = Document.fromDelta(newDelta); + + final outBuffer = quillDocument.root.accept(this); + + return outBuffer.toString(); + } + + final Map _blockAttrsHandlers = { + Attribute.codeBlock.key: _AttributeHandler( + beforeContent: (attribute, node, output) { + var infoString = ''; + if (node.containsAttr(CodeBlockLanguageAttribute.attrKey)) { + infoString = node.getAttrValueOr( + CodeBlockLanguageAttribute.attrKey, + '', + ); + } + if (infoString.isEmpty) { + final linesWithLang = (node as Block).children.where((child) => + child.containsAttr(CodeBlockLanguageAttribute.attrKey)); + if (linesWithLang.isNotEmpty) { + infoString = linesWithLang.first.getAttrValueOr( + CodeBlockLanguageAttribute.attrKey, + 'or', + ); + } + } + + output.writeln('```$infoString'); + }, + afterContent: (attribute, node, output) => output.writeln('```'), + ), + }; + + final Map _lineAttrsHandlers = { + Attribute.header.key: _AttributeHandler( + beforeContent: (attribute, node, output) { + output + ..write('#' * (attribute.value.asNullable() ?? 1)) + ..write(' '); + }, + ), + Attribute.blockQuote.key: _AttributeHandler( + beforeContent: (attribute, node, output) => output.write('> '), + ), + Attribute.list.key: _AttributeHandler( + beforeContent: (attribute, node, output) { + final indentLevel = node.getAttrValueOr(Attribute.indent.key, 0); + final isNumbered = attribute.value == 'ordered'; + output + ..write((isNumbered ? ' ' : ' ') * indentLevel) + ..write('${isNumbered ? '1.' : '-'} '); + }, + ), + }; + + final Map _textAttrsHandlers = { + Attribute.italic.key: _AttributeHandler( + beforeContent: (attribute, node, output) { + if (node.previous?.containsAttr(attribute.key) != true) { + output.write('_'); + } + }, + afterContent: (attribute, node, output) { + if (node.next?.containsAttr(attribute.key) != true) { + output.write('_'); + } + }, + ), + Attribute.bold.key: _AttributeHandler( + beforeContent: (attribute, node, output) { + if (node.previous?.containsAttr(attribute.key) != true) { + output.write('**'); + } + }, + afterContent: (attribute, node, output) { + if (node.next?.containsAttr(attribute.key) != true) { + output.write('**'); + } + }, + ), + Attribute.strikeThrough.key: _AttributeHandler( + beforeContent: (attribute, node, output) { + if (node.previous?.containsAttr(attribute.key) != true) { + output.write('~~'); + } + }, + afterContent: (attribute, node, output) { + if (node.next?.containsAttr(attribute.key) != true) { + output.write('~~'); + } + }, + ), + Attribute.inlineCode.key: _AttributeHandler( + beforeContent: (attribute, node, output) { + if (node.previous?.containsAttr(attribute.key) != true) { + output.write('`'); + } + }, + afterContent: (attribute, node, output) { + if (node.next?.containsAttr(attribute.key) != true) { + output.write('`'); + } + }, + ), + Attribute.link.key: _AttributeHandler( + beforeContent: (attribute, node, output) { + if (node.previous?.containsAttr(attribute.key, attribute.value) != + true) { + output.write('['); + } + }, + afterContent: (attribute, node, output) { + if (node.next?.containsAttr(attribute.key, attribute.value) != true) { + output.write('](${attribute.value.asNullable() ?? ''})'); + } + }, + ), + }; + + final Map _embedHandlers = { + BlockEmbed.imageType: (embed, out) => out.write('![](${embed.value.data})'), + horizontalRuleType: (embed, out) { + // adds new line after it + // make --- separated so it doesn't get rendered as header + out.writeln('- - -'); + }, + }; + + @override + StringSink visitRoot(Root root, [StringSink? output]) { + final out = output ??= StringBuffer(); + for (final container in root.children) { + container.accept(this, out); + } + return out; + } + + @override + StringSink visitBlock(Block block, [StringSink? output]) { + final out = output ??= StringBuffer(); + _handleAttribute(_blockAttrsHandlers, block, output, () { + for (final line in block.children) { + line.accept(this, out); + } + }); + return out; + } + + @override + StringSink visitLine(Line line, [StringSink? output]) { + final out = output ??= StringBuffer(); + final style = line.style; + _handleAttribute(_lineAttrsHandlers, line, output, () { + for (final leaf in line.children) { + leaf.accept(this, out); + } + }); + if (style.isEmpty || + style.values.every((item) => item.scope != AttributeScope.block)) { + out.writeln(); + } + if (style.containsKey(Attribute.list.key) && + line.nextLine?.style.containsKey(Attribute.list.key) != true) { + out.writeln(); + } + out.writeln(); + return out; + } + + @override + StringSink visitText(QuillText text, [StringSink? output]) { + final out = output ??= StringBuffer(); + final style = text.style; + _handleAttribute( + _textAttrsHandlers, + text, + output, + () { + var content = text.value; + if (!(style.containsKey(Attribute.codeBlock.key) || + style.containsKey(Attribute.inlineCode.key) || + (text.parent?.style.containsKey(Attribute.codeBlock.key) ?? + false))) { + content = content.replaceAllMapped( + RegExp(r'[\\\`\*\_\{\}\[\]\(\)\#\+\-\.\!\>\<]'), (match) { + return '\\${match[0]}'; + }); + } + out.write(content); + }, + sortedAttrsBySpan: true, + ); + return out; + } + + @override + StringSink visitEmbed(Embed embed, [StringSink? output]) { + final out = output ??= StringBuffer(); + + final type = embed.value.type; + + _embedHandlers[type]!.call(embed, out); + + return out; + } + + void _handleAttribute( + Map handlers, + Node node, + StringSink output, + VoidCallback contentHandler, { + bool sortedAttrsBySpan = false, + }) { + final attrs = sortedAttrsBySpan + ? node.attrsSortedByLongestSpan() + : node.style.attributes.values.toList(); + final handlersToUse = attrs + .where((attr) => handlers.containsKey(attr.key)) + .map((attr) => MapEntry(attr.key, handlers[attr.key]!)) + .toList(); + for (final handlerEntry in handlersToUse) { + handlerEntry.value.beforeContent?.call( + node.style.attributes[handlerEntry.key]!, + node, + output, + ); + } + contentHandler(); + for (final handlerEntry in handlersToUse.reversed) { + handlerEntry.value.afterContent?.call( + node.style.attributes[handlerEntry.key]!, + node, + output, + ); + } + } +} + +//// AST with visitor + +abstract class _NodeVisitor { + const _NodeVisitor._(); + + T visitRoot(Root root, [T? context]); + + T visitBlock(Block block, [T? context]); + + T visitLine(Line line, [T? context]); + + T visitText(QuillText text, [T? context]); + + T visitEmbed(Embed embed, [T? context]); +} + +extension _NodeX on Node { + T accept(_NodeVisitor visitor, [T? context]) { + switch (runtimeType) { + case Root _: + return visitor.visitRoot(this as Root, context); + case Block _: + return visitor.visitBlock(this as Block, context); + case Line _: + return visitor.visitLine(this as Line, context); + case QuillText _: + return visitor.visitText(this as QuillText, context); + case Embed _: + return visitor.visitEmbed(this as Embed, context); + } + throw Exception('Container of type $runtimeType cannot be visited'); + } + + bool containsAttr(String attributeKey, [Object? value]) { + if (!style.containsKey(attributeKey)) { + return false; + } + if (value == null) { + return true; + } + return style.attributes[attributeKey]!.value == value; + } + + T getAttrValueOr(String attributeKey, T or) { + final attrs = style.attributes; + final attrValue = attrs[attributeKey]?.value as T?; + return attrValue ?? or; + } + + List> attrsSortedByLongestSpan() { + final attrCount = , int>{}; + var node = this; + // get the first node + while (node.previous != null) { + node = node.previous!; + node.style.attributes.forEach((key, value) { + attrCount[value] = (attrCount[value] ?? 0) + 1; + }); + node = node.next!; + } + + final attrs = style.attributes.values.sorted( + (attr1, attr2) => attrCount[attr2]!.compareTo(attrCount[attr1]!)); + + return attrs; + } +} diff --git a/lib/src/packages/quill_markdown/embeddable_table_syntax.dart b/lib/src/packages/quill_markdown/embeddable_table_syntax.dart new file mode 100644 index 000000000..d33e703c5 --- /dev/null +++ b/lib/src/packages/quill_markdown/embeddable_table_syntax.dart @@ -0,0 +1,116 @@ +import 'package:charcode/charcode.dart'; +import 'package:flutter_quill/flutter_quill.dart' hide Node; +import 'package:markdown/markdown.dart'; + +/// Parses markdown table and saves the table markdown content into the element attributes. +class EmbeddableTableSyntax extends BlockSyntax { + /// @nodoc + const EmbeddableTableSyntax(); + static const _base = TableSyntax(); + + @override + bool canEndBlock(BlockParser parser) => false; + + @override + RegExp get pattern => _base.pattern; + + @override + bool canParse(BlockParser parser) => _base.canParse(parser); + + /// Parses a table into its three parts: + /// + /// * a head row of head cells (`` cells) + /// * a divider of hyphens and pipes (not rendered) + /// * many body rows of body cells (`` cells) + @override + Node? parse(BlockParser parser) { + final columnCount = _columnCount(parser.next!.content); + final headCells = _columnCount(parser.current.content); + final valBuf = + StringBuffer('${parser.current.content}\n${parser.next!.content}'); + parser.advance(); + if (columnCount != headCells) { + return null; + } + + // advance header and divider of hyphens. + parser.advance(); + + while (!parser.isDone && !BlockSyntax.isAtBlockEnd(parser)) { + valBuf.write('\n${parser.current.content}'); + parser.advance(); + } + + return Element.empty(EmbeddableTable.tableType) + ..attributes['data'] = valBuf.toString(); + } + + int _columnCount(String line) { + final startIndex = _walkPastOpeningPipe(line); + + var endIndex = line.length - 1; + while (endIndex > 0) { + final ch = line.codeUnitAt(endIndex); + if (ch == $pipe) { + endIndex--; + break; + } + if (ch != $space && ch != $tab) { + break; + } + endIndex--; + } + + return line.substring(startIndex, endIndex + 1).split('|').length; + } + + int _walkPastWhitespace(String line, int index) { + while (index < line.length) { + final ch = line.codeUnitAt(index); + if (ch != $space && ch != $tab) { + break; + } + //ignore: parameter_assignments + index++; + } + return index; + } + + int _walkPastOpeningPipe(String line) { + var index = 0; + while (index < line.length) { + final ch = line.codeUnitAt(index); + if (ch == $pipe) { + index++; + index = _walkPastWhitespace(line, index); + } + if (ch != $space && ch != $tab) { + // No leading pipe. + break; + } + index++; + } + return index; + } +} + +/// An [Embeddable] table that can used to render a table in quill_editor +class EmbeddableTable extends BlockEmbed { + /// @nodoc + EmbeddableTable(String data) : super(tableType, data); + + /// [Embeddable] type + static const tableType = 'x-embed-table'; + + /// Create from markdown. + //ignore: prefer_constructors_over_static_methods + static EmbeddableTable fromMdSyntax(Map attributes) => + EmbeddableTable(attributes['data']!); + + /// Outputs table markdown to output. + static void toMdSyntax(Embed embed, StringSink out) { + out + ..writeln(embed.value.data) + ..writeln(); + } +} diff --git a/lib/src/packages/quill_markdown/markdown_to_delta.dart b/lib/src/packages/quill_markdown/markdown_to_delta.dart new file mode 100644 index 000000000..d4bca2e7d --- /dev/null +++ b/lib/src/packages/quill_markdown/markdown_to_delta.dart @@ -0,0 +1,424 @@ +import 'dart:collection'; +import 'dart:convert'; + +import 'package:collection/collection.dart'; +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:markdown/markdown.dart' as md; + +import './custom_quill_attributes.dart'; +import './embeddable_table_syntax.dart'; +import './utils.dart'; + +/// Converts markdown [md.Element] to list of [Attribute]. +typedef ElementToAttributeConvertor = List> Function( + md.Element element, +); + +/// Converts markdown [md.Element] to [Embeddable]. +typedef ElementToEmbeddableConvertor = Embeddable Function( + Map elAttrs, +); + +/// Convertor from Markdown string to quill [Delta]. +class MarkdownToDelta extends Converter + implements md.NodeVisitor { + /// + MarkdownToDelta({ + required this.markdownDocument, + this.customElementToInlineAttribute = const {}, + this.customElementToBlockAttribute = const {}, + this.customElementToEmbeddable = const {}, + this.softLineBreak = false, + }); + + final md.Document markdownDocument; + final Map customElementToInlineAttribute; + final Map customElementToBlockAttribute; + final Map customElementToEmbeddable; + final bool softLineBreak; + + // final _blockTags = [ + // 'p', + // 'h1', + // 'h2', + // 'h3', + // 'h4', + // 'h5', + // 'h6', + // 'li', + // 'blockquote', + // 'pre', + // 'ol', + // 'ul', + // 'hr', + // 'table', + // 'thead', + // 'tbody', + // 'tr' + // ]; + + final _elementToBlockAttr = { + 'ul': (_) => [Attribute.ul], + 'ol': (_) => [Attribute.ol], + 'pre': (element) { + final codeChild = element.children!.first as md.Element; + final language = (codeChild.attributes['class'] ?? '') + .split(' ') + .where((class_) => class_.startsWith('language-')) + .firstOrNull + ?.split('-') + .lastOrNull; + return [ + Attribute.codeBlock, + if (language != null) CodeBlockLanguageAttribute(language), + ]; + }, + 'blockquote': (_) => [Attribute.blockQuote], + 'h1': (_) => [Attribute.h1], + 'h2': (_) => [Attribute.h2], + 'h3': (_) => [Attribute.h3], + }; + + final _elementToInlineAttr = { + 'em': (_) => [Attribute.italic], + 'strong': (_) => [Attribute.bold], + 'del': (_) => [Attribute.strikeThrough], + 'a': (element) => [LinkAttribute(element.attributes['href'])], + 'code': (_) => [Attribute.inlineCode], + }; + + final _elementToEmbed = { + 'hr': (_) => horizontalRule, + 'img': (elAttrs) => BlockEmbed.image(elAttrs['src'] ?? ''), + }; + + var _delta = Delta(); + final _activeInlineAttributes = Queue>>(); + final _activeBlockAttributes = Queue>>(); + final _topLevelNodes = []; + bool _isInBlockQuote = false; + bool _isInCodeblock = false; + bool _justPreviousBlockExit = false; + String? _lastTag; + String? _currentBlockTag; + int _listItemIndent = -1; + + @override + Delta convert(String input) { + _delta = Delta(); + _activeInlineAttributes.clear(); + _activeBlockAttributes.clear(); + _topLevelNodes.clear(); + _lastTag = null; + _currentBlockTag = null; + _isInBlockQuote = false; + _isInCodeblock = false; + _justPreviousBlockExit = false; + _listItemIndent = -1; + + final lines = const LineSplitter().convert(input); + final mdNodes = markdownDocument.parseLines(lines); + + _topLevelNodes.addAll(mdNodes); + + for (final node in mdNodes) { + node.accept(this); + } + + // Ensure the delta ends with a newline. + _appendLastNewLineIfNeeded(); + + return _delta; + } + + void _appendLastNewLineIfNeeded() { + if (_delta.isEmpty) return; + final dynamic lastValue = _delta.last.value; + if (!(lastValue is String && lastValue.endsWith('\n'))) { + _delta.insert('\n', _effectiveBlockAttrs()); + } + } + + @override + void visitText(md.Text text) { + String renderedText; + if (_isInBlockQuote) { + renderedText = text.text; + } else if (_isInCodeblock) { + renderedText = text.text.endsWith('\n') + ? text.text.substring(0, text.text.length - 1) + : text.text; + } else { + renderedText = _trimTextToMdSpec(text.text); + } + + if (renderedText.contains('\n')) { + var lines = renderedText.split('\n'); + if (renderedText.endsWith('\n')) { + lines = lines.sublist(0, lines.length - 1); + } + for (var i = 0; i < lines.length; i++) { + final isLastItem = i == lines.length - 1; + final line = lines[i]; + _delta.insert(line, _effectiveInlineAttrs()); + if (!isLastItem) { + _delta.insert('\n', _effectiveBlockAttrs()); + } + } + } else { + _delta.insert(renderedText, _effectiveInlineAttrs()); + } + _lastTag = null; + _justPreviousBlockExit = false; + } + + @override + bool visitElementBefore(md.Element element) { + _insertNewLineBeforeElementIfNeeded(element); + + final tag = element.tag; + _currentBlockTag ??= tag; + _lastTag = tag; + + if (_haveBlockAttrs(element)) { + _activeBlockAttributes.addLast(_toBlockAttributes(element)); + } + if (_haveInlineAttrs(element)) { + _activeInlineAttributes.addLast(_toInlineAttributes(element)); + } + + if (tag == 'blockquote') { + _isInBlockQuote = true; + } + + if (tag == 'pre') { + _isInCodeblock = true; + } + + if (tag == 'li') { + _listItemIndent++; + } + + return true; + } + + @override + void visitElementAfter(md.Element element) { + final tag = element.tag; + + if (_isEmbedElement(element)) { + _delta.insert(_toEmbeddable(element).toJson()); + } + + if (tag == 'br') { + _delta.insert('\n'); + } + + // exit block with new line + // hr need to be followed by new line + _insertNewLineAfterElementIfNeeded(element); + + if (tag == 'blockquote') { + _isInBlockQuote = false; + } + + if (tag == 'pre') { + _isInCodeblock = false; + } + + if (tag == 'li') { + _listItemIndent--; + } + + if (_haveBlockAttrs(element)) { + _activeBlockAttributes.removeLast(); + } + + if (_haveInlineAttrs(element)) { + _activeInlineAttributes.removeLast(); + } + + if (_currentBlockTag == tag) { + _currentBlockTag = null; + } + _lastTag = tag; + } + + void _insertNewLine() { + _delta.insert('\n', _effectiveBlockAttrs()); + } + + void _insertNewLineBeforeElementIfNeeded(md.Element element) { + if (!_isInBlockQuote && + _lastTag == 'blockquote' && + element.tag == 'blockquote') { + _insertNewLine(); + return; + } + + if (!_isInCodeblock && _lastTag == 'pre' && element.tag == 'pre') { + _insertNewLine(); + return; + } + + if (_listItemIndent >= 0 && (element.tag == 'ul' || element.tag == 'ol')) { + _insertNewLine(); + return; + } + } + + void _insertNewLineAfterElementIfNeeded(md.Element element) { + // TODO: refactor this to allow embeds to specify if they require + // new line after them + if (element.tag == 'hr' || element.tag == EmbeddableTable.tableType) { + // Always add new line after divider + _justPreviousBlockExit = true; + _insertNewLine(); + return; + } + + // if all the p children are embeddable add a new line + // example: images in a single line + if (element.tag == 'p' && + (element.children?.every( + (child) => child is md.Element && _isEmbedElement(child), + ) ?? + false)) { + _justPreviousBlockExit = true; + _insertNewLine(); + return; + } + + if (!_justPreviousBlockExit && + (_isTopLevelNode(element) || + _haveBlockAttrs(element) || + element.tag == 'li')) { + _justPreviousBlockExit = true; + _insertNewLine(); + return; + } + } + + bool _isTopLevelNode(md.Node node) => _topLevelNodes.contains(node); + + Map? _effectiveBlockAttrs() { + if (_activeBlockAttributes.isEmpty) return null; + final attrsRespectingExclusivity = >[ + if (_listItemIndent > 0) IndentAttribute(level: _listItemIndent), + ]; + + for (final attr in _activeBlockAttributes.expand((e) => e)) { + final isExclusiveAttr = Attribute.exclusiveBlockKeys.contains( + attr.key, + ); + final isThereAlreadyExclusiveAttr = attrsRespectingExclusivity.any( + (element) => Attribute.exclusiveBlockKeys.contains(element.key), + ); + + if (!(isExclusiveAttr && isThereAlreadyExclusiveAttr)) { + attrsRespectingExclusivity.add(attr); + } + } + + return { + for (final a in attrsRespectingExclusivity) ...a.toJson(), + }; + } + + Map? _effectiveInlineAttrs() { + if (_activeInlineAttributes.isEmpty) return null; + return { + for (final attrs in _activeInlineAttributes) + for (final a in attrs) ...a.toJson(), + }; + } + + // Define trim text function to remove spaces from text elements in + // accordance with Markdown specifications. + String _trimTextToMdSpec(String text) { + var result = text; + // The leading spaces pattern is used to identify spaces + // at the beginning of a line of text. + final leadingSpacesPattern = RegExp('^ *'); + + // The soft line break is used to identify the spaces at the end of a line + // of text and the leading spaces in the immediately following the line + // of text. These spaces are removed in accordance with the Markdown + // specification on soft line breaks when lines of text are joined. + final softLineBreak = RegExp(r' ?\n *'); + + // Leading spaces following a hard line break are ignored. + // https://github.github.com/gfm/#example-657 + if (const ['p', 'ol', 'li', 'br'].contains(_lastTag)) { + result = result.replaceAll(leadingSpacesPattern, ''); + } + + if (softLineBreak.hasMatch(result)) { + return result; + } + return result.replaceAll(softLineBreak, ' '); + } + + Map _effectiveElementToInlineAttr() { + return { + ...customElementToInlineAttribute, + ..._elementToInlineAttr, + }; + } + + bool _haveInlineAttrs(md.Element element) { + if (_isInCodeblock && element.tag == 'code') return false; + return _effectiveElementToInlineAttr().containsKey(element.tag); + } + + List> _toInlineAttributes(md.Element element) { + List>? result; + if (!(_isInCodeblock && element.tag == 'code')) { + result = _effectiveElementToInlineAttr()[element.tag]?.call(element); + } + if (result == null) { + throw Exception( + 'Element $element cannot be converted to inline attribute'); + } + return result; + } + + Map _effectiveElementToBlockAttr() { + return { + ...customElementToBlockAttribute, + ..._elementToBlockAttr, + }; + } + + bool _haveBlockAttrs(md.Element element) { + return _effectiveElementToBlockAttr().containsKey(element.tag); + } + + List> _toBlockAttributes(md.Element element) { + final result = _effectiveElementToBlockAttr()[element.tag]?.call(element); + if (result == null) { + throw Exception( + 'Element $element cannot be converted to block attribute'); + } + return result; + } + + Map _effectiveElementToEmbed() { + return { + ...customElementToEmbeddable, + ..._elementToEmbed, + }; + } + + bool _isEmbedElement(md.Element element) => + _effectiveElementToEmbed().containsKey(element.tag); + + Embeddable _toEmbeddable(md.Element element) { + final result = + _effectiveElementToEmbed()[element.tag]?.call(element.attributes); + if (result == null) { + throw Exception('Element $element cannot be converted to Embeddable'); + } + return result; + } +} diff --git a/lib/src/packages/quill_markdown/utils.dart b/lib/src/packages/quill_markdown/utils.dart new file mode 100644 index 000000000..c5843ec5c --- /dev/null +++ b/lib/src/packages/quill_markdown/utils.dart @@ -0,0 +1,59 @@ +//ignore_for_file: cast_nullable_to_non_nullable +import 'package:flutter_quill/flutter_quill.dart'; + +import './embeddable_table_syntax.dart'; + +/// To allow embedding images/videos in horizontal mode. +const BlockEmbed horizontalRule = BlockEmbed(horizontalRuleType, 'hr'); + +/// Necessary for [horizontalRule] BlockEmbed. +const String horizontalRuleType = 'divider'; + +/// Format the passed delta to ensure that there is new line +/// after embeds +Delta transform(Delta delta) { + final res = Delta(); + final ops = delta.toList(); + for (var i = 0; i < ops.length; i++) { + final op = ops[i]; + res.push(op); + autoAppendNewlineAfterEmbeddable(i, ops, op, res, [ + 'hr', + EmbeddableTable.tableType, + ]); + } + return res; +} + +/// Appends new line after embeds if needed +void autoAppendNewlineAfterEmbeddable( + int i, + List ops, + Operation op, + Delta res, + List types, +) { + final nextOpIsEmbed = i + 1 < ops.length && + ops[i + 1].isInsert && + ops[i + 1].data is Map && + types.any((type) => (ops[i + 1].data as Map).containsKey(type)); + + if (nextOpIsEmbed && + op.data is String && + (op.data as String).isNotEmpty && + !(op.data as String).endsWith('\n')) { + res.push(Operation.insert('\n')); + } + // embed could be image or video + final opInsertEmbed = op.isInsert && + op.data is Map && + types.any((type) => (op.data as Map).containsKey(type)); + final nextOpIsLineBreak = i + 1 < ops.length && + ops[i + 1].isInsert && + ops[i + 1].data is String && + (ops[i + 1].data as String).startsWith('\n'); + if (opInsertEmbed && (i + 1 == ops.length - 1 || !nextOpIsLineBreak)) { + // automatically append '\n' for embeddable + res.push(Operation.insert('\n')); + } +} diff --git a/lib/src/utils/embeds.dart b/lib/src/utils/embeds.dart index 973942bb1..4b3e2de38 100644 --- a/lib/src/utils/embeds.dart +++ b/lib/src/utils/embeds.dart @@ -2,7 +2,7 @@ import 'dart:math'; import '../models/documents/nodes/leaf.dart'; import '../models/structs/offset_value.dart'; -import '../widgets/others/controller.dart'; +import '../widgets/quill/quill_controller.dart'; OffsetValue getEmbedNode(QuillController controller, int offset) { var offset = controller.selection.start; diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index 68665809c..0017b68c0 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -18,7 +18,7 @@ import '../../utils/platform.dart'; import '../others/box.dart'; import '../others/cursor.dart'; import '../others/delegate.dart'; -import '../others/embeds.dart'; +import '../quill/embeds.dart'; import '../others/float_cursor.dart'; import '../others/text_selection.dart'; import '../raw_editor/raw_editor.dart'; diff --git a/lib/src/widgets/others/delegate.dart b/lib/src/widgets/others/delegate.dart index 3bf19cdc5..f22074abe 100644 --- a/lib/src/widgets/others/delegate.dart +++ b/lib/src/widgets/others/delegate.dart @@ -7,8 +7,8 @@ import '../../models/documents/attribute.dart'; import '../../models/documents/nodes/leaf.dart'; import '../../utils/platform.dart'; import '../editor/editor.dart'; +import '../quill/embeds.dart'; import '../raw_editor/raw_editor.dart'; -import 'embeds.dart'; import 'text_selection.dart'; typedef EmbedsBuilder = EmbedBuilder Function(Embed node); diff --git a/lib/src/widgets/others/embeds.dart b/lib/src/widgets/quill/embeds.dart similarity index 96% rename from lib/src/widgets/others/embeds.dart rename to lib/src/widgets/quill/embeds.dart index 9b828d1bc..d575f2fe1 100644 --- a/lib/src/widgets/others/embeds.dart +++ b/lib/src/widgets/quill/embeds.dart @@ -4,7 +4,7 @@ import '../../../extensions.dart'; import '../../models/documents/nodes/leaf.dart' as leaf; import '../../models/themes/quill_dialog_theme.dart'; import '../../models/themes/quill_icon_theme.dart'; -import 'controller.dart'; +import 'quill_controller.dart'; abstract class EmbedBuilder { const EmbedBuilder(); diff --git a/lib/src/widgets/others/controller.dart b/lib/src/widgets/quill/quill_controller.dart similarity index 90% rename from lib/src/widgets/others/controller.dart rename to lib/src/widgets/quill/quill_controller.dart index 0928cf88e..fd3403003 100644 --- a/lib/src/widgets/others/controller.dart +++ b/lib/src/widgets/quill/quill_controller.dart @@ -1,8 +1,11 @@ import 'dart:math' as math; -import 'package:flutter/cupertino.dart'; import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:html2md/html2md.dart' as html2md; +import 'package:markdown/markdown.dart' as md; +import '../../../markdown_quill.dart'; import '../../models/documents/attribute.dart'; import '../../models/documents/document.dart'; import '../../models/documents/nodes/embeddable.dart'; @@ -42,7 +45,7 @@ class QuillController extends ChangeNotifier { Document get document => _document; - set document(doc) { + set document(Document doc) { _document = doc; // Prevent the selection from @@ -51,6 +54,11 @@ class QuillController extends ChangeNotifier { notifyListeners(); } + void updateDocument(Document newDocument) { + _document = newDocument; + notifyListeners(); + } + /// Tells whether to keep or reset the [toggledStyle] /// when user adds a new line. final bool _keepStyleOnNewLine; @@ -439,4 +447,38 @@ class QuillController extends ChangeNotifier { // Notify toolbar buttons directly with attributes Map toolbarButtonToggler = const {}; + + /// Convert the HTML Raw string to [Delta] + /// + /// It will run using the following steps: + /// + /// 1. Convert the html to markdown string using `html2md` package + /// 2. Convert the markdown string to quill delta json string + /// 3. Decode the delta json string to [Delta] + /// + /// for more [info](https://github.com/singerdmx/flutter-quill/issues/1100) + static Delta fromHtml(String html) { + final markdown = html2md + .convert( + html, + ) + .replaceAll('unsafe:', ''); + + final mdDocument = md.Document(encodeHtml: false); + + final mdToDelta = MarkdownToDelta(markdownDocument: mdDocument); + + return mdToDelta.convert(markdown); + + // final deltaJsonString = markdownToDelta(markdown); + // final deltaJson = jsonDecode(deltaJsonString); + // if (deltaJson is! List) { + // throw ArgumentError( + // 'The delta json string should be of type list when jsonDecode() it', + // ); + // } + // return Delta.fromJson( + // deltaJson, + // ); + } } diff --git a/lib/src/widgets/others/text_block.dart b/lib/src/widgets/quill/text_block.dart similarity index 98% rename from lib/src/widgets/others/text_block.dart rename to lib/src/widgets/quill/text_block.dart index 878064804..c13c5eeb1 100644 --- a/lib/src/widgets/others/text_block.dart +++ b/lib/src/widgets/quill/text_block.dart @@ -11,14 +11,14 @@ import '../editor/editor.dart'; import '../style_widgets/bullet_point.dart'; import '../style_widgets/checkbox_point.dart'; import '../style_widgets/number_point.dart'; -import 'box.dart'; -import 'controller.dart'; -import 'cursor.dart'; -import 'default_styles.dart'; -import 'delegate.dart'; -import 'link.dart'; +import '../others/box.dart'; +import 'quill_controller.dart'; +import '../others/cursor.dart'; +import '../others/default_styles.dart'; +import '../others/delegate.dart'; +import '../others/link.dart'; import 'text_line.dart'; -import 'text_selection.dart'; +import '../others/text_selection.dart'; const List arabianRomanNumbers = [ 1000, diff --git a/lib/src/widgets/others/text_line.dart b/lib/src/widgets/quill/text_line.dart similarity index 99% rename from lib/src/widgets/others/text_line.dart rename to lib/src/widgets/quill/text_line.dart index 3a155333f..7ec68bd4a 100644 --- a/lib/src/widgets/others/text_line.dart +++ b/lib/src/widgets/quill/text_line.dart @@ -20,15 +20,15 @@ import '../../models/structs/vertical_spacing.dart'; import '../../utils/color.dart'; import '../../utils/font.dart'; import '../../utils/platform.dart'; -import 'box.dart'; -import 'controller.dart'; -import 'cursor.dart'; -import 'default_styles.dart'; -import 'delegate.dart'; -import 'keyboard_listener.dart'; -import 'link.dart'; -import 'proxy.dart'; -import 'text_selection.dart'; +import '../others/box.dart'; +import 'quill_controller.dart'; +import '../others/cursor.dart'; +import '../others/default_styles.dart'; +import '../others/delegate.dart'; +import '../others/keyboard_listener.dart'; +import '../others/link.dart'; +import '../others/proxy.dart'; +import '../others/text_selection.dart'; class TextLine extends StatefulWidget { const TextLine({ @@ -163,7 +163,7 @@ class _TextLineState extends State { ); } } - final textSpan = _getTextSpanForWholeLine(context); + final textSpan = _getTextSpanForWholeLine(); final strutStyle = StrutStyle.fromTextStyle(textSpan.style!); final textAlign = _getTextAlign(); final child = RichText( @@ -185,7 +185,7 @@ class _TextLineState extends State { ); } - InlineSpan _getTextSpanForWholeLine(BuildContext context) { + InlineSpan _getTextSpanForWholeLine() { final lineStyle = _getLineStyle(widget.styles); if (!widget.line.hasEmbed) { return _buildTextSpan(widget.styles, widget.line.children, lineStyle); diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index 897658cca..64d1e28c0 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -28,6 +28,7 @@ import '../../models/documents/nodes/embeddable.dart'; import '../../models/documents/nodes/leaf.dart' as leaf; import '../../models/documents/nodes/line.dart'; import '../../models/documents/nodes/node.dart'; +import '../../models/quill_delta.dart'; import '../../models/structs/offset_value.dart'; import '../../models/structs/vertical_spacing.dart'; import '../../utils/cast.dart'; @@ -35,14 +36,14 @@ import '../../utils/delta.dart'; import '../../utils/embeds.dart'; import '../../utils/platform.dart'; import '../editor/editor.dart'; -import '../others/controller.dart'; +import '../quill/quill_controller.dart'; import '../others/cursor.dart'; import '../others/default_styles.dart'; import '../others/keyboard_listener.dart'; import '../others/link.dart'; import '../others/proxy.dart'; -import '../others/text_block.dart'; -import '../others/text_line.dart'; +import '../quill/text_block.dart'; +import '../quill/text_line.dart'; import '../others/text_selection.dart'; import 'quill_single_child_scroll_view.dart'; import 'raw_editor.dart'; @@ -224,14 +225,65 @@ class QuillRawEditorState extends EditorState if (!selection.isValid) { return; } + + // TODO: Could be improved + Delta? deltaFromCliboard; + final reader = await ClipboardReader.readClipboard(); + if (reader.canProvide(Formats.htmlText)) { + final html = await reader.readValue(Formats.htmlText); + if (html == null) { + return; + } + deltaFromCliboard = QuillController.fromHtml(html); + } + if (deltaFromCliboard != null) { + // final index = selection.baseOffset; + // final length = selection.extentOffset - index; + + final list = controller.document.toDelta().toList() + ..insertAll(controller.document.toDelta().toList().length - 1, + deltaFromCliboard.toList()); + + final delta = controller.document.toDelta(); + for (final operation in list) { + delta.push(operation); + } + + controller + ..updateDocument( + Document.fromDelta(delta), + ) + ..updateSelection( + TextSelection.collapsed( + offset: controller.document.length, + ), + ChangeSource.local, + ); + + bringIntoView(textEditingValue.selection.extent); + + // Collapse the selection and hide the toolbar and handles. + userUpdateTextEditingValue( + TextEditingValue( + text: textEditingValue.text, + selection: TextSelection.collapsed( + offset: textEditingValue.selection.end, + ), + ), + cause, + ); + + return; + } + // Snapshot the input before using `await`. // See https://github.com/flutter/flutter/issues/11427 - final text = await Clipboard.getData(Clipboard.kTextPlain); - if (text != null) { + final plainText = await Clipboard.getData(Clipboard.kTextPlain); + if (plainText != null) { _replaceText( ReplaceTextIntent( textEditingValue, - text.text!, + plainText.text!, selection, cause, ), @@ -1693,6 +1745,8 @@ class QuillRawEditorState extends EditorState } } + // TODO: Review those + @override bool get liveTextInputEnabled => false; diff --git a/lib/src/widgets/style_widgets/number_point.dart b/lib/src/widgets/style_widgets/number_point.dart index 398dd3945..ed5d96c8c 100644 --- a/lib/src/widgets/style_widgets/number_point.dart +++ b/lib/src/widgets/style_widgets/number_point.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import '../../extensions/quill_configurations_ext.dart'; import '../../models/documents/attribute.dart'; -import '../others/text_block.dart'; +import '../quill/text_block.dart'; class QuillEditorNumberPoint extends StatelessWidget { const QuillEditorNumberPoint({ diff --git a/lib/src/widgets/toolbar/buttons/clear_format_button.dart b/lib/src/widgets/toolbar/buttons/clear_format_button.dart index bf1ba0962..751474116 100644 --- a/lib/src/widgets/toolbar/buttons/clear_format_button.dart +++ b/lib/src/widgets/toolbar/buttons/clear_format_button.dart @@ -4,7 +4,7 @@ import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../others/controller.dart'; +import '../../quill/quill_controller.dart'; import '../base_toolbar.dart'; class QuillToolbarClearFormatButton extends StatelessWidget { diff --git a/lib/src/widgets/toolbar/buttons/color/color_button.dart b/lib/src/widgets/toolbar/buttons/color/color_button.dart index ff2dce6b6..2140afc40 100644 --- a/lib/src/widgets/toolbar/buttons/color/color_button.dart +++ b/lib/src/widgets/toolbar/buttons/color/color_button.dart @@ -7,7 +7,7 @@ import '../../../../models/documents/attribute.dart'; import '../../../../models/documents/style.dart'; import '../../../../models/themes/quill_icon_theme.dart'; import '../../../../utils/color.dart'; -import '../../../others/controller.dart'; +import '../../../quill/quill_controller.dart'; import '../../base_toolbar.dart'; import 'color_dialog.dart'; diff --git a/lib/src/widgets/toolbar/buttons/custom_button_button.dart b/lib/src/widgets/toolbar/buttons/custom_button_button.dart index 27145d344..825b3d2f9 100644 --- a/lib/src/widgets/toolbar/buttons/custom_button_button.dart +++ b/lib/src/widgets/toolbar/buttons/custom_button_button.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import '../../../extensions/quill_configurations_ext.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../others/controller.dart'; +import '../../quill/quill_controller.dart'; import '../base_toolbar.dart'; class QuillToolbarCustomButton extends StatelessWidget { diff --git a/lib/src/widgets/toolbar/buttons/font_family_button.dart b/lib/src/widgets/toolbar/buttons/font_family_button.dart index dc23f92fa..8714d6fa3 100644 --- a/lib/src/widgets/toolbar/buttons/font_family_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_family_button.dart @@ -7,7 +7,7 @@ import '../../../models/config/toolbar/buttons/font_family_configurations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../others/controller.dart'; +import '../../quill/quill_controller.dart'; class QuillToolbarFontFamilyButton extends StatefulWidget { QuillToolbarFontFamilyButton({ diff --git a/lib/src/widgets/toolbar/buttons/font_size_button.dart b/lib/src/widgets/toolbar/buttons/font_size_button.dart index 0debeba72..d1ee7752e 100644 --- a/lib/src/widgets/toolbar/buttons/font_size_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_size_button.dart @@ -8,7 +8,7 @@ import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../../utils/font.dart'; -import '../../others/controller.dart'; +import '../../quill/quill_controller.dart'; class QuillToolbarFontSizeButton extends StatefulWidget { QuillToolbarFontSizeButton({ diff --git a/lib/src/widgets/toolbar/buttons/history_button.dart b/lib/src/widgets/toolbar/buttons/history_button.dart index 4346a6e37..5436e74cf 100644 --- a/lib/src/widgets/toolbar/buttons/history_button.dart +++ b/lib/src/widgets/toolbar/buttons/history_button.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; -import '../../others/controller.dart'; +import '../../quill/quill_controller.dart'; import '../base_toolbar.dart'; class QuillToolbarHistoryButton extends StatefulWidget { diff --git a/lib/src/widgets/toolbar/buttons/indent_button.dart b/lib/src/widgets/toolbar/buttons/indent_button.dart index f82097b16..654b3d472 100644 --- a/lib/src/widgets/toolbar/buttons/indent_button.dart +++ b/lib/src/widgets/toolbar/buttons/indent_button.dart @@ -4,7 +4,7 @@ import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/config/toolbar/buttons/indent_configurations.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../others/controller.dart'; +import '../../quill/quill_controller.dart'; import '../base_toolbar.dart' show QuillToolbarBaseButtonOptions, QuillToolbarIconButton; diff --git a/lib/src/widgets/toolbar/buttons/link_style2_button.dart b/lib/src/widgets/toolbar/buttons/link_style2_button.dart index a663d8647..63372fbae 100644 --- a/lib/src/widgets/toolbar/buttons/link_style2_button.dart +++ b/lib/src/widgets/toolbar/buttons/link_style2_button.dart @@ -10,7 +10,7 @@ import '../../../l10n/widgets/localizations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/themes/quill_dialog_theme.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../others/controller.dart'; +import '../../quill/quill_controller.dart'; import '../../others/link.dart'; import '../base_toolbar.dart'; diff --git a/lib/src/widgets/toolbar/buttons/link_style_button.dart b/lib/src/widgets/toolbar/buttons/link_style_button.dart index e52533d11..21d87dff6 100644 --- a/lib/src/widgets/toolbar/buttons/link_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/link_style_button.dart @@ -8,7 +8,7 @@ import '../../../models/rules/insert.dart'; import '../../../models/structs/link_dialog_action.dart'; import '../../../models/themes/quill_dialog_theme.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../others/controller.dart'; +import '../../quill/quill_controller.dart'; import '../../others/link.dart'; import '../base_toolbar.dart'; diff --git a/lib/src/widgets/toolbar/buttons/search/search_button.dart b/lib/src/widgets/toolbar/buttons/search/search_button.dart index ed8f634c3..78936d35c 100644 --- a/lib/src/widgets/toolbar/buttons/search/search_button.dart +++ b/lib/src/widgets/toolbar/buttons/search/search_button.dart @@ -5,7 +5,7 @@ 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 '../../../others/controller.dart'; +import '../../../quill/quill_controller.dart'; import '../../base_toolbar.dart'; class QuillToolbarSearchButton extends StatelessWidget { diff --git a/lib/src/widgets/toolbar/buttons/search/search_dialog.dart b/lib/src/widgets/toolbar/buttons/search/search_dialog.dart index 65b2c4d4c..337059f4f 100644 --- a/lib/src/widgets/toolbar/buttons/search/search_dialog.dart +++ b/lib/src/widgets/toolbar/buttons/search/search_dialog.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import '../../../../l10n/extensions/localizations.dart'; import '../../../../models/documents/document.dart'; import '../../../../models/themes/quill_dialog_theme.dart'; -import '../../../others/controller.dart'; +import '../../../quill/quill_controller.dart'; @immutable class QuillToolbarSearchDialogChildBuilderExtraOptions { diff --git a/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart b/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart index af5c383a5..7259a2c59 100644 --- a/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart +++ b/lib/src/widgets/toolbar/buttons/select_alignment_buttons.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import '../../../models/config/toolbar/buttons/select_alignment_configurations.dart'; import '../../../models/documents/attribute.dart'; -import '../../others/controller.dart'; +import '../../quill/quill_controller.dart'; import 'toggle_style_button.dart'; enum _AlignmentOptions { diff --git a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart index 189146a8e..1e92c84fd 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import '../../../../translations.dart'; import '../../../models/config/toolbar/buttons/select_header_style_configurations.dart'; import '../../../models/documents/attribute.dart'; -import '../../others/controller.dart'; +import '../../quill/quill_controller.dart'; enum _HeaderStyleOptions { normal, diff --git a/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart b/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart index b1d3dd2c3..a49151860 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style_buttons.dart @@ -7,7 +7,7 @@ import '../../../l10n/extensions/localizations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../others/controller.dart'; +import '../../quill/quill_controller.dart'; import '../base_toolbar.dart'; class QuillToolbarSelectHeaderStyleButtons extends StatefulWidget { diff --git a/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart b/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart index 866882481..7c2ba94f9 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart @@ -8,7 +8,7 @@ import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../../utils/widgets.dart'; -import '../../others/controller.dart'; +import '../../quill/quill_controller.dart'; import 'toggle_style_button.dart'; class QuillToolbarToggleCheckListButton extends StatefulWidget { diff --git a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart index 345f339d9..fd558ebb5 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart @@ -6,7 +6,7 @@ import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../../utils/widgets.dart'; -import '../../others/controller.dart'; +import '../../quill/quill_controller.dart'; import '../base_toolbar.dart'; typedef ToggleStyleButtonBuilder = Widget Function( diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index b52dd226b..52b9aadd2 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. ## 9.0.0-dev-7 * Fix a bug in chaning the background/font color of ol/ul list +* Better support for pasting HTML contents from external websites to the editor +* The experimental support of converting the HTML from `quill_html_converter` is now built-in in the `flutter_quill` and removed from there (Breaking change for `quill_html_converter`) * Flutter Quill Extensions: * Fix link bug in the video url * Fix patterns diff --git a/packages/quill_html_converter/lib/quill_html_converter.dart b/packages/quill_html_converter/lib/quill_html_converter.dart index 72645e997..2e8d080fa 100644 --- a/packages/quill_html_converter/lib/quill_html_converter.dart +++ b/packages/quill_html_converter/lib/quill_html_converter.dart @@ -1,11 +1,6 @@ library quill_html_converter; -import 'dart:convert' show jsonDecode; - -import 'package:delta_markdown_converter/delta_markdown_converter.dart' - as delta_markdown show markdownToDelta; import 'package:flutter_quill/flutter_quill.dart' show Delta; -import 'package:html2md/html2md.dart' as html2md; import 'package:vsc_quill_delta_to_html/vsc_quill_delta_to_html.dart' as conventer show ConverterOptions, QuillDeltaToHtmlConverter; @@ -30,31 +25,4 @@ extension DeltaHtmlExt on Delta { ).convert(); return html; } - - /// Convert the HTML Raw string to [Delta] - /// - /// It will run using the following steps: - /// - /// 1. Convert the html to markdown string using `html2md` package - /// 2. Convert the markdown string to quill delta json string - /// 3. Decode the delta json string to [Delta] - /// - /// for more [info](https://github.com/singerdmx/flutter-quill/issues/1100) - static Delta fromHtml(String html) { - final markdown = html2md - .convert( - html, - ) - .replaceAll('unsafe:', ''); - final deltaJsonString = delta_markdown.markdownToDelta(markdown); - final deltaJson = jsonDecode(deltaJsonString); - if (deltaJson is! List) { - throw ArgumentError( - 'The delta json string should be of type list when jsonDecode() it', - ); - } - return Delta.fromJson( - deltaJson, - ); - } } diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index 1264fccb1..32c279ef5 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -20,11 +20,14 @@ environment: dependencies: flutter: sdk: flutter - flutter_quill: ^7.10.2 + flutter_quill: ^9.0.0-dev-6 vsc_quill_delta_to_html: ^1.0.3 html2md: ^1.3.1 # markdown: ^7.1.1 - delta_markdown_converter: ^0.0.2 + # delta_markdown_converter: ^0.0.3-dev + markdown: ^7.1.1 + charcode: ^1.3.1 + collection: ^1.18.0 dev_dependencies: flutter_test: diff --git a/pubspec.yaml b/pubspec.yaml index e421ba8b8..5efb4f162 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -52,11 +52,16 @@ dependencies: equatable: ^2.0.5 meta: ^1.9.1 + # For Quill HTML + markdown: ^7.1.1 + html2md: ^1.3.1 + # Plugins url_launcher: ^6.1.14 flutter_keyboard_visibility: ^5.4.1 device_info_plus: ^9.1.0 super_clipboard: ^0.7.3 + charcode: ^1.3.1 dev_dependencies: flutter_lints: ^3.0.1 From 70d5fe020857bc0cefcc3ed67481cdd659d7d30c Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 7 Dec 2023 20:37:24 +0300 Subject: [PATCH 50/86] Fix analysis issues --- lib/flutter_quill.dart | 4 ++-- .../models/config/editor/editor_configurations.dart | 4 ++-- .../config/raw_editor/raw_editor_configurations.dart | 2 +- .../config/toolbar/simple_toolbar_configurations.dart | 2 +- .../quill_markdown/custom_quill_attributes.dart | 2 +- lib/src/packages/quill_markdown/delta_to_markdown.dart | 2 +- .../quill_markdown/embeddable_table_syntax.dart | 3 ++- lib/src/packages/quill_markdown/markdown_to_delta.dart | 2 +- lib/src/packages/quill_markdown/utils.dart | 2 +- lib/src/widgets/editor/editor.dart | 2 +- lib/src/widgets/quill/text_block.dart | 10 +++++----- lib/src/widgets/quill/text_line.dart | 4 ++-- lib/src/widgets/raw_editor/raw_editor_state.dart | 4 ++-- .../widgets/toolbar/buttons/link_style2_button.dart | 2 +- lib/src/widgets/toolbar/buttons/link_style_button.dart | 2 +- 15 files changed, 24 insertions(+), 23 deletions(-) diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index 15e58183e..0e14a5a9b 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -23,12 +23,12 @@ export 'src/models/themes/quill_dialog_theme.dart'; export 'src/models/themes/quill_icon_theme.dart'; export 'src/utils/embeds.dart'; export 'src/widgets/editor/editor.dart'; -export 'src/widgets/quill/quill_controller.dart'; export 'src/widgets/others/cursor.dart'; export 'src/widgets/others/default_styles.dart'; -export 'src/widgets/quill/embeds.dart'; export 'src/widgets/others/link.dart' show LinkActionPickerDelegate, LinkMenuAction; +export 'src/widgets/quill/embeds.dart'; +export 'src/widgets/quill/quill_controller.dart'; export 'src/widgets/raw_editor/raw_editor.dart'; export 'src/widgets/raw_editor/raw_editor_state.dart'; export 'src/widgets/style_widgets/style_widgets.dart'; diff --git a/lib/src/models/config/editor/editor_configurations.dart b/lib/src/models/config/editor/editor_configurations.dart index 029f5a48d..d6a4ecb10 100644 --- a/lib/src/models/config/editor/editor_configurations.dart +++ b/lib/src/models/config/editor/editor_configurations.dart @@ -7,11 +7,11 @@ import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart' show experimental; import '../../../widgets/editor/editor_builder.dart'; -import '../../../widgets/quill/quill_controller.dart'; import '../../../widgets/others/default_styles.dart'; import '../../../widgets/others/delegate.dart'; -import '../../../widgets/quill/embeds.dart'; import '../../../widgets/others/link.dart'; +import '../../../widgets/quill/embeds.dart'; +import '../../../widgets/quill/quill_controller.dart'; import '../../../widgets/raw_editor/raw_editor.dart'; import '../../themes/quill_dialog_theme.dart'; import '../quill_shared_configurations.dart'; diff --git a/lib/src/models/config/raw_editor/raw_editor_configurations.dart b/lib/src/models/config/raw_editor/raw_editor_configurations.dart index 03744e9e4..abe92a04a 100644 --- a/lib/src/models/config/raw_editor/raw_editor_configurations.dart +++ b/lib/src/models/config/raw_editor/raw_editor_configurations.dart @@ -25,11 +25,11 @@ import 'package:flutter/widgets.dart' Widget; import 'package:meta/meta.dart' show immutable; -import '../../../widgets/quill/quill_controller.dart'; import '../../../widgets/others/cursor.dart'; import '../../../widgets/others/default_styles.dart'; import '../../../widgets/others/delegate.dart'; import '../../../widgets/others/link.dart'; +import '../../../widgets/quill/quill_controller.dart'; import '../../../widgets/raw_editor/raw_editor.dart'; import '../../../widgets/raw_editor/raw_editor_state.dart'; import '../../themes/quill_dialog_theme.dart'; diff --git a/lib/src/models/config/toolbar/simple_toolbar_configurations.dart b/lib/src/models/config/toolbar/simple_toolbar_configurations.dart index 300547360..c9f0ffeb5 100644 --- a/lib/src/models/config/toolbar/simple_toolbar_configurations.dart +++ b/lib/src/models/config/toolbar/simple_toolbar_configurations.dart @@ -4,8 +4,8 @@ import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' show Axis, Widget, WrapAlignment, WrapCrossAlignment; -import '../../../widgets/quill/quill_controller.dart'; import '../../../widgets/quill/embeds.dart'; +import '../../../widgets/quill/quill_controller.dart'; import '../../themes/quill_dialog_theme.dart'; import '../../themes/quill_icon_theme.dart'; import 'buttons/base_configurations.dart'; diff --git a/lib/src/packages/quill_markdown/custom_quill_attributes.dart b/lib/src/packages/quill_markdown/custom_quill_attributes.dart index bb62ddbd4..fef8a953e 100644 --- a/lib/src/packages/quill_markdown/custom_quill_attributes.dart +++ b/lib/src/packages/quill_markdown/custom_quill_attributes.dart @@ -1,4 +1,4 @@ -import 'package:flutter_quill/flutter_quill.dart'; +import '../../../flutter_quill.dart'; /// Custom attribute to save the language of codeblock class CodeBlockLanguageAttribute extends Attribute { diff --git a/lib/src/packages/quill_markdown/delta_to_markdown.dart b/lib/src/packages/quill_markdown/delta_to_markdown.dart index cfeb97f62..ba1518b7d 100644 --- a/lib/src/packages/quill_markdown/delta_to_markdown.dart +++ b/lib/src/packages/quill_markdown/delta_to_markdown.dart @@ -2,7 +2,7 @@ import 'dart:convert'; import 'dart:ui'; import 'package:collection/collection.dart'; -import 'package:flutter_quill/flutter_quill.dart'; +import '../../../flutter_quill.dart'; import './custom_quill_attributes.dart'; import './utils.dart'; diff --git a/lib/src/packages/quill_markdown/embeddable_table_syntax.dart b/lib/src/packages/quill_markdown/embeddable_table_syntax.dart index d33e703c5..d6375cd4e 100644 --- a/lib/src/packages/quill_markdown/embeddable_table_syntax.dart +++ b/lib/src/packages/quill_markdown/embeddable_table_syntax.dart @@ -1,7 +1,8 @@ import 'package:charcode/charcode.dart'; -import 'package:flutter_quill/flutter_quill.dart' hide Node; import 'package:markdown/markdown.dart'; +import '../../../flutter_quill.dart' hide Node; + /// Parses markdown table and saves the table markdown content into the element attributes. class EmbeddableTableSyntax extends BlockSyntax { /// @nodoc diff --git a/lib/src/packages/quill_markdown/markdown_to_delta.dart b/lib/src/packages/quill_markdown/markdown_to_delta.dart index d4bca2e7d..76f5b4ba0 100644 --- a/lib/src/packages/quill_markdown/markdown_to_delta.dart +++ b/lib/src/packages/quill_markdown/markdown_to_delta.dart @@ -2,9 +2,9 @@ import 'dart:collection'; import 'dart:convert'; import 'package:collection/collection.dart'; -import 'package:flutter_quill/flutter_quill.dart'; import 'package:markdown/markdown.dart' as md; +import '../../../flutter_quill.dart'; import './custom_quill_attributes.dart'; import './embeddable_table_syntax.dart'; import './utils.dart'; diff --git a/lib/src/packages/quill_markdown/utils.dart b/lib/src/packages/quill_markdown/utils.dart index c5843ec5c..ba4c6b859 100644 --- a/lib/src/packages/quill_markdown/utils.dart +++ b/lib/src/packages/quill_markdown/utils.dart @@ -1,5 +1,5 @@ //ignore_for_file: cast_nullable_to_non_nullable -import 'package:flutter_quill/flutter_quill.dart'; +import '../../../flutter_quill.dart'; import './embeddable_table_syntax.dart'; diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index 0017b68c0..df8040e11 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -18,9 +18,9 @@ import '../../utils/platform.dart'; import '../others/box.dart'; import '../others/cursor.dart'; import '../others/delegate.dart'; -import '../quill/embeds.dart'; import '../others/float_cursor.dart'; import '../others/text_selection.dart'; +import '../quill/embeds.dart'; import '../raw_editor/raw_editor.dart'; import '../utils/provider.dart'; import 'editor_builder.dart'; diff --git a/lib/src/widgets/quill/text_block.dart b/lib/src/widgets/quill/text_block.dart index c13c5eeb1..6510357d6 100644 --- a/lib/src/widgets/quill/text_block.dart +++ b/lib/src/widgets/quill/text_block.dart @@ -8,17 +8,17 @@ import '../../models/documents/nodes/line.dart'; import '../../models/structs/vertical_spacing.dart'; import '../../utils/delta.dart'; import '../editor/editor.dart'; -import '../style_widgets/bullet_point.dart'; -import '../style_widgets/checkbox_point.dart'; -import '../style_widgets/number_point.dart'; import '../others/box.dart'; -import 'quill_controller.dart'; import '../others/cursor.dart'; import '../others/default_styles.dart'; import '../others/delegate.dart'; import '../others/link.dart'; -import 'text_line.dart'; import '../others/text_selection.dart'; +import '../style_widgets/bullet_point.dart'; +import '../style_widgets/checkbox_point.dart'; +import '../style_widgets/number_point.dart'; +import 'quill_controller.dart'; +import 'text_line.dart'; const List arabianRomanNumbers = [ 1000, diff --git a/lib/src/widgets/quill/text_line.dart b/lib/src/widgets/quill/text_line.dart index 7ec68bd4a..c1b68f42d 100644 --- a/lib/src/widgets/quill/text_line.dart +++ b/lib/src/widgets/quill/text_line.dart @@ -11,8 +11,8 @@ import 'package:url_launcher/url_launcher.dart'; import '../../models/documents/attribute.dart'; import '../../models/documents/nodes/container.dart' as container_node; import '../../models/documents/nodes/embeddable.dart'; -import '../../models/documents/nodes/leaf.dart'; import '../../models/documents/nodes/leaf.dart' as leaf; +import '../../models/documents/nodes/leaf.dart'; import '../../models/documents/nodes/line.dart'; import '../../models/documents/nodes/node.dart'; import '../../models/documents/style.dart'; @@ -21,7 +21,6 @@ import '../../utils/color.dart'; import '../../utils/font.dart'; import '../../utils/platform.dart'; import '../others/box.dart'; -import 'quill_controller.dart'; import '../others/cursor.dart'; import '../others/default_styles.dart'; import '../others/delegate.dart'; @@ -29,6 +28,7 @@ import '../others/keyboard_listener.dart'; import '../others/link.dart'; import '../others/proxy.dart'; import '../others/text_selection.dart'; +import 'quill_controller.dart'; class TextLine extends StatefulWidget { const TextLine({ diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index 64d1e28c0..3a9dfd608 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -36,15 +36,15 @@ import '../../utils/delta.dart'; import '../../utils/embeds.dart'; import '../../utils/platform.dart'; import '../editor/editor.dart'; -import '../quill/quill_controller.dart'; import '../others/cursor.dart'; import '../others/default_styles.dart'; import '../others/keyboard_listener.dart'; import '../others/link.dart'; import '../others/proxy.dart'; +import '../others/text_selection.dart'; +import '../quill/quill_controller.dart'; import '../quill/text_block.dart'; import '../quill/text_line.dart'; -import '../others/text_selection.dart'; import 'quill_single_child_scroll_view.dart'; import 'raw_editor.dart'; import 'raw_editor_actions.dart'; diff --git a/lib/src/widgets/toolbar/buttons/link_style2_button.dart b/lib/src/widgets/toolbar/buttons/link_style2_button.dart index 63372fbae..8fec6c3a6 100644 --- a/lib/src/widgets/toolbar/buttons/link_style2_button.dart +++ b/lib/src/widgets/toolbar/buttons/link_style2_button.dart @@ -10,8 +10,8 @@ import '../../../l10n/widgets/localizations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/themes/quill_dialog_theme.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../quill/quill_controller.dart'; import '../../others/link.dart'; +import '../../quill/quill_controller.dart'; import '../base_toolbar.dart'; /// Alternative version of [QuillToolbarLinkStyleButton]. This widget has more diff --git a/lib/src/widgets/toolbar/buttons/link_style_button.dart b/lib/src/widgets/toolbar/buttons/link_style_button.dart index 21d87dff6..33ae60e9c 100644 --- a/lib/src/widgets/toolbar/buttons/link_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/link_style_button.dart @@ -8,8 +8,8 @@ import '../../../models/rules/insert.dart'; import '../../../models/structs/link_dialog_action.dart'; import '../../../models/themes/quill_dialog_theme.dart'; import '../../../models/themes/quill_icon_theme.dart'; -import '../../quill/quill_controller.dart'; import '../../others/link.dart'; +import '../../quill/quill_controller.dart'; import '../base_toolbar.dart'; class QuillToolbarLinkStyleButton extends StatefulWidget { From 748c58c4a6f9fa7cf0b3ef0edffd837ee5ce5c88 Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 7 Dec 2023 20:44:15 +0300 Subject: [PATCH 51/86] Prepare dev version 8 --- flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/pubspec.yaml | 2 +- packages/quill_html_converter/pubspec.yaml | 2 +- pubspec.yaml | 2 +- version.dart | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index ea0fcdd92..8f3cf2068 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: 9.0.0-dev-7 +version: 9.0.0-dev-8 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 7e442cc7a..e50efc52b 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: 9.0.0-dev-7 +version: 9.0.0-dev-8 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index 32c279ef5..a5aa9589f 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.0.0-dev-7 +version: 9.0.0-dev-8 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 5efb4f162..7d396197b 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: 9.0.0-dev-7 +version: 9.0.0-dev-8 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/version.dart b/version.dart index 78f02741d..27a78c104 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev-7'; +const version = '9.0.0-dev-8'; From 1174f1ed71357357ecff94df8baa79e8bde3743f Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 7 Dec 2023 20:57:26 +0300 Subject: [PATCH 52/86] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++-- example/lib/presentation/quill/quill_screen.dart | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52b9aadd2..09d629a35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,12 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev-7 -* Fix a bug in chaning the background/font color of ol/ul list +## 9.0.0-dev-8 * Better support for pasting HTML contents from external websites to the editor * The experimental support of converting the HTML from `quill_html_converter` is now built-in in the `flutter_quill` and removed from there (Breaking change for `quill_html_converter`) + +## 9.0.0-dev-7 +* Fix a bug in chaning the background/font color of ol/ul list * Flutter Quill Extensions: * Fix link bug in the video url * Fix patterns diff --git a/example/lib/presentation/quill/quill_screen.dart b/example/lib/presentation/quill/quill_screen.dart index 51908827e..b3b73eee5 100644 --- a/example/lib/presentation/quill/quill_screen.dart +++ b/example/lib/presentation/quill/quill_screen.dart @@ -126,6 +126,7 @@ class _QuillScreenState extends State { sharedConfigurations: _sharedConfigurations, controller: _controller, readOnly: _isReadOnly, + customStyles: const DefaultStyles(), elementOptions: const QuillEditorElementOptions( codeBlock: QuillEditorCodeBlockElementOptions( enableLineNumbers: true, From f0fa2d13ab04ef7e344ec3b5dc28d7cf58a65ab8 Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 7 Dec 2023 21:01:06 +0300 Subject: [PATCH 53/86] Update CHANGELOG.md --- flutter_quill_extensions/CHANGELOG.md | 6 ++++-- flutter_quill_test/CHANGELOG.md | 6 ++++-- packages/quill_html_converter/CHANGELOG.md | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 52b9aadd2..09d629a35 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,10 +2,12 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev-7 -* Fix a bug in chaning the background/font color of ol/ul list +## 9.0.0-dev-8 * Better support for pasting HTML contents from external websites to the editor * The experimental support of converting the HTML from `quill_html_converter` is now built-in in the `flutter_quill` and removed from there (Breaking change for `quill_html_converter`) + +## 9.0.0-dev-7 +* Fix a bug in chaning the background/font color of ol/ul list * Flutter Quill Extensions: * Fix link bug in the video url * Fix patterns diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 52b9aadd2..09d629a35 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -2,10 +2,12 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev-7 -* Fix a bug in chaning the background/font color of ol/ul list +## 9.0.0-dev-8 * Better support for pasting HTML contents from external websites to the editor * The experimental support of converting the HTML from `quill_html_converter` is now built-in in the `flutter_quill` and removed from there (Breaking change for `quill_html_converter`) + +## 9.0.0-dev-7 +* Fix a bug in chaning the background/font color of ol/ul list * Flutter Quill Extensions: * Fix link bug in the video url * Fix patterns diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index 52b9aadd2..09d629a35 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -2,10 +2,12 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev-7 -* Fix a bug in chaning the background/font color of ol/ul list +## 9.0.0-dev-8 * Better support for pasting HTML contents from external websites to the editor * The experimental support of converting the HTML from `quill_html_converter` is now built-in in the `flutter_quill` and removed from there (Breaking change for `quill_html_converter`) + +## 9.0.0-dev-7 +* Fix a bug in chaning the background/font color of ol/ul list * Flutter Quill Extensions: * Fix link bug in the video url * Fix patterns From 1aab0c7d816930060a3e85584e4f56820bdfb4f7 Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 7 Dec 2023 21:20:42 +0300 Subject: [PATCH 54/86] Update doc and README.md --- README.md | 32 +++--- doc/custom_embed_blocks.md | 8 +- doc/custom_toolbar.md | 224 ++++++++++++++++--------------------- doc/translation.md | 24 ++-- 4 files changed, 127 insertions(+), 161 deletions(-) diff --git a/README.md b/README.md index 750f7a74f..71dea7328 100644 --- a/README.md +++ b/README.md @@ -96,10 +96,9 @@ dependencies: @@ -126,24 +125,23 @@ connect the `QuillController` to them using `QuillProvider` inherited widget ```dart -QuillProvider( - configurations: QuillConfigurations( +QuillToolbar.simple( + configurations: QuillSimpleToolbarConfigurations( controller: _controller, sharedConfigurations: const QuillSharedConfigurations( locale: Locale('de'), ), ), - child: Column( - children: [ - const QuillToolbar(), - Expanded( - child: QuillEditor.basic( - configurations: const QuillEditorConfigurations( - readOnly: false, - ), - ), - ) - ], +), +Expanded( + child: QuillEditor.basic( + configurations: QuillEditorConfigurations( + controller: _controller, + readOnly: false, + sharedConfigurations: const QuillSharedConfigurations( + locale: Locale('de'), + ), + ), ), ) ``` diff --git a/doc/custom_embed_blocks.md b/doc/custom_embed_blocks.md index 2b6093b9e..a4f3b7001 100644 --- a/doc/custom_embed_blocks.md +++ b/doc/custom_embed_blocks.md @@ -88,14 +88,10 @@ Future _addEditNote(BuildContext context, {Document? document}) async { ) ], ), - content: QuillProvider( - configurations: QuillConfigurations( - controller: quillEditorController, - ), - child: QuillEditor.basic( + content: QuillEditor.basic( configurations: const QuillEditorConfigurations( + controller: quillEditorController, readOnly: false, - ), ), ), ), diff --git a/doc/custom_toolbar.md b/doc/custom_toolbar.md index 39040ca8d..fc661b6d5 100644 --- a/doc/custom_toolbar.md +++ b/doc/custom_toolbar.md @@ -6,134 +6,108 @@ You can use the `QuillBaseToolbar` which is the base for the `QuillToolbar` Example: ```dart -QuillProvider( - configurations: QuillConfigurations( - controller: _controller, - sharedConfigurations: const QuillSharedConfigurations(), - ), - child: Column( - children: [ - QuillBaseToolbar( - configurations: QuillBaseToolbarConfigurations( - toolbarSize: 15 * 2, - multiRowsDisplay: false, - childrenBuilder: (context) { - final controller = context.requireQuillController; - return [ - QuillToolbarImageButton( - controller: controller, - options: const QuillToolbarImageButtonOptions(), - ), - 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, - ), - ), - ]; - }, - ), +QuillToolbar( + configurations: const QuillToolbarConfigurations( + buttonOptions: QuillToolbarButtonOptions( + base: QuillToolbarBaseButtonOptions( + globalIconSize: 20, + globalIconButtonFactor: 1.4, ), - Expanded( - child: QuillEditor.basic( - configurations: const QuillEditorConfigurations( - readOnly: false, - placeholder: 'Write your notes', - padding: EdgeInsets.all(16), + ), + ), + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + IconButton( + onPressed: () => context + .read() + .updateSettings( + state.copyWith(useCustomQuillToolbar: false)), + icon: const Icon( + Icons.width_normal, ), ), - ) - ], + QuillToolbarHistoryButton( + isUndo: true, + controller: controller, + ), + QuillToolbarHistoryButton( + isUndo: false, + controller: controller, + ), + QuillToolbarToggleStyleButton( + options: const QuillToolbarToggleStyleButtonOptions(), + controller: controller, + attribute: Attribute.bold, + ), + QuillToolbarToggleStyleButton( + options: const QuillToolbarToggleStyleButtonOptions(), + controller: controller, + attribute: Attribute.italic, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.underline, + ), + QuillToolbarClearFormatButton( + controller: controller, + ), + const VerticalDivider(), + QuillToolbarImageButton( + controller: controller, + ), + QuillToolbarCameraButton( + controller: controller, + ), + QuillToolbarVideoButton( + controller: controller, + ), + const VerticalDivider(), + QuillToolbarColorButton( + controller: controller, + isBackground: false, + ), + QuillToolbarColorButton( + controller: controller, + isBackground: true, + ), + const VerticalDivider(), + QuillToolbarSelectHeaderStyleButton( + controller: controller, + ), + const VerticalDivider(), + QuillToolbarToggleCheckListButton( + controller: controller, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.ol, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.ul, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.inlineCode, + ), + QuillToolbarToggleStyleButton( + controller: controller, + attribute: Attribute.blockQuote, + ), + QuillToolbarIndentButton( + controller: controller, + isIncrease: true, + ), + QuillToolbarIndentButton( + controller: controller, + isIncrease: false, + ), + const VerticalDivider(), + QuillToolbarLinkStyleButton(controller: controller), + ], + ), ), ) ``` diff --git a/doc/translation.md b/doc/translation.md index 5d801ba80..f98e64baa 100644 --- a/doc/translation.md +++ b/doc/translation.md @@ -3,24 +3,22 @@ The package offers translations for the quill toolbar and editor, it will follow the locale that is defined in your `WidgetsApp` for example `MaterialApp` which usually follows the system locally unless you set your own locale with: ```dart - QuillProvider( - configurations: QuillConfigurations( +QuillToolbar.simple( + configurations: QuillSimpleToolbarConfigurations( controller: _controller, sharedConfigurations: const QuillSharedConfigurations( - locale: Locale('fr'), // will take affect only if FlutterQuillLocalizations.delegate is not defined in the Widget app + locale: Locale('de'), ), ), - child: Column( - children: [ - const QuillToolbar( - configurations: QuillToolbarConfigurations(), +), +Expanded( + child: QuillEditor.basic( + configurations: QuillEditorConfigurations( + controller: _controller, + sharedConfigurations: const QuillSharedConfigurations( + locale: Locale('de'), ), - Expanded( - child: QuillEditor.basic( - configurations: const QuillEditorConfigurations(), - ), - ) - ], + ), ), ) ``` From 6c5bd5d2771a78ed7a4a1e731c9a522b28c674f3 Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 7 Dec 2023 20:59:21 +0300 Subject: [PATCH 55/86] Update main workflow name --- .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 f006ccb39..9e4b19eeb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,4 +1,4 @@ -name: Flutter Quill CI +name: CI Tests on: push: From 67adb199babd85e14e79fde601c50dc2a083d7d3 Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 7 Dec 2023 23:17:20 +0300 Subject: [PATCH 56/86] Improves the new logic of pasting HTML contents into the Editor --- CHANGELOG.md | 4 ++++ lib/src/widgets/raw_editor/raw_editor_state.dart | 12 +----------- version.dart | 2 +- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09d629a35..0b30a16d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-9 +* Improves the new logic of pasting HTML contents into the Editor +* Update `README.md` and the doc + ## 9.0.0-dev-8 * Better support for pasting HTML contents from external websites to the editor * The experimental support of converting the HTML from `quill_html_converter` is now built-in in the `flutter_quill` and removed from there (Breaking change for `quill_html_converter`) diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index 3a9dfd608..c09189f5a 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -237,17 +237,7 @@ class QuillRawEditorState extends EditorState deltaFromCliboard = QuillController.fromHtml(html); } if (deltaFromCliboard != null) { - // final index = selection.baseOffset; - // final length = selection.extentOffset - index; - - final list = controller.document.toDelta().toList() - ..insertAll(controller.document.toDelta().toList().length - 1, - deltaFromCliboard.toList()); - - final delta = controller.document.toDelta(); - for (final operation in list) { - delta.push(operation); - } + final delta = controller.document.toDelta().compose(deltaFromCliboard); controller ..updateDocument( diff --git a/version.dart b/version.dart index 27a78c104..9cac290fc 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev-8'; +const version = '9.0.0-dev-9'; From af5ac58497ed4c2b1ce2dd858309a80e59c25020 Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 7 Dec 2023 23:23:44 +0300 Subject: [PATCH 57/86] Cleanup code --- lib/src/widgets/raw_editor/raw_editor_state.dart | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index c09189f5a..3bca17097 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -226,17 +226,13 @@ class QuillRawEditorState extends EditorState return; } - // TODO: Could be improved - Delta? deltaFromCliboard; final reader = await ClipboardReader.readClipboard(); if (reader.canProvide(Formats.htmlText)) { final html = await reader.readValue(Formats.htmlText); if (html == null) { return; } - deltaFromCliboard = QuillController.fromHtml(html); - } - if (deltaFromCliboard != null) { + final deltaFromCliboard = QuillController.fromHtml(html); final delta = controller.document.toDelta().compose(deltaFromCliboard); controller From 0be81a7bf943651478778b7fce98bdbed936acbf Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 7 Dec 2023 23:58:05 +0300 Subject: [PATCH 58/86] Add new todo --- doc/todo.md | 1 + .../widgets/raw_editor/raw_editor_state.dart | 20 ------------------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/doc/todo.md b/doc/todo.md index 813a90669..01401c114 100644 --- a/doc/todo.md +++ b/doc/todo.md @@ -33,6 +33,7 @@ This is a todo list page that added recently and will be updated soon. - Change the color of the numbers and dots in ol/ul to match the ones in the item list - Fix the bugs of the font family and font size - Try to update Quill Html Converter + - When pasting a HTML text from cliboard by not using the context menu builder, the new logic won't work ### Bugs diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index 3bca17097..aaf32405b 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -117,26 +117,6 @@ class QuillRawEditorState extends EditorState .call(content); } - // List get contextMenuButtonItems { - // return EditableText.getEditableButtonItems( - // clipboardStatus: _clipboardStatus.value, - // onLiveTextInput: null, - // onCopy: copyEnabled - // ? () => copySelection(SelectionChangedCause.toolbar) - // : null, - // onCut: - // cutEnabled ? () => cutSelection(SelectionChangedCause.toolbar) : null, - // onPaste: - // pasteEnabled ? () => pasteText(SelectionChangedCause.toolbar) : null, - // onSelectAll: selectAllEnabled - // ? () => selectAll(SelectionChangedCause.toolbar) - // : null, - // onLookUp: null, - // onSearchWeb: null, - // onShare: null, - // ); - // } - /// Copy current selection to [Clipboard]. @override void copySelection(SelectionChangedCause cause) { From 615a0a21f9a54da2f49b8a587769248c9497b4a3 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 00:11:04 +0300 Subject: [PATCH 59/86] Update font family button to material 3 --- .../buttons/font_family_configurations.dart | 13 ------------ lib/src/widgets/quill/quill_controller.dart | 8 +++++++ .../toolbar/buttons/font_family_button.dart | 21 ++++++++++++------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/src/models/config/toolbar/buttons/font_family_configurations.dart b/lib/src/models/config/toolbar/buttons/font_family_configurations.dart index 5674232cf..74b9f35bd 100644 --- a/lib/src/models/config/toolbar/buttons/font_family_configurations.dart +++ b/lib/src/models/config/toolbar/buttons/font_family_configurations.dart @@ -50,17 +50,10 @@ class QuillToolbarFontFamilyButtonOptions extends QuillToolbarBaseButtonOptions< this.itemPadding, this.defaultItemColor = Colors.red, this.renderFontFamilies = true, - this.highlightElevation = 1, - this.hoverElevation = 1, - this.fillColor, this.iconSize, this.iconButtonFactor, }); - final Color? fillColor; - final double hoverElevation; - final double highlightElevation; - /// By default it will be [fontFamilyValues] from [QuillSimpleToolbarConfigurations] /// You can override this if you want final Map? rawItemsMap; @@ -83,9 +76,6 @@ class QuillToolbarFontFamilyButtonOptions extends QuillToolbarBaseButtonOptions< final double? iconButtonFactor; QuillToolbarFontFamilyButtonOptions copyWith({ - Color? fillColor, - double? hoverElevation, - double? highlightElevation, List>? items, Map? rawItemsMap, ValueChanged? onSelected, @@ -131,9 +121,6 @@ class QuillToolbarFontFamilyButtonOptions extends QuillToolbarBaseButtonOptions< 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/widgets/quill/quill_controller.dart b/lib/src/widgets/quill/quill_controller.dart index fd3403003..f9f89f6a7 100644 --- a/lib/src/widgets/quill/quill_controller.dart +++ b/lib/src/widgets/quill/quill_controller.dart @@ -59,6 +59,14 @@ class QuillController extends ChangeNotifier { notifyListeners(); } + /// The current font family, null to use the default one + String? _selectedFontFamily; + String? get selectedFontFamily => _selectedFontFamily; + + void selectFontFamily(String newFontFamily) { + _selectedFontFamily = selectedFontFamily; + } + /// Tells whether to keep or reset the [toggledStyle] /// when user adds a new line. final bool _keepStyleOnNewLine; diff --git a/lib/src/widgets/toolbar/buttons/font_family_button.dart b/lib/src/widgets/toolbar/buttons/font_family_button.dart index 8714d6fa3..edc115d2e 100644 --- a/lib/src/widgets/toolbar/buttons/font_family_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_family_button.dart @@ -184,17 +184,19 @@ class QuillToolbarFontFamilyButtonState } return Tooltip(message: effectiveTooltip, child: child); }, - child: RawMaterialButton( + child: IconButton( + // tooltip: '', // TODO: Use this here visualDensity: VisualDensity.compact, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(iconTheme?.borderRadius ?? 2), + style: IconButton.styleFrom( + shape: iconTheme?.borderRadius != null + ? RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(iconTheme?.borderRadius ?? -1), + ) + : null, ), - fillColor: options.fillColor, - elevation: 0, - hoverElevation: options.hoverElevation, - highlightElevation: options.hoverElevation, onPressed: _onPressed, - child: _buildContent(context), + icon: _buildContent(context), ), ), ); @@ -222,6 +224,9 @@ class QuillToolbarFontFamilyButtonState value: fontFamily.value, height: options.itemHeight ?? kMinInteractiveDimension, padding: options.itemPadding, + onTap: () { + controller.selectFontFamily(fontFamily.value); + }, child: Text( fontFamily.key.toString(), style: TextStyle( From 2283d8b3cebe513f66e3b1595e4c208a41db2c58 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 00:47:46 +0300 Subject: [PATCH 60/86] Improve font family button --- CHANGELOG.md | 3 + example/devtools_options.yaml | 1 + lib/src/widgets/quill/quill_controller.dart | 2 +- .../widgets/raw_editor/raw_editor_state.dart | 1 - ..._editor_state_text_input_client_mixin.dart | 18 +++++- .../toolbar/buttons/font_family_button.dart | 61 ++++++++++--------- .../buttons/select_header_style_button.dart | 18 ++++++ 7 files changed, 73 insertions(+), 31 deletions(-) create mode 100644 example/devtools_options.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b30a16d8..027e88975 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file. ## 9.0.0-dev-9 * Improves the new logic of pasting HTML contents into the Editor * Update `README.md` and the doc +* Dispose the `QuillToolbarSelectHeaderStyleButton` state listener in `dispose` +* Upgrade the font family button to material 3 +* Rework the font family functionallity to change the font once and type all over the editor ## 9.0.0-dev-8 * Better support for pasting HTML contents from external websites to the editor diff --git a/example/devtools_options.yaml b/example/devtools_options.yaml new file mode 100644 index 000000000..7e7e7f67d --- /dev/null +++ b/example/devtools_options.yaml @@ -0,0 +1 @@ +extensions: diff --git a/lib/src/widgets/quill/quill_controller.dart b/lib/src/widgets/quill/quill_controller.dart index f9f89f6a7..2ca84b8b7 100644 --- a/lib/src/widgets/quill/quill_controller.dart +++ b/lib/src/widgets/quill/quill_controller.dart @@ -64,7 +64,7 @@ class QuillController extends ChangeNotifier { String? get selectedFontFamily => _selectedFontFamily; void selectFontFamily(String newFontFamily) { - _selectedFontFamily = selectedFontFamily; + _selectedFontFamily = newFontFamily; } /// Tells whether to keep or reset the [toggledStyle] diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index aaf32405b..ce52e406b 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -28,7 +28,6 @@ import '../../models/documents/nodes/embeddable.dart'; import '../../models/documents/nodes/leaf.dart' as leaf; import '../../models/documents/nodes/line.dart'; import '../../models/documents/nodes/node.dart'; -import '../../models/quill_delta.dart'; import '../../models/structs/offset_value.dart'; import '../../models/structs/vertical_spacing.dart'; import '../../utils/cast.dart'; 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 2c6a08daa..d5dd41692 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 @@ -7,6 +7,7 @@ import 'package:flutter/material.dart' show Theme; import 'package:flutter/scheduler.dart' show SchedulerBinding; import 'package:flutter/services.dart'; +import '../../models/documents/attribute.dart'; import '../../models/documents/document.dart'; import '../../utils/delta.dart'; import '../editor/editor.dart'; @@ -200,7 +201,22 @@ mixin RawEditorStateTextInputClientMixin on EditorState .updateSelection(value.selection, ChangeSource.local); } else { widget.configurations.controller.replaceText( - diff.start, diff.deleted.length, diff.inserted, value.selection); + diff.start, + diff.deleted.length, + diff.inserted, + value.selection, + ); + print(widget.configurations.controller.selectedFontFamily != null); + if (widget.configurations.controller.selectedFontFamily != null) { + widget.configurations.controller.formatText( + diff.start, + diff.deleted.length, + Attribute.fromKeyValue( + Attribute.font.key, + widget.configurations.controller.selectedFontFamily, + ), + ); + } } } diff --git a/lib/src/widgets/toolbar/buttons/font_family_button.dart b/lib/src/widgets/toolbar/buttons/font_family_button.dart index edc115d2e..24d24c0c7 100644 --- a/lib/src/widgets/toolbar/buttons/font_family_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_family_button.dart @@ -51,39 +51,39 @@ class QuillToolbarFontFamilyButtonState void _initState() { _currentValue = _defaultDisplayText; - controller.addListener(_didChangeEditingValue); + // controller.addListener(_didChangeEditingValue); } - @override - void dispose() { - controller.removeListener(_didChangeEditingValue); - super.dispose(); - } + // @override + // void dispose() { + // controller.removeListener(_didChangeEditingValue); + // super.dispose(); + // } String get _defaultDisplayText { return options.initialValue ?? widget.defaultDispalyText; } - @override - void didUpdateWidget(covariant QuillToolbarFontFamilyButton oldWidget) { - super.didUpdateWidget(oldWidget); - if (oldWidget.controller == controller) { - return; - } - controller - ..removeListener(_didChangeEditingValue) - ..addListener(_didChangeEditingValue); - } + // @override + // void didUpdateWidget(covariant QuillToolbarFontFamilyButton oldWidget) { + // super.didUpdateWidget(oldWidget); + // if (oldWidget.controller == controller) { + // return; + // } + // controller + // ..removeListener(_didChangeEditingValue) + // ..addListener(_didChangeEditingValue); + // } - void _didChangeEditingValue() { - final attribute = _selectionStyle.attributes[options.attribute.key]; - if (attribute == null) { - setState(() => _currentValue = _defaultDisplayText); - return; - } - final keyName = _getKeyName(attribute.value); - setState(() => _currentValue = keyName ?? _defaultDisplayText); - } + // void _didChangeEditingValue() { + // final attribute = _selectionStyle.attributes[options.attribute.key]; + // if (attribute == null) { + // setState(() => _currentValue = _defaultDisplayText); + // return; + // } + // final keyName = _getKeyName(attribute.value); + // setState(() => _currentValue = keyName ?? _defaultDisplayText); + // } Map get rawItemsMap { final rawItemsMap = @@ -225,6 +225,9 @@ class QuillToolbarFontFamilyButtonState height: options.itemHeight ?? kMinInteractiveDimension, padding: options.itemPadding, onTap: () { + if (fontFamily.value == 'Clear') { + return; + } controller.selectFontFamily(fontFamily.value); }, child: Text( @@ -251,11 +254,13 @@ class QuillToolbarFontFamilyButtonState } final keyName = _getKeyName(newValue); setState(() { - _currentValue = keyName ?? _defaultDisplayText; + if (keyName != 'Clear') { + _currentValue = keyName ?? _defaultDisplayText; + } if (keyName != null) { controller.formatSelection( Attribute.fromKeyValue( - 'font', + Attribute.font.key, newValue == 'Clear' ? null : newValue, ), ); @@ -277,7 +282,7 @@ class QuillToolbarFontFamilyButtonState enabled: hasFinalWidth, wrapper: (child) => Expanded(child: child), child: Text( - _currentValue, + widget.controller.selectedFontFamily ?? _currentValue, maxLines: 1, overflow: options.labelOverflow, style: options.style ?? diff --git a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart index 1e92c84fd..da04b84aa 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart @@ -37,6 +37,24 @@ class _QuillToolbarSelectHeaderStyleButtonState widget.controller.addListener(_didChangeEditingValue); } + @override + void dispose() { + widget.controller.removeListener(_didChangeEditingValue); + super.dispose(); + } + + @override + void didUpdateWidget( + covariant QuillToolbarSelectHeaderStyleButton oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.controller == widget.controller) { + return; + } + widget.controller + ..removeListener(_didChangeEditingValue) + ..addListener(_didChangeEditingValue); + } + void _didChangeEditingValue() { final newSelectedItem = _getOptionsItemByAttribute(_getHeaderValue()); if (newSelectedItem == _selectedItem) { From f8fc9d874cdf71004fcebe6013b193dbdf88fd0d Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 00:49:12 +0300 Subject: [PATCH 61/86] Fix analysis warrnings --- .../raw_editor/raw_editor_state_text_input_client_mixin.dart | 1 - lib/src/widgets/toolbar/buttons/font_family_button.dart | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) 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 d5dd41692..b285d1f88 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 @@ -206,7 +206,6 @@ mixin RawEditorStateTextInputClientMixin on EditorState diff.inserted, value.selection, ); - print(widget.configurations.controller.selectedFontFamily != null); if (widget.configurations.controller.selectedFontFamily != null) { widget.configurations.controller.formatText( diff.start, diff --git a/lib/src/widgets/toolbar/buttons/font_family_button.dart b/lib/src/widgets/toolbar/buttons/font_family_button.dart index 24d24c0c7..3cfc4de4a 100644 --- a/lib/src/widgets/toolbar/buttons/font_family_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_family_button.dart @@ -41,7 +41,7 @@ class QuillToolbarFontFamilyButtonState return widget.options; } - Style get _selectionStyle => controller.getSelectionStyle(); + // Style get _selectionStyle => controller.getSelectionStyle(); @override void initState() { From 03610e9a871b9a2c4e76fd438c4693994957537e Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 01:15:43 +0300 Subject: [PATCH 62/86] Improve font size button --- CHANGELOG.md | 2 +- flutter_quill_extensions/CHANGELOG.md | 7 ++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 7 ++ flutter_quill_test/pubspec.yaml | 2 +- .../buttons/font_size_configurations.dart | 27 ++++--- lib/src/widgets/quill/quill_controller.dart | 10 ++- ..._editor_state_text_input_client_mixin.dart | 15 ++++ .../toolbar/buttons/font_family_button.dart | 4 +- .../toolbar/buttons/font_size_button.dart | 71 ++++++++----------- packages/quill_html_converter/CHANGELOG.md | 7 ++ packages/quill_html_converter/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 13 files changed, 93 insertions(+), 65 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 027e88975..888f66926 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. * Update `README.md` and the doc * Dispose the `QuillToolbarSelectHeaderStyleButton` state listener in `dispose` * Upgrade the font family button to material 3 -* Rework the font family functionallity to change the font once and type all over the editor +* Rework the font family and font size functionallities to change the font once and type all over the editor ## 9.0.0-dev-8 * Better support for pasting HTML contents from external websites to the editor diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 09d629a35..888f66926 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-9 +* Improves the new logic of pasting HTML contents into the Editor +* Update `README.md` and the doc +* Dispose the `QuillToolbarSelectHeaderStyleButton` state listener in `dispose` +* Upgrade the font family button to material 3 +* Rework the font family and font size functionallities to change the font once and type all over the editor + ## 9.0.0-dev-8 * Better support for pasting HTML contents from external websites to the editor * The experimental support of converting the HTML from `quill_html_converter` is now built-in in the `flutter_quill` and removed from there (Breaking change for `quill_html_converter`) diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 8f3cf2068..58d8952aa 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: 9.0.0-dev-8 +version: 9.0.0-dev-9 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 09d629a35..888f66926 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-9 +* Improves the new logic of pasting HTML contents into the Editor +* Update `README.md` and the doc +* Dispose the `QuillToolbarSelectHeaderStyleButton` state listener in `dispose` +* Upgrade the font family button to material 3 +* Rework the font family and font size functionallities to change the font once and type all over the editor + ## 9.0.0-dev-8 * Better support for pasting HTML contents from external websites to the editor * The experimental support of converting the HTML from `quill_html_converter` is now built-in in the `flutter_quill` and removed from there (Breaking change for `quill_html_converter`) diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index e50efc52b..75e9d5a95 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: 9.0.0-dev-8 +version: 9.0.0-dev-9 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/lib/src/models/config/toolbar/buttons/font_size_configurations.dart b/lib/src/models/config/toolbar/buttons/font_size_configurations.dart index ec3c66825..37ba61f11 100644 --- a/lib/src/models/config/toolbar/buttons/font_size_configurations.dart +++ b/lib/src/models/config/toolbar/buttons/font_size_configurations.dart @@ -2,13 +2,18 @@ import 'dart:ui'; import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/material.dart' - show Colors, PopupMenuEntry, ValueChanged; + show ButtonStyle, Colors, PopupMenuEntry, ValueChanged; import 'package:flutter/widgets.dart' - show Color, EdgeInsets, EdgeInsetsGeometry, TextOverflow, TextStyle; + show + Color, + EdgeInsets, + EdgeInsetsGeometry, + OutlinedBorder, + TextOverflow, + TextStyle; import '../../../../widgets/quill/quill_controller.dart'; import '../../../documents/attribute.dart'; -import '../../../themes/quill_icon_theme.dart'; import '../../quill_configurations.dart'; class QuillToolbarFontSizeButtonExtraOptions @@ -31,12 +36,8 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions< const QuillToolbarFontSizeButtonOptions({ this.iconSize, this.iconButtonFactor, - this.fillColor, - this.hoverElevation = 1, - this.highlightElevation = 1, this.rawItemsMap, this.onSelected, - super.iconTheme, this.attribute = Attribute.size, super.controller, super.afterButtonPressed, @@ -50,13 +51,13 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions< this.itemPadding, this.defaultItemColor = Colors.red, super.childBuilder, + this.shape, }); final double? iconSize; final double? iconButtonFactor; - final Color? fillColor; - final double hoverElevation; - final double highlightElevation; + + final ButtonStyle? shape; /// By default it will be [fontSizesValues] from [QuillSimpleToolbarConfigurations] /// You can override this if you want @@ -92,15 +93,12 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions< Color? defaultItemColor, VoidCallback? afterButtonPressed, String? tooltip, - QuillIconTheme? iconTheme, QuillController? controller, + OutlinedBorder? shape, }) { return QuillToolbarFontSizeButtonOptions( iconSize: iconSize ?? this.iconSize, iconButtonFactor: iconButtonFactor ?? this.iconButtonFactor, - fillColor: fillColor ?? this.fillColor, - hoverElevation: hoverElevation ?? this.hoverElevation, - highlightElevation: highlightElevation ?? this.highlightElevation, rawItemsMap: rawItemsMap ?? this.rawItemsMap, onSelected: onSelected ?? this.onSelected, attribute: attribute ?? this.attribute, @@ -113,7 +111,6 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions< itemPadding: itemPadding ?? this.itemPadding, defaultItemColor: defaultItemColor ?? this.defaultItemColor, tooltip: tooltip ?? super.tooltip, - iconTheme: iconTheme ?? super.iconTheme, afterButtonPressed: afterButtonPressed ?? super.afterButtonPressed, controller: controller ?? super.controller, ); diff --git a/lib/src/widgets/quill/quill_controller.dart b/lib/src/widgets/quill/quill_controller.dart index 2ca84b8b7..8bbf10950 100644 --- a/lib/src/widgets/quill/quill_controller.dart +++ b/lib/src/widgets/quill/quill_controller.dart @@ -63,10 +63,18 @@ class QuillController extends ChangeNotifier { String? _selectedFontFamily; String? get selectedFontFamily => _selectedFontFamily; - void selectFontFamily(String newFontFamily) { + void selectFontFamily(String? newFontFamily) { _selectedFontFamily = newFontFamily; } + /// The current font size, null to use the default one + String? _selectedFontSize; + String? get selectedFontSize => _selectedFontSize; + + void selectFontSize(String? newFontSize) { + _selectedFontSize = newFontSize; + } + /// Tells whether to keep or reset the [toggledStyle] /// when user adds a new line. final bool _keepStyleOnNewLine; 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 b285d1f88..9d51c5743 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 @@ -10,6 +10,7 @@ import 'package:flutter/services.dart'; import '../../models/documents/attribute.dart'; import '../../models/documents/document.dart'; import '../../utils/delta.dart'; +import '../../utils/font.dart'; import '../editor/editor.dart'; import 'raw_editor.dart'; @@ -216,6 +217,20 @@ mixin RawEditorStateTextInputClientMixin on EditorState ), ); } + + if (widget.configurations.controller.selectedFontSize != null) { + widget.configurations.controller.formatText( + diff.start, + diff.deleted.length, + Attribute.fromKeyValue( + Attribute.size.key, + widget.configurations.controller.selectedFontSize == '0' + ? null + : getFontSize( + widget.configurations.controller.selectedFontSize), + ), + ); + } } } diff --git a/lib/src/widgets/toolbar/buttons/font_family_button.dart b/lib/src/widgets/toolbar/buttons/font_family_button.dart index 3cfc4de4a..17c87fb92 100644 --- a/lib/src/widgets/toolbar/buttons/font_family_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_family_button.dart @@ -5,7 +5,6 @@ import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/config/toolbar/buttons/font_family_configurations.dart'; import '../../../models/documents/attribute.dart'; -import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../quill/quill_controller.dart'; @@ -226,6 +225,7 @@ class QuillToolbarFontFamilyButtonState padding: options.itemPadding, onTap: () { if (fontFamily.value == 'Clear') { + controller.selectFontFamily(null); return; } controller.selectFontFamily(fontFamily.value); @@ -256,6 +256,8 @@ class QuillToolbarFontFamilyButtonState setState(() { if (keyName != 'Clear') { _currentValue = keyName ?? _defaultDisplayText; + } else { + _currentValue = _defaultDisplayText; } if (keyName != null) { controller.formatSelection( diff --git a/lib/src/widgets/toolbar/buttons/font_size_button.dart b/lib/src/widgets/toolbar/buttons/font_size_button.dart index d1ee7752e..048c5fb3f 100644 --- a/lib/src/widgets/toolbar/buttons/font_size_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_size_button.dart @@ -57,47 +57,17 @@ class QuillToolbarFontSizeButtonState return options.initialValue ?? widget.defaultDisplayText; } - Style get _selectionStyle => controller.getSelectionStyle(); - @override void initState() { super.initState(); - - _initState(); - } - - void _initState() { _currentValue = _defaultDisplayText; - controller.addListener(_didChangeEditingValue); } @override void dispose() { - controller.removeListener(_didChangeEditingValue); super.dispose(); } - @override - void didUpdateWidget(covariant QuillToolbarFontSizeButton oldWidget) { - super.didUpdateWidget(oldWidget); - if (controller == oldWidget.controller) { - return; - } - controller - ..removeListener(_didChangeEditingValue) - ..addListener(_didChangeEditingValue); - } - - void _didChangeEditingValue() { - final attribute = _selectionStyle.attributes[options.attribute.key]; - if (attribute == null) { - setState(() => _currentValue = _defaultDisplayText); - return; - } - final keyName = _getKeyName(attribute.value); - setState(() => _currentValue = keyName ?? _defaultDisplayText); - } - String? _getKeyName(dynamic value) { for (final entry in rawItemsMap.entries) { if (getFontSize(entry.value) == getFontSize(value)) { @@ -157,7 +127,6 @@ class QuillToolbarFontSizeButtonState tooltip: tooltip, iconSize: iconSize, iconButtonFactor: iconButtonFactor, - iconTheme: iconTheme, afterButtonPressed: afterButtonPressed, controller: controller, ), @@ -177,17 +146,18 @@ class QuillToolbarFontSizeButtonState ), child: UtilityWidgets.maybeTooltip( message: tooltip, - child: RawMaterialButton( + child: IconButton( visualDensity: VisualDensity.compact, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(iconTheme?.borderRadius ?? 2), + style: IconButton.styleFrom( + shape: iconTheme?.borderRadius != null + ? RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(iconTheme?.borderRadius ?? -1), + ) + : null, ), - fillColor: options.fillColor, - elevation: 0, - hoverElevation: options.hoverElevation, - highlightElevation: options.hoverElevation, onPressed: _onPressed, - child: _buildContent(context), + icon: _buildContent(context), ), ), ); @@ -215,6 +185,13 @@ class QuillToolbarFontSizeButtonState value: fontSize.value, height: options.itemHeight ?? kMinInteractiveDimension, padding: options.itemPadding, + onTap: () { + if (fontSize.value == '0') { + controller.selectFontSize(null); + return; + } + controller.selectFontSize(fontSize.value); + }, child: Text( fontSize.key.toString(), style: TextStyle( @@ -233,10 +210,18 @@ class QuillToolbarFontSizeButtonState } final keyName = _getKeyName(newValue); setState(() { - _currentValue = keyName ?? _defaultDisplayText; + if (keyName != 'Clear') { + _currentValue = keyName ?? _defaultDisplayText; + } else { + _currentValue = _defaultDisplayText; + } if (keyName != null) { - controller.formatSelection(Attribute.fromKeyValue( - 'size', newValue == '0' ? null : getFontSize(newValue))); + controller.formatSelection( + Attribute.fromKeyValue( + Attribute.size.key, + newValue == '0' ? null : getFontSize(newValue), + ), + ); options.onSelected?.call(newValue); } }); @@ -255,7 +240,7 @@ class QuillToolbarFontSizeButtonState enabled: hasFinalWidth, wrapper: (child) => Expanded(child: child), child: Text( - _currentValue, + widget.controller.selectedFontSize ?? _currentValue, overflow: options.labelOverflow, style: options.style ?? TextStyle( diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index 09d629a35..888f66926 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-9 +* Improves the new logic of pasting HTML contents into the Editor +* Update `README.md` and the doc +* Dispose the `QuillToolbarSelectHeaderStyleButton` state listener in `dispose` +* Upgrade the font family button to material 3 +* Rework the font family and font size functionallities to change the font once and type all over the editor + ## 9.0.0-dev-8 * Better support for pasting HTML contents from external websites to the editor * The experimental support of converting the HTML from `quill_html_converter` is now built-in in the `flutter_quill` and removed from there (Breaking change for `quill_html_converter`) diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index a5aa9589f..4cc603a59 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.0.0-dev-8 +version: 9.0.0-dev-9 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 7d396197b..e26b0f7cf 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: 9.0.0-dev-8 +version: 9.0.0-dev-9 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 7266ed9c6f34b9fdf275f263871ed49e1b0c0161 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 01:17:37 +0300 Subject: [PATCH 63/86] Update workflows --- .github/workflows/build.yml | 2 +- .github/workflows/main.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5fdd3e33b..207173d07 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: Build the example on: pull_request: - branches: [master] + branches: [master, dev] jobs: tests: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9e4b19eeb..81cc2bd53 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,9 +2,9 @@ name: CI Tests on: push: - branches: [master] + branches: [master, dev] pull_request: - branches: [master] + branches: [master, dev] jobs: tests: From 94235df8dcce062d2598c4f31a7b604b0efefcbd Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 01:20:47 +0300 Subject: [PATCH 64/86] Fix analysis warrning --- lib/src/widgets/toolbar/buttons/font_size_button.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/src/widgets/toolbar/buttons/font_size_button.dart b/lib/src/widgets/toolbar/buttons/font_size_button.dart index 048c5fb3f..54a14b6bd 100644 --- a/lib/src/widgets/toolbar/buttons/font_size_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_size_button.dart @@ -5,7 +5,6 @@ import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/config/quill_configurations.dart'; import '../../../models/documents/attribute.dart'; -import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../../utils/font.dart'; import '../../quill/quill_controller.dart'; From 3218ee0f1f092c53b67a52083d2b3389d423e1b0 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 01:22:37 +0300 Subject: [PATCH 65/86] Fix a typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 888f66926..50ef4b524 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. * Update `README.md` and the doc * Dispose the `QuillToolbarSelectHeaderStyleButton` state listener in `dispose` * Upgrade the font family button to material 3 -* Rework the font family and font size functionallities to change the font once and type all over the editor +* Rework the font family and font size functionalities to change the font once and type all over the editor ## 9.0.0-dev-8 * Better support for pasting HTML contents from external websites to the editor From a1e73a52c8b4b1244ec5c6f9f3a0a227b2a59197 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 09:41:43 +0300 Subject: [PATCH 66/86] Update simple toolbar --- doc/todo.md | 1 + lib/src/widgets/quill/text_line.dart | 10 +++++++--- lib/src/widgets/toolbar/simple_toolbar.dart | 20 ++++++++++---------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/doc/todo.md b/doc/todo.md index 01401c114..1800df56b 100644 --- a/doc/todo.md +++ b/doc/todo.md @@ -34,6 +34,7 @@ This is a todo list page that added recently and will be updated soon. - Fix the bugs of the font family and font size - Try to update Quill Html Converter - When pasting a HTML text from cliboard by not using the context menu builder, the new logic won't work + - Add strike-through in checkbox text when the checkpoint is checked ### Bugs diff --git a/lib/src/widgets/quill/text_line.dart b/lib/src/widgets/quill/text_line.dart index c1b68f42d..cdf493ff5 100644 --- a/lib/src/widgets/quill/text_line.dart +++ b/lib/src/widgets/quill/text_line.dart @@ -164,7 +164,8 @@ class _TextLineState extends State { } } final textSpan = _getTextSpanForWholeLine(); - final strutStyle = StrutStyle.fromTextStyle(textSpan.style!); + final strutStyle = + StrutStyle.fromTextStyle(textSpan.style ?? const TextStyle()); final textAlign = _getTextAlign(); final child = RichText( key: _richTextKey, @@ -247,8 +248,11 @@ class _TextLineState extends State { return TextAlign.start; } - TextSpan _buildTextSpan(DefaultStyles defaultStyles, LinkedList nodes, - TextStyle lineStyle) { + TextSpan _buildTextSpan( + DefaultStyles defaultStyles, + LinkedList nodes, + TextStyle lineStyle, + ) { if (nodes.isEmpty && kIsWeb) { nodes = LinkedList()..add(leaf.QuillText('\u{200B}')); } diff --git a/lib/src/widgets/toolbar/simple_toolbar.dart b/lib/src/widgets/toolbar/simple_toolbar.dart index 9794b3127..4f91cb346 100644 --- a/lib/src/widgets/toolbar/simple_toolbar.dart +++ b/lib/src/widgets/toolbar/simple_toolbar.dart @@ -133,6 +133,16 @@ class QuillSimpleToolbar extends StatelessWidget ), spacerWidget, ], + if (configurations.showStrikeThrough) ...[ + QuillToolbarToggleStyleButton( + attribute: Attribute.strikeThrough, + options: toolbarConfigurations.buttonOptions.strikeThrough, + controller: + toolbarConfigurations.buttonOptions.strikeThrough.controller ?? + globalController, + ), + spacerWidget, + ], if (configurations.showInlineCode) ...[ QuillToolbarToggleStyleButton( attribute: Attribute.inlineCode, @@ -172,16 +182,6 @@ class QuillSimpleToolbar extends StatelessWidget ), spacerWidget, ], - if (configurations.showStrikeThrough) ...[ - QuillToolbarToggleStyleButton( - attribute: Attribute.strikeThrough, - options: toolbarConfigurations.buttonOptions.strikeThrough, - controller: - toolbarConfigurations.buttonOptions.strikeThrough.controller ?? - globalController, - ), - spacerWidget, - ], if (configurations.showColorButton) ...[ QuillToolbarColorButton( controller: toolbarConfigurations.buttonOptions.color.controller ?? From 12527e8038f2e16647fb4524a88aa0807b3c8d19 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 10:19:25 +0300 Subject: [PATCH 67/86] fix delta from cliboard compose --- .../lib/embeds/video/editor/video_embed.dart | 3 +++ lib/src/models/documents/document.dart | 1 + lib/src/widgets/raw_editor/raw_editor_state.dart | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/flutter_quill_extensions/lib/embeds/video/editor/video_embed.dart b/flutter_quill_extensions/lib/embeds/video/editor/video_embed.dart index fd1cd8fc5..292f7ada0 100644 --- a/flutter_quill_extensions/lib/embeds/video/editor/video_embed.dart +++ b/flutter_quill_extensions/lib/embeds/video/editor/video_embed.dart @@ -18,6 +18,9 @@ class QuillEditorVideoEmbedBuilder extends EmbedBuilder { @override String get key => BlockEmbed.videoType; + @override + bool get expanded => false; + @override Widget build( BuildContext context, diff --git a/lib/src/models/documents/document.dart b/lib/src/models/documents/document.dart index e0efbdf8e..74a532a88 100644 --- a/lib/src/models/documents/document.dart +++ b/lib/src/models/documents/document.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import '../../widgets/others/cursor.dart'; import '../../widgets/quill/embeds.dart'; import '../quill_delta.dart'; import '../rules/rule.dart'; diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index ce52e406b..31cffbebe 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -212,7 +212,7 @@ class QuillRawEditorState extends EditorState return; } final deltaFromCliboard = QuillController.fromHtml(html); - final delta = controller.document.toDelta().compose(deltaFromCliboard); + final delta = deltaFromCliboard.compose(controller.document.toDelta()); controller ..updateDocument( From d657731e18e96c1dbd45ea4aa2a84ac3e974fbc4 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 10:20:05 +0300 Subject: [PATCH 68/86] Fix analysis warrning --- lib/src/models/documents/document.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/src/models/documents/document.dart b/lib/src/models/documents/document.dart index 74a532a88..70c48f67d 100644 --- a/lib/src/models/documents/document.dart +++ b/lib/src/models/documents/document.dart @@ -1,6 +1,5 @@ -import 'dart:async'; +import 'dart:async' show StreamController; -import '../../widgets/others/cursor.dart'; import '../../widgets/quill/embeds.dart'; import '../quill_delta.dart'; import '../rules/rule.dart'; From 59d436d1ba427386d5b02d368c7dd236b28cb0f7 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 10:23:14 +0300 Subject: [PATCH 69/86] Fix a bug of the improved pasting HTML contents contents into the editor --- CHANGELOG.md | 3 +++ flutter_quill_extensions/CHANGELOG.md | 5 ++++- flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 5 ++++- flutter_quill_test/pubspec.yaml | 2 +- packages/quill_html_converter/CHANGELOG.md | 5 ++++- packages/quill_html_converter/pubspec.yaml | 2 +- pubspec.yaml | 2 +- version.dart | 2 +- 9 files changed, 20 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50ef4b524..c9c37430c 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-10 +* Fix a bug of the improved pasting HTML contents contents into the editor + ## 9.0.0-dev-9 * Improves the new logic of pasting HTML contents into the Editor * Update `README.md` and the doc diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 888f66926..c9c37430c 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,12 +2,15 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-10 +* Fix a bug of the improved pasting HTML contents contents into the editor + ## 9.0.0-dev-9 * Improves the new logic of pasting HTML contents into the Editor * Update `README.md` and the doc * Dispose the `QuillToolbarSelectHeaderStyleButton` state listener in `dispose` * Upgrade the font family button to material 3 -* Rework the font family and font size functionallities to change the font once and type all over the editor +* Rework the font family and font size functionalities to change the font once and type all over the editor ## 9.0.0-dev-8 * Better support for pasting HTML contents from external websites to the editor diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 58d8952aa..27c6ee08a 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: 9.0.0-dev-9 +version: 9.0.0-dev-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/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 888f66926..c9c37430c 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -2,12 +2,15 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-10 +* Fix a bug of the improved pasting HTML contents contents into the editor + ## 9.0.0-dev-9 * Improves the new logic of pasting HTML contents into the Editor * Update `README.md` and the doc * Dispose the `QuillToolbarSelectHeaderStyleButton` state listener in `dispose` * Upgrade the font family button to material 3 -* Rework the font family and font size functionallities to change the font once and type all over the editor +* Rework the font family and font size functionalities to change the font once and type all over the editor ## 9.0.0-dev-8 * Better support for pasting HTML contents from external websites to the editor diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 75e9d5a95..93ce9d91e 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: 9.0.0-dev-9 +version: 9.0.0-dev-10 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index 888f66926..c9c37430c 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -2,12 +2,15 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev-10 +* Fix a bug of the improved pasting HTML contents contents into the editor + ## 9.0.0-dev-9 * Improves the new logic of pasting HTML contents into the Editor * Update `README.md` and the doc * Dispose the `QuillToolbarSelectHeaderStyleButton` state listener in `dispose` * Upgrade the font family button to material 3 -* Rework the font family and font size functionallities to change the font once and type all over the editor +* Rework the font family and font size functionalities to change the font once and type all over the editor ## 9.0.0-dev-8 * Better support for pasting HTML contents from external websites to the editor diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index 4cc603a59..370208b92 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.0.0-dev-9 +version: 9.0.0-dev-10 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index e26b0f7cf..348005958 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: 9.0.0-dev-9 +version: 9.0.0-dev-10 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/version.dart b/version.dart index 9cac290fc..dbcd3438d 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev-9'; +const version = '9.0.0-dev-10'; From 409360a55e370a7cd09ce1f6eb230304c27270e7 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 11:27:15 +0300 Subject: [PATCH 70/86] Update workflows --- .github/workflows/build.yml | 66 ++++++++++++++++++++++++++++++++----- .github/workflows/main.yml | 11 ------- version.dart | 2 +- 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 207173d07..ffabe7226 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,11 +1,15 @@ -name: Build the example +name: Build the app on: + push: + paths: + - 'pubspec.yaml' pull_request: - branches: [master, dev] + branches: [main, dev] jobs: - tests: + build_linux: + name: Build Linux and Web Apps runs-on: ubuntu-latest steps: @@ -17,20 +21,66 @@ jobs: - name: Check flutter version run: flutter --version - - - name: Enable Local Dev - run: ./scripts/enable_local_dev.sh + - name: Fallbacks + run: ./scripts/fallbacks.sh + - name: Install dependencies run: flutter pub get - name: Flutter build Web 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: Flutter build Linux run: flutter build linux --release --verbose --dart-define=CI=true - working-directory: ./example + + build_windows: + name: Build Windows App + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + - uses: subosito/flutter-action@v2 + with: + channel: 'stable' + cache: true + + - name: Check flutter version + run: flutter --version + + - name: Fallbacks + run: ./scripts/fallbacks.sh + + - name: Install dependencies + run: flutter pub get + + - name: Flutter build windows + run: flutter build windows --release --verbose --dart-define=CI=true + + build_macOS: + name: Build macOS App + runs-on: macos-latest + + steps: + - uses: actions/checkout@v4 + - uses: subosito/flutter-action@v2 + with: + channel: 'stable' + cache: true + + - name: Check flutter version + run: flutter --version + + - name: Fallbacks + run: ./scripts/fallbacks.sh + + - name: Install dependencies + run: flutter pub get + + - name: Flutter build macOS + run: flutter build macos --release --verbose --dart-define=CI=true + - name: Flutter build iOS + run: flutter build ios --release --verbose --dart-define=CI=true \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 81cc2bd53..5a709a98e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -49,14 +49,3 @@ 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 - - # - 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 diff --git a/version.dart b/version.dart index dbcd3438d..bb6c16a6e 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev-10'; +const version = '9.0.0-dev.10'; From 343dc4c5fd0a09999942b43bc82ea06f4a44e006 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 11:30:25 +0300 Subject: [PATCH 71/86] Prepare to publish new version --- CHANGELOG.md | 2 +- flutter_quill_extensions/CHANGELOG.md | 2 +- flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 2 +- flutter_quill_test/pubspec.yaml | 2 +- packages/quill_html_converter/CHANGELOG.md | 2 +- packages/quill_html_converter/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9c37430c..669b6233f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev-10 +## 9.0.0-dev.10 * Fix a bug of the improved pasting HTML contents contents into the editor ## 9.0.0-dev-9 diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index c9c37430c..669b6233f 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev-10 +## 9.0.0-dev.10 * Fix a bug of the improved pasting HTML contents contents into the editor ## 9.0.0-dev-9 diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 27c6ee08a..89350624b 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: 9.0.0-dev-10 +version: 9.0.0-dev.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/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index c9c37430c..669b6233f 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev-10 +## 9.0.0-dev.10 * Fix a bug of the improved pasting HTML contents contents into the editor ## 9.0.0-dev-9 diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 93ce9d91e..61642c7f0 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: 9.0.0-dev-10 +version: 9.0.0-dev.10 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index c9c37430c..669b6233f 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev-10 +## 9.0.0-dev.10 * Fix a bug of the improved pasting HTML contents contents into the editor ## 9.0.0-dev-9 diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index 370208b92..fa68696de 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.0.0-dev-10 +version: 9.0.0-dev.10 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 348005958..6fa0a39bf 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: 9.0.0-dev-10 +version: 9.0.0-dev.10 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 675deabd6b758ce318c9db6c48acf8cf8aaa8c25 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 11:31:41 +0300 Subject: [PATCH 72/86] Update build.yml --- .github/workflows/build.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ffabe7226..b12d2dfb1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,9 +21,6 @@ jobs: - name: Check flutter version run: flutter --version - - - name: Fallbacks - run: ./scripts/fallbacks.sh - name: Install dependencies run: flutter pub get From a3ec1b925b1672618d71124cbe76b0f5a51cade8 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 11:35:20 +0300 Subject: [PATCH 73/86] Update build.yml --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b12d2dfb1..71dadd232 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,6 +21,9 @@ jobs: - name: Check flutter version run: flutter --version + + - name: Enable Local Dev + run: ./scripts/enable_local_dev.sh - name: Install dependencies run: flutter pub get From b9d9260c607ec58ce4540a343ea5c17b4d635424 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 11:37:18 +0300 Subject: [PATCH 74/86] Prepare for release --- CHANGELOG.md | 2 +- flutter_quill_extensions/CHANGELOG.md | 2 +- flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 2 +- flutter_quill_test/pubspec.yaml | 2 +- packages/quill_html_converter/CHANGELOG.md | 2 +- packages/quill_html_converter/pubspec.yaml | 2 +- pubspec.yaml | 2 +- version.dart | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 669b6233f..c9c37430c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev.10 +## 9.0.0-dev-10 * Fix a bug of the improved pasting HTML contents contents into the editor ## 9.0.0-dev-9 diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 669b6233f..c9c37430c 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev.10 +## 9.0.0-dev-10 * Fix a bug of the improved pasting HTML contents contents into the editor ## 9.0.0-dev-9 diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 89350624b..27c6ee08a 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: 9.0.0-dev.10 +version: 9.0.0-dev-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/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 669b6233f..c9c37430c 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev.10 +## 9.0.0-dev-10 * Fix a bug of the improved pasting HTML contents contents into the editor ## 9.0.0-dev-9 diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 61642c7f0..93ce9d91e 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: 9.0.0-dev.10 +version: 9.0.0-dev-10 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index 669b6233f..c9c37430c 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev.10 +## 9.0.0-dev-10 * Fix a bug of the improved pasting HTML contents contents into the editor ## 9.0.0-dev-9 diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index fa68696de..370208b92 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.0.0-dev.10 +version: 9.0.0-dev-10 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 6fa0a39bf..348005958 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: 9.0.0-dev.10 +version: 9.0.0-dev-10 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/version.dart b/version.dart index bb6c16a6e..dbcd3438d 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev.10'; +const version = '9.0.0-dev-10'; From a8f5dad0eb3c71048ceb833b962e7b1c4d6c2d84 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 11:41:45 +0300 Subject: [PATCH 75/86] An attemp to fix CI failures --- .github/workflows/build.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 71dadd232..508c809d1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,12 +30,14 @@ jobs: - name: Flutter build Web 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: Flutter build Linux run: flutter build linux --release --verbose --dart-define=CI=true + working-directory: ./example build_windows: name: Build Windows App @@ -59,6 +61,7 @@ jobs: - name: Flutter build windows run: flutter build windows --release --verbose --dart-define=CI=true + working-directory: ./example build_macOS: name: Build macOS App @@ -82,5 +85,7 @@ jobs: - name: Flutter build macOS run: flutter build macos --release --verbose --dart-define=CI=true + working-directory: ./example - name: Flutter build iOS - run: flutter build ios --release --verbose --dart-define=CI=true \ No newline at end of file + run: flutter build ios --release --verbose --dart-define=CI=true + working-directory: ./example \ No newline at end of file From b8f4af9095d087373d3cbd768ca477e3e013b197 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 11:44:10 +0300 Subject: [PATCH 76/86] Prepare for new version 11 --- CHANGELOG.md | 3 +++ flutter_quill_extensions/CHANGELOG.md | 3 +++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 3 +++ flutter_quill_test/pubspec.yaml | 2 +- packages/quill_html_converter/CHANGELOG.md | 3 +++ packages/quill_html_converter/pubspec.yaml | 2 +- pubspec.yaml | 2 +- version.dart | 2 +- 9 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9c37430c..61308f027 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.11 +* Test new GitHub workflows + ## 9.0.0-dev-10 * Fix a bug of the improved pasting HTML contents contents into the editor diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index c9c37430c..61308f027 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev.11 +* Test new GitHub workflows + ## 9.0.0-dev-10 * Fix a bug of the improved pasting HTML contents contents into the editor diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 27c6ee08a..cab57255c 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: 9.0.0-dev-10 +version: 9.0.0-dev.11 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index c9c37430c..61308f027 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev.11 +* Test new GitHub workflows + ## 9.0.0-dev-10 * Fix a bug of the improved pasting HTML contents contents into the editor diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 93ce9d91e..f7c7d1e26 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: 9.0.0-dev-10 +version: 9.0.0-dev.11 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index c9c37430c..61308f027 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +## 9.0.0-dev.11 +* Test new GitHub workflows + ## 9.0.0-dev-10 * Fix a bug of the improved pasting HTML contents contents into the editor diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index 370208b92..b036cbb41 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.0.0-dev-10 +version: 9.0.0-dev.11 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 348005958..6857b502c 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: 9.0.0-dev-10 +version: 9.0.0-dev.11 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/version.dart b/version.dart index dbcd3438d..b062dc883 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev-10'; +const version = '9.0.0-dev.11'; From 063390b121f2532256f2e01065c6e5f370ccb233 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 11:47:00 +0300 Subject: [PATCH 77/86] An attemp to fix CI build failures --- .github/workflows/build.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 508c809d1..e47e45bbd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -52,9 +52,6 @@ jobs: - name: Check flutter version run: flutter --version - - - name: Fallbacks - run: ./scripts/fallbacks.sh - name: Install dependencies run: flutter pub get @@ -76,9 +73,6 @@ jobs: - name: Check flutter version run: flutter --version - - - name: Fallbacks - run: ./scripts/fallbacks.sh - name: Install dependencies run: flutter pub get From 0e278e331b7a6c130575ae496321940b33bb059a Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 11:48:18 +0300 Subject: [PATCH 78/86] Update pubspec.yaml --- .github/workflows/build.yml | 1 + pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e47e45bbd..115750a9b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -80,6 +80,7 @@ jobs: - name: Flutter build macOS run: flutter build macos --release --verbose --dart-define=CI=true working-directory: ./example + - name: Flutter build iOS run: flutter build ios --release --verbose --dart-define=CI=true working-directory: ./example \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 6857b502c..9da1c40c6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -52,7 +52,7 @@ dependencies: equatable: ^2.0.5 meta: ^1.9.1 - # For Quill HTML + # For converting HTML to Quill delta markdown: ^7.1.1 html2md: ^1.3.1 From c75e984271240288b1849ca65f723f2b0770f18a Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 11:51:30 +0300 Subject: [PATCH 79/86] Update pubspec.yaml and update build.yml --- .github/workflows/build.yml | 10 ++++++++-- pubspec.yaml | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 115750a9b..2647b4250 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Build the app +name: Build the example on: push: @@ -52,6 +52,9 @@ jobs: - name: Check flutter version run: flutter --version + + - name: Enable Local Dev + run: ./scripts/enable_local_dev.sh - name: Install dependencies run: flutter pub get @@ -73,6 +76,9 @@ jobs: - name: Check flutter version run: flutter --version + + - name: Enable Local Dev + run: ./scripts/enable_local_dev.sh - name: Install dependencies run: flutter pub get @@ -80,7 +86,7 @@ jobs: - name: Flutter build macOS run: flutter build macos --release --verbose --dart-define=CI=true working-directory: ./example - + - name: Flutter build iOS run: flutter build ios --release --verbose --dart-define=CI=true working-directory: ./example \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 9da1c40c6..f83a843ea 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -55,13 +55,13 @@ dependencies: # For converting HTML to Quill delta markdown: ^7.1.1 html2md: ^1.3.1 + charcode: ^1.3.1 # Plugins url_launcher: ^6.1.14 flutter_keyboard_visibility: ^5.4.1 device_info_plus: ^9.1.0 super_clipboard: ^0.7.3 - charcode: ^1.3.1 dev_dependencies: flutter_lints: ^3.0.1 From 34030f172b1a8d20f15ba41813cee6d9b9b76443 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 11:55:36 +0300 Subject: [PATCH 80/86] Disable windows build --- .github/workflows/build.yml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2647b4250..e9ecadd23 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,29 +39,29 @@ jobs: run: flutter build linux --release --verbose --dart-define=CI=true working-directory: ./example - build_windows: - name: Build Windows App - runs-on: windows-latest + # build_windows: + # name: Build Windows App + # runs-on: windows-latest - steps: - - uses: actions/checkout@v4 - - uses: subosito/flutter-action@v2 - with: - channel: 'stable' - cache: true + # steps: + # - uses: actions/checkout@v4 + # - uses: subosito/flutter-action@v2 + # with: + # channel: 'stable' + # cache: true - - name: Check flutter version - run: flutter --version + # - name: Check flutter version + # run: flutter --version - - name: Enable Local Dev - run: ./scripts/enable_local_dev.sh + # - name: Enable Local Dev + # run: ./scripts/enable_local_dev.sh - - name: Install dependencies - run: flutter pub get + # - name: Install dependencies + # run: flutter pub get - - name: Flutter build windows - run: flutter build windows --release --verbose --dart-define=CI=true - working-directory: ./example + # - name: Flutter build windows + # run: flutter build windows --release --verbose --dart-define=CI=true + # working-directory: ./example build_macOS: name: Build macOS App From cb04c3b5f5f5aa6a88693e713b389e55bb457815 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 11:58:49 +0300 Subject: [PATCH 81/86] Update build.yml --- .github/workflows/build.yml | 43 +++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e9ecadd23..600d65e44 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,6 +53,7 @@ jobs: # - name: Check flutter version # run: flutter --version + # # Sh scripts is not supported on windows # - name: Enable Local Dev # run: ./scripts/enable_local_dev.sh @@ -63,30 +64,30 @@ jobs: # run: flutter build windows --release --verbose --dart-define=CI=true # working-directory: ./example - build_macOS: - name: Build macOS App - runs-on: macos-latest + # build_macOS: + # name: Build macOS App + # runs-on: macos-latest - steps: - - uses: actions/checkout@v4 - - uses: subosito/flutter-action@v2 - with: - channel: 'stable' - cache: true + # steps: + # - uses: actions/checkout@v4 + # - uses: subosito/flutter-action@v2 + # with: + # channel: 'stable' + # cache: true - - name: Check flutter version - run: flutter --version + # - name: Check flutter version + # run: flutter --version - - name: Enable Local Dev - run: ./scripts/enable_local_dev.sh + # - name: Enable Local Dev + # run: ./scripts/enable_local_dev.sh - - name: Install dependencies - run: flutter pub get + # - name: Install dependencies + # run: flutter pub get - - name: Flutter build macOS - run: flutter build macos --release --verbose --dart-define=CI=true - working-directory: ./example + # - name: Flutter build macOS + # run: flutter build macos --release --verbose --dart-define=CI=true + # working-directory: ./example - - name: Flutter build iOS - run: flutter build ios --release --verbose --dart-define=CI=true - working-directory: ./example \ No newline at end of file + # - name: Flutter build iOS + # run: flutter build ios --release --verbose --dart-define=CI=true + # working-directory: ./example \ No newline at end of file From bb13cd505775c3db9e37cc155f0abe8ca60962f3 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 12:03:15 +0300 Subject: [PATCH 82/86] 9.0.0-dev-11 --- CHANGELOG.md | 2 +- flutter_quill_extensions/CHANGELOG.md | 2 +- flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 2 +- flutter_quill_test/pubspec.yaml | 2 +- packages/quill_html_converter/CHANGELOG.md | 2 +- packages/quill_html_converter/pubspec.yaml | 2 +- pubspec.yaml | 2 +- version.dart | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61308f027..4392c9d05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev.11 +## 9.0.0-dev-11 * Test new GitHub workflows ## 9.0.0-dev-10 diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 61308f027..4392c9d05 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev.11 +## 9.0.0-dev-11 * Test new GitHub workflows ## 9.0.0-dev-10 diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index cab57255c..d328ff175 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: 9.0.0-dev.11 +version: 9.0.0-dev-11 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 61308f027..4392c9d05 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev.11 +## 9.0.0-dev-11 * Test new GitHub workflows ## 9.0.0-dev-10 diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index f7c7d1e26..e5856b719 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: 9.0.0-dev.11 +version: 9.0.0-dev-11 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/packages/quill_html_converter/CHANGELOG.md b/packages/quill_html_converter/CHANGELOG.md index 61308f027..4392c9d05 100644 --- a/packages/quill_html_converter/CHANGELOG.md +++ b/packages/quill_html_converter/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## 9.0.0-dev.11 +## 9.0.0-dev-11 * Test new GitHub workflows ## 9.0.0-dev-10 diff --git a/packages/quill_html_converter/pubspec.yaml b/packages/quill_html_converter/pubspec.yaml index b036cbb41..47f5796b8 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/packages/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.0.0-dev.11 +version: 9.0.0-dev-11 homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index f83a843ea..7c5063430 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: 9.0.0-dev.11 +version: 9.0.0-dev-11 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/version.dart b/version.dart index b062dc883..8ed75fba4 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.0.0-dev.11'; +const version = '9.0.0-dev-11'; From 0fd1125d4038087da3a7e2cb84ba9f570883d63a Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 12:05:25 +0300 Subject: [PATCH 83/86] Update build.yml to avoid duplications --- .github/workflows/build.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 600d65e44..1c020c25b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,8 +4,6 @@ on: push: paths: - 'pubspec.yaml' - pull_request: - branches: [main, dev] jobs: build_linux: From 34b8755cc9d384597919cd71be3a2b6c21364226 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 12:31:07 +0300 Subject: [PATCH 84/86] Add bug todo fix --- doc/todo.md | 3 +++ .../raw_editor/raw_editor_state_text_input_client_mixin.dart | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/doc/todo.md b/doc/todo.md index 1800df56b..21de47fe8 100644 --- a/doc/todo.md +++ b/doc/todo.md @@ -34,7 +34,10 @@ This is a todo list page that added recently and will be updated soon. - Fix the bugs of the font family and font size - Try to update Quill Html Converter - When pasting a HTML text from cliboard by not using the context menu builder, the new logic won't work + - When selecting all text and paste HTML text, it will not replace the current text, instead it will add a text - Add strike-through in checkbox text when the checkpoint is checked + - No more using of dynamic + - There is a bug here, the first character is not being formatted when choosing font family or font size and type in the editor ### Bugs 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 9d51c5743..aeb2135e7 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 @@ -207,6 +207,9 @@ mixin RawEditorStateTextInputClientMixin on EditorState diff.inserted, value.selection, ); + + // TODO: There is a bug here, the first character is not being formatted + if (widget.configurations.controller.selectedFontFamily != null) { widget.configurations.controller.formatText( diff.start, @@ -218,6 +221,8 @@ mixin RawEditorStateTextInputClientMixin on EditorState ); } + // TODO: A bug here too + if (widget.configurations.controller.selectedFontSize != null) { widget.configurations.controller.formatText( diff.start, From 6bbf680cc5eaabed7a5c96ad783610e26a1b6e79 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 8 Dec 2023 17:59:48 +0300 Subject: [PATCH 85/86] Add a bug todo --- lib/src/widgets/raw_editor/raw_editor_state.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index 31cffbebe..84af33167 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -205,6 +205,8 @@ class QuillRawEditorState extends EditorState return; } + // TODO: Bug, Doesn't replace the selected text, it just add a new one + final reader = await ClipboardReader.readClipboard(); if (reader.canProvide(Formats.htmlText)) { final html = await reader.readValue(Formats.htmlText); From 4df6b26bec49cfbd7f76d04916609207bc0f5f9d Mon Sep 17 00:00:00 2001 From: Ellet Date: Sat, 9 Dec 2023 00:56:10 +0300 Subject: [PATCH 86/86] Split quill delta into seperate package --- .github/workflows/main.yml | 2 +- .github/workflows/publish.yml | 2 +- .gitignore | 2 - README.md | 2 +- dart_quill_delta/.gitignore | 7 + dart_quill_delta/CHANGELOG.md | 3 + .../LICENSE | 0 dart_quill_delta/README.md | 2 + dart_quill_delta/analysis_options.yaml | 30 + .../example/dart_quill_delta_example.dart | 1 + dart_quill_delta/lib/dart_quill_delta.dart | 5 + dart_quill_delta/lib/src/delta/delta.dart | 562 ++++++ .../lib/src/delta/delta_iterator.dart | 100 + .../lib/src/operation/operation.dart | 171 ++ dart_quill_delta/pubspec.yaml | 20 + .../test/dart_quill_delta_test.dart | 11 + example/pubspec.yaml | 2 +- lib/src/models/quill_delta.dart | 1656 +++++++++-------- packages/README.md | 14 - .../pubspec_overrides.yaml.disabled | 3 - pubspec.yaml | 3 +- pubspec_overrides.yaml.disabled | 4 +- .../.gitignore | 0 .../.metadata | 0 .../CHANGELOG.md | 0 quill_html_converter/LICENSE | 21 + .../README.md | 0 .../analysis_options.yaml | 0 .../lib/quill_html_converter.dart | 2 +- .../pubspec.yaml | 11 +- .../pubspec_overrides.yaml.disabled | 3 + .../test/quill_html_converter.dart | 0 scripts/disable_local_dev.sh | 2 +- scripts/enable_local_dev.sh | 2 +- scripts/pub_get.sh | 2 +- scripts/regenerate_versions.dart | 2 +- 36 files changed, 1783 insertions(+), 864 deletions(-) create mode 100644 dart_quill_delta/.gitignore create mode 100644 dart_quill_delta/CHANGELOG.md rename {packages/quill_html_converter => dart_quill_delta}/LICENSE (100%) create mode 100644 dart_quill_delta/README.md create mode 100644 dart_quill_delta/analysis_options.yaml create mode 100644 dart_quill_delta/example/dart_quill_delta_example.dart create mode 100644 dart_quill_delta/lib/dart_quill_delta.dart create mode 100644 dart_quill_delta/lib/src/delta/delta.dart create mode 100644 dart_quill_delta/lib/src/delta/delta_iterator.dart create mode 100644 dart_quill_delta/lib/src/operation/operation.dart create mode 100644 dart_quill_delta/pubspec.yaml create mode 100644 dart_quill_delta/test/dart_quill_delta_test.dart delete mode 100644 packages/README.md delete mode 100644 packages/quill_html_converter/pubspec_overrides.yaml.disabled rename {packages/quill_html_converter => quill_html_converter}/.gitignore (100%) rename {packages/quill_html_converter => quill_html_converter}/.metadata (100%) rename {packages/quill_html_converter => quill_html_converter}/CHANGELOG.md (100%) create mode 100644 quill_html_converter/LICENSE rename {packages/quill_html_converter => quill_html_converter}/README.md (100%) rename {packages/quill_html_converter => quill_html_converter}/analysis_options.yaml (100%) rename {packages/quill_html_converter => quill_html_converter}/lib/quill_html_converter.dart (94%) rename {packages/quill_html_converter => quill_html_converter}/pubspec.yaml (80%) create mode 100644 quill_html_converter/pubspec_overrides.yaml.disabled rename {packages/quill_html_converter => quill_html_converter}/test/quill_html_converter.dart (100%) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5a709a98e..c4528f8d1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -33,7 +33,7 @@ jobs: run: flutter pub get -C flutter_quill_test - name: Install quill_html_converter dependencies - run: flutter pub get -C packages/quill_html_converter + run: flutter pub get -C quill_html_converter - name: Run flutter analysis run: flutter analyze diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 45970dc53..af93476e6 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -51,4 +51,4 @@ jobs: - name: Publish quill_html_converter run: flutter pub publish --force - working-directory: ./packages/quill_html_converter/ + working-directory: ./quill_html_converter/ diff --git a/.gitignore b/.gitignore index fc03c2767..9290cda2b 100644 --- a/.gitignore +++ b/.gitignore @@ -80,7 +80,5 @@ pubspec.lock # For local development pubspec_overrides.yaml -old_example - # A directory where you put all of your local things that you don't want to push .flutter-quill \ No newline at end of file diff --git a/README.md b/README.md index ecd67fb83..0bc825333 100644 --- a/README.md +++ b/README.md @@ -240,7 +240,7 @@ it to other formats such as HTML to publish it, or send an email. You have two options: -1. Using [quill_html_converter](./packages/quill_html_converter/) to convert to HTML, the package can convert the Quill delta to HTML well +1. Using [quill_html_converter](./quill_html_converter/) to convert to HTML, the package can convert the Quill delta to HTML well (it uses [vsc_quill_delta_to_html](https://pub.dev/packages/vsc_quill_delta_to_html)), it just a handy extension to do it more quickly 1. Another option is to use [vsc_quill_delta_to_html](https://pub.dev/packages/vsc_quill_delta_to_html) to convert your document diff --git a/dart_quill_delta/.gitignore b/dart_quill_delta/.gitignore new file mode 100644 index 000000000..3cceda557 --- /dev/null +++ b/dart_quill_delta/.gitignore @@ -0,0 +1,7 @@ +# https://dart.dev/guides/libraries/private-files +# Created by `dart pub` +.dart_tool/ + +# Avoid committing pubspec.lock for library packages; see +# https://dart.dev/guides/libraries/private-files#pubspeclock. +pubspec.lock diff --git a/dart_quill_delta/CHANGELOG.md b/dart_quill_delta/CHANGELOG.md new file mode 100644 index 000000000..59f8a732d --- /dev/null +++ b/dart_quill_delta/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* Initial version. diff --git a/packages/quill_html_converter/LICENSE b/dart_quill_delta/LICENSE similarity index 100% rename from packages/quill_html_converter/LICENSE rename to dart_quill_delta/LICENSE diff --git a/dart_quill_delta/README.md b/dart_quill_delta/README.md new file mode 100644 index 000000000..7d7aad35f --- /dev/null +++ b/dart_quill_delta/README.md @@ -0,0 +1,2 @@ +# Dart Quill Delta +A port of [quill-js-delta](https://github.com/quilljs/delta/) from typescript to dart \ No newline at end of file diff --git a/dart_quill_delta/analysis_options.yaml b/dart_quill_delta/analysis_options.yaml new file mode 100644 index 000000000..dee8927aa --- /dev/null +++ b/dart_quill_delta/analysis_options.yaml @@ -0,0 +1,30 @@ +# This file configures the static analysis results for your project (errors, +# warnings, and lints). +# +# This enables the 'recommended' set of lints from `package:lints`. +# This set helps identify many issues that may lead to problems when running +# or consuming Dart code, and enforces writing Dart using a single, idiomatic +# style and format. +# +# If you want a smaller set of lints you can change this to specify +# 'package:lints/core.yaml'. These are just the most critical lints +# (the recommended set includes the core lints). +# The core lints are also what is used by pub.dev for scoring packages. + +include: package:lints/recommended.yaml + +# Uncomment the following section to specify additional rules. + +# linter: +# rules: +# - camel_case_types + +# analyzer: +# exclude: +# - path/to/excluded/files/** + +# For more information about the core and recommended set of lints, see +# https://dart.dev/go/core-lints + +# For additional information about configuring this file, see +# https://dart.dev/guides/language/analysis-options diff --git a/dart_quill_delta/example/dart_quill_delta_example.dart b/dart_quill_delta/example/dart_quill_delta_example.dart new file mode 100644 index 000000000..ab73b3a23 --- /dev/null +++ b/dart_quill_delta/example/dart_quill_delta_example.dart @@ -0,0 +1 @@ +void main() {} diff --git a/dart_quill_delta/lib/dart_quill_delta.dart b/dart_quill_delta/lib/dart_quill_delta.dart new file mode 100644 index 000000000..d29a9063a --- /dev/null +++ b/dart_quill_delta/lib/dart_quill_delta.dart @@ -0,0 +1,5 @@ +library; + +export './src/delta/delta.dart'; +export './src/delta/delta_iterator.dart'; +export './src/operation/operation.dart'; diff --git a/dart_quill_delta/lib/src/delta/delta.dart b/dart_quill_delta/lib/src/delta/delta.dart new file mode 100644 index 000000000..cb3a60be6 --- /dev/null +++ b/dart_quill_delta/lib/src/delta/delta.dart @@ -0,0 +1,562 @@ +import 'dart:math' as math; + +import 'package:collection/collection.dart'; +import 'package:diff_match_patch/diff_match_patch.dart' as dmp; +import 'package:quiver/core.dart'; + +import '../operation/operation.dart'; +import 'delta_iterator.dart'; + +/// Delta represents a document or a modification of a document as a sequence of +/// insert, delete and retain operations. +/// +/// Delta consisting of only "insert" operations is usually referred to as +/// "document delta". When delta includes also "retain" or "delete" operations +/// it is a "change delta". +class Delta { + /// Creates new empty [Delta]. + factory Delta() => Delta._([]); + + Delta._(this.operations); + + /// Creates new [Delta] from [other]. + factory Delta.from(Delta other) => + Delta._(List.from(other.operations)); + + /// Creates new [Delta] from a List of Operation + factory Delta.fromOperations(List operations) => + Delta._(operations.toList()); + + // Placeholder char for embed in diff() + static final String _kNullCharacter = String.fromCharCode(0); + + /// Transforms two attribute sets. + static Map? transformAttributes( + Map? a, Map? b, bool priority) { + if (a == null) return b; + if (b == null) return null; + + if (!priority) return b; + + final result = b.keys.fold>({}, (attributes, key) { + if (!a.containsKey(key)) attributes[key] = b[key]; + return attributes; + }); + + return result.isEmpty ? null : result; + } + + /// Composes two attribute sets. + static Map? composeAttributes( + Map? a, Map? b, + {bool keepNull = false}) { + a ??= const {}; + b ??= const {}; + + final result = Map.from(a)..addAll(b); + final keys = result.keys.toList(growable: false); + + if (!keepNull) { + for (final key in keys) { + if (result[key] == null) result.remove(key); + } + } + + return result.isEmpty ? null : result; + } + + ///get anti-attr result base on base + static Map invertAttributes( + Map? attr, Map? base) { + attr ??= const {}; + base ??= const {}; + + final baseInverted = base.keys.fold({}, (dynamic memo, key) { + if (base![key] != attr![key] && attr.containsKey(key)) { + memo[key] = base[key]; + } + return memo; + }); + + final inverted = + Map.from(attr.keys.fold(baseInverted, (memo, key) { + if (base![key] != attr![key] && !base.containsKey(key)) { + memo[key] = null; + } + return memo; + })); + return inverted; + } + + /// Returns diff between two attribute sets + static Map? diffAttributes( + Map? a, Map? b) { + a ??= const {}; + b ??= const {}; + + final attributes = {}; + 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; + } + + final List operations; + + int modificationCount = 0; + + /// Creates [Delta] from de-serialized JSON representation. + /// + /// If `dataDecoder` parameter is not null then it is used to additionally + /// decode the operation's data object. Only applied to insert operations. + static Delta fromJson(List data, {DataDecoder? dataDecoder}) { + return Delta._(data + .map((op) => Operation.fromJson(op, dataDecoder: dataDecoder)) + .toList()); + } + + /// Returns list of operations in this delta. + List toList() => List.from(operations); + + /// Returns JSON-serializable version of this delta. + List toJson() => toList().map((operation) => operation.toJson()).toList(); + + /// Returns `true` if this delta is empty. + bool get isEmpty => operations.isEmpty; + + /// Returns `true` if this delta is not empty. + bool get isNotEmpty => operations.isNotEmpty; + + /// Returns number of operations in this delta. + int get length => operations.length; + + /// Returns [Operation] at specified [index] in this delta. + Operation operator [](int index) => operations[index]; + + /// Returns [Operation] at specified [index] in this delta. + Operation elementAt(int index) => operations.elementAt(index); + + /// Returns the first [Operation] in this delta. + Operation get first => operations.first; + + /// Returns the last [Operation] in this delta. + Operation get last => operations.last; + + @override + bool operator ==(dynamic other) { + if (identical(this, other)) return true; + if (other is! Delta) return false; + final typedOther = other; + const comparator = ListEquality(DefaultEquality()); + return comparator.equals(operations, typedOther.operations); + } + + @override + int get hashCode => hashObjects(operations); + + /// Retain [count] of characters from current position. + void retain(int count, [Map? attributes]) { + assert(count >= 0); + if (count == 0) return; // no-op + push(Operation.retain(count, attributes)); + } + + /// Insert [data] at current position. + void insert(dynamic data, [Map? attributes]) { + if (data is String && data.isEmpty) return; // no-op + push(Operation.insert(data, attributes)); + } + + /// Delete [count] characters from current position. + void delete(int count) { + assert(count >= 0); + if (count == 0) return; + push(Operation.delete(count)); + } + + void _mergeWithTail(Operation operation) { + assert(isNotEmpty); + assert(last.key == operation.key); + assert(operation.data is String && last.data is String); + + final length = operation.length! + last.length!; + final lastText = last.data as String; + final opText = operation.data as String; + final resultText = lastText + opText; + final index = operations.length; + operations.replaceRange(index - 1, index, [ + Operation(operation.key, length, resultText, operation.attributes), + ]); + } + + /// Pushes new operation into this delta. + /// + /// Performs compaction by composing [operation] with current tail operation + /// of this delta, when possible. For instance, if current tail is + /// `insert('abc')` and pushed operation is `insert('123')` then existing + /// tail is replaced with `insert('abc123')` - a compound result of the two + /// operations. + void push(Operation operation) { + if (operation.isEmpty) return; + + var index = operations.length; + final lastOp = operations.isNotEmpty ? operations.last : null; + if (lastOp != null) { + if (lastOp.isDelete && operation.isDelete) { + _mergeWithTail(operation); + return; + } + + if (lastOp.isDelete && operation.isInsert) { + index -= 1; // Always insert before deleting + final nLastOp = (index > 0) ? operations.elementAt(index - 1) : null; + if (nLastOp == null) { + operations.insert(0, operation); + return; + } + } + + if (lastOp.isInsert && operation.isInsert) { + if (lastOp.hasSameAttributes(operation) && + operation.data is String && + lastOp.data is String) { + _mergeWithTail(operation); + return; + } + } + + if (lastOp.isRetain && operation.isRetain) { + if (lastOp.hasSameAttributes(operation)) { + _mergeWithTail(operation); + return; + } + } + } + if (index == operations.length) { + operations.add(operation); + } else { + final opAtIndex = operations.elementAt(index); + operations.replaceRange(index, index + 1, [operation, opAtIndex]); + } + modificationCount++; + } + + /// Composes next operation from [thisIter] and [otherIter]. + /// + /// Returns new operation or `null` if operations from [thisIter] and + /// [otherIter] nullify each other. For instance, for the pair `insert('abc')` + /// and `delete(3)` composition result would be empty string. + Operation? _composeOperation( + DeltaIterator thisIter, DeltaIterator otherIter) { + if (otherIter.isNextInsert) return otherIter.next(); + if (thisIter.isNextDelete) return thisIter.next(); + + final length = math.min(thisIter.peekLength(), otherIter.peekLength()); + final thisOp = thisIter.next(length); + final otherOp = otherIter.next(length); + assert(thisOp.length == otherOp.length); + + if (otherOp.isRetain) { + final attributes = composeAttributes( + thisOp.attributes, + otherOp.attributes, + keepNull: thisOp.isRetain, + ); + if (thisOp.isRetain) { + return Operation.retain(thisOp.length, attributes); + } else if (thisOp.isInsert) { + return Operation.insert(thisOp.data, attributes); + } else { + throw StateError('Unreachable'); + } + } else { + // otherOp == delete && thisOp in [retain, insert] + assert(otherOp.isDelete); + if (thisOp.isRetain) return otherOp; + assert(thisOp.isInsert); + // otherOp(delete) + thisOp(insert) => null + } + return null; + } + + /// Composes this delta with [other] and returns new [Delta]. + /// + /// It is not required for this and [other] delta to represent a document + /// delta (consisting only of insert operations). + Delta compose(Delta other) { + final result = Delta(); + final thisIter = DeltaIterator(this); + final otherIter = DeltaIterator(other); + + while (thisIter.hasNext || otherIter.hasNext) { + final newOp = _composeOperation(thisIter, otherIter); + if (newOp != null) result.push(newOp); + } + return result..trim(); + } + + /// Returns a new lazy Iterable with elements that are created by calling + /// f on each element of this Iterable in iteration order. + /// + /// Convenience method + Iterable map(T Function(Operation) f) { + return operations.map(f); + } + + /// Returns a [Delta] containing differences between 2 [Delta]s. + /// If [cleanupSemantic] is `true` (default), applies the following: + /// + /// The diff of "mouse" and "sofas" is + /// [delete(1), insert("s"), retain(1), + /// delete("u"), insert("fa"), retain(1), delete(1)]. + /// While this is the optimum diff, it is difficult for humans to understand. + /// Semantic cleanup rewrites the diff, + /// expanding it into a more intelligible format. + /// The above example would become: [(-1, "mouse"), (1, "sofas")]. + /// (source: https://github.com/google/diff-match-patch/wiki/API) + /// + /// Useful when one wishes to display difference between 2 documents + Delta diff(Delta other, {bool cleanupSemantic = true}) { + if (operations.equals(other.operations)) { + return Delta(); + } + final stringThis = map((op) { + if (op.isInsert) { + return op.data is String ? op.data : _kNullCharacter; + } + final prep = this == other ? 'on' : 'with'; + throw ArgumentError('diff() call $prep non-document'); + }).join(); + final stringOther = other.map((op) { + if (op.isInsert) { + return op.data is String ? op.data : _kNullCharacter; + } + final prep = this == other ? 'on' : 'with'; + throw ArgumentError('diff() call $prep non-document'); + }).join(); + + final retDelta = Delta(); + final diffResult = dmp.diff(stringThis, stringOther); + if (cleanupSemantic) { + dmp.DiffMatchPatch().diffCleanupSemantic(diffResult); + } + + final thisIter = DeltaIterator(this); + final otherIter = DeltaIterator(other); + + for (final component in diffResult) { + var length = component.text.length; + while (length > 0) { + var opLength = 0; + switch (component.operation) { + case dmp.DIFF_INSERT: + opLength = math.min(otherIter.peekLength(), length); + retDelta.push(otherIter.next(opLength)); + break; + case dmp.DIFF_DELETE: + opLength = math.min(length, thisIter.peekLength()); + thisIter.next(opLength); + retDelta.delete(opLength); + break; + case dmp.DIFF_EQUAL: + opLength = math.min( + math.min(thisIter.peekLength(), otherIter.peekLength()), + length, + ); + final thisOp = thisIter.next(opLength); + final otherOp = otherIter.next(opLength); + if (thisOp.data == otherOp.data) { + retDelta.retain( + opLength, + diffAttributes(thisOp.attributes, otherOp.attributes), + ); + } else { + retDelta + ..push(otherOp) + ..delete(opLength); + } + break; + } + length -= opLength; + } + } + return retDelta..trim(); + } + + /// Transforms next operation from [otherIter] against next operation in + /// [thisIter]. + /// + /// Returns `null` if both operations nullify each other. + Operation? _transformOperation( + DeltaIterator thisIter, DeltaIterator otherIter, bool priority) { + if (thisIter.isNextInsert && (priority || !otherIter.isNextInsert)) { + return Operation.retain(thisIter.next().length); + } else if (otherIter.isNextInsert) { + return otherIter.next(); + } + + final length = math.min(thisIter.peekLength(), otherIter.peekLength()); + final thisOp = thisIter.next(length); + final otherOp = otherIter.next(length); + assert(thisOp.length == otherOp.length); + + // At this point only delete and retain operations are possible. + if (thisOp.isDelete) { + // otherOp is either delete or retain, so they nullify each other. + return null; + } else if (otherOp.isDelete) { + return otherOp; + } else { + // Retain otherOp which is either retain or insert. + return Operation.retain( + length, + transformAttributes(thisOp.attributes, otherOp.attributes, priority), + ); + } + } + + /// Transforms [other] delta against operations in this delta. + Delta transform(Delta other, bool priority) { + final result = Delta(); + final thisIter = DeltaIterator(this); + final otherIter = DeltaIterator(other); + + while (thisIter.hasNext || otherIter.hasNext) { + final newOp = _transformOperation(thisIter, otherIter, priority); + if (newOp != null) result.push(newOp); + } + return result..trim(); + } + + /// Removes trailing retain operation with empty attributes, if present. + void trim() { + if (isNotEmpty) { + final last = operations.last; + if (last.isRetain && last.isPlain) operations.removeLast(); + } + } + + /// Removes trailing '\n' + void _trimNewLine() { + if (isNotEmpty) { + final lastOp = operations.last; + final lastOpData = lastOp.data; + + if (lastOpData is String && lastOpData.endsWith('\n')) { + operations.removeLast(); + if (lastOpData.length > 1) { + insert(lastOpData.substring(0, lastOpData.length - 1), + lastOp.attributes); + } + } + } + } + + /// Concatenates [other] with this delta and returns the result. + Delta concat(Delta other, {bool trimNewLine = false}) { + final result = Delta.from(this); + if (trimNewLine) { + result._trimNewLine(); + } + if (other.isNotEmpty) { + // In case first operation of other can be merged with last operation in + // our list. + result.push(other.operations.first); + result.operations.addAll(other.operations.sublist(1)); + } + return result; + } + + /// Inverts this delta against [base]. + /// + /// Returns new delta which negates effect of this delta when applied to + /// [base]. This is an equivalent of "undo" operation on deltas. + Delta invert(Delta base) { + final inverted = Delta(); + if (base.isEmpty) return inverted; + + var baseIndex = 0; + for (final op in operations) { + if (op.isInsert) { + inverted.delete(op.length!); + } else if (op.isRetain && op.isPlain) { + inverted.retain(op.length!); + baseIndex += op.length!; + } else if (op.isDelete || (op.isRetain && op.isNotPlain)) { + final length = op.length!; + final sliceDelta = base.slice(baseIndex, baseIndex + length); + sliceDelta.toList().forEach((baseOp) { + if (op.isDelete) { + inverted.push(baseOp); + } else if (op.isRetain && op.isNotPlain) { + final invertAttr = + invertAttributes(op.attributes, baseOp.attributes); + inverted.retain( + baseOp.length!, invertAttr.isEmpty ? null : invertAttr); + } + }); + baseIndex += length; + } else { + throw StateError('Unreachable'); + } + } + inverted.trim(); + return inverted; + } + + /// Returns slice of this delta from [start] index (inclusive) to [end] + /// (exclusive). + Delta slice(int start, [int? end]) { + final delta = Delta(); + var index = 0; + final opIterator = DeltaIterator(this); + + final actualEnd = end ?? DeltaIterator.maxLength; + + while (index < actualEnd && opIterator.hasNext) { + Operation op; + if (index < start) { + op = opIterator.next(start - index); + } else { + op = opIterator.next(actualEnd - index); + delta.push(op); + } + index += op.length!; + } + return delta; + } + + /// Transforms [index] against this delta. + /// + /// Any "delete" operation before specified [index] shifts it backward, as + /// well as any "insert" operation shifts it forward. + /// + /// The [force] argument is used to resolve scenarios when there is an + /// insert operation at the same position as [index]. If [force] is set to + /// `true` (default) then position is forced to shift forward, otherwise + /// position stays at the same index. In other words setting [force] to + /// `false` gives higher priority to the transformed position. + /// + /// Useful to adjust caret or selection positions. + int transformPosition(int index, {bool force = true}) { + final iter = DeltaIterator(this); + var offset = 0; + while (iter.hasNext && offset <= index) { + final op = iter.next(); + if (op.isDelete) { + index -= math.min(op.length!, index - offset); + continue; + } else if (op.isInsert && (offset < index || force)) { + index += op.length!; + } + offset += op.length!; + } + return index; + } + + @override + String toString() => operations.join('\n'); +} diff --git a/dart_quill_delta/lib/src/delta/delta_iterator.dart b/dart_quill_delta/lib/src/delta/delta_iterator.dart new file mode 100644 index 000000000..bb8c41e0b --- /dev/null +++ b/dart_quill_delta/lib/src/delta/delta_iterator.dart @@ -0,0 +1,100 @@ +import 'dart:math' as math; + +import '../operation/operation.dart'; +import 'delta.dart'; + +/// Specialized iterator for [Delta]s. +class DeltaIterator { + DeltaIterator(this.delta) : _modificationCount = delta.modificationCount; + + static const int maxLength = 1073741824; + + final Delta delta; + final int _modificationCount; + int _index = 0; + int _offset = 0; + + bool get isNextInsert => nextOperationKey == Operation.insertKey; + + bool get isNextDelete => nextOperationKey == Operation.deleteKey; + + bool get isNextRetain => nextOperationKey == Operation.retainKey; + + String? get nextOperationKey { + if (_index < delta.length) { + return delta.elementAt(_index).key; + } else { + return null; + } + } + + bool get hasNext => peekLength() < maxLength; + + /// Returns length of next operation without consuming it. + /// + /// Returns [maxLength] if there is no more operations left to iterate. + int peekLength() { + if (_index < delta.length) { + final operation = delta.operations[_index]; + return operation.length! - _offset; + } + return maxLength; + } + + /// Consumes and returns next operation. + /// + /// Optional [length] specifies maximum length of operation to return. Note + /// that actual length of returned operation may be less than specified value. + /// + /// If this iterator reached the end of the Delta then returns a retain + /// operation with its length set to [maxLength]. + // TODO: Note that we used double.infinity as the default value + // for length here + // but this can now cause a type error since operation length is + // expected to be an int. Changing default length to [maxLength] is + // a workaround to avoid breaking changes. + Operation next([int length = maxLength]) { + if (_modificationCount != delta.modificationCount) { + throw ConcurrentModificationError(delta); + } + + if (_index < delta.length) { + 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) { + _index++; + _offset = 0; + } else { + _offset += actualLength; + } + final opData = op.isInsert && op.data is String + ? (op.data as String) + .substring(currentOffset, currentOffset + actualLength) + : op.data; + final opIsNotEmpty = + opData is String ? opData.isNotEmpty : true; // embeds are never empty + final opLength = opData is String ? opData.length : 1; + final opActualLength = opIsNotEmpty ? opLength : actualLength; + return Operation(opKey, opActualLength, opData, opAttributes); + } + return Operation.retain(length); + } + + /// Skips [length] characters in source delta. + /// + /// Returns last skipped operation, or `null` if there was nothing to skip. + Operation? skip(int length) { + var skipped = 0; + Operation? op; + while (skipped < length && hasNext) { + final opLength = peekLength(); + final skip = math.min(length - skipped, opLength); + op = next(skip); + skipped += op.length!; + } + return op; + } +} diff --git a/dart_quill_delta/lib/src/operation/operation.dart b/dart_quill_delta/lib/src/operation/operation.dart new file mode 100644 index 000000000..126942ae5 --- /dev/null +++ b/dart_quill_delta/lib/src/operation/operation.dart @@ -0,0 +1,171 @@ +import 'package:collection/collection.dart'; +import 'package:quiver/core.dart'; + +/// Decoder function to convert raw `data` object into a user-defined data type. +/// +/// Useful with embedded content. +typedef DataDecoder = Object? Function(Object data); + +/// Default data decoder which simply passes through the original value. +Object? _passThroughDataDecoder(Object? data) => data; + +const _attributeEquality = DeepCollectionEquality(); +const _valueEquality = DeepCollectionEquality(); + +/// Operation performed on a rich-text document. +class Operation { + Operation(this.key, this.length, this.data, Map? attributes) + : assert(_validKeys.contains(key), 'Invalid operation key "$key".'), + assert(() { + if (key != Operation.insertKey) return true; + return data is String ? data.length == length : length == 1; + }(), 'Length of insert operation must be equal to the data length.'), + _attributes = + attributes != null ? Map.from(attributes) : null; + + /// Creates operation which deletes [length] of characters. + factory Operation.delete(int length) => + Operation(Operation.deleteKey, length, '', null); + + /// Creates operation which inserts [text] with optional [attributes]. + factory Operation.insert(dynamic data, [Map? attributes]) => + Operation(Operation.insertKey, data is String ? data.length : 1, data, + attributes); + + /// Creates operation which retains [length] of characters and optionally + /// applies attributes. + factory Operation.retain(int? length, [Map? attributes]) => + Operation(Operation.retainKey, length, '', attributes); + + /// Key of insert operations. + static const String insertKey = 'insert'; + + /// Key of delete operations. + static const String deleteKey = 'delete'; + + /// Key of retain operations. + static const String retainKey = 'retain'; + + /// Key of attributes collection. + static const String attributesKey = 'attributes'; + + static const List _validKeys = [insertKey, deleteKey, retainKey]; + + /// Key of this operation, can be "insert", "delete" or "retain". + final String key; + + /// Length of this operation. + final int? length; + + /// Payload of "insert" operation, for other types is set to empty string. + final Object? data; + + /// Rich-text attributes set by this operation, can be `null`. + Map? get attributes => + _attributes == null ? null : Map.from(_attributes); + final Map? _attributes; + + /// Creates new [Operation] from JSON payload. + /// + /// If `dataDecoder` parameter is not null then it is used to additionally + /// decode the operation's data object. Only applied to insert operations. + static Operation fromJson(Map data, {DataDecoder? dataDecoder}) { + dataDecoder ??= _passThroughDataDecoder; + final map = Map.from(data); + if (map.containsKey(Operation.insertKey)) { + final data = dataDecoder(map[Operation.insertKey]); + final dataLength = data is String ? data.length : 1; + return Operation( + Operation.insertKey, dataLength, data, map[Operation.attributesKey]); + } else if (map.containsKey(Operation.deleteKey)) { + final int? length = map[Operation.deleteKey]; + return Operation(Operation.deleteKey, length, '', null); + } else if (map.containsKey(Operation.retainKey)) { + final int? length = map[Operation.retainKey]; + return Operation( + Operation.retainKey, length, '', map[Operation.attributesKey]); + } + throw ArgumentError.value(data, 'Invalid data for Delta operation.'); + } + + /// Returns JSON-serializable representation of this operation. + Map toJson() { + final json = {key: value}; + if (_attributes != null) json[Operation.attributesKey] = attributes; + return json; + } + + /// Returns value of this operation. + /// + /// For insert operations this returns text, for delete and retain - length. + dynamic get value => (key == Operation.insertKey) ? data : length; + + /// Returns `true` if this is a delete operation. + bool get isDelete => key == Operation.deleteKey; + + /// Returns `true` if this is an insert operation. + bool get isInsert => key == Operation.insertKey; + + /// Returns `true` if this is a retain operation. + bool get isRetain => key == Operation.retainKey; + + /// Returns `true` if this operation has no attributes, e.g. is plain text. + bool get isPlain => _attributes == null || _attributes.isEmpty; + + /// Returns `true` if this operation sets at least one attribute. + bool get isNotPlain => !isPlain; + + /// Returns `true` is this operation is empty. + /// + /// An operation is considered empty if its [length] is equal to `0`. + bool get isEmpty => length == 0; + + /// Returns `true` is this operation is not empty. + bool get isNotEmpty => length! > 0; + + @override + bool operator ==(other) { + if (identical(this, other)) return true; + if (other is! Operation) return false; + final typedOther = other; + return key == typedOther.key && + length == typedOther.length && + _valueEquality.equals(data, typedOther.data) && + hasSameAttributes(typedOther); + } + + /// Returns `true` if this operation has attribute specified by [name]. + bool hasAttribute(String name) => + isNotPlain && _attributes!.containsKey(name); + + /// Returns `true` if [other] operation has the same attributes as this one. + bool hasSameAttributes(Operation other) { + // treat null and empty equal + if ((_attributes?.isEmpty ?? true) && + (other._attributes?.isEmpty ?? true)) { + return true; + } + return _attributeEquality.equals(_attributes, other._attributes); + } + + @override + int get hashCode { + if (_attributes != null && _attributes.isNotEmpty) { + final attrsHash = + hashObjects(_attributes.entries.map((e) => hash2(e.key, e.value))); + return hash3(key, value, attrsHash); + } + return hash2(key, value); + } + + @override + String toString() { + final attr = attributes == null ? '' : ' + $attributes'; + final text = isInsert + ? (data is String + ? (data as String).replaceAll('\n', '⏎') + : data.toString()) + : '$length'; + return '$key⟨ $text ⟩$attr'; + } +} diff --git a/dart_quill_delta/pubspec.yaml b/dart_quill_delta/pubspec.yaml new file mode 100644 index 000000000..6f853b27e --- /dev/null +++ b/dart_quill_delta/pubspec.yaml @@ -0,0 +1,20 @@ +name: dart_quill_delta +description: A port of quill-js-delta from typescript to dart +version: 0.0.1 +homepage: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ +repository: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ +issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ +documentation: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ + +environment: + sdk: ^3.2.3 + +# Add regular dependencies here. +dependencies: + collection: ^1.17.0 + diff_match_patch: ^0.4.1 + quiver: ^3.2.1 + +dev_dependencies: + lints: ^3.0.0 + test: ^1.24.0 diff --git a/dart_quill_delta/test/dart_quill_delta_test.dart b/dart_quill_delta/test/dart_quill_delta_test.dart new file mode 100644 index 000000000..7de0162a4 --- /dev/null +++ b/dart_quill_delta/test/dart_quill_delta_test.dart @@ -0,0 +1,11 @@ +import 'package:test/test.dart'; + +void main() { + group('A group of tests', () { + setUp(() { + // Additional setup goes here. + }); + + test('First Test', () {}); + }); +} diff --git a/example/pubspec.yaml b/example/pubspec.yaml index b3d2e15c1..2fa4358ad 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -54,7 +54,7 @@ dependency_overrides: flutter_quill_test: path: ../flutter_quill_test quill_html_converter: - path: ../packages/quill_html_converter + path: ../quill_html_converter dev_dependencies: diff --git a/lib/src/models/quill_delta.dart b/lib/src/models/quill_delta.dart index 196651e94..8b31045e5 100644 --- a/lib/src/models/quill_delta.dart +++ b/lib/src/models/quill_delta.dart @@ -1,827 +1,829 @@ -/// Implementation of Quill Delta format in Dart. -library; - -import 'dart:math' as math; - -import 'package:collection/collection.dart'; -import 'package:diff_match_patch/diff_match_patch.dart' as dmp; -import 'package:quiver/core.dart'; - -const _attributeEquality = DeepCollectionEquality(); -const _valueEquality = DeepCollectionEquality(); - -/// Decoder function to convert raw `data` object into a user-defined data type. -/// -/// Useful with embedded content. -typedef DataDecoder = Object? Function(Object data); - -/// Default data decoder which simply passes through the original value. -Object? _passThroughDataDecoder(Object? data) => data; - -/// Operation performed on a rich-text document. -class Operation { - Operation._(this.key, this.length, this.data, Map? attributes) - : assert(_validKeys.contains(key), 'Invalid operation key "$key".'), - assert(() { - if (key != Operation.insertKey) return true; - return data is String ? data.length == length : length == 1; - }(), 'Length of insert operation must be equal to the data length.'), - _attributes = - attributes != null ? Map.from(attributes) : null; - - /// Creates operation which deletes [length] of characters. - factory Operation.delete(int length) => - Operation._(Operation.deleteKey, length, '', null); - - /// Creates operation which inserts [text] with optional [attributes]. - factory Operation.insert(dynamic data, [Map? attributes]) => - Operation._(Operation.insertKey, data is String ? data.length : 1, data, - attributes); - - /// Creates operation which retains [length] of characters and optionally - /// applies attributes. - factory Operation.retain(int? length, [Map? attributes]) => - Operation._(Operation.retainKey, length, '', attributes); - - /// Key of insert operations. - static const String insertKey = 'insert'; - - /// Key of delete operations. - static const String deleteKey = 'delete'; - - /// Key of retain operations. - static const String retainKey = 'retain'; - - /// Key of attributes collection. - static const String attributesKey = 'attributes'; - - static const List _validKeys = [insertKey, deleteKey, retainKey]; - - /// Key of this operation, can be "insert", "delete" or "retain". - final String key; - - /// Length of this operation. - final int? length; - - /// Payload of "insert" operation, for other types is set to empty string. - final Object? data; - - /// Rich-text attributes set by this operation, can be `null`. - Map? get attributes => - _attributes == null ? null : Map.from(_attributes!); - final Map? _attributes; - - /// Creates new [Operation] from JSON payload. - /// - /// If `dataDecoder` parameter is not null then it is used to additionally - /// decode the operation's data object. Only applied to insert operations. - static Operation fromJson(Map data, {DataDecoder? dataDecoder}) { - dataDecoder ??= _passThroughDataDecoder; - final map = Map.from(data); - if (map.containsKey(Operation.insertKey)) { - final data = dataDecoder(map[Operation.insertKey]); - final dataLength = data is String ? data.length : 1; - return Operation._( - Operation.insertKey, dataLength, data, map[Operation.attributesKey]); - } else if (map.containsKey(Operation.deleteKey)) { - final int? length = map[Operation.deleteKey]; - return Operation._(Operation.deleteKey, length, '', null); - } else if (map.containsKey(Operation.retainKey)) { - final int? length = map[Operation.retainKey]; - return Operation._( - Operation.retainKey, length, '', map[Operation.attributesKey]); - } - throw ArgumentError.value(data, 'Invalid data for Delta operation.'); - } - - /// Returns JSON-serializable representation of this operation. - Map toJson() { - final json = {key: value}; - if (_attributes != null) json[Operation.attributesKey] = attributes; - return json; - } - - /// Returns value of this operation. - /// - /// For insert operations this returns text, for delete and retain - length. - dynamic get value => (key == Operation.insertKey) ? data : length; - - /// Returns `true` if this is a delete operation. - bool get isDelete => key == Operation.deleteKey; - - /// Returns `true` if this is an insert operation. - bool get isInsert => key == Operation.insertKey; - - /// Returns `true` if this is a retain operation. - bool get isRetain => key == Operation.retainKey; - - /// Returns `true` if this operation has no attributes, e.g. is plain text. - bool get isPlain => _attributes == null || _attributes!.isEmpty; - - /// Returns `true` if this operation sets at least one attribute. - bool get isNotPlain => !isPlain; - - /// Returns `true` is this operation is empty. - /// - /// An operation is considered empty if its [length] is equal to `0`. - bool get isEmpty => length == 0; - - /// Returns `true` is this operation is not empty. - bool get isNotEmpty => length! > 0; - - @override - bool operator ==(other) { - if (identical(this, other)) return true; - if (other is! Operation) return false; - final typedOther = other; - return key == typedOther.key && - length == typedOther.length && - _valueEquality.equals(data, typedOther.data) && - hasSameAttributes(typedOther); - } - - /// Returns `true` if this operation has attribute specified by [name]. - bool hasAttribute(String name) => - isNotPlain && _attributes!.containsKey(name); - - /// Returns `true` if [other] operation has the same attributes as this one. - bool hasSameAttributes(Operation other) { - // treat null and empty equal - if ((_attributes?.isEmpty ?? true) && - (other._attributes?.isEmpty ?? true)) { - return true; - } - return _attributeEquality.equals(_attributes, other._attributes); - } - - @override - int get hashCode { - if (_attributes != null && _attributes!.isNotEmpty) { - final attrsHash = - hashObjects(_attributes!.entries.map((e) => hash2(e.key, e.value))); - return hash3(key, value, attrsHash); - } - return hash2(key, value); - } - - @override - String toString() { - final attr = attributes == null ? '' : ' + $attributes'; - final text = isInsert - ? (data is String - ? (data as String).replaceAll('\n', '⏎') - : data.toString()) - : '$length'; - return '$key⟨ $text ⟩$attr'; - } -} - -/// Delta represents a document or a modification of a document as a sequence of -/// insert, delete and retain operations. -/// -/// Delta consisting of only "insert" operations is usually referred to as -/// "document delta". When delta includes also "retain" or "delete" operations -/// it is a "change delta". -class Delta { - /// Creates new empty [Delta]. - factory Delta() => Delta._([]); - - Delta._(List operations) : _operations = operations; - - /// Creates new [Delta] from [other]. - factory Delta.from(Delta other) => - Delta._(List.from(other._operations)); - - /// Creates new [Delta] from a List of Operation - factory Delta.fromOperations(List operations) => - Delta._(operations.toList()); - - // Placeholder char for embed in diff() - static final String _kNullCharacter = String.fromCharCode(0); - - /// Transforms two attribute sets. - static Map? transformAttributes( - Map? a, Map? b, bool priority) { - if (a == null) return b; - if (b == null) return null; - - if (!priority) return b; - - final result = b.keys.fold>({}, (attributes, key) { - if (!a.containsKey(key)) attributes[key] = b[key]; - return attributes; - }); - - return result.isEmpty ? null : result; - } - - /// Composes two attribute sets. - static Map? composeAttributes( - Map? a, Map? b, - {bool keepNull = false}) { - a ??= const {}; - b ??= const {}; - - final result = Map.from(a)..addAll(b); - final keys = result.keys.toList(growable: false); - - if (!keepNull) { - for (final key in keys) { - if (result[key] == null) result.remove(key); - } - } - - return result.isEmpty ? null : result; - } - - ///get anti-attr result base on base - static Map invertAttributes( - Map? attr, Map? base) { - attr ??= const {}; - base ??= const {}; - - final baseInverted = base.keys.fold({}, (dynamic memo, key) { - if (base![key] != attr![key] && attr.containsKey(key)) { - memo[key] = base[key]; - } - return memo; - }); - - final inverted = - Map.from(attr.keys.fold(baseInverted, (memo, key) { - if (base![key] != attr![key] && !base.containsKey(key)) { - memo[key] = null; - } - return memo; - })); - return inverted; - } - - /// Returns diff between two attribute sets - static Map? diffAttributes( - Map? a, Map? b) { - a ??= const {}; - b ??= const {}; - - final attributes = {}; - 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; - } - - final List _operations; - - int _modificationCount = 0; - - /// Creates [Delta] from de-serialized JSON representation. - /// - /// If `dataDecoder` parameter is not null then it is used to additionally - /// decode the operation's data object. Only applied to insert operations. - static Delta fromJson(List data, {DataDecoder? dataDecoder}) { - return Delta._(data - .map((op) => Operation.fromJson(op, dataDecoder: dataDecoder)) - .toList()); - } - - /// Returns list of operations in this delta. - List toList() => List.from(_operations); - - /// Returns JSON-serializable version of this delta. - List toJson() => toList().map((operation) => operation.toJson()).toList(); - - /// Returns `true` if this delta is empty. - bool get isEmpty => _operations.isEmpty; - - /// Returns `true` if this delta is not empty. - bool get isNotEmpty => _operations.isNotEmpty; - - /// Returns number of operations in this delta. - int get length => _operations.length; - - /// Returns [Operation] at specified [index] in this delta. - Operation operator [](int index) => _operations[index]; - - /// Returns [Operation] at specified [index] in this delta. - Operation elementAt(int index) => _operations.elementAt(index); - - /// Returns the first [Operation] in this delta. - Operation get first => _operations.first; - - /// Returns the last [Operation] in this delta. - Operation get last => _operations.last; - - @override - bool operator ==(dynamic other) { - if (identical(this, other)) return true; - if (other is! Delta) return false; - final typedOther = other; - const comparator = ListEquality(DefaultEquality()); - return comparator.equals(_operations, typedOther._operations); - } - - @override - int get hashCode => hashObjects(_operations); - - /// Retain [count] of characters from current position. - void retain(int count, [Map? attributes]) { - assert(count >= 0); - if (count == 0) return; // no-op - push(Operation.retain(count, attributes)); - } - - /// Insert [data] at current position. - void insert(dynamic data, [Map? attributes]) { - if (data is String && data.isEmpty) return; // no-op - push(Operation.insert(data, attributes)); - } - - /// Delete [count] characters from current position. - void delete(int count) { - assert(count >= 0); - if (count == 0) return; - push(Operation.delete(count)); - } - - void _mergeWithTail(Operation operation) { - assert(isNotEmpty); - assert(last.key == operation.key); - assert(operation.data is String && last.data is String); - - final length = operation.length! + last.length!; - final lastText = last.data as String; - final opText = operation.data as String; - final resultText = lastText + opText; - final index = _operations.length; - _operations.replaceRange(index - 1, index, [ - Operation._(operation.key, length, resultText, operation.attributes), - ]); - } - - /// Pushes new operation into this delta. - /// - /// Performs compaction by composing [operation] with current tail operation - /// of this delta, when possible. For instance, if current tail is - /// `insert('abc')` and pushed operation is `insert('123')` then existing - /// tail is replaced with `insert('abc123')` - a compound result of the two - /// operations. - void push(Operation operation) { - if (operation.isEmpty) return; - - var index = _operations.length; - final lastOp = _operations.isNotEmpty ? _operations.last : null; - if (lastOp != null) { - if (lastOp.isDelete && operation.isDelete) { - _mergeWithTail(operation); - return; - } - - if (lastOp.isDelete && operation.isInsert) { - index -= 1; // Always insert before deleting - final nLastOp = (index > 0) ? _operations.elementAt(index - 1) : null; - if (nLastOp == null) { - _operations.insert(0, operation); - return; - } - } - - if (lastOp.isInsert && operation.isInsert) { - if (lastOp.hasSameAttributes(operation) && - operation.data is String && - lastOp.data is String) { - _mergeWithTail(operation); - return; - } - } - - if (lastOp.isRetain && operation.isRetain) { - if (lastOp.hasSameAttributes(operation)) { - _mergeWithTail(operation); - return; - } - } - } - if (index == _operations.length) { - _operations.add(operation); - } else { - final opAtIndex = _operations.elementAt(index); - _operations.replaceRange(index, index + 1, [operation, opAtIndex]); - } - _modificationCount++; - } - - /// Composes next operation from [thisIter] and [otherIter]. - /// - /// Returns new operation or `null` if operations from [thisIter] and - /// [otherIter] nullify each other. For instance, for the pair `insert('abc')` - /// and `delete(3)` composition result would be empty string. - Operation? _composeOperation( - DeltaIterator thisIter, DeltaIterator otherIter) { - if (otherIter.isNextInsert) return otherIter.next(); - if (thisIter.isNextDelete) return thisIter.next(); - - final length = math.min(thisIter.peekLength(), otherIter.peekLength()); - final thisOp = thisIter.next(length); - final otherOp = otherIter.next(length); - assert(thisOp.length == otherOp.length); - - if (otherOp.isRetain) { - final attributes = composeAttributes( - thisOp.attributes, - otherOp.attributes, - keepNull: thisOp.isRetain, - ); - if (thisOp.isRetain) { - return Operation.retain(thisOp.length, attributes); - } else if (thisOp.isInsert) { - return Operation.insert(thisOp.data, attributes); - } else { - throw StateError('Unreachable'); - } - } else { - // otherOp == delete && thisOp in [retain, insert] - assert(otherOp.isDelete); - if (thisOp.isRetain) return otherOp; - assert(thisOp.isInsert); - // otherOp(delete) + thisOp(insert) => null - } - return null; - } - - /// Composes this delta with [other] and returns new [Delta]. - /// - /// It is not required for this and [other] delta to represent a document - /// delta (consisting only of insert operations). - Delta compose(Delta other) { - final result = Delta(); - final thisIter = DeltaIterator(this); - final otherIter = DeltaIterator(other); - - while (thisIter.hasNext || otherIter.hasNext) { - final newOp = _composeOperation(thisIter, otherIter); - if (newOp != null) result.push(newOp); - } - return result..trim(); - } - - /// Returns a new lazy Iterable with elements that are created by calling - /// f on each element of this Iterable in iteration order. - /// - /// Convenience method - Iterable map(T Function(Operation) f) { - return _operations.map(f); - } - - /// Returns a [Delta] containing differences between 2 [Delta]s. - /// If [cleanupSemantic] is `true` (default), applies the following: - /// - /// The diff of "mouse" and "sofas" is - /// [delete(1), insert("s"), retain(1), - /// delete("u"), insert("fa"), retain(1), delete(1)]. - /// While this is the optimum diff, it is difficult for humans to understand. - /// Semantic cleanup rewrites the diff, - /// expanding it into a more intelligible format. - /// The above example would become: [(-1, "mouse"), (1, "sofas")]. - /// (source: https://github.com/google/diff-match-patch/wiki/API) - /// - /// Useful when one wishes to display difference between 2 documents - Delta diff(Delta other, {bool cleanupSemantic = true}) { - if (_operations.equals(other._operations)) { - return Delta(); - } - final stringThis = map((op) { - if (op.isInsert) { - return op.data is String ? op.data : _kNullCharacter; - } - final prep = this == other ? 'on' : 'with'; - throw ArgumentError('diff() call $prep non-document'); - }).join(); - final stringOther = other.map((op) { - if (op.isInsert) { - return op.data is String ? op.data : _kNullCharacter; - } - final prep = this == other ? 'on' : 'with'; - throw ArgumentError('diff() call $prep non-document'); - }).join(); - - final retDelta = Delta(); - final diffResult = dmp.diff(stringThis, stringOther); - if (cleanupSemantic) { - dmp.DiffMatchPatch().diffCleanupSemantic(diffResult); - } - - final thisIter = DeltaIterator(this); - final otherIter = DeltaIterator(other); - - for (final component in diffResult) { - var length = component.text.length; - while (length > 0) { - var opLength = 0; - switch (component.operation) { - case dmp.DIFF_INSERT: - opLength = math.min(otherIter.peekLength(), length); - retDelta.push(otherIter.next(opLength)); - break; - case dmp.DIFF_DELETE: - opLength = math.min(length, thisIter.peekLength()); - thisIter.next(opLength); - retDelta.delete(opLength); - break; - case dmp.DIFF_EQUAL: - opLength = math.min( - math.min(thisIter.peekLength(), otherIter.peekLength()), - length, - ); - final thisOp = thisIter.next(opLength); - final otherOp = otherIter.next(opLength); - if (thisOp.data == otherOp.data) { - retDelta.retain( - opLength, - diffAttributes(thisOp.attributes, otherOp.attributes), - ); - } else { - retDelta - ..push(otherOp) - ..delete(opLength); - } - break; - } - length -= opLength; - } - } - return retDelta..trim(); - } - - /// Transforms next operation from [otherIter] against next operation in - /// [thisIter]. - /// - /// Returns `null` if both operations nullify each other. - Operation? _transformOperation( - DeltaIterator thisIter, DeltaIterator otherIter, bool priority) { - if (thisIter.isNextInsert && (priority || !otherIter.isNextInsert)) { - return Operation.retain(thisIter.next().length); - } else if (otherIter.isNextInsert) { - return otherIter.next(); - } - - final length = math.min(thisIter.peekLength(), otherIter.peekLength()); - final thisOp = thisIter.next(length); - final otherOp = otherIter.next(length); - assert(thisOp.length == otherOp.length); - - // At this point only delete and retain operations are possible. - if (thisOp.isDelete) { - // otherOp is either delete or retain, so they nullify each other. - return null; - } else if (otherOp.isDelete) { - return otherOp; - } else { - // Retain otherOp which is either retain or insert. - return Operation.retain( - length, - transformAttributes(thisOp.attributes, otherOp.attributes, priority), - ); - } - } - - /// Transforms [other] delta against operations in this delta. - Delta transform(Delta other, bool priority) { - final result = Delta(); - final thisIter = DeltaIterator(this); - final otherIter = DeltaIterator(other); - - while (thisIter.hasNext || otherIter.hasNext) { - final newOp = _transformOperation(thisIter, otherIter, priority); - if (newOp != null) result.push(newOp); - } - return result..trim(); - } - - /// Removes trailing retain operation with empty attributes, if present. - void trim() { - if (isNotEmpty) { - final last = _operations.last; - if (last.isRetain && last.isPlain) _operations.removeLast(); - } - } - - /// Removes trailing '\n' - void _trimNewLine() { - if (isNotEmpty) { - final lastOp = _operations.last; - final lastOpData = lastOp.data; - - if (lastOpData is String && lastOpData.endsWith('\n')) { - _operations.removeLast(); - if (lastOpData.length > 1) { - insert(lastOpData.substring(0, lastOpData.length - 1), - lastOp.attributes); - } - } - } - } - - /// Concatenates [other] with this delta and returns the result. - Delta concat(Delta other, {bool trimNewLine = false}) { - final result = Delta.from(this); - if (trimNewLine) { - result._trimNewLine(); - } - if (other.isNotEmpty) { - // In case first operation of other can be merged with last operation in - // our list. - result.push(other._operations.first); - result._operations.addAll(other._operations.sublist(1)); - } - return result; - } - - /// Inverts this delta against [base]. - /// - /// Returns new delta which negates effect of this delta when applied to - /// [base]. This is an equivalent of "undo" operation on deltas. - Delta invert(Delta base) { - final inverted = Delta(); - if (base.isEmpty) return inverted; - - var baseIndex = 0; - for (final op in _operations) { - if (op.isInsert) { - inverted.delete(op.length!); - } else if (op.isRetain && op.isPlain) { - inverted.retain(op.length!); - baseIndex += op.length!; - } else if (op.isDelete || (op.isRetain && op.isNotPlain)) { - final length = op.length!; - final sliceDelta = base.slice(baseIndex, baseIndex + length); - sliceDelta.toList().forEach((baseOp) { - if (op.isDelete) { - inverted.push(baseOp); - } else if (op.isRetain && op.isNotPlain) { - final invertAttr = - invertAttributes(op.attributes, baseOp.attributes); - inverted.retain( - baseOp.length!, invertAttr.isEmpty ? null : invertAttr); - } - }); - baseIndex += length; - } else { - throw StateError('Unreachable'); - } - } - inverted.trim(); - return inverted; - } - - /// Returns slice of this delta from [start] index (inclusive) to [end] - /// (exclusive). - Delta slice(int start, [int? end]) { - final delta = Delta(); - var index = 0; - final opIterator = DeltaIterator(this); - - final actualEnd = end ?? DeltaIterator.maxLength; - - while (index < actualEnd && opIterator.hasNext) { - Operation op; - if (index < start) { - op = opIterator.next(start - index); - } else { - op = opIterator.next(actualEnd - index); - delta.push(op); - } - index += op.length!; - } - return delta; - } - - /// Transforms [index] against this delta. - /// - /// Any "delete" operation before specified [index] shifts it backward, as - /// well as any "insert" operation shifts it forward. - /// - /// The [force] argument is used to resolve scenarios when there is an - /// insert operation at the same position as [index]. If [force] is set to - /// `true` (default) then position is forced to shift forward, otherwise - /// position stays at the same index. In other words setting [force] to - /// `false` gives higher priority to the transformed position. - /// - /// Useful to adjust caret or selection positions. - int transformPosition(int index, {bool force = true}) { - final iter = DeltaIterator(this); - var offset = 0; - while (iter.hasNext && offset <= index) { - final op = iter.next(); - if (op.isDelete) { - index -= math.min(op.length!, index - offset); - continue; - } else if (op.isInsert && (offset < index || force)) { - index += op.length!; - } - offset += op.length!; - } - return index; - } - - @override - String toString() => _operations.join('\n'); -} - -/// Specialized iterator for [Delta]s. -class DeltaIterator { - DeltaIterator(this.delta) : _modificationCount = delta._modificationCount; - - static const int maxLength = 1073741824; - - final Delta delta; - final int _modificationCount; - int _index = 0; - int _offset = 0; - - bool get isNextInsert => nextOperationKey == Operation.insertKey; - - bool get isNextDelete => nextOperationKey == Operation.deleteKey; - - bool get isNextRetain => nextOperationKey == Operation.retainKey; - - String? get nextOperationKey { - if (_index < delta.length) { - return delta.elementAt(_index).key; - } else { - return null; - } - } - - bool get hasNext => peekLength() < maxLength; - - /// Returns length of next operation without consuming it. - /// - /// Returns [maxLength] if there is no more operations left to iterate. - int peekLength() { - if (_index < delta.length) { - final operation = delta._operations[_index]; - return operation.length! - _offset; - } - return maxLength; - } - - /// Consumes and returns next operation. - /// - /// Optional [length] specifies maximum length of operation to return. Note - /// that actual length of returned operation may be less than specified value. - /// - /// If this iterator reached the end of the Delta then returns a retain - /// operation with its length set to [maxLength]. - // TODO: Note that we used double.infinity as the default value - // for length here - // but this can now cause a type error since operation length is - // expected to be an int. Changing default length to [maxLength] is - // a workaround to avoid breaking changes. - Operation next([int length = maxLength]) { - if (_modificationCount != delta._modificationCount) { - throw ConcurrentModificationError(delta); - } - - if (_index < delta.length) { - 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) { - _index++; - _offset = 0; - } else { - _offset += actualLength; - } - final opData = op.isInsert && op.data is String - ? (op.data as String) - .substring(currentOffset, currentOffset + actualLength) - : op.data; - final opIsNotEmpty = - opData is String ? opData.isNotEmpty : true; // embeds are never empty - final opLength = opData is String ? opData.length : 1; - final opActualLength = opIsNotEmpty ? opLength : actualLength; - return Operation._(opKey, opActualLength, opData, opAttributes); - } - return Operation.retain(length); - } - - /// Skips [length] characters in source delta. - /// - /// Returns last skipped operation, or `null` if there was nothing to skip. - Operation? skip(int length) { - var skipped = 0; - Operation? op; - while (skipped < length && hasNext) { - final opLength = peekLength(); - final skip = math.min(length - skipped, opLength); - op = next(skip); - skipped += op.length!; - } - return op; - } -} +export 'package:dart_quill_delta/dart_quill_delta.dart'; + +// /// Implementation of Quill Delta format in Dart. +// library; + +// import 'dart:math' as math; + +// import 'package:collection/collection.dart'; +// import 'package:diff_match_patch/diff_match_patch.dart' as dmp; +// import 'package:quiver/core.dart'; + +// const _attributeEquality = DeepCollectionEquality(); +// const _valueEquality = DeepCollectionEquality(); + +// /// Decoder function to convert raw `data` object into a user-defined data type. +// /// +// /// Useful with embedded content. +// typedef DataDecoder = Object? Function(Object data); + +// /// Default data decoder which simply passes through the original value. +// Object? _passThroughDataDecoder(Object? data) => data; + +// /// Operation performed on a rich-text document. +// class Operation { +// Operation._(this.key, this.length, this.data, Map? attributes) +// : assert(_validKeys.contains(key), 'Invalid operation key "$key".'), +// assert(() { +// if (key != Operation.insertKey) return true; +// return data is String ? data.length == length : length == 1; +// }(), 'Length of insert operation must be equal to the data length.'), +// _attributes = +// attributes != null ? Map.from(attributes) : null; + +// /// Creates operation which deletes [length] of characters. +// factory Operation.delete(int length) => +// Operation._(Operation.deleteKey, length, '', null); + +// /// Creates operation which inserts [text] with optional [attributes]. +// factory Operation.insert(dynamic data, [Map? attributes]) => +// Operation._(Operation.insertKey, data is String ? data.length : 1, data, +// attributes); + +// /// Creates operation which retains [length] of characters and optionally +// /// applies attributes. +// factory Operation.retain(int? length, [Map? attributes]) => +// Operation._(Operation.retainKey, length, '', attributes); + +// /// Key of insert operations. +// static const String insertKey = 'insert'; + +// /// Key of delete operations. +// static const String deleteKey = 'delete'; + +// /// Key of retain operations. +// static const String retainKey = 'retain'; + +// /// Key of attributes collection. +// static const String attributesKey = 'attributes'; + +// static const List _validKeys = [insertKey, deleteKey, retainKey]; + +// /// Key of this operation, can be "insert", "delete" or "retain". +// final String key; + +// /// Length of this operation. +// final int? length; + +// /// Payload of "insert" operation, for other types is set to empty string. +// final Object? data; + +// /// Rich-text attributes set by this operation, can be `null`. +// Map? get attributes => +// _attributes == null ? null : Map.from(_attributes!); +// final Map? _attributes; + +// /// Creates new [Operation] from JSON payload. +// /// +// /// If `dataDecoder` parameter is not null then it is used to additionally +// /// decode the operation's data object. Only applied to insert operations. +// static Operation fromJson(Map data, {DataDecoder? dataDecoder}) { +// dataDecoder ??= _passThroughDataDecoder; +// final map = Map.from(data); +// if (map.containsKey(Operation.insertKey)) { +// final data = dataDecoder(map[Operation.insertKey]); +// final dataLength = data is String ? data.length : 1; +// return Operation._( +// Operation.insertKey, dataLength, data, map[Operation.attributesKey]); +// } else if (map.containsKey(Operation.deleteKey)) { +// final int? length = map[Operation.deleteKey]; +// return Operation._(Operation.deleteKey, length, '', null); +// } else if (map.containsKey(Operation.retainKey)) { +// final int? length = map[Operation.retainKey]; +// return Operation._( +// Operation.retainKey, length, '', map[Operation.attributesKey]); +// } +// throw ArgumentError.value(data, 'Invalid data for Delta operation.'); +// } + +// /// Returns JSON-serializable representation of this operation. +// Map toJson() { +// final json = {key: value}; +// if (_attributes != null) json[Operation.attributesKey] = attributes; +// return json; +// } + +// /// Returns value of this operation. +// /// +// /// For insert operations this returns text, for delete and retain - length. +// dynamic get value => (key == Operation.insertKey) ? data : length; + +// /// Returns `true` if this is a delete operation. +// bool get isDelete => key == Operation.deleteKey; + +// /// Returns `true` if this is an insert operation. +// bool get isInsert => key == Operation.insertKey; + +// /// Returns `true` if this is a retain operation. +// bool get isRetain => key == Operation.retainKey; + +// /// Returns `true` if this operation has no attributes, e.g. is plain text. +// bool get isPlain => _attributes == null || _attributes!.isEmpty; + +// /// Returns `true` if this operation sets at least one attribute. +// bool get isNotPlain => !isPlain; + +// /// Returns `true` is this operation is empty. +// /// +// /// An operation is considered empty if its [length] is equal to `0`. +// bool get isEmpty => length == 0; + +// /// Returns `true` is this operation is not empty. +// bool get isNotEmpty => length! > 0; + +// @override +// bool operator ==(other) { +// if (identical(this, other)) return true; +// if (other is! Operation) return false; +// final typedOther = other; +// return key == typedOther.key && +// length == typedOther.length && +// _valueEquality.equals(data, typedOther.data) && +// hasSameAttributes(typedOther); +// } + +// /// Returns `true` if this operation has attribute specified by [name]. +// bool hasAttribute(String name) => +// isNotPlain && _attributes!.containsKey(name); + +// /// Returns `true` if [other] operation has the same attributes as this one. +// bool hasSameAttributes(Operation other) { +// // treat null and empty equal +// if ((_attributes?.isEmpty ?? true) && +// (other._attributes?.isEmpty ?? true)) { +// return true; +// } +// return _attributeEquality.equals(_attributes, other._attributes); +// } + +// @override +// int get hashCode { +// if (_attributes != null && _attributes!.isNotEmpty) { +// final attrsHash = +// hashObjects(_attributes!.entries.map((e) => hash2(e.key, e.value))); +// return hash3(key, value, attrsHash); +// } +// return hash2(key, value); +// } + +// @override +// String toString() { +// final attr = attributes == null ? '' : ' + $attributes'; +// final text = isInsert +// ? (data is String +// ? (data as String).replaceAll('\n', '⏎') +// : data.toString()) +// : '$length'; +// return '$key⟨ $text ⟩$attr'; +// } +// } + +// /// Delta represents a document or a modification of a document as a sequence of +// /// insert, delete and retain operations. +// /// +// /// Delta consisting of only "insert" operations is usually referred to as +// /// "document delta". When delta includes also "retain" or "delete" operations +// /// it is a "change delta". +// class Delta { +// /// Creates new empty [Delta]. +// factory Delta() => Delta._([]); + +// Delta._(List operations) : _operations = operations; + +// /// Creates new [Delta] from [other]. +// factory Delta.from(Delta other) => +// Delta._(List.from(other._operations)); + +// /// Creates new [Delta] from a List of Operation +// factory Delta.fromOperations(List operations) => +// Delta._(operations.toList()); + +// // Placeholder char for embed in diff() +// static final String _kNullCharacter = String.fromCharCode(0); + +// /// Transforms two attribute sets. +// static Map? transformAttributes( +// Map? a, Map? b, bool priority) { +// if (a == null) return b; +// if (b == null) return null; + +// if (!priority) return b; + +// final result = b.keys.fold>({}, (attributes, key) { +// if (!a.containsKey(key)) attributes[key] = b[key]; +// return attributes; +// }); + +// return result.isEmpty ? null : result; +// } + +// /// Composes two attribute sets. +// static Map? composeAttributes( +// Map? a, Map? b, +// {bool keepNull = false}) { +// a ??= const {}; +// b ??= const {}; + +// final result = Map.from(a)..addAll(b); +// final keys = result.keys.toList(growable: false); + +// if (!keepNull) { +// for (final key in keys) { +// if (result[key] == null) result.remove(key); +// } +// } + +// return result.isEmpty ? null : result; +// } + +// ///get anti-attr result base on base +// static Map invertAttributes( +// Map? attr, Map? base) { +// attr ??= const {}; +// base ??= const {}; + +// final baseInverted = base.keys.fold({}, (dynamic memo, key) { +// if (base![key] != attr![key] && attr.containsKey(key)) { +// memo[key] = base[key]; +// } +// return memo; +// }); + +// final inverted = +// Map.from(attr.keys.fold(baseInverted, (memo, key) { +// if (base![key] != attr![key] && !base.containsKey(key)) { +// memo[key] = null; +// } +// return memo; +// })); +// return inverted; +// } + +// /// Returns diff between two attribute sets +// static Map? diffAttributes( +// Map? a, Map? b) { +// a ??= const {}; +// b ??= const {}; + +// final attributes = {}; +// 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; +// } + +// final List _operations; + +// int _modificationCount = 0; + +// /// Creates [Delta] from de-serialized JSON representation. +// /// +// /// If `dataDecoder` parameter is not null then it is used to additionally +// /// decode the operation's data object. Only applied to insert operations. +// static Delta fromJson(List data, {DataDecoder? dataDecoder}) { +// return Delta._(data +// .map((op) => Operation.fromJson(op, dataDecoder: dataDecoder)) +// .toList()); +// } + +// /// Returns list of operations in this delta. +// List toList() => List.from(_operations); + +// /// Returns JSON-serializable version of this delta. +// List toJson() => toList().map((operation) => operation.toJson()).toList(); + +// /// Returns `true` if this delta is empty. +// bool get isEmpty => _operations.isEmpty; + +// /// Returns `true` if this delta is not empty. +// bool get isNotEmpty => _operations.isNotEmpty; + +// /// Returns number of operations in this delta. +// int get length => _operations.length; + +// /// Returns [Operation] at specified [index] in this delta. +// Operation operator [](int index) => _operations[index]; + +// /// Returns [Operation] at specified [index] in this delta. +// Operation elementAt(int index) => _operations.elementAt(index); + +// /// Returns the first [Operation] in this delta. +// Operation get first => _operations.first; + +// /// Returns the last [Operation] in this delta. +// Operation get last => _operations.last; + +// @override +// bool operator ==(dynamic other) { +// if (identical(this, other)) return true; +// if (other is! Delta) return false; +// final typedOther = other; +// const comparator = ListEquality(DefaultEquality()); +// return comparator.equals(_operations, typedOther._operations); +// } + +// @override +// int get hashCode => hashObjects(_operations); + +// /// Retain [count] of characters from current position. +// void retain(int count, [Map? attributes]) { +// assert(count >= 0); +// if (count == 0) return; // no-op +// push(Operation.retain(count, attributes)); +// } + +// /// Insert [data] at current position. +// void insert(dynamic data, [Map? attributes]) { +// if (data is String && data.isEmpty) return; // no-op +// push(Operation.insert(data, attributes)); +// } + +// /// Delete [count] characters from current position. +// void delete(int count) { +// assert(count >= 0); +// if (count == 0) return; +// push(Operation.delete(count)); +// } + +// void _mergeWithTail(Operation operation) { +// assert(isNotEmpty); +// assert(last.key == operation.key); +// assert(operation.data is String && last.data is String); + +// final length = operation.length! + last.length!; +// final lastText = last.data as String; +// final opText = operation.data as String; +// final resultText = lastText + opText; +// final index = _operations.length; +// _operations.replaceRange(index - 1, index, [ +// Operation._(operation.key, length, resultText, operation.attributes), +// ]); +// } + +// /// Pushes new operation into this delta. +// /// +// /// Performs compaction by composing [operation] with current tail operation +// /// of this delta, when possible. For instance, if current tail is +// /// `insert('abc')` and pushed operation is `insert('123')` then existing +// /// tail is replaced with `insert('abc123')` - a compound result of the two +// /// operations. +// void push(Operation operation) { +// if (operation.isEmpty) return; + +// var index = _operations.length; +// final lastOp = _operations.isNotEmpty ? _operations.last : null; +// if (lastOp != null) { +// if (lastOp.isDelete && operation.isDelete) { +// _mergeWithTail(operation); +// return; +// } + +// if (lastOp.isDelete && operation.isInsert) { +// index -= 1; // Always insert before deleting +// final nLastOp = (index > 0) ? _operations.elementAt(index - 1) : null; +// if (nLastOp == null) { +// _operations.insert(0, operation); +// return; +// } +// } + +// if (lastOp.isInsert && operation.isInsert) { +// if (lastOp.hasSameAttributes(operation) && +// operation.data is String && +// lastOp.data is String) { +// _mergeWithTail(operation); +// return; +// } +// } + +// if (lastOp.isRetain && operation.isRetain) { +// if (lastOp.hasSameAttributes(operation)) { +// _mergeWithTail(operation); +// return; +// } +// } +// } +// if (index == _operations.length) { +// _operations.add(operation); +// } else { +// final opAtIndex = _operations.elementAt(index); +// _operations.replaceRange(index, index + 1, [operation, opAtIndex]); +// } +// _modificationCount++; +// } + +// /// Composes next operation from [thisIter] and [otherIter]. +// /// +// /// Returns new operation or `null` if operations from [thisIter] and +// /// [otherIter] nullify each other. For instance, for the pair `insert('abc')` +// /// and `delete(3)` composition result would be empty string. +// Operation? _composeOperation( +// DeltaIterator thisIter, DeltaIterator otherIter) { +// if (otherIter.isNextInsert) return otherIter.next(); +// if (thisIter.isNextDelete) return thisIter.next(); + +// final length = math.min(thisIter.peekLength(), otherIter.peekLength()); +// final thisOp = thisIter.next(length); +// final otherOp = otherIter.next(length); +// assert(thisOp.length == otherOp.length); + +// if (otherOp.isRetain) { +// final attributes = composeAttributes( +// thisOp.attributes, +// otherOp.attributes, +// keepNull: thisOp.isRetain, +// ); +// if (thisOp.isRetain) { +// return Operation.retain(thisOp.length, attributes); +// } else if (thisOp.isInsert) { +// return Operation.insert(thisOp.data, attributes); +// } else { +// throw StateError('Unreachable'); +// } +// } else { +// // otherOp == delete && thisOp in [retain, insert] +// assert(otherOp.isDelete); +// if (thisOp.isRetain) return otherOp; +// assert(thisOp.isInsert); +// // otherOp(delete) + thisOp(insert) => null +// } +// return null; +// } + +// /// Composes this delta with [other] and returns new [Delta]. +// /// +// /// It is not required for this and [other] delta to represent a document +// /// delta (consisting only of insert operations). +// Delta compose(Delta other) { +// final result = Delta(); +// final thisIter = DeltaIterator(this); +// final otherIter = DeltaIterator(other); + +// while (thisIter.hasNext || otherIter.hasNext) { +// final newOp = _composeOperation(thisIter, otherIter); +// if (newOp != null) result.push(newOp); +// } +// return result..trim(); +// } + +// /// Returns a new lazy Iterable with elements that are created by calling +// /// f on each element of this Iterable in iteration order. +// /// +// /// Convenience method +// Iterable map(T Function(Operation) f) { +// return _operations.map(f); +// } + +// /// Returns a [Delta] containing differences between 2 [Delta]s. +// /// If [cleanupSemantic] is `true` (default), applies the following: +// /// +// /// The diff of "mouse" and "sofas" is +// /// [delete(1), insert("s"), retain(1), +// /// delete("u"), insert("fa"), retain(1), delete(1)]. +// /// While this is the optimum diff, it is difficult for humans to understand. +// /// Semantic cleanup rewrites the diff, +// /// expanding it into a more intelligible format. +// /// The above example would become: [(-1, "mouse"), (1, "sofas")]. +// /// (source: https://github.com/google/diff-match-patch/wiki/API) +// /// +// /// Useful when one wishes to display difference between 2 documents +// Delta diff(Delta other, {bool cleanupSemantic = true}) { +// if (_operations.equals(other._operations)) { +// return Delta(); +// } +// final stringThis = map((op) { +// if (op.isInsert) { +// return op.data is String ? op.data : _kNullCharacter; +// } +// final prep = this == other ? 'on' : 'with'; +// throw ArgumentError('diff() call $prep non-document'); +// }).join(); +// final stringOther = other.map((op) { +// if (op.isInsert) { +// return op.data is String ? op.data : _kNullCharacter; +// } +// final prep = this == other ? 'on' : 'with'; +// throw ArgumentError('diff() call $prep non-document'); +// }).join(); + +// final retDelta = Delta(); +// final diffResult = dmp.diff(stringThis, stringOther); +// if (cleanupSemantic) { +// dmp.DiffMatchPatch().diffCleanupSemantic(diffResult); +// } + +// final thisIter = DeltaIterator(this); +// final otherIter = DeltaIterator(other); + +// for (final component in diffResult) { +// var length = component.text.length; +// while (length > 0) { +// var opLength = 0; +// switch (component.operation) { +// case dmp.DIFF_INSERT: +// opLength = math.min(otherIter.peekLength(), length); +// retDelta.push(otherIter.next(opLength)); +// break; +// case dmp.DIFF_DELETE: +// opLength = math.min(length, thisIter.peekLength()); +// thisIter.next(opLength); +// retDelta.delete(opLength); +// break; +// case dmp.DIFF_EQUAL: +// opLength = math.min( +// math.min(thisIter.peekLength(), otherIter.peekLength()), +// length, +// ); +// final thisOp = thisIter.next(opLength); +// final otherOp = otherIter.next(opLength); +// if (thisOp.data == otherOp.data) { +// retDelta.retain( +// opLength, +// diffAttributes(thisOp.attributes, otherOp.attributes), +// ); +// } else { +// retDelta +// ..push(otherOp) +// ..delete(opLength); +// } +// break; +// } +// length -= opLength; +// } +// } +// return retDelta..trim(); +// } + +// /// Transforms next operation from [otherIter] against next operation in +// /// [thisIter]. +// /// +// /// Returns `null` if both operations nullify each other. +// Operation? _transformOperation( +// DeltaIterator thisIter, DeltaIterator otherIter, bool priority) { +// if (thisIter.isNextInsert && (priority || !otherIter.isNextInsert)) { +// return Operation.retain(thisIter.next().length); +// } else if (otherIter.isNextInsert) { +// return otherIter.next(); +// } + +// final length = math.min(thisIter.peekLength(), otherIter.peekLength()); +// final thisOp = thisIter.next(length); +// final otherOp = otherIter.next(length); +// assert(thisOp.length == otherOp.length); + +// // At this point only delete and retain operations are possible. +// if (thisOp.isDelete) { +// // otherOp is either delete or retain, so they nullify each other. +// return null; +// } else if (otherOp.isDelete) { +// return otherOp; +// } else { +// // Retain otherOp which is either retain or insert. +// return Operation.retain( +// length, +// transformAttributes(thisOp.attributes, otherOp.attributes, priority), +// ); +// } +// } + +// /// Transforms [other] delta against operations in this delta. +// Delta transform(Delta other, bool priority) { +// final result = Delta(); +// final thisIter = DeltaIterator(this); +// final otherIter = DeltaIterator(other); + +// while (thisIter.hasNext || otherIter.hasNext) { +// final newOp = _transformOperation(thisIter, otherIter, priority); +// if (newOp != null) result.push(newOp); +// } +// return result..trim(); +// } + +// /// Removes trailing retain operation with empty attributes, if present. +// void trim() { +// if (isNotEmpty) { +// final last = _operations.last; +// if (last.isRetain && last.isPlain) _operations.removeLast(); +// } +// } + +// /// Removes trailing '\n' +// void _trimNewLine() { +// if (isNotEmpty) { +// final lastOp = _operations.last; +// final lastOpData = lastOp.data; + +// if (lastOpData is String && lastOpData.endsWith('\n')) { +// _operations.removeLast(); +// if (lastOpData.length > 1) { +// insert(lastOpData.substring(0, lastOpData.length - 1), +// lastOp.attributes); +// } +// } +// } +// } + +// /// Concatenates [other] with this delta and returns the result. +// Delta concat(Delta other, {bool trimNewLine = false}) { +// final result = Delta.from(this); +// if (trimNewLine) { +// result._trimNewLine(); +// } +// if (other.isNotEmpty) { +// // In case first operation of other can be merged with last operation in +// // our list. +// result.push(other._operations.first); +// result._operations.addAll(other._operations.sublist(1)); +// } +// return result; +// } + +// /// Inverts this delta against [base]. +// /// +// /// Returns new delta which negates effect of this delta when applied to +// /// [base]. This is an equivalent of "undo" operation on deltas. +// Delta invert(Delta base) { +// final inverted = Delta(); +// if (base.isEmpty) return inverted; + +// var baseIndex = 0; +// for (final op in _operations) { +// if (op.isInsert) { +// inverted.delete(op.length!); +// } else if (op.isRetain && op.isPlain) { +// inverted.retain(op.length!); +// baseIndex += op.length!; +// } else if (op.isDelete || (op.isRetain && op.isNotPlain)) { +// final length = op.length!; +// final sliceDelta = base.slice(baseIndex, baseIndex + length); +// sliceDelta.toList().forEach((baseOp) { +// if (op.isDelete) { +// inverted.push(baseOp); +// } else if (op.isRetain && op.isNotPlain) { +// final invertAttr = +// invertAttributes(op.attributes, baseOp.attributes); +// inverted.retain( +// baseOp.length!, invertAttr.isEmpty ? null : invertAttr); +// } +// }); +// baseIndex += length; +// } else { +// throw StateError('Unreachable'); +// } +// } +// inverted.trim(); +// return inverted; +// } + +// /// Returns slice of this delta from [start] index (inclusive) to [end] +// /// (exclusive). +// Delta slice(int start, [int? end]) { +// final delta = Delta(); +// var index = 0; +// final opIterator = DeltaIterator(this); + +// final actualEnd = end ?? DeltaIterator.maxLength; + +// while (index < actualEnd && opIterator.hasNext) { +// Operation op; +// if (index < start) { +// op = opIterator.next(start - index); +// } else { +// op = opIterator.next(actualEnd - index); +// delta.push(op); +// } +// index += op.length!; +// } +// return delta; +// } + +// /// Transforms [index] against this delta. +// /// +// /// Any "delete" operation before specified [index] shifts it backward, as +// /// well as any "insert" operation shifts it forward. +// /// +// /// The [force] argument is used to resolve scenarios when there is an +// /// insert operation at the same position as [index]. If [force] is set to +// /// `true` (default) then position is forced to shift forward, otherwise +// /// position stays at the same index. In other words setting [force] to +// /// `false` gives higher priority to the transformed position. +// /// +// /// Useful to adjust caret or selection positions. +// int transformPosition(int index, {bool force = true}) { +// final iter = DeltaIterator(this); +// var offset = 0; +// while (iter.hasNext && offset <= index) { +// final op = iter.next(); +// if (op.isDelete) { +// index -= math.min(op.length!, index - offset); +// continue; +// } else if (op.isInsert && (offset < index || force)) { +// index += op.length!; +// } +// offset += op.length!; +// } +// return index; +// } + +// @override +// String toString() => _operations.join('\n'); +// } + +// /// Specialized iterator for [Delta]s. +// class DeltaIterator { +// DeltaIterator(this.delta) : _modificationCount = delta._modificationCount; + +// static const int maxLength = 1073741824; + +// final Delta delta; +// final int _modificationCount; +// int _index = 0; +// int _offset = 0; + +// bool get isNextInsert => nextOperationKey == Operation.insertKey; + +// bool get isNextDelete => nextOperationKey == Operation.deleteKey; + +// bool get isNextRetain => nextOperationKey == Operation.retainKey; + +// String? get nextOperationKey { +// if (_index < delta.length) { +// return delta.elementAt(_index).key; +// } else { +// return null; +// } +// } + +// bool get hasNext => peekLength() < maxLength; + +// /// Returns length of next operation without consuming it. +// /// +// /// Returns [maxLength] if there is no more operations left to iterate. +// int peekLength() { +// if (_index < delta.length) { +// final operation = delta._operations[_index]; +// return operation.length! - _offset; +// } +// return maxLength; +// } + +// /// Consumes and returns next operation. +// /// +// /// Optional [length] specifies maximum length of operation to return. Note +// /// that actual length of returned operation may be less than specified value. +// /// +// /// If this iterator reached the end of the Delta then returns a retain +// /// operation with its length set to [maxLength]. +// // TODO: Note that we used double.infinity as the default value +// // for length here +// // but this can now cause a type error since operation length is +// // expected to be an int. Changing default length to [maxLength] is +// // a workaround to avoid breaking changes. +// Operation next([int length = maxLength]) { +// if (_modificationCount != delta._modificationCount) { +// throw ConcurrentModificationError(delta); +// } + +// if (_index < delta.length) { +// 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) { +// _index++; +// _offset = 0; +// } else { +// _offset += actualLength; +// } +// final opData = op.isInsert && op.data is String +// ? (op.data as String) +// .substring(currentOffset, currentOffset + actualLength) +// : op.data; +// final opIsNotEmpty = +// opData is String ? opData.isNotEmpty : true; // embeds are never empty +// final opLength = opData is String ? opData.length : 1; +// final opActualLength = opIsNotEmpty ? opLength : actualLength; +// return Operation._(opKey, opActualLength, opData, opAttributes); +// } +// return Operation.retain(length); +// } + +// /// Skips [length] characters in source delta. +// /// +// /// Returns last skipped operation, or `null` if there was nothing to skip. +// Operation? skip(int length) { +// var skipped = 0; +// Operation? op; +// while (skipped < length && hasNext) { +// final opLength = peekLength(); +// final skip = math.min(length - skipped, opLength); +// op = next(skip); +// skipped += op.length!; +// } +// return op; +// } +// } diff --git a/packages/README.md b/packages/README.md deleted file mode 100644 index 0f8fce772..000000000 --- a/packages/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# 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 - -Pub: [quill_html_converter](https://pub.dev/packages/quill_html_converter) - -## Table of contents -- [Flutter Quill Packages](#flutter-quill-packages) - - [Table of contents](#table-of-contents) - - [Packages](#packages) - -## Packages -- [quill_html_converter](./quill_html_converter/) \ No newline at end of file diff --git a/packages/quill_html_converter/pubspec_overrides.yaml.disabled b/packages/quill_html_converter/pubspec_overrides.yaml.disabled deleted file mode 100644 index 844dcdead..000000000 --- a/packages/quill_html_converter/pubspec_overrides.yaml.disabled +++ /dev/null @@ -1,3 +0,0 @@ -dependency_overrides: - flutter_quill: - path: ../../ \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 7c5063430..2d9c3572e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -47,8 +47,6 @@ dependencies: collection: ^1.17.0 flutter_colorpicker: ^1.0.3 quiver: ^3.2.1 - characters: ^1.3.0 - diff_match_patch: ^0.4.1 equatable: ^2.0.5 meta: ^1.9.1 @@ -62,6 +60,7 @@ dependencies: flutter_keyboard_visibility: ^5.4.1 device_info_plus: ^9.1.0 super_clipboard: ^0.7.3 + dart_quill_delta: ^0.0.1 dev_dependencies: flutter_lints: ^3.0.1 diff --git a/pubspec_overrides.yaml.disabled b/pubspec_overrides.yaml.disabled index 0c0f849c8..94d344b00 100644 --- a/pubspec_overrides.yaml.disabled +++ b/pubspec_overrides.yaml.disabled @@ -1,3 +1,5 @@ dependency_overrides: flutter_quill_test: - path: ./flutter_quill_test \ No newline at end of file + path: ./flutter_quill_test + dart_quill_delta: + path: ./dart_quill_delta \ No newline at end of file diff --git a/packages/quill_html_converter/.gitignore b/quill_html_converter/.gitignore similarity index 100% rename from packages/quill_html_converter/.gitignore rename to quill_html_converter/.gitignore diff --git a/packages/quill_html_converter/.metadata b/quill_html_converter/.metadata similarity index 100% rename from packages/quill_html_converter/.metadata rename to quill_html_converter/.metadata diff --git a/packages/quill_html_converter/CHANGELOG.md b/quill_html_converter/CHANGELOG.md similarity index 100% rename from packages/quill_html_converter/CHANGELOG.md rename to quill_html_converter/CHANGELOG.md diff --git a/quill_html_converter/LICENSE b/quill_html_converter/LICENSE new file mode 100644 index 000000000..e82b91ed3 --- /dev/null +++ b/quill_html_converter/LICENSE @@ -0,0 +1,21 @@ +MIT License + +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 +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/packages/quill_html_converter/README.md b/quill_html_converter/README.md similarity index 100% rename from packages/quill_html_converter/README.md rename to quill_html_converter/README.md diff --git a/packages/quill_html_converter/analysis_options.yaml b/quill_html_converter/analysis_options.yaml similarity index 100% rename from packages/quill_html_converter/analysis_options.yaml rename to quill_html_converter/analysis_options.yaml diff --git a/packages/quill_html_converter/lib/quill_html_converter.dart b/quill_html_converter/lib/quill_html_converter.dart similarity index 94% rename from packages/quill_html_converter/lib/quill_html_converter.dart rename to quill_html_converter/lib/quill_html_converter.dart index 2e8d080fa..7ed4fe0b6 100644 --- a/packages/quill_html_converter/lib/quill_html_converter.dart +++ b/quill_html_converter/lib/quill_html_converter.dart @@ -1,6 +1,6 @@ library quill_html_converter; -import 'package:flutter_quill/flutter_quill.dart' show Delta; +import 'package:dart_quill_delta/dart_quill_delta.dart'; import 'package:vsc_quill_delta_to_html/vsc_quill_delta_to_html.dart' as conventer show ConverterOptions, QuillDeltaToHtmlConverter; diff --git a/packages/quill_html_converter/pubspec.yaml b/quill_html_converter/pubspec.yaml similarity index 80% rename from packages/quill_html_converter/pubspec.yaml rename to quill_html_converter/pubspec.yaml index 47f5796b8..d09180207 100644 --- a/packages/quill_html_converter/pubspec.yaml +++ b/quill_html_converter/pubspec.yaml @@ -1,10 +1,10 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html version: 9.0.0-dev-11 -homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ -repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ +homepage: https://github.com/singerdmx/flutter-quill/tree/master/quill_html_converter/ +repository: https://github.com/singerdmx/flutter-quill/tree/master/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ -documentation: https://github.com/singerdmx/flutter-quill/tree/master/packages/quill_html_converter/ +documentation: https://github.com/singerdmx/flutter-quill/tree/master/quill_html_converter/ topics: - ui @@ -20,14 +20,13 @@ environment: dependencies: flutter: sdk: flutter - flutter_quill: ^9.0.0-dev-6 vsc_quill_delta_to_html: ^1.0.3 html2md: ^1.3.1 - # markdown: ^7.1.1 - # delta_markdown_converter: ^0.0.3-dev markdown: ^7.1.1 charcode: ^1.3.1 collection: ^1.18.0 + dart_quill_delta: ^0.0.1 + dev_dependencies: flutter_test: diff --git a/quill_html_converter/pubspec_overrides.yaml.disabled b/quill_html_converter/pubspec_overrides.yaml.disabled new file mode 100644 index 000000000..aae8e5dde --- /dev/null +++ b/quill_html_converter/pubspec_overrides.yaml.disabled @@ -0,0 +1,3 @@ +dependency_overrides: + dart_quill_delta: + path: ../dart_quill_delta \ No newline at end of file diff --git a/packages/quill_html_converter/test/quill_html_converter.dart b/quill_html_converter/test/quill_html_converter.dart similarity index 100% rename from packages/quill_html_converter/test/quill_html_converter.dart rename to quill_html_converter/test/quill_html_converter.dart diff --git a/scripts/disable_local_dev.sh b/scripts/disable_local_dev.sh index a64ba4869..ca52b8c20 100755 --- a/scripts/disable_local_dev.sh +++ b/scripts/disable_local_dev.sh @@ -20,7 +20,7 @@ rm flutter_quill_test/pubspec_overrides.yaml echo "" echo "Disable local development for all the other packages..." -rm packages/quill_html_converter/pubspec_overrides.yaml +rm quill_html_converter/pubspec_overrides.yaml echo "" diff --git a/scripts/enable_local_dev.sh b/scripts/enable_local_dev.sh index 603465bca..c37bc8951 100755 --- a/scripts/enable_local_dev.sh +++ b/scripts/enable_local_dev.sh @@ -20,7 +20,7 @@ cp flutter_quill_test/pubspec_overrides.yaml.disabled flutter_quill_test/pubspec echo "" echo "Enable local development for all the other packages..." -cp packages/quill_html_converter/pubspec_overrides.yaml.disabled packages/quill_html_converter/pubspec_overrides.yaml +cp quill_html_converter/pubspec_overrides.yaml.disabled quill_html_converter/pubspec_overrides.yaml echo "" diff --git a/scripts/pub_get.sh b/scripts/pub_get.sh index 6bd082c83..a836d79ff 100644 --- a/scripts/pub_get.sh +++ b/scripts/pub_get.sh @@ -2,4 +2,4 @@ flutter pub get (cd flutter_quill_extensions && flutter pub get) (cd flutter_quill_test && flutter pub get) -(cd packages/quill_html_converter && flutter pub get) +(cd quill_html_converter && flutter pub get) diff --git a/scripts/regenerate_versions.dart b/scripts/regenerate_versions.dart index ed73e523a..279890124 100644 --- a/scripts/regenerate_versions.dart +++ b/scripts/regenerate_versions.dart @@ -13,7 +13,7 @@ final packages = [ './', './flutter_quill_extensions', './flutter_quill_test', - './packages/quill_html_converter' + './quill_html_converter' ]; Future main(List args) async {