display image in chat after stored #188

This commit is contained in:
otsmr 2025-05-29 10:58:17 +02:00
parent 25d2edf89e
commit 96f4b5a136
2 changed files with 60 additions and 35 deletions

View file

@ -50,8 +50,7 @@ class _ChatMediaViewerFullScreenState extends State<ChatMediaViewerFullScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: Container( body: MediaViewSizing(
child: MediaViewSizing(
bottomNavigation: Positioned( bottomNavigation: Positioned(
bottom: 10, bottom: 10,
left: 0, left: 0,
@ -103,17 +102,18 @@ class _ChatMediaViewerFullScreenState extends State<ChatMediaViewerFullScreen> {
contact: widget.contact, contact: widget.contact,
isInFullscreen: true, isInFullscreen: true,
), ),
)), ),
); );
} }
} }
class InChatMediaViewer extends StatefulWidget { class InChatMediaViewer extends StatefulWidget {
const InChatMediaViewer( const InChatMediaViewer({
{super.key, super.key,
required this.message, required this.message,
required this.contact, required this.contact,
this.isInFullscreen = false}); this.isInFullscreen = false,
});
final Message message; final Message message;
final Contact contact; final Contact contact;
@ -129,26 +129,56 @@ class _InChatMediaViewerState extends State<InChatMediaViewer> {
bool isMounted = true; bool isMounted = true;
bool mirrorVideo = false; bool mirrorVideo = false;
VideoPlayerController? videoController; VideoPlayerController? videoController;
StreamSubscription<Message?>? messageStream;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
initAsync(); initAsync(widget.message);
initStream();
} }
Future initAsync() async { @override
if (!widget.message.mediaStored) return; void dispose() {
bool isSend = widget.message.messageOtherId == null; super.dispose();
isMounted = false;
messageStream?.cancel();
videoController?.dispose();
}
Future initStream() async {
/// When the image is opened from the chat and then stored the
/// image is not loaded so this will trigger an initAsync when mediaStored is changed
/// image is already show
if (widget.message.mediaStored) return;
final stream = twonlyDatabase.messagesDao
.getMessageByMessageId(widget.message.messageId)
.watchSingleOrNull();
messageStream = stream.listen((updated) async {
if (updated != null) {
if (updated.mediaStored) {
messageStream?.cancel();
initAsync(updated);
}
}
});
}
Future initAsync(Message message) async {
if (!message.mediaStored) return;
bool isSend = message.messageOtherId == null;
final basePath = await send.getMediaFilePath( final basePath = await send.getMediaFilePath(
isSend ? widget.message.mediaUploadId! : widget.message.messageId, isSend ? message.mediaUploadId! : message.messageId,
isSend ? "send" : "received", isSend ? "send" : "received",
); );
if (!isMounted) return; if (!isMounted) return;
final videoPath = File("$basePath.mp4"); final videoPath = File("$basePath.mp4");
final imagePath = File("$basePath.png"); final imagePath = File("$basePath.png");
if (videoPath.existsSync() && widget.message.contentJson != null) { if (videoPath.existsSync() && message.contentJson != null) {
MessageContent? content = MessageContent.fromJson( MessageContent? content = MessageContent.fromJson(
MessageKind.media, jsonDecode(widget.message.contentJson!)); MessageKind.media, jsonDecode(message.contentJson!));
if (content is MediaMessageContent) { if (content is MediaMessageContent) {
mirrorVideo = content.mirrorVideo; mirrorVideo = content.mirrorVideo;
} }
@ -178,13 +208,6 @@ class _InChatMediaViewerState extends State<InChatMediaViewer> {
} }
} }
@override
void dispose() {
super.dispose();
isMounted = false;
videoController?.dispose();
}
Future onTap() async { Future onTap() async {
if (image == null && videoController == null) return; if (image == null && videoController == null) return;
if (widget.isInFullscreen) return; if (widget.isInFullscreen) return;
@ -192,7 +215,9 @@ class _InChatMediaViewerState extends State<InChatMediaViewer> {
context, context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return ChatMediaViewerFullScreen( return ChatMediaViewerFullScreen(
message: widget.message, contact: widget.contact); message: widget.message,
contact: widget.contact,
);
}), }),
); );

View file

@ -77,6 +77,18 @@ class _MediaViewerViewState extends State<MediaViewerView> {
asyncLoadNextMedia(true); asyncLoadNextMedia(true);
} }
@override
void dispose() {
nextMediaTimer?.cancel();
progressTimer?.cancel();
_noScreenshot.screenshotOn();
_subscription.cancel();
downloadStateListener?.cancel();
videoController?.dispose();
isMounted = false;
super.dispose();
}
Future asyncLoadNextMedia(bool firstRun) async { Future asyncLoadNextMedia(bool firstRun) async {
Stream<List<Message>> messages = twonlyDatabase.messagesDao Stream<List<Message>> messages = twonlyDatabase.messagesDao
.watchMediaMessageNotOpened(widget.contact.userId); .watchMediaMessageNotOpened(widget.contact.userId);
@ -280,18 +292,6 @@ class _MediaViewerViewState extends State<MediaViewerView> {
}); });
} }
@override
void dispose() {
nextMediaTimer?.cancel();
progressTimer?.cancel();
_noScreenshot.screenshotOn();
_subscription.cancel();
downloadStateListener?.cancel();
videoController?.dispose();
isMounted = false;
super.dispose();
}
Future onPressedSaveToGallery() async { Future onPressedSaveToGallery() async {
if (allMediaFiles.first.messageOtherId == null) { if (allMediaFiles.first.messageOtherId == null) {
return; // should not be possible return; // should not be possible