From bfbbfc041fd6fc833f06dc930deace17fd62267b Mon Sep 17 00:00:00 2001 From: Maksim Nikolaev Date: Tue, 21 Jan 2025 15:07:31 +0100 Subject: [PATCH 1/3] Add an option for ClipboardPaste button to disable ClipboardMonitor (#2427) --------- Co-authored-by: Ellet --- CHANGELOG.md | 4 ++ lib/src/toolbar/buttons/clipboard_button.dart | 67 ++++++++++++++++--- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96a2e2217..fc60e661f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- `enableClipboardPaste` flag in `QuillToolbarClipboardButton` to determine if the button defaults to `null,` which will use `ClipboardMonitor`, which checks every second if the clipboard has content to paste [#2427](https://github.com/singerdmx/flutter-quill/pull/2427). + ## [11.0.0-dev.20] - 2025-01-19 ### Changed diff --git a/lib/src/toolbar/buttons/clipboard_button.dart b/lib/src/toolbar/buttons/clipboard_button.dart index 1b631e8ce..1e070de20 100644 --- a/lib/src/toolbar/buttons/clipboard_button.dart +++ b/lib/src/toolbar/buttons/clipboard_button.dart @@ -22,8 +22,11 @@ class ClipboardMonitor { bool get canPaste => _canPaste; Timer? _timer; + bool _isCheckingClipboard = false; + void monitorClipboard(bool add, void Function() listener) { if (kIsWeb) return; + if (add) { _timer = Timer.periodic( const Duration(seconds: 1), (timer) => _update(listener)); @@ -33,17 +36,27 @@ class ClipboardMonitor { } Future _update(void Function() listener) async { + if (_isCheckingClipboard) { + return; + } + + _isCheckingClipboard = true; + final clipboardService = ClipboardServiceProvider.instance; + if (await clipboardService.hasClipboardContent) { _canPaste = true; + listener(); } + + _isCheckingClipboard = false; } } @experimental class QuillToolbarClipboardButton extends QuillToolbarToggleStyleBaseButton { - QuillToolbarClipboardButton({ + const QuillToolbarClipboardButton({ required super.controller, required this.clipboardAction, QuillToolbarClipboardButtonOptions? options, @@ -55,14 +68,10 @@ class QuillToolbarClipboardButton extends QuillToolbarToggleStyleBaseButton { }) : _options = options, super(options: options ?? const QuillToolbarClipboardButtonOptions()); - // TODO: This field will be used by the PR: https://github.com/singerdmx/flutter-quill/pull/2427 - // ignore: unused_field final QuillToolbarClipboardButtonOptions? _options; final ClipboardAction clipboardAction; - final ClipboardMonitor _monitor = ClipboardMonitor(); - @override State createState() => QuillToolbarClipboardButtonState(); } @@ -70,6 +79,8 @@ class QuillToolbarClipboardButton extends QuillToolbarToggleStyleBaseButton { class QuillToolbarClipboardButtonState extends QuillToolbarToggleStyleBaseButtonState< QuillToolbarClipboardButton> { + final ClipboardMonitor _monitor = ClipboardMonitor(); + @override bool get currentStateValue { switch (widget.clipboardAction) { @@ -78,23 +89,54 @@ class QuillToolbarClipboardButtonState case ClipboardAction.copy: return !controller.selection.isCollapsed; case ClipboardAction.paste: - return !controller.readOnly && (kIsWeb || widget._monitor.canPaste); + return !controller.readOnly && + (kIsWeb || + (widget._options?.enableClipboardPaste ?? _monitor.canPaste)); } } void _listenClipboardStatus() => didChangeEditingValue(); + @override + void didUpdateWidget(QuillToolbarClipboardButton oldWidget) { + super.didUpdateWidget(oldWidget); + + // Default didUpdateWidget handler, otherwise simple flag change didn't stop the monitor. + if (oldWidget.controller != controller) { + oldWidget.controller.removeListener(didChangeEditingValue); + removeExtraListener(oldWidget); + controller.addListener(didChangeEditingValue); + addExtraListener(); + currentValue = currentStateValue; + } + // The controller didn't change, but enableClipboardPaste did. + else if (widget.clipboardAction == ClipboardAction.paste) { + final isTimerActive = _monitor._timer?.isActive ?? false; + + // Enable clipboard monitoring if not active and should be monitored. + if (_shouldUseClipboardMonitor && !isTimerActive) { + _monitor.monitorClipboard(true, _listenClipboardStatus); + } + // Disable clipboard monitoring if active and should not be monitored. + else if (!_shouldUseClipboardMonitor && isTimerActive) { + _monitor.monitorClipboard(false, _listenClipboardStatus); + } + + currentValue = currentStateValue; + } + } + @override void addExtraListener() { - if (widget.clipboardAction == ClipboardAction.paste) { - widget._monitor.monitorClipboard(true, _listenClipboardStatus); + if (_shouldUseClipboardMonitor) { + _monitor.monitorClipboard(true, _listenClipboardStatus); } } @override void removeExtraListener(covariant QuillToolbarClipboardButton oldWidget) { - if (widget.clipboardAction == ClipboardAction.paste) { - oldWidget._monitor.monitorClipboard(false, _listenClipboardStatus); + if (_shouldUseClipboardMonitor) { + _monitor.monitorClipboard(false, _listenClipboardStatus); } } @@ -112,6 +154,11 @@ class QuillToolbarClipboardButtonState ClipboardAction.paste => Icons.paste_outlined, }; + bool get _shouldUseClipboardMonitor { + return widget.clipboardAction == ClipboardAction.paste && + (widget._options?.enableClipboardPaste == null); + } + void _onPressed() { switch (widget.clipboardAction) { case ClipboardAction.cut: From 41bbb8a3492b0ede1c02facdb074228ed0473ec4 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 21 Jan 2025 17:08:50 +0300 Subject: [PATCH 2/3] chore(release): prepare to publish 11.0.0-dev.21 --- CHANGELOG.md | 5 ++++- example/pubspec.lock | 2 +- pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc60e661f..df5e5e30e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [11.0.0-dev.21] - 2025-01-21 + ### Added - `enableClipboardPaste` flag in `QuillToolbarClipboardButton` to determine if the button defaults to `null,` which will use `ClipboardMonitor`, which checks every second if the clipboard has content to paste [#2427](https://github.com/singerdmx/flutter-quill/pull/2427). @@ -194,7 +196,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Apple-specific font dependency for subscript and superscript functionality from the example. - **BREAKING**: The [`super_clipboard`](https://pub.dev/packages/super_clipboard) plugin, To restore legacy behavior for `super_clipboard`, use [`flutter_quill_extensions`](https://pub.dev/packages/flutter_quill_extensions) package and `FlutterQuillExtensions.useSuperClipboardPlugin()`. -[unreleased]: https://github.com/singerdmx/flutter-quill/compare/v11.0.0-dev.20...HEAD +[unreleased]: https://github.com/singerdmx/flutter-quill/compare/v11.0.0-dev.21...HEAD +[11.0.0-dev.21]: https://github.com/singerdmx/flutter-quill/compare/v11.0.0-dev.20...v11.0.0-dev.21 [11.0.0-dev.20]: https://github.com/singerdmx/flutter-quill/compare/v11.0.0-dev.19...v11.0.0-dev.20 [11.0.0-dev.19]: https://github.com/singerdmx/flutter-quill/compare/v11.0.0-dev.18...v11.0.0-dev.19 [11.0.0-dev.18]: https://github.com/singerdmx/flutter-quill/compare/v11.0.0-dev.17...v11.0.0-dev.18 diff --git a/example/pubspec.lock b/example/pubspec.lock index d559cf44d..01f1b2bda 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -230,7 +230,7 @@ packages: path: ".." relative: true source: path - version: "11.0.0-dev.20" + version: "11.0.0-dev.21" flutter_quill_delta_from_html: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index fb5480396..2c24e3851 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 11.0.0-dev.20 +version: 11.0.0-dev.21 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 221fce4d8e476b014af49ef074eb133810736053 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 21 Jan 2025 07:33:07 -0800 Subject: [PATCH 3/3] chore: fix a super nit in the GitHub bug template --- .github/ISSUE_TEMPLATE/1_bug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/1_bug.yml b/.github/ISSUE_TEMPLATE/1_bug.yml index b859a4076..8da2bfd73 100644 --- a/.github/ISSUE_TEMPLATE/1_bug.yml +++ b/.github/ISSUE_TEMPLATE/1_bug.yml @@ -10,7 +10,7 @@ body: - type: checkboxes attributes: label: Have you checked for an existing issue? - description: Ensure there isn’t already an open issue for this feature request. + description: Ensure there isn’t already an open issue for this bug. options: - label: I have searched the [existing issues](https://github.com/singerdmx/flutter-quill/issues) required: true