From d025f24928a9666d9edee7faf7b80c94b52f2731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Wed, 28 May 2025 10:34:12 +0200 Subject: [PATCH] media-viewer: Allow to show a media without an event ID --- src/session/model/room/timeline/event/mod.rs | 15 +------ .../history_viewer/visual_media.rs | 12 +++--- .../history_viewer/visual_media_item.rs | 2 +- .../room_history/message_row/content.rs | 9 +---- .../content/room_history/message_row/mod.rs | 26 +----------- .../room_history/message_row/visual_media.rs | 33 +++++++++++---- src/session/view/media_viewer.rs | 8 ++-- src/session/view/session_view.rs | 40 ++++++++++--------- 8 files changed, 63 insertions(+), 82 deletions(-) diff --git a/src/session/model/room/timeline/event/mod.rs b/src/session/model/room/timeline/event/mod.rs index abfbf3b1..e35880f4 100644 --- a/src/session/model/room/timeline/event/mod.rs +++ b/src/session/model/room/timeline/event/mod.rs @@ -27,7 +27,7 @@ use crate::{ prelude::*, session::model::Member, spawn_tokio, - utils::matrix::{raw_eq, timestamp_to_date, MediaMessage, VisualMediaMessage}, + utils::matrix::{raw_eq, timestamp_to_date, MediaMessage}, }; /// The possible states of a message. @@ -702,19 +702,6 @@ impl Event { } } - /// The visual media message of this event, if any. - pub(crate) fn visual_media_message(&self) -> Option { - match self.item().content() { - TimelineItemContent::MsgLike(msg_like) => match &msg_like.kind { - MsgLikeKind::Message(message) => { - VisualMediaMessage::from_message(message.msgtype()) - } - _ => None, - }, - _ => None, - } - } - /// Whether this event might contain an `@room` mention. /// /// This means that either it does not have intentional mentions, or it has diff --git a/src/session/view/content/room_details/history_viewer/visual_media.rs b/src/session/view/content/room_details/history_viewer/visual_media.rs index 5f20d811..a1fe64f3 100644 --- a/src/session/view/content/room_details/history_viewer/visual_media.rs +++ b/src/session/view/content/room_details/history_viewer/visual_media.rs @@ -231,8 +231,8 @@ mod imp { self.stack.set_visible_child_name(visible_child_name); } - /// Show the given media item. - pub(super) fn show_media(&self, item: &VisualMediaItem) { + /// Show the given media item in the media viewer. + pub(super) fn show_media_viewer(&self, item: &VisualMediaItem) { let Some(event) = item.event() else { return; }; @@ -244,7 +244,7 @@ mod imp { .visual_media_message() .expect("visual media items should contain only visual message content"); self.media_viewer - .set_message(&room, event.event_id(), media_message); + .set_message(&room, media_message, Some(event.event_id())); self.media_viewer.reveal(item); } } @@ -263,8 +263,8 @@ impl VisualMediaHistoryViewer { .build() } - /// Show the given media item. - pub(crate) fn show_media(&self, item: &VisualMediaItem) { - self.imp().show_media(item); + /// Show the given media item in the media viewer. + pub(crate) fn show_media_viewer(&self, item: &VisualMediaItem) { + self.imp().show_media_viewer(item); } } diff --git a/src/session/view/content/room_details/history_viewer/visual_media_item.rs b/src/session/view/content/room_details/history_viewer/visual_media_item.rs index 73fd20f5..248ebba3 100644 --- a/src/session/view/content/room_details/history_viewer/visual_media_item.rs +++ b/src/session/view/content/room_details/history_viewer/visual_media_item.rs @@ -227,7 +227,7 @@ mod imp { return; }; - media_history_viewer.show_media(&obj); + media_history_viewer.show_media_viewer(&obj); } } } diff --git a/src/session/view/content/room_history/message_row/content.rs b/src/session/view/content/room_history/message_row/content.rs index 7beb55ec..44db39e4 100644 --- a/src/session/view/content/room_history/message_row/content.rs +++ b/src/session/view/content/room_history/message_row/content.rs @@ -56,7 +56,7 @@ mod imp { #[property(get = Self::texture)] texture: PhantomData>, /// The widget with the visual media content of the event, if any. - pub(super) visual_media_widget: glib::WeakRef, + visual_media_widget: glib::WeakRef, } #[glib::object_subclass] @@ -152,11 +152,6 @@ impl MessageContent { glib::Object::new() } - /// The widget with the visual media content of the event, if any. - pub(crate) fn visual_media_widget(&self) -> Option { - self.imp().visual_media_widget.upgrade() - } - /// Update this widget to present the given `Event`. pub(crate) fn update_for_event(&self, event: &Event) { let detect_at_room = event.can_contain_at_room() && event.sender().can_notify_room(); @@ -490,7 +485,7 @@ pub(crate) struct MessageCacheKey { /// /// Local echo that was sent and remote echo should have the same event ID, /// so we do not need to reload the message if it did not change. - event_id: Option, + pub(crate) event_id: Option, /// Whether the message is edited. /// /// The message must be reloaded when it was edited. diff --git a/src/session/view/content/room_history/message_row/mod.rs b/src/session/view/content/room_history/message_row/mod.rs index d2ba87a8..47e6b190 100644 --- a/src/session/view/content/room_history/message_row/mod.rs +++ b/src/session/view/content/room_history/message_row/mod.rs @@ -1,6 +1,5 @@ use adw::{prelude::*, subclass::prelude::*}; use gtk::{gdk, glib, glib::clone, CompositeTemplate}; -use tracing::warn; mod audio; mod caption; @@ -23,7 +22,7 @@ use crate::{ session::model::{Event, EventHeaderState}, system_settings::ClockFormat, utils::BoundObject, - Application, Window, + Application, }; mod imp { @@ -74,10 +73,6 @@ mod imp { fn class_init(klass: &mut Self::Class) { Self::bind_template(klass); - - klass.install_action("message-row.show-media", None, |obj, _, _| { - obj.imp().show_media(); - }); } fn instance_init(obj: &InitializingObject) { @@ -266,25 +261,6 @@ mod imp { pub(super) fn texture(&self) -> Option { self.content.texture() } - - /// Open the media viewer with the media content of this row. - fn show_media(&self) { - let Some(window) = self.obj().root().and_downcast::() else { - return; - }; - let Some(event) = self.event.obj() else { - return; - }; - - let Some(visual_media_widget) = self.content.visual_media_widget() else { - warn!("Trying to show media of a non-media message"); - return; - }; - - window - .session_view() - .show_media(&event, &visual_media_widget); - } } } diff --git a/src/session/view/content/room_history/message_row/visual_media.rs b/src/session/view/content/room_history/message_row/visual_media.rs index 5369bf49..67536f8c 100644 --- a/src/session/view/content/room_history/message_row/visual_media.rs +++ b/src/session/view/content/room_history/message_row/visual_media.rs @@ -2,7 +2,7 @@ use adw::{prelude::*, subclass::prelude::*}; use gettextrs::gettext; use gtk::{gdk, glib, glib::clone, CompositeTemplate}; use ruma::api::client::media::get_content_thumbnail::v3::Method; -use tracing::{error, warn}; +use tracing::warn; use super::{content::MessageCacheKey, ContentFormat}; use crate::{ @@ -19,6 +19,7 @@ use crate::{ }, CountedRef, File, LoadingState, TemplateCallbacks, }, + Window, }; /// The dimensions to use for the media until we know its size. @@ -813,14 +814,32 @@ mod imp { fn activate(&self) { if self.state.get() == LoadingState::Initial { self.show_media(); - } else if self - .obj() - .activate_action("message-row.show-media", None) - .is_err() - { - error!("Could not activate `message-row.show-media` action"); + } else { + self.show_media_viewer(); } } + + /// Open the media viewer with the media content of this row. + fn show_media_viewer(&self) { + let Some(room) = self.room.upgrade() else { + return; + }; + let Some(media_message) = self.media_message.borrow().clone() else { + return; + }; + + let obj = self.obj(); + + let Some(window) = obj.root().and_downcast::() else { + return; + }; + + let event_id = self.cache_key.borrow().event_id.clone(); + + window + .session_view() + .show_media_viewer(&*self.obj(), &room, media_message, event_id); + } } } diff --git a/src/session/view/media_viewer.rs b/src/session/view/media_viewer.rs index bbeebbbc..ea968c00 100644 --- a/src/session/view/media_viewer.rs +++ b/src/session/view/media_viewer.rs @@ -225,11 +225,11 @@ mod imp { pub(super) fn set_message( &self, room: &Room, - event_id: OwnedEventId, message: VisualMediaMessage, + event_id: Option, ) { self.room.set(Some(room)); - self.event_id.replace(Some(event_id)); + self.event_id.replace(event_id); self.set_filename(message.filename()); self.message.replace(Some(message)); @@ -523,9 +523,9 @@ impl MediaViewer { pub(crate) fn set_message( &self, room: &Room, - event_id: OwnedEventId, message: VisualMediaMessage, + event_id: Option, ) { - self.imp().set_message(room, event_id, message); + self.imp().set_message(room, message, event_id); } } diff --git a/src/session/view/session_view.rs b/src/session/view/session_view.rs index 2cbe3f94..6479d73c 100644 --- a/src/session/view/session_view.rs +++ b/src/session/view/session_view.rs @@ -1,18 +1,17 @@ use adw::{prelude::*, subclass::prelude::*}; use gtk::{gdk, glib, glib::clone, CompositeTemplate}; -use ruma::{OwnedUserId, RoomId, RoomOrAliasId}; +use ruma::{OwnedEventId, OwnedUserId, RoomId, RoomOrAliasId}; use tracing::{error, warn}; use super::{Content, CreateDirectChatDialog, CreateRoomDialog, MediaViewer, Sidebar}; use crate::{ components::{RoomPreviewDialog, UserProfileDialog}, intent::SessionIntent, - prelude::*, session::model::{ - Event, IdentityVerification, Room, RoomCategory, RoomList, Session, SidebarItemList, + IdentityVerification, Room, RoomCategory, RoomList, Session, SidebarItemList, SidebarListModel, VerificationKey, }, - utils::matrix::{MatrixEventIdUri, MatrixIdUri, MatrixRoomIdUri}, + utils::matrix::{MatrixEventIdUri, MatrixIdUri, MatrixRoomIdUri, VisualMediaMessage}, Window, }; @@ -504,17 +503,15 @@ mod imp { self.content.handle_paste_action(); } - /// Show the given media event. - pub(super) fn show_media(&self, event: &Event, source_widget: >k::Widget) { - let Some(media_message) = event.visual_media_message() else { - error!( - "Trying to open the media viewer with an event that is not a visual media message" - ); - return; - }; - - self.media_viewer - .set_message(&event.room(), event.event_id().unwrap(), media_message); + /// Show the given media event in the media viewer. + pub(super) fn show_media_viewer( + &self, + source_widget: >k::Widget, + room: &Room, + media_message: VisualMediaMessage, + event_id: Option, + ) { + self.media_viewer.set_message(room, media_message, event_id); self.media_viewer.reveal(source_widget); } @@ -595,9 +592,16 @@ impl SessionView { self.imp().handle_paste_action(); } - /// Show a media event. - pub(crate) fn show_media(&self, event: &Event, source_widget: &impl IsA) { - self.imp().show_media(event, source_widget.upcast_ref()); + /// Show the given media event in the media viewer. + pub(crate) fn show_media_viewer( + &self, + source_widget: &impl IsA, + room: &Room, + media_message: VisualMediaMessage, + event_id: Option, + ) { + self.imp() + .show_media_viewer(source_widget.upcast_ref(), room, media_message, event_id); } /// Show the given `MatrixIdUri`.