diff --git a/example/lib/universal_ui/universal_ui.dart b/example/lib/universal_ui/universal_ui.dart index d214fc54..7b8ea3f4 100644 --- a/example/lib/universal_ui/universal_ui.dart +++ b/example/lib/universal_ui/universal_ui.dart @@ -25,8 +25,13 @@ class UniversalUI { var ui = UniversalUI(); -Widget defaultEmbedBuilderWeb(BuildContext context, QuillController controller, - Embed node, bool readOnly) { +Widget defaultEmbedBuilderWeb( + BuildContext context, + QuillController controller, + Embed node, + bool readOnly, + void Function(GlobalKey videoContainerKey)? onVideoInit, +) { switch (node.value.type) { case 'image': final imageUrl = node.value.data; diff --git a/lib/src/widgets/delegate.dart b/lib/src/widgets/delegate.dart index ddcc9053..2bc696df 100644 --- a/lib/src/widgets/delegate.dart +++ b/lib/src/widgets/delegate.dart @@ -6,8 +6,13 @@ import 'package:flutter/scheduler.dart'; import '../../flutter_quill.dart'; import 'text_selection.dart'; -typedef EmbedBuilder = Widget Function(BuildContext context, - QuillController controller, Embed node, bool readOnly); +typedef EmbedBuilder = Widget Function( + BuildContext context, + QuillController controller, + Embed node, + bool readOnly, + void Function(GlobalKey videoContainerKey)? onVideoInit, +); typedef CustomStyleBuilder = TextStyle Function(Attribute attribute); diff --git a/lib/src/widgets/embeds/default_embed_builder.dart b/lib/src/widgets/embeds/default_embed_builder.dart index 7eca1734..519a39c5 100644 --- a/lib/src/widgets/embeds/default_embed_builder.dart +++ b/lib/src/widgets/embeds/default_embed_builder.dart @@ -16,8 +16,13 @@ import 'image_resizer.dart'; import 'video_app.dart'; import 'youtube_video_app.dart'; -Widget defaultEmbedBuilder(BuildContext context, QuillController controller, - leaf.Embed node, bool readOnly) { +Widget defaultEmbedBuilder( + BuildContext context, + QuillController controller, + leaf.Embed node, + bool readOnly, + void Function(GlobalKey videoContainerKey)? onVideoInit, +) { assert(!kIsWeb, 'Please provide EmbedBuilder for Web'); Tuple2? _widthHeight; @@ -140,7 +145,12 @@ Widget defaultEmbedBuilder(BuildContext context, QuillController controller, return YoutubeVideoApp( videoUrl: videoUrl, context: context, readOnly: readOnly); } - return VideoApp(videoUrl: videoUrl, context: context, readOnly: readOnly); + return VideoApp( + videoUrl: videoUrl, + context: context, + readOnly: readOnly, + onVideoInit: onVideoInit, + ); default: throw UnimplementedError( 'Embeddable type "${node.value.type}" is not supported by default ' diff --git a/lib/src/widgets/embeds/video_app.dart b/lib/src/widgets/embeds/video_app.dart index d9b2f3c0..ce1ce881 100644 --- a/lib/src/widgets/embeds/video_app.dart +++ b/lib/src/widgets/embeds/video_app.dart @@ -10,12 +10,17 @@ import '../../../flutter_quill.dart'; /// Widget for playing back video /// Refer to https://github.com/flutter/plugins/tree/master/packages/video_player/video_player class VideoApp extends StatefulWidget { - const VideoApp( - {required this.videoUrl, required this.context, required this.readOnly}); + const VideoApp({ + required this.videoUrl, + required this.context, + required this.readOnly, + this.onVideoInit, + }); final String videoUrl; final BuildContext context; final bool readOnly; + final void Function(GlobalKey videoContainerKey)? onVideoInit; @override _VideoAppState createState() => _VideoAppState(); @@ -23,6 +28,7 @@ class VideoApp extends StatefulWidget { class _VideoAppState extends State { late VideoPlayerController _controller; + GlobalKey videoContainerKey = GlobalKey(); @override void initState() { @@ -35,6 +41,9 @@ class _VideoAppState extends State { // Ensure the first frame is shown after the video is initialized, // even before the play button has been pressed. setState(() {}); + if (widget.onVideoInit != null) { + widget.onVideoInit?.call(videoContainerKey); + } }).catchError((error) { setState(() {}); }); @@ -65,7 +74,8 @@ class _VideoAppState extends State { } return Container( - height: 300, + key: videoContainerKey, + // height: 300, child: InkWell( onTap: () { setState(() { diff --git a/lib/src/widgets/text_line.dart b/lib/src/widgets/text_line.dart index ed2c8f10..d629485b 100644 --- a/lib/src/widgets/text_line.dart +++ b/lib/src/widgets/text_line.dart @@ -135,8 +135,15 @@ class _TextLineState extends State { if (widget.line.hasEmbed && widget.line.childCount == 1) { // For video, it is always single child final embed = widget.line.children.single as Embed; - return EmbedProxy(widget.embedBuilder( - context, widget.controller, embed, widget.readOnly)); + return EmbedProxy( + widget.embedBuilder( + context, + widget.controller, + embed, + widget.readOnly, + null, + ), + ); } final textSpan = _getTextSpanForWholeLine(context); final strutStyle = StrutStyle.fromTextStyle(textSpan.style!); @@ -176,8 +183,16 @@ class _TextLineState extends State { } // Here it should be image final embed = WidgetSpan( - child: EmbedProxy(widget.embedBuilder( - context, widget.controller, child, widget.readOnly))); + child: EmbedProxy( + widget.embedBuilder( + context, + widget.controller, + child, + widget.readOnly, + null, + ), + ), + ); textSpanChildren.add(embed); continue; }