diff --git a/flutter_quill_extensions/lib/embeds/builders.dart b/flutter_quill_extensions/lib/embeds/builders.dart index 4888da9f..cf04a462 100644 --- a/flutter_quill_extensions/lib/embeds/builders.dart +++ b/flutter_quill_extensions/lib/embeds/builders.dart @@ -7,7 +7,10 @@ import 'package:flutter_quill/flutter_quill.dart' hide Text; import 'package:flutter_quill/translations.dart'; import 'package:gallery_saver/gallery_saver.dart'; import 'package:math_keyboard/math_keyboard.dart'; +import 'package:universal_html/html.dart' as html; +import '../shims/dart_ui_fake.dart' + if (dart.library.html) '../shims/dart_ui_real.dart' as ui; import 'utils.dart'; import 'widgets/image.dart'; import 'widgets/image_resizer.dart'; @@ -145,6 +148,41 @@ class ImageEmbedBuilder extends EmbedBuilder { } } +class ImageEmbedBuilderWeb extends EmbedBuilder { + ImageEmbedBuilderWeb({this.constraints}) + : assert(kIsWeb, 'ImageEmbedBuilderWeb is only for web platform'); + + final BoxConstraints? constraints; + + @override + String get key => BlockEmbed.imageType; + + @override + Widget build( + BuildContext context, + QuillController controller, + Embed node, + bool readOnly, + bool inline, + ) { + final imageUrl = node.value.data; + + ui.platformViewRegistry.registerViewFactory(imageUrl, (viewId) { + return html.ImageElement() + ..src = imageUrl + ..style.height = 'auto' + ..style.width = 'auto'; + }); + + return ConstrainedBox( + constraints: constraints ?? BoxConstraints.loose(const Size(200, 200)), + child: HtmlElementView( + viewType: imageUrl, + ), + ); + } +} + class VideoEmbedBuilder extends EmbedBuilder { VideoEmbedBuilder({this.onVideoInit}); diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index e5744c7c..fdbc54b2 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -29,6 +29,10 @@ class FlutterQuillEmbeds { FormulaEmbedBuilder(), ]; + static List webBuilders() => [ + ImageEmbedBuilderWeb(), + ]; + static List buttons({ bool showImageButton = true, bool showVideoButton = true, diff --git a/flutter_quill_extensions/lib/shims/dart_ui_fake.dart b/flutter_quill_extensions/lib/shims/dart_ui_fake.dart new file mode 100644 index 00000000..baaf9ebd --- /dev/null +++ b/flutter_quill_extensions/lib/shims/dart_ui_fake.dart @@ -0,0 +1,23 @@ +// ignore_for_file: avoid_classes_with_only_static_members, camel_case_types, lines_longer_than_80_chars + +import 'package:universal_html/html.dart' as html; + +// Fake interface for the logic that this package needs from (web-only) dart:ui. +// This is conditionally exported so the analyzer sees these methods as available. + +typedef PlatroformViewFactory = html.Element Function(int viewId); + +/// Shim for web_ui engine.PlatformViewRegistry +/// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/ui.dart#L62 +class platformViewRegistry { + /// Shim for registerViewFactory + /// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/ui.dart#L72 + static dynamic registerViewFactory( + String viewTypeId, PlatroformViewFactory viewFactory) {} +} + +/// Shim for web_ui engine.AssetManager +/// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/src/engine/assets.dart#L12 +class webOnlyAssetManager { + static dynamic getAssetUrl(String asset) {} +} diff --git a/flutter_quill_extensions/lib/shims/dart_ui_real.dart b/flutter_quill_extensions/lib/shims/dart_ui_real.dart new file mode 100644 index 00000000..69c06ee2 --- /dev/null +++ b/flutter_quill_extensions/lib/shims/dart_ui_real.dart @@ -0,0 +1 @@ +export 'dart:ui';