Browse Source

room-history: Add quick reaction chooser dynamically

Avoids to have duplicate menus just to add or remove it. It will avoid
possible duplication errors when changing the menu.
pipelines/786320
Kévin Commaille 1 year ago
parent
commit
aee4319640
No known key found for this signature in database
GPG Key ID: C971D9DBC9D678D
  1. 5
      po/POTFILES.in
  2. 2
      src/components/mod.rs
  3. 213
      src/session/view/content/room_history/event_actions.ui
  4. 89
      src/session/view/content/room_history/event_context_menu.ui
  5. 165
      src/session/view/content/room_history/item_row.rs
  6. 94
      src/session/view/content/room_history/item_row_context_menu.rs
  7. 56
      src/session/view/content/room_history/mod.rs
  8. 4
      src/session/view/content/room_history/quick_reaction_chooser.ui
  9. 4
      src/ui-resources.gresource.xml

5
po/POTFILES.in

@ -25,7 +25,6 @@ src/components/dialogs/user_profile.ui
src/components/offline_banner.rs
src/components/media/content_viewer.rs
src/components/media/location_viewer.rs
src/components/quick_reaction_chooser.ui
src/components/pill/at_room.rs
src/components/power_level_selection/popover.ui
src/components/rows/loading_row.ui
@ -135,8 +134,9 @@ src/session/view/content/room_details/permissions/permissions_subpage.rs
src/session/view/content/room_details/permissions/permissions_subpage.ui
src/session/view/content/room_details/room_upgrade_dialog.rs
src/session/view/content/room_history/divider_row.rs
src/session/view/content/room_history/event_actions.ui
src/session/view/content/room_history/event_context_menu.ui
src/session/view/content/room_history/item_row.rs
src/session/view/content/room_history/item_row_context_menu.rs
src/session/view/content/room_history/message_row/audio.rs
src/session/view/content/room_history/message_row/content.rs
src/session/view/content/room_history/message_row/file.rs
@ -157,6 +157,7 @@ src/session/view/content/room_history/message_toolbar/mod.ui
src/session/view/content/room_history/member_timestamp/row.rs
src/session/view/content/room_history/mod.rs
src/session/view/content/room_history/mod.ui
src/session/view/content/room_history/quick_reaction_chooser.ui
src/session/view/content/room_history/read_receipts_list/mod.rs
src/session/view/content/room_history/sender_avatar/mod.rs
src/session/view/content/room_history/sender_avatar/mod.ui

2
src/components/mod.rs

@ -11,7 +11,6 @@ mod media;
mod offline_banner;
mod pill;
mod power_level_selection;
mod quick_reaction_chooser;
mod role_badge;
mod rows;
mod scale_revealer;
@ -30,7 +29,6 @@ pub(crate) use self::{
offline_banner::OfflineBanner,
pill::*,
power_level_selection::*,
quick_reaction_chooser::QuickReactionChooser,
role_badge::RoleBadge,
rows::*,
scale_revealer::ScaleRevealer,

213
src/session/view/content/room_history/event_actions.ui

@ -1,213 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="message_menu_model_with_reactions">
<section>
<item>
<attribute name="custom">quick-reaction-chooser</attribute>
</item>
</section>
<section>
<item>
<!-- Translators: In this string, 'Reply' is a verb. -->
<attribute name="label" translatable="yes">_Reply</attribute>
<attribute name="action">event.reply</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<!-- Translators: In this string, 'Edit' is a verb. -->
<attribute name="label" translatable="yes">_Edit</attribute>
<attribute name="action">event.edit</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<!-- Translators: In this string, 'Forward' is a verb, this is to
re-send the same message in another room, like forwarding an e-mail. -->
<attribute name="label" translatable="yes">_Forward</attribute>
<attribute name="action">event.forward</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Select</attribute>
<attribute name="action">event.select</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Copy Text</attribute>
<attribute name="action">event.copy-text</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Copy T_humbnail</attribute>
<attribute name="action">event.copy-image</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">S_ave Image</attribute>
<attribute name="action">event.save-image</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">S_ave Video</attribute>
<attribute name="action">event.save-video</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">S_ave Audio</attribute>
<attribute name="action">event.save-audio</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Copy Message _Link</attribute>
<attribute name="action">event.permalink</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_View Details</attribute>
<attribute name="action">event.view-details</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Discard</attribute>
<attribute name="action">event.cancel-send</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Rep_ort…</attribute>
<attribute name="action">event.report</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Re_move</attribute>
<attribute name="action">event.remove</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
</menu>
<menu id="message_menu_model_no_reactions">
<section>
<item>
<!-- Translators: In this string, 'Reply' is a verb. -->
<attribute name="label" translatable="yes">_Reply</attribute>
<attribute name="action">event.reply</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<!-- Translators: In this string, 'Edit' is a verb. -->
<attribute name="label" translatable="yes">_Edit</attribute>
<attribute name="action">event.edit</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<!-- Translators: In this string, 'Forward' is a verb, this is to
re-send the same message in another room, like forwarding an e-mail. -->
<attribute name="label" translatable="yes">_Forward</attribute>
<attribute name="action">event.forward</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Select</attribute>
<attribute name="action">event.select</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Copy Text</attribute>
<attribute name="action">event.copy-text</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Copy Thumbnail</attribute>
<attribute name="action">event.copy-image</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">S_ave Image</attribute>
<attribute name="action">event.save-image</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">S_ave Video</attribute>
<attribute name="action">event.save-video</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">S_ave Audio</attribute>
<attribute name="action">event.save-audio</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Copy Message _Link</attribute>
<attribute name="action">event.permalink</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_View Details</attribute>
<attribute name="action">event.view-details</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Discard</attribute>
<attribute name="action">event.cancel-send</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Rep_ort</attribute>
<attribute name="action">event.report</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Re_move</attribute>
<attribute name="action">event.remove</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
</menu>
<menu id="state_menu_model">
<section>
<item>
<attribute name="label" translatable="yes">_Select</attribute>
<attribute name="action">event.select</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Copy Message _Link</attribute>
<attribute name="action">event.permalink</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_View Details</attribute>
<attribute name="action">event.view-details</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Rep_ort</attribute>
<attribute name="action">event.report</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Re_move</attribute>
<attribute name="action">event.remove</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
</menu>
</interface>

89
src/session/view/content/room_history/event_context_menu.ui

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="event-menu">
<section>
<item>
<!-- Translators: In this string, 'Reply' is a verb. -->
<attribute name="label" translatable="yes">_Reply</attribute>
<attribute name="action">event.reply</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<!-- Translators: In this string, 'Edit' is a verb. -->
<attribute name="label" translatable="yes">_Edit</attribute>
<attribute name="action">event.edit</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<!-- Translators: In this string, 'Forward' is a verb, this is to
re-send the same message in another room, like forwarding an e-mail. -->
<attribute name="label" translatable="yes">_Forward</attribute>
<attribute name="action">event.forward</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Select</attribute>
<attribute name="action">event.select</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Copy Text</attribute>
<attribute name="action">event.copy-text</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Copy T_humbnail</attribute>
<attribute name="action">event.copy-image</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">S_ave Image</attribute>
<attribute name="action">event.save-image</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">S_ave Video</attribute>
<attribute name="action">event.save-video</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">S_ave Audio</attribute>
<attribute name="action">event.save-audio</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Copy Message _Link</attribute>
<attribute name="action">event.permalink</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_View Details</attribute>
<attribute name="action">event.view-details</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Discard</attribute>
<attribute name="action">event.cancel-send</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Rep_ort…</attribute>
<attribute name="action">event.report</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Re_move</attribute>
<attribute name="action">event.remove</attribute>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
</menu>
</interface>

165
src/session/view/content/room_history/item_row.rs

@ -1,5 +1,3 @@
use std::sync::LazyLock;
use adw::{prelude::*, subclass::prelude::*};
use gettextrs::gettext;
use gtk::{gio, glib, glib::clone};
@ -132,81 +130,39 @@ mod imp {
return;
};
let popover = room_history.item_context_menu().to_owned();
room_history.enable_sticky_mode(false);
obj.add_css_class("has-open-popup");
let menu = room_history.item_context_menu();
// Reset the state when the popover is closed.
let closed_handler_cell: Rc<RefCell<Option<glib::signal::SignalHandlerId>>> =
Rc::default();
let quick_reaction_chooser_handler_cell: Rc<
RefCell<Option<glib::signal::SignalHandlerId>>,
> = Rc::default();
let closed_handler = popover.connect_closed(clone!(
let closed_handler = menu.popover.connect_closed(clone!(
#[weak]
obj,
#[weak]
room_history,
#[strong]
closed_handler_cell,
#[strong]
quick_reaction_chooser_handler_cell,
move |popover| {
room_history.enable_sticky_mode(true);
obj.remove_css_class("has-open-popup");
if let Some(handler) = closed_handler_cell.take() {
popover.disconnect(handler);
}
if let Some(handler) = quick_reaction_chooser_handler_cell.take() {
room_history
.item_quick_reaction_chooser()
.disconnect(handler);
}
}
));
closed_handler_cell.replace(Some(closed_handler));
if event.is_message() {
let can_be_reacted_to = event.can_be_reacted_to();
let menu_model = if can_be_reacted_to {
event_message_menu_model_with_reactions()
} else {
event_message_menu_model_no_reactions()
};
if popover.menu_model().as_ref() != Some(menu_model) {
popover.set_menu_model(Some(menu_model));
}
if can_be_reacted_to {
let quick_reaction_chooser = room_history.item_quick_reaction_chooser();
quick_reaction_chooser.set_reactions(Some(event.reactions()));
popover.add_child(quick_reaction_chooser, "quick-reaction-chooser");
// Open emoji chooser
let quick_reaction_chooser_handler = quick_reaction_chooser
.connect_more_reactions_activated(clone!(
#[weak(rename_to = imp)]
self,
#[weak]
popover,
move |_| {
imp.show_reactions_chooser(&popover);
}
));
quick_reaction_chooser_handler_cell
.replace(Some(quick_reaction_chooser_handler));
}
if event.can_be_reacted_to() {
menu.add_quick_reaction_chooser(event.reactions());
} else {
let menu_model = event_state_menu_model();
if popover.menu_model().as_ref() != Some(menu_model) {
popover.set_menu_model(Some(menu_model));
}
menu.remove_quick_reaction_chooser();
}
obj.set_popover(Some(popover));
room_history.enable_sticky_mode(false);
obj.add_css_class("has-open-popup");
obj.set_popover(Some(menu.popover.clone()));
}
}
@ -476,9 +432,14 @@ mod imp {
}
}
/// Replace the given popover with an emoji chooser for reactions.
fn show_reactions_chooser(&self, popover: &gtk::PopoverMenu) {
/// Replace the context menu with an emoji chooser for reactions.
fn show_reactions_chooser(&self) {
let obj = self.obj();
let Some(popover) = obj.popover() else {
return;
};
let (_, rectangle) = popover.pointing_to();
let emoji_chooser = gtk::EmojiChooser::builder()
@ -660,23 +621,34 @@ mod imp {
// Send/redact a reaction.
if event.can_be_reacted_to() {
action_group.add_action_entries([gio::ActionEntry::builder("toggle-reaction")
.parameter_type(Some(&String::static_variant_type()))
.activate(clone!(
#[weak(rename_to = imp)]
self,
move |_, _, variant| {
let Some(key) = variant.unwrap().get::<String>() else {
error!("Could not parse reaction to toggle");
return;
};
action_group.add_action_entries([
gio::ActionEntry::builder("toggle-reaction")
.parameter_type(Some(&String::static_variant_type()))
.activate(clone!(
#[weak(rename_to = imp)]
self,
move |_, _, variant| {
let Some(key) = variant.unwrap().get::<String>() else {
error!("Could not parse reaction to toggle");
return;
};
spawn!(async move {
imp.toggle_reaction(key).await;
});
}
))
.build()]);
spawn!(async move {
imp.toggle_reaction(key).await;
});
}
))
.build(),
gio::ActionEntry::builder("show-reactions-chooser")
.activate(clone!(
#[weak(rename_to = imp)]
self,
move |_, _, _| {
imp.show_reactions_chooser();
}
))
.build(),
]);
}
// Reply.
@ -1076,55 +1048,6 @@ impl ItemRow {
}
}
// This is only safe because the trait `EventActions` can
// only be implemented on `gtk::Widgets` that run only on the main thread
struct MenuModelSendSync(gio::MenuModel);
#[allow(clippy::non_send_fields_in_send_ty)]
unsafe impl Send for MenuModelSendSync {}
unsafe impl Sync for MenuModelSendSync {}
/// The `MenuModel` for common message event actions, including reactions.
fn event_message_menu_model_with_reactions() -> &'static gio::MenuModel {
static MODEL: LazyLock<MenuModelSendSync> = LazyLock::new(|| {
MenuModelSendSync(
gtk::Builder::from_resource(
"/org/gnome/Fractal/ui/session/view/content/room_history/event_actions.ui",
)
.object::<gio::MenuModel>("message_menu_model_with_reactions")
.unwrap(),
)
});
&MODEL.0
}
/// The `MenuModel` for common message event actions, without reactions.
fn event_message_menu_model_no_reactions() -> &'static gio::MenuModel {
static MODEL: LazyLock<MenuModelSendSync> = LazyLock::new(|| {
MenuModelSendSync(
gtk::Builder::from_resource(
"/org/gnome/Fractal/ui/session/view/content/room_history/event_actions.ui",
)
.object::<gio::MenuModel>("message_menu_model_no_reactions")
.unwrap(),
)
});
&MODEL.0
}
/// The `MenuModel` for common state event actions.
fn event_state_menu_model() -> &'static gio::MenuModel {
static MODEL: LazyLock<MenuModelSendSync> = LazyLock::new(|| {
MenuModelSendSync(
gtk::Builder::from_resource(
"/org/gnome/Fractal/ui/session/view/content/room_history/event_actions.ui",
)
.object::<gio::MenuModel>("state_menu_model")
.unwrap(),
)
});
&MODEL.0
}
/// Create a spinner widget.
fn spinner() -> adw::Spinner {
adw::Spinner::builder()

94
src/components/quick_reaction_chooser.rs → src/session/view/content/room_history/item_row_context_menu.rs

@ -1,13 +1,97 @@
use adw::subclass::prelude::*;
use adw::{prelude::*, subclass::prelude::*};
use gettextrs::gettext;
use gtk::{
glib,
gio, glib,
glib::{clone, closure_local},
prelude::*,
CompositeTemplate,
};
use crate::{session::model::ReactionList, utils::BoundObject};
/// Helper struct for the context menu of an `ItemRow`.
#[derive(Debug)]
pub(super) struct ItemRowContextMenu {
/// The popover of the context menu.
pub(super) popover: gtk::PopoverMenu,
/// The menu model of the popover.
menu_model: gio::Menu,
/// The quick reaction chooser in the context menu.
quick_reaction_chooser: QuickReactionChooser,
}
impl ItemRowContextMenu {
/// The identifier in the context menu for the quick reaction chooser.
const QUICK_REACTION_CHOOSER_ID: &str = "quick-reaction-chooser";
/// Whether the menu includes an item for the quick reaction chooser.
fn has_quick_reaction_chooser(&self) -> bool {
let first_section = self
.menu_model
.item_link(0, gio::MENU_LINK_SECTION)
.and_downcast::<gio::Menu>()
.expect("item row context menu has at least one section");
first_section
.item_attribute_value(0, "custom", Some(&String::static_variant_type()))
.and_then(|variant| variant.get::<String>())
.is_some_and(|value| value == Self::QUICK_REACTION_CHOOSER_ID)
}
/// Add the quick reaction chooser to this menu, if it is not already
/// present, and set the reaction list.
pub(super) fn add_quick_reaction_chooser(&self, reactions: ReactionList) {
if !self.has_quick_reaction_chooser() {
let section_menu = gio::Menu::new();
let item = gio::MenuItem::new(None, None);
item.set_attribute_value(
"custom",
Some(&Self::QUICK_REACTION_CHOOSER_ID.to_variant()),
);
section_menu.append_item(&item);
self.menu_model.insert_section(0, None, &section_menu);
self.popover.add_child(
&self.quick_reaction_chooser,
Self::QUICK_REACTION_CHOOSER_ID,
);
}
self.quick_reaction_chooser.set_reactions(Some(reactions));
}
/// Remove the quick reaction chooser from this menu, if it is present.
pub(super) fn remove_quick_reaction_chooser(&self) {
if !self.has_quick_reaction_chooser() {
return;
}
self.popover.remove_child(&self.quick_reaction_chooser);
self.menu_model.remove(0);
}
}
impl Default for ItemRowContextMenu {
fn default() -> Self {
let menu_model = gtk::Builder::from_resource(
"/org/gnome/Fractal/ui/session/view/content/room_history/event_context_menu.ui",
)
.object::<gio::Menu>("event-menu")
.expect("resource and menu exist");
let popover = gtk::PopoverMenu::builder()
.has_arrow(false)
.halign(gtk::Align::Start)
.menu_model(&menu_model)
.build();
popover.update_property(&[gtk::accessible::Property::Label(&gettext("Context Menu"))]);
Self {
popover,
menu_model,
quick_reaction_chooser: Default::default(),
}
}
}
/// A quick reaction.
#[derive(Debug, Clone, Copy)]
struct QuickReaction {
@ -71,7 +155,9 @@ mod imp {
use super::*;
#[derive(Debug, Default, CompositeTemplate, glib::Properties)]
#[template(resource = "/org/gnome/Fractal/ui/components/quick_reaction_chooser.ui")]
#[template(
resource = "/org/gnome/Fractal/ui/session/view/content/room_history/quick_reaction_chooser.ui"
)]
#[properties(wrapper_type = super::QuickReactionChooser)]
pub struct QuickReactionChooser {
#[template_child]

56
src/session/view/content/room_history/mod.rs

@ -1,5 +1,16 @@
use std::time::Duration;
use adw::{prelude::*, subclass::prelude::*};
use gettextrs::gettext;
use gtk::{gdk, gio, glib, glib::clone, graphene::Point, CompositeTemplate};
use matrix_sdk::ruma::EventId;
use matrix_sdk_ui::timeline::TimelineEventItemId;
use ruma::{api::client::receipt::create_receipt::v3::ReceiptType, OwnedEventId};
use tracing::{error, warn};
mod divider_row;
mod item_row;
mod item_row_context_menu;
mod member_timestamp;
mod message_row;
mod message_toolbar;
@ -10,25 +21,15 @@ mod title;
mod typing_row;
mod verification_info_bar;
use std::time::Duration;
use adw::{prelude::*, subclass::prelude::*};
use gettextrs::gettext;
use gtk::{gdk, gio, glib, glib::clone, graphene::Point, CompositeTemplate};
use matrix_sdk::ruma::EventId;
use matrix_sdk_ui::timeline::TimelineEventItemId;
use ruma::{api::client::receipt::create_receipt::v3::ReceiptType, OwnedEventId};
use tracing::{error, warn};
use self::{
divider_row::DividerRow, item_row::ItemRow, message_row::MessageRow,
message_toolbar::MessageToolbar, read_receipts_list::ReadReceiptsList,
divider_row::DividerRow, item_row::ItemRow, item_row_context_menu::ItemRowContextMenu,
message_row::MessageRow, message_toolbar::MessageToolbar, read_receipts_list::ReadReceiptsList,
sender_avatar::SenderAvatar, state_row::StateRow, title::RoomHistoryTitle,
typing_row::TypingRow, verification_info_bar::VerificationInfoBar,
};
use super::{room_details, RoomDetails};
use crate::{
components::{confirm_leave_room_dialog, DragOverlay, QuickReactionChooser},
components::{confirm_leave_room_dialog, DragOverlay},
prelude::*,
session::model::{
Event, MemberList, Membership, ReceiptPosition, Room, RoomCategory, Timeline, TimelineState,
@ -86,8 +87,7 @@ mod imp {
tombstoned_banner: TemplateChild<adw::Banner>,
#[template_child]
drag_overlay: TemplateChild<DragOverlay>,
item_context_menu: OnceCell<gtk::PopoverMenu>,
item_quick_reaction_chooser: QuickReactionChooser,
item_context_menu: OnceCell<ItemRowContextMenu>,
sender_context_menu: OnceCell<gtk::PopoverMenu>,
/// The room currently displayed.
#[property(get, set = Self::set_room, explicit_notify, nullable)]
@ -989,21 +989,8 @@ mod imp {
}
/// The context menu for the item rows.
pub(super) fn item_context_menu(&self) -> &gtk::PopoverMenu {
self.item_context_menu.get_or_init(|| {
let popover = gtk::PopoverMenu::builder()
.has_arrow(false)
.halign(gtk::Align::Start)
.build();
popover
.update_property(&[gtk::accessible::Property::Label(&gettext("Context Menu"))]);
popover
})
}
/// The reaction chooser for the item rows.
pub(super) fn item_quick_reaction_chooser(&self) -> &QuickReactionChooser {
&self.item_quick_reaction_chooser
pub(super) fn item_context_menu(&self) -> &ItemRowContextMenu {
self.item_context_menu.get_or_init(Default::default)
}
/// The context menu for the sender avatars.
@ -1077,17 +1064,12 @@ impl RoomHistory {
}
/// The context menu for the item rows.
pub(crate) fn item_context_menu(&self) -> &gtk::PopoverMenu {
fn item_context_menu(&self) -> &ItemRowContextMenu {
self.imp().item_context_menu()
}
/// The reaction chooser for the item rows.
pub(crate) fn item_quick_reaction_chooser(&self) -> &QuickReactionChooser {
self.imp().item_quick_reaction_chooser()
}
/// The context menu for the sender avatars.
pub(crate) fn sender_context_menu(&self) -> &gtk::PopoverMenu {
fn sender_context_menu(&self) -> &gtk::PopoverMenu {
self.imp().sender_context_menu()
}
}

4
src/components/quick_reaction_chooser.ui → src/session/view/content/room_history/quick_reaction_chooser.ui

@ -18,8 +18,8 @@
<style>
<class name="circular"/>
</style>
<property name="icon_name">view-more-horizontal-symbolic</property>
<signal name="clicked" handler="more_reactions_activated" swapped="yes" />
<property name="icon-name">view-more-horizontal-symbolic</property>
<property name="action-name">event.show-reactions-chooser</property>
<layout>
<property name="column">3</property>
<property name="row">1</property>

4
src/ui-resources.gresource.xml

@ -28,7 +28,6 @@
<file compressed="true" preprocess="xml-stripblanks">components/power_level_selection/combo_box.ui</file>
<file compressed="true" preprocess="xml-stripblanks">components/power_level_selection/popover.ui</file>
<file compressed="true" preprocess="xml-stripblanks">components/power_level_selection/row.ui</file>
<file compressed="true" preprocess="xml-stripblanks">components/quick_reaction_chooser.ui</file>
<file compressed="true" preprocess="xml-stripblanks">components/rows/button_count_row.ui</file>
<file compressed="true" preprocess="xml-stripblanks">components/rows/check_loading_row.ui</file>
<file compressed="true" preprocess="xml-stripblanks">components/rows/combo_loading_row.ui</file>
@ -104,7 +103,7 @@
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_details/permissions/permissions_subpage.ui</file>
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_details/permissions/select_member_row.ui</file>
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_history/divider_row.ui</file>
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_history/event_actions.ui</file>
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_history/event_context_menu.ui</file>
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_history/member_timestamp/row.ui</file>
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_history/message_row/audio.ui</file>
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_history/message_row/file.ui</file>
@ -120,6 +119,7 @@
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_history/message_toolbar/completion/completion_popover.ui</file>
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_history/message_toolbar/mod.ui</file>
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_history/mod.ui</file>
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_history/quick_reaction_chooser.ui</file>
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_history/read_receipts_list/mod.ui</file>
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_history/read_receipts_list/read_receipts_popover.ui</file>
<file compressed="true" preprocess="xml-stripblanks">session/view/content/room_history/sender_avatar/mod.ui</file>

Loading…
Cancel
Save