@@ -22,8 +22,11 @@ class ClipboardMonitor {
22
22
bool get canPaste => _canPaste;
23
23
Timer ? _timer;
24
24
25
+ bool _isCheckingClipboard = false ;
26
+
25
27
void monitorClipboard (bool add, void Function () listener) {
26
28
if (kIsWeb) return ;
29
+
27
30
if (add) {
28
31
_timer = Timer .periodic (
29
32
const Duration (seconds: 1 ), (timer) => _update (listener));
@@ -33,17 +36,27 @@ class ClipboardMonitor {
33
36
}
34
37
35
38
Future <void > _update (void Function () listener) async {
39
+ if (_isCheckingClipboard) {
40
+ return ;
41
+ }
42
+
43
+ _isCheckingClipboard = true ;
44
+
36
45
final clipboardService = ClipboardServiceProvider .instance;
46
+
37
47
if (await clipboardService.hasClipboardContent) {
38
48
_canPaste = true ;
49
+
39
50
listener ();
40
51
}
52
+
53
+ _isCheckingClipboard = false ;
41
54
}
42
55
}
43
56
44
57
@experimental
45
58
class QuillToolbarClipboardButton extends QuillToolbarToggleStyleBaseButton {
46
- QuillToolbarClipboardButton ({
59
+ const QuillToolbarClipboardButton ({
47
60
required super .controller,
48
61
required this .clipboardAction,
49
62
QuillToolbarClipboardButtonOptions ? options,
@@ -55,21 +68,19 @@ class QuillToolbarClipboardButton extends QuillToolbarToggleStyleBaseButton {
55
68
}) : _options = options,
56
69
super (options: options ?? const QuillToolbarClipboardButtonOptions ());
57
70
58
- // TODO: This field will be used by the PR: https://github.com/singerdmx/flutter-quill/pull/2427
59
- // ignore: unused_field
60
71
final QuillToolbarClipboardButtonOptions ? _options;
61
72
62
73
final ClipboardAction clipboardAction;
63
74
64
- final ClipboardMonitor _monitor = ClipboardMonitor ();
65
-
66
75
@override
67
76
State <StatefulWidget > createState () => QuillToolbarClipboardButtonState ();
68
77
}
69
78
70
79
class QuillToolbarClipboardButtonState
71
80
extends QuillToolbarToggleStyleBaseButtonState <
72
81
QuillToolbarClipboardButton > {
82
+ final ClipboardMonitor _monitor = ClipboardMonitor ();
83
+
73
84
@override
74
85
bool get currentStateValue {
75
86
switch (widget.clipboardAction) {
@@ -78,23 +89,54 @@ class QuillToolbarClipboardButtonState
78
89
case ClipboardAction .copy:
79
90
return ! controller.selection.isCollapsed;
80
91
case ClipboardAction .paste:
81
- return ! controller.readOnly && (kIsWeb || widget._monitor.canPaste);
92
+ return ! controller.readOnly &&
93
+ (kIsWeb ||
94
+ (widget._options? .enableClipboardPaste ?? _monitor.canPaste));
82
95
}
83
96
}
84
97
85
98
void _listenClipboardStatus () => didChangeEditingValue ();
86
99
100
+ @override
101
+ void didUpdateWidget (QuillToolbarClipboardButton oldWidget) {
102
+ super .didUpdateWidget (oldWidget);
103
+
104
+ // Default didUpdateWidget handler, otherwise simple flag change didn't stop the monitor.
105
+ if (oldWidget.controller != controller) {
106
+ oldWidget.controller.removeListener (didChangeEditingValue);
107
+ removeExtraListener (oldWidget);
108
+ controller.addListener (didChangeEditingValue);
109
+ addExtraListener ();
110
+ currentValue = currentStateValue;
111
+ }
112
+ // The controller didn't change, but enableClipboardPaste did.
113
+ else if (widget.clipboardAction == ClipboardAction .paste) {
114
+ final isTimerActive = _monitor._timer? .isActive ?? false ;
115
+
116
+ // Enable clipboard monitoring if not active and should be monitored.
117
+ if (_shouldUseClipboardMonitor && ! isTimerActive) {
118
+ _monitor.monitorClipboard (true , _listenClipboardStatus);
119
+ }
120
+ // Disable clipboard monitoring if active and should not be monitored.
121
+ else if (! _shouldUseClipboardMonitor && isTimerActive) {
122
+ _monitor.monitorClipboard (false , _listenClipboardStatus);
123
+ }
124
+
125
+ currentValue = currentStateValue;
126
+ }
127
+ }
128
+
87
129
@override
88
130
void addExtraListener () {
89
- if (widget.clipboardAction == ClipboardAction .paste ) {
90
- widget. _monitor.monitorClipboard (true , _listenClipboardStatus);
131
+ if (_shouldUseClipboardMonitor ) {
132
+ _monitor.monitorClipboard (true , _listenClipboardStatus);
91
133
}
92
134
}
93
135
94
136
@override
95
137
void removeExtraListener (covariant QuillToolbarClipboardButton oldWidget) {
96
- if (widget.clipboardAction == ClipboardAction .paste ) {
97
- oldWidget. _monitor.monitorClipboard (false , _listenClipboardStatus);
138
+ if (_shouldUseClipboardMonitor ) {
139
+ _monitor.monitorClipboard (false , _listenClipboardStatus);
98
140
}
99
141
}
100
142
@@ -112,6 +154,11 @@ class QuillToolbarClipboardButtonState
112
154
ClipboardAction .paste => Icons .paste_outlined,
113
155
};
114
156
157
+ bool get _shouldUseClipboardMonitor {
158
+ return widget.clipboardAction == ClipboardAction .paste &&
159
+ (widget._options? .enableClipboardPaste == null );
160
+ }
161
+
115
162
void _onPressed () {
116
163
switch (widget.clipboardAction) {
117
164
case ClipboardAction .cut:
0 commit comments