Skip to content

Commit 05c17e1

Browse files
authored
feat: add paste gif from clipboard (singerdmx#1788)
1 parent 63c8af6 commit 05c17e1

File tree

5 files changed

+66
-15
lines changed

5 files changed

+66
-15
lines changed

example/lib/screens/quill/my_quill_editor.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,21 @@ class MyQuillEditor extends StatelessWidget {
8080
).writeAsBytes(imageBytes, flush: true);
8181
return file.path;
8282
},
83+
onGifPaste: (gifBytes) async {
84+
if (isWeb()) {
85+
return null;
86+
}
87+
// We will save it to system temporary files
88+
final newFileName = '${DateTime.now().toIso8601String()}.gif';
89+
final newPath = path.join(
90+
io.Directory.systemTemp.path,
91+
newFileName,
92+
);
93+
final file = await io.File(
94+
newPath,
95+
).writeAsBytes(gifBytes, flush: true);
96+
return file.path;
97+
},
8398
embedBuilders: [
8499
...(isWeb()
85100
? FlutterQuillEmbeds.editorWebBuilders()

lib/src/models/config/editor/editor_configurations.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class QuillEditorConfigurations extends Equatable {
6161
this.floatingCursorDisabled = false,
6262
this.textSelectionControls,
6363
this.onImagePaste,
64+
this.onGifPaste,
6465
this.customShortcuts,
6566
this.customActions,
6667
this.detectWordBoundary = true,
@@ -282,6 +283,11 @@ class QuillEditorConfigurations extends Equatable {
282283
/// Returns the url of the image if the image should be inserted.
283284
final Future<String?> Function(Uint8List imageBytes)? onImagePaste;
284285

286+
/// Callback when the user pastes the given gif.
287+
///
288+
/// Returns the url of the gif if the gif should be inserted.
289+
final Future<String?> Function(Uint8List imageBytes)? onGifPaste;
290+
285291
/// Contains user-defined shortcuts map.
286292
///
287293
/// [https://docs.flutter.dev/development/ui/advanced/actions-and-shortcuts#shortcuts]
@@ -391,6 +397,7 @@ class QuillEditorConfigurations extends Equatable {
391397
bool? floatingCursorDisabled,
392398
TextSelectionControls? textSelectionControls,
393399
Future<String?> Function(Uint8List imageBytes)? onImagePaste,
400+
Future<String?> Function(Uint8List imageBytes)? onGifPaste,
394401
Map<ShortcutActivator, Intent>? customShortcuts,
395402
Map<Type, Action<Intent>>? customActions,
396403
bool? detectWordBoundary,
@@ -449,6 +456,7 @@ class QuillEditorConfigurations extends Equatable {
449456
textSelectionControls:
450457
textSelectionControls ?? this.textSelectionControls,
451458
onImagePaste: onImagePaste ?? this.onImagePaste,
459+
onGifPaste: onGifPaste ?? this.onGifPaste,
452460
customShortcuts: customShortcuts ?? this.customShortcuts,
453461
customActions: customActions ?? this.customActions,
454462
detectWordBoundary: detectWordBoundary ?? this.detectWordBoundary,

lib/src/models/config/raw_editor/raw_editor_configurations.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class QuillRawEditorConfigurations extends Equatable {
7373
this.customRecognizerBuilder,
7474
this.floatingCursorDisabled = false,
7575
this.onImagePaste,
76+
this.onGifPaste,
7677
this.customLinkPrefixes = const <String>[],
7778
this.dialogTheme,
7879
this.contentInsertionConfiguration,
@@ -261,6 +262,8 @@ class QuillRawEditorConfigurations extends Equatable {
261262

262263
final Future<String?> Function(Uint8List imageBytes)? onImagePaste;
263264

265+
final Future<String?> Function(Uint8List imageBytes)? onGifPaste;
266+
264267
/// Contains user-defined shortcuts map.
265268
///
266269
/// [https://docs.flutter.dev/development/ui/advanced/actions-and-shortcuts#shortcuts]

lib/src/widgets/editor/editor.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ class QuillEditorState extends State<QuillEditor>
277277
customRecognizerBuilder: configurations.customRecognizerBuilder,
278278
floatingCursorDisabled: configurations.floatingCursorDisabled,
279279
onImagePaste: configurations.onImagePaste,
280+
onGifPaste: configurations.onGifPaste,
280281
customShortcuts: configurations.customShortcuts,
281282
customActions: configurations.customActions,
282283
customLinkPrefixes: configurations.customLinkPrefixes,

lib/src/widgets/raw_editor/raw_editor_state.dart

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -279,26 +279,50 @@ class QuillRawEditorState extends EditorState
279279
if (onImagePaste != null) {
280280
if (clipboard != null) {
281281
final reader = await clipboard.read();
282-
if (!reader.canProvide(Formats.png)) {
283-
return;
282+
if (reader.canProvide(Formats.png)) {
283+
reader.getFile(Formats.png, (value) async {
284+
final image = value;
285+
286+
final imageUrl = await onImagePaste(await image.readAll());
287+
if (imageUrl == null) {
288+
return;
289+
}
290+
291+
controller.replaceText(
292+
textEditingValue.selection.end,
293+
0,
294+
BlockEmbed.image(imageUrl),
295+
null,
296+
);
297+
});
284298
}
285-
reader.getFile(Formats.png, (value) async {
286-
final image = value;
299+
}
300+
}
287301

288-
final imageUrl = await onImagePaste(await image.readAll());
289-
if (imageUrl == null) {
290-
return;
291-
}
302+
final onGifPaste = widget.configurations.onGifPaste;
303+
if (onGifPaste != null) {
304+
if (clipboard != null) {
305+
final reader = await clipboard.read();
306+
if (reader.canProvide(Formats.gif)) {
307+
reader.getFile(Formats.gif, (value) async {
308+
final gif = value;
292309

293-
controller.replaceText(
294-
textEditingValue.selection.end,
295-
0,
296-
BlockEmbed.image(imageUrl),
297-
null,
298-
);
299-
});
310+
final gifUrl = await onGifPaste(await gif.readAll());
311+
if (gifUrl == null) {
312+
return;
313+
}
314+
315+
controller.replaceText(
316+
textEditingValue.selection.end,
317+
0,
318+
BlockEmbed.image(gifUrl),
319+
null,
320+
);
321+
});
322+
}
300323
}
301324
}
325+
return;
302326
}
303327

304328
/// Select the entire text value.

0 commit comments

Comments
 (0)