fractal/session/view/content/room_details/invite_subpage/
item.rs

1use gtk::{glib, prelude::*, subclass::prelude::*};
2
3use crate::session::model::User;
4
5mod imp {
6    use std::{
7        cell::{Cell, OnceCell, RefCell},
8        marker::PhantomData,
9    };
10
11    use super::*;
12
13    #[derive(Debug, Default, glib::Properties)]
14    #[properties(wrapper_type = super::InviteItem)]
15    pub struct InviteItem {
16        /// The user data of the item.
17        #[property(get, construct_only)]
18        user: OnceCell<User>,
19        /// Whether the user is invited.
20        #[property(get, set = Self::set_is_invitee, explicit_notify)]
21        is_invitee: Cell<bool>,
22        /// Whether the user can be invited.
23        #[property(get = Self::can_invite)]
24        can_invite: PhantomData<bool>,
25        /// The reason why the user cannot be invited, when applicable.
26        #[property(get, set = Self::set_invite_exception, explicit_notify, nullable)]
27        invite_exception: RefCell<Option<String>>,
28    }
29
30    #[glib::object_subclass]
31    impl ObjectSubclass for InviteItem {
32        const NAME: &'static str = "RoomDetailsInviteItem";
33        type Type = super::InviteItem;
34    }
35
36    #[glib::derived_properties]
37    impl ObjectImpl for InviteItem {}
38
39    impl InviteItem {
40        /// Set whether this user is invited.
41        fn set_is_invitee(&self, is_invitee: bool) {
42            if self.is_invitee.get() == is_invitee {
43                return;
44            }
45
46            self.is_invitee.set(is_invitee);
47            self.obj().notify_is_invitee();
48        }
49
50        /// Whether the user can be invited.
51        fn can_invite(&self) -> bool {
52            self.invite_exception.borrow().is_none()
53        }
54
55        /// Set the reason the user can't be invited.
56        fn set_invite_exception(&self, exception: Option<String>) {
57            if exception == *self.invite_exception.borrow() {
58                return;
59            }
60
61            let could_invite = self.can_invite();
62
63            self.invite_exception.replace(exception);
64
65            let obj = self.obj();
66            obj.notify_invite_exception();
67
68            if could_invite != self.can_invite() {
69                obj.notify_can_invite();
70            }
71        }
72    }
73}
74
75glib::wrapper! {
76    /// An item of the result of a search in the user directory.
77    ///
78    /// This also keeps track whether the user is invited or the reason why they cannot be invited.
79    pub struct InviteItem(ObjectSubclass<imp::InviteItem>);
80}
81
82impl InviteItem {
83    /// Construct a new `InviteItem` with the given user.
84    pub fn new(user: &impl IsA<User>) -> Self {
85        glib::Object::builder().property("user", user).build()
86    }
87}