ui: Render video thumbnails in the SendFiles page

This commit is contained in:
PapaTutuWawa 2022-07-25 22:24:57 +02:00
parent f6d85a505b
commit f0958aad7c
3 changed files with 75 additions and 41 deletions

View File

@ -6,6 +6,7 @@ import 'package:moxxyv2/ui/bloc/sendfiles_bloc.dart';
import 'package:moxxyv2/ui/constants.dart'; import 'package:moxxyv2/ui/constants.dart';
import 'package:moxxyv2/ui/widgets/chat/shared/base.dart'; import 'package:moxxyv2/ui/widgets/chat/shared/base.dart';
import 'package:moxxyv2/ui/widgets/chat/shared/image.dart'; import 'package:moxxyv2/ui/widgets/chat/shared/image.dart';
import 'package:moxxyv2/ui/widgets/chat/shared/video.dart';
import 'package:moxxyv2/ui/widgets/chat/thumbnail.dart'; import 'package:moxxyv2/ui/widgets/chat/thumbnail.dart';
import 'package:path/path.dart' as pathlib; import 'package:path/path.dart' as pathlib;
@ -46,6 +47,33 @@ class SendFilesPage extends StatelessWidget {
) : null, ) : null,
), ),
); );
} else if (mime.startsWith('video/')) {
return Padding(
padding: const EdgeInsets.only(right: 4),
child: SharedVideoWidget(
path,
() {
if (selected) {
// The trash can icon has been tapped
context.read<SendFilesBloc>().add(
ItemRemovedEvent(index),
);
} else {
// Another item has been tapped
context.read<SendFilesBloc>().add(
IndexSetEvent(index),
);
}
},
borderColor: selected ? Colors.blue : null,
child: selected ? const Center(
child: Icon(
Icons.delete,
size: 32,
),
) : null,
),
);
} else { } else {
// Render a generic file // Render a generic file
return Padding( return Padding(
@ -91,6 +119,13 @@ class SendFilesPage extends StatelessWidget {
path, path,
Image.memory, Image.memory,
); );
} else if (mime.startsWith('video/')) {
// Render the video thumbnail
// TODO(PapaTutuWawa): Maybe allow playing the video back inline
return VideoThumbnailWidget(
path,
Image.memory,
);
} else { } else {
// Generic file // Generic file
final width = MediaQuery.of(context).size.width; final width = MediaQuery.of(context).size.width;

View File

@ -200,12 +200,17 @@ Widget buildQuoteMessageWidget(Message message, { void Function()? resetQuote})
} }
Widget buildSharedMediaWidget(SharedMedium medium, String conversationJid) { Widget buildSharedMediaWidget(SharedMedium medium, String conversationJid) {
if (medium.mime == null) return SharedFileWidget(medium.path); if (medium.mime == null) {
return SharedFileWidget(medium.path);
if (medium.mime!.startsWith('image/')) { } else if (medium.mime!.startsWith('image/')) {
return SharedImageWidget(medium.path, () => OpenFile.open(medium.path)); return SharedImageWidget(medium.path, () => OpenFile.open(medium.path));
} else if (medium.mime!.startsWith('video/')) {
return SharedVideoWidget(
medium.path,
() => OpenFile.open(medium.path),
child: const PlayButton(),
);
} }
if (medium.mime!.startsWith('video/')) return SharedVideoWidget(medium.path, conversationJid);
// TODO(Unknown): Audio // TODO(Unknown): Audio
//if (message.mime!.startsWith("audio/")) return const SizedBox(); //if (message.mime!.startsWith("audio/")) return const SizedBox();

View File

@ -1,54 +1,48 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart'; import 'package:get_it/get_it.dart';
import 'package:moxxyv2/ui/service/thumbnail.dart'; import 'package:moxxyv2/ui/service/thumbnail.dart';
import 'package:moxxyv2/ui/widgets/chat/playbutton.dart';
import 'package:moxxyv2/ui/widgets/chat/shared/base.dart'; import 'package:moxxyv2/ui/widgets/chat/shared/base.dart';
import 'package:open_file/open_file.dart';
class SharedVideoWidget extends StatelessWidget { class SharedVideoWidget extends StatelessWidget {
const SharedVideoWidget(this.path, this.jid, { Key? key }) : super(key: key); const SharedVideoWidget(this.path, this.onTap, { this.borderColor, this.child, Key? key }) : super(key: key);
final String path; final String path;
final String jid; final Color? borderColor;
final void Function() onTap;
final Widget? child;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SharedMediaContainer( return SharedMediaContainer(
ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Stack(
alignment: Alignment.center,
children: [
FutureBuilder<Uint8List>( FutureBuilder<Uint8List>(
future: GetIt.I.get<ThumbnailCacheService>().getVideoThumbnail(path), future: GetIt.I.get<ThumbnailCacheService>().getVideoThumbnail(path),
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) { if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data != null) { return Container(
return Image.memory( decoration: BoxDecoration(
snapshot.data!, borderRadius: BorderRadius.circular(10),
border: borderColor != null ? Border.all(
color: borderColor!,
width: 4,
) : null,
image: DecorationImage(
fit: BoxFit.cover, fit: BoxFit.cover,
image: MemoryImage(snapshot.data!),
),
),
clipBehavior: Clip.hardEdge,
child: child,
); );
} else { } else {
return const Padding( return const Padding(
padding: EdgeInsets.all(32), padding: EdgeInsets.all(32),
child: Icon( child: CircularProgressIndicator(),
Icons.error_outline,
size: 32,
),
); );
} }
} else {
return const CircularProgressIndicator();
}
}, },
), ),
const PlayButton(size: 16) onTap: onTap,
],
),
),
onTap: () => OpenFile.open(path),
); );
} }
} }