dartlangeditorflutterflutter-appsflutter-examplesflutter-packageflutter-widgetquillquill-deltaquilljsreactquillrich-textrich-text-editorwysiwygwysiwyg-editor
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
5.0 KiB
139 lines
5.0 KiB
import 'dart:io' as io show Directory, File; |
|
import 'dart:ui' show FontFeature; |
|
|
|
import 'package:cached_network_image/cached_network_image.dart' |
|
show CachedNetworkImageProvider; |
|
import 'package:desktop_drop/desktop_drop.dart' show DropTarget; |
|
import 'package:flutter/material.dart'; |
|
import 'package:flutter_quill/extensions.dart' show isAndroid, isIOS, isWeb; |
|
import 'package:flutter_quill/flutter_quill.dart'; |
|
import 'package:flutter_quill_extensions/embeds/widgets/image.dart' |
|
show getImageProviderByImageSource, imageFileExtensions; |
|
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'; |
|
|
|
class MyQuillEditor extends StatelessWidget { |
|
const MyQuillEditor({ |
|
required this.configurations, |
|
required this.scrollController, |
|
required this.focusNode, |
|
super.key, |
|
}); |
|
|
|
final QuillEditorConfigurations configurations; |
|
final ScrollController scrollController; |
|
final FocusNode focusNode; |
|
|
|
@override |
|
Widget build(BuildContext context) { |
|
return QuillEditor( |
|
scrollController: scrollController, |
|
focusNode: focusNode, |
|
configurations: configurations.copyWith( |
|
customStyles: const DefaultStyles( |
|
h1: DefaultTextBlockStyle( |
|
TextStyle( |
|
fontSize: 32, |
|
height: 1.15, |
|
fontWeight: FontWeight.w300, |
|
), |
|
VerticalSpacing(16, 0), |
|
VerticalSpacing(0, 0), |
|
null, |
|
), |
|
sizeSmall: TextStyle(fontSize: 9), |
|
subscript: TextStyle( |
|
fontFamily: 'SF-UI-Display', |
|
fontFeatures: [FontFeature.subscripts()], |
|
), |
|
superscript: TextStyle( |
|
fontFamily: 'SF-UI-Display', |
|
fontFeatures: [FontFeature.superscripts()], |
|
), |
|
), |
|
scrollable: true, |
|
placeholder: 'Start writting your notes...', |
|
padding: const EdgeInsets.all(16), |
|
onImagePaste: (imageBytes) async { |
|
if (isWeb()) { |
|
return null; |
|
} |
|
// We will save it to system temporary files |
|
final newFileName = '${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; |
|
}, |
|
embedBuilders: [ |
|
...(isWeb() |
|
? 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 (isAndroid(supportWeb: false) || |
|
isIOS(supportWeb: false) || |
|
isWeb()) { |
|
if (isHttpBasedUrl(imageUrl)) { |
|
return CachedNetworkImageProvider( |
|
imageUrl, |
|
); |
|
} |
|
} |
|
return getImageProviderByImageSource( |
|
imageUrl, |
|
imageProviderBuilder: null, |
|
context: context, |
|
assetsPrefix: QuillSharedExtensionsConfigurations.get( |
|
context: context) |
|
.assetsPrefix, |
|
); |
|
}, |
|
), |
|
)), |
|
TimeStampEmbedBuilderWidget(), |
|
], |
|
builder: (context, rawEditor) { |
|
// The `desktop_drop` plugin doesn't support iOS platform for now |
|
if (isIOS(supportWeb: false)) { |
|
return rawEditor; |
|
} |
|
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, |
|
); |
|
}, |
|
), |
|
); |
|
} |
|
}
|
|
|