Merge pull request #1390 from GetStream/fix/video-thumbnail-on-web-not-showing

This commit is contained in:
Sahil Kumar
2022-12-07 14:01:01 +05:30
committed by GitHub
8 changed files with 27 additions and 13 deletions
@@ -9,6 +9,7 @@
🐞 Fixed 🐞 Fixed
- [[#1379]](https://github.com/GetStream/stream-chat-flutter/issues/1379) Fixed "Issues with photo attachments on web", where the cached image attachment would not render while uploading. - [[#1379]](https://github.com/GetStream/stream-chat-flutter/issues/1379) Fixed "Issues with photo attachments on web", where the cached image attachment would not render while uploading.
- Fix render overflow issue with `MessageSearchListTileTitle`. It now uses `Text.rich` instead of `Row`. Better default behaviour and allows `TextOverflow`. - Fix render overflow issue with `MessageSearchListTileTitle`. It now uses `Text.rich` instead of `Row`. Better default behaviour and allows `TextOverflow`.
- [[1346]](https://github.com/GetStream/stream-chat-flutter/issues/1346) Fixed a render issue while uploading video on web.
- [[#1347]](https://github.com/GetStream/stream-chat-flutter/issues/1347) `onReply` not working in `AttachmentActionsModal` which is used by `StreamImageAttachment` and `StreamImageGroup`. - [[#1347]](https://github.com/GetStream/stream-chat-flutter/issues/1347) `onReply` not working in `AttachmentActionsModal` which is used by `StreamImageAttachment` and `StreamImageGroup`.
## 5.1.0 ## 5.1.0
@@ -195,7 +195,7 @@ class _FileTypeImage extends StatelessWidget {
shape: _getDefaultShape(context), shape: _getDefaultShape(context),
child: source.when( child: source.when(
local: () => StreamVideoThumbnailImage( local: () => StreamVideoThumbnailImage(
video: attachment.file!.path!, video: attachment.file!.path,
placeholderBuilder: (_) => const Center( placeholderBuilder: (_) => const Center(
child: SizedBox( child: SizedBox(
width: 20, width: 20,
@@ -205,7 +205,7 @@ class _FileTypeImage extends StatelessWidget {
), ),
), ),
network: () => StreamVideoThumbnailImage( network: () => StreamVideoThumbnailImage(
video: attachment.assetUrl!, video: attachment.assetUrl,
placeholderBuilder: (_) => const Center( placeholderBuilder: (_) => const Center(
child: SizedBox( child: SizedBox(
width: 20, width: 20,
@@ -41,7 +41,7 @@ class StreamVideoAttachment extends StreamAttachmentWidget {
return _buildVideoAttachment( return _buildVideoAttachment(
context, context,
StreamVideoThumbnailImage( StreamVideoThumbnailImage(
video: attachment.file!.path!, video: attachment.file!.path,
thumbUrl: attachment.thumbUrl, thumbUrl: attachment.thumbUrl,
constraints: constraints, constraints: constraints,
), ),
@@ -54,7 +54,7 @@ class StreamVideoAttachment extends StreamAttachmentWidget {
return _buildVideoAttachment( return _buildVideoAttachment(
context, context,
StreamVideoThumbnailImage( StreamVideoThumbnailImage(
video: attachment.assetUrl!, video: attachment.assetUrl,
thumbUrl: attachment.thumbUrl, thumbUrl: attachment.thumbUrl,
constraints: constraints, constraints: constraints,
), ),
@@ -219,8 +219,8 @@ class _StreamGalleryFooterState extends State<StreamGalleryFooter> {
child: AspectRatio( child: AspectRatio(
aspectRatio: 1, aspectRatio: 1,
child: StreamVideoThumbnailImage( child: StreamVideoThumbnailImage(
video: (attachment.file?.path ?? video:
attachment.assetUrl)!, attachment.file?.path ?? attachment.assetUrl,
), ),
), ),
), ),
@@ -276,7 +276,7 @@ class _ParseAttachments extends StatelessWidget {
'video': (_, attachment) { 'video': (_, attachment) {
return StreamVideoThumbnailImage( return StreamVideoThumbnailImage(
key: ValueKey(attachment.assetUrl), key: ValueKey(attachment.assetUrl),
video: attachment.file?.path ?? attachment.assetUrl!, video: attachment.file?.path ?? attachment.assetUrl,
constraints: BoxConstraints.loose(const Size(32, 32)), constraints: BoxConstraints.loose(const Size(32, 32)),
errorBuilder: (_, __) => AttachmentError( errorBuilder: (_, __) => AttachmentError(
constraints: BoxConstraints.loose(const Size(32, 32)), constraints: BoxConstraints.loose(const Size(32, 32)),
@@ -1194,7 +1194,7 @@ class StreamMessageInputState extends State<StreamMessageInput>
104, 104,
), ),
), ),
video: (attachment.file?.path ?? attachment.assetUrl)!, video: attachment.file?.path ?? attachment.assetUrl,
), ),
Positioned( Positioned(
left: 8, left: 8,
@@ -21,6 +21,9 @@ class _IVideoService {
/// ///
/// Thumbnails are not supported on Web at this time. /// Thumbnails are not supported on Web at this time.
/// ///
/// If no [video] path is supplied, or if a thumbnail cannot be generated,
/// returns [generatePlaceholderThumbnail]. A stock placeholder image.
///
/// For desktop, you can specify the position of the video to generate /// For desktop, you can specify the position of the video to generate
/// the thumbnail. /// the thumbnail.
/// ///
@@ -29,14 +32,14 @@ class _IVideoService {
/// creates lower quality of the thumbnail image, but it gets ignored for /// creates lower quality of the thumbnail image, but it gets ignored for
/// PNG format. /// PNG format.
Future<Uint8List?> generateVideoThumbnail({ Future<Uint8List?> generateVideoThumbnail({
required String video, String? video,
ImageFormat imageFormat = ImageFormat.PNG, ImageFormat imageFormat = ImageFormat.PNG,
int maxHeight = 0, int maxHeight = 0,
int maxWidth = 0, int maxWidth = 0,
int timeMs = 0, int timeMs = 0,
int quality = 10, int quality = 10,
}) async { }) async {
if (kIsWeb) { if (kIsWeb || video == null) {
final placeholder = await generatePlaceholderThumbnail(); final placeholder = await generatePlaceholderThumbnail();
return placeholder; return placeholder;
} }
@@ -8,13 +8,23 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:video_thumbnail/video_thumbnail.dart'; import 'package:video_thumbnail/video_thumbnail.dart';
/// {@template streamVideoThumbnailImage} /// {@template streamVideoThumbnailImage}
/// Displays a video thumbnail for video attachments in a message. /// Displays a video thumbnail for video attachments.
///
/// [thumbUrl] is used if provided.
///
/// Else [video] (path to local or remote video) is used to generate
/// a thumbnail from the video asset.
///
/// WARNING! a local path does not work on web.
///
/// If both [thumbUrl] and [video] are null, or if a thumbnail can't be
/// generated, a stock default image will be used.
/// {@endtemplate} /// {@endtemplate}
class StreamVideoThumbnailImage extends StatefulWidget { class StreamVideoThumbnailImage extends StatefulWidget {
/// {@macro streamVideoThumbnailImage} /// {@macro streamVideoThumbnailImage}
const StreamVideoThumbnailImage({ const StreamVideoThumbnailImage({
super.key, super.key,
required this.video, this.video,
this.thumbUrl, this.thumbUrl,
this.constraints, this.constraints,
this.fit = BoxFit.cover, this.fit = BoxFit.cover,
@@ -24,7 +34,7 @@ class StreamVideoThumbnailImage extends StatefulWidget {
}); });
/// Video path or url /// Video path or url
final String video; final String? video;
/// Video thumbnail url /// Video thumbnail url
final String? thumbUrl; final String? thumbUrl;