From 9223e454107625d5d52f5eccd28c8c551f0ede2f Mon Sep 17 00:00:00 2001 From: Alexandre Franke Date: Mon, 14 Apr 2025 17:45:37 +0200 Subject: [PATCH] wip: make a dedicated widget --- .../room_history/message_row/content.rs | 61 ++++---------- .../content/room_history/message_row/info.rs | 79 +++++++++++++++++++ .../content/room_history/message_row/info.ui | 25 ++++++ .../content/room_history/message_row/mod.rs | 1 + 4 files changed, 120 insertions(+), 46 deletions(-) create mode 100644 src/session/view/content/room_history/message_row/info.rs create mode 100644 src/session/view/content/room_history/message_row/info.ui 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 88865501..ecdcc105 100644 --- a/src/session/view/content/room_history/message_row/content.rs +++ b/src/session/view/content/room_history/message_row/content.rs @@ -6,8 +6,14 @@ use ruma::{events::room::message::MessageType, OwnedEventId, OwnedTransactionId} use tracing::{error, warn}; use super::{ - audio::MessageAudio, caption::MessageCaption, file::MessageFile, location::MessageLocation, - reply::MessageReply, text::MessageText, visual_media::MessageVisualMedia, + audio::MessageAudio, + caption::MessageCaption, + file::MessageFile, + info::{MessageIcon, MessageInfo}, + location::MessageLocation, + reply::MessageReply, + text::MessageText, + visual_media::MessageVisualMedia, }; use crate::{ prelude::*, @@ -40,20 +46,6 @@ pub enum ContentFormat { Ellipsized = 2, } -enum MessageIcon { - Info, - Warning, -} - -impl MessageIcon { - fn icon_name(self) -> &'static str { - match self { - MessageIcon::Info => "info-symbolic", - MessageIcon::Warning => "warning-symbolic", - } - } -} - mod imp { use std::cell::Cell; @@ -293,9 +285,10 @@ trait MessageContentContainer: IsA { ); } MsgLikeKind::UnableToDecrypt(_) => { - self.build_info_message_content( - &gettext("Could not decrypt this message, decryption will be retried once the keys are available."), - MessageIcon::Warning, + let child = self.reuse_child_or_default::(); + child.set_icon(MessageIcon::Warning); + child.set_text( + &gettext("Could not decrypt this message, decryption will be retried once the keys are available.") ); } msg_like_kind => { @@ -365,7 +358,9 @@ trait MessageContentContainer: IsA { ); } MessageType::ServerNotice(message) => { - self.build_info_message_content(&message.body.clone(), MessageIcon::Info); + let child = self.reuse_child_or_default::(); + child.set_icon(MessageIcon::Info); + child.set_text(&message.body.clone()); } MessageType::Text(message) => { let child = self.reuse_child_or_default::(); @@ -385,32 +380,6 @@ trait MessageContentContainer: IsA { } } - /// Build the content widget of the given informative message as a child - /// of this widget - fn build_info_message_content(&self, label: &str, icon: MessageIcon) { - let child = gtk::Grid::new(); - let icon_widget = gtk::Image::new(); - let icon_name = icon.icon_name(); - icon_widget.set_icon_name(Some(icon_name)); - icon_widget.set_margin_start(6); - icon_widget.set_margin_end(12); - let label_widget = gtk::Label::new(Some(label)); - label_widget.set_css_classes(&["dimmed"]); - label_widget.set_wrap(true); - label_widget.set_wrap_mode(gtk::pango::WrapMode::WordChar); - label_widget.set_xalign(0.0); - label_widget.set_hexpand(true); - child.attach(&icon_widget, 0, 0, 1, 1); - child.attach_next_to( - &label_widget, - Some(&icon_widget), - gtk::PositionType::Right, - 1, - 1, - ); - self.set_child(Some(child.clone().upcast())); - } - /// Build the content widget of the given media message as a child of this /// widget. fn build_media_message_content( diff --git a/src/session/view/content/room_history/message_row/info.rs b/src/session/view/content/room_history/message_row/info.rs new file mode 100644 index 00000000..57e720e7 --- /dev/null +++ b/src/session/view/content/room_history/message_row/info.rs @@ -0,0 +1,79 @@ +use adw::{prelude::*, subclass::prelude::*}; +use gtk::{glib, CompositeTemplate}; + +#[derive(Default)] +pub(crate) enum MessageIcon { + #[default] + Info, + Warning, +} + +impl MessageIcon { + fn icon_name(self) -> &'static str { + match self { + MessageIcon::Info => "info-symbolic", + MessageIcon::Warning => "warning-symbolic", + } + } +} + +mod imp { + use glib::subclass::InitializingObject; + + use super::*; + + #[derive(Debug, Default, CompositeTemplate)] + #[template( + resource = "/org/gnome/Fractal/ui/session/view/content/room_history/message_row/info.ui" + )] + pub struct MessageInfo { + #[template_child] + icon: TemplateChild, + #[template_child] + description: TemplateChild, + } + + #[glib::object_subclass] + impl ObjectSubclass for MessageInfo { + const NAME: &'static str = "ContentMessageInfo"; + type Type = super::MessageInfo; + type ParentType = adw::Bin; + + fn class_init(klass: &mut Self::Class) { + Self::bind_template(klass); + } + + fn instance_init(obj: &InitializingObject) { + obj.init_template(); + } + } + + impl ObjectImpl for MessageInfo {} + impl WidgetImpl for MessageInfo {} + impl BinImpl for MessageInfo {} + + impl MessageInfo { + pub(super) fn set_icon(&self, icon: MessageIcon) { + self.icon.set_icon_name(Some(icon.icon_name())); + } + + pub(super) fn set_text(&self, text: String) { + self.description.set_text(&text); + } + } +} + +glib::wrapper! { + /// A widget presenting an informative event. + pub struct MessageInfo(ObjectSubclass) + @extends gtk::Widget, adw::Bin, @implements gtk::Accessible; +} + +impl MessageInfo { + pub fn new() -> Self { + let obj: Self = glib::Object::new(); + obj.imp().set_icon(Some(MessageIcon::Info)); + obj.imp().set_text(""); + obj + } +} diff --git a/src/session/view/content/room_history/message_row/info.ui b/src/session/view/content/room_history/message_row/info.ui new file mode 100644 index 00000000..63565e98 --- /dev/null +++ b/src/session/view/content/room_history/message_row/info.ui @@ -0,0 +1,25 @@ + + + + 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 a7cab953..e7ad71cd 100644 --- a/src/session/view/content/room_history/message_row/mod.rs +++ b/src/session/view/content/room_history/message_row/mod.rs @@ -6,6 +6,7 @@ mod audio; mod caption; mod content; mod file; +mod info; mod location; mod message_state_stack; mod reaction;