fractal/session/view/content/room_history/message_row/reaction/
reaction_popover.rs1use adw::{prelude::*, subclass::prelude::*};
2use gtk::{
3 gio,
4 glib::{self, clone},
5 CompositeTemplate,
6};
7
8use crate::{
9 components::UserProfileDialog,
10 session::view::content::room_history::member_timestamp::{
11 row::MemberTimestampRow, MemberTimestamp,
12 },
13};
14
15mod imp {
16 use glib::subclass::InitializingObject;
17
18 use super::*;
19
20 #[derive(Debug, Default, CompositeTemplate, glib::Properties)]
21 #[template(
22 resource = "/org/gnome/Fractal/ui/session/view/content/room_history/message_row/reaction/reaction_popover.ui"
23 )]
24 #[properties(wrapper_type = super::ReactionPopover)]
25 pub struct ReactionPopover {
26 #[template_child]
27 list: TemplateChild<gtk::ListView>,
28 #[property(get, set = Self::set_senders, construct_only)]
30 senders: glib::WeakRef<gio::ListStore>,
31 }
32
33 #[glib::object_subclass]
34 impl ObjectSubclass for ReactionPopover {
35 const NAME: &'static str = "ContentMessageReactionPopover";
36 type Type = super::ReactionPopover;
37 type ParentType = gtk::Popover;
38
39 fn class_init(klass: &mut Self::Class) {
40 MemberTimestampRow::ensure_type();
41
42 Self::bind_template(klass);
43 }
44
45 fn instance_init(obj: &InitializingObject<Self>) {
46 obj.init_template();
47 }
48 }
49
50 #[glib::derived_properties]
51 impl ObjectImpl for ReactionPopover {}
52
53 impl WidgetImpl for ReactionPopover {}
54 impl PopoverImpl for ReactionPopover {}
55
56 impl ReactionPopover {
57 fn set_senders(&self, senders: gio::ListStore) {
59 self.senders.set(Some(&senders));
60 self.list
61 .set_model(Some(>k::NoSelection::new(Some(senders))));
62 self.list.connect_activate(clone!(
63 #[weak(rename_to = imp)]
64 self,
65 move |_, pos| {
66 let Some(member) = imp
67 .senders
68 .upgrade()
69 .and_then(|list| list.item(pos))
70 .and_downcast::<MemberTimestamp>()
71 .and_then(|ts| ts.member())
72 else {
73 return;
74 };
75
76 let obj = imp.obj();
77
78 let dialog = UserProfileDialog::new();
79 dialog.set_room_member(member);
80 dialog.present(Some(&*obj));
81
82 obj.popdown();
83 }
84 ));
85 }
86 }
87}
88
89glib::wrapper! {
90 pub struct ReactionPopover(ObjectSubclass<imp::ReactionPopover>)
92 @extends gtk::Widget, gtk::Popover;
93}
94
95impl ReactionPopover {
96 pub fn new(senders: &gio::ListStore) -> Self {
98 glib::Object::builder().property("senders", senders).build()
99 }
100}