ui: Render video thumbnails in the SendFiles page
This commit is contained in:
parent
f6d85a505b
commit
f0958aad7c
@ -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;
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user