From 96f4b5a136308d2459b90f40aa45f1c302de07ef Mon Sep 17 00:00:00 2001 From: otsmr Date: Thu, 29 May 2025 10:58:17 +0200 Subject: [PATCH] display image in chat after stored #188 --- .../components/in_chat_media_viewer.dart | 71 +++++++++++++------ lib/src/views/chats/media_viewer_view.dart | 24 +++---- 2 files changed, 60 insertions(+), 35 deletions(-) diff --git a/lib/src/views/chats/components/in_chat_media_viewer.dart b/lib/src/views/chats/components/in_chat_media_viewer.dart index ab1a930..0418e62 100644 --- a/lib/src/views/chats/components/in_chat_media_viewer.dart +++ b/lib/src/views/chats/components/in_chat_media_viewer.dart @@ -50,8 +50,7 @@ class _ChatMediaViewerFullScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - body: Container( - child: MediaViewSizing( + body: MediaViewSizing( bottomNavigation: Positioned( bottom: 10, left: 0, @@ -103,17 +102,18 @@ class _ChatMediaViewerFullScreenState extends State { contact: widget.contact, isInFullscreen: true, ), - )), + ), ); } } class InChatMediaViewer extends StatefulWidget { - const InChatMediaViewer( - {super.key, - required this.message, - required this.contact, - this.isInFullscreen = false}); + const InChatMediaViewer({ + super.key, + required this.message, + required this.contact, + this.isInFullscreen = false, + }); final Message message; final Contact contact; @@ -129,26 +129,56 @@ class _InChatMediaViewerState extends State { bool isMounted = true; bool mirrorVideo = false; VideoPlayerController? videoController; + StreamSubscription? messageStream; @override void initState() { super.initState(); - initAsync(); + initAsync(widget.message); + initStream(); } - Future initAsync() async { - if (!widget.message.mediaStored) return; - bool isSend = widget.message.messageOtherId == null; + @override + void dispose() { + 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( - isSend ? widget.message.mediaUploadId! : widget.message.messageId, + isSend ? message.mediaUploadId! : message.messageId, isSend ? "send" : "received", ); if (!isMounted) return; final videoPath = File("$basePath.mp4"); final imagePath = File("$basePath.png"); - if (videoPath.existsSync() && widget.message.contentJson != null) { + if (videoPath.existsSync() && message.contentJson != null) { MessageContent? content = MessageContent.fromJson( - MessageKind.media, jsonDecode(widget.message.contentJson!)); + MessageKind.media, jsonDecode(message.contentJson!)); if (content is MediaMessageContent) { mirrorVideo = content.mirrorVideo; } @@ -178,13 +208,6 @@ class _InChatMediaViewerState extends State { } } - @override - void dispose() { - super.dispose(); - isMounted = false; - videoController?.dispose(); - } - Future onTap() async { if (image == null && videoController == null) return; if (widget.isInFullscreen) return; @@ -192,7 +215,9 @@ class _InChatMediaViewerState extends State { context, MaterialPageRoute(builder: (context) { return ChatMediaViewerFullScreen( - message: widget.message, contact: widget.contact); + message: widget.message, + contact: widget.contact, + ); }), ); diff --git a/lib/src/views/chats/media_viewer_view.dart b/lib/src/views/chats/media_viewer_view.dart index f84a474..cb0c6b6 100644 --- a/lib/src/views/chats/media_viewer_view.dart +++ b/lib/src/views/chats/media_viewer_view.dart @@ -77,6 +77,18 @@ class _MediaViewerViewState extends State { 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 { Stream> messages = twonlyDatabase.messagesDao .watchMediaMessageNotOpened(widget.contact.userId); @@ -280,18 +292,6 @@ class _MediaViewerViewState extends State { }); } - @override - void dispose() { - nextMediaTimer?.cancel(); - progressTimer?.cancel(); - _noScreenshot.screenshotOn(); - _subscription.cancel(); - downloadStateListener?.cancel(); - videoController?.dispose(); - isMounted = false; - super.dispose(); - } - Future onPressedSaveToGallery() async { if (allMediaFiles.first.messageOtherId == null) { return; // should not be possible