|
| 1 | +use glib::clone; |
| 2 | +use gtk::glib; |
| 3 | +use gtk::prelude::*; |
| 4 | +use gtk::subclass::prelude::*; |
| 5 | +use tdlib::enums::UserStatus; |
| 6 | + |
| 7 | +use crate::strings; |
| 8 | +use crate::tdlib::User; |
| 9 | + |
| 10 | +mod imp { |
| 11 | + use super::*; |
| 12 | + use once_cell::sync::Lazy; |
| 13 | + use once_cell::unsync::OnceCell; |
| 14 | + |
| 15 | + #[derive(Debug, Default)] |
| 16 | + pub(crate) struct UserStatusString(pub(super) OnceCell<User>); |
| 17 | + |
| 18 | + #[glib::object_subclass] |
| 19 | + impl ObjectSubclass for UserStatusString { |
| 20 | + const NAME: &'static str = "UserStatusString"; |
| 21 | + type Type = super::UserStatusString; |
| 22 | + } |
| 23 | + |
| 24 | + impl ObjectImpl for UserStatusString { |
| 25 | + fn properties() -> &'static [glib::ParamSpec] { |
| 26 | + static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = |
| 27 | + Lazy::new(|| vec![glib::ParamSpecString::builder("string").read_only().build()]); |
| 28 | + PROPERTIES.as_ref() |
| 29 | + } |
| 30 | + |
| 31 | + fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { |
| 32 | + let obj = self.obj(); |
| 33 | + |
| 34 | + match pspec.name() { |
| 35 | + "string" => obj.string().to_value(), |
| 36 | + _ => unimplemented!(), |
| 37 | + } |
| 38 | + } |
| 39 | + } |
| 40 | +} |
| 41 | + |
| 42 | +glib::wrapper! { |
| 43 | + pub(crate) struct UserStatusString(ObjectSubclass<imp::UserStatusString>); |
| 44 | +} |
| 45 | + |
| 46 | +impl UserStatusString { |
| 47 | + pub(crate) fn new(user: User) -> UserStatusString { |
| 48 | + let obj: UserStatusString = glib::Object::builder().build(); |
| 49 | + |
| 50 | + user.connect_notify_local( |
| 51 | + Some("status"), |
| 52 | + clone!(@weak obj => move |_, _| { |
| 53 | + obj.notify("string"); |
| 54 | + }), |
| 55 | + ); |
| 56 | + |
| 57 | + // Notify the string every minute when the user is offline so that |
| 58 | + // the "last seen" text is updated when time passes. |
| 59 | + glib::timeout_add_seconds_local( |
| 60 | + 60, |
| 61 | + clone!(@weak obj => @default-return glib::Continue(false), move || { |
| 62 | + let user = obj.imp().0.get().unwrap(); |
| 63 | + if let UserStatus::Offline(_) = user.status().0 { |
| 64 | + obj.notify("string"); |
| 65 | + } |
| 66 | + glib::Continue(true) |
| 67 | + }), |
| 68 | + ); |
| 69 | + |
| 70 | + obj.imp().0.set(user).unwrap(); |
| 71 | + obj |
| 72 | + } |
| 73 | + |
| 74 | + pub(crate) fn string(&self) -> String { |
| 75 | + let user = self.imp().0.get().unwrap(); |
| 76 | + strings::user_status(&user.status().0) |
| 77 | + } |
| 78 | +} |
0 commit comments