Browse Source

media-viewer: Allow to show a media without an event ID

fractal-12
Kévin Commaille 10 months ago
parent
commit
d025f24928
No known key found for this signature in database
GPG Key ID: F26F4BE20A08255B
  1. 15
      src/session/model/room/timeline/event/mod.rs
  2. 12
      src/session/view/content/room_details/history_viewer/visual_media.rs
  3. 2
      src/session/view/content/room_details/history_viewer/visual_media_item.rs
  4. 9
      src/session/view/content/room_history/message_row/content.rs
  5. 26
      src/session/view/content/room_history/message_row/mod.rs
  6. 33
      src/session/view/content/room_history/message_row/visual_media.rs
  7. 8
      src/session/view/media_viewer.rs
  8. 40
      src/session/view/session_view.rs

15
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<VisualMediaMessage> {
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

12
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);
}
}

2
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);
}
}
}

9
src/session/view/content/room_history/message_row/content.rs

@ -56,7 +56,7 @@ mod imp {
#[property(get = Self::texture)]
texture: PhantomData<Option<gdk::Texture>>,
/// The widget with the visual media content of the event, if any.
pub(super) visual_media_widget: glib::WeakRef<MessageVisualMedia>,
visual_media_widget: glib::WeakRef<MessageVisualMedia>,
}
#[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<MessageVisualMedia> {
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<OwnedEventId>,
pub(crate) event_id: Option<OwnedEventId>,
/// Whether the message is edited.
///
/// The message must be reloaded when it was edited.

26
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<Self>) {
@ -266,25 +261,6 @@ mod imp {
pub(super) fn texture(&self) -> Option<gdk::Texture> {
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::<Window>() 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);
}
}
}

33
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::<Window>() 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);
}
}
}

8
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<OwnedEventId>,
) {
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<OwnedEventId>,
) {
self.imp().set_message(room, event_id, message);
self.imp().set_message(room, message, event_id);
}
}

40
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: &gtk::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: &gtk::Widget,
room: &Room,
media_message: VisualMediaMessage,
event_id: Option<OwnedEventId>,
) {
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<gtk::Widget>) {
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<gtk::Widget>,
room: &Room,
media_message: VisualMediaMessage,
event_id: Option<OwnedEventId>,
) {
self.imp()
.show_media_viewer(source_widget.upcast_ref(), room, media_message, event_id);
}
/// Show the given `MatrixIdUri`.

Loading…
Cancel
Save