From 5f2058d3541c8fbb13a5502a0d003b3a755ed6de Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 17 Oct 2024 05:50:55 +0300 Subject: [PATCH 01/93] fix: remove super_clipboard from flutter_quill_extensions and move it to quill_super_clipboard (#2322) --- example/android/app/build.gradle | 2 +- .../android/app/src/main/AndroidManifest.xml | 7 - .../flutter/generated_plugin_registrant.cc | 8 - example/linux/flutter/generated_plugins.cmake | 2 - .../Flutter/GeneratedPluginRegistrant.swift | 8 +- example/macos/Podfile.lock | 22 +-- .../flutter/generated_plugin_registrant.cc | 6 - .../windows/flutter/generated_plugins.cmake | 2 - .../lib/flutter_quill_extensions.dart | 8 +- .../clipboard/super_clipboard_service.dart | 152 ++---------------- flutter_quill_extensions/pubspec.yaml | 1 - 11 files changed, 20 insertions(+), 198 deletions(-) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 41df88424..cefaa47ae 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -39,7 +39,7 @@ android { defaultConfig { applicationId = "com.example.example" - minSdk = 23 + minSdk = flutter.minSdkVersion targetSdk = flutter.targetSdkVersion versionCode = flutterVersionCode.toInteger() versionName = flutterVersionName diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index b4ca5acfe..6144a50f1 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -56,13 +56,6 @@ android:name="flutterEmbedding" android:value="2" /> - - - #include -#include -#include #include void fl_register_plugins(FlPluginRegistry* registry) { @@ -19,12 +17,6 @@ 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) 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 b75263bb2..074d9445f 100644 --- a/example/linux/flutter/generated_plugins.cmake +++ b/example/linux/flutter/generated_plugins.cmake @@ -5,8 +5,6 @@ list(APPEND FLUTTER_PLUGIN_LIST desktop_drop file_selector_linux - irondash_engine_context - super_native_extensions url_launcher_linux ) diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index 10abb57dc..6386fee92 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,29 +6,23 @@ import FlutterMacOS import Foundation import desktop_drop -import device_info_plus import file_selector_macos import gal -import irondash_engine_context import path_provider_foundation import quill_native_bridge_macos import share_plus -import sqflite_darwin -import super_native_extensions +import sqflite import url_launcher_macos import video_player_avfoundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin")) - DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin")) - IrondashEngineContextPlugin.register(with: registry.registrar(forPlugin: "IrondashEngineContextPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) QuillNativeBridgePlugin.register(with: registry.registrar(forPlugin: "QuillNativeBridgePlugin")) 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 d9fe20ac9..c557e215c 100644 --- a/example/macos/Podfile.lock +++ b/example/macos/Podfile.lock @@ -1,16 +1,12 @@ PODS: - desktop_drop (0.0.1): - FlutterMacOS - - device_info_plus (0.0.1): - - FlutterMacOS - file_selector_macos (0.0.1): - FlutterMacOS - FlutterMacOS (1.0.0) - gal (1.0.0): - Flutter - FlutterMacOS - - irondash_engine_context (0.0.1): - - FlutterMacOS - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS @@ -21,8 +17,6 @@ PODS: - sqflite (0.0.3): - Flutter - FlutterMacOS - - super_native_extensions (0.0.1): - - FlutterMacOS - url_launcher_macos (0.0.1): - FlutterMacOS - video_player_avfoundation (0.0.1): @@ -31,32 +25,25 @@ PODS: DEPENDENCIES: - desktop_drop (from `Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos`) - - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) - file_selector_macos (from `Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - gal (from `Flutter/ephemeral/.symlinks/plugins/gal/darwin`) - - irondash_engine_context (from `Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos`) - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - quill_native_bridge_macos (from `Flutter/ephemeral/.symlinks/plugins/quill_native_bridge_macos/macos`) - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`) - - 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`) EXTERNAL SOURCES: desktop_drop: :path: Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos - device_info_plus: - :path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos file_selector_macos: :path: Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos FlutterMacOS: :path: Flutter/ephemeral gal: :path: Flutter/ephemeral/.symlinks/plugins/gal/darwin - irondash_engine_context: - :path: Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos path_provider_foundation: :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin quill_native_bridge_macos: @@ -65,8 +52,6 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos sqflite: :path: Flutter/ephemeral/.symlinks/plugins/sqflite/darwin - 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: @@ -74,17 +59,14 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: desktop_drop: 69eeff437544aa619c8db7f4481b3a65f7696898 - device_info_plus: ce1b7762849d3ec103d0e0517299f2db7ad60720 - file_selector_macos: 54fdab7caa3ac3fc43c9fac4d7d8d231277f8cf2 + file_selector_macos: cc3858c981fe6889f364731200d6232dac1d812d FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 gal: 61e868295d28fe67ffa297fae6dacebf56fd53e1 - irondash_engine_context: da62996ee25616d2f01bbeb85dc115d813359478 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 quill_native_bridge_macos: f90985c5269ac7ba84d933605b463d96e5f544fe share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec - super_native_extensions: 85efee3a7495b46b04befcfc86ed12069264ebf3 - url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399 + url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404 video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3 PODFILE CHECKSUM: 7159dd71cf9f57a5669bb2dee7a5030dbcc0483f diff --git a/example/windows/flutter/generated_plugin_registrant.cc b/example/windows/flutter/generated_plugin_registrant.cc index 084810413..644ed755b 100644 --- a/example/windows/flutter/generated_plugin_registrant.cc +++ b/example/windows/flutter/generated_plugin_registrant.cc @@ -9,9 +9,7 @@ #include #include #include -#include #include -#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { @@ -21,12 +19,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("FileSelectorWindows")); GalPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("GalPluginCApi")); - 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 f568d1445..54763af6f 100644 --- a/example/windows/flutter/generated_plugins.cmake +++ b/example/windows/flutter/generated_plugins.cmake @@ -6,9 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST desktop_drop file_selector_windows gal - irondash_engine_context share_plus - super_native_extensions url_launcher_windows ) diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index e36dce9e1..01fa017ff 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -4,8 +4,6 @@ import 'package:flutter_quill/flutter_quill_internal.dart' show ClipboardServiceProvider; import 'package:meta/meta.dart' show experimental; -import 'src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart'; - export 'src/common/extensions/controller_ext.dart'; export 'src/common/utils/utils.dart'; export 'src/editor/image/image_embed.dart'; @@ -67,11 +65,13 @@ class FlutterQuillExtensions { 'The functionality of super_clipboard is now built-in in recent versions of flutter_quill.\n' 'To migrate, remove this function call and see ' 'https://pub.dev/packages/quill_native_bridge#-platform-configuration (optional for copying images on Android) to use quill_native_bridge implementation (the new default).\n' - 'Or if you want to use super_clipboard implementation (support might discontinued in newer versions), use the package https://pub.dev/packages/quill_super_clipboard\n' + 'Or if you want to use super_clipboard implementation (support might discontinued in newer versions), use the experimental package: https://pub.dev/packages/quill_super_clipboard\n' 'See https://github.com/singerdmx/flutter-quill/pull/2230 for more details.', ) @experimental static void useSuperClipboardPlugin() { - ClipboardServiceProvider.setInstance(SuperClipboardService()); + throw UnimplementedError( + 'The super_clipboard plugin is no longer a dependency. See the deprecation message of FlutterQuillExtensions.useSuperClipboardPlugin()', + ); } } diff --git a/flutter_quill_extensions/lib/src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart b/flutter_quill_extensions/lib/src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart index 51466ff61..185ab13b6 100644 --- a/flutter_quill_extensions/lib/src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart +++ b/flutter_quill_extensions/lib/src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart @@ -1,144 +1,16 @@ -import 'dart:async' show Completer; -import 'dart:convert' show utf8; +@Deprecated( + 'The super_clipboard implementation has been moved into a separate package: https://pub.dev/packages/quill_super_clipboard and this class will be removed in future releases.\n' + 'The new default implementation of flutter_quill is https://pub.dev/packages/quill_native_bridge and supports required features for rich text pasting.\n' + 'Also see https://github.com/singerdmx/flutter-quill/pull/2230 and https://pub.dev/packages/quill_native_bridge#-platform-configuration', +) +library; -import 'package:flutter/foundation.dart'; -import 'package:flutter_quill/flutter_quill_internal.dart' - show ClipboardService; import 'package:meta/meta.dart' show experimental; -import 'package:super_clipboard/super_clipboard.dart'; - -/// Implementation using the https://pub.dev/packages/super_clipboard plugin. @experimental -class SuperClipboardService extends ClipboardService { - /// [Null] if the Clipboard API is not supported on this platform - /// https://pub.dev/packages/super_clipboard#usage - SystemClipboard? _getSuperClipboard() { - return SystemClipboard.instance; - } - - SystemClipboard _getSuperClipboardOrThrow() { - final clipboard = _getSuperClipboard(); - if (clipboard == null) { - // To avoid getting this exception, use _canProvide() - throw UnsupportedError( - 'Clipboard API is not supported on this platform.', - ); - } - return clipboard; - } - - Future _canProvide({required DataFormat format}) async { - final clipboard = _getSuperClipboard(); - if (clipboard == null) { - return false; - } - final reader = await clipboard.read(); - return reader.canProvide(format); - } - - Future _provideFileAsBytes({ - required SimpleFileFormat format, - }) async { - final clipboard = _getSuperClipboardOrThrow(); - final reader = await clipboard.read(); - final completer = Completer(); - - reader.getFile( - format, - (file) async { - final bytes = await file.readAll(); - completer.complete(bytes); - }, - onError: completer.completeError, - ); - final bytes = await completer.future; - return bytes; - } - - Future _provideFileAsString({ - required SimpleFileFormat format, - }) async { - final fileBytes = await _provideFileAsBytes(format: format); - final fileText = utf8.decode(fileBytes); - return fileText; - } - - /// According to super_clipboard docs, will return `null` if the value - /// is not available or the data is virtual (macOS and Windows) - Future _provideSimpleValueFormatAsString({ - required SimpleValueFormat format, - }) async { - final clipboard = _getSuperClipboardOrThrow(); - final reader = await clipboard.read(); - final value = await reader.readValue(format); - return value; - } - - @override - Future getHtmlText() async { - if (!(await _canProvide(format: Formats.htmlText))) { - return null; - } - return _provideSimpleValueFormatAsString(format: Formats.htmlText); - } - - @override - Future getHtmlFile() async { - if (!(await _canProvide(format: Formats.htmlFile))) { - return null; - } - return await _provideFileAsString(format: Formats.htmlFile); - } - - @override - Future getGifFile() async { - if (!(await _canProvide(format: Formats.gif))) { - return null; - } - return await _provideFileAsBytes(format: Formats.gif); - } - - @override - Future getImageFile() async { - final canProvidePngFile = await _canProvide(format: Formats.png); - if (canProvidePngFile) { - return _provideFileAsBytes(format: Formats.png); - } - final canProvideJpegFile = await _canProvide(format: Formats.jpeg); - if (canProvideJpegFile) { - return _provideFileAsBytes(format: Formats.jpeg); - } - return null; - } - - @override - Future getMarkdownFile() async { - // Formats.md is for markdown files - if (!(await _canProvide(format: Formats.md))) { - return null; - } - return await _provideFileAsString(format: Formats.md); - } - - @override - Future copyImage(Uint8List imageBytes) async { - final clipboard = SystemClipboard.instance; - if (clipboard == null) { - return; - } - final item = DataWriterItem()..add(Formats.png(imageBytes)); - await clipboard.write([item]); - } - - @override - Future get hasClipboardContent async { - final clipboard = _getSuperClipboard(); - if (clipboard == null) { - return false; - } - final reader = await clipboard.read(); - final availablePlatformFormats = reader.platformFormats; - return availablePlatformFormats.isNotEmpty; - } -} +@Deprecated( + 'The super_clipboard implementation has been moved into a separate package: https://pub.dev/packages/quill_super_clipboard and this class will be removed in future releases.\n' + 'The new default implementation of flutter_quill is https://pub.dev/packages/quill_native_bridge and supports required features for rich text pasting.\n' + 'Also see https://github.com/singerdmx/flutter-quill/pull/2230 and https://pub.dev/packages/quill_native_bridge#-platform-configuration', +) +class SuperClipboardService {} diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 37b2dcdc0..b7e14bef5 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -43,7 +43,6 @@ dependencies: # Plugins video_player: ^2.8.1 url_launcher: ^6.2.1 - super_clipboard: ^0.8.22 gal: ^2.3.0 gal_linux: ^0.1.0 image_picker: ^1.0.4 From fd6fa5071815928389dfb2b8c77d614cd2edd978 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 22 Oct 2024 16:22:42 +0300 Subject: [PATCH 02/93] chore: remove controller from configuration class, remove the quill toolbar and editor provider widgets, other minor breaking changes --- README.md | 20 +- doc/configurations/custom_buttons.md | 9 +- doc/configurations/font_size.md | 25 +- doc/configurations/localizations_setup.md | 23 +- doc/configurations/search.md | 2 +- doc/configurations/using_custom_app_widget.md | 16 +- doc/custom_embed_blocks.md | 8 +- doc/custom_toolbar.md | 211 +++++++------- doc/customizing_shortcuts.md | 8 +- doc/migration/10_to_11.md | 170 ++++++++++++ doc/translation.md | 24 +- example/lib/main.dart | 8 +- .../lib/screens/quill/my_quill_editor.dart | 260 +++++++++--------- .../lib/screens/quill/my_quill_toolbar.dart | 238 ++++++++-------- example/lib/screens/quill/quill_screen.dart | 12 +- example/lib/screens/simple/simple_screen.dart | 36 --- flutter_quill_extensions/README.md | 114 +------- .../lib/flutter_quill_extensions.dart | 1 - .../lib/src/common/image_video_utils.dart | 2 +- .../lib/src/common/utils/utils.dart | 51 ++-- .../lib/src/editor/image/image_embed.dart | 24 +- .../src/editor/image/image_embed_types.dart | 4 +- .../lib/src/editor/image/image_menu.dart | 57 ++-- .../image/models/image_configurations.dart | 20 +- .../lib/src/editor/image/widgets/image.dart | 39 ++- .../editor/image/widgets/image_resizer.dart | 2 +- .../image_picker/image_options.dart | 20 -- .../image_picker/image_picker.dart | 30 -- .../image_picker/packages/image_picker.dart | 80 ------ .../image_picker/s_image_picker.dart | 61 ---- .../image_saver/exceptions.dart | 23 -- .../image_saver/image_saver.dart | 7 - .../image_saver/packages/gal.dart | 77 ------ .../image_saver/s_image_saver.dart | 31 --- .../shared_configurations.dart | 78 ------ .../lib/src/toolbar/camera/camera_button.dart | 57 +--- .../toolbar/camera/select_camera_action.dart | 4 +- .../src/toolbar/formula/formula_button.dart | 28 +- .../lib/src/toolbar/image/image_button.dart | 63 ++--- .../toolbar/image/select_image_source.dart | 8 +- .../lib/src/toolbar/table/table_button.dart | 28 +- .../lib/src/toolbar/video/models/video.dart | 2 - .../toolbar/video/select_video_source.dart | 7 +- .../lib/src/toolbar/video/video_button.dart | 54 ++-- .../pubspec_overrides.yaml | 4 + lib/flutter_quill.dart | 10 +- lib/flutter_quill_internal.dart | 1 + lib/src/controller/provider.dart | 23 -- lib/src/controller/quill_controller.dart | 29 +- .../editor/config/editor_configurations.dart | 42 +-- lib/src/editor/config/element_options.dart | 7 +- .../editor/config/elements/code_block.dart | 8 +- .../config/elements/list/ordered_list.dart | 5 +- .../config/elements/list/unordered_list.dart | 5 +- lib/src/editor/editor.dart | 212 ++++++-------- lib/src/editor/editor_builder.dart | 31 --- lib/src/editor/provider.dart | 96 ------- .../config/raw_editor_configurations.dart | 44 +-- lib/src/editor/raw_editor/raw_editor.dart | 22 +- .../editor/raw_editor/raw_editor_actions.dart | 7 +- .../editor/style_widgets/bullet_point.dart | 18 +- .../editor/style_widgets/checkbox_point.dart | 9 +- .../editor/style_widgets/number_point.dart | 28 +- .../bullet_point_leading.dart | 3 +- .../check_box_leading.dart | 3 +- .../codeblock_line_number_leading.dart | 2 +- .../number_point_leading.dart | 3 +- lib/src/editor/widgets/text/text_block.dart | 18 +- .../quill_configurations.dart | 1 - lib/src/editor_toolbar_shared/color.dart | 22 ++ .../quill_configurations_ext.dart | 13 - .../l10n/extensions/localizations_ext.dart | 15 +- lib/src/l10n/widgets/localizations.dart | 31 --- .../base_button/base_value_button.dart | 26 +- .../base_button/stateless_base_button.dart | 27 +- lib/src/toolbar/base_toolbar.dart | 74 ----- .../alignment/select_alignment_buttons.dart | 3 +- .../toolbar/buttons/clear_format_button.dart | 3 +- lib/src/toolbar/buttons/clipboard_button.dart | 6 +- .../toolbar/buttons/color/color_button.dart | 42 +-- .../toolbar/buttons/color/color_dialog.dart | 13 +- .../toolbar/buttons/custom_button_button.dart | 41 +-- .../toolbar/buttons/font_family_button.dart | 37 +-- lib/src/toolbar/buttons/font_size_button.dart | 14 +- .../select_header_style_buttons.dart | 10 +- .../select_header_style_dropdown_button.dart | 8 +- lib/src/toolbar/buttons/history_button.dart | 6 +- lib/src/toolbar/buttons/indent_button.dart | 6 +- .../toolbar/buttons/link_style2_button.dart | 103 ++----- .../toolbar/buttons/link_style_button.dart | 33 +-- .../search/legacy/legacy_search_button.dart | 137 --------- .../search/legacy/legacy_search_dialog.dart | 230 ---------------- .../toolbar/buttons/search/search_button.dart | 95 ++----- .../toolbar/buttons/search/search_dialog.dart | 27 +- .../select_line_height_dropdown_button.dart | 9 +- .../buttons/toggle_check_list_button.dart | 6 +- .../toolbar/buttons/toggle_style_button.dart | 6 +- .../config/base_button_configurations.dart | 48 +--- .../config/buttons/color_configurations.dart | 7 - .../buttons/font_size_configurations.dart | 32 +-- .../buttons/link_style2_configurations.dart | 3 - .../buttons/link_style_configurations.dart | 7 +- .../config/buttons/search_configurations.dart | 24 +- ...t_header_style_buttons_configurations.dart | 2 +- ..._style_dropdown_button_configurations.dart | 2 +- ..._style_dropdown_button_configurations.dart | 3 +- .../buttons/toggle_style_configurations.dart | 1 + .../config/simple_toolbar_button_options.dart | 15 +- .../config/simple_toolbar_configurations.dart | 67 +---- .../config/toolbar_configurations.dart | 18 -- .../config/toolbar_shared_configurations.dart | 5 +- lib/src/toolbar/provider.dart | 74 ----- lib/src/toolbar/simple_toolbar.dart | 225 +++++++-------- lib/src/toolbar/simple_toolbar_provider.dart | 77 ------ lib/src/toolbar/theme/quill_dialog_theme.dart | 10 +- lib/translations.dart | 4 - test/bug_fix_test.dart | 4 +- test/editor/editor_test.dart | 31 ++- 118 files changed, 1230 insertions(+), 3145 deletions(-) create mode 100644 doc/migration/10_to_11.md delete mode 100644 example/lib/screens/simple/simple_screen.dart delete mode 100644 flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/image_options.dart delete mode 100644 flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/image_picker.dart delete mode 100644 flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/packages/image_picker.dart delete mode 100644 flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/s_image_picker.dart delete mode 100644 flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/exceptions.dart delete mode 100644 flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/image_saver.dart delete mode 100644 flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/packages/gal.dart delete mode 100644 flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/s_image_saver.dart delete mode 100644 flutter_quill_extensions/lib/src/editor_toolbar_shared/shared_configurations.dart create mode 100644 flutter_quill_extensions/pubspec_overrides.yaml delete mode 100644 lib/src/controller/provider.dart delete mode 100644 lib/src/editor/editor_builder.dart delete mode 100644 lib/src/editor/provider.dart create mode 100644 lib/src/editor_toolbar_shared/color.dart delete mode 100644 lib/src/editor_toolbar_shared/quill_configurations_ext.dart delete mode 100644 lib/src/l10n/widgets/localizations.dart delete mode 100644 lib/src/toolbar/base_toolbar.dart delete mode 100644 lib/src/toolbar/buttons/search/legacy/legacy_search_button.dart delete mode 100644 lib/src/toolbar/buttons/search/legacy/legacy_search_dialog.dart delete mode 100644 lib/src/toolbar/config/toolbar_configurations.dart delete mode 100644 lib/src/toolbar/provider.dart delete mode 100644 lib/src/toolbar/simple_toolbar_provider.dart delete mode 100644 lib/translations.dart diff --git a/README.md b/README.md index 9b545160c..15f24c131 100644 --- a/README.md +++ b/README.md @@ -163,13 +163,29 @@ Create the file `your_project/android/app/src/main/res/xml/file_paths.xml` with ## 🚀 Usage +Add the localization delegate to your app widget: + +```dart +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; + +MaterialApp( + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + FlutterQuillLocalizations.delegate, + ], +); +``` + Instantiate a controller: ```dart QuillController _controller = QuillController.basic(); ``` -Use the `QuillEditor`, and `QuillSimpleToolbar` widgets, +Use the `QuillEditor` and `QuillSimpleToolbar` widgets, and attach the `QuillController` to them: ```dart @@ -376,7 +392,7 @@ Open this [page](./doc/translation.md) for more info Take a look at [flutter_quill_test](https://pub.dev/packages/flutter_quill_test) for testing. -Notice that currently, the support for testing is limited. +Currently, the support for testing is limited. ## 🤝 Contributing diff --git a/doc/configurations/custom_buttons.md b/doc/configurations/custom_buttons.md index 1bff246f1..05817f867 100644 --- a/doc/configurations/custom_buttons.md +++ b/doc/configurations/custom_buttons.md @@ -1,18 +1,17 @@ -# Custom `QuillToolbar` Buttons ✨ +# Custom `QuillSimpleToolbar` Buttons ✨ You may add custom buttons to the _end_ of the toolbar, via the `customButtons` option, which is a `List` of `QuillToolbarCustomButtonOptions`. ## Adding an Icon 🖌️ -To add an Icon, we should use a new `QuillToolbarCustomButtonOptions` class +To add an Icon: ```dart QuillToolbarCustomButtonOptions( icon: const Icon(Icons.ac_unit), - tooltip: '', + tooltip: 'Tooltip', onPressed: () {}, - afterButtonPressed: () {}, ), ``` @@ -21,7 +20,7 @@ To add an Icon, we should use a new `QuillToolbarCustomButtonOptions` class Each `QuillCustomButton` is used as part of the `customButtons` option as follows: ```dart -QuillToolbar.simple( +QuillSimpleToolbar( controller: _controller, configurations: QuillSimpleToolbarConfigurations( customButtons: [ diff --git a/doc/configurations/font_size.md b/doc/configurations/font_size.md index 2eb3d8e9f..4e64519d8 100644 --- a/doc/configurations/font_size.md +++ b/doc/configurations/font_size.md @@ -1,19 +1,34 @@ # 🔠 Font Size Within the editor toolbar, a drop-down with font-sizing capabilities is available. -This can be enabled or disabled -with `showFontSize`. +This can be enabled or disabled with `showFontSize`. -When enabled, the default font-size values can be modified via _optional_ `fontSizeValues`. +When enabled, the default font-size values can be modified via _optional_ `rawItemsMap`. Accepts a `Map` consisting of a `String` title for the font size and a `String` value for the font size. Example: ```dart -fontSizeValues: const {'Small': '8', 'Medium': '24.5', 'Large': '46'} +QuillSimpleToolbar( + configurations: const QuillSimpleToolbarConfigurations( + buttonOptions: QuillSimpleToolbarButtonOptions( + fontSize: QuillToolbarFontSizeButtonOptions( + rawItemsMap: {'Small': '8', 'Medium': '24.5', 'Large': '46'}, + ), + ), + ), + ); ``` Font size can be cleared with a value of `0`, for example: ```dart -fontSizeValues: const {'Small': '8', 'Medium': '24.5', 'Large': '46', 'Clear': '0'} +QuillSimpleToolbar( + configurations: const QuillSimpleToolbarConfigurations( + buttonOptions: QuillSimpleToolbarButtonOptions( + fontSize: QuillToolbarFontSizeButtonOptions( + rawItemsMap: {'Small': '8', 'Medium': '24.5', 'Large': '46', 'Clear': '0'}, + ), + ), + ), + ); ``` \ No newline at end of file diff --git a/doc/configurations/localizations_setup.md b/doc/configurations/localizations_setup.md index a2184dfe9..1bb6298cc 100644 --- a/doc/configurations/localizations_setup.md +++ b/doc/configurations/localizations_setup.md @@ -1,31 +1,14 @@ # 🌍 Localizations Setup -In addition to the required delegates mentioned above in [Using custom app widget](./using_custom_app_widget.md), -which are: +The required localization delegates: ```dart localizationsDelegates: const [ DefaultCupertinoLocalizations.delegate, DefaultMaterialLocalizations.delegate, DefaultWidgetsLocalizations.delegate, -], + FlutterQuillLocalizations.delegate, +] ``` -Which are used by Flutter widgets. - -📌 Note: The library also needs the `FlutterQuillLocalizations.delegate`: - -```dart -// Required localizations delegates ... -FlutterQuillLocalizations.delegate -``` - -**You don't have to add this explicitly** because we have wrapped the `QuillEditor` and `QuillToolbar` with -`FlutterQuillLocalizationsWidget`. -This widget will check if the necessary localizations are set; if not, it will -provide them only for these widgets. -Therefore, it's not strictly required. -However, if you are overriding the -`localizationsDelegates`, you can also add the `FlutterQuillLocalizations.delegate`. - 📄 For additional notes, refer to the [Translation](../translation.md) section. diff --git a/doc/configurations/search.md b/doc/configurations/search.md index 78aba4723..af6c02623 100644 --- a/doc/configurations/search.md +++ b/doc/configurations/search.md @@ -10,7 +10,7 @@ By default, the content of Embed objects are not searched. You can enable search by setting the [searchEmbedMode] in searchConfigurations: ```dart - MyQuillEditor( + QuillEditor.basic( controller: _controller, configurations: QuillEditorConfigurations( searchConfigurations: const QuillSearchConfigurations( diff --git a/doc/configurations/using_custom_app_widget.md b/doc/configurations/using_custom_app_widget.md index f498db587..a1fe497a4 100644 --- a/doc/configurations/using_custom_app_widget.md +++ b/doc/configurations/using_custom_app_widget.md @@ -16,19 +16,5 @@ localizationsDelegates: const [ ], ``` +📄 For additional notes, see the [localizations setup](./localizations_setup.md) page. -You might need more depending on your use case. For example, if you are using custom localizations for your app with a custom app widget like `FluentApp` from [FluentUI], you will also need: - -```dart -localizationsDelegates: const [ - // Required localizations delegates ... - FluentLocalizations.delegate, - AppLocalizations.delegate, -], -``` - -📌 Note: In recent versions of `FluentApp`, you no longer need to add the `localizationsDelegates`. This is just an example. For more information, refer to the [#946](https://github.com/bdlukaa/fluent_ui/pull/946). - -📄 For additional notes, see the [Localizations](./localizations_setup.md) page. - -[FluentUI]: https://pub.dev/packages/fluent_ui diff --git a/doc/custom_embed_blocks.md b/doc/custom_embed_blocks.md index d61b4faa9..d08b21a0d 100644 --- a/doc/custom_embed_blocks.md +++ b/doc/custom_embed_blocks.md @@ -78,7 +78,7 @@ the `CustomBlockEmbed` inside of a `BlockEmbed.custom`). ```dart Future _addEditNote(BuildContext context, {Document? document}) async { final isEditing = document != null; - final quillEditorController = QuillController( + final controller = QuillController( document: document ?? Document(), selection: const TextSelection.collapsed(offset: 0), ); @@ -98,16 +98,16 @@ Future _addEditNote(BuildContext context, {Document? document}) async { ], ), content: QuillEditor.basic( - controller: quillEditorController, + controller: controller, configurations: const QuillEditorConfigurations(), ), ), ); - if (quillEditorController.document.isEmpty()) return; + if (controller.document.isEmpty()) return; final block = BlockEmbed.custom( - NotesBlockEmbed.fromDocument(quillEditorController.document), + NotesBlockEmbed.fromDocument(controller.document), ); final controller = _controller!; final index = controller.selection.baseOffset; diff --git a/doc/custom_toolbar.md b/doc/custom_toolbar.md index 53d04229d..c76accdb1 100644 --- a/doc/custom_toolbar.md +++ b/doc/custom_toolbar.md @@ -1,124 +1,103 @@ -# Custom Toolbar +# 🎨 Custom Toolbar -If you want to use a custom toolbar but still want the support of this library, -You can use the `QuillBaseToolbar` which is the base for the `QuillToolbar` - -Example: +You can use the `QuillController` in your custom toolbar or use the button widgets of the `QuillSimpleToolbar`: ```dart -QuillToolbar.simple( - configurations: const QuillSimpleToolbarConfigurations( - 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(), - // This is an implementation that only is used on - // flutter_quill and it's not originally - // implemented in Quill JS API, so it could cause conflicts - // with the original Quill Delta format - QuillToolbarSelectLineHeightStyleDropdownButton( - controller: globalController, - ), - 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, +SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Wrap( + 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(), + QuillToolbarSelectHeaderStyleDropdownButton( + controller: controller, + ), + const VerticalDivider(), + QuillToolbarSelectLineHeightStyleDropdownButton( + 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), + ], ), ) ``` -if you want a more customized toolbar feel free to create your own and use the `controller` to interact with the editor. -checkout the `QuillToolbar` and the buttons inside it to see an example of how that will work diff --git a/doc/customizing_shortcuts.md b/doc/customizing_shortcuts.md index c4b88f7cc..4300cae91 100644 --- a/doc/customizing_shortcuts.md +++ b/doc/customizing_shortcuts.md @@ -15,9 +15,7 @@ class AsteriskToItalicStyle extends StatelessWidget { @override Widget build(BuildContext context) { - return QuillEditor( - scrollController: , - focusNode: , + return QuillEditor.basic( controller: , configurations: QuillEditorConfigurations( characterShortcutEvents: [], @@ -73,9 +71,7 @@ class AsteriskToItalicStyle extends StatelessWidget { @override Widget build(BuildContext context) { - return QuillEditor( - scrollController: , - focusNode: , + return QuillEditor.basic( controller: , configurations: QuillEditorConfigurations( characterShortcutEvents: [ diff --git a/doc/migration/10_to_11.md b/doc/migration/10_to_11.md new file mode 100644 index 000000000..88f0c618b --- /dev/null +++ b/doc/migration/10_to_11.md @@ -0,0 +1,170 @@ +# Migration from 10.x.x to 11.x.x + +## 1. Clipboard + +The `super_clipboard` plugin has been removed from `flutter_quill` and `flutter_quill_extensions`. + +Remove the following if used: + +```diff +- FlutterQuillExtensions.useSuperClipboardPlugin(); +``` + +### A. Using the new default implementation + +> [!NOTE] +> You only need to remove `super_clipboard` configuration if you're not using [super_clipboard](https://pub.dev/packages/super_clipboard) which was introduced in your app as a transitive dependency. + +The [configuration of `super_clipboard`](https://pub.dev/packages/super_clipboard#getting-started) is no longer required. + +The following snippet in your `AndroidManifest.xml` **should be removed** otherwise you will be unable to launch the **Android app**: + +```xml + + +``` + +It can be found inside the `` tag if you have [added it](https://pub.dev/packages/super_clipboard#android-support). + +See the [`quill_native_bridge` platform configuration](https://pub.dev/packages/quill_native_bridge#-platform-configuration) (optional for copying images on **Android**). + +#### Other Optional changes + +The `super_clipboard` is no longer a dependency of `flutter_quill_extensions`. + +As such it's no longer required to set the `minSdkVersion` to `23` on **Android**. If the main reason you updated +the version was `flutter_quill_extensions` then you can restore the Flutter default now (currently `21`). + +- Use the Flutter default `minSdkVersion`: + +```kotlin +android { + defaultConfig { + minSdk = flutter.minSdkVersion + } +} +``` + +- Use the Flutter default `ndkVersion`: + +```kotlin +android { + ndkVersion = flutter.ndkVersion +} +``` + +> [!NOTE] +> You should only apply this optional change if you're not using +> [`super_clipboard`](https://pub.dev/packages/super_clipboard) or you don't have a reason to change it. + +### B. Continue using the `super_clipboard` implementation + +Use the new default implementation or if you want to continue using `super_clipboard`, use the package [quill_super_clipboard](https://pub.dev/packages/quill_super_clipboard) (**support might be discontinued in future releases**). + +> [!WARNING] +> The support of [quill_super_clipboard](https://pub.dev/packages/quill_super_clipboard) might be discontinued. It's still possible to +> override the default implementation manually. + +See [#2229](https://github.com/singerdmx/flutter-quill/issues/2229). + +## 2. Quill Controller + +The `QuillController` should now be passed to the `QuillEditor` and `QuillSimpleToolbar` constructor directly instead of the configuration class. + +**Before**: + +```dart +QuillEditor.basic( + configurations: QuillEditorConfigurations( + controller: _controller, + ), + ) +``` + +**After**: + +```dart +QuillEditor.basic( + controller: _controller, +) +``` + +See [#2037](https://github.com/singerdmx/flutter-quill/discussions/2037) for discussion. Thanks to [#2078](https://github.com/singerdmx/flutter-quill/pull/2078) + +## 3. Removal of the `QuillEditorProvider` and `QuillToolbarProvider` inherited widgets + +It's no longer possible to access the `QuillController`, the `QuillEditorConfiugrations`, and `QuillSimpleToolbarConfigurations` using the `BuildContext`. +Instead, you will have to pass them through constructors (revert to the old behavior). + +The extension methods on `BuildContext` like `requireQuillEditorConfigurations`, `quillEditorConfigurations`, and `quillEditorElementOptions` have been removed. + +See [#2301](https://github.com/singerdmx/flutter-quill/issues/2301). + +## 4. Required localization delegate + +This project uses the [Flutter Localizations library](https://api.flutter.dev/flutter/flutter_localizations/flutter_localizations-library.html), requiring `FlutterQuillLocalizations.delegate` to be included in your app widget (e.g., `MaterialApp`, `WidgetsApp`, `CupertinoApp`). + +Previously, we used a helper widget (`FlutterQuillLocalizationsWidget`) to manually provide localization delegates, but this approach was inefficient and error-prone, causing unexpected bugs. It has been removed. + +To use the `QuillEditor` and `QuillSimpleToolbar` widgets, add the required delegates as shown: + +```dart +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; + +MaterialApp( + localizationsDelegates: const [ + // Your other delegates... + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + FlutterQuillLocalizations.delegate, + ], +); +``` + +

OR (less code with less control)

+ +```dart +import 'package:flutter_quill/flutter_quill.dart'; + +MaterialApp( + localizationsDelegates: FlutterQuillLocalizations.localizationsDelegates, +); +``` + +The widget `FlutterQuillLocalizationsWidget` has been removed. + +The library `package:flutter_quill/translations.dart` has been removed and the replacement is `package:flutter_quill/flutter_quill.dart` + +## 5. The `flutter_quill_extensions` + +- Removes `ImagePickerService` and from `OnRequestPickVideo` and `OnRequestPickImage`. +- Removes `ImageSaverService` and from `ImageOptionsMenu`. +- Removes `QuillSharedExtensionsConfigurations`. +- The return type (`ImageProvider`) of `ImageEmbedBuilderProviderBuilder` has been made `null` so you can return `null` and fallback to our default handling. See [#2317](https://github.com/singerdmx/flutter-quill/pull/2317). +- Does not handle `AssetImage` anymore by default when loading images, instead use `imageProviderBuilder` to override the default handling. See [Image assets support](https://pub.dev/packages/flutter_quill_extensions#-image-assets). +- Removes `QuillSharedExtensionsConfigurations.assetsPrefix`. Use `imageProviderBuilder` to support image assets. See [Image assets support](https://pub.dev/packages/flutter_quill_extensions#-image-assets). + +## Minor changes + +- `QuillEditorConfigurations.readOnly` has been removed and is accessible from `QuillController.readOnly`. +- `QuillController.editorFocusNode` has been removed, and should be passed and accessed to the `QuillEditor` instead. +- `QuillSimpleToolbar` and related toolbar buttons no longer request focus from the editor (revert to the old behavior). +- `QuillEditorBuilderWidget` and `QuillEditorConfigurations.builder` have been removed as there's no valid use-case and this can be confusing. +- `QuillToolbarLegacySearchDialog` and `QuillToolbarLegacySearchButton` have been removed and replaced with `QuillToolbarSearchDialog` and `QuillToolbarSearchButton` which has been introduced in [9.4.0](https://github.com/singerdmx/flutter-quill/releases/tag/v9.4.0). `QuillSimpleToolbarConfigurations.searchButtonType` is removed too. +- The property `dialog BarrierColor` has been removed from all buttons, use the `Dialog Theme` in your `ThemeData` instead to customize it. See [Override a theme](https://docs.flutter.dev/cookbook/design/themes#override-a-theme). +- The deprecated member `QuillRawEditorConfigurations.enableMarkdownStyleConversion` has been removed. See [#2214](https://github.com/singerdmx/flutter-quill/issues/2214). +- Removes `QuillSharedConfigurations.extraConfigurations`. The optional confiugration of `flutter_quill_extensions` should be separated. +- Renames `QuillEditorBulletPoint` to `QuillBulletPoint`, `QuillEditorCheckboxPoint` to `QuillCheckbox`, `QuillEditorNumberPoint` to `QuillNumberPoint`. +- Removes `QuillEditorElementOptions` and `QuillEditorConfigurations.elementOptions`. To customize the leading, see [#2146](https://github.com/singerdmx/flutter-quill/pull/2146) as an example. +- Removes `QuillController.toolbarConfigurations` to not store anything specific to the `QuillSimpleToolbar` in the `QuillController`. +- Removes the base toolbar (`QuillToolbar`) since it's no longer required. Previously it was required due to the provider and localization delegate check. The class `QuillToolbarConfigurations` has been also removed. +- Removes `QuillToolbarBaseButtonOptions.globalIconSize` and `QuillToolbarBaseButtonOptions.globalIconButtonFactor`. Both are deprecated for at least 10 months. +- Removes `QuillToolbarFontSizeButton.defaultDisplayText` (deprecated for more than 10 months). +- Removes `fontSizesValues` and `fontFamilyValues` from `QuillSimpleToolbarConfigurations` since those were used only in `QuillToolbarFontSizeButton` and `QuillToolbarFontFamilyButton`. Pass them to `rawItemsMap` (which exists in each button configuration) directly. +- Removes `QuillSimpleToolbarButtonOptions.base` which allows having default configuration for all buttons, it didn't work correctly and involved a lot of manual checks, and is a bad design. Introduced in `8.0.0` and we don't have plans on introducing an alternative. diff --git a/doc/translation.md b/doc/translation.md index 8eae802fc..825ee9158 100644 --- a/doc/translation.md +++ b/doc/translation.md @@ -1,29 +1,7 @@ # 🌍 Translation 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 -QuillToolbar.simple( - controller: _controller, - configurations: QuillSimpleToolbarConfigurations( - sharedConfigurations: const QuillSharedConfigurations( - locale: Locale('de'), - ), - ), -), -Expanded( - child: QuillEditor.basic( - controller: _controller, - configurations: QuillEditorConfigurations( - sharedConfigurations: const QuillSharedConfigurations( - locale: Locale('de'), - ), - ), - ), -) -``` +your `WidgetsApp` for example `MaterialApp` which usually follows the system locally unless you set your own locale. ## 🌐 Supported Locales diff --git a/example/lib/main.dart b/example/lib/main.dart index 27e107671..1decdb361 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -5,8 +5,7 @@ import 'package:flutter_localizations/flutter_localizations.dart' GlobalCupertinoLocalizations, GlobalMaterialLocalizations, GlobalWidgetsLocalizations; -import 'package:flutter_quill/flutter_quill.dart' show Document; -import 'package:flutter_quill/translations.dart' show FlutterQuillLocalizations; +import 'package:flutter_quill/flutter_quill.dart'; import 'screens/home/widgets/home_screen.dart'; import 'screens/quill/quill_screen.dart'; @@ -59,10 +58,7 @@ class MyApp extends StatelessWidget { GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, - // Uncomment this line to use provide flutter quill localizations - // in your widgets app, otherwise the quill widgets will provide it - // internally: - // FlutterQuillLocalizations.delegate, + FlutterQuillLocalizations.delegate, ], supportedLocales: FlutterQuillLocalizations.supportedLocales, routes: { diff --git a/example/lib/screens/quill/my_quill_editor.dart b/example/lib/screens/quill/my_quill_editor.dart index c9fb632c8..5684c6bd7 100644 --- a/example/lib/screens/quill/my_quill_editor.dart +++ b/example/lib/screens/quill/my_quill_editor.dart @@ -8,9 +8,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill/flutter_quill_internal.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; -// ignore: implementation_imports -import 'package:flutter_quill_extensions/src/editor/image/widgets/image.dart' - show getImageProviderByImageSource, imageFileExtensions; import 'package:path/path.dart' as path; import '../../extensions/scaffold_messenger.dart'; @@ -33,138 +30,147 @@ class MyQuillEditor extends StatelessWidget { @override Widget build(BuildContext context) { final defaultTextStyle = DefaultTextStyle.of(context); - return QuillEditor( - scrollController: scrollController, - focusNode: focusNode, - controller: controller, - configurations: configurations.copyWith( - elementOptions: const QuillEditorElementOptions( - codeBlock: QuillEditorCodeBlockElementOptions( - enableLineNumbers: true, - ), - orderedList: QuillEditorOrderedListElementOptions(), - unorderedList: QuillEditorUnOrderedListElementOptions( - useTextColorForDot: true, + return Builder(builder: (context) { + final editor = QuillEditor( + scrollController: scrollController, + focusNode: focusNode, + controller: controller, + configurations: configurations.copyWith( + elementOptions: const QuillEditorElementOptions( + codeBlock: QuillEditorCodeBlockElementOptions( + enableLineNumbers: true, + ), + orderedList: QuillEditorOrderedListElementOptions(), + unorderedList: QuillEditorUnOrderedListElementOptions( + useTextColorForDot: true, + ), ), - ), - customStyles: DefaultStyles( - h1: DefaultTextBlockStyle( - defaultTextStyle.style.copyWith( - fontSize: 32, - height: 1.15, - fontWeight: FontWeight.w300, + customStyles: DefaultStyles( + h1: DefaultTextBlockStyle( + defaultTextStyle.style.copyWith( + fontSize: 32, + height: 1.15, + fontWeight: FontWeight.w300, + ), + HorizontalSpacing.zero, + const VerticalSpacing(16, 0), + VerticalSpacing.zero, + null, ), - HorizontalSpacing.zero, - const VerticalSpacing(16, 0), - VerticalSpacing.zero, - null, + sizeSmall: defaultTextStyle.style.copyWith(fontSize: 9), ), - sizeSmall: defaultTextStyle.style.copyWith(fontSize: 9), - ), - scrollable: true, - placeholder: 'Start writing your notes...', - padding: const EdgeInsets.all(16), - onImagePaste: (imageBytes) async { - if (kIsWeb) { - return null; - } - // We will save it to system temporary files - final newFileName = - 'imageFile-${DateTime.now().toIso8601String()}.png'; - final newPath = path.join( - io.Directory.systemTemp.path, - newFileName, - ); - final file = await io.File( - newPath, - ).writeAsBytes(imageBytes, flush: true); - return file.path; - }, - onGifPaste: (gifBytes) async { - if (kIsWeb) { - return null; - } - // We will save it to system temporary files - final newFileName = 'gifFile-${DateTime.now().toIso8601String()}.gif'; - final newPath = path.join( - io.Directory.systemTemp.path, - newFileName, - ); - final file = await io.File( - newPath, - ).writeAsBytes(gifBytes, flush: true); - return file.path; - }, - embedBuilders: [ - ...(kIsWeb - ? FlutterQuillEmbeds.editorWebBuilders() - : FlutterQuillEmbeds.editorBuilders( - imageEmbedConfigurations: QuillEditorImageEmbedConfigurations( - imageErrorWidgetBuilder: (context, error, stackTrace) { - return Text( - 'Error while loading an image: ${error.toString()}', - ); - }, - imageProviderBuilder: (context, imageUrl) { - // cached_network_image is supported - // only for Android, iOS and web + scrollable: true, + placeholder: 'Start writing your notes...', + padding: const EdgeInsets.all(16), + onImagePaste: (imageBytes) async { + if (kIsWeb) { + return null; + } + // We will save it to system temporary files + final newFileName = + 'imageFile-${DateTime.now().toIso8601String()}.png'; + final newPath = path.join( + io.Directory.systemTemp.path, + newFileName, + ); + final file = await io.File( + newPath, + ).writeAsBytes(imageBytes, flush: true); + return file.path; + }, + onGifPaste: (gifBytes) async { + if (kIsWeb) { + return null; + } + // We will save it to system temporary files + final newFileName = + 'gifFile-${DateTime.now().toIso8601String()}.gif'; + final newPath = path.join( + io.Directory.systemTemp.path, + newFileName, + ); + final file = await io.File( + newPath, + ).writeAsBytes(gifBytes, flush: true); + return file.path; + }, + embedBuilders: [ + ...(kIsWeb + ? FlutterQuillEmbeds.editorWebBuilders() + : FlutterQuillEmbeds.editorBuilders( + imageEmbedConfigurations: + QuillEditorImageEmbedConfigurations( + imageErrorWidgetBuilder: (context, error, stackTrace) { + return Text( + 'Error while loading an image: ${error.toString()}', + ); + }, + imageProviderBuilder: (context, imageUrl) { + // cached_network_image is supported + // only for Android, iOS and web - // We will use it only if image from network - if (isAndroidApp || isIosApp || kIsWeb) { - if (isHttpBasedUrl(imageUrl)) { - return CachedNetworkImageProvider( - imageUrl, - ); + // We will use it only if image from network + if (isAndroidApp || isIosApp || kIsWeb) { + if (isHttpBasedUrl(imageUrl)) { + return CachedNetworkImageProvider( + imageUrl, + ); + } } - } - return getImageProviderByImageSource( - imageUrl, - imageProviderBuilder: null, - context: context, - assetsPrefix: QuillSharedExtensionsConfigurations.get( - context: context) - .assetsPrefix, - ); - }, - ), - videoEmbedConfigurations: QuillEditorVideoEmbedConfigurations( - customVideoBuilder: (videoUrl, readOnly) { - // Example: Check for YouTube Video URL and return your - // YouTube video widget here. - // Otherwise return null to fallback to the defualt logic - return null; - }, - ignoreYouTubeSupport: true, - ), - )), - TimeStampEmbedBuilderWidget(), - ], - builder: (context, rawEditor) { - // The `desktop_drop` plugin doesn't support iOS platform for now - if (isIosApp) { - return rawEditor; + if (imageUrl.startsWith('assets/')) { + return AssetImage(imageUrl); + } + return null; + }, + ), + videoEmbedConfigurations: + QuillEditorVideoEmbedConfigurations( + customVideoBuilder: (videoUrl, readOnly) { + // Example: Check for YouTube Video URL and return your + // YouTube video widget here. + + // Otherwise return null to fallback to the defualt logic + return null; + }, + ignoreYouTubeSupport: true, + ), + )), + TimeStampEmbedBuilderWidget(), + ], + ), + ); + // The `desktop_drop` plugin doesn't support iOS platform for now + if (isIosApp) { + return editor; + } + return DropTarget( + onDragDone: (details) { + final scaffoldMessenger = ScaffoldMessenger.of(context); + final file = details.files.first; + const imageFileExtensions = [ + '.jpeg', + '.png', + '.jpg', + '.gif', + '.webp', + '.tif', + '.heic' + ]; + final isSupported = imageFileExtensions.any(file.name.endsWith); + if (!isSupported) { + scaffoldMessenger.showText( + 'Only images are supported right now: ${file.mimeType}, ${file.name}, ${file.path}, $imageFileExtensions', + ); + return; } - return DropTarget( - onDragDone: (details) { - final scaffoldMessenger = ScaffoldMessenger.of(context); - final file = details.files.first; - final isSupported = imageFileExtensions.any(file.name.endsWith); - if (!isSupported) { - scaffoldMessenger.showText( - 'Only images are supported right now: ${file.mimeType}, ${file.name}, ${file.path}, $imageFileExtensions', - ); - return; - } - context.requireQuillController.insertImageBlock( - imageSource: file.path, - ); - scaffoldMessenger.showText('Image is inserted.'); - }, - child: rawEditor, + controller.insertImageBlock( + imageSource: file.path, ); + scaffoldMessenger.showText('Image is inserted.'); }, - ), - ); + child: editor, + ); + }); } } diff --git a/example/lib/screens/quill/my_quill_toolbar.dart b/example/lib/screens/quill/my_quill_toolbar.dart index ef13bd34d..d72a239be 100644 --- a/example/lib/screens/quill/my_quill_toolbar.dart +++ b/example/lib/screens/quill/my_quill_toolbar.dart @@ -108,109 +108,104 @@ class MyQuillToolbar extends StatelessWidget { if (state.useCustomQuillToolbar) { // For more info // https://github.com/singerdmx/flutter-quill/blob/master/doc/custom_toolbar.md - return QuillToolbar( - configurations: const QuillToolbarConfigurations(), - child: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Wrap( - 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, + return SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Wrap( + children: [ + IconButton( + onPressed: () => context.read().updateSettings( + state.copyWith(useCustomQuillToolbar: false)), + icon: const Icon( + Icons.width_normal, ), - const VerticalDivider(), - QuillToolbarSelectHeaderStyleDropdownButton( - controller: controller, - ), - const VerticalDivider(), - QuillToolbarSelectLineHeightStyleDropdownButton( - 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), - ], - ), + ), + 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(), + QuillToolbarSelectHeaderStyleDropdownButton( + controller: controller, + ), + const VerticalDivider(), + QuillToolbarSelectLineHeightStyleDropdownButton( + 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), + ], ), ); } - return QuillToolbar.simple( + return QuillSimpleToolbar( controller: controller, /// configurations parameter: @@ -219,26 +214,31 @@ class MyQuillToolbar extends StatelessWidget { configurations: QuillSimpleToolbarConfigurations( showAlignmentButtons: true, multiRowsDisplay: true, - fontFamilyValues: { - 'Amatic': GoogleFonts.amaticSc().fontFamily!, - 'Annie': GoogleFonts.annieUseYourTelescope().fontFamily!, - 'Formal': GoogleFonts.petitFormalScript().fontFamily!, - 'Roboto': GoogleFonts.roboto().fontFamily! - }, - fontSizesValues: const { - '14': '14.0', - '16': '16.0', - '18': '18.0', - '20': '20.0', - '22': '22.0', - '24': '24.0', - '26': '26.0', - '28': '28.0', - '30': '30.0', - '35': '35.0', - '40': '40.0' - }, - searchButtonType: SearchButtonType.modern, + buttonOptions: QuillSimpleToolbarButtonOptions( + fontFamily: QuillToolbarFontFamilyButtonOptions( + rawItemsMap: { + 'Amatic': GoogleFonts.amaticSc().fontFamily!, + 'Annie': GoogleFonts.annieUseYourTelescope().fontFamily!, + 'Formal': GoogleFonts.petitFormalScript().fontFamily!, + 'Roboto': GoogleFonts.roboto().fontFamily! + }, + ), + fontSize: const QuillToolbarFontSizeButtonOptions( + rawItemsMap: { + '14': '14.0', + '16': '16.0', + '18': '18.0', + '20': '20.0', + '22': '22.0', + '24': '24.0', + '26': '26.0', + '28': '28.0', + '30': '30.0', + '35': '35.0', + '40': '40.0' + }, + ), + ), customButtons: [ QuillToolbarCustomButtonOptions( icon: const Icon(Icons.add_alarm_rounded), diff --git a/example/lib/screens/quill/quill_screen.dart b/example/lib/screens/quill/quill_screen.dart index acb3dffe4..03b38bbe0 100644 --- a/example/lib/screens/quill/quill_screen.dart +++ b/example/lib/screens/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:share_plus/share_plus.dart' show Share; import '../../extensions/scaffold_messenger.dart'; @@ -149,14 +149,6 @@ class _QuillScreenState extends State { } QuillSharedConfigurations get _sharedConfigurations { - return const QuillSharedConfigurations( - // locale: Locale('en'), - extraConfigurations: { - QuillSharedExtensionsConfigurations.key: - QuillSharedExtensionsConfigurations( - assetsPrefix: 'assets', // Defaults to assets - ), - }, - ); + return const QuillSharedConfigurations(); } } diff --git a/example/lib/screens/simple/simple_screen.dart b/example/lib/screens/simple/simple_screen.dart deleted file mode 100644 index 15ab1e5e8..000000000 --- a/example/lib/screens/simple/simple_screen.dart +++ /dev/null @@ -1,36 +0,0 @@ -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( - controller: _controller, - configurations: const QuillSimpleToolbarConfigurations(), - ), - Expanded( - child: QuillEditor.basic( - controller: _controller, - configurations: const QuillEditorConfigurations( - padding: EdgeInsets.all(16), - ), - ), - ), - ], - ), - ); - } -} diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index 98988ae9d..6a4f2599a 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -75,12 +75,12 @@ the [Flutter macOS Networking documentation](https://docs.flutter.dev/data-and-b ## 🚀 Usage Once you follow the [Installation](#-installation) section. -Set the `embedBuilders` and `embedToolbar` params in configurations of `QuillEditor` and `QuillToolbar`. +Set the `embedBuilders` and `embedToolbar` params in configurations of `QuillEditor` and `QuillSimpleToolbar`. **Quill Toolbar**: ```dart -QuillToolbar.simple( +QuillSimpleToolbar( configurations: QuillSimpleToolbarConfigurations( embedButtons: FlutterQuillEmbeds.toolbarButtons(), ), @@ -144,111 +144,25 @@ Define flutterAlignment` as follows: This works only for non-web platforms. -### 📝 Rich Text Paste Feature - -The rich text paste feature is now supported directly in `flutter_quill` -as platform code is not bundled with the project. - ### 🖼️ Image Assets -If you want to use image assets in the Quill Editor, you need to make sure your assets folder is `assets` otherwise: +To support loading image assets in the editor: ```dart -QuillEditor.basic( - configurations: const QuillEditorConfigurations( - // ... - sharedConfigurations: QuillSharedConfigurations( - extraConfigurations: { - QuillSharedExtensionsConfigurations.key: - QuillSharedExtensionsConfigurations( - assetsPrefix: 'your-assets-folder-name', // Defaults to `assets` - ), +FlutterQuillEmbeds.editorBuilders( + imageEmbedConfigurations: + QuillEditorImageEmbedConfigurations( + imageProviderBuilder: (context, imageUrl) { + if (imageUrl.startsWith('assets/')) { + return AssetImage(imageUrl); + } + return null; }, - ), - ), -); + ), +) ``` -This info is necessary for the package to check if its 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: - -1. Drag and drop require native code, you can use any Flutter plugin you like, if you want a suggestion we - recommend [desktop_drop](https://pub.dev/packages/desktop_drop), it was originally developed for desktop. - It has support for the web as well as Android (that is not the case for iOS) -2. Add the dependency in your `pubspec.yaml` using the following command: - - ```yaml - flutter pub add desktop_drop - ``` - and import it with - ```dart - import 'package:desktop_drop/desktop_drop.dart'; - ``` -3. in the configurations of `QuillEditor`, use the `builder` to wrap the editor with `DropTarget` which comes - from `desktop_drop` - - ```dart - import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; - - QuillEditor.basic( - configurations: QuillEditorConfigurations( - padding: const EdgeInsets.all(16), - builder: (context, rawEditor) { - return DropTarget( - onDragDone: _onDragDone, - child: rawEditor, - ); - }, - embedBuilders: kIsWeb - ? FlutterQuillEmbeds.editorWebBuilders() - : FlutterQuillEmbeds.editorBuilders(), - ), - ) - ``` -4. Implement the `_onDragDone`, it depends on your use case but this is just a simple example - -```dart -const List imageFileExtensions = [ - '.jpeg', - '.png', - '.jpg', - '.gif', - '.webp', - '.tif', - '.heic' -]; -OnDragDoneCallback get _onDragDone { - return (details) { - final scaffoldMessenger = ScaffoldMessenger.of(context); - final file = details.files.first; - final isSupported = - imageFileExtensions.any((ext) => file.name.endsWith(ext)); - if (!isSupported) { - scaffoldMessenger.showSnackBar( - SnackBar( - content: Text( - 'Only images are supported right now: ${file.mimeType}, ${file.name}, ${file.path}, $imageFileExtensions', - ), - ), - ); - return; - } - // To get this extension function please import flutter_quill_extensions - _controller.insertImageBlock( - imageSource: file.path, - ); - scaffoldMessenger.showSnackBar( - const SnackBar( - content: Text('Image is inserted.'), - ), - ); - }; - } -``` +Ensures to replace `assets` with your assets directory name or change the logic to fit your needs. ## 🤝 Contributing diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index 01fa017ff..6db9f0898 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -21,7 +21,6 @@ export 'src/editor/video/models/video_web_configurations.dart'; export 'src/editor/video/models/youtube_video_support_mode.dart'; export 'src/editor/video/video_embed.dart'; export 'src/editor/video/video_web_embed.dart'; -export 'src/editor_toolbar_shared/shared_configurations.dart'; export 'src/flutter_quill_embeds.dart'; export 'src/toolbar/camera/camera_button.dart'; export 'src/toolbar/camera/camera_types.dart'; diff --git a/flutter_quill_extensions/lib/src/common/image_video_utils.dart b/flutter_quill_extensions/lib/src/common/image_video_utils.dart index 48ab383ee..319eb3118 100644 --- a/flutter_quill_extensions/lib/src/common/image_video_utils.dart +++ b/flutter_quill_extensions/lib/src/common/image_video_utils.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart' show QuillDialogTheme; -import 'package:flutter_quill/translations.dart'; +import 'package:flutter_quill/flutter_quill_internal.dart'; import 'utils/patterns.dart'; diff --git a/flutter_quill_extensions/lib/src/common/utils/utils.dart b/flutter_quill_extensions/lib/src/common/utils/utils.dart index 7e6b6d8ca..bfb342f73 100644 --- a/flutter_quill_extensions/lib/src/common/utils/utils.dart +++ b/flutter_quill_extensions/lib/src/common/utils/utils.dart @@ -1,9 +1,10 @@ import 'dart:io' show File; import 'package:flutter/foundation.dart' show immutable; +import 'package:gal/gal.dart'; +import 'package:http/http.dart' as http; import '../../editor/image/widgets/image.dart'; -import '../../editor_toolbar_shared/image_saver/s_image_saver.dart'; import 'patterns.dart'; bool isBase64(String str) { @@ -51,17 +52,16 @@ class SaveImageResult { Future saveImage({ required String imageUrl, - required ImageSaverService imageSaverService, }) async { final imageFile = File(imageUrl); - final hasPermission = await imageSaverService.hasAccess(); + final hasPermission = await Gal.hasAccess(); if (!hasPermission) { - await imageSaverService.requestAccess(); + await Gal.requestAccess(); } final imageExistsLocally = await imageFile.exists(); if (!imageExistsLocally) { try { - await imageSaverService.saveImageFromNetwork( + await _saveImageFromNetwork( Uri.parse(appendFileExtensionToImageUrl(imageUrl)), ); return const SaveImageResult( @@ -74,17 +74,36 @@ Future saveImage({ method: SaveImageResultMethod.network, ); } + } else { + try { + await _saveLocalImage(Uri.parse(imageUrl)); + return const SaveImageResult( + error: null, + method: SaveImageResultMethod.localStorage, + ); + } catch (e) { + return SaveImageResult( + error: e.toString(), + method: SaveImageResultMethod.localStorage, + ); + } } - try { - await imageSaverService.saveLocalImage(imageUrl); - return const SaveImageResult( - error: null, - method: SaveImageResultMethod.localStorage, - ); - } catch (e) { - return SaveImageResult( - error: e.toString(), - method: SaveImageResultMethod.localStorage, - ); +} + +Future _saveImageFromNetwork(Uri imageUrl) async { + final response = await http.get( + imageUrl, + ); + if (response.statusCode != 200) { + throw Exception('Response to $imageUrl is not successful.'); } + final imageBytes = response.bodyBytes; + await Gal.putImageBytes(imageBytes, + name: imageUrl.pathSegments.isNotEmpty + ? imageUrl.pathSegments.last + : 'image'); +} + +Future _saveLocalImage(Uri imageUrl) async { + await Gal.putImage(imageUrl.toString()); } diff --git a/flutter_quill_extensions/lib/src/editor/image/image_embed.dart b/flutter_quill_extensions/lib/src/editor/image/image_embed.dart index 5e6985541..0ede8c970 100644 --- a/flutter_quill_extensions/lib/src/editor/image/image_embed.dart +++ b/flutter_quill_extensions/lib/src/editor/image/image_embed.dart @@ -1,9 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart' hide OptionalSize; -import 'package:flutter_quill/translations.dart'; import '../../common/utils/element_utils/element_utils.dart'; -import '../../editor_toolbar_shared/shared_configurations.dart'; import 'image_menu.dart'; import 'models/image_configurations.dart'; import 'widgets/image.dart'; @@ -46,13 +44,8 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { alignment: alignment, height: height, width: width, - assetsPrefix: QuillSharedExtensionsConfigurations.get(context: context) - .assetsPrefix, ); - final imageSaverService = - QuillSharedExtensionsConfigurations.get(context: context) - .imageSaverService; return GestureDetector( onTap: () { final onImageClicked = configurations.onImageClicked; @@ -62,16 +55,13 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { } showDialog( context: context, - builder: (_) => FlutterQuillLocalizationsWidget( - child: ImageOptionsMenu( - controller: controller, - configurations: configurations, - imageSource: imageSource, - imageSize: imageSize, - isReadOnly: readOnly, - imageSaverService: imageSaverService, - imageProvider: imageWidget.image, - ), + builder: (_) => ImageOptionsMenu( + controller: controller, + configurations: configurations, + imageSource: imageSource, + imageSize: imageSize, + isReadOnly: readOnly, + imageProvider: imageWidget.image, ), ); }, diff --git a/flutter_quill_extensions/lib/src/editor/image/image_embed_types.dart b/flutter_quill_extensions/lib/src/editor/image/image_embed_types.dart index 38fef651a..8d4cb8d60 100644 --- a/flutter_quill_extensions/lib/src/editor/image/image_embed_types.dart +++ b/flutter_quill_extensions/lib/src/editor/image/image_embed_types.dart @@ -5,7 +5,6 @@ import 'package:flutter_quill/flutter_quill.dart'; import 'package:meta/meta.dart' show immutable; import '../../common/extensions/controller_ext.dart'; -import '../../editor_toolbar_shared/image_picker/s_image_picker.dart'; /// When request picking an image, for example when the image button toolbar /// clicked, it should be null in case the user didn't choose any image or @@ -16,7 +15,6 @@ import '../../editor_toolbar_shared/image_picker/s_image_picker.dart'; /// request the source for picking the image, from gallery, link or camera typedef OnRequestPickImage = Future Function( BuildContext context, - ImagePickerService imagePickerService, ); /// A callback will called when inserting a image in the editor @@ -75,7 +73,7 @@ typedef ImageEmbedBuilderOnRemovedCallback = Future Function( String imageUrl, ); -typedef ImageEmbedBuilderProviderBuilder = ImageProvider Function( +typedef ImageEmbedBuilderProviderBuilder = ImageProvider? Function( BuildContext context, String imageUrl, ); diff --git a/flutter_quill_extensions/lib/src/editor/image/image_menu.dart b/flutter_quill_extensions/lib/src/editor/image/image_menu.dart index 6f64c4e5f..61d86e31b 100644 --- a/flutter_quill_extensions/lib/src/editor/image/image_menu.dart +++ b/flutter_quill_extensions/lib/src/editor/image/image_menu.dart @@ -7,13 +7,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart' show ImageUrl, QuillController, StyleAttribute, getEmbedNode; import 'package:flutter_quill/flutter_quill_internal.dart'; -import 'package:flutter_quill/translations.dart'; import '../../common/utils/element_utils/element_utils.dart'; import '../../common/utils/string.dart'; import '../../common/utils/utils.dart'; -import '../../editor_toolbar_shared/image_saver/s_image_saver.dart'; -import '../../editor_toolbar_shared/shared_configurations.dart'; import 'models/image_configurations.dart'; import 'widgets/image.dart' show ImageTapWrapper, getImageStyleString; import 'widgets/image_resizer.dart' show ImageResizer; @@ -25,7 +22,6 @@ class ImageOptionsMenu extends StatelessWidget { required this.imageSource, required this.imageSize, required this.isReadOnly, - required this.imageSaverService, required this.imageProvider, super.key, }); @@ -35,7 +31,6 @@ class ImageOptionsMenu extends StatelessWidget { final String imageSource; final ElementSize imageSize; final bool isReadOnly; - final ImageSaverService imageSaverService; final ImageProvider imageProvider; @override @@ -56,32 +51,30 @@ class ImageOptionsMenu extends StatelessWidget { context: context, builder: (modalContext) { final screenSize = MediaQuery.sizeOf(modalContext); - return FlutterQuillLocalizationsWidget( - child: ImageResizer( - onImageResize: (width, height) { - final res = getEmbedNode( - controller, - controller.selection.start, + return ImageResizer( + onImageResize: (width, height) { + final res = getEmbedNode( + controller, + controller.selection.start, + ); + + final attr = replaceStyleStringWithSize( + getImageStyleString(controller), + width: width, + height: height, + ); + controller + ..skipRequestKeyboard = true + ..formatText( + res.offset, + 1, + StyleAttribute(attr), ); - - final attr = replaceStyleStringWithSize( - getImageStyleString(controller), - width: width, - height: height, - ); - 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, ); }, ); @@ -145,7 +138,6 @@ class ImageOptionsMenu extends StatelessWidget { final saveImageResult = await saveImage( imageUrl: imageSource, - imageSaverService: imageSaverService, ); final imageSavedSuccessfully = saveImageResult.error == null; @@ -184,9 +176,6 @@ class ImageOptionsMenu extends StatelessWidget { context, MaterialPageRoute( builder: (_) => ImageTapWrapper( - assetsPrefix: - QuillSharedExtensionsConfigurations.get(context: context) - .assetsPrefix, imageUrl: imageSource, configurations: configurations, ), diff --git a/flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart b/flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart index 8af3527f3..193732336 100644 --- a/flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart +++ b/flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart @@ -73,20 +73,20 @@ class QuillEditorImageEmbedConfigurations { /// final ImageEmbedBuilderWillRemoveCallback? shouldRemoveImageCallback; - /// [imageProviderBuilder] if you want to use custom image provider, please - /// pass a value to this property - /// By default we will use [NetworkImage] provider if the image url/path - /// is using http/https, if not then we will use [FileImage] provider - /// If you ovveride this make sure to handle the case where if the [imageUrl] - /// is in the local storage or it does exists in the system file - /// or use the same way we did it + /// Allows to override the default handling and fallback to the default if `null` was returned. /// /// Example of [imageProviderBuilder] customization: /// ```dart /// imageProviderBuilder: (imageUrl) async { - /// // Example of using cached_network_image package - /// // Don't forgot to check if that image is local or network one - /// return CachedNetworkImageProvider(imageUrl); + /// if (imageUrl.startsWith('assets/')) { + /// // Supports Image assets + /// return AssetImage(imageUrl); + /// } + /// if (imageUrl.startsWith('http')) { + /// // Use https://pub.dev/packages/cached_network_image + /// // for network images to cache them. + /// return CachedNetworkImageProvider(imageUrl); + /// } /// } /// ``` /// diff --git a/flutter_quill_extensions/lib/src/editor/image/widgets/image.dart b/flutter_quill_extensions/lib/src/editor/image/widgets/image.dart index 59e1ccc0c..147110386 100644 --- a/flutter_quill_extensions/lib/src/editor/image/widgets/image.dart +++ b/flutter_quill_extensions/lib/src/editor/image/widgets/image.dart @@ -10,16 +10,6 @@ import '../../../common/utils/utils.dart'; import '../image_embed_types.dart'; import '../models/image_configurations.dart'; -const List imageFileExtensions = [ - '.jpeg', - '.png', - '.jpg', - '.gif', - '.webp', - '.tif', - '.heic' -]; - String getImageStyleString(QuillController controller) { final String? s = controller .getAllSelectionStyles() @@ -36,11 +26,13 @@ String getImageStyleString(QuillController controller) { ImageProvider getImageProviderByImageSource( String imageSource, { required ImageEmbedBuilderProviderBuilder? imageProviderBuilder, - required String assetsPrefix, required BuildContext context, }) { if (imageProviderBuilder != null) { - return imageProviderBuilder(context, imageSource); + final imageProvider = imageProviderBuilder(context, imageSource); + if (imageProvider != null) { + return imageProvider; + } } if (isImageBase64(imageSource)) { @@ -51,10 +43,6 @@ ImageProvider getImageProviderByImageSource( return NetworkImage(imageSource); } - if (imageSource.startsWith(assetsPrefix)) { - return AssetImage(imageSource); - } - // File image if (kIsWeb) { return NetworkImage(imageSource); @@ -67,7 +55,6 @@ Image getImageWidgetByImageSource( required BuildContext context, required ImageEmbedBuilderProviderBuilder? imageProviderBuilder, required ImageErrorWidgetBuilder? imageErrorWidgetBuilder, - required String assetsPrefix, double? width, double? height, AlignmentGeometry alignment = Alignment.center, @@ -77,7 +64,6 @@ Image getImageWidgetByImageSource( context: context, imageSource, imageProviderBuilder: imageProviderBuilder, - assetsPrefix: assetsPrefix, ), width: width, height: height, @@ -93,6 +79,16 @@ String standardizeImageUrl(String url) { return url; } +const List _imageFileExtensions = [ + '.jpeg', + '.png', + '.jpg', + '.gif', + '.webp', + '.tif', + '.heic' +]; + /// This is a bug of Gallery Saver Package. /// It can not save image that's filename does not end with it's file extension /// like below. @@ -100,13 +96,13 @@ String standardizeImageUrl(String url) { /// If imageUrl does not end with it's file extension, /// file extension is added to image url for saving. String appendFileExtensionToImageUrl(String url) { - final endsWithImageFileExtension = imageFileExtensions + final endsWithImageFileExtension = _imageFileExtensions .firstWhere((s) => url.toLowerCase().endsWith(s), orElse: () => ''); if (endsWithImageFileExtension.isNotEmpty) { return url; } - final imageFileExtension = imageFileExtensions + final imageFileExtension = _imageFileExtensions .firstWhere((s) => url.toLowerCase().contains(s), orElse: () => ''); return url + imageFileExtension; @@ -116,13 +112,11 @@ class ImageTapWrapper extends StatelessWidget { const ImageTapWrapper({ required this.imageUrl, required this.configurations, - required this.assetsPrefix, super.key, }); final String imageUrl; final QuillEditorImageEmbedConfigurations configurations; - final String assetsPrefix; @override Widget build(BuildContext context) { @@ -138,7 +132,6 @@ class ImageTapWrapper extends StatelessWidget { context: context, imageUrl, imageProviderBuilder: configurations.imageProviderBuilder, - assetsPrefix: assetsPrefix, ), errorBuilder: configurations.imageErrorWidgetBuilder, loadingBuilder: (context, event) { diff --git a/flutter_quill_extensions/lib/src/editor/image/widgets/image_resizer.dart b/flutter_quill_extensions/lib/src/editor/image/widgets/image_resizer.dart index 0e7f90cf9..009e1aa9a 100644 --- a/flutter_quill_extensions/lib/src/editor/image/widgets/image_resizer.dart +++ b/flutter_quill_extensions/lib/src/editor/image/widgets/image_resizer.dart @@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart' show defaultTargetPlatform; import 'package:flutter/material.dart' show Slider, Card; import 'package:flutter/scheduler.dart' show SchedulerBinding; import 'package:flutter/widgets.dart'; -import 'package:flutter_quill/translations.dart'; +import 'package:flutter_quill/flutter_quill_internal.dart'; class ImageResizer extends StatefulWidget { const ImageResizer({ diff --git a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/image_options.dart b/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/image_options.dart deleted file mode 100644 index acecbacf1..000000000 --- a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/image_options.dart +++ /dev/null @@ -1,20 +0,0 @@ -/// Specifies the source where the picked image should come from. -enum ImageSource { - /// Opens up the device camera, letting the user to take a new picture. - camera, - - /// Opens the user's photo gallery. - gallery, -} - -enum CameraDevice { - /// Use the rear camera. - /// - /// In most of the cases, it is the default configuration. - rear, - - /// Use the front camera. - /// - /// Supported on all iPhones/iPads and some Android devices. - front, -} diff --git a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/image_picker.dart b/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/image_picker.dart deleted file mode 100644 index b79d816ab..000000000 --- a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/image_picker.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:cross_file/cross_file.dart' show XFile; - -import 'image_options.dart'; - -export 'package:cross_file/cross_file.dart' show XFile; - -export 'image_options.dart'; - -abstract class ImagePickerInterface { - const ImagePickerInterface(); - Future pickImage({ - required ImageSource source, - double? maxWidth, - double? maxHeight, - int? imageQuality, - CameraDevice preferredCameraDevice = CameraDevice.rear, - bool requestFullMetadata = true, - }); - Future pickMedia({ - double? maxWidth, - double? maxHeight, - int? imageQuality, - bool requestFullMetadata = true, - }); - Future pickVideo({ - required ImageSource source, - CameraDevice preferredCameraDevice = CameraDevice.rear, - Duration? maxDuration, - }); -} diff --git a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/packages/image_picker.dart b/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/packages/image_picker.dart deleted file mode 100644 index e009648da..000000000 --- a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/packages/image_picker.dart +++ /dev/null @@ -1,80 +0,0 @@ -import 'package:image_picker/image_picker.dart' as package - show ImagePicker, ImageSource, CameraDevice; - -import '../image_picker.dart'; - -class ImagePickerPackageImpl extends ImagePickerInterface { - const ImagePickerPackageImpl(); - package.ImagePicker get _picker { - return package.ImagePicker(); - } - - @override - Future pickImage({ - required ImageSource source, - double? maxWidth, - double? maxHeight, - int? imageQuality, - CameraDevice preferredCameraDevice = CameraDevice.rear, - bool requestFullMetadata = true, - }) { - return _picker.pickImage( - source: source.toImagePickerPackage(), - maxWidth: maxWidth, - maxHeight: maxHeight, - imageQuality: imageQuality, - preferredCameraDevice: preferredCameraDevice.toImagePickerPackage(), - requestFullMetadata: requestFullMetadata, - ); - } - - @override - Future pickMedia({ - double? maxWidth, - double? maxHeight, - int? imageQuality, - bool requestFullMetadata = true, - }) { - return _picker.pickMedia( - maxWidth: maxWidth, - maxHeight: maxHeight, - imageQuality: imageQuality, - requestFullMetadata: requestFullMetadata, - ); - } - - @override - Future pickVideo({ - required ImageSource source, - CameraDevice preferredCameraDevice = CameraDevice.rear, - Duration? maxDuration, - }) { - return _picker.pickVideo( - source: source.toImagePickerPackage(), - preferredCameraDevice: preferredCameraDevice.toImagePickerPackage(), - maxDuration: maxDuration, - ); - } -} - -extension ImageSoureceExt on ImageSource { - package.ImageSource toImagePickerPackage() { - switch (this) { - case ImageSource.camera: - return package.ImageSource.camera; - case ImageSource.gallery: - return package.ImageSource.gallery; - } - } -} - -extension CameraDeviceExt on CameraDevice { - package.CameraDevice toImagePickerPackage() { - switch (this) { - case CameraDevice.rear: - return package.CameraDevice.rear; - case CameraDevice.front: - return package.CameraDevice.front; - } - } -} diff --git a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/s_image_picker.dart b/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/s_image_picker.dart deleted file mode 100644 index 23d19e2e3..000000000 --- a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_picker/s_image_picker.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'image_picker.dart'; -import 'packages/image_picker.dart'; - -/// A service used for packing images in the extensions package -class ImagePickerService extends ImagePickerInterface { - const ImagePickerService( - this._impl, - ); - - factory ImagePickerService.imagePickerPackage() => const ImagePickerService( - ImagePickerPackageImpl(), - ); - - factory ImagePickerService.defaultImpl() => - ImagePickerService.imagePickerPackage(); - - final ImagePickerInterface _impl; - @override - Future pickImage({ - required ImageSource source, - double? maxWidth, - double? maxHeight, - int? imageQuality, - CameraDevice preferredCameraDevice = CameraDevice.rear, - bool requestFullMetadata = true, - }) => - _impl.pickImage( - source: source, - maxWidth: maxWidth, - maxHeight: maxHeight, - imageQuality: imageQuality, - preferredCameraDevice: preferredCameraDevice, - requestFullMetadata: requestFullMetadata, - ); - - @override - Future pickMedia({ - double? maxWidth, - double? maxHeight, - int? imageQuality, - bool requestFullMetadata = true, - }) => - _impl.pickMedia( - maxWidth: maxWidth, - maxHeight: maxHeight, - imageQuality: imageQuality, - requestFullMetadata: requestFullMetadata, - ); - - @override - Future pickVideo({ - required ImageSource source, - CameraDevice preferredCameraDevice = CameraDevice.rear, - Duration? maxDuration, - }) => - _impl.pickVideo( - source: source, - preferredCameraDevice: preferredCameraDevice, - maxDuration: maxDuration, - ); -} diff --git a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/exceptions.dart b/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/exceptions.dart deleted file mode 100644 index 70933e10c..000000000 --- a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/exceptions.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:meta/meta.dart' show immutable; - -enum ImageSaverExceptionType { - accessDenied, - notEnoughSpace, - notSupportedFormat, - unexpected, - unknown; -} - -@immutable -class ImageSaverException implements Exception { - const ImageSaverException({ - required this.message, - required this.type, - }); - - final String message; - final ImageSaverExceptionType type; - - @override - String toString() => 'Error while saving image, error type: ${type.name}'; -} diff --git a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/image_saver.dart b/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/image_saver.dart deleted file mode 100644 index 2417ae8c6..000000000 --- a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/image_saver.dart +++ /dev/null @@ -1,7 +0,0 @@ -abstract class ImageSaverInterface { - const ImageSaverInterface(); - Future saveLocalImage(String imageUrl); - Future saveImageFromNetwork(Uri imageUrl); - Future hasAccess({required bool toAlbum}); - Future requestAccess({required bool toAlbum}); -} diff --git a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/packages/gal.dart b/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/packages/gal.dart deleted file mode 100644 index aec93ff44..000000000 --- a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/packages/gal.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:flutter/widgets.dart' show NetworkImageLoadException; -import 'package:gal/gal.dart' show Gal, GalException, GalExceptionType; -import 'package:http/http.dart' as http; - -import '../exceptions.dart'; -import '../image_saver.dart'; - -class ImageSaverGalImpl extends ImageSaverInterface { - @override - Future saveImageFromNetwork(Uri imageUrl) async { - try { - final response = await http.get( - imageUrl, - ); - if (response.statusCode != 200) { - throw NetworkImageLoadException( - statusCode: response.statusCode, - uri: imageUrl, - ); - } - final imageBytes = response.bodyBytes; - await Gal.putImageBytes(imageBytes); - } on GalException catch (e) { - throw ImageSaverException( - message: e.toString(), - type: e.type.toImageSaverExceptionType(), - ); - } catch (e) { - throw ImageSaverException( - message: e.toString(), - type: ImageSaverExceptionType.unknown, - ); - } - } - - @override - Future saveLocalImage(String imageUrl) async { - try { - await Gal.putImage(imageUrl); - } on GalException catch (e) { - throw ImageSaverException( - message: e.toString(), - type: e.type.toImageSaverExceptionType(), - ); - } catch (e) { - throw ImageSaverException( - message: e.toString(), - type: ImageSaverExceptionType.unknown, - ); - } - } - - @override - Future hasAccess({required bool toAlbum}) { - return Gal.hasAccess(toAlbum: toAlbum); - } - - @override - Future requestAccess({required bool toAlbum}) { - return Gal.requestAccess(toAlbum: toAlbum); - } -} - -extension GalExceptionTypeExt on GalExceptionType { - ImageSaverExceptionType toImageSaverExceptionType() { - switch (this) { - case GalExceptionType.accessDenied: - return ImageSaverExceptionType.accessDenied; - case GalExceptionType.notEnoughSpace: - return ImageSaverExceptionType.notEnoughSpace; - case GalExceptionType.notSupportedFormat: - return ImageSaverExceptionType.notSupportedFormat; - case GalExceptionType.unexpected: - return ImageSaverExceptionType.unexpected; - } - } -} diff --git a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/s_image_saver.dart b/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/s_image_saver.dart deleted file mode 100644 index 35b9ee34e..000000000 --- a/flutter_quill_extensions/lib/src/editor_toolbar_shared/image_saver/s_image_saver.dart +++ /dev/null @@ -1,31 +0,0 @@ -// ignore_for_file: public_member_api_docs, sort_constructors_first -import 'image_saver.dart'; -import 'packages/gal.dart' show ImageSaverGalImpl; - -/// A service used for saving images in the extensions package -class ImageSaverService extends ImageSaverInterface { - final ImageSaverInterface _impl; - const ImageSaverService(this._impl); - - factory ImageSaverService.galPackage() => ImageSaverService( - ImageSaverGalImpl(), - ); - - factory ImageSaverService.defaultImpl() => ImageSaverService.galPackage(); - - @override - Future hasAccess({bool toAlbum = false}) => - _impl.hasAccess(toAlbum: toAlbum); - - @override - Future requestAccess({bool toAlbum = false}) => - _impl.requestAccess(toAlbum: toAlbum); - - @override - Future saveImageFromNetwork(Uri imageUrl) => - _impl.saveImageFromNetwork(imageUrl); - - @override - Future saveLocalImage(String imageUrl) => - _impl.saveLocalImage(imageUrl); -} diff --git a/flutter_quill_extensions/lib/src/editor_toolbar_shared/shared_configurations.dart b/flutter_quill_extensions/lib/src/editor_toolbar_shared/shared_configurations.dart deleted file mode 100644 index 4c8fbe49f..000000000 --- a/flutter_quill_extensions/lib/src/editor_toolbar_shared/shared_configurations.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'package:flutter/widgets.dart' show BuildContext; -import 'package:flutter_quill/flutter_quill.dart'; -import 'package:meta/meta.dart' show immutable; - -import 'image_picker/s_image_picker.dart'; -import 'image_saver/s_image_saver.dart'; - -/// Configurations for Flutter Editor Extensions -/// shared between toolbar and editor -@immutable -class QuillSharedExtensionsConfigurations { - const QuillSharedExtensionsConfigurations({ - ImagePickerService? imagePickerService, - ImageSaverService? imageSaverService, - this.assetsPrefix = 'assets', - }) : _imagePickerService = imagePickerService, - _imageSaverService = imageSaverService; - - /// Get the instance from the widget tree in [QuillSharedConfigurations] - /// if it doesn't exists, we will create new one with default options - factory QuillSharedExtensionsConfigurations.get({ - required BuildContext context, - }) { - final value = context.quillSharedConfigurations?.extraConfigurations[key]; - if (value != null) { - if (value is! QuillSharedExtensionsConfigurations) { - throw ArgumentError( - 'The value of key `$key` should be of type ' - '$key', - ); - } - return value; - } - return const QuillSharedExtensionsConfigurations(); - } - - /// The key to be used in the `extraConfigurations` property - /// which can be found in the [QuillSharedConfigurations] - /// - /// which exists in the [QuillEditorConfigurations] - static const String key = 'QuillSharedExtensionsConfigurations'; - - /// Defaults to [ImagePickerService.defaultImpl] - final ImagePickerService? _imagePickerService; - - /// A getter method which returns the [ImagePickerService] that is provided - /// by the developer, if it can't be found then we will use default impl - ImagePickerService get imagePickerService { - return _imagePickerService ?? ImagePickerService.defaultImpl(); - } - - /// Default to [ImageSaverService.defaultImpl] - final ImageSaverService? _imageSaverService; - - /// A getter method which returns the [ImageSaverService] that is provided - /// by the developer, if it can't be found then we will use default impl - ImageSaverService get imageSaverService { - return _imageSaverService ?? ImageSaverService.defaultImpl(); - } - - /// The property [assetsPrefix] should be the start of your assets folder - /// by default it to `assets` and the reason why we need to know it - /// - /// Because in case when you don't define a value for [ImageProviderBuilder] - /// in the [QuillEditorImageEmbedConfigurations] which exists in - /// [FlutterQuillEmbeds.editorBuilders] - /// - /// then the only way of how to know if this is asset image that you added - /// in the `pubspec.yaml` is by asking you the assetsPrefix, how should the - /// start of your asset images usualy looks like?? in most projects it's - /// assets so we will go with that as a default - /// - /// but if you are using different name and you want to use assets images - /// in the [QuillEditor] then it's important to override this - /// - /// if you want a custom solution then please use [imageProviderBuilder] - final String assetsPrefix; -} diff --git a/flutter_quill_extensions/lib/src/toolbar/camera/camera_button.dart b/flutter_quill_extensions/lib/src/toolbar/camera/camera_button.dart index 204e911ee..eafa3e0b2 100644 --- a/flutter_quill_extensions/lib/src/toolbar/camera/camera_button.dart +++ b/flutter_quill_extensions/lib/src/toolbar/camera/camera_button.dart @@ -1,17 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill.dart' - show - QuillController, - QuillIconTheme, - QuillSimpleToolbarExt, - QuillToolbarBaseButtonOptions, - QuillToolbarIconButton, - kDefaultIconSize, - kDefaultIconButtonFactor; -import 'package:flutter_quill/translations.dart'; - -import '../../editor_toolbar_shared/image_picker/image_options.dart'; -import '../../editor_toolbar_shared/shared_configurations.dart'; +import 'package:flutter_quill/flutter_quill.dart'; +import 'package:flutter_quill/flutter_quill_internal.dart'; + +import 'package:image_picker/image_picker.dart'; import 'camera_types.dart'; import 'models/camera_configurations.dart'; import 'select_camera_action.dart'; @@ -27,40 +18,29 @@ class QuillToolbarCameraButton extends StatelessWidget { final QuillToolbarCameraButtonOptions options; double _iconSize(BuildContext context) { - final baseFontSize = baseButtonExtraOptions(context)?.iconSize; final iconSize = options.iconSize; - return iconSize ?? baseFontSize ?? kDefaultIconSize; + return iconSize ?? kDefaultIconSize; } double _iconButtonFactor(BuildContext context) { - final baseIconFactor = baseButtonExtraOptions(context)?.iconButtonFactor; final iconButtonFactor = options.iconButtonFactor; - return iconButtonFactor ?? baseIconFactor ?? kDefaultIconButtonFactor; + return iconButtonFactor ?? kDefaultIconButtonFactor; } VoidCallback? _afterButtonPressed(BuildContext context) { - return options.afterButtonPressed ?? - baseButtonExtraOptions(context)?.afterButtonPressed; + return options.afterButtonPressed; } QuillIconTheme? _iconTheme(BuildContext context) { - return options.iconTheme ?? baseButtonExtraOptions(context)?.iconTheme; - } - - QuillToolbarBaseButtonOptions? baseButtonExtraOptions(BuildContext context) { - return context.quillToolbarBaseButtonOptions; + return options.iconTheme; } IconData _iconData(BuildContext context) { - return options.iconData ?? - baseButtonExtraOptions(context)?.iconData ?? - Icons.photo_camera; + return options.iconData ?? Icons.photo_camera; } String _tooltip(BuildContext context) { - return options.tooltip ?? - baseButtonExtraOptions(context)?.tooltip ?? - context.loc.camera; + return options.tooltip ?? context.loc.camera; } void _sharedOnPressed(BuildContext context) { @@ -79,8 +59,7 @@ class QuillToolbarCameraButton extends StatelessWidget { final iconData = _iconData(context); final iconButtonFactor = _iconButtonFactor(context); - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions(context)?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { childBuilder( @@ -131,10 +110,6 @@ class QuillToolbarCameraButton extends StatelessWidget { BuildContext context, QuillController controller, ) async { - final imagePickerService = - QuillSharedExtensionsConfigurations.get(context: context) - .imagePickerService; - final cameraAction = await _getCameraAction(context); if (cameraAction == null) { @@ -143,9 +118,8 @@ class QuillToolbarCameraButton extends StatelessWidget { switch (cameraAction) { case CameraAction.video: - final videoFile = await imagePickerService.pickVideo( - source: ImageSource.camera, - ); + final videoFile = + await ImagePicker().pickVideo(source: ImageSource.camera); if (videoFile == null) { return; } @@ -156,9 +130,8 @@ class QuillToolbarCameraButton extends StatelessWidget { await options.cameraConfigurations.onVideoInsertedCallback ?.call(videoFile.path); case CameraAction.image: - final imageFile = await imagePickerService.pickImage( - source: ImageSource.camera, - ); + final imageFile = + await ImagePicker().pickImage(source: ImageSource.camera); if (imageFile == null) { return; } diff --git a/flutter_quill_extensions/lib/src/toolbar/camera/select_camera_action.dart b/flutter_quill_extensions/lib/src/toolbar/camera/select_camera_action.dart index 5d10de8b2..b18e11695 100644 --- a/flutter_quill_extensions/lib/src/toolbar/camera/select_camera_action.dart +++ b/flutter_quill_extensions/lib/src/toolbar/camera/select_camera_action.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill_internal.dart'; -import 'package:flutter_quill/translations.dart'; import 'camera_types.dart'; @@ -47,8 +46,7 @@ Future showSelectCameraActionDialog({ showDragHandle: true, context: context, constraints: const BoxConstraints(maxWidth: 640), - builder: (context) => const FlutterQuillLocalizationsWidget( - child: SelectCameraActionDialog()), + builder: (context) => const SelectCameraActionDialog(), ); return imageSource; } diff --git a/flutter_quill_extensions/lib/src/toolbar/formula/formula_button.dart b/flutter_quill_extensions/lib/src/toolbar/formula/formula_button.dart index 9e4847e3a..60d7850e3 100644 --- a/flutter_quill_extensions/lib/src/toolbar/formula/formula_button.dart +++ b/flutter_quill_extensions/lib/src/toolbar/formula/formula_button.dart @@ -14,41 +14,30 @@ class QuillToolbarFormulaButton extends StatelessWidget { final QuillToolbarFormulaButtonOptions options; double _iconSize(BuildContext context) { - final baseFontSize = baseButtonExtraOptions(context)?.iconSize; final iconSize = options.iconSize; - return iconSize ?? baseFontSize ?? kDefaultIconSize; + return iconSize ?? kDefaultIconSize; } double _iconButtonFactor(BuildContext context) { - final baseIconFactor = baseButtonExtraOptions(context)?.iconButtonFactor; final iconButtonFactor = options.iconButtonFactor; - return iconButtonFactor ?? baseIconFactor ?? kDefaultIconButtonFactor; + return iconButtonFactor ?? kDefaultIconButtonFactor; } VoidCallback? _afterButtonPressed(BuildContext context) { - return options.afterButtonPressed ?? - baseButtonExtraOptions(context)?.afterButtonPressed; + return options.afterButtonPressed; } QuillIconTheme? _iconTheme(BuildContext context) { - return options.iconTheme ?? baseButtonExtraOptions(context)?.iconTheme; - } - - QuillToolbarBaseButtonOptions? baseButtonExtraOptions(BuildContext context) { - return context.quillToolbarBaseButtonOptions; + return options.iconTheme; } IconData _iconData(BuildContext context) { - return options.iconData ?? - baseButtonExtraOptions(context)?.iconData ?? - Icons.functions; + return options.iconData ?? Icons.functions; } String _tooltip(BuildContext context) { - return options.tooltip ?? - baseButtonExtraOptions(context)?.tooltip ?? - 'Insert formula'; - // ('Insert formula'.i18n); + // TODO: Add insert formula translation + return options.tooltip ?? 'Insert formula'; } void _sharedOnPressed(BuildContext context) { @@ -64,8 +53,7 @@ class QuillToolbarFormulaButton extends StatelessWidget { final iconSize = _iconSize(context); final iconButtonFactor = _iconButtonFactor(context); final iconData = _iconData(context); - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions(context)?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( diff --git a/flutter_quill_extensions/lib/src/toolbar/image/image_button.dart b/flutter_quill_extensions/lib/src/toolbar/image/image_button.dart index 03dc707b6..fba7c28a5 100644 --- a/flutter_quill_extensions/lib/src/toolbar/image/image_button.dart +++ b/flutter_quill_extensions/lib/src/toolbar/image/image_button.dart @@ -1,13 +1,10 @@ -// ignore_for_file: use_build_context_synchronously - import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/translations.dart'; +import 'package:flutter_quill/flutter_quill_internal.dart'; +import 'package:image_picker/image_picker.dart'; import '../../common/image_video_utils.dart'; import '../../editor/image/image_embed_types.dart'; -import '../../editor_toolbar_shared/image_picker/image_picker.dart'; -import '../../editor_toolbar_shared/shared_configurations.dart'; import 'models/image_configurations.dart'; import 'select_image_source.dart'; @@ -23,40 +20,29 @@ class QuillToolbarImageButton extends StatelessWidget { final QuillToolbarImageButtonOptions options; double _iconSize(BuildContext context) { - final baseFontSize = baseButtonExtraOptions(context)?.iconSize; final iconSize = options.iconSize; - return iconSize ?? baseFontSize ?? kDefaultIconSize; + return iconSize ?? kDefaultIconSize; } double _iconButtonFactor(BuildContext context) { - final baseIconFactor = baseButtonExtraOptions(context)?.iconButtonFactor; final iconButtonFactor = options.iconButtonFactor; - return iconButtonFactor ?? baseIconFactor ?? kDefaultIconButtonFactor; + return iconButtonFactor ?? kDefaultIconButtonFactor; } VoidCallback? _afterButtonPressed(BuildContext context) { - return options.afterButtonPressed ?? - baseButtonExtraOptions(context)?.afterButtonPressed; + return options.afterButtonPressed; } QuillIconTheme? _iconTheme(BuildContext context) { - return options.iconTheme ?? baseButtonExtraOptions(context)?.iconTheme; - } - - QuillToolbarBaseButtonOptions? baseButtonExtraOptions(BuildContext context) { - return context.quillToolbarBaseButtonOptions; + return options.iconTheme; } IconData _iconData(BuildContext context) { - return options.iconData ?? - baseButtonExtraOptions(context)?.iconData ?? - Icons.image; + return options.iconData ?? Icons.image; } String _tooltip(BuildContext context) { - return options.tooltip ?? - baseButtonExtraOptions(context)?.tooltip ?? - context.loc.insertImage; + return options.tooltip ?? context.loc.insertImage; } void _sharedOnPressed(BuildContext context) { @@ -70,8 +56,7 @@ class QuillToolbarImageButton extends StatelessWidget { final iconSize = _iconSize(context); final iconButtonFactor = _iconButtonFactor(context); final iconData = _iconData(context); - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions(context)?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( @@ -107,16 +92,11 @@ class QuillToolbarImageButton extends StatelessWidget { } Future _onPressedHandler(BuildContext context) async { - final imagePickerService = - QuillSharedExtensionsConfigurations.get(context: context) - .imagePickerService; - final onRequestPickImage = options.imageButtonConfigurations.onRequestPickImage; if (onRequestPickImage != null) { final imageUrl = await onRequestPickImage( context, - imagePickerService, ); if (imageUrl != null) { await options.imageButtonConfigurations @@ -134,15 +114,12 @@ class QuillToolbarImageButton extends StatelessWidget { } final imageUrl = switch (source) { - InsertImageSource.gallery => (await imagePickerService.pickImage( - source: ImageSource.gallery, - )) - ?.path, - InsertImageSource.link => await _typeLink(context), - InsertImageSource.camera => (await imagePickerService.pickImage( - source: ImageSource.camera, - )) - ?.path, + InsertImageSource.gallery => + (await ImagePicker().pickImage(source: ImageSource.gallery))?.path, + InsertImageSource.link => + context.mounted ? await _typeLink(context) : null, + InsertImageSource.camera => + (await ImagePicker().pickImage(source: ImageSource.camera))?.path, }; if (imageUrl == null) { return; @@ -158,12 +135,10 @@ class QuillToolbarImageButton extends StatelessWidget { Future _typeLink(BuildContext context) async { final value = await showDialog( context: context, - builder: (_) => FlutterQuillLocalizationsWidget( - child: TypeLinkDialog( - dialogTheme: options.dialogTheme, - linkRegExp: options.linkRegExp, - linkType: LinkType.image, - ), + builder: (_) => TypeLinkDialog( + dialogTheme: options.dialogTheme, + linkRegExp: options.linkRegExp, + linkType: LinkType.image, ), ); return value; diff --git a/flutter_quill_extensions/lib/src/toolbar/image/select_image_source.dart b/flutter_quill_extensions/lib/src/toolbar/image/select_image_source.dart index 2a7241a25..8a389edb7 100644 --- a/flutter_quill_extensions/lib/src/toolbar/image/select_image_source.dart +++ b/flutter_quill_extensions/lib/src/toolbar/image/select_image_source.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill_internal.dart' show isDesktopApp; -import 'package:flutter_quill/translations.dart'; +import 'package:flutter_quill/flutter_quill_internal.dart' + show LocalizationsExt, isDesktopApp; import '../../editor/image/image_embed_types.dart'; @@ -54,9 +54,7 @@ Future showSelectImageSourceDialog({ showDragHandle: true, context: context, constraints: const BoxConstraints(maxWidth: 640), - builder: (_) => const FlutterQuillLocalizationsWidget( - child: SelectImageSourceDialog(), - ), + builder: (_) => const SelectImageSourceDialog(), ); return imageSource; } diff --git a/flutter_quill_extensions/lib/src/toolbar/table/table_button.dart b/flutter_quill_extensions/lib/src/toolbar/table/table_button.dart index dd0fabf30..5a1dc33e1 100644 --- a/flutter_quill_extensions/lib/src/toolbar/table/table_button.dart +++ b/flutter_quill_extensions/lib/src/toolbar/table/table_button.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/translations.dart'; +import 'package:flutter_quill/flutter_quill_internal.dart'; import 'package:meta/meta.dart'; import '../../common/utils/quill_table_utils.dart'; @@ -21,40 +21,29 @@ class QuillToolbarTableButton extends StatelessWidget { final QuillToolbarTableButtonOptions options; double _iconSize(BuildContext context) { - final baseFontSize = baseButtonExtraOptions(context)?.iconSize; final iconSize = options.iconSize; - return iconSize ?? baseFontSize ?? kDefaultIconSize; + return iconSize ?? kDefaultIconSize; } double _iconButtonFactor(BuildContext context) { - final baseIconFactor = baseButtonExtraOptions(context)?.iconButtonFactor; final iconButtonFactor = options.iconButtonFactor; - return iconButtonFactor ?? baseIconFactor ?? kDefaultIconButtonFactor; + return iconButtonFactor ?? kDefaultIconButtonFactor; } VoidCallback? _afterButtonPressed(BuildContext context) { - return options.afterButtonPressed ?? - baseButtonExtraOptions(context)?.afterButtonPressed; + return options.afterButtonPressed; } QuillIconTheme? _iconTheme(BuildContext context) { - return options.iconTheme ?? baseButtonExtraOptions(context)?.iconTheme; - } - - QuillToolbarBaseButtonOptions? baseButtonExtraOptions(BuildContext context) { - return context.quillToolbarBaseButtonOptions; + return options.iconTheme; } IconData _iconData(BuildContext context) { - return options.iconData ?? - baseButtonExtraOptions(context)?.iconData ?? - Icons.table_chart; + return options.iconData ?? Icons.table_chart; } String _tooltip(BuildContext context) { - return options.tooltip ?? - baseButtonExtraOptions(context)?.tooltip ?? - context.loc.insertTable; + return options.tooltip ?? context.loc.insertTable; } void _sharedOnPressed(BuildContext context) { @@ -68,8 +57,7 @@ class QuillToolbarTableButton extends StatelessWidget { final iconSize = _iconSize(context); final iconButtonFactor = _iconButtonFactor(context); final iconData = _iconData(context); - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions(context)?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( diff --git a/flutter_quill_extensions/lib/src/toolbar/video/models/video.dart b/flutter_quill_extensions/lib/src/toolbar/video/models/video.dart index 151f442c9..9cfede528 100644 --- a/flutter_quill_extensions/lib/src/toolbar/video/models/video.dart +++ b/flutter_quill_extensions/lib/src/toolbar/video/models/video.dart @@ -3,7 +3,6 @@ import 'package:flutter_quill/flutter_quill.dart'; import 'package:meta/meta.dart' show immutable; import '../../../common/extensions/controller_ext.dart'; -import '../../../editor_toolbar_shared/image_picker/s_image_picker.dart'; /// When request picking an video, for example when the video button toolbar /// clicked, it should be null in case the user didn't choose any video or @@ -14,7 +13,6 @@ import '../../../editor_toolbar_shared/image_picker/s_image_picker.dart'; /// request the source for picking the video, from gallery, link or camera typedef OnRequestPickVideo = Future Function( BuildContext context, - ImagePickerService imagePickerService, ); /// A callback will called when inserting a video in the editor diff --git a/flutter_quill_extensions/lib/src/toolbar/video/select_video_source.dart b/flutter_quill_extensions/lib/src/toolbar/video/select_video_source.dart index c19080f1a..e14475c63 100644 --- a/flutter_quill_extensions/lib/src/toolbar/video/select_video_source.dart +++ b/flutter_quill_extensions/lib/src/toolbar/video/select_video_source.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill_internal.dart' show isDesktopApp; -import 'package:flutter_quill/translations.dart'; +import 'package:flutter_quill/flutter_quill_internal.dart' + show LocalizationsExt, isDesktopApp; import 'models/video.dart'; @@ -52,8 +52,7 @@ Future showSelectVideoSourceDialog({ showDragHandle: true, context: context, constraints: const BoxConstraints(maxWidth: 640), - builder: (context) => - const FlutterQuillLocalizationsWidget(child: SelectVideoSourceDialog()), + builder: (context) => const SelectVideoSourceDialog(), ); return imageSource; } diff --git a/flutter_quill_extensions/lib/src/toolbar/video/video_button.dart b/flutter_quill_extensions/lib/src/toolbar/video/video_button.dart index e8effbfda..da953915f 100644 --- a/flutter_quill_extensions/lib/src/toolbar/video/video_button.dart +++ b/flutter_quill_extensions/lib/src/toolbar/video/video_button.dart @@ -1,16 +1,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/translations.dart'; + +import 'package:image_picker/image_picker.dart'; import '../../common/image_video_utils.dart'; -import '../../editor_toolbar_shared/image_picker/image_options.dart'; -import '../../editor_toolbar_shared/shared_configurations.dart'; + import 'models/video.dart'; import 'models/video_configurations.dart'; import 'select_video_source.dart'; -// TODO: Add custom callback to validate the video link input - class QuillToolbarVideoButton extends StatelessWidget { const QuillToolbarVideoButton({ required this.controller, @@ -23,41 +21,30 @@ class QuillToolbarVideoButton extends StatelessWidget { final QuillToolbarVideoButtonOptions options; double _iconSize(BuildContext context) { - final baseFontSize = baseButtonExtraOptions(context)?.iconSize; final iconSize = options.iconSize; - return iconSize ?? baseFontSize ?? kDefaultIconSize; + return iconSize ?? kDefaultIconSize; } double _iconButtonFactor(BuildContext context) { - final baseIconFactor = baseButtonExtraOptions(context)?.iconButtonFactor; final iconButtonFactor = options.iconButtonFactor; - return iconButtonFactor ?? baseIconFactor ?? kDefaultIconButtonFactor; + return iconButtonFactor ?? kDefaultIconButtonFactor; } VoidCallback? _afterButtonPressed(BuildContext context) { - return options.afterButtonPressed ?? - baseButtonExtraOptions(context)?.afterButtonPressed; + return options.afterButtonPressed; } QuillIconTheme? _iconTheme(BuildContext context) { - return options.iconTheme ?? baseButtonExtraOptions(context)?.iconTheme; - } - - QuillToolbarBaseButtonOptions? baseButtonExtraOptions(BuildContext context) { - return context.quillToolbarBaseButtonOptions; + return options.iconTheme; } IconData _iconData(BuildContext context) { - return options.iconData ?? - baseButtonExtraOptions(context)?.iconData ?? - Icons.movie_creation; + return options.iconData ?? Icons.movie_creation; } String _tooltip(BuildContext context) { - return options.tooltip ?? - baseButtonExtraOptions(context)?.tooltip ?? - 'Insert video'; - // ('Insert video'.i18n); + // TODO: Add insert video translation + return options.tooltip ?? 'Insert video'; } void _sharedOnPressed(BuildContext context) { @@ -71,8 +58,7 @@ class QuillToolbarVideoButton extends StatelessWidget { final iconSize = _iconSize(context); final iconButtonFactor = _iconButtonFactor(context); final iconData = _iconData(context); - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions(context)?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( @@ -108,13 +94,9 @@ class QuillToolbarVideoButton extends StatelessWidget { } Future _onPressedHandler(BuildContext context) async { - final imagePickerService = - QuillSharedExtensionsConfigurations.get(context: context) - .imagePickerService; - final onRequestPickVideo = options.videoConfigurations.onRequestPickVideo; if (onRequestPickVideo != null) { - final videoUrl = await onRequestPickVideo(context, imagePickerService); + final videoUrl = await onRequestPickVideo(context); if (videoUrl != null) { await options.videoConfigurations .onVideoInsertCallback(videoUrl, controller); @@ -132,9 +114,9 @@ class QuillToolbarVideoButton extends StatelessWidget { final videoUrl = switch (imageSource) { InsertVideoSource.gallery => - (await imagePickerService.pickVideo(source: ImageSource.gallery))?.path, + (await ImagePicker().pickVideo(source: ImageSource.gallery))?.path, InsertVideoSource.camera => - (await imagePickerService.pickVideo(source: ImageSource.camera))?.path, + (await ImagePicker().pickVideo(source: ImageSource.camera))?.path, InsertVideoSource.link => context.mounted ? await _typeLink(context) : null, }; @@ -152,11 +134,9 @@ class QuillToolbarVideoButton extends StatelessWidget { Future _typeLink(BuildContext context) async { final value = await showDialog( context: context, - builder: (_) => FlutterQuillLocalizationsWidget( - child: TypeLinkDialog( - dialogTheme: options.dialogTheme, - linkType: LinkType.video, - ), + builder: (_) => TypeLinkDialog( + dialogTheme: options.dialogTheme, + linkType: LinkType.video, ), ); return value; diff --git a/flutter_quill_extensions/pubspec_overrides.yaml b/flutter_quill_extensions/pubspec_overrides.yaml new file mode 100644 index 000000000..4d3d8342e --- /dev/null +++ b/flutter_quill_extensions/pubspec_overrides.yaml @@ -0,0 +1,4 @@ +# TODO: (11.0.0) Remove this file on publish +dependency_overrides: + flutter_quill: + path: ../ \ No newline at end of file diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index 2c51d6ebd..48b95434c 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -6,7 +6,6 @@ export 'src/common/structs/offset_value.dart'; export 'src/common/structs/optional_size.dart'; export 'src/common/structs/vertical_spacing.dart'; export 'src/common/utils/embeds.dart'; -export 'src/controller/provider.dart'; export 'src/controller/quill_controller.dart'; export 'src/document/attribute.dart'; export 'src/document/document.dart'; @@ -19,7 +18,6 @@ export 'src/document/structs/doc_change.dart'; export 'src/document/style.dart'; export 'src/editor/editor.dart'; export 'src/editor/embed/embed_editor_builder.dart'; -export 'src/editor/provider.dart'; export 'src/editor/raw_editor/builders/leading_block_builder.dart'; export 'src/editor/raw_editor/config/events/events.dart'; export 'src/editor/raw_editor/config/raw_editor_configurations.dart'; @@ -37,15 +35,9 @@ export 'src/editor_toolbar_controller_shared/copy_cut_service/copy_cut_service.d export 'src/editor_toolbar_controller_shared/copy_cut_service/copy_cut_service_provider.dart'; export 'src/editor_toolbar_controller_shared/copy_cut_service/default_copy_cut_service.dart'; export 'src/editor_toolbar_controller_shared/quill_configurations.dart'; -export 'src/editor_toolbar_shared/quill_configurations_ext.dart'; -export 'src/toolbar/base_toolbar.dart'; -export 'src/toolbar/buttons/alignment/select_alignment_button.dart'; -export 'src/toolbar/buttons/hearder_style/select_header_style_dropdown_button.dart'; -export 'src/toolbar/config/toolbar_configurations.dart'; +export 'src/l10n/generated/quill_localizations.dart'; export 'src/toolbar/embed/embed_button_builder.dart'; -export 'src/toolbar/provider.dart'; export 'src/toolbar/simple_toolbar.dart'; -export 'src/toolbar/simple_toolbar_provider.dart'; export 'src/toolbar/structs/link_dialog_action.dart'; export 'src/toolbar/theme/quill_dialog_theme.dart'; export 'src/toolbar/theme/quill_icon_theme.dart'; diff --git a/lib/flutter_quill_internal.dart b/lib/flutter_quill_internal.dart index 50d2fde78..61ab7dc2f 100644 --- a/lib/flutter_quill_internal.dart +++ b/lib/flutter_quill_internal.dart @@ -17,6 +17,7 @@ export 'src/common/utils/widgets.dart'; export 'src/document/nodes/leaf.dart'; export 'src/editor_toolbar_controller_shared/clipboard/clipboard_service.dart'; export 'src/editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; +export 'src/l10n/extensions/localizations_ext.dart'; export 'src/rules/delete.dart'; export 'src/rules/format.dart'; export 'src/rules/insert.dart'; diff --git a/lib/src/controller/provider.dart b/lib/src/controller/provider.dart deleted file mode 100644 index add8ad10c..000000000 --- a/lib/src/controller/provider.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/widgets.dart' show BuildContext; - -import '../editor/provider.dart'; -import '../toolbar/simple_toolbar_provider.dart'; -import 'quill_controller.dart'; - -extension QuillControllerExt on BuildContext { - QuillController? get quilController { - // ignore: deprecated_member_use_from_same_package - return quillSimpleToolbarConfigurations?.controller ?? - // ignore: deprecated_member_use_from_same_package - quillEditorConfigurations?.controller; - } - - QuillController get requireQuillController { - // ignore: deprecated_member_use_from_same_package - return quillSimpleToolbarConfigurations?.controller ?? - // ignore: deprecated_member_use_from_same_package - quillEditorConfigurations?.controller ?? - (throw ArgumentError( - 'The quill provider is required, you must only call requireQuillController inside the QuillToolbar and QuillEditor')); - } -} diff --git a/lib/src/controller/quill_controller.dart b/lib/src/controller/quill_controller.dart index 2ffdcb049..6618f8077 100644 --- a/lib/src/controller/quill_controller.dart +++ b/lib/src/controller/quill_controller.dart @@ -16,7 +16,6 @@ import '../document/nodes/leaf.dart'; import '../document/structs/doc_change.dart'; import '../document/style.dart'; import '../editor/config/editor_configurations.dart'; -import '../toolbar/config/simple_toolbar_configurations.dart'; import 'quill_controller_configurations.dart'; import 'quill_controller_rich_paste.dart'; @@ -34,17 +33,15 @@ class QuillController extends ChangeNotifier { this.onSelectionCompleted, this.onSelectionChanged, this.readOnly = false, - this.editorFocusNode, }) : _document = document, _selection = selection; - factory QuillController.basic( - {QuillControllerConfigurations configurations = - const QuillControllerConfigurations(), - FocusNode? editorFocusNode}) => + factory QuillController.basic({ + QuillControllerConfigurations configurations = + const QuillControllerConfigurations(), + }) => QuillController( configurations: configurations, - editorFocusNode: editorFocusNode, document: Document(), selection: const TextSelection.collapsed(offset: 0), ); @@ -60,15 +57,6 @@ class QuillController extends ChangeNotifier { set editorConfigurations(QuillEditorConfigurations? value) => _editorConfigurations = document.editorConfigurations = value; - /// Toolbar configurations - /// - /// Caches configuration set in QuillSimpleToolbar ctor. - QuillSimpleToolbarConfigurations? _toolbarConfigurations; - QuillSimpleToolbarConfigurations get toolbarConfigurations => - _toolbarConfigurations ?? const QuillSimpleToolbarConfigurations(); - set toolbarConfigurations(QuillSimpleToolbarConfigurations? value) => - _toolbarConfigurations = value; - /// Document managed by this controller. Document _document; @@ -511,11 +499,14 @@ class QuillController extends ChangeNotifier { Delta get pasteDelta => _pasteDelta; List get pasteStyleAndEmbed => _pasteStyleAndEmbed; + /// Whether the text can be changed. + /// + /// When this is set to `true`, the text cannot be modified + /// by any shortcut or keyboard operation. The text is still selectable. + /// + /// Defaults to `false`. Must not be `null`. bool readOnly; - /// Used to give focus to the editor following a toolbar action - FocusNode? editorFocusNode; - ImageUrl? _copiedImageUrl; ImageUrl? get copiedImageUrl => _copiedImageUrl; diff --git a/lib/src/editor/config/editor_configurations.dart b/lib/src/editor/config/editor_configurations.dart index 540f483c1..d27bd0aa5 100644 --- a/lib/src/editor/config/editor_configurations.dart +++ b/lib/src/editor/config/editor_configurations.dart @@ -1,4 +1,3 @@ -import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show Brightness, Uint8List, immutable; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart' @@ -9,7 +8,6 @@ import 'package:meta/meta.dart' show experimental; import '../../controller/quill_controller.dart'; import '../../editor_toolbar_shared/config/quill_shared_configurations.dart'; import '../../toolbar/theme/quill_dialog_theme.dart'; -import '../editor_builder.dart'; import '../embed/embed_editor_builder.dart'; import '../raw_editor/builders/leading_block_builder.dart'; import '../raw_editor/config/events/events.dart'; @@ -24,13 +22,10 @@ export 'element_options.dart'; /// The configurations for the quill editor widget of flutter quill @immutable -class QuillEditorConfigurations extends Equatable { +class QuillEditorConfigurations { /// Important note for the maintainers /// When editing this class please update the [copyWith] function too. const QuillEditorConfigurations({ - @Deprecated( - 'controller should be passed directly to the editor - this parameter will be removed in future versions.') - this.controller, this.sharedConfigurations = const QuillSharedConfigurations(), this.scrollable = true, this.padding = EdgeInsets.zero, @@ -85,8 +80,6 @@ class QuillEditorConfigurations extends Equatable { this.contextMenuBuilder, this.editorKey, this.requestKeyboardFocusOnCheckListChanged = false, - this.elementOptions = const QuillEditorElementOptions(), - this.builder, this.magnifierConfiguration, this.textInputAction = TextInputAction.newline, this.enableScribble = false, @@ -101,9 +94,6 @@ class QuillEditorConfigurations extends Equatable { final LeadingBlockNodeBuilder? customLeadingBlockBuilder; - @Deprecated('controller will be removed in future versions.') - final QuillController? controller; - /// The text placeholder in the quill editor final String? placeholder; @@ -153,15 +143,6 @@ class QuillEditorConfigurations extends Equatable { ///``` final List spaceShortcutEvents; - /// Whether the text can be changed. - /// - /// When this is set to `true`, the text cannot be modified - /// by any shortcut or keyboard operation. The text is still selectable. - /// - /// Defaults to `false`. Must not be `null`. - // ignore: deprecated_member_use_from_same_package - bool get readOnly => controller?.readOnly != false; - /// Override [readOnly] for checkbox. /// /// When this is set to `false`, the checkbox can be checked @@ -434,11 +415,6 @@ class QuillEditorConfigurations extends Equatable { /// should we request keyboard focus?? final bool requestKeyboardFocusOnCheckListChanged; - /// This is not complete yet and might changed - final QuillEditorElementOptions elementOptions; - - final QuillEditorBuilder? builder; - /// Currently this feature is experimental @experimental final TextMagnifierConfiguration? magnifierConfiguration; @@ -458,17 +434,6 @@ class QuillEditorConfigurations extends Equatable { /// Called when a text input action is performed. final void Function(TextInputAction action)? onPerformAction; - @override - List get props => [ - placeholder, - // ignore: deprecated_member_use_from_same_package - controller?.readOnly, - ]; - - // We might use code generator like freezed but sometimes it can be limited - // instead whatever there is a change to the parameters in this class please - // regenerate this function using extension in vs code or plugin in intellij - QuillEditorConfigurations copyWith({ QuillSharedConfigurations? sharedConfigurations, QuillController? controller, @@ -521,7 +486,6 @@ class QuillEditorConfigurations extends Equatable { LeadingBlockNodeBuilder? customLeadingBlockBuilder, bool? requestKeyboardFocusOnCheckListChanged, QuillEditorElementOptions? elementOptions, - QuillEditorBuilder? builder, TextMagnifierConfiguration? magnifierConfiguration, TextInputAction? textInputAction, bool? enableScribble, @@ -533,8 +497,6 @@ class QuillEditorConfigurations extends Equatable { sharedConfigurations: sharedConfigurations ?? this.sharedConfigurations, customLeadingBlockBuilder: customLeadingBlockBuilder ?? this.customLeadingBlockBuilder, - // ignore: deprecated_member_use_from_same_package - controller: controller ?? this.controller, placeholder: placeholder ?? this.placeholder, checkBoxReadOnly: checkBoxReadOnly ?? this.checkBoxReadOnly, disableClipboard: disableClipboard ?? this.disableClipboard, @@ -597,8 +559,6 @@ class QuillEditorConfigurations extends Equatable { requestKeyboardFocusOnCheckListChanged: requestKeyboardFocusOnCheckListChanged ?? this.requestKeyboardFocusOnCheckListChanged, - elementOptions: elementOptions ?? this.elementOptions, - builder: builder ?? this.builder, magnifierConfiguration: magnifierConfiguration ?? this.magnifierConfiguration, textInputAction: textInputAction ?? this.textInputAction, diff --git a/lib/src/editor/config/element_options.dart b/lib/src/editor/config/element_options.dart index f083f692e..dccdf615f 100644 --- a/lib/src/editor/config/element_options.dart +++ b/lib/src/editor/config/element_options.dart @@ -1,4 +1,3 @@ -import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show immutable; import 'elements/code_block.dart'; @@ -10,7 +9,7 @@ export 'elements/list/ordered_list.dart'; export 'elements/list/unordered_list.dart'; @immutable -class QuillEditorElementOptions extends Equatable { +class QuillEditorElementOptions { const QuillEditorElementOptions({ this.codeBlock = const QuillEditorCodeBlockElementOptions(), this.orderedList = const QuillEditorOrderedListElementOptions(), @@ -21,8 +20,4 @@ class QuillEditorElementOptions extends Equatable { final QuillEditorOrderedListElementOptions orderedList; final QuillEditorUnOrderedListElementOptions unorderedList; - @override - List get props => [ - codeBlock, - ]; } diff --git a/lib/src/editor/config/elements/code_block.dart b/lib/src/editor/config/elements/code_block.dart index 136d2cb9e..04780dd78 100644 --- a/lib/src/editor/config/elements/code_block.dart +++ b/lib/src/editor/config/elements/code_block.dart @@ -1,8 +1,7 @@ -import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show immutable; @immutable -class QuillEditorCodeBlockElementOptions extends Equatable { +class QuillEditorCodeBlockElementOptions { const QuillEditorCodeBlockElementOptions({ this.enableLineNumbers = false, }); @@ -10,9 +9,4 @@ class QuillEditorCodeBlockElementOptions extends Equatable { /// If you want line numbers in the code block, please pass true /// by default it's false as it's not really needed in most cases final bool enableLineNumbers; - - @override - List get props => [ - enableLineNumbers, - ]; } diff --git a/lib/src/editor/config/elements/list/ordered_list.dart b/lib/src/editor/config/elements/list/ordered_list.dart index 9cad77dca..fde4daf62 100644 --- a/lib/src/editor/config/elements/list/ordered_list.dart +++ b/lib/src/editor/config/elements/list/ordered_list.dart @@ -1,9 +1,8 @@ -import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' show Widget; @immutable -class QuillEditorOrderedListElementOptions extends Equatable { +class QuillEditorOrderedListElementOptions { const QuillEditorOrderedListElementOptions({ this.useTextColorForDot = true, this.customWidget, @@ -11,6 +10,4 @@ class QuillEditorOrderedListElementOptions extends Equatable { final bool useTextColorForDot; final Widget? customWidget; - @override - List get props => []; } diff --git a/lib/src/editor/config/elements/list/unordered_list.dart b/lib/src/editor/config/elements/list/unordered_list.dart index 322cf1181..f0a19d48c 100644 --- a/lib/src/editor/config/elements/list/unordered_list.dart +++ b/lib/src/editor/config/elements/list/unordered_list.dart @@ -1,9 +1,8 @@ -import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' show Widget; @immutable -class QuillEditorUnOrderedListElementOptions extends Equatable { +class QuillEditorUnOrderedListElementOptions { const QuillEditorUnOrderedListElementOptions({ this.useTextColorForDot = true, this.customWidget, @@ -11,6 +10,4 @@ class QuillEditorUnOrderedListElementOptions extends Equatable { final bool useTextColorForDot; final Widget? customWidget; - @override - List get props => []; } diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 617d88fbc..5fcfd1677 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -4,13 +4,7 @@ import 'package:flutter/cupertino.dart' show CupertinoTheme, cupertinoTextSelectionControls; import 'package:flutter/foundation.dart' show ValueListenable, defaultTargetPlatform, kIsWeb; -import 'package:flutter/gestures.dart' - show - PointerDeviceKind, - TapDragDownDetails, - TapDragEndDetails, - TapDragStartDetails, - TapDragUpDetails; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; @@ -21,11 +15,8 @@ import '../document/attribute.dart'; import '../document/document.dart'; import '../document/nodes/container.dart' as container_node; import '../document/nodes/leaf.dart'; -import '../l10n/widgets/localizations.dart'; import 'config/editor_configurations.dart'; -import 'editor_builder.dart'; import 'embed/embed_editor_builder.dart'; -import 'provider.dart'; import 'raw_editor/config/raw_editor_configurations.dart'; import 'raw_editor/raw_editor.dart'; import 'widgets/box.dart'; @@ -130,62 +121,48 @@ class QuillEditor extends StatefulWidget { /// Quick start guide: /// /// Instantiate a controller: + /// ```dart /// QuillController _controller = QuillController.basic(); + /// ``` /// /// Connect the controller to the `QuillEditor` and `QuillSimpleToolbar` widgets. + /// + /// ```dart /// QuillSimpleToolbar( /// controller: _controller, - /// configurations: const QuillSimpleToolbarConfigurations(), /// ), /// Expanded( /// child: QuillEditor.basic( /// controller: _controller, - /// configurations: const QuillEditorConfigurations(), /// ), /// ), + /// ``` /// factory QuillEditor({ required FocusNode focusNode, required ScrollController scrollController, + required QuillController controller, Key? key, - - /// Controller and configurations are required - /// - /// Prefer: use controller and pass QuillEditorConfigurations in constructor for controller (using QuillControllerConfigurations). - /// Backward compatibility: use configurations and pass QuillController in constructor for configurations. (Will be removed in future versions.) - QuillController? controller, QuillEditorConfigurations? configurations, }) { - // ignore: deprecated_member_use_from_same_package - controller ??= configurations?.controller; - assert(controller != null, - 'controller required. Provide controller directly (preferred) or indirectly through configurations (not recommended - will be removed in future versions).'); - controller ??= QuillController( - document: Document(), - selection: const TextSelection.collapsed(offset: 0)); - // - controller - ..editorConfigurations = configurations - ..editorFocusNode = focusNode; - // + controller.editorConfigurations = configurations; return QuillEditor._( - focusNode: focusNode, - scrollController: scrollController, - controller: controller, - key: key); + key: key, + focusNode: focusNode, + scrollController: scrollController, + controller: controller, + ); } - const QuillEditor._( - {required this.focusNode, - required this.scrollController, - required this.controller, - super.key}); + const QuillEditor._({ + required this.focusNode, + required this.scrollController, + required this.controller, + super.key, + }); factory QuillEditor.basic({ - /// The controller for the quill editor widget of flutter quill - QuillController? controller, - - /// The configurations for the quill editor widget of flutter quill + required QuillController controller, QuillEditorConfigurations? configurations, FocusNode? focusNode, ScrollController? scrollController, @@ -194,7 +171,7 @@ class QuillEditor extends StatefulWidget { scrollController: scrollController ?? ScrollController(), focusNode: focusNode ?? FocusNode(), controller: controller, - configurations: configurations?.copyWith(), + configurations: configurations, ); } @@ -286,86 +263,75 @@ class QuillEditorState extends State final showSelectionToolbar = configurations.enableInteractiveSelection && configurations.enableSelectionToolbar; - final child = FlutterQuillLocalizationsWidget( - child: QuillEditorProvider( - controller: controller, - child: QuillEditorBuilderWidget( - builder: configurations.builder, - child: QuillRawEditor( - key: _editorKey, - controller: controller, - configurations: QuillRawEditorConfigurations( - characterShortcutEvents: - widget.configurations.characterShortcutEvents, - spaceShortcutEvents: widget.configurations.spaceShortcutEvents, - customLeadingBuilder: - widget.configurations.customLeadingBlockBuilder, - focusNode: widget.focusNode, - scrollController: widget.scrollController, - scrollable: configurations.scrollable, - enableAlwaysIndentOnTab: configurations.enableAlwaysIndentOnTab, - scrollBottomInset: configurations.scrollBottomInset, - padding: configurations.padding, - readOnly: controller.readOnly, - checkBoxReadOnly: configurations.checkBoxReadOnly, - disableClipboard: configurations.disableClipboard, - placeholder: configurations.placeholder, - onLaunchUrl: configurations.onLaunchUrl, - contextMenuBuilder: showSelectionToolbar - ? (configurations.contextMenuBuilder ?? - QuillRawEditorConfigurations.defaultContextMenuBuilder) - : null, - showSelectionHandles: isMobile, - showCursor: configurations.showCursor ?? true, - cursorStyle: CursorStyle( - color: cursorColor, - backgroundColor: Colors.grey, - width: 2, - radius: cursorRadius, - offset: cursorOffset, - paintAboveText: - configurations.paintCursorAboveText ?? paintCursorAboveText, - opacityAnimates: cursorOpacityAnimates, - ), - textCapitalization: configurations.textCapitalization, - minHeight: configurations.minHeight, - maxHeight: configurations.maxHeight, - maxContentWidth: configurations.maxContentWidth, - customStyles: configurations.customStyles, - expands: configurations.expands, - autoFocus: configurations.autoFocus, - selectionColor: selectionColor, - selectionCtrls: - configurations.textSelectionControls ?? textSelectionControls, - keyboardAppearance: configurations.keyboardAppearance, - enableInteractiveSelection: - configurations.enableInteractiveSelection, - scrollPhysics: configurations.scrollPhysics, - embedBuilder: _getEmbedBuilder, - linkActionPickerDelegate: configurations.linkActionPickerDelegate, - customStyleBuilder: configurations.customStyleBuilder, - customRecognizerBuilder: configurations.customRecognizerBuilder, - floatingCursorDisabled: configurations.floatingCursorDisabled, - onImagePaste: configurations.onImagePaste, - onGifPaste: configurations.onGifPaste, - customShortcuts: configurations.customShortcuts, - customActions: configurations.customActions, - customLinkPrefixes: configurations.customLinkPrefixes, - isOnTapOutsideEnabled: configurations.isOnTapOutsideEnabled, - onTapOutside: configurations.onTapOutside, - dialogTheme: configurations.dialogTheme, - contentInsertionConfiguration: - configurations.contentInsertionConfiguration, - enableScribble: configurations.enableScribble, - onScribbleActivated: configurations.onScribbleActivated, - scribbleAreaInsets: configurations.scribbleAreaInsets, - readOnlyMouseCursor: configurations.readOnlyMouseCursor, - magnifierConfiguration: configurations.magnifierConfiguration, - textInputAction: configurations.textInputAction, - onPerformAction: configurations.onPerformAction, - ), - ), + final child = QuillRawEditor( + key: _editorKey, + controller: controller, + configurations: QuillRawEditorConfigurations( + characterShortcutEvents: widget.configurations.characterShortcutEvents, + spaceShortcutEvents: widget.configurations.spaceShortcutEvents, + customLeadingBuilder: widget.configurations.customLeadingBlockBuilder, + focusNode: widget.focusNode, + scrollController: widget.scrollController, + scrollable: configurations.scrollable, + enableAlwaysIndentOnTab: configurations.enableAlwaysIndentOnTab, + scrollBottomInset: configurations.scrollBottomInset, + padding: configurations.padding, + readOnly: controller.readOnly, + checkBoxReadOnly: configurations.checkBoxReadOnly, + disableClipboard: configurations.disableClipboard, + placeholder: configurations.placeholder, + onLaunchUrl: configurations.onLaunchUrl, + contextMenuBuilder: showSelectionToolbar + ? (configurations.contextMenuBuilder ?? + QuillRawEditorConfigurations.defaultContextMenuBuilder) + : null, + showSelectionHandles: isMobile, + showCursor: configurations.showCursor ?? true, + cursorStyle: CursorStyle( + color: cursorColor, + backgroundColor: Colors.grey, + width: 2, + radius: cursorRadius, + offset: cursorOffset, + paintAboveText: + configurations.paintCursorAboveText ?? paintCursorAboveText, + opacityAnimates: cursorOpacityAnimates, ), + textCapitalization: configurations.textCapitalization, + minHeight: configurations.minHeight, + maxHeight: configurations.maxHeight, + maxContentWidth: configurations.maxContentWidth, + customStyles: configurations.customStyles, + expands: configurations.expands, + autoFocus: configurations.autoFocus, + selectionColor: selectionColor, + selectionCtrls: + configurations.textSelectionControls ?? textSelectionControls, + keyboardAppearance: configurations.keyboardAppearance, + enableInteractiveSelection: configurations.enableInteractiveSelection, + scrollPhysics: configurations.scrollPhysics, + embedBuilder: _getEmbedBuilder, + linkActionPickerDelegate: configurations.linkActionPickerDelegate, + customStyleBuilder: configurations.customStyleBuilder, + customRecognizerBuilder: configurations.customRecognizerBuilder, + floatingCursorDisabled: configurations.floatingCursorDisabled, + onImagePaste: configurations.onImagePaste, + onGifPaste: configurations.onGifPaste, + customShortcuts: configurations.customShortcuts, + customActions: configurations.customActions, + customLinkPrefixes: configurations.customLinkPrefixes, + isOnTapOutsideEnabled: configurations.isOnTapOutsideEnabled, + onTapOutside: configurations.onTapOutside, + dialogTheme: configurations.dialogTheme, + contentInsertionConfiguration: + configurations.contentInsertionConfiguration, + enableScribble: configurations.enableScribble, + onScribbleActivated: configurations.onScribbleActivated, + scribbleAreaInsets: configurations.scribbleAreaInsets, + readOnlyMouseCursor: configurations.readOnlyMouseCursor, + magnifierConfiguration: configurations.magnifierConfiguration, + textInputAction: configurations.textInputAction, + onPerformAction: configurations.onPerformAction, ), ); diff --git a/lib/src/editor/editor_builder.dart b/lib/src/editor/editor_builder.dart deleted file mode 100644 index 95195cbfb..000000000 --- a/lib/src/editor/editor_builder.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/widgets.dart'; - -import 'raw_editor/raw_editor.dart'; - -typedef QuillEditorBuilder = Widget Function( - BuildContext context, - QuillRawEditor rawEditor, -); - -class QuillEditorBuilderWidget extends StatelessWidget { - const QuillEditorBuilderWidget({ - required this.child, - this.builder, - super.key, - }); - - final QuillRawEditor child; - final QuillEditorBuilder? builder; - - @override - Widget build(BuildContext context) { - final builderCallback = builder; - if (builderCallback != null) { - return builderCallback( - context, - child, - ); - } - return child; - } -} diff --git a/lib/src/editor/provider.dart b/lib/src/editor/provider.dart deleted file mode 100644 index d59746318..000000000 --- a/lib/src/editor/provider.dart +++ /dev/null @@ -1,96 +0,0 @@ -import 'package:flutter/foundation.dart' show debugPrint, kDebugMode; -import 'package:flutter/widgets.dart' - show BuildContext, InheritedWidget, Widget; - -import '../controller/quill_controller.dart'; -import 'config/editor_configurations.dart'; - -class QuillEditorProvider extends InheritedWidget { - QuillEditorProvider({ - required super.child, - - /// Controller and configurations are required but should only be provided from one. - /// - /// Passing the controller as part of configurations is being deprecated and will be removed in the future. - /// Prefer: use controller and set QuillEditorConfigurations in the controller. - /// Current: use configurations and pass QuillController in constructor for configurations. - QuillController? controller, - @Deprecated( - 'editorConfigurations are no longer needed and will be removed in future versions. Set configurations in the controller') - QuillEditorConfigurations? editorConfigurations, - super.key, - }) : editorConfigurations = editorConfigurations ?? - controller?.editorConfigurations ?? - const QuillEditorConfigurations(), - controller = controller ?? - // ignore: deprecated_member_use_from_same_package - editorConfigurations?.controller ?? - QuillController.basic(); - - final QuillController controller; - final QuillEditorConfigurations editorConfigurations; - - @override - bool updateShouldNotify(covariant QuillEditorProvider oldWidget) { - return oldWidget.editorConfigurations != editorConfigurations; - } - - static QuillEditorProvider? maybeOf(BuildContext context) { - return context.dependOnInheritedWidgetOfExactType(); - } - - static QuillEditorProvider of(BuildContext context) { - final provider = maybeOf(context); - if (provider == null) { - if (kDebugMode) { - debugPrint( - 'The quill editor 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 editor provider widget to be in the parent widget tree ' - 'because ' - 'The provider is $provider. Please make sure to wrap this widget' - ' with' - ' QuillEditorProvider widget. ' - 'You might using QuillEditor so make sure to' - ' wrap them with the quill provider widget and setup the required ' - 'configurations', - 'QuillEditorProvider', - ); - } - return provider; - } - - /// To pass the [QuillEditorProvider] instance as value instead of creating - /// new widget - static QuillEditorProvider value({ - required QuillEditorProvider value, - required Widget child, - }) { - value.controller.editorConfigurations = value.editorConfigurations; - return QuillEditorProvider( - controller: value.controller, - child: child, - ); - } -} - -extension QuillEditorExt on BuildContext { - QuillEditorConfigurations get requireQuillEditorConfigurations { - return QuillEditorProvider.of(this).editorConfigurations; - } - - QuillEditorConfigurations? get quillEditorConfigurations { - return QuillEditorProvider.maybeOf(this)?.editorConfigurations; - } - - QuillEditorElementOptions? get quillEditorElementOptions { - return quillEditorConfigurations?.elementOptions; - } - - QuillEditorElementOptions get requireQuillEditorElementOptions { - return requireQuillEditorConfigurations.elementOptions; - } -} diff --git a/lib/src/editor/raw_editor/config/raw_editor_configurations.dart b/lib/src/editor/raw_editor/config/raw_editor_configurations.dart index 959bf2570..0de64a99a 100644 --- a/lib/src/editor/raw_editor/config/raw_editor_configurations.dart +++ b/lib/src/editor/raw_editor/config/raw_editor_configurations.dart @@ -1,33 +1,7 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show Brightness, Uint8List, immutable; -import 'package:flutter/material.dart' - show - AdaptiveTextSelectionToolbar, - PointerDownEvent, - TextCapitalization, - TextInputAction, - TextMagnifierConfiguration; -import 'package:flutter/widgets.dart' - show - Action, - BuildContext, - Color, - ContentInsertionConfiguration, - EdgeInsets, - EdgeInsetsGeometry, - FocusNode, - Intent, - ScrollController, - ScrollPhysics, - ShortcutActivator, - TextFieldTapRegion, - TextSelectionControls, - ValueChanged, - Widget, - MouseCursor, - SystemMouseCursors; - -import '../../../controller/quill_controller.dart'; +import 'package:flutter/material.dart'; + import '../../../editor/embed/embed_editor_builder.dart'; import '../../../editor/raw_editor/raw_editor.dart'; import '../../../editor/raw_editor/raw_editor_state.dart'; @@ -52,9 +26,6 @@ class QuillRawEditorConfigurations extends Equatable { required this.autoFocus, required this.characterShortcutEvents, required this.spaceShortcutEvents, - @Deprecated( - 'controller should be passed directly to the editor - this parameter will be removed in future versions.') - this.controller, this.showCursor = true, this.scrollable = true, this.padding = EdgeInsets.zero, @@ -74,9 +45,6 @@ class QuillRawEditorConfigurations extends Equatable { this.customActions, this.expands = false, this.isOnTapOutsideEnabled = true, - @Deprecated( - 'Use space/char shortcut events instead - enableMarkdownStyleConversion will be removed in future releases') - this.enableMarkdownStyleConversion = true, this.enableAlwaysIndentOnTab = false, this.onTapOutside, this.keyboardAppearance, @@ -102,10 +70,6 @@ class QuillRawEditorConfigurations extends Equatable { this.customLeadingBuilder, }); - /// Controls the document being edited. - @Deprecated('controller will be removed in future versions.') - final QuillController? controller; - /// Controls whether this editor has keyboard focus. final FocusNode focusNode; final ScrollController scrollController; @@ -162,10 +126,6 @@ class QuillRawEditorConfigurations extends Equatable { /// Additional space around the editor contents. final EdgeInsetsGeometry padding; - @Deprecated( - 'enableMarkdownStyleConversion is no longer used and will be removed in future releases. Use space/char shortcut events instead.') - final bool enableMarkdownStyleConversion; - /// Enables always indenting when the TAB key is pressed. /// /// When set to true, pressing the TAB key will always insert an indentation diff --git a/lib/src/editor/raw_editor/raw_editor.dart b/lib/src/editor/raw_editor/raw_editor.dart index 8ae7d9399..c43b5087d 100644 --- a/lib/src/editor/raw_editor/raw_editor.dart +++ b/lib/src/editor/raw_editor/raw_editor.dart @@ -1,15 +1,4 @@ -import 'dart:ui' show Offset; - -import 'package:flutter/widgets.dart' - show - AnimationController, - BuildContext, - ScrollController, - State, - StatefulWidget, - TextSelectionDelegate, - Widget, - immutable; +import 'package:flutter/widgets.dart'; import '../../common/structs/offset_value.dart'; import '../../controller/quill_controller.dart'; @@ -21,14 +10,9 @@ import 'raw_editor_state.dart'; class QuillRawEditor extends StatefulWidget { QuillRawEditor({ required this.configurations, - controller, + required this.controller, super.key, - }) : - // ignore: deprecated_member_use_from_same_package - assert((controller ?? configurations.controller) != null), - // ignore: deprecated_member_use_from_same_package - controller = controller ?? configurations.controller, - assert( + }) : assert( configurations.maxHeight == null || configurations.maxHeight! > 0, 'maxHeight cannot be null'), assert( diff --git a/lib/src/editor/raw_editor/raw_editor_actions.dart b/lib/src/editor/raw_editor/raw_editor_actions.dart index e9cec3af6..1c89f144e 100644 --- a/lib/src/editor/raw_editor/raw_editor_actions.dart +++ b/lib/src/editor/raw_editor/raw_editor_actions.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import '../../../translations.dart'; import '../../document/attribute.dart'; import '../../document/style.dart'; import '../../toolbar/buttons/link_style2_button.dart'; @@ -507,10 +506,8 @@ class QuillEditorOpenSearchAction extends ContextAction { await showDialog( barrierColor: Colors.transparent, context: context, - builder: (_) => FlutterQuillLocalizationsWidget( - child: QuillToolbarSearchDialog( - controller: state.controller, - ), + builder: (_) => QuillToolbarSearchDialog( + controller: state.controller, ), ); } diff --git a/lib/src/editor/style_widgets/bullet_point.dart b/lib/src/editor/style_widgets/bullet_point.dart index 7872d58ea..abba0d9d0 100644 --- a/lib/src/editor/style_widgets/bullet_point.dart +++ b/lib/src/editor/style_widgets/bullet_point.dart @@ -1,9 +1,7 @@ import 'package:flutter/widgets.dart'; -import '../provider.dart'; - -class QuillEditorBulletPoint extends StatelessWidget { - const QuillEditorBulletPoint({ +class QuillBulletPoint extends StatelessWidget { + const QuillBulletPoint({ required this.style, required this.width, this.padding = 0, @@ -25,13 +23,11 @@ class QuillEditorBulletPoint extends StatelessWidget { width: width, padding: EdgeInsetsDirectional.only(end: padding), color: backgroundColor, - child: context.quillEditorConfigurations?.elementOptions.unorderedList - .customWidget ?? - Text( - '•', - style: style, - textAlign: textAlign, - ), + child: Text( + '•', + style: style, + textAlign: textAlign, + ), ); } } diff --git a/lib/src/editor/style_widgets/checkbox_point.dart b/lib/src/editor/style_widgets/checkbox_point.dart index 860d5696f..f79a5f4be 100644 --- a/lib/src/editor/style_widgets/checkbox_point.dart +++ b/lib/src/editor/style_widgets/checkbox_point.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -class QuillEditorCheckboxPoint extends StatefulWidget { - const QuillEditorCheckboxPoint({ +class QuillCheckboxPoint extends StatefulWidget { + const QuillCheckboxPoint({ required this.size, required this.value, required this.enabled, @@ -17,11 +17,10 @@ class QuillEditorCheckboxPoint extends StatefulWidget { final QuillCheckboxBuilder? uiBuilder; @override - QuillEditorCheckboxPointState createState() => - QuillEditorCheckboxPointState(); + QuillCheckboxPointState createState() => QuillCheckboxPointState(); } -class QuillEditorCheckboxPointState extends State { +class QuillCheckboxPointState extends State { @override Widget build(BuildContext context) { final uiBuilder = widget.uiBuilder; diff --git a/lib/src/editor/style_widgets/number_point.dart b/lib/src/editor/style_widgets/number_point.dart index c45b7cee1..fadba673e 100644 --- a/lib/src/editor/style_widgets/number_point.dart +++ b/lib/src/editor/style_widgets/number_point.dart @@ -1,8 +1,8 @@ import 'package:flutter/widgets.dart'; import '../../../flutter_quill.dart'; -class QuillEditorNumberPoint extends StatelessWidget { - const QuillEditorNumberPoint({ +class QuillNumberPoint extends StatelessWidget { + const QuillNumberPoint({ required this.index, required this.indentLevelCounts, required this.count, @@ -35,13 +35,11 @@ class QuillEditorNumberPoint extends StatelessWidget { width: width, padding: EdgeInsetsDirectional.only(end: padding), color: backgroundColor, - child: context.quillEditorConfigurations?.elementOptions.orderedList - .customWidget ?? - Text( - withDot ? '$index.' : index, - style: style, - textAlign: textAlign, - ), + child: Text( + withDot ? '$index.' : index, + style: style, + textAlign: textAlign, + ), ); } return Container( @@ -49,13 +47,11 @@ class QuillEditorNumberPoint extends StatelessWidget { width: width, padding: EdgeInsetsDirectional.only(end: padding), color: backgroundColor, - child: context.quillEditorConfigurations?.elementOptions.orderedList - .customWidget ?? - Text( - withDot ? '$index.' : index, - style: style, - textAlign: textAlign, - ), + child: Text( + withDot ? '$index.' : index, + style: style, + textAlign: textAlign, + ), ); } } diff --git a/lib/src/editor/widgets/default_leading_components/bullet_point_leading.dart b/lib/src/editor/widgets/default_leading_components/bullet_point_leading.dart index 952533ec1..14ce8c7d3 100644 --- a/lib/src/editor/widgets/default_leading_components/bullet_point_leading.dart +++ b/lib/src/editor/widgets/default_leading_components/bullet_point_leading.dart @@ -2,8 +2,7 @@ import 'package:flutter/material.dart'; import '../../raw_editor/builders/leading_block_builder.dart'; import '../../style_widgets/style_widgets.dart'; -Widget bulletPointLeading(LeadingConfigurations config) => - QuillEditorBulletPoint( +Widget bulletPointLeading(LeadingConfigurations config) => QuillBulletPoint( style: config.style!, width: config.width!, padding: config.padding!, diff --git a/lib/src/editor/widgets/default_leading_components/check_box_leading.dart b/lib/src/editor/widgets/default_leading_components/check_box_leading.dart index cf4883921..6fb26ea8f 100644 --- a/lib/src/editor/widgets/default_leading_components/check_box_leading.dart +++ b/lib/src/editor/widgets/default_leading_components/check_box_leading.dart @@ -2,8 +2,7 @@ import 'package:flutter/material.dart'; import '../../raw_editor/builders/leading_block_builder.dart'; import '../../style_widgets/style_widgets.dart'; -Widget checkboxLeading(LeadingConfigurations config) => - QuillEditorCheckboxPoint( +Widget checkboxLeading(LeadingConfigurations config) => QuillCheckboxPoint( size: config.lineSize!, value: config.value, enabled: config.enabled!, diff --git a/lib/src/editor/widgets/default_leading_components/codeblock_line_number_leading.dart b/lib/src/editor/widgets/default_leading_components/codeblock_line_number_leading.dart index 3a0a1c66b..b094ea571 100644 --- a/lib/src/editor/widgets/default_leading_components/codeblock_line_number_leading.dart +++ b/lib/src/editor/widgets/default_leading_components/codeblock_line_number_leading.dart @@ -3,7 +3,7 @@ import '../../raw_editor/builders/leading_block_builder.dart'; import '../../style_widgets/style_widgets.dart'; Widget codeBlockLineNumberLeading(LeadingConfigurations config) => - QuillEditorNumberPoint( + QuillNumberPoint( index: config.getIndexNumberByIndent!, indentLevelCounts: config.indentLevelCounts, count: config.count, diff --git a/lib/src/editor/widgets/default_leading_components/number_point_leading.dart b/lib/src/editor/widgets/default_leading_components/number_point_leading.dart index 375aac2aa..f48002b1f 100644 --- a/lib/src/editor/widgets/default_leading_components/number_point_leading.dart +++ b/lib/src/editor/widgets/default_leading_components/number_point_leading.dart @@ -2,8 +2,7 @@ import 'package:flutter/material.dart'; import '../../raw_editor/builders/leading_block_builder.dart'; import '../../style_widgets/style_widgets.dart'; -Widget numberPointLeading(LeadingConfigurations config) => - QuillEditorNumberPoint( +Widget numberPointLeading(LeadingConfigurations config) => QuillNumberPoint( index: config.getIndexNumberByIndent!, indentLevelCounts: config.indentLevelCounts, count: config.count, diff --git a/lib/src/editor/widgets/text/text_block.dart b/lib/src/editor/widgets/text/text_block.dart index 9f619b634..a57f5bd71 100644 --- a/lib/src/editor/widgets/text/text_block.dart +++ b/lib/src/editor/widgets/text/text_block.dart @@ -9,10 +9,9 @@ import '../../../delta/delta_diff.dart'; import '../../../document/attribute.dart'; import '../../../document/nodes/block.dart'; import '../../../document/nodes/line.dart'; -import '../../../toolbar/base_toolbar.dart'; +import '../../../editor_toolbar_shared/color.dart'; import '../../editor.dart'; import '../../embed/embed_editor_builder.dart'; -import '../../provider.dart'; import '../../raw_editor/builders/leading_block_builder.dart'; import '../box.dart'; import '../cursor.dart'; @@ -277,22 +276,14 @@ class EditableTextBlock extends StatelessWidget { if (isOrdered) { return defaultStyles.leading!.style.copyWith( fontSize: size, - color: context.quillEditorElementOptions?.orderedList - .useTextColorForDot == - true - ? fontColor - : null, + color: fontColor, ); } if (isUnordered) { return defaultStyles.leading!.style.copyWith( fontWeight: FontWeight.bold, fontSize: size, - color: context.quillEditorElementOptions?.unorderedList - .useTextColorForDot == - true - ? fontColor - : null, + color: fontColor, ); } if (isCheck) { @@ -348,8 +339,7 @@ class EditableTextBlock extends StatelessWidget { if (isCheck) { return checkboxLeading(leadingConfigurations); } - if (isCodeBlock && - context.requireQuillEditorElementOptions.codeBlock.enableLineNumbers) { + if (isCodeBlock) { return codeBlockLineNumberLeading(leadingConfigurations); } return null; diff --git a/lib/src/editor_toolbar_controller_shared/quill_configurations.dart b/lib/src/editor_toolbar_controller_shared/quill_configurations.dart index faa1365f1..a6b614383 100644 --- a/lib/src/editor_toolbar_controller_shared/quill_configurations.dart +++ b/lib/src/editor_toolbar_controller_shared/quill_configurations.dart @@ -3,4 +3,3 @@ export '../editor/config/editor_configurations.dart'; export '../editor/config/search_configurations.dart'; export '../editor_toolbar_shared/config/quill_shared_configurations.dart'; export '../toolbar/config/simple_toolbar_configurations.dart'; -export '../toolbar/config/toolbar_configurations.dart'; diff --git a/lib/src/editor_toolbar_shared/color.dart b/lib/src/editor_toolbar_shared/color.dart new file mode 100644 index 000000000..653e842e9 --- /dev/null +++ b/lib/src/editor_toolbar_shared/color.dart @@ -0,0 +1,22 @@ +import 'package:flutter/material.dart'; + +Color hexToColor(String? hexString) { + if (hexString == null) { + return Colors.black; + } + final hexRegex = RegExp(r'([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$'); + + hexString = hexString.replaceAll('#', ''); + if (!hexRegex.hasMatch(hexString)) { + return Colors.black; + } + + final buffer = StringBuffer(); + if (hexString.length == 6 || hexString.length == 7) buffer.write('ff'); + buffer.write(hexString); + return Color(int.tryParse(buffer.toString(), radix: 16) ?? 0xFF000000); +} + +String colorToHex(Color color) { + return color.value.toRadixString(16).padLeft(8, '0').toUpperCase(); +} diff --git a/lib/src/editor_toolbar_shared/quill_configurations_ext.dart b/lib/src/editor_toolbar_shared/quill_configurations_ext.dart deleted file mode 100644 index 64c0691f8..000000000 --- a/lib/src/editor_toolbar_shared/quill_configurations_ext.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/widgets.dart' show BuildContext; - -import '../editor/provider.dart'; -import '../toolbar/simple_toolbar_provider.dart'; -import 'config/quill_shared_configurations.dart'; - -extension QuillSharedExt on BuildContext { - /// return nullable [QuillSharedConfigurations] - QuillSharedConfigurations? get quillSharedConfigurations { - return quillSimpleToolbarConfigurations?.sharedConfigurations ?? - quillEditorConfigurations?.sharedConfigurations; - } -} diff --git a/lib/src/l10n/extensions/localizations_ext.dart b/lib/src/l10n/extensions/localizations_ext.dart index d8726dee6..91128d659 100644 --- a/lib/src/l10n/extensions/localizations_ext.dart +++ b/lib/src/l10n/extensions/localizations_ext.dart @@ -1,22 +1,19 @@ import 'package:flutter/widgets.dart' show BuildContext; -import '../generated/quill_localizations.dart' as generated; - -typedef FlutterQuillLocalizations = generated.FlutterQuillLocalizations; +import '../generated/quill_localizations.dart'; class MissingFlutterQuillLocalizationException extends UnimplementedError { MissingFlutterQuillLocalizationException(); @override String? get message => - 'FlutterQuillLocalizations instance is required and could not found. ' - 'Ensure that you are wrapping the current widget with ' - 'FlutterQuillLocalizationsWidget or add ' - 'FlutterQuillLocalizations.delegate to the localizationsDelegates ' - 'in your App widget (e.,g WidgetsApp, MaterialApp). If you believe this is a bug, consider reporting it.'; + '$FlutterQuillLocalizations instance is required and could not found.\n' + 'Add the delegate `FlutterQuillLocalizations.delegate` to your widget app (e.g., MaterialApp) to fix.\n' + 'If the issue continues, consider reporting a bug.\n' + 'See https://github.com/singerdmx/flutter-quill/blob/master/doc/translation.md'; } extension LocalizationsExt on BuildContext { - /// Require the [FlutterQuillLocalizations] instance + /// Require the [FlutterQuillLocalizations] instance. /// /// `loc` is short for `localizations` FlutterQuillLocalizations get loc { diff --git a/lib/src/l10n/widgets/localizations.dart b/lib/src/l10n/widgets/localizations.dart deleted file mode 100644 index ad27179d5..000000000 --- a/lib/src/l10n/widgets/localizations.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../editor_toolbar_shared/quill_configurations_ext.dart'; -import '../extensions/localizations_ext.dart'; - -/// A widget that check if [FlutterQuillLocalizations.delegate] is provided -/// in the widgets app (e.g, [MaterialApp] or [WidgetsApp]). -/// -/// If not, will provide in the [child] to access it in the widget tree. -class FlutterQuillLocalizationsWidget extends StatelessWidget { - const FlutterQuillLocalizationsWidget({ - required this.child, - super.key, - }); - - final Widget child; - - @override - Widget build(BuildContext context) { - final loc = FlutterQuillLocalizations.of(context); - if (loc != null) { - return child; - } - return Localizations( - locale: context.quillSharedConfigurations?.locale ?? - Localizations.localeOf(context), - delegates: FlutterQuillLocalizations.localizationsDelegates, - child: child, - ); - } -} diff --git a/lib/src/toolbar/base_button/base_value_button.dart b/lib/src/toolbar/base_button/base_value_button.dart index d05a72f2e..673d030ff 100644 --- a/lib/src/toolbar/base_button/base_value_button.dart +++ b/lib/src/toolbar/base_button/base_value_button.dart @@ -24,36 +24,22 @@ abstract class QuillToolbarCommonButtonState< QuillController get controller => widget.controller; - QuillToolbarBaseButtonOptions? get baseButtonExtraOptions => - context.quillToolbarBaseButtonOptions; - String get defaultTooltip; - String get tooltip => - options.tooltip ?? baseButtonExtraOptions?.tooltip ?? defaultTooltip; + String get tooltip => options.tooltip ?? defaultTooltip; IconData get defaultIconData; - IconData get iconData => - options.iconData ?? - context.quillToolbarBaseButtonOptions?.iconData ?? - defaultIconData; + IconData get iconData => options.iconData ?? defaultIconData; - double get iconSize => - options.iconSize ?? baseButtonExtraOptions?.iconSize ?? kDefaultIconSize; + double get iconSize => options.iconSize ?? kDefaultIconSize; double get iconButtonFactor => - options.iconButtonFactor ?? - baseButtonExtraOptions?.iconButtonFactor ?? - kDefaultIconButtonFactor; + options.iconButtonFactor ?? kDefaultIconButtonFactor; - QuillIconTheme? get iconTheme => - options.iconTheme ?? baseButtonExtraOptions?.iconTheme; + QuillIconTheme? get iconTheme => options.iconTheme; - VoidCallback? get afterButtonPressed => - options.afterButtonPressed ?? - baseButtonExtraOptions?.afterButtonPressed ?? - () => controller.editorFocusNode?.requestFocus(); + VoidCallback? get afterButtonPressed => options.afterButtonPressed; } /// The [W] is the widget that creates this State diff --git a/lib/src/toolbar/base_button/stateless_base_button.dart b/lib/src/toolbar/base_button/stateless_base_button.dart index 65289d3e8..803412c71 100644 --- a/lib/src/toolbar/base_button/stateless_base_button.dart +++ b/lib/src/toolbar/base_button/stateless_base_button.dart @@ -2,11 +2,8 @@ import 'package:flutter/material.dart'; import '../../controller/quill_controller.dart'; import '../config/simple_toolbar_configurations.dart'; -import '../simple_toolbar_provider.dart'; import '../theme/quill_icon_theme.dart'; -// TODO: Use this later or remove it - /// The [T] is the options for the button, usually should refresnce itself /// it's used in [childBuilder] so the developer can custmize this when using it /// The [I] is extra options for the button, usually for it's state @@ -22,41 +19,29 @@ abstract class QuillToolbarBaseButton extends StatelessWidget { final QuillController controller; double iconSize(BuildContext context) { - final baseFontSize = baseButtonExtraOptions(context)?.iconSize; final iconSize = options?.iconSize; - return iconSize ?? baseFontSize ?? kDefaultIconSize; + return iconSize ?? kDefaultIconSize; } double iconButtonFactor(BuildContext context) { - final baseIconFactor = baseButtonExtraOptions(context)?.iconButtonFactor; final iconButtonFactor = options?.iconButtonFactor; - return iconButtonFactor ?? baseIconFactor ?? kDefaultIconButtonFactor; + return iconButtonFactor ?? kDefaultIconButtonFactor; } VoidCallback? afterButtonPressed(BuildContext context) { - return options?.afterButtonPressed ?? - baseButtonExtraOptions(context)?.afterButtonPressed ?? - () => controller.editorFocusNode?.requestFocus(); + return options?.afterButtonPressed; } QuillIconTheme? iconTheme(BuildContext context) { - return options?.iconTheme ?? baseButtonExtraOptions(context)?.iconTheme; - } - - QuillToolbarBaseButtonOptions? baseButtonExtraOptions(BuildContext context) { - return context.quillToolbarBaseButtonOptions; + return options?.iconTheme; } IconData iconData(BuildContext context) { - return options?.iconData ?? - baseButtonExtraOptions(context)?.iconData ?? - getDefaultIconData(context); + return options?.iconData ?? getDefaultIconData(context); } String tooltip(BuildContext context) { - return options?.tooltip ?? - baseButtonExtraOptions(context)?.tooltip ?? - getDefaultTooltip(context); + return options?.tooltip ?? getDefaultTooltip(context); } abstract final IconData Function(BuildContext context) getDefaultIconData; diff --git a/lib/src/toolbar/base_toolbar.dart b/lib/src/toolbar/base_toolbar.dart deleted file mode 100644 index 1634ca9ee..000000000 --- a/lib/src/toolbar/base_toolbar.dart +++ /dev/null @@ -1,74 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../flutter_quill.dart' - show QuillToolbarProvider, kDefaultToolbarSize; -import '../controller/quill_controller.dart'; -import '../l10n/widgets/localizations.dart'; -import 'config/simple_toolbar_configurations.dart'; -import 'config/toolbar_configurations.dart'; -import 'simple_toolbar.dart'; - -export 'buttons/clear_format_button.dart'; -export 'buttons/clipboard_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/hearder_style/select_header_style_buttons.dart'; -export 'buttons/hearder_style/select_header_style_dropdown_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/legacy/legacy_search_button.dart'; -export 'buttons/search/search_button.dart'; -export 'buttons/select_line_height_dropdown_button.dart'; -export 'buttons/toggle_check_list_button.dart'; -export 'buttons/toggle_style_button.dart'; -export 'config/base_button_configurations.dart'; -export 'config/simple_toolbar_configurations.dart'; - -typedef QuillBaseToolbarChildrenBuilder = List Function( - BuildContext context, -); - -class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { - const QuillToolbar({ - required this.child, - this.configurations = const QuillToolbarConfigurations(), - super.key, - }); - - static QuillSimpleToolbar simple( - {QuillController? controller, - QuillSimpleToolbarConfigurations? configurations}) { - return QuillSimpleToolbar( - controller: controller, - configurations: configurations, - ); - } - - final Widget child; - - 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 - // a difference no matter what the value is so I will leave it to the - // default - @override - Size get preferredSize => configurations.axis == Axis.horizontal - ? const Size.fromHeight(kDefaultToolbarSize) - : const Size.fromWidth(kDefaultToolbarSize); - - @override - Widget build(BuildContext context) { - return FlutterQuillLocalizationsWidget( - child: QuillToolbarProvider( - toolbarConfigurations: configurations, - child: child, - ), - ); - } -} diff --git a/lib/src/toolbar/buttons/alignment/select_alignment_buttons.dart b/lib/src/toolbar/buttons/alignment/select_alignment_buttons.dart index a301b1a44..43d33907e 100644 --- a/lib/src/toolbar/buttons/alignment/select_alignment_buttons.dart +++ b/lib/src/toolbar/buttons/alignment/select_alignment_buttons.dart @@ -2,7 +2,8 @@ import 'package:flutter/material.dart'; import '../../../controller/quill_controller.dart'; import '../../../document/attribute.dart'; -import '../../base_toolbar.dart'; +import '../../config/simple_toolbar_button_options.dart'; +import '../toggle_style_button.dart'; class QuillToolbarSelectAlignmentButtons extends StatelessWidget { const QuillToolbarSelectAlignmentButtons({ diff --git a/lib/src/toolbar/buttons/clear_format_button.dart b/lib/src/toolbar/buttons/clear_format_button.dart index 920a14c3f..18fa9ec52 100644 --- a/lib/src/toolbar/buttons/clear_format_button.dart +++ b/lib/src/toolbar/buttons/clear_format_button.dart @@ -3,7 +3,8 @@ import 'package:flutter/material.dart'; import '../../document/attribute.dart'; import '../../l10n/extensions/localizations_ext.dart'; import '../base_button/stateless_base_button.dart'; -import '../base_toolbar.dart'; +import '../config/buttons/clear_format_configurations.dart'; +import 'quill_icon_button.dart'; class QuillToolbarClearFormatButton extends QuillToolbarBaseButton { const QuillToolbarClearFormatButton({ diff --git a/lib/src/toolbar/buttons/clipboard_button.dart b/lib/src/toolbar/buttons/clipboard_button.dart index 4f1d43bea..d80b23a53 100644 --- a/lib/src/toolbar/buttons/clipboard_button.dart +++ b/lib/src/toolbar/buttons/clipboard_button.dart @@ -7,8 +7,7 @@ import '../../common/utils/widgets.dart'; import '../../editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; import '../../l10n/extensions/localizations_ext.dart'; import '../base_button/base_value_button.dart'; -import '../base_toolbar.dart'; -import '../simple_toolbar_provider.dart'; +import '../simple_toolbar.dart'; enum ClipboardAction { cut, copy, paste } @@ -113,8 +112,7 @@ class QuillToolbarClipboardButtonState @override Widget build(BuildContext context) { - final childBuilder = options.childBuilder ?? - context.quillToolbarBaseButtonOptions?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( options, diff --git a/lib/src/toolbar/buttons/color/color_button.dart b/lib/src/toolbar/buttons/color/color_button.dart index c430582ed..bd74f2961 100644 --- a/lib/src/toolbar/buttons/color/color_button.dart +++ b/lib/src/toolbar/buttons/color/color_button.dart @@ -3,9 +3,8 @@ import 'package:flutter/material.dart'; import '../../../common/utils/color.dart'; import '../../../document/attribute.dart'; import '../../../document/style.dart'; -import '../../../editor_toolbar_shared/quill_configurations_ext.dart'; +import '../../../editor_toolbar_shared/color.dart'; import '../../../l10n/extensions/localizations_ext.dart'; -import '../../../l10n/widgets/localizations.dart'; import '../../base_button/base_value_button.dart'; import '../../config/buttons/color_configurations.dart'; import '../quill_icon_button.dart'; @@ -127,8 +126,7 @@ class QuillToolbarColorButtonState extends QuillToolbarColorBaseButtonState { ? stringToColor('#ffffff') : null; - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( options, @@ -185,38 +183,12 @@ class QuillToolbarColorButtonState extends QuillToolbarColorBaseButtonState { } showDialog( context: context, - barrierColor: options.dialogBarrierColor ?? - context.quillSharedConfigurations?.dialogBarrierColor ?? - Colors.black54, - builder: (_) => FlutterQuillLocalizationsWidget( - child: ColorPickerDialog( - isBackground: widget.isBackground, - onRequestChangeColor: _changeColor, - isToggledColor: _isToggledColor, - selectionStyle: _selectionStyle, - ), + builder: (_) => ColorPickerDialog( + isBackground: widget.isBackground, + onRequestChangeColor: _changeColor, + isToggledColor: _isToggledColor, + selectionStyle: _selectionStyle, ), ); } } - -Color hexToColor(String? hexString) { - if (hexString == null) { - return Colors.black; - } - final hexRegex = RegExp(r'([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$'); - - hexString = hexString.replaceAll('#', ''); - if (!hexRegex.hasMatch(hexString)) { - return Colors.black; - } - - final buffer = StringBuffer(); - if (hexString.length == 6 || hexString.length == 7) buffer.write('ff'); - buffer.write(hexString); - return Color(int.tryParse(buffer.toString(), radix: 16) ?? 0xFF000000); -} - -String colorToHex(Color color) { - return color.value.toRadixString(16).padLeft(8, '0').toUpperCase(); -} diff --git a/lib/src/toolbar/buttons/color/color_dialog.dart b/lib/src/toolbar/buttons/color/color_dialog.dart index dc15c8686..acfabc9f2 100644 --- a/lib/src/toolbar/buttons/color/color_dialog.dart +++ b/lib/src/toolbar/buttons/color/color_dialog.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart' +import 'package:flutter_colorpicker/flutter_colorpicker.dart' as color_picker show ColorPicker, MaterialPicker, colorToHex; -import '../../../../translations.dart'; import '../../../document/style.dart'; -import 'color_button.dart' show hexToColor; +import '../../../editor_toolbar_shared/color.dart'; +import '../../../l10n/extensions/localizations_ext.dart'; enum _PickerType { material, @@ -39,7 +39,8 @@ class ColorPickerDialogState extends State { @override void initState() { super.initState(); - hexController = TextEditingController(text: colorToHex(selectedColor)); + hexController = + TextEditingController(text: color_picker.colorToHex(selectedColor)); if (widget.isToggledColor) { selectedColor = widget.isBackground ? hexToColor(widget.selectionStyle.attributes['background']?.value) @@ -95,7 +96,7 @@ class ColorPickerDialogState extends State { Column( children: [ if (pickerType == _PickerType.material) - MaterialPicker( + color_picker.MaterialPicker( pickerColor: selectedColor, onColorChanged: (color) { widget.onRequestChangeColor(context, color); @@ -103,7 +104,7 @@ class ColorPickerDialogState extends State { }, ), if (pickerType == _PickerType.color) - ColorPicker( + color_picker.ColorPicker( pickerColor: selectedColor, onColorChanged: (color) { widget.onRequestChangeColor(context, color); diff --git a/lib/src/toolbar/buttons/custom_button_button.dart b/lib/src/toolbar/buttons/custom_button_button.dart index 78f85ee9d..f08426d02 100644 --- a/lib/src/toolbar/buttons/custom_button_button.dart +++ b/lib/src/toolbar/buttons/custom_button_button.dart @@ -1,9 +1,8 @@ import 'package:flutter/material.dart'; import '../../controller/quill_controller.dart'; -import '../base_toolbar.dart'; -import '../simple_toolbar_provider.dart'; -import '../theme/quill_icon_theme.dart'; +import '../config/buttons/custom_button_configurations.dart'; +import 'quill_icon_button.dart'; class QuillToolbarCustomButton extends StatelessWidget { const QuillToolbarCustomButton({ @@ -15,36 +14,13 @@ class QuillToolbarCustomButton extends StatelessWidget { final QuillController controller; final QuillToolbarCustomButtonOptions options; - VoidCallback? _afterButtonPressed(BuildContext context) { - return options.afterButtonPressed ?? - baseButtonExtraOptions(context)?.afterButtonPressed; - } - - QuillIconTheme? _iconTheme(BuildContext context) { - return options.iconTheme ?? baseButtonExtraOptions(context)?.iconTheme; - } - - QuillToolbarBaseButtonOptions? baseButtonExtraOptions(BuildContext context) { - return context.quillToolbarBaseButtonOptions; - } - - String? _tooltip(BuildContext context) { - return options.tooltip ?? baseButtonExtraOptions(context)?.tooltip; - } - void _onPressed(BuildContext context) { options.onPressed?.call(); - _afterButtonPressed(context)?.call(); } @override Widget build(BuildContext context) { - final iconTheme = _iconTheme(context); - final tooltip = _tooltip(context); - - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions(context)?.childBuilder; - final afterButtonPressed = _afterButtonPressed(context); + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( @@ -52,7 +28,10 @@ class QuillToolbarCustomButton extends StatelessWidget { QuillToolbarCustomButtonExtraOptions( context: context, controller: controller, - onPressed: () => _onPressed(context), + onPressed: () { + _onPressed(context); + options.afterButtonPressed?.call(); + }, ), ); } @@ -60,10 +39,10 @@ class QuillToolbarCustomButton extends StatelessWidget { return QuillToolbarIconButton( icon: options.icon ?? const SizedBox.shrink(), isSelected: false, - tooltip: tooltip, + tooltip: options.tooltip, onPressed: () => _onPressed(context), - afterPressed: afterButtonPressed, - iconTheme: iconTheme, + afterPressed: options.afterButtonPressed, + iconTheme: options.iconTheme, ); } } diff --git a/lib/src/toolbar/buttons/font_family_button.dart b/lib/src/toolbar/buttons/font_family_button.dart index 89742fb4a..feed3d99a 100644 --- a/lib/src/toolbar/buttons/font_family_button.dart +++ b/lib/src/toolbar/buttons/font_family_button.dart @@ -4,8 +4,8 @@ import '../../common/utils/widgets.dart'; import '../../document/attribute.dart'; import '../../l10n/extensions/localizations_ext.dart'; import '../base_button/base_value_button.dart'; -import '../base_toolbar.dart'; -import '../simple_toolbar_provider.dart'; + +import '../simple_toolbar.dart'; class QuillToolbarFontFamilyButton extends QuillToolbarBaseButton< QuillToolbarFontFamilyButtonOptions, @@ -50,20 +50,18 @@ class QuillToolbarFontFamilyButtonState extends QuillToolbarBaseButtonState< } Map get rawItemsMap { - 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' - }; + 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' + }; return rawItemsMap; } @@ -95,9 +93,7 @@ class QuillToolbarFontFamilyButtonState extends QuillToolbarBaseButtonState< @override Widget build(BuildContext context) { - final baseButtonConfigurations = context.quillToolbarBaseButtonOptions; - final childBuilder = - options.childBuilder ?? baseButtonConfigurations?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( options, @@ -201,15 +197,12 @@ class QuillToolbarFontFamilyButtonState extends QuillToolbarBaseButtonState< style: options.style ?? TextStyle( fontSize: iconSize / 1.15, - // color: iconTheme?.iconUnselectedFillColor ?? - // theme.iconTheme.color, ), ), ), Icon( Icons.arrow_drop_down, size: iconSize * iconButtonFactor, - // color: iconTheme?.iconUnselectedFillColor ?? theme.iconTheme.color, ) ], ), diff --git a/lib/src/toolbar/buttons/font_size_button.dart b/lib/src/toolbar/buttons/font_size_button.dart index eb825bd67..fc88f7d89 100644 --- a/lib/src/toolbar/buttons/font_size_button.dart +++ b/lib/src/toolbar/buttons/font_size_button.dart @@ -5,23 +5,18 @@ import '../../common/utils/widgets.dart'; import '../../document/attribute.dart'; import '../../l10n/extensions/localizations_ext.dart'; import '../base_button/base_value_button.dart'; -import '../base_toolbar.dart'; -import '../simple_toolbar_provider.dart'; +import '../simple_toolbar.dart'; class QuillToolbarFontSizeButton extends QuillToolbarBaseButton< QuillToolbarFontSizeButtonOptions, QuillToolbarFontSizeButtonExtraOptions> { QuillToolbarFontSizeButton({ required super.controller, - @Deprecated('Please use the default display text from the options') - this.defaultDisplayText, super.options = const QuillToolbarFontSizeButtonOptions(), super.key, }) : assert(options.rawItemsMap?.isNotEmpty ?? true), assert(options.initialValue == null || (options.initialValue?.isNotEmpty ?? true)); - final String? defaultDisplayText; - @override QuillToolbarFontSizeButtonState createState() => QuillToolbarFontSizeButtonState(); @@ -36,7 +31,6 @@ class QuillToolbarFontSizeButtonState extends QuillToolbarBaseButtonState< Map get rawItemsMap { final fontSizes = options.rawItemsMap ?? - context.quillSimpleToolbarConfigurations?.fontSizesValues ?? { context.loc.small: 'small', context.loc.large: 'large', @@ -59,7 +53,6 @@ class QuillToolbarFontSizeButtonState extends QuillToolbarBaseButtonState< String get _defaultDisplayText { return options.initialValue ?? widget.options.defaultDisplayText ?? - widget.defaultDisplayText ?? context.loc.fontSize; } @@ -98,9 +91,7 @@ class QuillToolbarFontSizeButtonState extends QuillToolbarBaseButtonState< @override Widget build(BuildContext context) { - final baseButtonConfigurations = context.quillToolbarBaseButtonOptions; - final childBuilder = - options.childBuilder ?? baseButtonConfigurations?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( options, @@ -169,6 +160,7 @@ class QuillToolbarFontSizeButtonState extends QuillToolbarBaseButtonState< } Widget _buildContent(BuildContext context) { + options.attribute; final hasFinalWidth = options.width != null; return Padding( padding: options.padding ?? const EdgeInsets.fromLTRB(10, 0, 0, 0), diff --git a/lib/src/toolbar/buttons/hearder_style/select_header_style_buttons.dart b/lib/src/toolbar/buttons/hearder_style/select_header_style_buttons.dart index bd082f633..4f8c485e1 100644 --- a/lib/src/toolbar/buttons/hearder_style/select_header_style_buttons.dart +++ b/lib/src/toolbar/buttons/hearder_style/select_header_style_buttons.dart @@ -6,8 +6,6 @@ import '../../../document/style.dart'; import '../../../l10n/extensions/localizations_ext.dart'; import '../../base_button/base_value_button.dart'; import '../../config/buttons/select_header_style_buttons_configurations.dart'; -import '../../provider.dart'; -import '../../simple_toolbar_provider.dart'; import '../quill_icon_button.dart'; typedef QuillToolbarSelectHeaderStyleBaseButtons = QuillToolbarBaseButton< @@ -63,10 +61,7 @@ class QuillToolbarSelectHeaderStyleButtonsState } Axis get axis { - return options.axis ?? - context.quillSimpleToolbarConfigurations?.axis ?? - context.quillToolbarConfigurations?.axis ?? - Axis.horizontal; + return options.axis ?? Axis.horizontal; } void _sharedOnPressed(Attribute attribute) { @@ -100,8 +95,7 @@ class QuillToolbarSelectHeaderStyleButtonsState fontSize: iconSize * 0.7, ); - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions?.childBuilder; + final childBuilder = options.childBuilder; final children = _attributes.map((attribute) { if (childBuilder != null) { diff --git a/lib/src/toolbar/buttons/hearder_style/select_header_style_dropdown_button.dart b/lib/src/toolbar/buttons/hearder_style/select_header_style_dropdown_button.dart index 7696bb17c..2cc1b186c 100644 --- a/lib/src/toolbar/buttons/hearder_style/select_header_style_dropdown_button.dart +++ b/lib/src/toolbar/buttons/hearder_style/select_header_style_dropdown_button.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; -import '../../../../translations.dart'; import '../../../document/attribute.dart'; +import '../../../l10n/extensions/localizations_ext.dart'; import '../../base_button/base_value_button.dart'; import '../../config/buttons/select_header_style_dropdown_button_configurations.dart'; -import '../../simple_toolbar_provider.dart'; + import '../quill_icon_button.dart'; typedef QuillToolbarSelectHeaderStyleDropdownBaseButton @@ -121,9 +121,7 @@ class _QuillToolbarSelectHeaderStyleDropdownButtonState @override Widget build(BuildContext context) { - final baseButtonConfigurations = context.quillToolbarBaseButtonOptions; - final childBuilder = - widget.options.childBuilder ?? baseButtonConfigurations?.childBuilder; + final childBuilder = widget.options.childBuilder; if (childBuilder != null) { return childBuilder( widget.options, diff --git a/lib/src/toolbar/buttons/history_button.dart b/lib/src/toolbar/buttons/history_button.dart index bf81076a2..1602fb93a 100644 --- a/lib/src/toolbar/buttons/history_button.dart +++ b/lib/src/toolbar/buttons/history_button.dart @@ -2,7 +2,8 @@ import 'package:flutter/material.dart'; import '../../l10n/extensions/localizations_ext.dart'; import '../base_button/base_value_button.dart'; -import '../base_toolbar.dart'; +import '../config/buttons/history_configurations.dart'; +import 'quill_icon_button.dart'; typedef QuillToolbarHistoryBaseButton = QuillToolbarBaseButton< QuillToolbarHistoryButtonOptions, QuillToolbarHistoryButtonExtraOptions>; @@ -57,8 +58,7 @@ class QuillToolbarHistoryButtonState @override Widget build(BuildContext context) { - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( diff --git a/lib/src/toolbar/buttons/indent_button.dart b/lib/src/toolbar/buttons/indent_button.dart index 6cc78b399..3b673aa65 100644 --- a/lib/src/toolbar/buttons/indent_button.dart +++ b/lib/src/toolbar/buttons/indent_button.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import '../../l10n/extensions/localizations_ext.dart'; import '../base_button/base_value_button.dart'; -import '../base_toolbar.dart' show QuillToolbarIconButton; import '../config/simple_toolbar_configurations.dart'; +import 'quill_icon_button.dart'; typedef QuillToolbarIndentBaseButton = QuillToolbarBaseButton< QuillToolbarIndentButtonOptions, QuillToolbarIndentButtonExtraOptions>; @@ -44,8 +44,7 @@ class QuillToolbarIndentButtonState extends QuillToolbarIndentBaseButtonState { @override Widget build(BuildContext context) { - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( @@ -61,7 +60,6 @@ class QuillToolbarIndentButtonState extends QuillToolbarIndentBaseButtonState { ); } - // final iconColor = iconTheme?.iconUnselectedFillColor; return QuillToolbarIconButton( tooltip: tooltip, icon: Icon( diff --git a/lib/src/toolbar/buttons/link_style2_button.dart b/lib/src/toolbar/buttons/link_style2_button.dart index 3a77102e4..10a63a8b9 100644 --- a/lib/src/toolbar/buttons/link_style2_button.dart +++ b/lib/src/toolbar/buttons/link_style2_button.dart @@ -3,17 +3,16 @@ import 'package:flutter/material.dart'; import 'package:url_launcher/link.dart'; import '../../common/utils/widgets.dart'; -import '../../controller/quill_controller.dart'; + import '../../editor/widgets/link.dart'; -import '../../editor_toolbar_shared/quill_configurations_ext.dart'; import '../../l10n/extensions/localizations_ext.dart'; -import '../../l10n/widgets/localizations.dart'; import '../../rules/insert.dart'; import '../base_button/base_value_button.dart'; -import '../base_toolbar.dart'; -import '../simple_toolbar_provider.dart'; + +import '../config/simple_toolbar_configurations.dart'; import '../theme/quill_dialog_theme.dart'; -import '../theme/quill_icon_theme.dart'; + +import 'quill_icon_button.dart'; typedef QuillToolbarLinkStyleBaseButton2 = QuillToolbarBaseButton< QuillToolbarLinkStyleButton2Options, @@ -68,86 +67,41 @@ class _QuillToolbarLinkStyleButton2State } } - QuillController get controller { - return widget.controller; - } - QuillToolbarLinkStyleButton2Options get options { return widget.options; } - double get iconSize { - final baseFontSize = baseButtonExtraOptions?.iconSize; - final iconSize = options.iconSize; - return iconSize ?? baseFontSize ?? kDefaultIconSize; - } - double get iconButtonFactor { - final baseIconFactor = baseButtonExtraOptions?.iconButtonFactor; - final iconButtonFactor = options.iconButtonFactor; - return iconButtonFactor ?? baseIconFactor ?? kDefaultIconButtonFactor; - } - - VoidCallback? get afterButtonPressed { - return options.afterButtonPressed ?? - baseButtonExtraOptions?.afterButtonPressed; - } - - QuillIconTheme? get iconTheme { - return options.iconTheme ?? baseButtonExtraOptions?.iconTheme; - } - - QuillToolbarBaseButtonOptions? get baseButtonExtraOptions { - return context.quillToolbarBaseButtonOptions; - } - - String get tooltip { - return options.tooltip ?? - baseButtonExtraOptions?.tooltip ?? - context.loc.insertURL; - } - - IconData get iconData { - return options.iconData ?? baseButtonExtraOptions?.iconData ?? Icons.link; - } - - Color get dialogBarrierColor { - return options.dialogBarrierColor ?? - context.quillSharedConfigurations?.dialogBarrierColor ?? - Colors.black54; + return options.iconButtonFactor ?? kDefaultIconButtonFactor; } @override Widget build(BuildContext context) { - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( options, QuillToolbarLinkStyleButton2ExtraOptions( - controller: controller, + controller: widget.controller, context: context, onPressed: () { _openLinkDialog(); - afterButtonPressed?.call(); + options.afterButtonPressed?.call(); }, ), ); } - final isToggled = QuillTextLink.isSelected(controller); + final isToggled = QuillTextLink.isSelected(widget.controller); return QuillToolbarIconButton( - tooltip: tooltip, + tooltip: options.tooltip ?? context.loc.insertURL, icon: Icon( - iconData, - size: iconSize * iconButtonFactor, - // color: isToggled - // ? iconTheme?.iconSelectedFillColor - // : iconTheme?.iconUnselectedFillColor, + options.iconData ?? Icons.link, + size: (options.iconSize ?? kDefaultIconSize) * iconButtonFactor, ), isSelected: isToggled, onPressed: _openLinkDialog, - iconTheme: iconTheme, - afterPressed: afterButtonPressed, + iconTheme: options.iconTheme, + afterPressed: options.afterButtonPressed, ); } @@ -156,21 +110,18 @@ class _QuillToolbarLinkStyleButton2State final textLink = await showDialog( context: context, - barrierColor: dialogBarrierColor, - 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, - ), + builder: (_) => 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/toolbar/buttons/link_style_button.dart b/lib/src/toolbar/buttons/link_style_button.dart index 8868c1a29..ebafe3856 100644 --- a/lib/src/toolbar/buttons/link_style_button.dart +++ b/lib/src/toolbar/buttons/link_style_button.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import '../../editor/widgets/link.dart'; -import '../../editor_toolbar_shared/quill_configurations_ext.dart'; import '../../l10n/extensions/localizations_ext.dart'; -import '../../l10n/widgets/localizations.dart'; import '../../rules/insert.dart'; import '../base_button/base_value_button.dart'; -import '../base_toolbar.dart'; + +import '../config/buttons/link_style_configurations.dart'; import '../structs/link_dialog_action.dart'; import '../theme/quill_dialog_theme.dart'; +import 'quill_icon_button.dart'; typedef QuillToolbarLinkStyleBaseButton = QuillToolbarBaseButton< QuillToolbarLinkStyleButtonOptions, @@ -64,12 +64,6 @@ class QuillToolbarLinkStyleButtonState @override IconData get defaultIconData => Icons.link; - Color get dialogBarrierColor { - return options.dialogBarrierColor ?? - context.quillSharedConfigurations?.dialogBarrierColor ?? - Colors.black54; - } - RegExp? get linkRegExp { return options.linkRegExp; } @@ -78,8 +72,7 @@ class QuillToolbarLinkStyleButtonState Widget build(BuildContext context) { final isToggled = QuillTextLink.isSelected(controller); - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( options, @@ -98,9 +91,6 @@ class QuillToolbarLinkStyleButtonState icon: Icon( iconData, size: iconSize * iconButtonFactor, - // color: isToggled - // ? iconTheme?.iconSelectedFillColor - // : iconTheme?.iconUnselectedFillColor, ), isSelected: isToggled, onPressed: () => _openLinkDialog(context), @@ -114,16 +104,13 @@ class QuillToolbarLinkStyleButtonState final textLink = await showDialog( context: context, - barrierColor: dialogBarrierColor, builder: (_) { - return FlutterQuillLocalizationsWidget( - child: _LinkDialog( - dialogTheme: options.dialogTheme, - text: initialTextLink.text, - link: initialTextLink.link, - linkRegExp: linkRegExp, - action: options.linkDialogAction, - ), + return _LinkDialog( + dialogTheme: options.dialogTheme, + text: initialTextLink.text, + link: initialTextLink.link, + linkRegExp: linkRegExp, + action: options.linkDialogAction, ); }, ); diff --git a/lib/src/toolbar/buttons/search/legacy/legacy_search_button.dart b/lib/src/toolbar/buttons/search/legacy/legacy_search_button.dart deleted file mode 100644 index 1ba6c5abe..000000000 --- a/lib/src/toolbar/buttons/search/legacy/legacy_search_button.dart +++ /dev/null @@ -1,137 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../../../controller/quill_controller.dart'; -import '../../../../editor_toolbar_shared/quill_configurations_ext.dart'; -import '../../../../l10n/extensions/localizations_ext.dart'; -import '../../../../l10n/widgets/localizations.dart'; -import '../../../base_toolbar.dart'; -import '../../../simple_toolbar_provider.dart'; -import '../../../theme/quill_dialog_theme.dart'; -import '../../../theme/quill_icon_theme.dart'; -import 'legacy_search_dialog.dart'; - -/// We suggest to see [QuillToolbarSearchButton] before using this widget. -class QuillToolbarLegacySearchButton extends StatelessWidget { - const QuillToolbarLegacySearchButton({ - required QuillController controller, - this.options = const QuillToolbarSearchButtonOptions(), - super.key, - }) : _controller = controller; - - final QuillController _controller; - final QuillToolbarSearchButtonOptions options; - - QuillController get controller { - return _controller; - } - - // TODO: The logic is common and can be extracted - - double _iconSize(BuildContext context) { - final baseFontSize = baseButtonExtraOptions(context)?.iconSize; - final iconSize = options.iconSize; - return iconSize ?? baseFontSize ?? kDefaultIconSize; - } - - double _iconButtonFactor(BuildContext context) { - final baseIconFactor = baseButtonExtraOptions(context)?.iconButtonFactor; - final iconButtonFactor = options.iconButtonFactor; - return iconButtonFactor ?? baseIconFactor ?? kDefaultIconButtonFactor; - } - - VoidCallback? _afterButtonPressed(BuildContext context) { - return options.afterButtonPressed ?? - baseButtonExtraOptions(context)?.afterButtonPressed; - } - - QuillIconTheme? _iconTheme(BuildContext context) { - return options.iconTheme ?? baseButtonExtraOptions(context)?.iconTheme; - } - - QuillToolbarBaseButtonOptions? baseButtonExtraOptions(BuildContext context) { - return context.quillToolbarBaseButtonOptions; - } - - IconData _iconData(BuildContext context) { - return options.iconData ?? - baseButtonExtraOptions(context)?.iconData ?? - Icons.search; - } - - String _tooltip(BuildContext context) { - return options.tooltip ?? - baseButtonExtraOptions(context)?.tooltip ?? - (context.loc.search); - } - - Color _dialogBarrierColor(BuildContext context) { - return options.dialogBarrierColor ?? - context.quillSharedConfigurations?.dialogBarrierColor ?? - Colors.black54; - } - - QuillDialogTheme? _dialogTheme(BuildContext context) { - return options.dialogTheme ?? - context.quillSharedConfigurations?.dialogTheme; - } - - @override - Widget build(BuildContext context) { - final iconTheme = _iconTheme(context); - final tooltip = _tooltip(context); - final iconData = _iconData(context); - final iconSize = _iconSize(context); - final iconButtonFactor = _iconButtonFactor(context); - final afterButtonPressed = _afterButtonPressed(context); - - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions(context)?.childBuilder; - - if (childBuilder != null) { - return childBuilder( - options, - QuillToolbarSearchButtonExtraOptions( - controller: controller, - context: context, - onPressed: () { - _sharedOnPressed(context); - afterButtonPressed?.call(); - }, - ), - ); - } - - return QuillToolbarIconButton( - tooltip: tooltip, - icon: Icon( - iconData, - size: iconSize * iconButtonFactor, - ), - isSelected: false, - onPressed: () => _sharedOnPressed(context), - afterPressed: afterButtonPressed, - iconTheme: iconTheme, - ); - } - - Future _sharedOnPressed(BuildContext context) async { - final customCallback = options.customOnPressedCallback; - if (customCallback != null) { - await customCallback( - controller, - ); - return; - } - await showDialog( - barrierColor: _dialogBarrierColor(context), - context: context, - builder: (_) => FlutterQuillLocalizationsWidget( - child: QuillToolbarLegacySearchDialog( - controller: controller, - dialogTheme: _dialogTheme(context), - text: '', - ), - ), - ); - } -} diff --git a/lib/src/toolbar/buttons/search/legacy/legacy_search_dialog.dart b/lib/src/toolbar/buttons/search/legacy/legacy_search_dialog.dart deleted file mode 100644 index 6ed453fb1..000000000 --- a/lib/src/toolbar/buttons/search/legacy/legacy_search_dialog.dart +++ /dev/null @@ -1,230 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../../../../translations.dart'; -import '../../../../controller/quill_controller.dart'; -import '../../../../document/document.dart'; -import '../../../theme/quill_dialog_theme.dart'; - -class QuillToolbarLegacySearchDialog extends StatefulWidget { - const QuillToolbarLegacySearchDialog({ - required this.controller, - this.dialogTheme, - this.text, - super.key, - }); - - final QuillController controller; - final QuillDialogTheme? dialogTheme; - final String? text; - - @override - QuillToolbarLegacySearchDialogState createState() => - QuillToolbarLegacySearchDialogState(); -} - -class QuillToolbarLegacySearchDialogState - extends State { - late String _text; - late TextEditingController _controller; - late List? _offsets; - late int _index; - bool _caseSensitive = false; - bool _wholeWord = false; - - @override - void initState() { - super.initState(); - _text = widget.text ?? ''; - _offsets = null; - _index = 0; - _controller = TextEditingController(text: _text); - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - var matchShown = ''; - if (_offsets != null) { - if (_offsets!.isEmpty) { - matchShown = '0/0'; - } else { - matchShown = '${_index + 1}/${_offsets!.length}'; - } - } - - return Dialog( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5), - ), - backgroundColor: widget.dialogTheme?.dialogBackgroundColor, - alignment: Alignment.bottomCenter, - insetPadding: EdgeInsets.zero, - child: FlutterQuillLocalizationsWidget( - child: Builder( - builder: (context) { - return SizedBox( - height: 45, - child: Row( - children: [ - Tooltip( - message: context.loc.caseSensitivityAndWholeWordSearch, - child: ToggleButtons( - onPressed: (index) { - if (index == 0) { - _changeCaseSensitivity(); - } else if (index == 1) { - _changeWholeWord(); - } - }, - borderRadius: const BorderRadius.all(Radius.circular(2)), - isSelected: [_caseSensitive, _wholeWord], - children: const [ - Text( - '\u0391\u03b1', - style: TextStyle( - fontFamily: 'MaterialIcons', - fontSize: 24, - ), - ), - Text( - '\u201c\u2026\u201d', - style: TextStyle( - fontFamily: 'MaterialIcons', - fontSize: 24, - ), - ), - ], - ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.only(bottom: 12, left: 5), - child: TextField( - style: widget.dialogTheme?.inputTextStyle, - decoration: InputDecoration( - isDense: true, - suffixText: (_offsets != null) ? matchShown : '', - suffixStyle: widget.dialogTheme?.labelTextStyle, - ), - autofocus: true, - onChanged: _textChanged, - textInputAction: TextInputAction.done, - keyboardType: TextInputType.text, - onEditingComplete: _findText, - controller: _controller, - ), - ), - ), - if (_offsets == null) - IconButton( - icon: const Icon(Icons.search), - tooltip: context.loc.findText, - onPressed: _findText, - ), - if (_offsets != null) - IconButton( - icon: const Icon(Icons.keyboard_arrow_up), - tooltip: context.loc.moveToPreviousOccurrence, - onPressed: - (_offsets!.isNotEmpty) ? _moveToPrevious : null, - ), - if (_offsets != null) - IconButton( - icon: const Icon(Icons.keyboard_arrow_down), - tooltip: context.loc.moveToNextOccurrence, - onPressed: (_offsets!.isNotEmpty) ? _moveToNext : null, - ), - ], - ), - ); - }, - ), - ), - ); - } - - void _findText() { - _text = _controller.text; - if (_text.isEmpty) { - return; - } - setState(() { - _offsets = widget.controller.document.search( - _text, - caseSensitive: _caseSensitive, - wholeWord: _wholeWord, - ); - _index = 0; - }); - if (_offsets!.isNotEmpty) { - _moveToPosition(); - } - } - - void _moveToPosition() { - widget.controller.updateSelection( - TextSelection( - baseOffset: _offsets![_index], - extentOffset: _offsets![_index] + _text.length, - ), - ChangeSource.local, - ); - } - - void _moveToPrevious() { - if (_offsets!.isEmpty) { - return; - } - setState(() { - if (_index > 0) { - _index -= 1; - } else { - _index = _offsets!.length - 1; - } - }); - _moveToPosition(); - } - - void _moveToNext() { - if (_offsets!.isEmpty) { - return; - } - setState(() { - if (_index < _offsets!.length - 1) { - _index += 1; - } else { - _index = 0; - } - }); - _moveToPosition(); - } - - void _textChanged(String value) { - setState(() { - _text = value; - _offsets = null; - _index = 0; - }); - } - - void _changeCaseSensitivity() { - setState(() { - _caseSensitive = !_caseSensitive; - _offsets = null; - _index = 0; - }); - } - - void _changeWholeWord() { - setState(() { - _wholeWord = !_wholeWord; - _offsets = null; - _index = 0; - }); - } -} diff --git a/lib/src/toolbar/buttons/search/search_button.dart b/lib/src/toolbar/buttons/search/search_button.dart index 05ec648a9..0494e5f22 100644 --- a/lib/src/toolbar/buttons/search/search_button.dart +++ b/lib/src/toolbar/buttons/search/search_button.dart @@ -1,87 +1,27 @@ import 'package:flutter/material.dart'; import '../../../controller/quill_controller.dart'; -import '../../../editor_toolbar_shared/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations_ext.dart'; -import '../../../l10n/widgets/localizations.dart'; -import '../../base_toolbar.dart'; -import '../../simple_toolbar_provider.dart'; -import '../../theme/quill_dialog_theme.dart'; -import '../../theme/quill_icon_theme.dart'; +import '../../simple_toolbar.dart'; class QuillToolbarSearchButton extends StatelessWidget { const QuillToolbarSearchButton({ - required QuillController controller, + required this.controller, this.options = const QuillToolbarSearchButtonOptions(), super.key, - }) : _controller = controller; + }); - final QuillController _controller; + final QuillController controller; final QuillToolbarSearchButtonOptions options; - QuillController get controller { - return _controller; - } - - // TODO: Extract the common duplicated methods - - double _iconSize(BuildContext context) { - final baseFontSize = baseButtonExtraOptions(context)?.iconSize; - final iconSize = options.iconSize; - return iconSize ?? baseFontSize ?? kDefaultIconSize; - } - - double _iconButtonFactor(BuildContext context) { - final baseIconFactor = baseButtonExtraOptions(context)?.iconButtonFactor; - final iconButtonFactor = options.iconButtonFactor; - return iconButtonFactor ?? baseIconFactor ?? kDefaultIconButtonFactor; - } - - VoidCallback? _afterButtonPressed(BuildContext context) { - return options.afterButtonPressed ?? - baseButtonExtraOptions(context)?.afterButtonPressed; - } - - QuillIconTheme? _iconTheme(BuildContext context) { - return options.iconTheme ?? baseButtonExtraOptions(context)?.iconTheme; - } - - QuillToolbarBaseButtonOptions? baseButtonExtraOptions(BuildContext context) { - return context.quillToolbarBaseButtonOptions; - } - - IconData _iconData(BuildContext context) { - return options.iconData ?? - baseButtonExtraOptions(context)?.iconData ?? - Icons.search; - } - - String _tooltip(BuildContext context) { - return options.tooltip ?? - baseButtonExtraOptions(context)?.tooltip ?? - (context.loc.search); - } - - Color _dialogBarrierColor(BuildContext context) { - return options.dialogBarrierColor ?? Colors.transparent; - } - - QuillDialogTheme? _dialogTheme(BuildContext context) { - return options.dialogTheme ?? - context.quillSharedConfigurations?.dialogTheme; - } - @override Widget build(BuildContext context) { - final iconTheme = _iconTheme(context); - final tooltip = _tooltip(context); - final iconData = _iconData(context); - final iconSize = _iconSize(context); - final iconButtonFactor = _iconButtonFactor(context); - final afterButtonPressed = _afterButtonPressed(context); + final iconSize = options.iconSize ?? kDefaultIconSize; + final iconButtonFactor = + options.iconButtonFactor ?? kDefaultIconButtonFactor; + final afterButtonPressed = options.afterButtonPressed; - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions(context)?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( @@ -98,15 +38,15 @@ class QuillToolbarSearchButton extends StatelessWidget { } return QuillToolbarIconButton( - tooltip: tooltip, + tooltip: options.tooltip ?? (context.loc.search), icon: Icon( - iconData, + options.iconData ?? Icons.search, size: iconSize * iconButtonFactor, ), isSelected: false, onPressed: () => _sharedOnPressed(context), afterPressed: afterButtonPressed, - iconTheme: iconTheme, + iconTheme: options.iconTheme, ); } @@ -119,14 +59,11 @@ class QuillToolbarSearchButton extends StatelessWidget { return; } await showDialog( - barrierColor: _dialogBarrierColor(context), context: context, - builder: (_) => FlutterQuillLocalizationsWidget( - child: QuillToolbarSearchDialog( - controller: controller, - dialogTheme: _dialogTheme(context), - searchBarAlignment: options.searchBarAlignment, - ), + builder: (_) => QuillToolbarSearchDialog( + controller: controller, + dialogTheme: options.dialogTheme, + searchBarAlignment: options.searchBarAlignment, ), ); } diff --git a/lib/src/toolbar/buttons/search/search_dialog.dart b/lib/src/toolbar/buttons/search/search_dialog.dart index dc5648d2e..eaf8e51be 100644 --- a/lib/src/toolbar/buttons/search/search_dialog.dart +++ b/lib/src/toolbar/buttons/search/search_dialog.dart @@ -7,7 +7,6 @@ import '../../../controller/quill_controller.dart'; import '../../../document/document.dart'; import '../../../document/nodes/leaf.dart'; import '../../../l10n/extensions/localizations_ext.dart'; -import '../../../l10n/widgets/localizations.dart'; import '../../theme/quill_dialog_theme.dart'; @immutable @@ -228,21 +227,17 @@ class QuillToolbarSearchDialogState extends State { backgroundColor: widget.dialogTheme?.dialogBackgroundColor, alignment: searchBarAlignment, insetPadding: EdgeInsets.zero, - child: FlutterQuillLocalizationsWidget( - child: Builder( - builder: (context) { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (_searchSettingsUnfolded && searchBarAtBottom) - searchSettings, - searchBar, - if (_searchSettingsUnfolded && !searchBarAtBottom) - searchSettings, - ], - ); - }, - ), + child: Builder( + builder: (context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (_searchSettingsUnfolded && searchBarAtBottom) searchSettings, + searchBar, + if (_searchSettingsUnfolded && !searchBarAtBottom) searchSettings, + ], + ); + }, ), ); } diff --git a/lib/src/toolbar/buttons/select_line_height_dropdown_button.dart b/lib/src/toolbar/buttons/select_line_height_dropdown_button.dart index 19f9728cd..a348537ab 100644 --- a/lib/src/toolbar/buttons/select_line_height_dropdown_button.dart +++ b/lib/src/toolbar/buttons/select_line_height_dropdown_button.dart @@ -1,12 +1,11 @@ import 'package:flutter/material.dart'; -import '../../../translations.dart'; import '../../document/attribute.dart'; +import '../../l10n/extensions/localizations_ext.dart'; import '../base_button/base_value_button.dart'; -import '../base_toolbar.dart'; import '../config/buttons/select_line_height_style_dropdown_button_configurations.dart'; -import '../simple_toolbar_provider.dart'; import '../theme/quill_icon_theme.dart'; +import 'quill_icon_button.dart'; typedef QuillToolbarSelectLineHeightStyleDropdownBaseButton = QuillToolbarBaseButton< @@ -117,9 +116,7 @@ class _QuillToolbarSelectLineHeightStyleDropdownButtonState @override Widget build(BuildContext context) { - final baseButtonConfigurations = context.quillToolbarBaseButtonOptions; - final childBuilder = - widget.options.childBuilder ?? baseButtonConfigurations?.childBuilder; + final childBuilder = widget.options.childBuilder; if (childBuilder != null) { return childBuilder( widget.options, diff --git a/lib/src/toolbar/buttons/toggle_check_list_button.dart b/lib/src/toolbar/buttons/toggle_check_list_button.dart index 77571d03a..a173fba05 100644 --- a/lib/src/toolbar/buttons/toggle_check_list_button.dart +++ b/lib/src/toolbar/buttons/toggle_check_list_button.dart @@ -5,7 +5,8 @@ import '../../document/attribute.dart'; import '../../document/style.dart'; import '../../l10n/extensions/localizations_ext.dart'; import '../base_button/base_value_button.dart'; -import '../base_toolbar.dart'; +import '../config/buttons/toggle_check_list_configurations.dart'; +import 'toggle_style_button.dart'; class QuillToolbarToggleCheckListButton extends QuillToolbarBaseButton< QuillToolbarToggleCheckListButtonOptions, @@ -57,8 +58,7 @@ class QuillToolbarToggleCheckListButtonState @override Widget build(BuildContext context) { - final childBuilder = - options.childBuilder ?? baseButtonExtraOptions?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( options, diff --git a/lib/src/toolbar/buttons/toggle_style_button.dart b/lib/src/toolbar/buttons/toggle_style_button.dart index 896c56786..53321b649 100644 --- a/lib/src/toolbar/buttons/toggle_style_button.dart +++ b/lib/src/toolbar/buttons/toggle_style_button.dart @@ -5,8 +5,7 @@ import '../../document/attribute.dart'; import '../../document/style.dart'; import '../../l10n/extensions/localizations_ext.dart'; import '../base_button/base_value_button.dart'; -import '../base_toolbar.dart'; -import '../simple_toolbar_provider.dart'; +import '../simple_toolbar.dart'; import '../theme/quill_icon_theme.dart'; typedef ToggleStyleButtonBuilder = Widget Function( @@ -103,8 +102,7 @@ class QuillToolbarToggleStyleButtonState @override Widget build(BuildContext context) { - final childBuilder = options.childBuilder ?? - context.quillToolbarBaseButtonOptions?.childBuilder; + final childBuilder = options.childBuilder; if (childBuilder != null) { return childBuilder( options, diff --git a/lib/src/toolbar/config/base_button_configurations.dart b/lib/src/toolbar/config/base_button_configurations.dart index c06255e56..b59eee777 100644 --- a/lib/src/toolbar/config/base_button_configurations.dart +++ b/lib/src/toolbar/config/base_button_configurations.dart @@ -1,23 +1,19 @@ -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; +import '../../controller/quill_controller.dart'; import '../../editor_toolbar_controller_shared/quill_configurations.dart' - show kDefaultIconSize, kDefaultIconButtonFactor; + show kDefaultIconSize; import '../theme/quill_icon_theme.dart' show QuillIconTheme; -class QuillToolbarBaseButtonExtraOptionsIsToggled extends Equatable { +class QuillToolbarBaseButtonExtraOptionsIsToggled { const QuillToolbarBaseButtonExtraOptionsIsToggled(this.isToggled); final bool isToggled; - - @override - List get props => [isToggled]; } @immutable -class QuillToolbarBaseButtonExtraOptions extends Equatable { +class QuillToolbarBaseButtonExtraOptions { const QuillToolbarBaseButtonExtraOptions({ required this.controller, required this.context, @@ -31,26 +27,17 @@ class QuillToolbarBaseButtonExtraOptions extends Equatable { final VoidCallback? onPressed; final BuildContext context; - @override - List get props => [ - controller, - ]; } /// The [T] is the options for the button, usually should refresnce itself /// it's used in [childBuilder] so the developer can customize this when using it /// The [I] is extra options for the button, usually for it's state @immutable -class QuillToolbarBaseButtonOptions extends Equatable { +class QuillToolbarBaseButtonOptions { const QuillToolbarBaseButtonOptions({ this.iconData, - @Deprecated('This will be removed in future releases, use iconSize instead') - this.globalIconSize = kDefaultIconSize, this.iconSize, this.iconButtonFactor, - @Deprecated( - 'This will be removed in future releases, use iconButtonFactor instead') - this.globalIconButtonFactor = kDefaultIconButtonFactor, this.afterButtonPressed, this.tooltip, this.iconTheme, @@ -59,26 +46,14 @@ class QuillToolbarBaseButtonOptions extends Equatable { /// By default it will use a Icon data from Icons which comes from material /// library, to change this, please pass a different value - /// If there is no Icon in this button then pass null in the child class + /// If there is no Icon in this button then pass `null` in the child class final IconData? iconData; - /// To change the 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 - @Deprecated('This will be removed in future releases, use iconSize instead') - final double globalIconSize; - /// To change the 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? iconSize; - /// The factor of how much larger the button is in relation to the icon, - /// by default it will be [kDefaultIconButtonFactor]. - @Deprecated( - 'This will be removed in future releases, use iconButtonFactor instead') - final double globalIconButtonFactor; - final double? iconButtonFactor; /// To do extra logic after pressing the button @@ -92,17 +67,6 @@ class QuillToolbarBaseButtonOptions extends Equatable { /// If you want to display a different widget based using a builder final QuillToolbarButtonOptionsChildBuilder childBuilder; - - @override - List get props => [ - iconData, - iconSize, - iconButtonFactor, - afterButtonPressed, - tooltip, - iconTheme, - childBuilder, - ]; } typedef QuillToolbarButtonOptionsChildBuilder = Widget Function( diff --git a/lib/src/toolbar/config/buttons/color_configurations.dart b/lib/src/toolbar/config/buttons/color_configurations.dart index 2b9f2b402..c6ad17867 100644 --- a/lib/src/toolbar/config/buttons/color_configurations.dart +++ b/lib/src/toolbar/config/buttons/color_configurations.dart @@ -1,8 +1,6 @@ import 'package:flutter/widgets.dart' show Color; import '../../../controller/quill_controller.dart'; -import '../../../editor_toolbar_shared/config/quill_shared_configurations.dart' - show QuillSharedConfigurations; import '../base_button_configurations.dart'; class QuillToolbarColorButtonExtraOptions @@ -26,7 +24,6 @@ class QuillToolbarColorButtonExtraOptions class QuillToolbarColorButtonOptions extends QuillToolbarBaseButtonOptions< QuillToolbarColorButtonOptions, QuillToolbarColorButtonExtraOptions> { const QuillToolbarColorButtonOptions({ - this.dialogBarrierColor, super.iconSize, super.iconButtonFactor, super.iconData, @@ -37,10 +34,6 @@ class QuillToolbarColorButtonOptions extends QuillToolbarBaseButtonOptions< this.customOnPressedCallback, }); - /// By default will use the default `dialogBarrierColor` from - /// [QuillSharedConfigurations] - final Color? dialogBarrierColor; - final QuillToolbarColorPickerOnPressedCallback? customOnPressedCallback; } diff --git a/lib/src/toolbar/config/buttons/font_size_configurations.dart b/lib/src/toolbar/config/buttons/font_size_configurations.dart index c326a5e19..2de0b42aa 100644 --- a/lib/src/toolbar/config/buttons/font_size_configurations.dart +++ b/lib/src/toolbar/config/buttons/font_size_configurations.dart @@ -1,16 +1,4 @@ -import 'dart:ui'; - -import 'package:flutter/foundation.dart' show immutable; -import 'package:flutter/material.dart' - show ButtonStyle, Colors, PopupMenuEntry, ValueChanged; -import 'package:flutter/widgets.dart' - show - Color, - EdgeInsets, - EdgeInsetsGeometry, - OutlinedBorder, - TextOverflow, - TextStyle; +import 'package:flutter/material.dart'; import '../../../document/attribute.dart'; import '../../../editor_toolbar_controller_shared/quill_configurations.dart'; @@ -42,35 +30,27 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions< super.tooltip, this.padding, this.style, - @Deprecated('No longer used') this.width, this.initialValue, this.labelOverflow = TextOverflow.visible, - this.itemHeight, - this.itemPadding, this.defaultItemColor = Colors.red, super.childBuilder, this.shape, this.defaultDisplayText, + this.width, }); final ButtonStyle? shape; - /// By default it will be [fontSizesValues] from [QuillSimpleToolbarConfigurations] - /// You can override this if you want final Map? rawItemsMap; final ValueChanged? onSelected; final Attribute attribute; final EdgeInsetsGeometry? padding; final TextStyle? style; - final double? width; final String? initialValue; final TextOverflow labelOverflow; - @Deprecated('No longer used') - final double? itemHeight; - @Deprecated('No longer used') - final EdgeInsets? itemPadding; final Color? defaultItemColor; final String? defaultDisplayText; + final double? width; QuillToolbarFontSizeButtonOptions copyWith({ double? iconSize, @@ -102,14 +82,8 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions< attribute: attribute ?? this.attribute, padding: padding ?? this.padding, style: style ?? this.style, - // ignore: deprecated_member_use_from_same_package - width: width ?? this.width, initialValue: initialValue ?? this.initialValue, labelOverflow: labelOverflow ?? this.labelOverflow, - // ignore: deprecated_member_use_from_same_package - itemHeight: itemHeight ?? this.itemHeight, - // ignore: deprecated_member_use_from_same_package - itemPadding: itemPadding ?? this.itemPadding, defaultItemColor: defaultItemColor ?? this.defaultItemColor, tooltip: tooltip ?? super.tooltip, afterButtonPressed: afterButtonPressed ?? super.afterButtonPressed, diff --git a/lib/src/toolbar/config/buttons/link_style2_configurations.dart b/lib/src/toolbar/config/buttons/link_style2_configurations.dart index 849d97a07..6a1960ef4 100644 --- a/lib/src/toolbar/config/buttons/link_style2_configurations.dart +++ b/lib/src/toolbar/config/buttons/link_style2_configurations.dart @@ -25,7 +25,6 @@ class QuillToolbarLinkStyleButton2Options extends QuillToolbarBaseButtonOptions< this.linkColor, this.validationMessage, this.buttonSize, - this.dialogBarrierColor, this.childrenSpacing = 16.0, this.autovalidateMode = AutovalidateMode.disabled, super.iconData, @@ -57,6 +56,4 @@ class QuillToolbarLinkStyleButton2Options extends QuillToolbarBaseButtonOptions< /// The size of dialog buttons. final Size? buttonSize; - - final Color? dialogBarrierColor; } diff --git a/lib/src/toolbar/config/buttons/link_style_configurations.dart b/lib/src/toolbar/config/buttons/link_style_configurations.dart index f1adc247f..01d2c0628 100644 --- a/lib/src/toolbar/config/buttons/link_style_configurations.dart +++ b/lib/src/toolbar/config/buttons/link_style_configurations.dart @@ -1,6 +1,4 @@ -import 'package:flutter/widgets.dart' show Color; - -import '../../base_toolbar.dart'; +import '../../simple_toolbar.dart'; import '../../structs/link_dialog_action.dart'; import '../../theme/quill_dialog_theme.dart'; @@ -20,11 +18,9 @@ class QuillToolbarLinkStyleButtonOptions extends QuillToolbarBaseButtonOptions< this.dialogTheme, this.linkRegExp, this.linkDialogAction, - this.dialogBarrierColor, super.iconSize, super.iconButtonFactor, super.iconData, - super.globalIconSize, super.afterButtonPressed, super.tooltip, super.iconTheme, @@ -34,5 +30,4 @@ class QuillToolbarLinkStyleButtonOptions extends QuillToolbarBaseButtonOptions< final QuillDialogTheme? dialogTheme; final RegExp? linkRegExp; final LinkDialogAction? linkDialogAction; - final Color? dialogBarrierColor; } diff --git a/lib/src/toolbar/config/buttons/search_configurations.dart b/lib/src/toolbar/config/buttons/search_configurations.dart index 6bdbfdf75..d174a53a6 100644 --- a/lib/src/toolbar/config/buttons/search_configurations.dart +++ b/lib/src/toolbar/config/buttons/search_configurations.dart @@ -11,8 +11,7 @@ class QuillToolbarSearchButtonExtraOptions }); } -class QuillToolbarSearchButtonOptions extends QuillToolbarBaseButtonOptions< - QuillToolbarBaseButtonOptions, QuillToolbarSearchButtonExtraOptions> { +class QuillToolbarSearchButtonOptions extends QuillToolbarBaseButtonOptions { const QuillToolbarSearchButtonOptions({ super.iconData, super.childBuilder, @@ -22,16 +21,12 @@ class QuillToolbarSearchButtonOptions extends QuillToolbarBaseButtonOptions< this.dialogTheme, super.iconSize, super.iconButtonFactor, - this.dialogBarrierColor, this.customOnPressedCallback, this.searchBarAlignment, }); final QuillDialogTheme? dialogTheme; - /// By default will be [dialogBarrierColor] from [QuillSharedConfigurations] - final Color? dialogBarrierColor; - /// By default we will show simple search dialog ui /// you can pass value to this callback to change this final QuillToolbarSearchButtonOnPressedCallback? customOnPressedCallback; @@ -42,20 +37,3 @@ class QuillToolbarSearchButtonOptions extends QuillToolbarBaseButtonOptions< typedef QuillToolbarSearchButtonOnPressedCallback = Future Function( QuillController controller, ); - -// typedef QuillToolbarSearchButtonFindTextCallback = List Function({ -// required int index, -// required String text, -// required QuillController controller, -// required List offsets, -// required bool wholeWord, -// required bool caseSensitive, -// bool moveToPosition, -// }); - -// typedef QuillToolbarSearchButtonMoveToPositionCallback = void Function({ -// required int index, -// required String text, -// required QuillController controller, -// required List offsets, -// }); diff --git a/lib/src/toolbar/config/buttons/select_header_style_buttons_configurations.dart b/lib/src/toolbar/config/buttons/select_header_style_buttons_configurations.dart index 6177c4cf0..b32b62d07 100644 --- a/lib/src/toolbar/config/buttons/select_header_style_buttons_configurations.dart +++ b/lib/src/toolbar/config/buttons/select_header_style_buttons_configurations.dart @@ -1,7 +1,7 @@ import 'package:flutter/widgets.dart' show Axis; import '../../../document/attribute.dart'; -import '../../base_toolbar.dart'; +import '../../simple_toolbar.dart'; class QuillToolbarSelectHeaderStyleButtonsExtraOptions extends QuillToolbarBaseButtonExtraOptions { diff --git a/lib/src/toolbar/config/buttons/select_header_style_dropdown_button_configurations.dart b/lib/src/toolbar/config/buttons/select_header_style_dropdown_button_configurations.dart index 37fc1522c..c35b53b0c 100644 --- a/lib/src/toolbar/config/buttons/select_header_style_dropdown_button_configurations.dart +++ b/lib/src/toolbar/config/buttons/select_header_style_dropdown_button_configurations.dart @@ -2,7 +2,7 @@ import 'package:flutter/widgets.dart' show IconData, TextStyle, ValueChanged, VoidCallback; import '../../../document/attribute.dart'; -import '../../base_toolbar.dart'; +import '../../simple_toolbar.dart'; import '../../theme/quill_icon_theme.dart'; class QuillToolbarSelectHeaderStyleDropdownButtonExtraOptions diff --git a/lib/src/toolbar/config/buttons/select_line_height_style_dropdown_button_configurations.dart b/lib/src/toolbar/config/buttons/select_line_height_style_dropdown_button_configurations.dart index a190dd55b..f1071e9a4 100644 --- a/lib/src/toolbar/config/buttons/select_line_height_style_dropdown_button_configurations.dart +++ b/lib/src/toolbar/config/buttons/select_line_height_style_dropdown_button_configurations.dart @@ -2,7 +2,8 @@ import 'package:flutter/widgets.dart' show IconData, TextStyle, ValueChanged, VoidCallback; import '../../../document/attribute.dart'; -import '../../base_toolbar.dart'; + +import '../../simple_toolbar.dart'; import '../../theme/quill_icon_theme.dart'; class QuillToolbarSelectLineHeightStyleDropdownButtonExtraOptions diff --git a/lib/src/toolbar/config/buttons/toggle_style_configurations.dart b/lib/src/toolbar/config/buttons/toggle_style_configurations.dart index e1c2ac78a..411c92c32 100644 --- a/lib/src/toolbar/config/buttons/toggle_style_configurations.dart +++ b/lib/src/toolbar/config/buttons/toggle_style_configurations.dart @@ -1,5 +1,6 @@ // ignore_for_file: public_member_api_docs, sort_constructors_first import 'package:flutter/foundation.dart' show immutable; +import 'package:meta/meta.dart'; import '../base_button_configurations.dart'; diff --git a/lib/src/toolbar/config/simple_toolbar_button_options.dart b/lib/src/toolbar/config/simple_toolbar_button_options.dart index 7da8da34d..6a4084a10 100644 --- a/lib/src/toolbar/config/simple_toolbar_button_options.dart +++ b/lib/src/toolbar/config/simple_toolbar_button_options.dart @@ -1,8 +1,5 @@ -// ignore_for_file: public_member_api_docs, sort_constructors_first -import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show immutable; -import 'base_button_configurations.dart'; import 'buttons/clear_format_configurations.dart'; import 'buttons/color_configurations.dart'; import 'buttons/custom_button_configurations.dart'; @@ -40,9 +37,8 @@ export 'buttons/toggle_style_configurations.dart'; /// The configurations for the buttons of the toolbar widget of flutter quill @immutable -class QuillSimpleToolbarButtonOptions extends Equatable { +class QuillSimpleToolbarButtonOptions { const QuillSimpleToolbarButtonOptions({ - this.base = const QuillToolbarBaseButtonOptions(), this.undoHistory = const QuillToolbarHistoryButtonOptions(), this.redoHistory = const QuillToolbarHistoryButtonOptions(), this.fontFamily = const QuillToolbarFontFamilyButtonOptions(), @@ -83,10 +79,6 @@ class QuillSimpleToolbarButtonOptions extends Equatable { this.clipboardPaste = const QuillToolbarToggleStyleButtonOptions(), }); - /// 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; @@ -141,9 +133,4 @@ class QuillSimpleToolbarButtonOptions extends Equatable { final QuillToolbarLinkStyleButton2Options linkStyle2; final QuillToolbarCustomButtonOptions customButtons; - - @override - List get props => [ - base, - ]; } diff --git a/lib/src/toolbar/config/simple_toolbar_configurations.dart b/lib/src/toolbar/config/simple_toolbar_configurations.dart index 1579ee695..2e7bcbec4 100644 --- a/lib/src/toolbar/config/simple_toolbar_configurations.dart +++ b/lib/src/toolbar/config/simple_toolbar_configurations.dart @@ -1,14 +1,10 @@ -import 'package:flutter/foundation.dart' show immutable; -import 'package:flutter/widgets.dart' - show Axis, WrapAlignment, WrapCrossAlignment; +import 'package:flutter/widgets.dart'; +import 'package:meta/meta.dart'; -import '../../controller/quill_controller.dart'; import '../buttons/hearder_style/select_header_style_buttons.dart'; import '../buttons/hearder_style/select_header_style_dropdown_button.dart'; import '../buttons/link_style2_button.dart'; import '../buttons/link_style_button.dart'; -import '../buttons/search/legacy/legacy_search_button.dart'; -import '../buttons/search/search_button.dart'; import '../embed/embed_button_builder.dart'; import '../theme/quill_dialog_theme.dart'; import '../theme/quill_icon_theme.dart'; @@ -68,30 +64,17 @@ enum HeaderStyleType { bool get isButtons => this == HeaderStyleType.buttons; } -enum SearchButtonType { - /// Will use [QuillToolbarSearchButton] - legacy, - - /// Will use [QuillToolbarLegacySearchButton] - modern, -} - /// The configurations for the toolbar widget of flutter quill @immutable class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { const QuillSimpleToolbarConfigurations({ - @Deprecated( - 'controller should be passed directly to the toolbar - this parameter will be removed in future versions.') - this.controller, super.sharedConfigurations, super.toolbarSectionSpacing = kToolbarSectionSpacing, super.toolbarIconAlignment = WrapAlignment.center, super.toolbarIconCrossAlignment = WrapCrossAlignment.center, super.buttonOptions = const QuillSimpleToolbarButtonOptions(), this.customButtons = const [], - this.fontFamilyValues, super.multiRowsDisplay = true, - this.fontSizesValues, this.showDividers = true, this.showFontFamily = true, this.showFontSize = true, @@ -129,7 +112,6 @@ class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { this.showClipboardPaste = true, this.linkStyleType = LinkStyleType.original, this.headerStyleType = HeaderStyleType.original, - this.searchButtonType = SearchButtonType.modern, /// The decoration to use for the toolbar. super.decoration, @@ -141,47 +123,27 @@ class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { ///The theme to use for the icons in the toolbar, uses type [QuillIconTheme] // this.iconTheme, this.dialogTheme, + this.iconTheme, super.axis = Axis.horizontal, super.color, super.sectionDividerColor, super.sectionDividerSpace, - /// 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 + /// The change only applies if [multiRowsDisplay] is `false` 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.iconSize ?? kDefaultIconSize) * 2; + return kDefaultIconSize * 2; } - final Map? fontFamilyValues; - - @Deprecated('controller will be removed in future versions.') - final QuillController? controller; - - /// By default it will be - /// ```dart - /// { - /// 'Small'.i18n: 'small', - /// 'Large'.i18n: 'large', - /// 'Huge'.i18n: 'huge', - /// 'Clear'.loc: '0' - /// } - /// ``` - final Map? fontSizesValues; - /// List of custom buttons final List customButtons; @@ -228,11 +190,10 @@ class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { /// 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; + @experimental + final QuillIconTheme? iconTheme; - ///The theme to use for the theming of the [LinkDialog()], - ///shown when embedding an image, for example + @experimental final QuillDialogTheme? dialogTheme; /// Defines which dialog is used for applying link attribute. @@ -240,16 +201,4 @@ class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { /// Defines which dialog is used for applying header attribute. final HeaderStyleType headerStyleType; - - /// Define which button type should be used for the [showSearchButton] - final SearchButtonType searchButtonType; - - @override - List get props => [ - buttonOptions, - multiRowsDisplay, - fontSizesValues, - toolbarSize, - axis, - ]; } diff --git a/lib/src/toolbar/config/toolbar_configurations.dart b/lib/src/toolbar/config/toolbar_configurations.dart deleted file mode 100644 index 42c45ffb0..000000000 --- a/lib/src/toolbar/config/toolbar_configurations.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/widgets.dart' show immutable; - -import 'simple_toolbar_button_options.dart'; -import 'toolbar_shared_configurations.dart'; - -@immutable -class QuillToolbarConfigurations extends QuillSharedToolbarProperties { - const QuillToolbarConfigurations({ - super.sharedConfigurations, - - /// Note this only used when you using the quill toolbar buttons like - /// `QuillToolbarHistoryButton` inside it - super.buttonOptions = const QuillSimpleToolbarButtonOptions(), - }); - - @override - List get props => []; -} diff --git a/lib/src/toolbar/config/toolbar_shared_configurations.dart b/lib/src/toolbar/config/toolbar_shared_configurations.dart index 6f05df51c..2165ac2d2 100644 --- a/lib/src/toolbar/config/toolbar_shared_configurations.dart +++ b/lib/src/toolbar/config/toolbar_shared_configurations.dart @@ -1,12 +1,11 @@ -import 'package:equatable/equatable.dart'; import 'package:flutter/widgets.dart' show Axis, Color, Decoration, WrapAlignment, WrapCrossAlignment; import '../../editor_toolbar_shared/config/quill_shared_configurations.dart'; -import '../base_toolbar.dart'; import '../structs/link_dialog_action.dart'; +import 'simple_toolbar_configurations.dart'; -abstract class QuillSharedToolbarProperties extends Equatable { +abstract class QuillSharedToolbarProperties { const QuillSharedToolbarProperties({ this.sharedConfigurations = const QuillSharedConfigurations(), this.toolbarSize, diff --git a/lib/src/toolbar/provider.dart b/lib/src/toolbar/provider.dart deleted file mode 100644 index 146fe174a..000000000 --- a/lib/src/toolbar/provider.dart +++ /dev/null @@ -1,74 +0,0 @@ -import 'package:flutter/foundation.dart' show debugPrint, kDebugMode; -import 'package:flutter/widgets.dart' - show BuildContext, InheritedWidget, Widget; - -import 'config/toolbar_configurations.dart'; - -class QuillToolbarProvider extends InheritedWidget { - const QuillToolbarProvider({ - required super.child, - required this.toolbarConfigurations, - super.key, - }); - - /// The configurations for the toolbar widget of flutter quill - final QuillToolbarConfigurations toolbarConfigurations; - - @override - bool updateShouldNotify(covariant QuillToolbarProvider oldWidget) { - return oldWidget.toolbarConfigurations != toolbarConfigurations; - } - - static QuillToolbarProvider? maybeOf(BuildContext context) { - /// The configurations for the quill editor widget of flutter quill - return context.dependOnInheritedWidgetOfExactType(); - } - - static QuillToolbarProvider of(BuildContext context) { - final provider = maybeOf(context); - if (provider == null) { - if (kDebugMode) { - debugPrint( - 'The quill toolbar 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 toolbar provider widget to be in the parent widget tree ' - 'because ' - 'The provider is $provider. Please make sure to wrap this widget' - ' with' - ' QuillBaseToolbarProvider widget. ' - 'You might using QuillBaseToolbar so make sure to' - ' wrap them with the quill provider widget and setup the required ' - 'configurations', - 'QuillToolbarProvider', - ); - } - return provider; - } - - /// To pass the [QuillToolbarConfigurations] instance as value - /// instead of creating new widget - static QuillToolbarProvider value({ - required QuillToolbarConfigurations value, - required Widget child, - }) { - return QuillToolbarProvider( - toolbarConfigurations: value, - child: child, - ); - } -} - -extension QuillToolbarExt on BuildContext { - /// return [QuillToolbarConfigurations] as not null - QuillToolbarConfigurations get requireQuillToolbarConfigurations { - return QuillToolbarProvider.of(this).toolbarConfigurations; - } - - /// return nullable [QuillToolbarConfigurations]. - QuillToolbarConfigurations? get quillToolbarConfigurations { - return QuillToolbarProvider.maybeOf(this)?.toolbarConfigurations; - } -} diff --git a/lib/src/toolbar/simple_toolbar.dart b/lib/src/toolbar/simple_toolbar.dart index f765e2f37..68e78b54f 100644 --- a/lib/src/toolbar/simple_toolbar.dart +++ b/lib/src/toolbar/simple_toolbar.dart @@ -2,60 +2,51 @@ import 'package:flutter/material.dart'; import '../controller/quill_controller.dart'; import '../document/attribute.dart'; -import '../document/document.dart'; -import 'base_toolbar.dart'; import 'buttons/alignment/select_alignment_buttons.dart'; import 'buttons/arrow_indicated_list_button.dart'; -import 'config/toolbar_configurations.dart'; -import 'simple_toolbar_provider.dart'; +import 'simple_toolbar.dart'; + +export 'buttons/alignment/select_alignment_button.dart'; +export 'buttons/clear_format_button.dart'; +export 'buttons/clipboard_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/hearder_style/select_header_style_buttons.dart'; +export 'buttons/hearder_style/select_header_style_dropdown_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_line_height_dropdown_button.dart'; +export 'buttons/toggle_check_list_button.dart'; +export 'buttons/toggle_style_button.dart'; +export 'config/base_button_configurations.dart'; +export 'config/simple_toolbar_configurations.dart'; class QuillSimpleToolbar extends StatelessWidget implements PreferredSizeWidget { - factory QuillSimpleToolbar({ - required QuillSimpleToolbarConfigurations? configurations, - QuillController? controller, - Key? key, - }) { - // ignore: deprecated_member_use_from_same_package - controller ??= configurations?.controller; - assert(controller != null, - 'controller required. Provide controller directly (preferred) or indirectly through configurations (not recommended - will be removed in future versions).'); - controller ??= QuillController( - document: Document(), - selection: const TextSelection.collapsed(offset: 0)); - // - controller.toolbarConfigurations = configurations; - // - return QuillSimpleToolbar._( - controller: controller, - key: key, - ); - } - - const QuillSimpleToolbar._({ + const QuillSimpleToolbar({ required this.controller, + this.configurations = const QuillSimpleToolbarConfigurations(), super.key, }); final QuillController controller; - /// The configurations for the toolbar widget of flutter quill - QuillSimpleToolbarConfigurations get configurations => - controller.toolbarConfigurations; + final QuillSimpleToolbarConfigurations configurations; double get _toolbarSize => configurations.toolbarSize * 1.4; @override Widget build(BuildContext context) { - final theEmbedButtons = configurations.embedButtons; + final embedButtons = configurations.embedButtons; List childrenBuilder(BuildContext context) { - final toolbarConfigurations = - context.requireQuillSimpleToolbarConfigurations; - - final globalIconSize = toolbarConfigurations.buttonOptions.base.iconSize; - - final axis = toolbarConfigurations.axis; + final axis = configurations.axis; final divider = SizedBox( height: _toolbarSize, @@ -70,105 +61,105 @@ class QuillSimpleToolbar extends StatelessWidget if (configurations.showUndo) QuillToolbarHistoryButton( isUndo: true, - options: toolbarConfigurations.buttonOptions.undoHistory, + options: configurations.buttonOptions.undoHistory, controller: controller, ), if (configurations.showRedo) QuillToolbarHistoryButton( isUndo: false, - options: toolbarConfigurations.buttonOptions.redoHistory, + options: configurations.buttonOptions.redoHistory, controller: controller, ), if (configurations.showFontFamily) QuillToolbarFontFamilyButton( - options: toolbarConfigurations.buttonOptions.fontFamily, + options: configurations.buttonOptions.fontFamily, controller: controller, ), if (configurations.showFontSize) QuillToolbarFontSizeButton( - options: toolbarConfigurations.buttonOptions.fontSize, + options: configurations.buttonOptions.fontSize, controller: controller, ), if (configurations.showBoldButton) QuillToolbarToggleStyleButton( attribute: Attribute.bold, - options: toolbarConfigurations.buttonOptions.bold, + options: configurations.buttonOptions.bold, controller: controller, ), if (configurations.showItalicButton) QuillToolbarToggleStyleButton( attribute: Attribute.italic, - options: toolbarConfigurations.buttonOptions.italic, + options: configurations.buttonOptions.italic, controller: controller, ), if (configurations.showUnderLineButton) QuillToolbarToggleStyleButton( attribute: Attribute.underline, - options: toolbarConfigurations.buttonOptions.underLine, + options: configurations.buttonOptions.underLine, controller: controller, ), if (configurations.showStrikeThrough) QuillToolbarToggleStyleButton( attribute: Attribute.strikeThrough, - options: toolbarConfigurations.buttonOptions.strikeThrough, + options: configurations.buttonOptions.strikeThrough, controller: controller, ), if (configurations.showInlineCode) QuillToolbarToggleStyleButton( attribute: Attribute.inlineCode, - options: toolbarConfigurations.buttonOptions.inlineCode, + options: configurations.buttonOptions.inlineCode, controller: controller, ), if (configurations.showSubscript) QuillToolbarToggleStyleButton( attribute: Attribute.subscript, - options: toolbarConfigurations.buttonOptions.subscript, + options: configurations.buttonOptions.subscript, controller: controller, ), if (configurations.showSuperscript) QuillToolbarToggleStyleButton( attribute: Attribute.superscript, - options: toolbarConfigurations.buttonOptions.superscript, + options: configurations.buttonOptions.superscript, controller: controller, ), if (configurations.showSmallButton) QuillToolbarToggleStyleButton( attribute: Attribute.small, - options: toolbarConfigurations.buttonOptions.small, + options: configurations.buttonOptions.small, controller: controller, ), if (configurations.showColorButton) QuillToolbarColorButton( controller: controller, isBackground: false, - options: toolbarConfigurations.buttonOptions.color, + options: configurations.buttonOptions.color, ), if (configurations.showBackgroundColorButton) QuillToolbarColorButton( - options: toolbarConfigurations.buttonOptions.backgroundColor, + options: configurations.buttonOptions.backgroundColor, controller: controller, isBackground: true, ), if (configurations.showClearFormat) QuillToolbarClearFormatButton( controller: controller, - options: toolbarConfigurations.buttonOptions.clearFormat, + options: configurations.buttonOptions.clearFormat, ), - if (theEmbedButtons != null) - for (final builder in theEmbedButtons) + if (embedButtons != null) + for (final builder in embedButtons) builder( - controller, - globalIconSize ?? kDefaultIconSize, - context.quillToolbarBaseButtonOptions?.iconTheme, - configurations.dialogTheme), + controller, + kDefaultIconSize, + configurations.iconTheme, + configurations.dialogTheme, + ), ], [ if (configurations.showAlignmentButtons) QuillToolbarSelectAlignmentButtons( controller: controller, - options: toolbarConfigurations - .buttonOptions.selectAlignmentButtons - .copyWith( + options: + configurations.buttonOptions.selectAlignmentButtons.copyWith( showLeftAlignment: configurations.showLeftAlignment, showCenterAlignment: configurations.showCenterAlignment, showRightAlignment: configurations.showRightAlignment, @@ -178,7 +169,7 @@ class QuillSimpleToolbar extends StatelessWidget if (configurations.showDirection) QuillToolbarToggleStyleButton( attribute: Attribute.rtl, - options: toolbarConfigurations.buttonOptions.direction, + options: configurations.buttonOptions.direction, controller: controller, ), ], @@ -186,21 +177,20 @@ class QuillSimpleToolbar extends StatelessWidget if (configurations.showLineHeightButton) QuillToolbarSelectLineHeightStyleDropdownButton( controller: controller, - options: toolbarConfigurations + options: configurations .buttonOptions.selectLineHeightStyleDropdownButton, ), if (configurations.showHeaderStyle) ...[ if (configurations.headerStyleType.isOriginal) QuillToolbarSelectHeaderStyleDropdownButton( controller: controller, - options: toolbarConfigurations + options: configurations .buttonOptions.selectHeaderStyleDropdownButton, ) else QuillToolbarSelectHeaderStyleButtons( controller: controller, - options: toolbarConfigurations - .buttonOptions.selectHeaderStyleButtons, + options: configurations.buttonOptions.selectHeaderStyleButtons, ), ], ], @@ -208,31 +198,31 @@ class QuillSimpleToolbar extends StatelessWidget if (configurations.showListNumbers) QuillToolbarToggleStyleButton( attribute: Attribute.ol, - options: toolbarConfigurations.buttonOptions.listNumbers, + options: configurations.buttonOptions.listNumbers, controller: controller, ), if (configurations.showListBullets) QuillToolbarToggleStyleButton( attribute: Attribute.ul, - options: toolbarConfigurations.buttonOptions.listBullets, + options: configurations.buttonOptions.listBullets, controller: controller, ), if (configurations.showListCheck) QuillToolbarToggleCheckListButton( - options: toolbarConfigurations.buttonOptions.toggleCheckList, + options: configurations.buttonOptions.toggleCheckList, controller: controller, ), if (configurations.showCodeBlock) QuillToolbarToggleStyleButton( attribute: Attribute.codeBlock, - options: toolbarConfigurations.buttonOptions.codeBlock, + options: configurations.buttonOptions.codeBlock, controller: controller, ), ], [ if (configurations.showQuote) QuillToolbarToggleStyleButton( - options: toolbarConfigurations.buttonOptions.quote, + options: configurations.buttonOptions.quote, controller: controller, attribute: Attribute.blockQuote, ), @@ -240,52 +230,46 @@ class QuillSimpleToolbar extends StatelessWidget QuillToolbarIndentButton( controller: controller, isIncrease: true, - options: toolbarConfigurations.buttonOptions.indentIncrease, + options: configurations.buttonOptions.indentIncrease, ), if (configurations.showIndent) QuillToolbarIndentButton( controller: controller, isIncrease: false, - options: toolbarConfigurations.buttonOptions.indentDecrease, + options: configurations.buttonOptions.indentDecrease, ), ], [ if (configurations.showLink) - toolbarConfigurations.linkStyleType.isOriginal + configurations.linkStyleType.isOriginal ? QuillToolbarLinkStyleButton( controller: controller, - options: toolbarConfigurations.buttonOptions.linkStyle, + options: configurations.buttonOptions.linkStyle, ) : QuillToolbarLinkStyleButton2( controller: controller, - options: toolbarConfigurations.buttonOptions.linkStyle2, + options: configurations.buttonOptions.linkStyle2, ), if (configurations.showSearchButton) - switch (configurations.searchButtonType) { - SearchButtonType.legacy => QuillToolbarLegacySearchButton( - controller: controller, - options: toolbarConfigurations.buttonOptions.search, - ), - SearchButtonType.modern => QuillToolbarSearchButton( - controller: controller, - options: toolbarConfigurations.buttonOptions.search, - ), - }, + QuillToolbarSearchButton( + controller: controller, + options: configurations.buttonOptions.search, + ), if (configurations.showClipboardCut) QuillToolbarClipboardButton( - options: toolbarConfigurations.buttonOptions.clipboardCut, + options: configurations.buttonOptions.clipboardCut, controller: controller, clipboardAction: ClipboardAction.cut, ), if (configurations.showClipboardCopy) QuillToolbarClipboardButton( - options: toolbarConfigurations.buttonOptions.clipboardCopy, + options: configurations.buttonOptions.clipboardCopy, controller: controller, clipboardAction: ClipboardAction.copy, ), if (configurations.showClipboardPaste) QuillToolbarClipboardButton( - options: toolbarConfigurations.buttonOptions.clipboardPaste, + options: configurations.buttonOptions.clipboardPaste, controller: controller, clipboardAction: ClipboardAction.paste, ), @@ -315,45 +299,34 @@ class QuillSimpleToolbar extends StatelessWidget return buttonsAll; } - return QuillSimpleToolbarProvider( - 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: configurations.toolbarRunSpacing, - 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 - ? _toolbarSize - : null, - width: - configurations.axis == Axis.vertical ? _toolbarSize : null, - ), - child: QuillToolbarArrowIndicatedButtonList( - axis: configurations.axis, - buttons: childrenBuilder(context), + return Builder( + builder: (context) { + if (configurations.multiRowsDisplay) { + return Wrap( + direction: configurations.axis, + alignment: configurations.toolbarIconAlignment, + crossAxisAlignment: configurations.toolbarIconCrossAlignment, + runSpacing: configurations.toolbarRunSpacing, + 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 ? _toolbarSize : null, + width: configurations.axis == Axis.vertical ? _toolbarSize : null, + ), + child: QuillToolbarArrowIndicatedButtonList( + axis: configurations.axis, + buttons: childrenBuilder(context), + ), + ); + }, ); } diff --git a/lib/src/toolbar/simple_toolbar_provider.dart b/lib/src/toolbar/simple_toolbar_provider.dart deleted file mode 100644 index ad845e8bb..000000000 --- a/lib/src/toolbar/simple_toolbar_provider.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:flutter/foundation.dart' show debugPrint, kDebugMode; -import 'package:flutter/widgets.dart' - show BuildContext, InheritedWidget, Widget; - -import 'config/simple_toolbar_configurations.dart'; - -class QuillSimpleToolbarProvider extends InheritedWidget { - const QuillSimpleToolbarProvider({ - required super.child, - required this.toolbarConfigurations, - super.key, - }); - - /// The configurations for the toolbar widget of flutter quill - final QuillSimpleToolbarConfigurations toolbarConfigurations; - - @override - bool updateShouldNotify(covariant QuillSimpleToolbarProvider oldWidget) { - return oldWidget.toolbarConfigurations != toolbarConfigurations; - } - - static QuillSimpleToolbarProvider? maybeOf(BuildContext context) { - /// The configurations for the quill editor widget of flutter quill - return context - .dependOnInheritedWidgetOfExactType(); - } - - static QuillSimpleToolbarProvider of(BuildContext context) { - final provider = maybeOf(context); - if (provider == null) { - if (kDebugMode) { - debugPrint( - 'The quill toolbar 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 toolbar provider widget to be in the parent widget tree ' - 'because ' - 'The provider is $provider. Please make sure to wrap this widget' - ' with' - ' QuillToolbarProvider widget. ' - 'You might using QuillToolbar so make sure to' - ' wrap them with the quill provider widget and setup the required ' - 'configurations', - 'QuillSimpleToolbarProvider', - ); - } - return provider; - } - - /// To pass the [QuillSimpleToolbarProvider] instance as value instead of creating - /// new widget - static QuillSimpleToolbarProvider value({ - required QuillSimpleToolbarProvider value, - required Widget child, - }) { - return QuillSimpleToolbarProvider( - toolbarConfigurations: value.toolbarConfigurations, - child: child, - ); - } -} - -extension QuillSimpleToolbarExt on BuildContext { - QuillSimpleToolbarConfigurations get requireQuillSimpleToolbarConfigurations { - return QuillSimpleToolbarProvider.of(this).toolbarConfigurations; - } - - QuillSimpleToolbarConfigurations? get quillSimpleToolbarConfigurations { - return QuillSimpleToolbarProvider.maybeOf(this)?.toolbarConfigurations; - } - - QuillToolbarBaseButtonOptions? get quillToolbarBaseButtonOptions { - return quillSimpleToolbarConfigurations?.buttonOptions.base; - } -} diff --git a/lib/src/toolbar/theme/quill_dialog_theme.dart b/lib/src/toolbar/theme/quill_dialog_theme.dart index fedf316f1..423296ba1 100644 --- a/lib/src/toolbar/theme/quill_dialog_theme.dart +++ b/lib/src/toolbar/theme/quill_dialog_theme.dart @@ -1,13 +1,5 @@ import 'package:flutter/foundation.dart' show Diagnosticable, immutable; -import 'package:flutter/material.dart' - show - BoxConstraints, - ButtonStyle, - Color, - EdgeInsets, - EdgeInsetsGeometry, - ShapeBorder, - TextStyle; +import 'package:flutter/material.dart'; /// Used to configure the dialog's look and feel. diff --git a/lib/translations.dart b/lib/translations.dart deleted file mode 100644 index fe3f03591..000000000 --- a/lib/translations.dart +++ /dev/null @@ -1,4 +0,0 @@ -library; - -export 'src/l10n/extensions/localizations_ext.dart'; -export 'src/l10n/widgets/localizations.dart'; diff --git a/test/bug_fix_test.dart b/test/bug_fix_test.dart index e1a728237..8bd56deb4 100644 --- a/test/bug_fix_test.dart +++ b/test/bug_fix_test.dart @@ -41,7 +41,7 @@ void main() { expect(builtinFinder, findsOneWidget); final customFinder = find.descendant( - of: find.byType(QuillToolbar), + of: find.byType(QuillSimpleToolbar), matching: find.byWidgetPredicate((widget) => widget is QuillToolbarIconButton && widget.tooltip == tooltip), matchRoot: true); @@ -114,7 +114,7 @@ void main() { controller.formatSelection(Attribute.unchecked); editor.focusNode.unfocus(); await tester.pump(); - await tester.tap(find.byType(QuillEditorCheckboxPoint)); + await tester.tap(find.byType(QuillCheckboxPoint)); expect(tester.takeException(), isNull); }); }); diff --git a/test/editor/editor_test.dart b/test/editor/editor_test.dart index a7843bebf..9a7d0ce57 100644 --- a/test/editor/editor_test.dart +++ b/test/editor/editor_test.dart @@ -3,7 +3,7 @@ import 'dart:convert' show jsonDecode; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/translations.dart'; +import 'package:flutter_quill/src/l10n/extensions/localizations_ext.dart'; import 'package:flutter_quill_test/flutter_quill_test.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -193,10 +193,10 @@ void main() { (tester) async { await tester.pumpWidget( MaterialApp( - home: FlutterQuillLocalizationsWidget( - child: Builder( - builder: (context) => Text(context.loc.font), - ), + localizationsDelegates: + FlutterQuillLocalizations.localizationsDelegates, + home: Builder( + builder: (context) => Text(context.loc.font), ), ), ); @@ -210,5 +210,26 @@ void main() { ); }, ); + + testWidgets( + 'should throw MissingFlutterQuillLocalizationException if the delegate is not provided', + (tester) async { + await tester.pumpWidget( + MaterialApp( + home: Builder( + builder: (context) => Text(context.loc.font), + ), + ), + ); + + final exception = tester.takeException(); + + expect(exception, isNotNull); + expect( + exception, + isA(), + ); + }, + ); }); } From 76eced49f1af0b52ed4a044b3232aff8783a01a7 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 22 Oct 2024 16:31:03 +0300 Subject: [PATCH 03/93] chore: remove SimpleSpellCheckerService from flutter_quill_extensions --- .../lib/flutter_quill_extensions.dart | 2 - .../simple_spell_checker_service.dart | 56 ------------------- 2 files changed, 58 deletions(-) delete mode 100644 flutter_quill_extensions/lib/src/editor/spell_checker/simple_spell_checker_service.dart diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index 6db9f0898..612a254fc 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -11,8 +11,6 @@ export 'src/editor/image/image_embed_types.dart'; export 'src/editor/image/image_web_embed.dart'; export 'src/editor/image/models/image_configurations.dart'; export 'src/editor/image/models/image_web_configurations.dart'; -// TODO: Remove Simple Spell Checker Service -export 'src/editor/spell_checker/simple_spell_checker_service.dart'; export 'src/editor/table/table_cell_embed.dart'; export 'src/editor/table/table_embed.dart'; export 'src/editor/table/table_models.dart'; diff --git a/flutter_quill_extensions/lib/src/editor/spell_checker/simple_spell_checker_service.dart b/flutter_quill_extensions/lib/src/editor/spell_checker/simple_spell_checker_service.dart deleted file mode 100644 index c6fbb7807..000000000 --- a/flutter_quill_extensions/lib/src/editor/spell_checker/simple_spell_checker_service.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill.dart'; - -@Deprecated( - ''' - Spell checker feature has been removed from the package to make it optional and - reduce bundle size. See issue https://github.com/singerdmx/flutter-quill/issues/2142 - for more details. - - Calling this function will not activate the feature. - - This class will be removed in future releases. - ''', -) -class SimpleSpellCheckerService extends SpellCheckerService { - SimpleSpellCheckerService({required super.language}); - - void _featureNoLongerAvailable() => throw UnimplementedError( - ''' - The spell checker feature has been removed from the package and is now optional. - See https://github.com/singerdmx/flutter-quill/issues/2142 for more details. - ''', - ); - @override - void addCustomLanguage({required Object? languageIdentifier}) => - _featureNoLongerAvailable(); - - @override - List? checkSpelling(String text, - {LongPressGestureRecognizer Function(String p1)? - customLongPressRecognizerOnWrongSpan}) { - _featureNoLongerAvailable(); - throw UnimplementedError(); - } - - @override - void dispose({bool onlyPartial = false}) => _featureNoLongerAvailable(); - - @override - bool isServiceActive() { - _featureNoLongerAvailable(); - throw UnimplementedError(); - } - - @override - void setNewLanguageState({required String language}) => - _featureNoLongerAvailable(); - - @override - void toggleChecker() => _featureNoLongerAvailable(); - - @override - void updateCustomLanguageIfExist({required Object? languageIdentifier}) => - _featureNoLongerAvailable(); -} From b437e84b138ad58419c09f4df322afbc0af9e28f Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 22 Oct 2024 17:15:25 +0300 Subject: [PATCH 04/93] chore: remove experimental support for spell checking, remove the deprecated support for YouTube in flutter_quill_extensions and other minor breaking changes --- doc/migration/10_to_11.md | 11 +- .../lib/screens/home/widgets/home_screen.dart | 7 - example/lib/screens/quill/http_url.dart | 8 + .../lib/screens/quill/my_quill_editor.dart | 9 +- .../lib/screens/quill/my_quill_toolbar.dart | 5 +- example/lib/screens/quill/quill_screen.dart | 31 +-- .../simple_spell_checker_service.dart | 70 ------- example/lib/spell_checker/spell_checker.dart | 29 --- .../lib/flutter_quill_extensions.dart | 46 ----- .../lib/src/common/image_video_utils.dart | 2 +- .../utils/element_utils/element_utils.dart | 2 +- .../lib/src/common/utils/utils.dart | 8 +- .../lib/src/editor/image/image_embed.dart | 2 +- .../lib/src/editor/image/image_menu.dart | 10 +- .../image/models/image_configurations.dart | 2 +- .../lib/src/editor/image/widgets/image.dart | 2 +- .../editor/image/widgets/image_resizer.dart | 2 +- .../video/models/video_configurations.dart | 38 ---- .../models/youtube_video_support_mode.dart | 54 ----- .../lib/src/editor/video/video_embed.dart | 21 +- .../lib/src/editor/video/video_web_embed.dart | 1 - .../src/editor/video/widgets/video_app.dart | 4 +- .../video/widgets/youtube_video_app.dart | 185 ------------------ .../lib/src/toolbar/camera/camera_button.dart | 2 +- .../toolbar/camera/select_camera_action.dart | 2 +- .../lib/src/toolbar/image/image_button.dart | 2 +- .../toolbar/image/select_image_source.dart | 3 +- .../lib/src/toolbar/table/table_button.dart | 3 +- .../toolbar/video/select_video_source.dart | 3 +- flutter_quill_extensions/pubspec.yaml | 2 - lib/flutter_quill.dart | 2 - lib/flutter_quill_internal.dart | 25 +-- lib/{extensions.dart => internal.dart} | 18 +- lib/markdown_quill.dart | 10 - .../quill_controller_configurations.dart | 17 +- lib/src/delta/delta_x.dart | 7 +- lib/src/document/document.dart | 16 +- lib/src/document/nodes/container.dart | 5 - .../editor/config/editor_configurations.dart | 18 -- .../default_spellchecker_service.dart | 46 ----- .../spellchecker/spellchecker_service.dart | 46 ----- .../spellchecker_service_provider.dart | 45 ----- lib/src/editor/widgets/text/text_line.dart | 25 +-- 43 files changed, 81 insertions(+), 765 deletions(-) create mode 100644 example/lib/screens/quill/http_url.dart delete mode 100644 example/lib/spell_checker/simple_spell_checker_service.dart delete mode 100644 example/lib/spell_checker/spell_checker.dart delete mode 100644 flutter_quill_extensions/lib/src/editor/video/models/youtube_video_support_mode.dart delete mode 100644 flutter_quill_extensions/lib/src/editor/video/widgets/youtube_video_app.dart rename lib/{extensions.dart => internal.dart} (51%) delete mode 100644 lib/markdown_quill.dart delete mode 100644 lib/src/editor/spellchecker/default_spellchecker_service.dart delete mode 100644 lib/src/editor/spellchecker/spellchecker_service.dart delete mode 100644 lib/src/editor/spellchecker/spellchecker_service_provider.dart diff --git a/doc/migration/10_to_11.md b/doc/migration/10_to_11.md index 88f0c618b..6b2fd604d 100644 --- a/doc/migration/10_to_11.md +++ b/doc/migration/10_to_11.md @@ -1,5 +1,7 @@ # Migration from 10.x.x to 11.x.x +If you're using version `10.x.x`, we recommend fixing all the deprecations before migrating to `11.x.x` for a smoother migration. + ## 1. Clipboard The `super_clipboard` plugin has been removed from `flutter_quill` and `flutter_quill_extensions`. @@ -149,6 +151,9 @@ The library `package:flutter_quill/translations.dart` has been removed and the r - The return type (`ImageProvider`) of `ImageEmbedBuilderProviderBuilder` has been made `null` so you can return `null` and fallback to our default handling. See [#2317](https://github.com/singerdmx/flutter-quill/pull/2317). - Does not handle `AssetImage` anymore by default when loading images, instead use `imageProviderBuilder` to override the default handling. See [Image assets support](https://pub.dev/packages/flutter_quill_extensions#-image-assets). - Removes `QuillSharedExtensionsConfigurations.assetsPrefix`. Use `imageProviderBuilder` to support image assets. See [Image assets support](https://pub.dev/packages/flutter_quill_extensions#-image-assets). +- Removes YouTube video support. To migrate see [CHANGELOG of 10.8.0](https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.0). See [#2284](https://github.com/singerdmx/flutter-quill/issues/2284). +- Removes the deprecated class `FlutterQuillExtensions`. +- Avoid exporting `flutter_quill_extensions/utils.dart`. ## Minor changes @@ -158,7 +163,7 @@ The library `package:flutter_quill/translations.dart` has been removed and the r - `QuillEditorBuilderWidget` and `QuillEditorConfigurations.builder` have been removed as there's no valid use-case and this can be confusing. - `QuillToolbarLegacySearchDialog` and `QuillToolbarLegacySearchButton` have been removed and replaced with `QuillToolbarSearchDialog` and `QuillToolbarSearchButton` which has been introduced in [9.4.0](https://github.com/singerdmx/flutter-quill/releases/tag/v9.4.0). `QuillSimpleToolbarConfigurations.searchButtonType` is removed too. - The property `dialog BarrierColor` has been removed from all buttons, use the `Dialog Theme` in your `ThemeData` instead to customize it. See [Override a theme](https://docs.flutter.dev/cookbook/design/themes#override-a-theme). -- The deprecated member `QuillRawEditorConfigurations.enableMarkdownStyleConversion` has been removed. See [#2214](https://github.com/singerdmx/flutter-quill/issues/2214). +- The deprecated members `QuillRawEditorConfigurations.enableMarkdownStyleConversion` and `QuillEditorConfigurations.enableMarkdownStyleConversion` has been removed. See [#2214](https://github.com/singerdmx/flutter-quill/issues/2214). - Removes `QuillSharedConfigurations.extraConfigurations`. The optional confiugration of `flutter_quill_extensions` should be separated. - Renames `QuillEditorBulletPoint` to `QuillBulletPoint`, `QuillEditorCheckboxPoint` to `QuillCheckbox`, `QuillEditorNumberPoint` to `QuillNumberPoint`. - Removes `QuillEditorElementOptions` and `QuillEditorConfigurations.elementOptions`. To customize the leading, see [#2146](https://github.com/singerdmx/flutter-quill/pull/2146) as an example. @@ -168,3 +173,7 @@ The library `package:flutter_quill/translations.dart` has been removed and the r - Removes `QuillToolbarFontSizeButton.defaultDisplayText` (deprecated for more than 10 months). - Removes `fontSizesValues` and `fontFamilyValues` from `QuillSimpleToolbarConfigurations` since those were used only in `QuillToolbarFontSizeButton` and `QuillToolbarFontFamilyButton`. Pass them to `rawItemsMap` (which exists in each button configuration) directly. - Removes `QuillSimpleToolbarButtonOptions.base` which allows having default configuration for all buttons, it didn't work correctly and involved a lot of manual checks, and is a bad design. Introduced in `8.0.0` and we don't have plans on introducing an alternative. +- Removes the deprecated library `flutter_quill/extensions.dart` since the name was confusing, it's for `flutter_quill_extensions`. +- Removes the deprecated library `flutter_quill/markdown_quill.dart`. Suggested alternatives: [markdown_quill](https://pub.dev/packages/markdown_quill) or [quill_markdown](https://pub.dev/packages/quill_markdown). +- Removes `Document.fromHtml`. Use an alternative such as [flutter_quill_delta_from_html](https://pub.dev/packages/flutter_quill_delta_from_html). +- Removes `QuillControllerConfigurations.editorConfigurations` (not being used and invalid). diff --git a/example/lib/screens/home/widgets/home_screen.dart b/example/lib/screens/home/widgets/home_screen.dart index c75a6e514..ee352cfaf 100644 --- a/example/lib/screens/home/widgets/home_screen.dart +++ b/example/lib/screens/home/widgets/home_screen.dart @@ -25,13 +25,6 @@ class HomeScreen extends StatefulWidget { } class _HomeScreenState extends State { - @override - void dispose() { - // ignore: deprecated_member_use - SpellCheckerServiceProvider.dispose(); - super.dispose(); - } - @override Widget build(BuildContext context) { return Scaffold( diff --git a/example/lib/screens/quill/http_url.dart b/example/lib/screens/quill/http_url.dart new file mode 100644 index 000000000..98f691bd6 --- /dev/null +++ b/example/lib/screens/quill/http_url.dart @@ -0,0 +1,8 @@ +bool isHttpUrl(String url) { + try { + final uri = Uri.parse(url.trim()); + return uri.isScheme('HTTP') || uri.isScheme('HTTPS'); + } catch (_) { + return false; + } +} diff --git a/example/lib/screens/quill/my_quill_editor.dart b/example/lib/screens/quill/my_quill_editor.dart index 5684c6bd7..491ae153a 100644 --- a/example/lib/screens/quill/my_quill_editor.dart +++ b/example/lib/screens/quill/my_quill_editor.dart @@ -6,12 +6,13 @@ import 'package:desktop_drop/desktop_drop.dart' show DropTarget; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/flutter_quill_internal.dart'; +import 'package:flutter_quill/internal.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; import 'package:path/path.dart' as path; import '../../extensions/scaffold_messenger.dart'; import 'embeds/timestamp_embed.dart'; +import 'http_url.dart'; class MyQuillEditor extends StatelessWidget { const MyQuillEditor({ @@ -111,7 +112,7 @@ class MyQuillEditor extends StatelessWidget { // We will use it only if image from network if (isAndroidApp || isIosApp || kIsWeb) { - if (isHttpBasedUrl(imageUrl)) { + if (isHttpUrl(imageUrl)) { return CachedNetworkImageProvider( imageUrl, ); @@ -130,10 +131,12 @@ class MyQuillEditor extends StatelessWidget { // Example: Check for YouTube Video URL and return your // YouTube video widget here. + // See https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.0 + // and https://github.com/singerdmx/flutter-quill/pull/2286 + // Otherwise return null to fallback to the defualt logic return null; }, - ignoreYouTubeSupport: true, ), )), TimeStampEmbedBuilderWidget(), diff --git a/example/lib/screens/quill/my_quill_toolbar.dart b/example/lib/screens/quill/my_quill_toolbar.dart index d72a239be..b3f137c79 100644 --- a/example/lib/screens/quill/my_quill_toolbar.dart +++ b/example/lib/screens/quill/my_quill_toolbar.dart @@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/flutter_quill_internal.dart'; +import 'package:flutter_quill/internal.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:image_cropper/image_cropper.dart'; @@ -14,6 +14,7 @@ import 'package:path_provider/path_provider.dart' import '../settings/cubit/settings_cubit.dart'; import 'embeds/timestamp_embed.dart'; +import 'http_url.dart'; class MyQuillToolbar extends StatelessWidget { const MyQuillToolbar({ @@ -75,7 +76,7 @@ class MyQuillToolbar extends StatelessWidget { } Future onImageInsert(String image, QuillController controller) async { - if (kIsWeb || isHttpBasedUrl(image)) { + if (kIsWeb || isHttpUrl(image)) { controller.insertImageBlock(imageSource: image); return; } diff --git a/example/lib/screens/quill/quill_screen.dart b/example/lib/screens/quill/quill_screen.dart index 03b38bbe0..fce8700ed 100644 --- a/example/lib/screens/quill/quill_screen.dart +++ b/example/lib/screens/quill/quill_screen.dart @@ -7,7 +7,6 @@ import 'package:flutter_quill_extensions/flutter_quill_extensions.dart' import 'package:share_plus/share_plus.dart' show Share; import '../../extensions/scaffold_messenger.dart'; -import '../../spell_checker/spell_checker.dart'; import '../shared/widgets/home_screen_button.dart'; import 'my_quill_editor.dart'; import 'my_quill_toolbar.dart'; @@ -38,8 +37,6 @@ class _QuillScreenState extends State { final _controller = QuillController.basic(); final _editorFocusNode = FocusNode(); final _editorScrollController = ScrollController(); - var _isReadOnly = false; - var _isSpellcheckerActive = false; @override void initState() { @@ -57,31 +54,10 @@ class _QuillScreenState extends State { @override Widget build(BuildContext context) { - _controller.readOnly = _isReadOnly; - if (!_isSpellcheckerActive) { - _isSpellcheckerActive = true; - SpellChecker.useSpellCheckerService( - Localizations.localeOf(context).languageCode); - } return Scaffold( appBar: AppBar( title: const Text('Flutter Quill'), actions: [ - IconButton( - tooltip: 'Spell-checker', - onPressed: () { - // ignore: deprecated_member_use - SpellCheckerServiceProvider.toggleState(); - setState(() {}); - }, - icon: Icon( - Icons.document_scanner, - // ignore: deprecated_member_use - color: SpellCheckerServiceProvider.isServiceActive() - ? Colors.red.withOpacity(0.5) - : null, - ), - ), IconButton( tooltip: 'Share', onPressed: () { @@ -115,7 +91,7 @@ class _QuillScreenState extends State { ), body: Column( children: [ - if (!_isReadOnly) + if (!_controller.readOnly) MyQuillToolbar( controller: _controller, focusNode: _editorFocusNode, @@ -142,8 +118,9 @@ class _QuillScreenState extends State { ], ), floatingActionButton: FloatingActionButton( - child: Icon(!_isReadOnly ? Icons.lock : Icons.edit), - onPressed: () => setState(() => _isReadOnly = !_isReadOnly), + child: Icon(!_controller.readOnly ? Icons.lock : Icons.edit), + onPressed: () => + setState(() => _controller.readOnly = !_controller.readOnly), ), ); } diff --git a/example/lib/spell_checker/simple_spell_checker_service.dart b/example/lib/spell_checker/simple_spell_checker_service.dart deleted file mode 100644 index 26c109e11..000000000 --- a/example/lib/spell_checker/simple_spell_checker_service.dart +++ /dev/null @@ -1,70 +0,0 @@ -import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill.dart'; -import 'package:simple_spell_checker/simple_spell_checker.dart'; - -/// SimpleSpellChecker is a simple spell checker for get -/// all words divide on different objects if them are wrong or not. -/// -/// **Important**: A breaking change is planned and this shouldn't be used -/// for new applications. A replacement will arrive soon. -/// See: https://github.com/singerdmx/flutter-quill/issues/2246 -class SimpleSpellCheckerService - // ignore: deprecated_member_use - extends SpellCheckerService { - SimpleSpellCheckerService({required super.language}) - : checker = SimpleSpellChecker( - language: language, - safeDictionaryLoad: true, - ); - - /// [SimpleSpellChecker] comes from the package [simple_spell_checker] - /// that give us all necessary methods for get our spans with highlighting - /// where needed - final SimpleSpellChecker checker; - - @override - List? checkSpelling( - String text, { - LongPressGestureRecognizer Function(String word)? - customLongPressRecognizerOnWrongSpan, - }) { - return checker.check( - text, - customLongPressRecognizerOnWrongSpan: - customLongPressRecognizerOnWrongSpan, - ); - } - - @override - void toggleChecker() => checker.toggleChecker(); - - @override - bool isServiceActive() => checker.isCheckerActive(); - - @override - void dispose({bool onlyPartial = false}) { - if (onlyPartial) { - checker.disposeControllers(); - return; - } - checker.dispose(); - } - - @override - void addCustomLanguage({required languageIdentifier}) { - checker - ..registerLanguage(languageIdentifier.language) - ..addCustomLanguage(languageIdentifier); - } - - @override - void setNewLanguageState({required String language}) { - checker.setNewLanguageToState(language); - } - - @override - void updateCustomLanguageIfExist({required languageIdentifier}) { - checker.updateCustomLanguageIfExist(languageIdentifier); - } -} diff --git a/example/lib/spell_checker/spell_checker.dart b/example/lib/spell_checker/spell_checker.dart deleted file mode 100644 index df9eea350..000000000 --- a/example/lib/spell_checker/spell_checker.dart +++ /dev/null @@ -1,29 +0,0 @@ -// ignore_for_file: deprecated_member_use - -import 'package:flutter_quill/flutter_quill.dart'; - -import 'simple_spell_checker_service.dart'; - -class SpellChecker { - SpellChecker._(); - - /// override the default implementation of [SpellCheckerServiceProvider] - /// to allow a `flutter quill` support a better check spelling - /// - /// # !WARNING - /// To avoid memory leaks, ensure to use [dispose()] method to - /// close stream controllers that used by this custom implementation - /// when them no longer needed - /// - /// Example: - /// - ///```dart - ///// set partial true if you only need to close the controllers - ///SpellCheckerServiceProvider.dispose(onlyPartial: false); - ///``` - static void useSpellCheckerService(String language) { - SpellCheckerServiceProvider.setNewCheckerService( - SimpleSpellCheckerService(language: language), - ); - } -} diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index 612a254fc..1d48c7f59 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -1,11 +1,6 @@ library; -import 'package:flutter_quill/flutter_quill_internal.dart' - show ClipboardServiceProvider; -import 'package:meta/meta.dart' show experimental; - export 'src/common/extensions/controller_ext.dart'; -export 'src/common/utils/utils.dart'; export 'src/editor/image/image_embed.dart'; export 'src/editor/image/image_embed_types.dart'; export 'src/editor/image/image_web_embed.dart'; @@ -16,7 +11,6 @@ export 'src/editor/table/table_embed.dart'; export 'src/editor/table/table_models.dart'; export 'src/editor/video/models/video_configurations.dart'; export 'src/editor/video/models/video_web_configurations.dart'; -export 'src/editor/video/models/youtube_video_support_mode.dart'; export 'src/editor/video/video_embed.dart'; export 'src/editor/video/video_web_embed.dart'; export 'src/flutter_quill_embeds.dart'; @@ -32,43 +26,3 @@ export 'src/toolbar/table/table_button.dart'; export 'src/toolbar/video/models/video.dart'; export 'src/toolbar/video/models/video_configurations.dart'; export 'src/toolbar/video/video_button.dart'; - -@Deprecated( - 'Should not be used as will removed soon in future releases.', -) -@experimental -class FlutterQuillExtensions { - FlutterQuillExtensions._(); - - @Deprecated( - ''' - Spell checker feature has been removed from the package to make it optional and - reduce bundle size. See issue https://github.com/singerdmx/flutter-quill/issues/2142 - for more details. - - Calling this function will no longer activate the feature. - ''', - ) - @experimental - static void useSpellCheckerService(String language) { - // This feature has been removed from the package. - // See https://github.com/singerdmx/flutter-quill/issues/2142 - } - - /// Override default implementation of [ClipboardServiceProvider.instance] - /// to allow `flutter_quill` package to use `super_clipboard` plugin - /// to support rich text features, gif and images. - @Deprecated( - 'The functionality of super_clipboard is now built-in in recent versions of flutter_quill.\n' - 'To migrate, remove this function call and see ' - 'https://pub.dev/packages/quill_native_bridge#-platform-configuration (optional for copying images on Android) to use quill_native_bridge implementation (the new default).\n' - 'Or if you want to use super_clipboard implementation (support might discontinued in newer versions), use the experimental package: https://pub.dev/packages/quill_super_clipboard\n' - 'See https://github.com/singerdmx/flutter-quill/pull/2230 for more details.', - ) - @experimental - static void useSuperClipboardPlugin() { - throw UnimplementedError( - 'The super_clipboard plugin is no longer a dependency. See the deprecation message of FlutterQuillExtensions.useSuperClipboardPlugin()', - ); - } -} diff --git a/flutter_quill_extensions/lib/src/common/image_video_utils.dart b/flutter_quill_extensions/lib/src/common/image_video_utils.dart index 319eb3118..216566586 100644 --- a/flutter_quill_extensions/lib/src/common/image_video_utils.dart +++ b/flutter_quill_extensions/lib/src/common/image_video_utils.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart' show QuillDialogTheme; -import 'package:flutter_quill/flutter_quill_internal.dart'; +import 'package:flutter_quill/internal.dart'; import 'utils/patterns.dart'; diff --git a/flutter_quill_extensions/lib/src/common/utils/element_utils/element_utils.dart b/flutter_quill_extensions/lib/src/common/utils/element_utils/element_utils.dart index a350f288e..86a95f461 100644 --- a/flutter_quill_extensions/lib/src/common/utils/element_utils/element_utils.dart +++ b/flutter_quill_extensions/lib/src/common/utils/element_utils/element_utils.dart @@ -1,7 +1,7 @@ import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' show Alignment, BuildContext; import 'package:flutter_quill/flutter_quill.dart' show Attribute, Node; -import 'package:flutter_quill/flutter_quill_internal.dart'; +import 'package:flutter_quill/internal.dart'; import 'element_shared_utils.dart'; diff --git a/flutter_quill_extensions/lib/src/common/utils/utils.dart b/flutter_quill_extensions/lib/src/common/utils/utils.dart index bfb342f73..ab13830d7 100644 --- a/flutter_quill_extensions/lib/src/common/utils/utils.dart +++ b/flutter_quill_extensions/lib/src/common/utils/utils.dart @@ -11,7 +11,7 @@ bool isBase64(String str) { return base64RegExp.hasMatch(str); } -bool isHttpBasedUrl(String url) { +bool isHttpUrl(String url) { try { final uri = Uri.parse(url.trim()); return uri.isScheme('HTTP') || uri.isScheme('HTTPS'); @@ -21,13 +21,9 @@ bool isHttpBasedUrl(String url) { } bool isImageBase64(String imageUrl) { - return !isHttpBasedUrl(imageUrl) && isBase64(imageUrl); + return !isHttpUrl(imageUrl) && isBase64(imageUrl); } -@Deprecated( - 'Will be removed in future releases. See https://github.com/singerdmx/flutter-quill/issues/2284' - ' and https://github.com/singerdmx/flutter-quill/issues/2276', -) bool isYouTubeUrl(String videoUrl) { try { final uri = Uri.parse(videoUrl); diff --git a/flutter_quill_extensions/lib/src/editor/image/image_embed.dart b/flutter_quill_extensions/lib/src/editor/image/image_embed.dart index 0ede8c970..7a7086f9f 100644 --- a/flutter_quill_extensions/lib/src/editor/image/image_embed.dart +++ b/flutter_quill_extensions/lib/src/editor/image/image_embed.dart @@ -60,7 +60,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { configurations: configurations, imageSource: imageSource, imageSize: imageSize, - isReadOnly: readOnly, + readOnly: readOnly, imageProvider: imageWidget.image, ), ); diff --git a/flutter_quill_extensions/lib/src/editor/image/image_menu.dart b/flutter_quill_extensions/lib/src/editor/image/image_menu.dart index 61d86e31b..32b177813 100644 --- a/flutter_quill_extensions/lib/src/editor/image/image_menu.dart +++ b/flutter_quill_extensions/lib/src/editor/image/image_menu.dart @@ -6,7 +6,7 @@ import 'package:flutter/foundation.dart' show kIsWeb, Uint8List; import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart' show ImageUrl, QuillController, StyleAttribute, getEmbedNode; -import 'package:flutter_quill/flutter_quill_internal.dart'; +import 'package:flutter_quill/internal.dart'; import '../../common/utils/element_utils/element_utils.dart'; import '../../common/utils/string.dart'; @@ -21,7 +21,7 @@ class ImageOptionsMenu extends StatelessWidget { required this.configurations, required this.imageSource, required this.imageSize, - required this.isReadOnly, + required this.readOnly, required this.imageProvider, super.key, }); @@ -30,7 +30,7 @@ class ImageOptionsMenu extends StatelessWidget { final QuillEditorImageEmbedConfigurations configurations; final String imageSource; final ElementSize imageSize; - final bool isReadOnly; + final bool readOnly; final ImageProvider imageProvider; @override @@ -41,7 +41,7 @@ class ImageOptionsMenu extends StatelessWidget { child: SimpleDialog( title: Text(context.loc.image), children: [ - if (!isReadOnly) + if (!readOnly) ListTile( title: Text(context.loc.resize), leading: const Icon(Icons.settings_outlined), @@ -96,7 +96,7 @@ class ImageOptionsMenu extends StatelessWidget { } }, ), - if (!isReadOnly) + if (!readOnly) ListTile( leading: Icon( Icons.delete_forever_outlined, diff --git a/flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart b/flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart index 193732336..9d30f9c80 100644 --- a/flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart +++ b/flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart @@ -1,7 +1,7 @@ import 'dart:io' show File; import 'package:flutter/foundation.dart'; -import 'package:flutter_quill/flutter_quill_internal.dart'; +import 'package:flutter_quill/internal.dart'; import '../image_embed_types.dart'; diff --git a/flutter_quill_extensions/lib/src/editor/image/widgets/image.dart b/flutter_quill_extensions/lib/src/editor/image/widgets/image.dart index 147110386..543102c22 100644 --- a/flutter_quill_extensions/lib/src/editor/image/widgets/image.dart +++ b/flutter_quill_extensions/lib/src/editor/image/widgets/image.dart @@ -39,7 +39,7 @@ ImageProvider getImageProviderByImageSource( return MemoryImage(base64.decode(imageSource)); } - if (isHttpBasedUrl(imageSource)) { + if (isHttpUrl(imageSource)) { return NetworkImage(imageSource); } diff --git a/flutter_quill_extensions/lib/src/editor/image/widgets/image_resizer.dart b/flutter_quill_extensions/lib/src/editor/image/widgets/image_resizer.dart index 009e1aa9a..a8d2609b0 100644 --- a/flutter_quill_extensions/lib/src/editor/image/widgets/image_resizer.dart +++ b/flutter_quill_extensions/lib/src/editor/image/widgets/image_resizer.dart @@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart' show defaultTargetPlatform; import 'package:flutter/material.dart' show Slider, Card; import 'package:flutter/scheduler.dart' show SchedulerBinding; import 'package:flutter/widgets.dart'; -import 'package:flutter_quill/flutter_quill_internal.dart'; +import 'package:flutter_quill/internal.dart'; class ImageResizer extends StatefulWidget { const ImageResizer({ diff --git a/flutter_quill_extensions/lib/src/editor/video/models/video_configurations.dart b/flutter_quill_extensions/lib/src/editor/video/models/video_configurations.dart index ba1ac23c7..08b1cf3a2 100644 --- a/flutter_quill_extensions/lib/src/editor/video/models/video_configurations.dart +++ b/flutter_quill_extensions/lib/src/editor/video/models/video_configurations.dart @@ -1,21 +1,10 @@ import 'package:flutter/widgets.dart' show GlobalKey, Widget; import 'package:meta/meta.dart' show experimental, immutable; -import 'youtube_video_support_mode.dart'; - @immutable class QuillEditorVideoEmbedConfigurations { const QuillEditorVideoEmbedConfigurations({ this.onVideoInit, - @Deprecated( - 'Loading youtube videos is no longer built-in feature of flutter_quill_extensions.\n' - 'See https://github.com/singerdmx/flutter-quill/issues/2284.\n' - 'Try to use the experimental `customVideoBuilder` property to implement\n' - 'your own YouTube logic using packages such as ' - 'https://pub.dev/packages/youtube_video_player or https://pub.dev/packages/youtube_player_flutter', - ) - this.youtubeVideoSupportMode = YoutubeVideoSupportMode.disabled, - this.ignoreYouTubeSupport = false, this.customVideoBuilder, }); @@ -34,33 +23,6 @@ class QuillEditorVideoEmbedConfigurations { /// ``` final void Function(GlobalKey videoContainerKey)? onVideoInit; - /// Specifies how YouTube videos should be loaded if the video URL - /// is YouTube video. - @Deprecated( - 'Loading youtube videos is no longer built-in feature of flutter_quill_extensions.\n' - 'See https://github.com/singerdmx/flutter-quill/issues/2284.\n' - 'Try to use the experimental `customVideoBuilder` property to implement\n' - 'your own YouTube logic using packages such as ' - 'https://pub.dev/packages/youtube_video_player or https://pub.dev/packages/youtube_player_flutter', - ) - final YoutubeVideoSupportMode youtubeVideoSupportMode; - - /// Pass `true` to ignore anything related to YouTube which will disable - /// This functionality is without any warnings. - /// - /// Making it `true`, means that the video embed widget will no longer - /// check for the video URL and expect it a valid and a standrad video URL. - /// - /// This property will be removed in future releases once YouTube support is - /// removed. - /// - /// Use [customVideoBuilder] to load youtube videos. - @experimental - @Deprecated( - 'Will be removed in future releases. Exist to allow users to ignore warnings.', - ) - final bool ignoreYouTubeSupport; - /// [customVideoBuilder] is a callback function that receives the /// video URL and a read-only flag. This allows users to define /// their own logic for rendering video widgets, enabling support diff --git a/flutter_quill_extensions/lib/src/editor/video/models/youtube_video_support_mode.dart b/flutter_quill_extensions/lib/src/editor/video/models/youtube_video_support_mode.dart deleted file mode 100644 index 0884c6741..000000000 --- a/flutter_quill_extensions/lib/src/editor/video/models/youtube_video_support_mode.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:meta/meta.dart'; - -/// **Will be removed soon in future releases**. -@experimental -@Deprecated( - 'YouTube video support will be removed soon and completely in the next releases.', -) -enum YoutubeVideoSupportMode { - /// **Will be removed soon in future releases**. - /// Disable loading of YouTube videos. - /// **Will be removed soon in future releases**. - @Deprecated('Loading YouTube videos is already disabled by default.') - disabled, - - /// **Will be removed soon in future releases**. - /// - /// Load the video using the official YouTube IFrame API. - /// See [YouTube IFrame API](https://developers.google.com/youtube/iframe_api_reference) for more details. - /// - /// This will use Platform View on native platforms to use WebView - /// The WebView might not be supported on Desktop and will throw an exception - /// - /// See [Flutter InAppWebview Support for Flutter Desktop](https://github.com/pichillilorenzo/flutter_inappwebview/issues/460) - /// - /// **Important**: We had to remove [flutter_inappwebview](https://pub.dev/packages/flutter_inappwebview) - /// and [youtube_player_flutter](https://pub.dev/packages/youtube_player_flutter) - /// as non breaking change since most users are unable to build the project, - /// preventing them from using - /// - /// **Will be removed soon in future releases**. - @Deprecated( - 'This functionality has been removed to fix build failure issues. See https://github.com/singerdmx/flutter-quill/issues/2284 for discussion.', - ) - iframeView, - - /// **Will be removed soon in future releases**. - /// - /// Load the video using a custom video player by fetching the YouTube video URL. - /// Note: This might violate YouTube's terms of service. - /// See [YouTube Terms of Service](https://www.youtube.com/static?template=terms) for more details. - /// - /// **WARNING**: We highly suggest to not use this solution, - /// can cause issues with YouTube Terms of Service and require a extra dependency for all users. - /// YouTube servers can reject requests and respond with `Sign in to confirm you’re not a bot` - /// See related issue: https://github.com/Hexer10/youtube_explode_dart/issues/282 - /// - /// **Will be removed soon in future releases**. - @Deprecated( - 'Can cause issues with YouTube Terms of Service and require a extra dependency for all users - Will be removed soon.\n' - 'YouTube servers can reject requests and respond with "Sign in to confirm you’re not a bot"\n' - 'See related issue https://github.com/Hexer10/youtube_explode_dart/issues/282\n', - ) - customPlayerWithDownloadUrl, -} diff --git a/flutter_quill_extensions/lib/src/editor/video/video_embed.dart b/flutter_quill_extensions/lib/src/editor/video/video_embed.dart index f387febd6..e11bb8741 100644 --- a/flutter_quill_extensions/lib/src/editor/video/video_embed.dart +++ b/flutter_quill_extensions/lib/src/editor/video/video_embed.dart @@ -6,7 +6,6 @@ import '../../common/utils/element_utils/element_utils.dart'; import '../../common/utils/utils.dart'; import 'models/video_configurations.dart'; import 'widgets/video_app.dart'; -import 'widgets/youtube_video_app.dart'; class QuillEditorVideoEmbedBuilder extends EmbedBuilder { const QuillEditorVideoEmbedBuilder({ @@ -42,9 +41,8 @@ class QuillEditorVideoEmbedBuilder extends EmbedBuilder { } } - // ignore: deprecated_member_use_from_same_package - if (isYouTubeUrl(videoUrl) && !configurations.ignoreYouTubeSupport) { - assert(() { + assert(() { + if (isYouTubeUrl(videoUrl)) { debugPrint( "It seems that you're loading a youtube video URL.\n" 'Loading YouTube videos is no longer built-in feature as part of flutter_quill_extensions.\n' @@ -52,19 +50,10 @@ class QuillEditorVideoEmbedBuilder extends EmbedBuilder { 'Consider using the experimental property `QuillEditorVideoEmbedConfigurations.customVideoBuilder` in your configuration.\n' 'This message will only included in development mode.\n', ); - return true; - }()); - - /// Will be removed soon in future releases + } + return true; + }()); - // ignore: deprecated_member_use_from_same_package - return YoutubeVideoApp( - videoUrl: videoUrl, - readOnly: readOnly, - // ignore: deprecated_member_use_from_same_package - youtubeVideoSupportMode: configurations.youtubeVideoSupportMode, - ); - } final ((elementSize), margin, alignment) = getElementAttributes( node, context, diff --git a/flutter_quill_extensions/lib/src/editor/video/video_web_embed.dart b/flutter_quill_extensions/lib/src/editor/video/video_web_embed.dart index 0b27755b2..893fffa01 100644 --- a/flutter_quill_extensions/lib/src/editor/video/video_web_embed.dart +++ b/flutter_quill_extensions/lib/src/editor/video/video_web_embed.dart @@ -33,7 +33,6 @@ class QuillEditorWebVideoEmbedBuilder extends EmbedBuilder { TextStyle textStyle, ) { var videoUrl = node.value.data; - // ignore: deprecated_member_use_from_same_package if (isYouTubeUrl(videoUrl)) { // ignore: deprecated_member_use_from_same_package final youtubeID = convertVideoUrlToId(videoUrl); diff --git a/flutter_quill_extensions/lib/src/editor/video/widgets/video_app.dart b/flutter_quill_extensions/lib/src/editor/video/widgets/video_app.dart index bd02df6a4..c224f1be9 100644 --- a/flutter_quill_extensions/lib/src/editor/video/widgets/video_app.dart +++ b/flutter_quill_extensions/lib/src/editor/video/widgets/video_app.dart @@ -6,7 +6,7 @@ import 'package:flutter_quill/flutter_quill.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:video_player/video_player.dart'; -import '../../../../flutter_quill_extensions.dart'; +import '../../../common/utils/utils.dart'; /// Widget for playing back video /// Refer to https://github.com/flutter/plugins/tree/master/packages/video_player/video_player @@ -38,7 +38,7 @@ class VideoAppState extends State { void initState() { super.initState(); - _controller = isHttpBasedUrl(widget.videoUrl) + _controller = isHttpUrl(widget.videoUrl) ? VideoPlayerController.networkUrl(Uri.parse(widget.videoUrl)) : VideoPlayerController.file(File(widget.videoUrl)) ..initialize().then((_) { diff --git a/flutter_quill_extensions/lib/src/editor/video/widgets/youtube_video_app.dart b/flutter_quill_extensions/lib/src/editor/video/widgets/youtube_video_app.dart deleted file mode 100644 index 503aea5fd..000000000 --- a/flutter_quill_extensions/lib/src/editor/video/widgets/youtube_video_app.dart +++ /dev/null @@ -1,185 +0,0 @@ -import 'package:flutter/gestures.dart' show TapGestureRecognizer; -import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill.dart' show DefaultStyles; -import 'package:url_launcher/url_launcher_string.dart'; -import 'package:youtube_explode_dart/youtube_explode_dart.dart'; - -import '../models/youtube_video_support_mode.dart'; -import '../youtube_video_url.dart'; -import 'video_app.dart'; - -/// **Will be removed soon in future releases**. -@Deprecated( - 'Will be removed in future releases. See https://github.com/singerdmx/flutter-quill/issues/2284', -) -class YoutubeVideoApp extends StatefulWidget { - const YoutubeVideoApp({ - required this.videoUrl, - required this.readOnly, - required this.youtubeVideoSupportMode, - super.key, - }); - - final String videoUrl; - final bool readOnly; - final YoutubeVideoSupportMode youtubeVideoSupportMode; - - @override - YoutubeVideoAppState createState() => YoutubeVideoAppState(); -} - -// ignore: deprecated_member_use_from_same_package -class YoutubeVideoAppState extends State { - /// On some platforms such as desktop, Webview is not supported yet - /// as a result the youtube video player package is not supported too - /// this future will be not null and fetch the video url to load it using - /// [VideoApp] - Future? _loadYoutubeVideoByDownloadUrlFuture; - - /// Null if the video URL is not a YouTube video - String? get _videoId { - // ignore: deprecated_member_use_from_same_package - return convertVideoUrlToId(widget.videoUrl); - } - - @override - void initState() { - super.initState(); - final videoId = _videoId; - if (videoId == null) { - return; - } - switch (widget.youtubeVideoSupportMode) { - // ignore: deprecated_member_use_from_same_package - case YoutubeVideoSupportMode.disabled: - break; - // ignore: deprecated_member_use_from_same_package - case YoutubeVideoSupportMode.iframeView: - assert(() { - debugPrint( - 'Youtube Iframe is no longer supported on non-web platforms.\n' - 'See https://github.com/singerdmx/flutter-quill/issues/2284\n' - 'This message will only included in development mode.\n', - ); - return true; - }()); - break; - // ignore: deprecated_member_use_from_same_package - case YoutubeVideoSupportMode.customPlayerWithDownloadUrl: - _loadYoutubeVideoByDownloadUrlFuture = - _loadYoutubeVideoWithVideoPlayerByVideoUrl(); - break; - } - } - - Future _loadYoutubeVideoWithVideoPlayerByVideoUrl() async { - final youtubeExplode = YoutubeExplode(); - final manifest = - await youtubeExplode.videos.streamsClient.getManifest(_videoId); - final streamInfo = manifest.muxed.withHighestBitrate(); - final videoDownloadUri = streamInfo.url; - return videoDownloadUri.toString(); - } - - Widget _clickableVideoLinkText({required DefaultStyles defaultStyles}) { - return RichText( - text: TextSpan( - text: widget.videoUrl, - style: defaultStyles.link, - recognizer: TapGestureRecognizer() - ..onTap = () => launchUrlString(widget.videoUrl), - ), - ); - } - - @override - Widget build(BuildContext context) { - assert(() { - debugPrint( - "WARNING: It seems that you're using YoutubeVideoApp widget from flutter_quill_extensions " - 'which will be removed in future releases and will cause many issues.\n' - 'Use `customVideoBuilder` in the configuration class of `QuillEditorVideoEmbedConfigurations`.\n' - 'This message is only shown in development mode.\n' - 'Refer to https://github.com/singerdmx/flutter-quill/issues/2284 if you need help.', - ); - return true; - }()); - final defaultStyles = DefaultStyles.getInstance(context); - - switch (widget.youtubeVideoSupportMode) { - // ignore: deprecated_member_use_from_same_package - case YoutubeVideoSupportMode.disabled: - // Don't remove this assert, it's required to ensure - // a smoother migration for users, will be only included in development mode - assert(() { - debugPrint( - 'Loading Youtube Videos has been disabled in recent versions of flutter_quill_extensions.\n' - 'See https://github.com/singerdmx/flutter-quill/issues/2284.\n' - 'We highly suggest to use the experimental property `QuillEditorVideoEmbedConfigurations.customVideoBuilder`\n' - 'in your configuration to handle YouTube video support.\n' - 'This message will only included in development mode.\n', - ); - throw UnsupportedError( - 'Loading YouTube videos is no longer supported in flutter_quill_extensions.' - 'Take a look at the debug console for more details.\n' - 'Refer to https://github.com/singerdmx/flutter-quill/issues/2284 if you need help.\n' - 'This error will only happen in development mode, in production will return a clickable video link text.\n', - ); - }()); - return _clickableVideoLinkText(defaultStyles: defaultStyles); - // ignore: deprecated_member_use_from_same_package - case YoutubeVideoSupportMode.iframeView: - if (widget.readOnly) { - return _clickableVideoLinkText(defaultStyles: defaultStyles); - } - - return RichText( - text: TextSpan(text: widget.videoUrl, style: defaultStyles.link), - ); - // ignore: deprecated_member_use_from_same_package - case YoutubeVideoSupportMode.customPlayerWithDownloadUrl: - assert( - _loadYoutubeVideoByDownloadUrlFuture != null, - 'The load youtube video future should not null for "${widget.youtubeVideoSupportMode}" mode', - ); - assert(() { - debugPrint( - 'WARNING: Using the YouTube video download URL can violate their terms of service.\n' - 'This is already documented in customPlayerWithDownloadUrl option.\n' - 'See https://github.com/singerdmx/flutter-quill/issues/2284.\n' - 'We suggest to use the experimental property `QuillEditorVideoEmbedConfigurations.customVideoBuilder`\n' - 'in your configuration to handle YouTube video support.\n' - 'This message will only included in development mode.\n', - ); - debugPrint( - 'WARNING: Using customPlayerWithDownloadUrl might not work anymore ' - 'as YouTube servers can reject requests and respond with "Sign in to confirm you’re not a bot"\n' - 'See https://github.com/Hexer10/youtube_explode_dart/issues/282\n' - 'This message will only included in development mode.\n', - ); - throw UnsupportedError( - 'Loading YouTube videos is no longer supported in flutter_quill_extensions.' - 'Take a look at the debug console for more details.\n' - 'Refer to https://github.com/singerdmx/flutter-quill/issues/2284 if you need help.\n' - 'This error will only happen in development mode, in producation, YouTube servers will respond with "Sign in to confirm you’re not a bot".\n', - ); - }()); - - return FutureBuilder( - future: _loadYoutubeVideoByDownloadUrlFuture, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const Center(child: CircularProgressIndicator.adaptive()); - } - if (snapshot.hasError) { - return _clickableVideoLinkText(defaultStyles: defaultStyles); - } - return VideoApp( - videoUrl: snapshot.requireData, - readOnly: widget.readOnly, - ); - }, - ); - } - } -} diff --git a/flutter_quill_extensions/lib/src/toolbar/camera/camera_button.dart b/flutter_quill_extensions/lib/src/toolbar/camera/camera_button.dart index eafa3e0b2..ff98cf197 100644 --- a/flutter_quill_extensions/lib/src/toolbar/camera/camera_button.dart +++ b/flutter_quill_extensions/lib/src/toolbar/camera/camera_button.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/flutter_quill_internal.dart'; +import 'package:flutter_quill/internal.dart'; import 'package:image_picker/image_picker.dart'; import 'camera_types.dart'; diff --git a/flutter_quill_extensions/lib/src/toolbar/camera/select_camera_action.dart b/flutter_quill_extensions/lib/src/toolbar/camera/select_camera_action.dart index b18e11695..2c0c3f84b 100644 --- a/flutter_quill_extensions/lib/src/toolbar/camera/select_camera_action.dart +++ b/flutter_quill_extensions/lib/src/toolbar/camera/select_camera_action.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill_internal.dart'; +import 'package:flutter_quill/internal.dart'; import 'camera_types.dart'; diff --git a/flutter_quill_extensions/lib/src/toolbar/image/image_button.dart b/flutter_quill_extensions/lib/src/toolbar/image/image_button.dart index fba7c28a5..129e3f121 100644 --- a/flutter_quill_extensions/lib/src/toolbar/image/image_button.dart +++ b/flutter_quill_extensions/lib/src/toolbar/image/image_button.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/flutter_quill_internal.dart'; +import 'package:flutter_quill/internal.dart'; import 'package:image_picker/image_picker.dart'; import '../../common/image_video_utils.dart'; diff --git a/flutter_quill_extensions/lib/src/toolbar/image/select_image_source.dart b/flutter_quill_extensions/lib/src/toolbar/image/select_image_source.dart index 8a389edb7..80f846a28 100644 --- a/flutter_quill_extensions/lib/src/toolbar/image/select_image_source.dart +++ b/flutter_quill_extensions/lib/src/toolbar/image/select_image_source.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill_internal.dart' - show LocalizationsExt, isDesktopApp; +import 'package:flutter_quill/internal.dart'; import '../../editor/image/image_embed_types.dart'; diff --git a/flutter_quill_extensions/lib/src/toolbar/table/table_button.dart b/flutter_quill_extensions/lib/src/toolbar/table/table_button.dart index 5a1dc33e1..5fb1c137d 100644 --- a/flutter_quill_extensions/lib/src/toolbar/table/table_button.dart +++ b/flutter_quill_extensions/lib/src/toolbar/table/table_button.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/flutter_quill_internal.dart'; +import 'package:flutter_quill/internal.dart'; + import 'package:meta/meta.dart'; import '../../common/utils/quill_table_utils.dart'; diff --git a/flutter_quill_extensions/lib/src/toolbar/video/select_video_source.dart b/flutter_quill_extensions/lib/src/toolbar/video/select_video_source.dart index e14475c63..30b648be3 100644 --- a/flutter_quill_extensions/lib/src/toolbar/video/select_video_source.dart +++ b/flutter_quill_extensions/lib/src/toolbar/video/select_video_source.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill_internal.dart' - show LocalizationsExt, isDesktopApp; +import 'package:flutter_quill/internal.dart'; import 'models/video.dart'; diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 7f77691ff..6d54c2d82 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -37,8 +37,6 @@ dependencies: flutter_quill: ^10.8.3 photo_view: ^0.15.0 - # TODO: Remove youtube_explode_dart - youtube_explode_dart: ^2.2.1 # Plugins video_player: ^2.8.1 diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index 48b95434c..eb4bf1050 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -24,8 +24,6 @@ export 'src/editor/raw_editor/config/raw_editor_configurations.dart'; export 'src/editor/raw_editor/quill_single_child_scroll_view.dart'; export 'src/editor/raw_editor/raw_editor.dart'; export 'src/editor/raw_editor/raw_editor_state.dart'; -export 'src/editor/spellchecker/spellchecker_service.dart'; -export 'src/editor/spellchecker/spellchecker_service_provider.dart'; export 'src/editor/style_widgets/style_widgets.dart'; export 'src/editor/widgets/cursor.dart'; export 'src/editor/widgets/default_styles.dart'; diff --git a/lib/flutter_quill_internal.dart b/lib/flutter_quill_internal.dart index 61ab7dc2f..dbefe67b4 100644 --- a/lib/flutter_quill_internal.dart +++ b/lib/flutter_quill_internal.dart @@ -1,24 +1,7 @@ -// WARNING: This file is for internal use for flutter_quill_extensions -// and other related packages. Breaking changes -// can be introduced in minor versions. +// TODO: (11.0.0) remove this file once publish a new version of flutter_quill, +// then update quill_super_clipboard and flutter_quill_extensions before the remove -@experimental +@Deprecated('Use internal.dart instead of flutter_quill_internal.dart') library; -// This file contains exports that are meant to be used -// internally and are not part of the public API as -// breaking changes can happen. - -import 'package:meta/meta.dart' show experimental; - -export 'src/common/utils/platform.dart'; -export 'src/common/utils/string.dart'; -export 'src/common/utils/widgets.dart'; -export 'src/document/nodes/leaf.dart'; -export 'src/editor_toolbar_controller_shared/clipboard/clipboard_service.dart'; -export 'src/editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; -export 'src/l10n/extensions/localizations_ext.dart'; -export 'src/rules/delete.dart'; -export 'src/rules/format.dart'; -export 'src/rules/insert.dart'; -export 'src/rules/rule.dart'; +export 'internal.dart'; diff --git a/lib/extensions.dart b/lib/internal.dart similarity index 51% rename from lib/extensions.dart rename to lib/internal.dart index 9b5596b03..ff99bced5 100644 --- a/lib/extensions.dart +++ b/lib/internal.dart @@ -1,13 +1,14 @@ -@Deprecated( - 'The extensions.dart file was primarily intended for flutter_quill_extensions ' - 'to expose certain internal APIs and should not be used directly, as it is subject to breaking changes.\n' - 'The replacement is flutter_quill_internal.dart which is also for internal use only.', -) +/// This library contains exports that are meant to be used +/// internally and are not part of the public API as +/// breaking changes can happen. +/// +/// WARNING: This file is for internal use for related packages. +/// Breaking changes can be introduced in minor versions. +/// +@experimental library; -// This file contains exports that are meant to be used -// internally and are not part of the public API as -// breaking changes can happen +import 'package:meta/meta.dart' show experimental; export 'src/common/utils/platform.dart'; export 'src/common/utils/string.dart'; @@ -15,6 +16,7 @@ export 'src/common/utils/widgets.dart'; export 'src/document/nodes/leaf.dart'; export 'src/editor_toolbar_controller_shared/clipboard/clipboard_service.dart'; export 'src/editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; +export 'src/l10n/extensions/localizations_ext.dart'; export 'src/rules/delete.dart'; export 'src/rules/format.dart'; export 'src/rules/insert.dart'; diff --git a/lib/markdown_quill.dart b/lib/markdown_quill.dart deleted file mode 100644 index 326b5d542..000000000 --- a/lib/markdown_quill.dart +++ /dev/null @@ -1,10 +0,0 @@ -@Deprecated( - 'markdown_quill is no longer part of public API and will be removed in future releases.' - 'See https://pub.dev/packages/markdown_quill or ' - 'https://pub.dev/packages/quill_markdown as alternatives.', -) -library; - -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/controller/quill_controller_configurations.dart b/lib/src/controller/quill_controller_configurations.dart index 3f0926fd1..9faae07d1 100644 --- a/lib/src/controller/quill_controller_configurations.dart +++ b/lib/src/controller/quill_controller_configurations.dart @@ -1,17 +1,8 @@ -import '../editor/config/editor_configurations.dart' - show QuillEditorConfigurations; - class QuillControllerConfigurations { - const QuillControllerConfigurations( - {@Deprecated( - 'This parameter is not used and will be removed in future versions.') - this.editorConfigurations, - this.onClipboardPaste, - this.requireScriptFontFeatures = false}); - - @Deprecated( - 'This parameter is not used and will be removed in future versions.') - final QuillEditorConfigurations? editorConfigurations; + const QuillControllerConfigurations({ + this.onClipboardPaste, + this.requireScriptFontFeatures = false, + }); /// Callback when the user pastes and data has not already been processed /// diff --git a/lib/src/delta/delta_x.dart b/lib/src/delta/delta_x.dart index 45da51bee..beb4c4ebe 100644 --- a/lib/src/delta/delta_x.dart +++ b/lib/src/delta/delta_x.dart @@ -1,17 +1,12 @@ -import 'package:flutter/foundation.dart' show immutable; import 'package:flutter_quill_delta_from_html/flutter_quill_delta_from_html.dart'; import 'package:markdown/markdown.dart' as md; import 'package:meta/meta.dart' show experimental; -// ignore: deprecated_member_use_from_same_package -import '../../markdown_quill.dart'; import '../../quill_delta.dart'; +import '../packages/quill_markdown/markdown_to_delta.dart'; -@immutable @experimental class DeltaX { - const DeltaX._(); - /// Convert Markdown text to [Delta] /// /// This api is **experimental** and designed to be used **internally** and shouldn't diff --git a/lib/src/document/document.dart b/lib/src/document/document.dart index 063c099e3..2c08318a3 100644 --- a/lib/src/document/document.dart +++ b/lib/src/document/document.dart @@ -1,11 +1,9 @@ import 'dart:async' show StreamController; -import 'package:meta/meta.dart' show experimental; - import '../../quill_delta.dart'; import '../common/structs/offset_value.dart'; import '../common/structs/segment_leaf_node.dart'; -import '../delta/delta_x.dart'; + import '../editor/config/editor_configurations.dart'; import '../editor/config/search_configurations.dart'; import '../editor/embed/embed_editor_builder.dart'; @@ -547,18 +545,6 @@ class Document { delta.first.data == '\n' && delta.first.key == 'insert'; } - - /// Convert the HTML Raw string to [Document] - @experimental - @Deprecated( - ''' - The experimental support for HTML conversion has been dropped and will be removed in future releases, - consider using alternatives such as https://pub.dev/packages/flutter_quill_delta_from_html - ''', - ) - static Document fromHtml(String html) { - return Document.fromDelta(DeltaX.fromHtml(html)); - } } /// Source of a [Change]. diff --git a/lib/src/document/nodes/container.dart b/lib/src/document/nodes/container.dart index acc2f8d59..72cce56fc 100644 --- a/lib/src/document/nodes/container.dart +++ b/lib/src/document/nodes/container.dart @@ -6,11 +6,6 @@ import 'leaf.dart'; import 'line.dart'; import 'node.dart'; -@Deprecated('Please use QuillContainer instead') - -/// For backward compatibility -abstract base class Container extends QuillContainer {} - /// Container can accommodate other nodes. /// /// Delegates insert, retain and delete operations to children nodes. For each diff --git a/lib/src/editor/config/editor_configurations.dart b/lib/src/editor/config/editor_configurations.dart index d27bd0aa5..904777d05 100644 --- a/lib/src/editor/config/editor_configurations.dart +++ b/lib/src/editor/config/editor_configurations.dart @@ -55,9 +55,6 @@ class QuillEditorConfigurations { this.onSingleLongTapStart, this.onSingleLongTapMoveUpdate, this.onSingleLongTapEnd, - @Deprecated( - 'Use space/char shortcut events instead - enableMarkdownStyleConversion will be removed in future releases.') - this.enableMarkdownStyleConversion = true, this.enableAlwaysIndentOnTab = false, this.embedBuilders, this.unknownEmbedBuilder, @@ -172,17 +169,6 @@ class QuillEditorConfigurations { final bool scrollable; final double scrollBottomInset; - /// Configuration to enable or disable automatic Markdown style conversions. - /// - /// This setting controls the behavior of input. Specifically, when enabled, - /// entering '1.' followed by a space or '-' followed by a space - /// will automatically convert the input into a Markdown list format. - /// - /// ## !This functionality now does not work because was replaced by a more advanced using [SpaceShortcutEvent] and [CharacterShortcutEvent] classes - @Deprecated( - 'enableMarkdownStyleConversion is no longer used and will be removed in future releases. Use space/char shortcut events instead.') - final bool enableMarkdownStyleConversion; - /// Enables always indenting when the TAB key is pressed. /// /// When set to true, pressing the TAB key will always insert an indentation @@ -506,10 +492,6 @@ class QuillEditorConfigurations { characterShortcutEvents ?? this.characterShortcutEvents, spaceShortcutEvents: spaceShortcutEvents ?? this.spaceShortcutEvents, padding: padding ?? this.padding, - // ignore: deprecated_member_use_from_same_package - enableMarkdownStyleConversion: - // ignore: deprecated_member_use_from_same_package - enableMarkdownStyleConversion ?? this.enableMarkdownStyleConversion, enableAlwaysIndentOnTab: enableAlwaysIndentOnTab ?? this.enableAlwaysIndentOnTab, autoFocus: autoFocus ?? this.autoFocus, diff --git a/lib/src/editor/spellchecker/default_spellchecker_service.dart b/lib/src/editor/spellchecker/default_spellchecker_service.dart deleted file mode 100644 index 79ec19c0a..000000000 --- a/lib/src/editor/spellchecker/default_spellchecker_service.dart +++ /dev/null @@ -1,46 +0,0 @@ -// ignore_for_file: deprecated_member_use_from_same_package - -import 'package:flutter/gestures.dart' show LongPressGestureRecognizer; -import 'package:flutter/material.dart' show TextSpan; -import 'package:meta/meta.dart'; -import 'spellchecker_service.dart' show SpellCheckerService; - -/// A default implementation of the [SpellcheckerService] -/// that always will return null since Spell checking -/// is not a standard feature -@Deprecated( - 'A breaking change is being planned for the SpellCheckerService and SpellCheckerServiceProvider.\n' - "A replacement doesn't exist yet but should arrive soon." - 'See https://github.com/singerdmx/flutter-quill/issues/2246 for more details.', -) -@experimental -class DefaultSpellCheckerService extends SpellCheckerService { - DefaultSpellCheckerService() : super(language: 'en'); - - @override - void dispose({bool onlyPartial = false}) {} - - @override - List? checkSpelling( - String text, { - LongPressGestureRecognizer Function(String p1)? - customLongPressRecognizerOnWrongSpan, - }) { - return null; - } - - @override - void addCustomLanguage({languageIdentifier}) {} - - @override - void setNewLanguageState({required String language}) {} - - @override - void updateCustomLanguageIfExist({languageIdentifier}) {} - - @override - bool isServiceActive() => false; - - @override - void toggleChecker() {} -} diff --git a/lib/src/editor/spellchecker/spellchecker_service.dart b/lib/src/editor/spellchecker/spellchecker_service.dart deleted file mode 100644 index 41b34678f..000000000 --- a/lib/src/editor/spellchecker/spellchecker_service.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; -import 'package:meta/meta.dart'; - -/// A representation a custom SpellCheckService. -@Deprecated( - 'A breaking change is being planned for the SpellCheckerService.\n' - "A replacement doesn't exist yet but should arrive soon." - 'See https://github.com/singerdmx/flutter-quill/issues/2246 for more details.', -) -@experimental -abstract class SpellCheckerService { - SpellCheckerService({required this.language}); - - final String language; - - /// Decide if the service should be activate or deactivate - /// without dispose the service - void toggleChecker(); - - bool isServiceActive(); - - /// dispose all the resources used for SpellcheckerService - /// - /// if [onlyPartial] is true just dispose a part of the SpellcheckerService - /// (this comes from the implementation) - /// - /// if [onlyPartial] is false dispose all resources - void dispose({bool onlyPartial = false}); - - /// set a new language state used for SpellcheckerService - void setNewLanguageState({required String language}); - - /// set a new language state used for SpellcheckerService - void updateCustomLanguageIfExist({required T languageIdentifier}); - - /// set a new custom language for SpellcheckerService - void addCustomLanguage({required T languageIdentifier}); - - /// Facilitates a spell check request. - /// - /// Returns a [List] with all misspelled words divide from the right words. - List? checkSpelling(String text, - {LongPressGestureRecognizer Function(String)? - customLongPressRecognizerOnWrongSpan}); -} diff --git a/lib/src/editor/spellchecker/spellchecker_service_provider.dart b/lib/src/editor/spellchecker/spellchecker_service_provider.dart deleted file mode 100644 index 47e80182d..000000000 --- a/lib/src/editor/spellchecker/spellchecker_service_provider.dart +++ /dev/null @@ -1,45 +0,0 @@ -// ignore_for_file: deprecated_member_use_from_same_package - -import 'package:flutter/foundation.dart' show immutable; -import 'package:meta/meta.dart' show experimental; -import 'default_spellchecker_service.dart'; -import 'spellchecker_service.dart'; - -@immutable -@Deprecated( - 'A breaking change is being planned for the SpellCheckerService and SpellCheckerServiceProvider.\n' - "A replacement doesn't exist yet but should arrive soon." - 'See https://github.com/singerdmx/flutter-quill/issues/2246 for more details.', -) -@experimental -class SpellCheckerServiceProvider { - const SpellCheckerServiceProvider._(); - static SpellCheckerService _instance = DefaultSpellCheckerService(); - - static SpellCheckerService get instance => _instance; - - static void setNewCheckerService(SpellCheckerService service) { - _instance = service; - } - - static void dispose({bool onlyPartial = false}) { - _instance.dispose(onlyPartial: onlyPartial); - } - - static void toggleState() { - _instance.toggleChecker(); - } - - static bool isServiceActive() { - return _instance.isServiceActive(); - } - - static void setNewLanguageState({required String language}) { - assert(language.isNotEmpty); - _instance.setNewLanguageState(language: language); - } - - static void turnOffService() { - _instance = DefaultSpellCheckerService(); - } -} diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index a47d6f0e4..4ec06f9fc 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -2,12 +2,10 @@ import 'dart:collection'; import 'dart:math' as math; import 'package:flutter/foundation.dart' show kIsWeb; -import 'package:flutter/gestures.dart' - show GestureRecognizer, LongPressGestureRecognizer, TapGestureRecognizer; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart' - show BoxParentData, PipelineOwner, BoxHitTestResult, RenderObjectVisitor; -import 'package:flutter/services.dart' show ClipboardData, Clipboard; +import 'package:flutter/rendering.dart'; +import 'package:flutter/services.dart'; import 'package:url_launcher/url_launcher_string.dart' show launchUrlString; import '../../../../flutter_quill.dart'; @@ -477,23 +475,6 @@ class _TextLineState extends State { } } - if (!isLink && - !widget.readOnly && - !widget.line.style.attributes.containsKey('code-block') && - !widget.line.style.attributes.containsKey('placeholder') && - !isPlaceholderLine) { - // ignore: deprecated_member_use_from_same_package - final service = SpellCheckerServiceProvider.instance; - final spellcheckedSpans = service.checkSpelling(textNode.value); - if (spellcheckedSpans != null && spellcheckedSpans.isNotEmpty) { - return TextSpan( - children: spellcheckedSpans, - style: style, - mouseCursor: null, - ); - } - } - final recognizer = _getRecognizer(node, isLink); return TextSpan( text: textNode.value, From a0ae1425ae0f947406e4e8d14ce8347230ae308a Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 22 Oct 2024 17:48:35 +0300 Subject: [PATCH 05/93] chore(deps): remove equatable --- README.md | 2 +- lib/src/document/attribute.dart | 7 +------ .../editor/config/editor_configurations.dart | 6 ++++-- .../events/character_shortcuts_events.dart | 18 ++++++++++++++---- .../raw_editor/config/events/events.dart | 5 +++++ .../config/events/space_shortcut_events.dart | 15 ++++++++++++--- .../config/raw_editor_configurations.dart | 9 +-------- .../config/quill_shared_configurations.dart | 10 +--------- pubspec.yaml | 1 - test/bug_fix_test.dart | 2 ++ test/editor/editor_test.dart | 4 +++- 11 files changed, 44 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 15f24c131..88b80e454 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ Create the file `your_project/android/app/src/main/res/xml/file_paths.xml` with > [!NOTE] > Starting with Flutter Quill `10.8.4`, [super_clipboard](https://pub.dev/packages/super_clipboard) is no longer required in `flutter_quill` or `flutter_quill_extensions`. -> The new default is an internal plugin, [`quill_native_bridge`](https://pub.dev/packages/quill_native_bridge). +> The new default is an internal plugin [`quill_native_bridge`](https://pub.dev/packages/quill_native_bridge). > If you want to continue using `super_clipboard`, you can use the [quill_super_clipboard](https://pub.dev/packages/quill_super_clipboard) package (support may be discontinued). ## 🚀 Usage diff --git a/lib/src/document/attribute.dart b/lib/src/document/attribute.dart index 458bb9e22..d0fa32c0e 100644 --- a/lib/src/document/attribute.dart +++ b/lib/src/document/attribute.dart @@ -1,6 +1,5 @@ import 'dart:collection' show LinkedHashSet, LinkedHashMap; -import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show immutable; import 'package:quiver/core.dart'; @@ -15,7 +14,7 @@ enum AttributeScope { } @immutable -class Attribute extends Equatable { +class Attribute { const Attribute( this.key, this.scope, @@ -287,7 +286,6 @@ class Attribute extends Equatable { value == typedOther.value; } - // This might not needed anymore because of equatable @override int get hashCode => hash3(key, scope, value); @@ -295,9 +293,6 @@ class Attribute extends Equatable { String toString() { return 'Attribute{key: $key, scope: $scope, value: $value}'; } - - @override - List get props => [key, scope, value]; } class BoldAttribute extends Attribute { diff --git a/lib/src/editor/config/editor_configurations.dart b/lib/src/editor/config/editor_configurations.dart index 904777d05..ae4e8cf20 100644 --- a/lib/src/editor/config/editor_configurations.dart +++ b/lib/src/editor/config/editor_configurations.dart @@ -29,8 +29,8 @@ class QuillEditorConfigurations { this.sharedConfigurations = const QuillSharedConfigurations(), this.scrollable = true, this.padding = EdgeInsets.zero, - this.characterShortcutEvents = const [], - this.spaceShortcutEvents = const [], + @experimental this.characterShortcutEvents = const [], + @experimental this.spaceShortcutEvents = const [], this.autoFocus = false, this.expands = false, this.placeholder, @@ -116,6 +116,7 @@ class QuillEditorConfigurations { /// handler: (controller) {...your implementation} ///); ///``` + @experimental final List characterShortcutEvents; /// Contains all the events that will be handled when @@ -138,6 +139,7 @@ class QuillEditorConfigurations { /// handler: (QuillText textNode, controller) {...your implementation} ///); ///``` + @experimental final List spaceShortcutEvents; /// Override [readOnly] for checkbox. diff --git a/lib/src/editor/raw_editor/config/events/character_shortcuts_events.dart b/lib/src/editor/raw_editor/config/events/character_shortcuts_events.dart index 538e4ecee..d2d097a49 100644 --- a/lib/src/editor/raw_editor/config/events/character_shortcuts_events.dart +++ b/lib/src/editor/raw_editor/config/events/character_shortcuts_events.dart @@ -1,14 +1,14 @@ -import 'package:equatable/equatable.dart'; import 'package:meta/meta.dart'; -import '../../../../../flutter_quill.dart'; +import '../../../../controller/quill_controller.dart' show QuillController; typedef CharacterShortcutEventHandler = bool Function( QuillController controller); /// Defines the implementation of shortcut event based on character. @immutable -class CharacterShortcutEvent extends Equatable { +@experimental +class CharacterShortcutEvent { const CharacterShortcutEvent({ required this.key, required this.character, @@ -41,5 +41,15 @@ class CharacterShortcutEvent extends Equatable { 'CharacterShortcutEvent(key: $key, character: $character, handler: $handler)'; @override - List get props => [key, character, handler]; + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is CharacterShortcutEvent && + other.key == key && + other.character == character && + other.handler == handler; + } + + @override + int get hashCode => key.hashCode ^ character.hashCode ^ handler.hashCode; } diff --git a/lib/src/editor/raw_editor/config/events/events.dart b/lib/src/editor/raw_editor/config/events/events.dart index 2e534e0fc..20c77f452 100644 --- a/lib/src/editor/raw_editor/config/events/events.dart +++ b/lib/src/editor/raw_editor/config/events/events.dart @@ -1,3 +1,8 @@ +@experimental +library; + +import 'package:meta/meta.dart'; + // event classes export 'character_shortcuts_events.dart'; export 'space_shortcut_events.dart'; diff --git a/lib/src/editor/raw_editor/config/events/space_shortcut_events.dart b/lib/src/editor/raw_editor/config/events/space_shortcut_events.dart index 68def2c1e..639dcd439 100644 --- a/lib/src/editor/raw_editor/config/events/space_shortcut_events.dart +++ b/lib/src/editor/raw_editor/config/events/space_shortcut_events.dart @@ -1,4 +1,3 @@ -import 'package:equatable/equatable.dart'; import 'package:meta/meta.dart'; import '../../../../controller/quill_controller.dart'; import '../../../../document/nodes/leaf.dart'; @@ -8,7 +7,8 @@ typedef SpaceShortcutEventHandler = bool Function( /// Defines the implementation of shortcut events for space key calls. @immutable -class SpaceShortcutEvent extends Equatable { +@experimental +class SpaceShortcutEvent { SpaceShortcutEvent({ required this.character, required this.handler, @@ -37,5 +37,14 @@ class SpaceShortcutEvent extends Equatable { 'SpaceShortcutEvent(character: $character, handler: $handler)'; @override - List get props => [character, handler]; + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is SpaceShortcutEvent && + other.character == character && + other.handler == handler; + } + + @override + int get hashCode => character.hashCode ^ handler.hashCode; } diff --git a/lib/src/editor/raw_editor/config/raw_editor_configurations.dart b/lib/src/editor/raw_editor/config/raw_editor_configurations.dart index 0de64a99a..e854ebea0 100644 --- a/lib/src/editor/raw_editor/config/raw_editor_configurations.dart +++ b/lib/src/editor/raw_editor/config/raw_editor_configurations.dart @@ -1,4 +1,3 @@ -import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show Brightness, Uint8List, immutable; import 'package:flutter/material.dart'; @@ -14,7 +13,7 @@ import '../builders/leading_block_builder.dart'; import 'events/events.dart'; @immutable -class QuillRawEditorConfigurations extends Equatable { +class QuillRawEditorConfigurations { const QuillRawEditorConfigurations({ required this.focusNode, required this.scrollController, @@ -374,10 +373,4 @@ class QuillRawEditorConfigurations extends Equatable { /// Called when a text input action is performed. final void Function(TextInputAction action)? onPerformAction; - - @override - List get props => [ - readOnly, - placeholder, - ]; } diff --git a/lib/src/editor_toolbar_shared/config/quill_shared_configurations.dart b/lib/src/editor_toolbar_shared/config/quill_shared_configurations.dart index 173461a81..94117f46e 100644 --- a/lib/src/editor_toolbar_shared/config/quill_shared_configurations.dart +++ b/lib/src/editor_toolbar_shared/config/quill_shared_configurations.dart @@ -1,4 +1,3 @@ -import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart' show Color, Colors, Locale; import '../../editor/config/editor_configurations.dart' @@ -9,7 +8,7 @@ import '../../toolbar/theme/quill_dialog_theme.dart'; /// The shared configurations between [QuillEditorConfigurations] and /// [QuillSimpleToolbarConfigurations] so we don't duplicate things -class QuillSharedConfigurations extends Equatable { +class QuillSharedConfigurations { const QuillSharedConfigurations({ this.dialogBarrierColor = Colors.black54, this.dialogTheme, @@ -36,11 +35,4 @@ class QuillSharedConfigurations extends Equatable { /// Store custom configurations in here and use it in the widget tree. /// Useful for `flutter_quill_extensions` to store additional configurations. final Map extraConfigurations; - - @override - List get props => [ - dialogBarrierColor, - dialogTheme, - locale, - ]; } diff --git a/pubspec.yaml b/pubspec.yaml index 19829c413..19a064332 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -47,7 +47,6 @@ dependencies: dart_quill_delta: ^10.0.0 collection: ^1.17.0 quiver: ^3.2.1 - equatable: ^2.0.5 meta: ^1.10.0 html: ^0.15.4 diff --git a/test/bug_fix_test.dart b/test/bug_fix_test.dart index 8bd56deb4..8b27e01f6 100644 --- a/test/bug_fix_test.dart +++ b/test/bug_fix_test.dart @@ -17,6 +17,8 @@ void main() { await tester.pumpWidget( MaterialApp( + localizationsDelegates: + FlutterQuillLocalizations.localizationsDelegates, home: Scaffold( body: QuillSimpleToolbar( controller: controller, diff --git a/test/editor/editor_test.dart b/test/editor/editor_test.dart index 9a7d0ce57..d6036eaab 100644 --- a/test/editor/editor_test.dart +++ b/test/editor/editor_test.dart @@ -134,11 +134,13 @@ void main() { }); testWidgets( - 'make sure QuillEditorOpenSearchAction does not throw an exception', + 'QuillEditorOpenSearchAction should not throw an exception when the required localization delegates are provided', (tester) async { final editorFocusNode = FocusNode(); await tester.pumpWidget( MaterialApp( + localizationsDelegates: + FlutterQuillLocalizations.localizationsDelegates, home: QuillEditor.basic( controller: controller, configurations: const QuillEditorConfigurations(), From bc6b6b87d2eeab06338a26229336bd0733cb35e7 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 22 Oct 2024 18:06:43 +0300 Subject: [PATCH 06/93] chore: remove quill shared confiugration and toolbar shared configuration --- doc/migration/10_to_11.md | 3 + example/lib/screens/quill/quill_screen.dart | 5 -- .../editor/config/editor_configurations.dart | 7 +- .../quill_configurations.dart | 1 - .../config/quill_shared_configurations.dart | 38 ----------- .../config/simple_toolbar_configurations.dart | 68 ++++++++++++++----- .../config/toolbar_shared_configurations.dart | 64 ----------------- 7 files changed, 56 insertions(+), 130 deletions(-) delete mode 100644 lib/src/editor_toolbar_shared/config/quill_shared_configurations.dart delete mode 100644 lib/src/toolbar/config/toolbar_shared_configurations.dart diff --git a/doc/migration/10_to_11.md b/doc/migration/10_to_11.md index 6b2fd604d..91230cb6f 100644 --- a/doc/migration/10_to_11.md +++ b/doc/migration/10_to_11.md @@ -12,6 +12,8 @@ Remove the following if used: - FlutterQuillExtensions.useSuperClipboardPlugin(); ``` +You can either use our default implementation or continue using `super_clipboard`, if you're unsure, try with **option A** unless you have a reason to use **option B**. + ### A. Using the new default implementation > [!NOTE] @@ -177,3 +179,4 @@ The library `package:flutter_quill/translations.dart` has been removed and the r - Removes the deprecated library `flutter_quill/markdown_quill.dart`. Suggested alternatives: [markdown_quill](https://pub.dev/packages/markdown_quill) or [quill_markdown](https://pub.dev/packages/quill_markdown). - Removes `Document.fromHtml`. Use an alternative such as [flutter_quill_delta_from_html](https://pub.dev/packages/flutter_quill_delta_from_html). - Removes `QuillControllerConfigurations.editorConfigurations` (not being used and invalid). +- Remove `QuillSharedConfigurations` (it's no longer used). It was previously used to set the `Local` for both `QuillEditor` and `QuillToolbar` simultaneously. diff --git a/example/lib/screens/quill/quill_screen.dart b/example/lib/screens/quill/quill_screen.dart index fce8700ed..80f52cc9b 100644 --- a/example/lib/screens/quill/quill_screen.dart +++ b/example/lib/screens/quill/quill_screen.dart @@ -107,7 +107,6 @@ class _QuillScreenState extends State { searchConfigurations: const QuillSearchConfigurations( searchEmbedMode: SearchEmbedMode.plainText, ), - sharedConfigurations: _sharedConfigurations, ), scrollController: _editorScrollController, focusNode: _editorFocusNode, @@ -124,8 +123,4 @@ class _QuillScreenState extends State { ), ); } - - QuillSharedConfigurations get _sharedConfigurations { - return const QuillSharedConfigurations(); - } } diff --git a/lib/src/editor/config/editor_configurations.dart b/lib/src/editor/config/editor_configurations.dart index ae4e8cf20..0db4cf6a9 100644 --- a/lib/src/editor/config/editor_configurations.dart +++ b/lib/src/editor/config/editor_configurations.dart @@ -6,7 +6,7 @@ import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart' show experimental; import '../../controller/quill_controller.dart'; -import '../../editor_toolbar_shared/config/quill_shared_configurations.dart'; + import '../../toolbar/theme/quill_dialog_theme.dart'; import '../embed/embed_editor_builder.dart'; import '../raw_editor/builders/leading_block_builder.dart'; @@ -26,7 +26,6 @@ class QuillEditorConfigurations { /// Important note for the maintainers /// When editing this class please update the [copyWith] function too. const QuillEditorConfigurations({ - this.sharedConfigurations = const QuillSharedConfigurations(), this.scrollable = true, this.padding = EdgeInsets.zero, @experimental this.characterShortcutEvents = const [], @@ -87,8 +86,6 @@ class QuillEditorConfigurations { this.customLeadingBlockBuilder, }); - final QuillSharedConfigurations sharedConfigurations; - final LeadingBlockNodeBuilder? customLeadingBlockBuilder; /// The text placeholder in the quill editor @@ -423,7 +420,6 @@ class QuillEditorConfigurations { final void Function(TextInputAction action)? onPerformAction; QuillEditorConfigurations copyWith({ - QuillSharedConfigurations? sharedConfigurations, QuillController? controller, String? placeholder, bool? readOnly, @@ -482,7 +478,6 @@ class QuillEditorConfigurations { void Function(TextInputAction action)? onPerformAction, }) { return QuillEditorConfigurations( - sharedConfigurations: sharedConfigurations ?? this.sharedConfigurations, customLeadingBlockBuilder: customLeadingBlockBuilder ?? this.customLeadingBlockBuilder, placeholder: placeholder ?? this.placeholder, diff --git a/lib/src/editor_toolbar_controller_shared/quill_configurations.dart b/lib/src/editor_toolbar_controller_shared/quill_configurations.dart index a6b614383..55d22025a 100644 --- a/lib/src/editor_toolbar_controller_shared/quill_configurations.dart +++ b/lib/src/editor_toolbar_controller_shared/quill_configurations.dart @@ -1,5 +1,4 @@ export '../controller/quill_controller_configurations.dart'; export '../editor/config/editor_configurations.dart'; export '../editor/config/search_configurations.dart'; -export '../editor_toolbar_shared/config/quill_shared_configurations.dart'; export '../toolbar/config/simple_toolbar_configurations.dart'; diff --git a/lib/src/editor_toolbar_shared/config/quill_shared_configurations.dart b/lib/src/editor_toolbar_shared/config/quill_shared_configurations.dart deleted file mode 100644 index 94117f46e..000000000 --- a/lib/src/editor_toolbar_shared/config/quill_shared_configurations.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart' show Color, Colors, Locale; - -import '../../editor/config/editor_configurations.dart' - show QuillEditorConfigurations; -import '../../toolbar/config/simple_toolbar_configurations.dart' - show QuillSimpleToolbarConfigurations; -import '../../toolbar/theme/quill_dialog_theme.dart'; - -/// The shared configurations between [QuillEditorConfigurations] and -/// [QuillSimpleToolbarConfigurations] so we don't duplicate things -class QuillSharedConfigurations { - const QuillSharedConfigurations({ - 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 - // more maintanable, flexible, and customizable - /// The barrier color of the shown dialogs - final Color dialogBarrierColor; - - /// The default dialog theme for all the dialogs for quill editor and - /// quill toolbar - final QuillDialogTheme? dialogTheme; - - /// The locale to use for the editor and toolbar, defaults to system locale - /// More https://github.com/singerdmx/flutter-quill/blob/master/doc/translation.md - /// this won't used if you defined the [FlutterQuillLocalizations.delegate] - /// in the `localizationsDelegates` which exists in - /// `MaterialApp` or `WidgetsApp` - final Locale? locale; - - /// Store custom configurations in here and use it in the widget tree. - /// Useful for `flutter_quill_extensions` to store additional configurations. - final Map extraConfigurations; -} diff --git a/lib/src/toolbar/config/simple_toolbar_configurations.dart b/lib/src/toolbar/config/simple_toolbar_configurations.dart index 2e7bcbec4..ce61351bc 100644 --- a/lib/src/toolbar/config/simple_toolbar_configurations.dart +++ b/lib/src/toolbar/config/simple_toolbar_configurations.dart @@ -6,10 +6,10 @@ import '../buttons/hearder_style/select_header_style_dropdown_button.dart'; import '../buttons/link_style2_button.dart'; import '../buttons/link_style_button.dart'; import '../embed/embed_button_builder.dart'; +import '../structs/link_dialog_action.dart'; import '../theme/quill_dialog_theme.dart'; import '../theme/quill_icon_theme.dart'; import 'simple_toolbar_button_options.dart'; -import 'toolbar_shared_configurations.dart'; export '../buttons/search/search_dialog.dart'; export 'base_button_configurations.dart'; @@ -66,15 +66,14 @@ enum HeaderStyleType { /// The configurations for the toolbar widget of flutter quill @immutable -class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { +class QuillSimpleToolbarConfigurations { const QuillSimpleToolbarConfigurations({ - super.sharedConfigurations, - super.toolbarSectionSpacing = kToolbarSectionSpacing, - super.toolbarIconAlignment = WrapAlignment.center, - super.toolbarIconCrossAlignment = WrapCrossAlignment.center, - super.buttonOptions = const QuillSimpleToolbarButtonOptions(), + this.toolbarSectionSpacing = kToolbarSectionSpacing, + this.toolbarIconAlignment = WrapAlignment.center, + this.toolbarIconCrossAlignment = WrapCrossAlignment.center, + this.buttonOptions = const QuillSimpleToolbarButtonOptions(), this.customButtons = const [], - super.multiRowsDisplay = true, + this.multiRowsDisplay = true, this.showDividers = true, this.showFontFamily = true, this.showFontSize = true, @@ -114,28 +113,28 @@ class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { this.headerStyleType = HeaderStyleType.original, /// The decoration to use for the toolbar. - super.decoration, + this.decoration, /// Toolbar items to display for controls of embed blocks this.embedButtons, - super.linkDialogAction, + this.linkDialogAction, ///The theme to use for the icons in the toolbar, uses type [QuillIconTheme] // this.iconTheme, this.dialogTheme, this.iconTheme, - super.axis = Axis.horizontal, - super.color, - super.sectionDividerColor, - super.sectionDividerSpace, + this.axis = Axis.horizontal, + this.color, + this.sectionDividerColor, + this.sectionDividerSpace, /// The change only applies if [multiRowsDisplay] is `false` - super.toolbarSize, + double? toolbarSize, + this.toolbarRunSpacing = 4, }) : _toolbarSize = toolbarSize; final double? _toolbarSize; - @override double get toolbarSize { final alternativeToolbarSize = _toolbarSize; if (alternativeToolbarSize != null) { @@ -201,4 +200,41 @@ class QuillSimpleToolbarConfigurations extends QuillSharedToolbarProperties { /// Defines which dialog is used for applying header attribute. final HeaderStyleType headerStyleType; + + final Axis axis; + + final WrapAlignment toolbarIconAlignment; + final WrapCrossAlignment toolbarIconCrossAlignment; + final double toolbarRunSpacing; + + /// Only works if [multiRowsDisplay] is `true` + final double toolbarSectionSpacing; + + // Overrides the action in the _LinkDialog widget + final LinkDialogAction? linkDialogAction; + + /// The color of the toolbar. + /// + /// Defaults to [ThemeData.canvasColor] of the current [Theme] if no color + /// is given. + final Color? color; + + /// The color to use when painting the toolbar section divider. + /// + /// If this is null, then the [DividerThemeData.color] is used. If that is + /// also null, then [ThemeData.dividerColor] is used. + final Color? sectionDividerColor; + + /// The space occupied by toolbar section divider. + final double? sectionDividerSpace; + + /// If you want the toolbar to not be a multiple rows pass false + final bool multiRowsDisplay; + + /// The decoration to use for the toolbar. + final Decoration? decoration; + + /// If you want change spesefic buttons or all of them + /// then you came to the right place + final QuillSimpleToolbarButtonOptions buttonOptions; } diff --git a/lib/src/toolbar/config/toolbar_shared_configurations.dart b/lib/src/toolbar/config/toolbar_shared_configurations.dart deleted file mode 100644 index 2165ac2d2..000000000 --- a/lib/src/toolbar/config/toolbar_shared_configurations.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter/widgets.dart' - show Axis, Color, Decoration, WrapAlignment, WrapCrossAlignment; - -import '../../editor_toolbar_shared/config/quill_shared_configurations.dart'; -import '../structs/link_dialog_action.dart'; -import 'simple_toolbar_configurations.dart'; - -abstract class QuillSharedToolbarProperties { - const QuillSharedToolbarProperties({ - this.sharedConfigurations = const QuillSharedConfigurations(), - this.toolbarSize, - this.axis = Axis.horizontal, - this.toolbarIconAlignment = WrapAlignment.center, - this.toolbarIconCrossAlignment = WrapCrossAlignment.center, - this.toolbarSectionSpacing = kToolbarSectionSpacing, - this.color, - this.sectionDividerColor, - this.sectionDividerSpace, - this.linkDialogAction, - this.multiRowsDisplay = true, - this.decoration, - this.buttonOptions = const QuillSimpleToolbarButtonOptions(), - this.toolbarRunSpacing = 4, - }); - final Axis axis; - - final WrapAlignment toolbarIconAlignment; - final WrapCrossAlignment toolbarIconCrossAlignment; - final double toolbarRunSpacing; - final double? toolbarSize; - - /// Only works if [multiRowsDisplay] is `true` - final double toolbarSectionSpacing; - - // Overrides the action in the _LinkDialog widget - final LinkDialogAction? linkDialogAction; - - /// The color of the toolbar. - /// - /// Defaults to [ThemeData.canvasColor] of the current [Theme] if no color - /// is given. - final Color? color; - - /// The color to use when painting the toolbar section divider. - /// - /// If this is null, then the [DividerThemeData.color] is used. If that is - /// also null, then [ThemeData.dividerColor] is used. - final Color? sectionDividerColor; - - /// The space occupied by toolbar section divider. - final double? sectionDividerSpace; - - /// If you want the toolbar to not be a multiple rows pass false - final bool multiRowsDisplay; - - /// The decoration to use for the toolbar. - final Decoration? decoration; - - /// If you want change spesefic buttons or all of them - /// then you came to the right place - final QuillSimpleToolbarButtonOptions buttonOptions; - - final QuillSharedConfigurations sharedConfigurations; -} From fa7540709e31be327dc28dedb5beedf6ac5b81d8 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 22 Oct 2024 18:19:25 +0300 Subject: [PATCH 07/93] chore: remove QuillController.setContents() --- doc/migration/10_to_11.md | 1 + lib/src/controller/quill_controller.dart | 16 ---------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/doc/migration/10_to_11.md b/doc/migration/10_to_11.md index 91230cb6f..f07f86007 100644 --- a/doc/migration/10_to_11.md +++ b/doc/migration/10_to_11.md @@ -180,3 +180,4 @@ The library `package:flutter_quill/translations.dart` has been removed and the r - Removes `Document.fromHtml`. Use an alternative such as [flutter_quill_delta_from_html](https://pub.dev/packages/flutter_quill_delta_from_html). - Removes `QuillControllerConfigurations.editorConfigurations` (not being used and invalid). - Remove `QuillSharedConfigurations` (it's no longer used). It was previously used to set the `Local` for both `QuillEditor` and `QuillToolbar` simultaneously. +- Removes the experimental method `QuillController.setContents`. diff --git a/lib/src/controller/quill_controller.dart b/lib/src/controller/quill_controller.dart index 6618f8077..a71b488c2 100644 --- a/lib/src/controller/quill_controller.dart +++ b/lib/src/controller/quill_controller.dart @@ -2,7 +2,6 @@ import 'dart:math' as math; import 'package:flutter/services.dart' show ClipboardData, Clipboard; import 'package:flutter/widgets.dart'; -import 'package:meta/meta.dart' show experimental; import '../../quill_delta.dart'; import '../common/structs/image_url.dart'; @@ -72,21 +71,6 @@ class QuillController extends ChangeNotifier { notifyListeners(); } - @experimental - void setContents( - Delta delta, { - ChangeSource changeSource = ChangeSource.local, - }) { - final newDocument = Document.fromDelta(delta); - - final change = DocChange(_document.toDelta(), delta, changeSource); - newDocument.documentChangeObserver.add(change); - newDocument.history.handleDocChange(change); - - _document = newDocument; - notifyListeners(); - } - /// Tells whether to keep or reset the [toggledStyle] /// when user adds a new line. final bool keepStyleOnNewLine; From 6149dc117b317b99baba68a162fec430fe844f52 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 22 Oct 2024 18:33:18 +0300 Subject: [PATCH 08/93] chore: remove QuillController.editorFocusNode --- doc/migration/10_to_11.md | 7 +++--- lib/src/controller/quill_controller.dart | 11 --------- lib/src/editor/editor.dart | 31 +++++++----------------- 3 files changed, 13 insertions(+), 36 deletions(-) diff --git a/doc/migration/10_to_11.md b/doc/migration/10_to_11.md index f07f86007..575c28163 100644 --- a/doc/migration/10_to_11.md +++ b/doc/migration/10_to_11.md @@ -159,9 +159,10 @@ The library `package:flutter_quill/translations.dart` has been removed and the r ## Minor changes -- `QuillEditorConfigurations.readOnly` has been removed and is accessible from `QuillController.readOnly`. -- `QuillController.editorFocusNode` has been removed, and should be passed and accessed to the `QuillEditor` instead. -- `QuillSimpleToolbar` and related toolbar buttons no longer request focus from the editor (revert to the old behavior). +- `QuillEditorConfigurations.readOnly` has been removed and is accessible in `QuillController.readOnly`. +- `QuillController.editorFocusNode` has been removed, and is accessible in `QuillEditor` widget. +- `QuillController.editorConfigurations` has been removed, and is accessible in `QuillEditor` widget. +- `QuillSimpleToolbar` and related toolbar buttons no longer request focus from the editor after pressing a button (**revert to the old behavior**). - `QuillEditorBuilderWidget` and `QuillEditorConfigurations.builder` have been removed as there's no valid use-case and this can be confusing. - `QuillToolbarLegacySearchDialog` and `QuillToolbarLegacySearchButton` have been removed and replaced with `QuillToolbarSearchDialog` and `QuillToolbarSearchButton` which has been introduced in [9.4.0](https://github.com/singerdmx/flutter-quill/releases/tag/v9.4.0). `QuillSimpleToolbarConfigurations.searchButtonType` is removed too. - The property `dialog BarrierColor` has been removed from all buttons, use the `Dialog Theme` in your `ThemeData` instead to customize it. See [Override a theme](https://docs.flutter.dev/cookbook/design/themes#override-a-theme). diff --git a/lib/src/controller/quill_controller.dart b/lib/src/controller/quill_controller.dart index a71b488c2..c46a0dae6 100644 --- a/lib/src/controller/quill_controller.dart +++ b/lib/src/controller/quill_controller.dart @@ -14,7 +14,6 @@ import '../document/nodes/embeddable.dart'; import '../document/nodes/leaf.dart'; import '../document/structs/doc_change.dart'; import '../document/style.dart'; -import '../editor/config/editor_configurations.dart'; import 'quill_controller_configurations.dart'; import 'quill_controller_rich_paste.dart'; @@ -47,15 +46,6 @@ class QuillController extends ChangeNotifier { final QuillControllerConfigurations configurations; - /// Editor configurations - /// - /// Caches configuration set in QuillEditor ctor. - QuillEditorConfigurations? _editorConfigurations; - QuillEditorConfigurations get editorConfigurations => - _editorConfigurations ?? const QuillEditorConfigurations(); - set editorConfigurations(QuillEditorConfigurations? value) => - _editorConfigurations = document.editorConfigurations = value; - /// Document managed by this controller. Document _document; @@ -63,7 +53,6 @@ class QuillController extends ChangeNotifier { set document(Document doc) { _document = doc; - _document.editorConfigurations = editorConfigurations; // Prevent the selection from _selection = const TextSelection(baseOffset: 0, extentOffset: 0); diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 5fcfd1677..7160de673 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -138,36 +138,24 @@ class QuillEditor extends StatefulWidget { /// ), /// ``` /// - factory QuillEditor({ - required FocusNode focusNode, - required ScrollController scrollController, - required QuillController controller, - Key? key, - QuillEditorConfigurations? configurations, - }) { - controller.editorConfigurations = configurations; - return QuillEditor._( - key: key, - focusNode: focusNode, - scrollController: scrollController, - controller: controller, - ); - } - - const QuillEditor._({ + const QuillEditor({ required this.focusNode, required this.scrollController, required this.controller, + this.configurations = const QuillEditorConfigurations(), super.key, }); factory QuillEditor.basic({ required QuillController controller, - QuillEditorConfigurations? configurations, + Key? key, + QuillEditorConfigurations configurations = + const QuillEditorConfigurations(), FocusNode? focusNode, ScrollController? scrollController, }) { return QuillEditor( + key: key, scrollController: scrollController ?? ScrollController(), focusNode: focusNode ?? FocusNode(), controller: controller, @@ -175,12 +163,11 @@ class QuillEditor extends StatefulWidget { ); } - /// The controller for the quill editor widget of flutter quill + /// The controller for the editor widget. final QuillController controller; - /// The configurations for the quill editor widget of flutter quill - QuillEditorConfigurations get configurations => - controller.editorConfigurations; + /// The configurations for the editor widget. + final QuillEditorConfigurations configurations; /// Controls whether this editor has keyboard focus. final FocusNode focusNode; From 0a05f02a179d1b7b0899023c9b444af95ea30dc9 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 22 Oct 2024 19:01:34 +0300 Subject: [PATCH 09/93] chore: remove outdated comments --- lib/src/controller/quill_controller.dart | 6 ++++-- lib/src/editor/raw_editor/raw_editor_state.dart | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/src/controller/quill_controller.dart b/lib/src/controller/quill_controller.dart index c46a0dae6..921365f41 100644 --- a/lib/src/controller/quill_controller.dart +++ b/lib/src/controller/quill_controller.dart @@ -2,6 +2,7 @@ import 'dart:math' as math; import 'package:flutter/services.dart' show ClipboardData, Clipboard; import 'package:flutter/widgets.dart'; +import '../editor/raw_editor/raw_editor_state.dart'; import '../../quill_delta.dart'; import '../common/structs/image_url.dart'; @@ -91,8 +92,9 @@ class QuillController extends ChangeNotifier { bool ignoreFocusOnTextChange = false; - /// Skip requestKeyboard being called - /// in [QuillRawEditorState._didChangeTextEditingValue] + /// Skip the keyboard request in [QuillRawEditorState.requestKeyboard]. + /// + /// See also: [QuillRawEditorState._didChangeTextEditingValue] bool skipRequestKeyboard = false; /// True when this [QuillController] instance has been disposed. diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index 6c16dae22..b268991f2 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -1019,7 +1019,7 @@ class QuillRawEditorState extends EditorState /// operating on stale data. void _markNeedsBuild() { if (_dirty) { - // No need to rebuilt if it already dirty + // No need to rebuild if it is already dirty return; } setState(() { @@ -1217,7 +1217,6 @@ class QuillRawEditorState extends EditorState @override void requestKeyboard() { if (controller.skipRequestKeyboard) { - // and that just by one simple change controller.skipRequestKeyboard = false; return; } From a127628214c23bb4a7a3b0cdc644fefb21eee738 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 22 Oct 2024 19:05:14 +0300 Subject: [PATCH 10/93] chore: always call setState() in _markNeedsBuild() in QuillRawEditorState even if dirty is already true (revert to old behavior) --- lib/src/editor/raw_editor/raw_editor_state.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index b268991f2..6f72460d5 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -1018,10 +1018,6 @@ class QuillRawEditorState extends EditorState /// state being in sync with the controller know they may be /// operating on stale data. void _markNeedsBuild() { - if (_dirty) { - // No need to rebuild if it is already dirty - return; - } setState(() { _dirty = true; }); From ec24661426230830b2fe03c3b44886d49cda18b6 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 22 Oct 2024 19:23:18 +0300 Subject: [PATCH 11/93] chore: extract code from _requestKeyboard() and add docs comment for _requireEditorCurrentState --- lib/src/editor/editor.dart | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 7160de673..732701afc 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -380,14 +380,20 @@ class QuillEditorState extends State @override bool get selectionEnabled => configurations.enableInteractiveSelection; - void _requestKeyboard() { - final editorCurrentState = _editorKey.currentState; - if (editorCurrentState == null) { - throw ArgumentError.notNull( - 'To request keyboard the editor key must not be null', - ); + /// Throws [StateError] if [_editorKey] is not connected to [QuillRawEditor] correctly. + /// + /// See also: [Flutter currentState docs](https://github.com/flutter/flutter/blob/b8211b3d941f2dcaa2db22e4572b74ede620cced/packages/flutter/lib/src/widgets/framework.dart#L179-L181) + EditorState get _requireEditorCurrentState { + final currentState = _editorKey.currentState; + if (currentState == null) { + throw StateError( + 'The $EditorState is null, ensure the $_editorKey is associated correctly with $QuillRawEditor.'); } - editorCurrentState.requestKeyboard(); + return currentState; + } + + void _requestKeyboard() { + _requireEditorCurrentState.requestKeyboard(); } } From 1c10cd047877b0b178842b286af346bd82389a7c Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 22 Oct 2024 20:18:38 +0300 Subject: [PATCH 12/93] chore: remove classes related to editor element options, minor docs updates in editor config, rename isOnTapOutsideEnabled to onTapOutsideEnabled --- doc/migration/10_to_11.md | 3 +- .../lib/screens/quill/my_quill_editor.dart | 9 -- .../element_utils/element_shared_utils.dart | 2 - .../editor/config/editor_configurations.dart | 85 +++++++++++-------- lib/src/editor/config/element_options.dart | 23 ----- .../editor/config/elements/code_block.dart | 12 --- .../config/elements/list/ordered_list.dart | 13 --- .../config/elements/list/unordered_list.dart | 13 --- lib/src/editor/editor.dart | 5 +- .../config/raw_editor_configurations.dart | 35 ++++---- .../editor/raw_editor/raw_editor_state.dart | 2 +- .../select_alignment_configurations.dart | 1 - .../buttons/toggle_style_configurations.dart | 1 - 13 files changed, 76 insertions(+), 128 deletions(-) delete mode 100644 lib/src/editor/config/element_options.dart delete mode 100644 lib/src/editor/config/elements/code_block.dart delete mode 100644 lib/src/editor/config/elements/list/ordered_list.dart delete mode 100644 lib/src/editor/config/elements/list/unordered_list.dart diff --git a/doc/migration/10_to_11.md b/doc/migration/10_to_11.md index 575c28163..431f55fec 100644 --- a/doc/migration/10_to_11.md +++ b/doc/migration/10_to_11.md @@ -169,7 +169,7 @@ The library `package:flutter_quill/translations.dart` has been removed and the r - The deprecated members `QuillRawEditorConfigurations.enableMarkdownStyleConversion` and `QuillEditorConfigurations.enableMarkdownStyleConversion` has been removed. See [#2214](https://github.com/singerdmx/flutter-quill/issues/2214). - Removes `QuillSharedConfigurations.extraConfigurations`. The optional confiugration of `flutter_quill_extensions` should be separated. - Renames `QuillEditorBulletPoint` to `QuillBulletPoint`, `QuillEditorCheckboxPoint` to `QuillCheckbox`, `QuillEditorNumberPoint` to `QuillNumberPoint`. -- Removes `QuillEditorElementOptions` and `QuillEditorConfigurations.elementOptions`. To customize the leading, see [#2146](https://github.com/singerdmx/flutter-quill/pull/2146) as an example. +- Removes `QuillEditorElementOptions` and `QuillEditorConfigurations.elementOptions`. To customize the leading, see [#2146](https://github.com/singerdmx/flutter-quill/pull/2146) as an example. The classes related to `QuillEditorElementOptions` such as `QuillEditorCodeBlockElementOptions` has been removed. - Removes `QuillController.toolbarConfigurations` to not store anything specific to the `QuillSimpleToolbar` in the `QuillController`. - Removes the base toolbar (`QuillToolbar`) since it's no longer required. Previously it was required due to the provider and localization delegate check. The class `QuillToolbarConfigurations` has been also removed. - Removes `QuillToolbarBaseButtonOptions.globalIconSize` and `QuillToolbarBaseButtonOptions.globalIconButtonFactor`. Both are deprecated for at least 10 months. @@ -182,3 +182,4 @@ The library `package:flutter_quill/translations.dart` has been removed and the r - Removes `QuillControllerConfigurations.editorConfigurations` (not being used and invalid). - Remove `QuillSharedConfigurations` (it's no longer used). It was previously used to set the `Local` for both `QuillEditor` and `QuillToolbar` simultaneously. - Removes the experimental method `QuillController.setContents`. +- Renames `isOnTapOutsideEnabled` from `QuillRawEditorConfigurations` and `QuillEditorConfigurations` to `onTapOutsideEnabled`. diff --git a/example/lib/screens/quill/my_quill_editor.dart b/example/lib/screens/quill/my_quill_editor.dart index 491ae153a..17475f035 100644 --- a/example/lib/screens/quill/my_quill_editor.dart +++ b/example/lib/screens/quill/my_quill_editor.dart @@ -37,15 +37,6 @@ class MyQuillEditor extends StatelessWidget { focusNode: focusNode, controller: controller, configurations: configurations.copyWith( - elementOptions: const QuillEditorElementOptions( - codeBlock: QuillEditorCodeBlockElementOptions( - enableLineNumbers: true, - ), - orderedList: QuillEditorOrderedListElementOptions(), - unorderedList: QuillEditorUnOrderedListElementOptions( - useTextColorForDot: true, - ), - ), customStyles: DefaultStyles( h1: DefaultTextBlockStyle( defaultTextStyle.style.copyWith( diff --git a/flutter_quill_extensions/lib/src/common/utils/element_utils/element_shared_utils.dart b/flutter_quill_extensions/lib/src/common/utils/element_utils/element_shared_utils.dart index 8632fba0f..c5a7d1fd5 100644 --- a/flutter_quill_extensions/lib/src/common/utils/element_utils/element_shared_utils.dart +++ b/flutter_quill_extensions/lib/src/common/utils/element_utils/element_shared_utils.dart @@ -73,11 +73,9 @@ double? parseCssPropertyAsDouble( 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; } diff --git a/lib/src/editor/config/editor_configurations.dart b/lib/src/editor/config/editor_configurations.dart index 0db4cf6a9..3703dd640 100644 --- a/lib/src/editor/config/editor_configurations.dart +++ b/lib/src/editor/config/editor_configurations.dart @@ -1,3 +1,5 @@ +import 'dart:ui' as ui; + import 'package:flutter/foundation.dart' show Brightness, Uint8List, immutable; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart' @@ -5,26 +7,23 @@ import 'package:flutter/material.dart' import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart' show experimental; -import '../../controller/quill_controller.dart'; - import '../../toolbar/theme/quill_dialog_theme.dart'; import '../embed/embed_editor_builder.dart'; import '../raw_editor/builders/leading_block_builder.dart'; import '../raw_editor/config/events/events.dart'; +import '../raw_editor/config/raw_editor_configurations.dart'; import '../raw_editor/raw_editor.dart'; import '../widgets/default_styles.dart'; import '../widgets/delegate.dart'; import '../widgets/link.dart'; -import 'element_options.dart'; import 'search_configurations.dart'; -export 'element_options.dart'; +// IMPORTANT For project authors: The QuillEditorConfigurations.copyWith() +// should be manually updated each time we add or remove a property -/// The configurations for the quill editor widget of flutter quill +/// The configuration of the editor widget. @immutable class QuillEditorConfigurations { - /// Important note for the maintainers - /// When editing this class please update the [copyWith] function too. const QuillEditorConfigurations({ this.scrollable = true, this.padding = EdgeInsets.zero, @@ -68,7 +67,7 @@ class QuillEditorConfigurations { this.customShortcuts, this.customActions, this.detectWordBoundary = true, - this.isOnTapOutsideEnabled = true, + this.onTapOutsideEnabled = true, this.onTapOutside, this.customLinkPrefixes = const [], this.dialogTheme, @@ -191,16 +190,21 @@ class QuillEditorConfigurations { /// Defaults to `false`. Cannot be `null`. final bool autoFocus; - /// Whether the [onTapOutside] should be triggered or not - /// Defaults to `true` - /// it have default implementation, check [onTapOutside] for more - final bool isOnTapOutsideEnabled; + /// Whether the [onTapOutside] should be triggered or not. + /// + /// Defaults to `true`. + /// + /// See also: [onTapOutside] and [QuillRawEditorConfigurations.onTapOutsideEnabled]. + final bool onTapOutsideEnabled; - /// This will run only when [isOnTapOutsideEnabled] is true - /// by default on desktop and web it will un-focus - /// on mobile it will only unFocus if the kind property of - /// event [PointerDownEvent] is [PointerDeviceKind.unknown] - /// you can override this to fit your needs + /// By default on non-mobile platforms, the editor will unfocus. + /// + /// On mobile platforms, it will only unfocus if the input kind in [PointerDownEvent.kind] + /// is [ui.PointerDeviceKind.unknown]. + /// + /// By passing a non-null value, you will override the default behavior. + /// + /// See also: [onTapOutsideEnabled] and [QuillRawEditorConfigurations.onTapOutside]. final Function(PointerDownEvent event, FocusNode focusNode)? onTapOutside; /// Whether to show cursor. @@ -278,7 +282,18 @@ class QuillEditorConfigurations { /// /// This setting is only honored on iOS devices. /// - /// Defaults to [Brightness.light]. + /// Defaults to Material/Cupertino App Brightness. + /// + /// The keyboardd appearance will set using the following: + /// + /// ```dart + /// widget.configurations.keyboardAppearance ?? + /// CupertinoTheme.maybeBrightnessOf(context) ?? + /// Theme.of(context).brightness + /// ``` + /// + /// See also: https://github.com/flutter/flutter/blob/06b9f7ba0bef2b5b44a643c73f4295a096de1202/packages/flutter/lib/src/services/text_input.dart#L621-L626 + /// and [QuillRawEditorConfigurations.keyboardAppearance] final Brightness keyboardAppearance; /// The [ScrollPhysics] to use when vertically scrolling the input. @@ -419,22 +434,26 @@ class QuillEditorConfigurations { /// Called when a text input action is performed. final void Function(TextInputAction action)? onPerformAction; + // IMPORTANT For project authors: The copyWith() + // should be manually updated each time we add or remove a property + QuillEditorConfigurations copyWith({ - QuillController? controller, + LeadingBlockNodeBuilder? customLeadingBlockBuilder, String? placeholder, - bool? readOnly, + List? characterShortcutEvents, + List? spaceShortcutEvents, bool? checkBoxReadOnly, bool? disableClipboard, bool? scrollable, - bool? enableMarkdownStyleConversion, - bool? enableAlwaysIndentOnTab, double? scrollBottomInset, + bool? enableAlwaysIndentOnTab, EdgeInsetsGeometry? padding, bool? autoFocus, - bool? isOnTapOutsideEnabled, + bool? onTapOutsideEnabled, Function(PointerDownEvent event, FocusNode focusNode)? onTapOutside, bool? showCursor, bool? paintCursorAboveText, + MouseCursor? readOnlyMouseCursor, bool? enableInteractiveSelection, bool? enableSelectionToolbar, double? minHeight, @@ -448,14 +467,12 @@ class QuillEditorConfigurations { ValueChanged? onLaunchUrl, Iterable? embedBuilders, EmbedBuilder? unknownEmbedBuilder, - QuillSearchConfigurations? searchConfigurations, CustomStyleBuilder? customStyleBuilder, CustomRecognizerBuilder? customRecognizerBuilder, + QuillSearchConfigurations? searchConfigurations, LinkActionPickerDelegate? linkActionPickerDelegate, bool? floatingCursorDisabled, TextSelectionControls? textSelectionControls, - List? characterShortcutEvents, - List? spaceShortcutEvents, Future Function(Uint8List imageBytes)? onImagePaste, Future Function(Uint8List imageBytes)? onGifPaste, Map? customShortcuts, @@ -467,9 +484,7 @@ class QuillEditorConfigurations { ContentInsertionConfiguration? contentInsertionConfiguration, GlobalKey? editorKey, TextSelectionThemeData? textSelectionThemeData, - LeadingBlockNodeBuilder? customLeadingBlockBuilder, bool? requestKeyboardFocusOnCheckListChanged, - QuillEditorElementOptions? elementOptions, TextMagnifierConfiguration? magnifierConfiguration, TextInputAction? textInputAction, bool? enableScribble, @@ -481,22 +496,22 @@ class QuillEditorConfigurations { customLeadingBlockBuilder: customLeadingBlockBuilder ?? this.customLeadingBlockBuilder, placeholder: placeholder ?? this.placeholder, + characterShortcutEvents: + characterShortcutEvents ?? this.characterShortcutEvents, + spaceShortcutEvents: spaceShortcutEvents ?? this.spaceShortcutEvents, checkBoxReadOnly: checkBoxReadOnly ?? this.checkBoxReadOnly, disableClipboard: disableClipboard ?? this.disableClipboard, scrollable: scrollable ?? this.scrollable, scrollBottomInset: scrollBottomInset ?? this.scrollBottomInset, - characterShortcutEvents: - characterShortcutEvents ?? this.characterShortcutEvents, - spaceShortcutEvents: spaceShortcutEvents ?? this.spaceShortcutEvents, - padding: padding ?? this.padding, enableAlwaysIndentOnTab: enableAlwaysIndentOnTab ?? this.enableAlwaysIndentOnTab, + padding: padding ?? this.padding, autoFocus: autoFocus ?? this.autoFocus, - isOnTapOutsideEnabled: - isOnTapOutsideEnabled ?? this.isOnTapOutsideEnabled, + onTapOutsideEnabled: onTapOutsideEnabled ?? this.onTapOutsideEnabled, onTapOutside: onTapOutside ?? this.onTapOutside, showCursor: showCursor ?? this.showCursor, paintCursorAboveText: paintCursorAboveText ?? this.paintCursorAboveText, + readOnlyMouseCursor: readOnlyMouseCursor ?? this.readOnlyMouseCursor, enableInteractiveSelection: enableInteractiveSelection ?? this.enableInteractiveSelection, enableSelectionToolbar: @@ -512,10 +527,10 @@ class QuillEditorConfigurations { onLaunchUrl: onLaunchUrl ?? this.onLaunchUrl, embedBuilders: embedBuilders ?? this.embedBuilders, unknownEmbedBuilder: unknownEmbedBuilder ?? this.unknownEmbedBuilder, - searchConfigurations: searchConfigurations ?? this.searchConfigurations, customStyleBuilder: customStyleBuilder ?? this.customStyleBuilder, customRecognizerBuilder: customRecognizerBuilder ?? this.customRecognizerBuilder, + searchConfigurations: searchConfigurations ?? this.searchConfigurations, linkActionPickerDelegate: linkActionPickerDelegate ?? this.linkActionPickerDelegate, floatingCursorDisabled: diff --git a/lib/src/editor/config/element_options.dart b/lib/src/editor/config/element_options.dart deleted file mode 100644 index dccdf615f..000000000 --- a/lib/src/editor/config/element_options.dart +++ /dev/null @@ -1,23 +0,0 @@ -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 { - const QuillEditorElementOptions({ - this.codeBlock = const QuillEditorCodeBlockElementOptions(), - this.orderedList = const QuillEditorOrderedListElementOptions(), - this.unorderedList = const QuillEditorUnOrderedListElementOptions(), - }); - - final QuillEditorCodeBlockElementOptions codeBlock; - - final QuillEditorOrderedListElementOptions orderedList; - final QuillEditorUnOrderedListElementOptions unorderedList; -} diff --git a/lib/src/editor/config/elements/code_block.dart b/lib/src/editor/config/elements/code_block.dart deleted file mode 100644 index 04780dd78..000000000 --- a/lib/src/editor/config/elements/code_block.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/foundation.dart' show immutable; - -@immutable -class QuillEditorCodeBlockElementOptions { - const QuillEditorCodeBlockElementOptions({ - this.enableLineNumbers = false, - }); - - /// If you want line numbers in the code block, please pass true - /// by default it's false as it's not really needed in most cases - final bool enableLineNumbers; -} diff --git a/lib/src/editor/config/elements/list/ordered_list.dart b/lib/src/editor/config/elements/list/ordered_list.dart deleted file mode 100644 index fde4daf62..000000000 --- a/lib/src/editor/config/elements/list/ordered_list.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/foundation.dart' show immutable; -import 'package:flutter/widgets.dart' show Widget; - -@immutable -class QuillEditorOrderedListElementOptions { - const QuillEditorOrderedListElementOptions({ - this.useTextColorForDot = true, - this.customWidget, - }); - - final bool useTextColorForDot; - final Widget? customWidget; -} diff --git a/lib/src/editor/config/elements/list/unordered_list.dart b/lib/src/editor/config/elements/list/unordered_list.dart deleted file mode 100644 index f0a19d48c..000000000 --- a/lib/src/editor/config/elements/list/unordered_list.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/foundation.dart' show immutable; -import 'package:flutter/widgets.dart' show Widget; - -@immutable -class QuillEditorUnOrderedListElementOptions { - const QuillEditorUnOrderedListElementOptions({ - this.useTextColorForDot = true, - this.customWidget, - }); - - final bool useTextColorForDot; - final Widget? customWidget; -} diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 732701afc..175b13802 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -163,7 +163,8 @@ class QuillEditor extends StatefulWidget { ); } - /// The controller for the editor widget. + /// Controller object which establishes a link between a rich text document + /// and this editor. final QuillController controller; /// The configurations for the editor widget. @@ -307,7 +308,7 @@ class QuillEditorState extends State customShortcuts: configurations.customShortcuts, customActions: configurations.customActions, customLinkPrefixes: configurations.customLinkPrefixes, - isOnTapOutsideEnabled: configurations.isOnTapOutsideEnabled, + onTapOutsideEnabled: configurations.onTapOutsideEnabled, onTapOutside: configurations.onTapOutside, dialogTheme: configurations.dialogTheme, contentInsertionConfiguration: diff --git a/lib/src/editor/raw_editor/config/raw_editor_configurations.dart b/lib/src/editor/raw_editor/config/raw_editor_configurations.dart index e854ebea0..d897d2041 100644 --- a/lib/src/editor/raw_editor/config/raw_editor_configurations.dart +++ b/lib/src/editor/raw_editor/config/raw_editor_configurations.dart @@ -1,3 +1,5 @@ +import 'dart:ui' as ui; + import 'package:flutter/foundation.dart' show Brightness, Uint8List, immutable; import 'package:flutter/material.dart'; @@ -43,7 +45,7 @@ class QuillRawEditorConfigurations { this.customShortcuts, this.customActions, this.expands = false, - this.isOnTapOutsideEnabled = true, + this.onTapOutsideEnabled = true, this.enableAlwaysIndentOnTab = false, this.onTapOutside, this.keyboardAppearance, @@ -279,18 +281,16 @@ class QuillRawEditorConfigurations { /// This setting is only honored on iOS devices. /// /// Defaults to Material/Cupertino App Brightness. - /// If you are using Custom widget app then we will use the system - /// theme mode as a default. /// - /// It will run using the following logic: + /// The keyboardd appearance will set using the following: /// /// ```dart - /// /// widget.configurations.keyboardAppearance ?? /// CupertinoTheme.maybeBrightnessOf(context) ?? /// Theme.of(context).brightness - /// /// ``` + /// + /// See also: https://github.com/flutter/flutter/blob/06b9f7ba0bef2b5b44a643c73f4295a096de1202/packages/flutter/lib/src/services/text_input.dart#L621-L626 final Brightness? keyboardAppearance; /// If true, then long-pressing this TextField will select text and show the @@ -342,16 +342,21 @@ class QuillRawEditorConfigurations { /// See [https://api.flutter.dev/flutter/widgets/EditableText/contentInsertionConfiguration.html] final ContentInsertionConfiguration? contentInsertionConfiguration; - /// Whether the [onTapOutside] should be triggered or not - /// Defaults to `true` - /// it have default implementation, check [onTapOuside] for more - final bool isOnTapOutsideEnabled; + /// Whether the [onTapOutside] should be triggered or not. + /// + /// Defaults to `true`. + /// + /// See also: [onTapOutside]. + final bool onTapOutsideEnabled; - /// This will run only when [isOnTapOutsideEnabled] is true - /// by default on desktop and web it will unfocus - /// on mobile it will only unFocus if the kind property of - /// event [PointerDownEvent] is [PointerDeviceKind.unknown] - /// you can override this to fit your needs + /// By default on non-mobile platforms, the editor will unfocus. + /// + /// On mobile platforms, it will only unfocus if the input kind in [PointerDownEvent.kind] + /// is [ui.PointerDeviceKind.unknown]. + /// + /// By passing a non-null value, you will override the default behavior. + /// + /// See also: [onTapOutsideEnabled]. final Function(PointerDownEvent event, FocusNode focusNode)? onTapOutside; /// When there is a change the check list values diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index 6f72460d5..6643cbf1e 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -519,7 +519,7 @@ class QuillRawEditorState extends EditorState ); return TextFieldTapRegion( - enabled: widget.configurations.isOnTapOutsideEnabled, + enabled: widget.configurations.onTapOutsideEnabled, onTapOutside: (event) { final onTapOutside = widget.configurations.onTapOutside; if (onTapOutside != null) { diff --git a/lib/src/toolbar/config/buttons/select_alignment_configurations.dart b/lib/src/toolbar/config/buttons/select_alignment_configurations.dart index 1e90a3020..e75e9ed70 100644 --- a/lib/src/toolbar/config/buttons/select_alignment_configurations.dart +++ b/lib/src/toolbar/config/buttons/select_alignment_configurations.dart @@ -1,4 +1,3 @@ -// ignore_for_file: public_member_api_docs, sort_constructors_first import 'package:flutter/widgets.dart' show IconData, immutable; import '../../../document/attribute.dart'; diff --git a/lib/src/toolbar/config/buttons/toggle_style_configurations.dart b/lib/src/toolbar/config/buttons/toggle_style_configurations.dart index 411c92c32..99c699407 100644 --- a/lib/src/toolbar/config/buttons/toggle_style_configurations.dart +++ b/lib/src/toolbar/config/buttons/toggle_style_configurations.dart @@ -1,4 +1,3 @@ -// ignore_for_file: public_member_api_docs, sort_constructors_first import 'package:flutter/foundation.dart' show immutable; import 'package:meta/meta.dart'; From 56216718afcd63541562b3aac1f5404faa610be8 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 23 Oct 2024 17:05:16 +0300 Subject: [PATCH 13/93] chore: rename 'Configurations' to 'Config' --- README.md | 10 +- doc/attribute_introduction.md | 6 +- doc/configurations/custom_buttons.md | 2 +- doc/configurations/font_size.md | 4 +- doc/configurations/search.md | 6 +- doc/custom_embed_blocks.md | 2 +- doc/customizing_shortcuts.md | 6 +- doc/migration/10_to_11.md | 36 +- .../lib/screens/quill/my_quill_editor.dart | 12 +- .../lib/screens/quill/my_quill_toolbar.dart | 4 +- example/lib/screens/quill/quill_screen.dart | 4 +- flutter_quill_extensions/README.md | 12 +- .../lib/flutter_quill_extensions.dart | 16 +- .../lib/src/editor/image/image_embed.dart | 14 +- .../src/editor/image/image_embed_types.dart | 4 +- .../lib/src/editor/image/image_menu.dart | 13 +- .../lib/src/editor/image/image_web_embed.dart | 10 +- ..._configurations.dart => image_config.dart} | 14 +- ...figurations.dart => image_web_config.dart} | 4 +- .../lib/src/editor/image/widgets/image.dart | 10 +- ..._configurations.dart => video_config.dart} | 4 +- ...figurations.dart => video_web_config.dart} | 4 +- .../lib/src/editor/video/video_embed.dart | 10 +- .../lib/src/editor/video/video_web_embed.dart | 6 +- .../lib/src/flutter_quill_embeds.dart | 46 +- .../lib/src/toolbar/camera/camera_button.dart | 15 +- .../lib/src/toolbar/camera/camera_types.dart | 4 +- ...configurations.dart => camera_config.dart} | 4 +- .../lib/src/toolbar/image/image_button.dart | 17 +- ..._configurations.dart => image_config.dart} | 4 +- ..._configurations.dart => table_config.dart} | 0 .../lib/src/toolbar/table/table_button.dart | 2 +- .../lib/src/toolbar/video/models/video.dart | 4 +- ..._configurations.dart => video_config.dart} | 4 +- .../lib/src/toolbar/video/video_button.dart | 17 +- flutter_quill_test/CHANGELOG.md | 1424 ++++++++--------- lib/flutter_quill.dart | 4 +- lib/src/controller/quill_controller.dart | 13 +- .../quill_controller_configurations.dart | 4 +- lib/src/document/document.dart | 30 +- lib/src/document/nodes/line.dart | 11 +- ...configurations.dart => editor_config.dart} | 32 +- ...configurations.dart => search_config.dart} | 8 +- lib/src/editor/editor.dart | 25 +- .../builders/leading_block_builder.dart | 6 +- ...igurations.dart => raw_editor_config.dart} | 4 +- lib/src/editor/raw_editor/raw_editor.dart | 18 +- .../editor/raw_editor/raw_editor_actions.dart | 21 +- .../editor/raw_editor/raw_editor_state.dart | 194 ++- ...editor_state_selection_delegate_mixin.dart | 10 +- ..._editor_state_text_input_client_mixin.dart | 29 +- .../bullet_point_leading.dart | 2 +- .../check_box_leading.dart | 2 +- .../codeblock_line_number_leading.dart | 3 +- .../number_point_leading.dart | 2 +- lib/src/editor/widgets/text/text_block.dart | 12 +- lib/src/editor/widgets/text/text_line.dart | 2 +- .../quill_config.dart | 4 + .../quill_configurations.dart | 4 - .../base_button/stateless_base_button.dart | 2 +- .../toolbar/buttons/clear_format_button.dart | 2 +- .../toolbar/buttons/color/color_button.dart | 2 +- .../toolbar/buttons/custom_button_button.dart | 2 +- .../select_header_style_buttons.dart | 2 +- .../select_header_style_dropdown_button.dart | 2 +- lib/src/toolbar/buttons/history_button.dart | 2 +- lib/src/toolbar/buttons/indent_button.dart | 2 +- .../toolbar/buttons/link_style2_button.dart | 2 +- .../toolbar/buttons/link_style_button.dart | 2 +- .../select_line_height_dropdown_button.dart | 2 +- .../buttons/toggle_check_list_button.dart | 2 +- ...urations.dart => base_button_options.dart} | 2 +- ...rations.dart => clear_format_options.dart} | 2 +- ...configurations.dart => color_options.dart} | 2 +- ...ations.dart => custom_button_options.dart} | 2 +- ...urations.dart => font_family_options.dart} | 2 +- ...igurations.dart => font_size_options.dart} | 2 +- ...nfigurations.dart => history_options.dart} | 2 +- ...onfigurations.dart => indent_options.dart} | 2 +- ...urations.dart => link_style2_options.dart} | 2 +- ...gurations.dart => link_style_options.dart} | 0 ...onfigurations.dart => search_options.dart} | 0 ...ons.dart => select_alignment_options.dart} | 2 +- ... select_header_style_buttons_options.dart} | 2 +- ...header_style_dropdown_button_options.dart} | 0 ...height_style_dropdown_button_options.dart} | 0 ...ns.dart => toggle_check_list_options.dart} | 2 +- ...rations.dart => toggle_style_options.dart} | 2 +- .../config/simple_toolbar_button_options.dart | 64 +- ...ations.dart => simple_toolbar_config.dart} | 36 +- lib/src/toolbar/simple_toolbar.dart | 194 ++- test/bug_fix_test.dart | 4 +- test/document/document_search_test.dart | 24 +- test/editor/editor_test.dart | 8 +- 94 files changed, 1275 insertions(+), 1299 deletions(-) rename flutter_quill_extensions/lib/src/editor/image/models/{image_configurations.dart => image_config.dart} (93%) rename flutter_quill_extensions/lib/src/editor/image/models/{image_web_configurations.dart => image_web_config.dart} (66%) rename flutter_quill_extensions/lib/src/editor/video/models/{video_configurations.dart => video_config.dart} (94%) rename flutter_quill_extensions/lib/src/editor/video/models/{video_web_configurations.dart => video_web_config.dart} (71%) rename flutter_quill_extensions/lib/src/toolbar/camera/models/{camera_configurations.dart => camera_config.dart} (83%) rename flutter_quill_extensions/lib/src/toolbar/image/models/{image_configurations.dart => image_config.dart} (87%) rename flutter_quill_extensions/lib/src/toolbar/table/models/{table_configurations.dart => table_config.dart} (100%) rename flutter_quill_extensions/lib/src/toolbar/video/models/{video_configurations.dart => video_config.dart} (85%) rename lib/src/editor/config/{editor_configurations.dart => editor_config.dart} (95%) rename lib/src/editor/config/{search_configurations.dart => search_config.dart} (88%) rename lib/src/editor/raw_editor/config/{raw_editor_configurations.dart => raw_editor_config.dart} (99%) create mode 100644 lib/src/editor_toolbar_controller_shared/quill_config.dart delete mode 100644 lib/src/editor_toolbar_controller_shared/quill_configurations.dart rename lib/src/toolbar/config/{base_button_configurations.dart => base_button_options.dart} (96%) rename lib/src/toolbar/config/buttons/{clear_format_configurations.dart => clear_format_options.dart} (89%) rename lib/src/toolbar/config/buttons/{color_configurations.dart => color_options.dart} (96%) rename lib/src/toolbar/config/buttons/{custom_button_configurations.dart => custom_button_options.dart} (93%) rename lib/src/toolbar/config/buttons/{font_family_configurations.dart => font_family_options.dart} (99%) rename lib/src/toolbar/config/buttons/{font_size_configurations.dart => font_size_options.dart} (97%) rename lib/src/toolbar/config/buttons/{history_configurations.dart => history_options.dart} (94%) rename lib/src/toolbar/config/buttons/{indent_configurations.dart => indent_options.dart} (93%) rename lib/src/toolbar/config/buttons/{link_style2_configurations.dart => link_style2_options.dart} (97%) rename lib/src/toolbar/config/buttons/{link_style_configurations.dart => link_style_options.dart} (100%) rename lib/src/toolbar/config/buttons/{search_configurations.dart => search_options.dart} (100%) rename lib/src/toolbar/config/buttons/{select_alignment_configurations.dart => select_alignment_options.dart} (98%) rename lib/src/toolbar/config/buttons/{select_header_style_buttons_configurations.dart => select_header_style_buttons_options.dart} (98%) rename lib/src/toolbar/config/buttons/{select_header_style_dropdown_button_configurations.dart => select_header_style_dropdown_button_options.dart} (100%) rename lib/src/toolbar/config/buttons/{select_line_height_style_dropdown_button_configurations.dart => select_line_height_style_dropdown_button_options.dart} (100%) rename lib/src/toolbar/config/buttons/{toggle_check_list_configurations.dart => toggle_check_list_options.dart} (93%) rename lib/src/toolbar/config/buttons/{toggle_style_configurations.dart => toggle_style_options.dart} (95%) rename lib/src/toolbar/config/{simple_toolbar_configurations.dart => simple_toolbar_config.dart} (88%) diff --git a/README.md b/README.md index 88b80e454..e531f37ce 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ You can join our [Slack Group] for discussion. - [📸 Screenshots](#-screenshots) - [📦 Installation](#-installation) -- [🛠 Platform Specific Configurations](#-platform-specific-configurations) +- [🛠 Platform Setup](#-platform-setup) - [🚀 Usage](#-usage) - [💥 Breaking Changes](#-breaking-changes) - [🔤 Input / Output](#-input--output) @@ -105,7 +105,7 @@ dependencies: > being part of the open-source community! > -## 🛠 Platform Specific Configurations +## 🛠 Platform Setup The `flutter_quill` package uses the following plugins: @@ -191,12 +191,12 @@ and attach the `QuillController` to them: ```dart QuillSimpleToolbar( controller: _controller, - configurations: const QuillSimpleToolbarConfigurations(), + config: const QuillSimpleToolbarConfig(), ), Expanded( child: QuillEditor.basic( controller: _controller, - configurations: const QuillEditorConfigurations(), + config: const QuillEditorConfig(), ), ) ``` @@ -373,7 +373,7 @@ The plugin [`quill_native_bridge`](https://pub.dev/packages/quill_native_bridge) ## ✂️ Shortcut events -We can customize some Shorcut events, using the parameters `characterShortcutEvents` or `spaceShortcutEvents` from `QuillEditorConfigurations` to add more functionality to our editor. +We can customize some Shorcut events, using the parameters `characterShortcutEvents` or `spaceShortcutEvents` from `QuillEditorConfig` to add more functionality to our editor. > [!NOTE] > diff --git a/doc/attribute_introduction.md b/doc/attribute_introduction.md index c0304e755..26d26bb4f 100644 --- a/doc/attribute_introduction.md +++ b/doc/attribute_introduction.md @@ -91,8 +91,8 @@ class HighlightAttr extends Attribute { ##### Where should we add this `HighlightAttr`? -On `QuillEditor` or `QuillEditorConfigurations` **doesn't exist** a param that let us pass our `Attribute` -implementations. To make this more easy, we can use just `customStyleBuilder` param from `QuillEditorConfigurations`, +On `QuillEditor` or `QuillEditorConfig` **doesn't exist** a param that let us pass our `Attribute` +implementations. To make this more easy, we can use just `customStyleBuilder` param from `QuillEditorConfig`, that let us define a function to return a `TextStyle`. With this, we can define now our `HighlightAttr` ##### The editor @@ -100,7 +100,7 @@ that let us define a function to return a `TextStyle`. With this, we can define ```dart QuillEditor.basic( controller: controller, - configurations: QuillEditorConfigurations( + config: QuillEditorConfig( customStyleBuilder: (Attribute attribute) { if (attribute.key.equals(highlightKey)) { return TextStyle(color: Colors.black, backgroundColor: Colors.yellow); diff --git a/doc/configurations/custom_buttons.md b/doc/configurations/custom_buttons.md index 05817f867..a641adfd1 100644 --- a/doc/configurations/custom_buttons.md +++ b/doc/configurations/custom_buttons.md @@ -22,7 +22,7 @@ Each `QuillCustomButton` is used as part of the `customButtons` option as follow ```dart QuillSimpleToolbar( controller: _controller, - configurations: QuillSimpleToolbarConfigurations( + config: QuillSimpleToolbarConfig( customButtons: [ QuillToolbarCustomButtonOptions( icon: const Icon(Icons.ac_unit), diff --git a/doc/configurations/font_size.md b/doc/configurations/font_size.md index 4e64519d8..f00796924 100644 --- a/doc/configurations/font_size.md +++ b/doc/configurations/font_size.md @@ -9,7 +9,7 @@ Example: ```dart QuillSimpleToolbar( - configurations: const QuillSimpleToolbarConfigurations( + config: const QuillSimpleToolbarConfig( buttonOptions: QuillSimpleToolbarButtonOptions( fontSize: QuillToolbarFontSizeButtonOptions( rawItemsMap: {'Small': '8', 'Medium': '24.5', 'Large': '46'}, @@ -23,7 +23,7 @@ Font size can be cleared with a value of `0`, for example: ```dart QuillSimpleToolbar( - configurations: const QuillSimpleToolbarConfigurations( + config: const QuillSimpleToolbarConfig( buttonOptions: QuillSimpleToolbarButtonOptions( fontSize: QuillToolbarFontSizeButtonOptions( rawItemsMap: {'Small': '8', 'Medium': '24.5', 'Large': '46', 'Clear': '0'}, diff --git a/doc/configurations/search.md b/doc/configurations/search.md index af6c02623..04fdfa16c 100644 --- a/doc/configurations/search.md +++ b/doc/configurations/search.md @@ -7,13 +7,13 @@ Use the 3 vertical dots icon to turn on case-sensitivity or whole word constrain ## Search configuration options By default, the content of Embed objects are not searched. -You can enable search by setting the [searchEmbedMode] in searchConfigurations: +You can enable search by setting the [searchEmbedMode] in `searchConfig`: ```dart QuillEditor.basic( controller: _controller, - configurations: QuillEditorConfigurations( - searchConfigurations: const QuillSearchConfigurations( + config: QuillEditorConfig( + searchConfig: const QuillSearchConfig( searchEmbedMode: SearchEmbedMode.plainText, ), ), diff --git a/doc/custom_embed_blocks.md b/doc/custom_embed_blocks.md index d08b21a0d..76c7701f4 100644 --- a/doc/custom_embed_blocks.md +++ b/doc/custom_embed_blocks.md @@ -99,7 +99,7 @@ Future _addEditNote(BuildContext context, {Document? document}) async { ), content: QuillEditor.basic( controller: controller, - configurations: const QuillEditorConfigurations(), + config: const QuillEditorConfig(), ), ), ); diff --git a/doc/customizing_shortcuts.md b/doc/customizing_shortcuts.md index 4300cae91..cae78b6e7 100644 --- a/doc/customizing_shortcuts.md +++ b/doc/customizing_shortcuts.md @@ -17,7 +17,7 @@ class AsteriskToItalicStyle extends StatelessWidget { Widget build(BuildContext context) { return QuillEditor.basic( controller: , - configurations: QuillEditorConfigurations( + config: QuillEditorConfig( characterShortcutEvents: [], ), ); @@ -60,7 +60,7 @@ CharacterShortcutEvent asteriskToItalicStyleEvent = CharacterShortcutEvent( ); ``` -Now our 'asterisk handler' function is done and the only task left is to inject it into the `QuillEditorConfigurations`. +Now our 'asterisk handler' function is done and the only task left is to inject it into the `QuillEditorConfig`. ```dart import 'package:flutter_quill/flutter_quill.dart'; @@ -73,7 +73,7 @@ class AsteriskToItalicStyle extends StatelessWidget { Widget build(BuildContext context) { return QuillEditor.basic( controller: , - configurations: QuillEditorConfigurations( + config: QuillEditorConfig( characterShortcutEvents: [ asteriskToItalicStyleEvent, ], diff --git a/doc/migration/10_to_11.md b/doc/migration/10_to_11.md index 431f55fec..b8108418a 100644 --- a/doc/migration/10_to_11.md +++ b/doc/migration/10_to_11.md @@ -83,7 +83,7 @@ The `QuillController` should now be passed to the `QuillEditor` and `QuillSimple ```dart QuillEditor.basic( - configurations: QuillEditorConfigurations( + configurations: QuillEditorConfig( controller: _controller, ), ) @@ -97,6 +97,9 @@ QuillEditor.basic( ) ``` +> [!IMPORTANT] +> The class `QuillEditorConfigurations` has been renamed to `QuillEditorConfig`. See [renames to configuration classes](#5-renames-to-configuration-classes) section. + See [#2037](https://github.com/singerdmx/flutter-quill/discussions/2037) for discussion. Thanks to [#2078](https://github.com/singerdmx/flutter-quill/pull/2078) ## 3. Removal of the `QuillEditorProvider` and `QuillToolbarProvider` inherited widgets @@ -145,7 +148,18 @@ The widget `FlutterQuillLocalizationsWidget` has been removed. The library `package:flutter_quill/translations.dart` has been removed and the replacement is `package:flutter_quill/flutter_quill.dart` -## 5. The `flutter_quill_extensions` +## 5. Renames to configuration classes + +- **Renames `QuillEditorConfigurations` to `QuillEditorConfig` and `QuillEditor.configurations` to `QuillEditor.config`.** +- **Renames `QuillRawEditorConfigurations` to `QuillRawEditorConfig` and `QuillRawEditor.configurations` to `QuillRawEditor.config`.** +- **Renames `QuillSimpleToolbarConfigurations` to `QuillSimpleToolbarConfig` and `QuillSimpleToolbar.configurations` to `QuillSimpleToolbar.config`.** +- **Renames `QuillSearchConfigurations` to `QuillSearchConfig` and `QuillEditorConfig.searchConfigurations` to `QuillEditorConfig.searchConfig`.** +- **Renames `QuillControllerConfigurations` to `QuillControllerConfig` and `QuillController.configurations` to `QuillController.config`.** The `configurations` parameter in the `QuillController.basic()` factory constructor was also renamed to `config`. +- **Renames `QuillToolbarImageConfigurations` to `QuillToolbarImageConfig` and `QuillToolbarImageButtonOptions.imageButtonConfigurations` to `QuillToolbarImageButtonOptions.imageButtonConfig`.** + +All class names have been updated to replace `Configurations` with `Config`, and the related parameter name has been changed from `configurations` to `config`. + +## 6. The `flutter_quill_extensions` - Removes `ImagePickerService` and from `OnRequestPickVideo` and `OnRequestPickImage`. - Removes `ImageSaverService` and from `ImageOptionsMenu`. @@ -159,27 +173,27 @@ The library `package:flutter_quill/translations.dart` has been removed and the r ## Minor changes -- `QuillEditorConfigurations.readOnly` has been removed and is accessible in `QuillController.readOnly`. +- `QuillEditorConfig.readOnly` has been removed and is accessible in `QuillController.readOnly`. - `QuillController.editorFocusNode` has been removed, and is accessible in `QuillEditor` widget. -- `QuillController.editorConfigurations` has been removed, and is accessible in `QuillEditor` widget. +- `QuillController.editorConfig` has been removed, and is accessible in `QuillEditor` widget. - `QuillSimpleToolbar` and related toolbar buttons no longer request focus from the editor after pressing a button (**revert to the old behavior**). -- `QuillEditorBuilderWidget` and `QuillEditorConfigurations.builder` have been removed as there's no valid use-case and this can be confusing. -- `QuillToolbarLegacySearchDialog` and `QuillToolbarLegacySearchButton` have been removed and replaced with `QuillToolbarSearchDialog` and `QuillToolbarSearchButton` which has been introduced in [9.4.0](https://github.com/singerdmx/flutter-quill/releases/tag/v9.4.0). `QuillSimpleToolbarConfigurations.searchButtonType` is removed too. +- `QuillEditorBuilderWidget` and `QuillEditorConfig.builder` have been removed as there's no valid use-case and this can be confusing. +- `QuillToolbarLegacySearchDialog` and `QuillToolbarLegacySearchButton` have been removed and replaced with `QuillToolbarSearchDialog` and `QuillToolbarSearchButton` which has been introduced in [9.4.0](https://github.com/singerdmx/flutter-quill/releases/tag/v9.4.0). `QuillSimpleToolbarConfigu.searchButtonType` is removed too. - The property `dialog BarrierColor` has been removed from all buttons, use the `Dialog Theme` in your `ThemeData` instead to customize it. See [Override a theme](https://docs.flutter.dev/cookbook/design/themes#override-a-theme). -- The deprecated members `QuillRawEditorConfigurations.enableMarkdownStyleConversion` and `QuillEditorConfigurations.enableMarkdownStyleConversion` has been removed. See [#2214](https://github.com/singerdmx/flutter-quill/issues/2214). +- The deprecated members `QuillRawEditorConfig.enableMarkdownStyleConversion` and `QuillEditorConfig.enableMarkdownStyleConversion` has been removed. See [#2214](https://github.com/singerdmx/flutter-quill/issues/2214). - Removes `QuillSharedConfigurations.extraConfigurations`. The optional confiugration of `flutter_quill_extensions` should be separated. - Renames `QuillEditorBulletPoint` to `QuillBulletPoint`, `QuillEditorCheckboxPoint` to `QuillCheckbox`, `QuillEditorNumberPoint` to `QuillNumberPoint`. -- Removes `QuillEditorElementOptions` and `QuillEditorConfigurations.elementOptions`. To customize the leading, see [#2146](https://github.com/singerdmx/flutter-quill/pull/2146) as an example. The classes related to `QuillEditorElementOptions` such as `QuillEditorCodeBlockElementOptions` has been removed. +- Removes `QuillEditorElementOptions` and `QuillEditorConfig.elementOptions`. To customize the leading, see [#2146](https://github.com/singerdmx/flutter-quill/pull/2146) as an example. The classes related to `QuillEditorElementOptions` such as `QuillEditorCodeBlockElementOptions` has been removed. - Removes `QuillController.toolbarConfigurations` to not store anything specific to the `QuillSimpleToolbar` in the `QuillController`. - Removes the base toolbar (`QuillToolbar`) since it's no longer required. Previously it was required due to the provider and localization delegate check. The class `QuillToolbarConfigurations` has been also removed. - Removes `QuillToolbarBaseButtonOptions.globalIconSize` and `QuillToolbarBaseButtonOptions.globalIconButtonFactor`. Both are deprecated for at least 10 months. - Removes `QuillToolbarFontSizeButton.defaultDisplayText` (deprecated for more than 10 months). -- Removes `fontSizesValues` and `fontFamilyValues` from `QuillSimpleToolbarConfigurations` since those were used only in `QuillToolbarFontSizeButton` and `QuillToolbarFontFamilyButton`. Pass them to `rawItemsMap` (which exists in each button configuration) directly. +- Removes `fontSizesValues` and `fontFamilyValues` from `QuillSimpleToolbarConfig` since those were used only in `QuillToolbarFontSizeButton` and `QuillToolbarFontFamilyButton`. Pass them to `rawItemsMap` (which exists in each button configuration) directly. - Removes `QuillSimpleToolbarButtonOptions.base` which allows having default configuration for all buttons, it didn't work correctly and involved a lot of manual checks, and is a bad design. Introduced in `8.0.0` and we don't have plans on introducing an alternative. - Removes the deprecated library `flutter_quill/extensions.dart` since the name was confusing, it's for `flutter_quill_extensions`. - Removes the deprecated library `flutter_quill/markdown_quill.dart`. Suggested alternatives: [markdown_quill](https://pub.dev/packages/markdown_quill) or [quill_markdown](https://pub.dev/packages/quill_markdown). - Removes `Document.fromHtml`. Use an alternative such as [flutter_quill_delta_from_html](https://pub.dev/packages/flutter_quill_delta_from_html). -- Removes `QuillControllerConfigurations.editorConfigurations` (not being used and invalid). +- Removes `QuillControllerConfig.editorConfig` (not being used and invalid). - Remove `QuillSharedConfigurations` (it's no longer used). It was previously used to set the `Local` for both `QuillEditor` and `QuillToolbar` simultaneously. - Removes the experimental method `QuillController.setContents`. -- Renames `isOnTapOutsideEnabled` from `QuillRawEditorConfigurations` and `QuillEditorConfigurations` to `onTapOutsideEnabled`. +- Renames `isOnTapOutsideEnabled` from `QuillRawEditorConfig` and `QuillEditorConfig` to `onTapOutsideEnabled`. diff --git a/example/lib/screens/quill/my_quill_editor.dart b/example/lib/screens/quill/my_quill_editor.dart index 17475f035..4ba2427d2 100644 --- a/example/lib/screens/quill/my_quill_editor.dart +++ b/example/lib/screens/quill/my_quill_editor.dart @@ -17,14 +17,14 @@ import 'http_url.dart'; class MyQuillEditor extends StatelessWidget { const MyQuillEditor({ required this.controller, - required this.configurations, + required this.config, required this.scrollController, required this.focusNode, super.key, }); final QuillController controller; - final QuillEditorConfigurations configurations; + final QuillEditorConfig config; final ScrollController scrollController; final FocusNode focusNode; @@ -36,7 +36,7 @@ class MyQuillEditor extends StatelessWidget { scrollController: scrollController, focusNode: focusNode, controller: controller, - configurations: configurations.copyWith( + config: config.copyWith( customStyles: DefaultStyles( h1: DefaultTextBlockStyle( defaultTextStyle.style.copyWith( @@ -90,8 +90,7 @@ class MyQuillEditor extends StatelessWidget { ...(kIsWeb ? FlutterQuillEmbeds.editorWebBuilders() : FlutterQuillEmbeds.editorBuilders( - imageEmbedConfigurations: - QuillEditorImageEmbedConfigurations( + imageEmbedConfig: QuillEditorImageEmbedConfig( imageErrorWidgetBuilder: (context, error, stackTrace) { return Text( 'Error while loading an image: ${error.toString()}', @@ -116,8 +115,7 @@ class MyQuillEditor extends StatelessWidget { return null; }, ), - videoEmbedConfigurations: - QuillEditorVideoEmbedConfigurations( + videoEmbedConfig: QuillEditorVideoEmbedConfig( customVideoBuilder: (videoUrl, readOnly) { // Example: Check for YouTube Video URL and return your // YouTube video widget here. diff --git a/example/lib/screens/quill/my_quill_toolbar.dart b/example/lib/screens/quill/my_quill_toolbar.dart index b3f137c79..d22c2ab58 100644 --- a/example/lib/screens/quill/my_quill_toolbar.dart +++ b/example/lib/screens/quill/my_quill_toolbar.dart @@ -212,7 +212,7 @@ class MyQuillToolbar extends StatelessWidget { /// configurations parameter: /// Optional: if not provided will use the configuration set when the controller was instantiated. /// Override: Provide parameter here to override the default configuration - useful if configuration will change. - configurations: QuillSimpleToolbarConfigurations( + config: QuillSimpleToolbarConfig( showAlignmentButtons: true, multiRowsDisplay: true, buttonOptions: QuillSimpleToolbarButtonOptions( @@ -296,7 +296,7 @@ class MyQuillToolbar extends StatelessWidget { ], embedButtons: FlutterQuillEmbeds.toolbarButtons( imageButtonOptions: QuillToolbarImageButtonOptions( - imageButtonConfigurations: QuillToolbarImageConfigurations( + imageButtonConfig: QuillToolbarImageConfig( onImageInsertCallback: isAndroidApp || isIosApp || kIsWeb ? (image, controller) => onImageInsertWithCropping(image, controller, context) diff --git a/example/lib/screens/quill/quill_screen.dart b/example/lib/screens/quill/quill_screen.dart index 80f52cc9b..31644c566 100644 --- a/example/lib/screens/quill/quill_screen.dart +++ b/example/lib/screens/quill/quill_screen.dart @@ -101,10 +101,10 @@ class _QuillScreenState extends State { return Expanded( child: MyQuillEditor( controller: _controller, - configurations: QuillEditorConfigurations( + config: QuillEditorConfig( characterShortcutEvents: standardCharactersShortcutEvents, spaceShortcutEvents: standardSpaceShorcutEvents, - searchConfigurations: const QuillSearchConfigurations( + searchConfig: const QuillSearchConfig( searchEmbedMode: SearchEmbedMode.plainText, ), ), diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index 6a4f2599a..6ee2525c8 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -7,7 +7,7 @@ to support embedding widgets images, formulas, and videos. - [📝 About](#-about) - [📦 Installation](#-installation) -- [🛠 Platform Specific Configurations](#-platform-specific-configurations) +- [🛠 Platform Setup](#-platform-setup) - [🚀 Usage](#-usage) - [⚙️ Configurations](#-configurations) - [🤝 Contributing](#-contributing) @@ -41,7 +41,7 @@ dependencies: path: flutter_quill_extensions ``` -## 🛠 Platform Specific Configurations +## 🛠 Platform Setup The package uses the following plugins: @@ -81,7 +81,7 @@ Set the `embedBuilders` and `embedToolbar` params in configurations of `QuillEdi ```dart QuillSimpleToolbar( - configurations: QuillSimpleToolbarConfigurations( + config: QuillSimpleToolbarConfig( embedButtons: FlutterQuillEmbeds.toolbarButtons(), ), ), @@ -92,7 +92,7 @@ QuillSimpleToolbar( ```dart Expanded( child: QuillEditor.basic( - configurations: QuillEditorConfigurations( + config: QuillEditorConfig( embedBuilders: kIsWeb ? FlutterQuillEmbeds.editorWebBuilders() : FlutterQuillEmbeds.editorBuilders(), ), ), @@ -150,8 +150,8 @@ To support loading image assets in the editor: ```dart FlutterQuillEmbeds.editorBuilders( - imageEmbedConfigurations: - QuillEditorImageEmbedConfigurations( + imageEmbedConfig: + QuillEditorImageEmbedConfig( imageProviderBuilder: (context, imageUrl) { if (imageUrl.startsWith('assets/')) { return AssetImage(imageUrl); diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index 1d48c7f59..d3aa638ec 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -4,25 +4,25 @@ export 'src/common/extensions/controller_ext.dart'; export 'src/editor/image/image_embed.dart'; export 'src/editor/image/image_embed_types.dart'; export 'src/editor/image/image_web_embed.dart'; -export 'src/editor/image/models/image_configurations.dart'; -export 'src/editor/image/models/image_web_configurations.dart'; +export 'src/editor/image/models/image_config.dart'; +export 'src/editor/image/models/image_web_config.dart'; export 'src/editor/table/table_cell_embed.dart'; export 'src/editor/table/table_embed.dart'; export 'src/editor/table/table_models.dart'; -export 'src/editor/video/models/video_configurations.dart'; -export 'src/editor/video/models/video_web_configurations.dart'; +export 'src/editor/video/models/video_config.dart'; +export 'src/editor/video/models/video_web_config.dart'; export 'src/editor/video/video_embed.dart'; export 'src/editor/video/video_web_embed.dart'; export 'src/flutter_quill_embeds.dart'; export 'src/toolbar/camera/camera_button.dart'; export 'src/toolbar/camera/camera_types.dart'; -export 'src/toolbar/camera/models/camera_configurations.dart'; +export 'src/toolbar/camera/models/camera_config.dart'; export 'src/toolbar/formula/formula_button.dart'; export 'src/toolbar/formula/models/formula_configurations.dart'; export 'src/toolbar/image/image_button.dart'; -export 'src/toolbar/image/models/image_configurations.dart'; -export 'src/toolbar/table/models/table_configurations.dart'; +export 'src/toolbar/image/models/image_config.dart'; +export 'src/toolbar/table/models/table_config.dart'; export 'src/toolbar/table/table_button.dart'; export 'src/toolbar/video/models/video.dart'; -export 'src/toolbar/video/models/video_configurations.dart'; +export 'src/toolbar/video/models/video_config.dart'; export 'src/toolbar/video/video_button.dart'; diff --git a/flutter_quill_extensions/lib/src/editor/image/image_embed.dart b/flutter_quill_extensions/lib/src/editor/image/image_embed.dart index 7a7086f9f..597b514d3 100644 --- a/flutter_quill_extensions/lib/src/editor/image/image_embed.dart +++ b/flutter_quill_extensions/lib/src/editor/image/image_embed.dart @@ -3,14 +3,14 @@ import 'package:flutter_quill/flutter_quill.dart' hide OptionalSize; import '../../common/utils/element_utils/element_utils.dart'; import 'image_menu.dart'; -import 'models/image_configurations.dart'; +import 'models/image_config.dart'; import 'widgets/image.dart'; class QuillEditorImageEmbedBuilder extends EmbedBuilder { QuillEditorImageEmbedBuilder({ - required this.configurations, + required this.config, }); - final QuillEditorImageEmbedConfigurations configurations; + final QuillEditorImageEmbedConfig config; @override String get key => BlockEmbed.imageType; @@ -39,8 +39,8 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { final imageWidget = getImageWidgetByImageSource( context: context, imageSource, - imageProviderBuilder: configurations.imageProviderBuilder, - imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder, + imageProviderBuilder: config.imageProviderBuilder, + imageErrorWidgetBuilder: config.imageErrorWidgetBuilder, alignment: alignment, height: height, width: width, @@ -48,7 +48,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { return GestureDetector( onTap: () { - final onImageClicked = configurations.onImageClicked; + final onImageClicked = config.onImageClicked; if (onImageClicked != null) { onImageClicked(imageSource); return; @@ -57,7 +57,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { context: context, builder: (_) => ImageOptionsMenu( controller: controller, - configurations: configurations, + config: config, imageSource: imageSource, imageSize: imageSize, readOnly: readOnly, diff --git a/flutter_quill_extensions/lib/src/editor/image/image_embed_types.dart b/flutter_quill_extensions/lib/src/editor/image/image_embed_types.dart index 8d4cb8d60..91b7fd0f5 100644 --- a/flutter_quill_extensions/lib/src/editor/image/image_embed_types.dart +++ b/flutter_quill_extensions/lib/src/editor/image/image_embed_types.dart @@ -47,8 +47,8 @@ enum InsertImageSource { /// Configurations for dealing with images, on insert a image /// on request picking a image @immutable -class QuillToolbarImageConfigurations { - const QuillToolbarImageConfigurations({ +class QuillToolbarImageConfig { + const QuillToolbarImageConfig({ this.onRequestPickImage, this.onImageInsertedCallback, OnImageInsertCallback? onImageInsertCallback, diff --git a/flutter_quill_extensions/lib/src/editor/image/image_menu.dart b/flutter_quill_extensions/lib/src/editor/image/image_menu.dart index 32b177813..95f2f25f0 100644 --- a/flutter_quill_extensions/lib/src/editor/image/image_menu.dart +++ b/flutter_quill_extensions/lib/src/editor/image/image_menu.dart @@ -11,14 +11,14 @@ import 'package:flutter_quill/internal.dart'; import '../../common/utils/element_utils/element_utils.dart'; import '../../common/utils/string.dart'; import '../../common/utils/utils.dart'; -import 'models/image_configurations.dart'; +import 'models/image_config.dart'; import 'widgets/image.dart' show ImageTapWrapper, getImageStyleString; import 'widgets/image_resizer.dart' show ImageResizer; class ImageOptionsMenu extends StatelessWidget { const ImageOptionsMenu({ required this.controller, - required this.configurations, + required this.config, required this.imageSource, required this.imageSize, required this.readOnly, @@ -27,7 +27,7 @@ class ImageOptionsMenu extends StatelessWidget { }); final QuillController controller; - final QuillEditorImageEmbedConfigurations configurations; + final QuillEditorImageEmbedConfig config; final String imageSource; final ElementSize imageSize; final bool readOnly; @@ -107,8 +107,7 @@ class ImageOptionsMenu extends StatelessWidget { Navigator.of(context).pop(); // Call the remove check callback if set - if (await configurations.shouldRemoveImageCallback - ?.call(imageSource) == + if (await config.shouldRemoveImageCallback?.call(imageSource) == false) { return; } @@ -124,7 +123,7 @@ class ImageOptionsMenu extends StatelessWidget { TextSelection.collapsed(offset: offset), ); // Call the post remove callback if set - await configurations.onImageRemovedCallback.call(imageSource); + await config.onImageRemovedCallback.call(imageSource); }, ), if (!kIsWeb) @@ -177,7 +176,7 @@ class ImageOptionsMenu extends StatelessWidget { MaterialPageRoute( builder: (_) => ImageTapWrapper( imageUrl: imageSource, - configurations: configurations, + config: config, ), ), ), diff --git a/flutter_quill_extensions/lib/src/editor/image/image_web_embed.dart b/flutter_quill_extensions/lib/src/editor/image/image_web_embed.dart index 6568fdc61..1eb377104 100644 --- a/flutter_quill_extensions/lib/src/editor/image/image_web_embed.dart +++ b/flutter_quill_extensions/lib/src/editor/image/image_web_embed.dart @@ -8,14 +8,14 @@ import '../../common/utils/dart_ui/dart_ui_fake.dart' as ui; import '../../common/utils/element_utils/element_web_utils.dart'; import '../../common/utils/utils.dart'; -import 'models/image_web_configurations.dart'; +import 'models/image_web_config.dart'; class QuillEditorWebImageEmbedBuilder extends EmbedBuilder { const QuillEditorWebImageEmbedBuilder({ - required this.configurations, + required this.config, }); - final QuillEditorWebImageEmbedConfigurations configurations; + final QuillEditorWebImageEmbedConfig config; @override String get key => BlockEmbed.imageType; @@ -62,8 +62,8 @@ class QuillEditorWebImageEmbedBuilder extends EmbedBuilder { }); return ConstrainedBox( - constraints: configurations.constraints ?? - BoxConstraints.loose(const Size(200, 200)), + constraints: + config.constraints ?? BoxConstraints.loose(const Size(200, 200)), child: HtmlElementView( viewType: imageSource, ), diff --git a/flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart b/flutter_quill_extensions/lib/src/editor/image/models/image_config.dart similarity index 93% rename from flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart rename to flutter_quill_extensions/lib/src/editor/image/models/image_config.dart index 9d30f9c80..46e2749ca 100644 --- a/flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart +++ b/flutter_quill_extensions/lib/src/editor/image/models/image_config.dart @@ -5,13 +5,13 @@ import 'package:flutter_quill/internal.dart'; import '../image_embed_types.dart'; -/// [QuillEditorImageEmbedConfigurations] for desktop, mobile and +/// [QuillEditorImageEmbedConfig] for desktop, mobile and /// other platforms /// excluding web, it's configurations that is needed for the editor /// @immutable -class QuillEditorImageEmbedConfigurations { - const QuillEditorImageEmbedConfigurations({ +class QuillEditorImageEmbedConfig { + const QuillEditorImageEmbedConfig({ ImageEmbedBuilderOnRemovedCallback? onImageRemovedCallback, this.shouldRemoveImageCallback, this.imageProviderBuilder, @@ -36,7 +36,7 @@ class QuillEditorImageEmbedConfigurations { /// ``` /// /// Default value if the passed value is null: - /// [QuillEditorImageEmbedConfigurations.defaultOnImageRemovedCallback] + /// [QuillEditorImageEmbedConfig.defaultOnImageRemovedCallback] /// /// so if you want to do nothing make sure to pass a empty callback /// instead of passing null as value @@ -44,7 +44,7 @@ class QuillEditorImageEmbedConfigurations { ImageEmbedBuilderOnRemovedCallback get onImageRemovedCallback { return _onImageRemovedCallback ?? - QuillEditorImageEmbedConfigurations.defaultOnImageRemovedCallback; + QuillEditorImageEmbedConfig.defaultOnImageRemovedCallback; } /// [shouldRemoveImageCallback] is a callback @@ -143,14 +143,14 @@ class QuillEditorImageEmbedConfigurations { }; } - QuillEditorImageEmbedConfigurations copyWith({ + QuillEditorImageEmbedConfig copyWith({ ImageEmbedBuilderOnRemovedCallback? onImageRemovedCallback, ImageEmbedBuilderWillRemoveCallback? shouldRemoveImageCallback, ImageEmbedBuilderProviderBuilder? imageProviderBuilder, ImageEmbedBuilderErrorWidgetBuilder? imageErrorWidgetBuilder, bool? forceUseMobileOptionMenuForImageClick, }) { - return QuillEditorImageEmbedConfigurations( + return QuillEditorImageEmbedConfig( onImageRemovedCallback: onImageRemovedCallback ?? _onImageRemovedCallback, shouldRemoveImageCallback: shouldRemoveImageCallback ?? this.shouldRemoveImageCallback, diff --git a/flutter_quill_extensions/lib/src/editor/image/models/image_web_configurations.dart b/flutter_quill_extensions/lib/src/editor/image/models/image_web_config.dart similarity index 66% rename from flutter_quill_extensions/lib/src/editor/image/models/image_web_configurations.dart rename to flutter_quill_extensions/lib/src/editor/image/models/image_web_config.dart index 8facc8a6c..b1b60b060 100644 --- a/flutter_quill_extensions/lib/src/editor/image/models/image_web_configurations.dart +++ b/flutter_quill_extensions/lib/src/editor/image/models/image_web_config.dart @@ -2,8 +2,8 @@ import 'package:flutter/widgets.dart' show BoxConstraints; import 'package:meta/meta.dart' show immutable; @immutable -class QuillEditorWebImageEmbedConfigurations { - const QuillEditorWebImageEmbedConfigurations({ +class QuillEditorWebImageEmbedConfig { + const QuillEditorWebImageEmbedConfig({ this.constraints, }); diff --git a/flutter_quill_extensions/lib/src/editor/image/widgets/image.dart b/flutter_quill_extensions/lib/src/editor/image/widgets/image.dart index 543102c22..8e3817525 100644 --- a/flutter_quill_extensions/lib/src/editor/image/widgets/image.dart +++ b/flutter_quill_extensions/lib/src/editor/image/widgets/image.dart @@ -8,7 +8,7 @@ import 'package:photo_view/photo_view.dart'; import '../../../common/utils/utils.dart'; import '../image_embed_types.dart'; -import '../models/image_configurations.dart'; +import '../models/image_config.dart'; String getImageStyleString(QuillController controller) { final String? s = controller @@ -111,12 +111,12 @@ String appendFileExtensionToImageUrl(String url) { class ImageTapWrapper extends StatelessWidget { const ImageTapWrapper({ required this.imageUrl, - required this.configurations, + required this.config, super.key, }); final String imageUrl; - final QuillEditorImageEmbedConfigurations configurations; + final QuillEditorImageEmbedConfig config; @override Widget build(BuildContext context) { @@ -131,9 +131,9 @@ class ImageTapWrapper extends StatelessWidget { imageProvider: getImageProviderByImageSource( context: context, imageUrl, - imageProviderBuilder: configurations.imageProviderBuilder, + imageProviderBuilder: config.imageProviderBuilder, ), - errorBuilder: configurations.imageErrorWidgetBuilder, + errorBuilder: config.imageErrorWidgetBuilder, loadingBuilder: (context, event) { return Container( color: Colors.black, diff --git a/flutter_quill_extensions/lib/src/editor/video/models/video_configurations.dart b/flutter_quill_extensions/lib/src/editor/video/models/video_config.dart similarity index 94% rename from flutter_quill_extensions/lib/src/editor/video/models/video_configurations.dart rename to flutter_quill_extensions/lib/src/editor/video/models/video_config.dart index 08b1cf3a2..876efecc2 100644 --- a/flutter_quill_extensions/lib/src/editor/video/models/video_configurations.dart +++ b/flutter_quill_extensions/lib/src/editor/video/models/video_config.dart @@ -2,8 +2,8 @@ import 'package:flutter/widgets.dart' show GlobalKey, Widget; import 'package:meta/meta.dart' show experimental, immutable; @immutable -class QuillEditorVideoEmbedConfigurations { - const QuillEditorVideoEmbedConfigurations({ +class QuillEditorVideoEmbedConfig { + const QuillEditorVideoEmbedConfig({ this.onVideoInit, this.customVideoBuilder, }); diff --git a/flutter_quill_extensions/lib/src/editor/video/models/video_web_configurations.dart b/flutter_quill_extensions/lib/src/editor/video/models/video_web_config.dart similarity index 71% rename from flutter_quill_extensions/lib/src/editor/video/models/video_web_configurations.dart rename to flutter_quill_extensions/lib/src/editor/video/models/video_web_config.dart index 084cb1939..d9ba3ca1a 100644 --- a/flutter_quill_extensions/lib/src/editor/video/models/video_web_configurations.dart +++ b/flutter_quill_extensions/lib/src/editor/video/models/video_web_config.dart @@ -2,8 +2,8 @@ import 'package:flutter/widgets.dart' show BoxConstraints; import 'package:meta/meta.dart' show immutable; @immutable -class QuillEditorWebVideoEmbedConfigurations { - const QuillEditorWebVideoEmbedConfigurations({ +class QuillEditorWebVideoEmbedConfig { + const QuillEditorWebVideoEmbedConfig({ this.constraints, }); diff --git a/flutter_quill_extensions/lib/src/editor/video/video_embed.dart b/flutter_quill_extensions/lib/src/editor/video/video_embed.dart index e11bb8741..ebb9df962 100644 --- a/flutter_quill_extensions/lib/src/editor/video/video_embed.dart +++ b/flutter_quill_extensions/lib/src/editor/video/video_embed.dart @@ -4,15 +4,15 @@ import 'package:flutter_quill/flutter_quill.dart'; import '../../common/utils/element_utils/element_utils.dart'; import '../../common/utils/utils.dart'; -import 'models/video_configurations.dart'; +import 'models/video_config.dart'; import 'widgets/video_app.dart'; class QuillEditorVideoEmbedBuilder extends EmbedBuilder { const QuillEditorVideoEmbedBuilder({ - required this.configurations, + required this.config, }); - final QuillEditorVideoEmbedConfigurations configurations; + final QuillEditorVideoEmbedConfig config; @override String get key => BlockEmbed.videoType; @@ -33,7 +33,7 @@ class QuillEditorVideoEmbedBuilder extends EmbedBuilder { final videoUrl = node.value.data; - final customVideoBuilder = configurations.customVideoBuilder; + final customVideoBuilder = config.customVideoBuilder; if (customVideoBuilder != null) { final videoWidget = customVideoBuilder(videoUrl, readOnly); if (videoWidget != null) { @@ -69,7 +69,7 @@ class QuillEditorVideoEmbedBuilder extends EmbedBuilder { child: VideoApp( videoUrl: videoUrl, readOnly: readOnly, - onVideoInit: configurations.onVideoInit, + onVideoInit: config.onVideoInit, ), ); } diff --git a/flutter_quill_extensions/lib/src/editor/video/video_web_embed.dart b/flutter_quill_extensions/lib/src/editor/video/video_web_embed.dart index 893fffa01..77ebb31bf 100644 --- a/flutter_quill_extensions/lib/src/editor/video/video_web_embed.dart +++ b/flutter_quill_extensions/lib/src/editor/video/video_web_embed.dart @@ -7,15 +7,15 @@ import '../../common/utils/dart_ui/dart_ui_fake.dart' as ui; import '../../common/utils/element_utils/element_web_utils.dart'; import '../../common/utils/utils.dart'; -import 'models/video_web_configurations.dart'; +import 'models/video_web_config.dart'; import 'youtube_video_url.dart'; class QuillEditorWebVideoEmbedBuilder extends EmbedBuilder { const QuillEditorWebVideoEmbedBuilder({ - required this.configurations, + required this.config, }); - final QuillEditorWebVideoEmbedConfigurations configurations; + final QuillEditorWebVideoEmbedConfig config; @override String get key => BlockEmbed.videoType; diff --git a/flutter_quill_extensions/lib/src/flutter_quill_embeds.dart b/flutter_quill_extensions/lib/src/flutter_quill_embeds.dart index cfaa1b7d2..ba4637d5e 100644 --- a/flutter_quill_extensions/lib/src/flutter_quill_embeds.dart +++ b/flutter_quill_extensions/lib/src/flutter_quill_embeds.dart @@ -3,17 +3,17 @@ import 'package:flutter_quill/flutter_quill.dart' as fq; import 'package:meta/meta.dart' show experimental, immutable; import 'editor/image/image_embed.dart'; -import 'editor/image/models/image_configurations.dart'; -import 'editor/video/models/video_configurations.dart'; -import 'editor/video/models/video_web_configurations.dart'; +import 'editor/image/models/image_config.dart'; +import 'editor/video/models/video_config.dart'; +import 'editor/video/models/video_web_config.dart'; import 'editor/video/video_embed.dart'; import 'editor/video/video_web_embed.dart'; import 'toolbar/camera/camera_button.dart'; -import 'toolbar/camera/models/camera_configurations.dart'; +import 'toolbar/camera/models/camera_config.dart'; import 'toolbar/image/image_button.dart'; -import 'toolbar/image/models/image_configurations.dart'; -import 'toolbar/table/models/table_configurations.dart'; -import 'toolbar/video/models/video_configurations.dart'; +import 'toolbar/image/models/image_config.dart'; +import 'toolbar/table/models/table_config.dart'; +import 'toolbar/video/models/video_config.dart'; import 'toolbar/video/video_button.dart'; @immutable @@ -40,10 +40,10 @@ class FlutterQuillEmbeds { /// ``` /// static List editorBuilders({ - QuillEditorImageEmbedConfigurations? imageEmbedConfigurations = - const QuillEditorImageEmbedConfigurations(), - QuillEditorVideoEmbedConfigurations? videoEmbedConfigurations = - const QuillEditorVideoEmbedConfigurations(), + QuillEditorImageEmbedConfig? imageEmbedConfig = + const QuillEditorImageEmbedConfig(), + QuillEditorVideoEmbedConfig? videoEmbedConfig = + const QuillEditorVideoEmbedConfig(), }) { if (kIsWeb) { throw UnsupportedError( @@ -52,13 +52,13 @@ class FlutterQuillEmbeds { ); } return [ - if (imageEmbedConfigurations != null) + if (imageEmbedConfig != null) QuillEditorImageEmbedBuilder( - configurations: imageEmbedConfigurations, + config: imageEmbedConfig, ), - if (videoEmbedConfigurations != null) + if (videoEmbedConfig != null) QuillEditorVideoEmbedBuilder( - configurations: videoEmbedConfigurations, + config: videoEmbedConfig, ), // We disable the table feature is in experimental phase // and it does not work as we expect @@ -76,10 +76,10 @@ class FlutterQuillEmbeds { /// videos iframe on the web. this will use