fractal/session/view/content/room_history/member_timestamp/
row.rs1use adw::{prelude::*, subclass::prelude::*};
2use gettextrs::gettext;
3use gtk::{CompositeTemplate, glib, glib::clone};
4
5use super::MemberTimestamp;
6use crate::{
7 Application, system_settings::ClockFormat, utils::matrix::seconds_since_unix_epoch_to_date,
8};
9
10mod imp {
11 use std::cell::RefCell;
12
13 use glib::subclass::InitializingObject;
14
15 use super::*;
16
17 #[derive(Debug, Default, CompositeTemplate, glib::Properties)]
18 #[template(
19 resource = "/org/gnome/Fractal/ui/session/view/content/room_history/member_timestamp/row.ui"
20 )]
21 #[properties(wrapper_type = super::MemberTimestampRow)]
22 pub struct MemberTimestampRow {
23 #[template_child]
24 timestamp: TemplateChild<gtk::Label>,
25 #[property(get, set = Self::set_data, explicit_notify, nullable)]
27 data: glib::WeakRef<MemberTimestamp>,
28 system_settings_handler: RefCell<Option<glib::SignalHandlerId>>,
29 }
30
31 #[glib::object_subclass]
32 impl ObjectSubclass for MemberTimestampRow {
33 const NAME: &'static str = "ContentMemberTimestampRow";
34 type Type = super::MemberTimestampRow;
35 type ParentType = adw::Bin;
36
37 fn class_init(klass: &mut Self::Class) {
38 Self::bind_template(klass);
39 }
40
41 fn instance_init(obj: &InitializingObject<Self>) {
42 obj.init_template();
43 }
44 }
45
46 #[glib::derived_properties]
47 impl ObjectImpl for MemberTimestampRow {
48 fn constructed(&self) {
49 self.parent_constructed();
50
51 let system_settings = Application::default().system_settings();
52 let system_settings_handler = system_settings.connect_clock_format_notify(clone!(
53 #[weak(rename_to = imp)]
54 self,
55 move |_| {
56 imp.update_timestamp();
57 }
58 ));
59 self.system_settings_handler
60 .replace(Some(system_settings_handler));
61 }
62
63 fn dispose(&self) {
64 if let Some(handler) = self.system_settings_handler.take() {
65 Application::default().system_settings().disconnect(handler);
66 }
67 }
68 }
69
70 impl WidgetImpl for MemberTimestampRow {}
71 impl BinImpl for MemberTimestampRow {}
72
73 impl MemberTimestampRow {
74 fn set_data(&self, data: Option<&MemberTimestamp>) {
76 if self.data.upgrade().as_ref() == data {
77 return;
78 }
79
80 self.data.set(data);
81
82 self.obj().notify_data();
83 self.update_timestamp();
84 }
85
86 fn update_timestamp(&self) {
88 let Some(timestamp) = self
89 .data
90 .upgrade()
91 .map(|d| d.timestamp())
92 .filter(|t| *t > 0)
93 else {
94 self.timestamp.set_visible(false);
96 return;
97 };
98
99 let timestamp = timestamp.try_into().unwrap_or(i64::MAX);
100 let datetime = seconds_since_unix_epoch_to_date(timestamp);
101
102 let clock_format = Application::default().system_settings().clock_format();
103
104 let format = if clock_format == ClockFormat::TwelveHours {
105 gettext("%B %-e at %I:%M %p")
110 } else {
111 gettext("%B %-e at %H:%M")
116 };
117 let label = datetime.format(&format).unwrap();
118
119 self.timestamp.set_label(&label);
120 self.timestamp.set_visible(true);
121 }
122 }
123}
124
125glib::wrapper! {
126 pub struct MemberTimestampRow(ObjectSubclass<imp::MemberTimestampRow>)
128 @extends gtk::Widget, adw::Bin;
129}
130
131impl MemberTimestampRow {
132 pub fn new() -> Self {
133 glib::Object::new()
134 }
135}
136
137impl Default for MemberTimestampRow {
138 fn default() -> Self {
139 Self::new()
140 }
141}