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.
114 lines
3.0 KiB
114 lines
3.0 KiB
library universal_ui; |
|
|
|
import 'package:flutter/cupertino.dart'; |
|
import 'package:flutter/foundation.dart'; |
|
import 'package:flutter_quill/flutter_quill.dart'; |
|
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; |
|
import 'package:universal_html/html.dart' as html; |
|
import 'package:youtube_player_flutter/youtube_player_flutter.dart'; |
|
|
|
import '../widgets/responsive_widget.dart'; |
|
import 'fake_ui.dart' if (dart.library.html) 'real_ui.dart' as ui_instance; |
|
|
|
class PlatformViewRegistryFix { |
|
void registerViewFactory(dynamic x, dynamic y) { |
|
if (kIsWeb) { |
|
ui_instance.PlatformViewRegistry.registerViewFactory( |
|
x, |
|
y, |
|
); |
|
} |
|
} |
|
} |
|
|
|
class UniversalUI { |
|
PlatformViewRegistryFix platformViewRegistry = PlatformViewRegistryFix(); |
|
} |
|
|
|
var ui = UniversalUI(); |
|
|
|
class ImageEmbedBuilderWeb extends EmbedBuilder { |
|
@override |
|
String get key => BlockEmbed.imageType; |
|
|
|
@override |
|
Widget build( |
|
BuildContext context, |
|
QuillController controller, |
|
Embed node, |
|
bool readOnly, |
|
bool inline, |
|
TextStyle textStyle, |
|
) { |
|
final imageUrl = node.value.data; |
|
if (isImageBase64(imageUrl)) { |
|
// TODO: handle imageUrl of base64 |
|
return const SizedBox(); |
|
} |
|
final size = MediaQuery.sizeOf(context); |
|
UniversalUI().platformViewRegistry.registerViewFactory(imageUrl, (viewId) { |
|
return html.ImageElement() |
|
..src = imageUrl |
|
..style.height = 'auto' |
|
..style.width = 'auto'; |
|
}); |
|
return Padding( |
|
padding: EdgeInsets.only( |
|
right: ResponsiveWidget.isMediumScreen(context) |
|
? size.width * 0.5 |
|
: (ResponsiveWidget.isLargeScreen(context)) |
|
? size.width * 0.75 |
|
: size.width * 0.2, |
|
), |
|
child: SizedBox( |
|
height: MediaQuery.sizeOf(context).height * 0.45, |
|
child: HtmlElementView( |
|
viewType: imageUrl, |
|
), |
|
), |
|
); |
|
} |
|
} |
|
|
|
class VideoEmbedBuilderWeb extends EmbedBuilder { |
|
@override |
|
String get key => BlockEmbed.videoType; |
|
|
|
@override |
|
Widget build( |
|
BuildContext context, |
|
QuillController controller, |
|
Embed node, |
|
bool readOnly, |
|
bool inline, |
|
TextStyle textStyle, |
|
) { |
|
var videoUrl = node.value.data; |
|
if (videoUrl.contains('youtube.com') || videoUrl.contains('youtu.be')) { |
|
final youtubeID = YoutubePlayer.convertUrlToId(videoUrl); |
|
if (youtubeID != null) { |
|
videoUrl = 'https://www.youtube.com/embed/$youtubeID'; |
|
} |
|
} |
|
|
|
UniversalUI().platformViewRegistry.registerViewFactory( |
|
videoUrl, |
|
(id) => html.IFrameElement() |
|
..width = MediaQuery.sizeOf(context).width.toString() |
|
..height = MediaQuery.sizeOf(context).height.toString() |
|
..src = videoUrl |
|
..style.border = 'none'); |
|
|
|
return SizedBox( |
|
height: 500, |
|
child: HtmlElementView( |
|
viewType: videoUrl, |
|
), |
|
); |
|
} |
|
} |
|
|
|
List<EmbedBuilder> get defaultEmbedBuildersWeb => [ |
|
ImageEmbedBuilderWeb(), |
|
VideoEmbedBuilderWeb(), |
|
];
|
|
|