Skip to content

Commit a06ad7c

Browse files
content: Implement inline video preview
Fixes: zulip#356
1 parent 56add36 commit a06ad7c

File tree

6 files changed

+495
-20
lines changed

6 files changed

+495
-20
lines changed

assets/l10n/app_en.arb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,10 @@
381381
"httpStatus": {"type": "int", "example": "500"}
382382
}
383383
},
384+
"errorVideoPlayerFailed": "Unable to play the video",
385+
"@errorVideoPlayerFailed": {
386+
"description": "Error message when a video fails to play."
387+
},
384388
"serverUrlValidationErrorEmpty": "Please enter a URL.",
385389
"@serverUrlValidationErrorEmpty": {
386390
"description": "Error message when URL is empty"

lib/widgets/content.dart

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,7 @@ class BlockContentList extends StatelessWidget {
9999
);
100100
return MessageImage(node: node);
101101
} else if (node is InlineVideoNode) {
102-
return Text.rich(
103-
TextSpan(children: [
104-
const TextSpan(text: "(unimplemented:", style: errorStyle),
105-
TextSpan(text: node.debugHtmlText, style: errorCodeStyle),
106-
const TextSpan(text: ")", style: errorStyle),
107-
]),
108-
style: errorStyle);
102+
return MessageInlineVideo(node: node);
109103
} else if (node is EmbedVideoNode) {
110104
return MessageEmbedVideo(node: node);
111105
} else if (node is UnimplementedBlockContentNode) {
@@ -387,7 +381,10 @@ class MessageImage extends StatelessWidget {
387381
return MessageMediaContainer(
388382
onTap: resolvedSrc == null ? null : () { // TODO(log)
389383
Navigator.of(context).push(getLightboxRoute(
390-
context: context, message: message, src: resolvedSrc));
384+
context: context,
385+
message: message,
386+
src: resolvedSrc,
387+
mediaType: MediaType.image));
391388
},
392389
child: resolvedSrc == null ? null : LightboxHero(
393390
message: message,
@@ -398,6 +395,37 @@ class MessageImage extends StatelessWidget {
398395
}
399396
}
400397

398+
class MessageInlineVideo extends StatelessWidget {
399+
const MessageInlineVideo({super.key, required this.node});
400+
401+
final InlineVideoNode node;
402+
403+
@override
404+
Widget build(BuildContext context) {
405+
final message = InheritedMessage.of(context);
406+
final store = PerAccountStoreWidget.of(context);
407+
final resolvedSrc = store.tryResolveUrl(node.srcUrl);
408+
409+
return MessageMediaContainer(
410+
onTap: resolvedSrc == null ? null : () { // TODO(log)
411+
Navigator.of(context).push(getLightboxRoute(
412+
context: context,
413+
message: message,
414+
src: resolvedSrc,
415+
mediaType: MediaType.video));
416+
},
417+
child: Container(
418+
color: Colors.black,
419+
alignment: Alignment.center,
420+
// To avoid potentially confusing UX, do not show play icon as
421+
// we also disable onTap above.
422+
child: resolvedSrc == null ? null : const Icon( // TODO(log)
423+
Icons.play_arrow_rounded,
424+
color: Colors.white,
425+
size: 32)));
426+
}
427+
}
428+
401429
class MessageEmbedVideo extends StatelessWidget {
402430
const MessageEmbedVideo({super.key, required this.node});
403431

lib/widgets/dialog.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,19 @@ Future<void> showErrorDialog({
1919
required BuildContext context,
2020
required String title,
2121
String? message,
22+
bool barrierDismissible = true,
23+
VoidCallback? onContinue,
2224
}) {
2325
final zulipLocalizations = ZulipLocalizations.of(context);
2426
return showDialog(
2527
context: context,
28+
barrierDismissible: barrierDismissible,
2629
builder: (BuildContext context) => AlertDialog(
2730
title: Text(title),
2831
content: message != null ? SingleChildScrollView(child: Text(message)) : null,
2932
actions: [
3033
TextButton(
31-
onPressed: () => Navigator.pop(context),
34+
onPressed: onContinue ?? () => Navigator.pop(context),
3235
child: _dialogActionText(zulipLocalizations.errorDialogContinue)),
3336
]));
3437
}

0 commit comments

Comments
 (0)