Added onVideoInit callback for video documents. See description for details

This onVideoInit callack will be called when user adds a video to quill document. This callback also give you the GlobalKey (videoContainerKey) which you can use to determine the height and width of video and other useful information.
pull/867/head
Syed-Waleed-Shah 3 years ago
parent 36cb37baa9
commit 224bde8826
  1. 9
      example/lib/universal_ui/universal_ui.dart
  2. 9
      lib/src/widgets/delegate.dart
  3. 16
      lib/src/widgets/embeds/default_embed_builder.dart
  4. 16
      lib/src/widgets/embeds/video_app.dart
  5. 23
      lib/src/widgets/text_line.dart

@ -25,8 +25,13 @@ class UniversalUI {
var ui = UniversalUI(); var ui = UniversalUI();
Widget defaultEmbedBuilderWeb(BuildContext context, QuillController controller, Widget defaultEmbedBuilderWeb(
Embed node, bool readOnly) { BuildContext context,
QuillController controller,
Embed node,
bool readOnly,
void Function(GlobalKey videoContainerKey)? onVideoInit,
) {
switch (node.value.type) { switch (node.value.type) {
case 'image': case 'image':
final imageUrl = node.value.data; final imageUrl = node.value.data;

@ -6,8 +6,13 @@ import 'package:flutter/scheduler.dart';
import '../../flutter_quill.dart'; import '../../flutter_quill.dart';
import 'text_selection.dart'; import 'text_selection.dart';
typedef EmbedBuilder = Widget Function(BuildContext context, typedef EmbedBuilder = Widget Function(
QuillController controller, Embed node, bool readOnly); BuildContext context,
QuillController controller,
Embed node,
bool readOnly,
void Function(GlobalKey videoContainerKey)? onVideoInit,
);
typedef CustomStyleBuilder = TextStyle Function(Attribute attribute); typedef CustomStyleBuilder = TextStyle Function(Attribute attribute);

@ -16,8 +16,13 @@ import 'image_resizer.dart';
import 'video_app.dart'; import 'video_app.dart';
import 'youtube_video_app.dart'; import 'youtube_video_app.dart';
Widget defaultEmbedBuilder(BuildContext context, QuillController controller, Widget defaultEmbedBuilder(
leaf.Embed node, bool readOnly) { BuildContext context,
QuillController controller,
leaf.Embed node,
bool readOnly,
void Function(GlobalKey videoContainerKey)? onVideoInit,
) {
assert(!kIsWeb, 'Please provide EmbedBuilder for Web'); assert(!kIsWeb, 'Please provide EmbedBuilder for Web');
Tuple2<double?, double?>? _widthHeight; Tuple2<double?, double?>? _widthHeight;
@ -140,7 +145,12 @@ Widget defaultEmbedBuilder(BuildContext context, QuillController controller,
return YoutubeVideoApp( return YoutubeVideoApp(
videoUrl: videoUrl, context: context, readOnly: readOnly); 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: default:
throw UnimplementedError( throw UnimplementedError(
'Embeddable type "${node.value.type}" is not supported by default ' 'Embeddable type "${node.value.type}" is not supported by default '

@ -10,12 +10,17 @@ import '../../../flutter_quill.dart';
/// Widget for playing back video /// Widget for playing back video
/// Refer to https://github.com/flutter/plugins/tree/master/packages/video_player/video_player /// Refer to https://github.com/flutter/plugins/tree/master/packages/video_player/video_player
class VideoApp extends StatefulWidget { class VideoApp extends StatefulWidget {
const VideoApp( const VideoApp({
{required this.videoUrl, required this.context, required this.readOnly}); required this.videoUrl,
required this.context,
required this.readOnly,
this.onVideoInit,
});
final String videoUrl; final String videoUrl;
final BuildContext context; final BuildContext context;
final bool readOnly; final bool readOnly;
final void Function(GlobalKey videoContainerKey)? onVideoInit;
@override @override
_VideoAppState createState() => _VideoAppState(); _VideoAppState createState() => _VideoAppState();
@ -23,6 +28,7 @@ class VideoApp extends StatefulWidget {
class _VideoAppState extends State<VideoApp> { class _VideoAppState extends State<VideoApp> {
late VideoPlayerController _controller; late VideoPlayerController _controller;
GlobalKey videoContainerKey = GlobalKey();
@override @override
void initState() { void initState() {
@ -35,6 +41,9 @@ class _VideoAppState extends State<VideoApp> {
// Ensure the first frame is shown after the video is initialized, // Ensure the first frame is shown after the video is initialized,
// even before the play button has been pressed. // even before the play button has been pressed.
setState(() {}); setState(() {});
if (widget.onVideoInit != null) {
widget.onVideoInit?.call(videoContainerKey);
}
}).catchError((error) { }).catchError((error) {
setState(() {}); setState(() {});
}); });
@ -65,7 +74,8 @@ class _VideoAppState extends State<VideoApp> {
} }
return Container( return Container(
height: 300, key: videoContainerKey,
// height: 300,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
setState(() { setState(() {

@ -135,8 +135,15 @@ class _TextLineState extends State<TextLine> {
if (widget.line.hasEmbed && widget.line.childCount == 1) { if (widget.line.hasEmbed && widget.line.childCount == 1) {
// For video, it is always single child // For video, it is always single child
final embed = widget.line.children.single as Embed; final embed = widget.line.children.single as Embed;
return EmbedProxy(widget.embedBuilder( return EmbedProxy(
context, widget.controller, embed, widget.readOnly)); widget.embedBuilder(
context,
widget.controller,
embed,
widget.readOnly,
null,
),
);
} }
final textSpan = _getTextSpanForWholeLine(context); final textSpan = _getTextSpanForWholeLine(context);
final strutStyle = StrutStyle.fromTextStyle(textSpan.style!); final strutStyle = StrutStyle.fromTextStyle(textSpan.style!);
@ -176,8 +183,16 @@ class _TextLineState extends State<TextLine> {
} }
// Here it should be image // Here it should be image
final embed = WidgetSpan( final embed = WidgetSpan(
child: EmbedProxy(widget.embedBuilder( child: EmbedProxy(
context, widget.controller, child, widget.readOnly))); widget.embedBuilder(
context,
widget.controller,
child,
widget.readOnly,
null,
),
),
);
textSpanChildren.add(embed); textSpanChildren.add(embed);
continue; continue;
} }

Loading…
Cancel
Save