Skip to main content

fractal/identity_verification_view/
completed_page.rs

1use adw::{prelude::*, subclass::prelude::*};
2use gettextrs::gettext;
3use gtk::{glib, glib::clone};
4
5use crate::{gettext_f, prelude::*, session::IdentityVerification};
6
7mod imp {
8    use std::cell::RefCell;
9
10    use glib::subclass::InitializingObject;
11
12    use super::*;
13
14    #[derive(Debug, Default, gtk::CompositeTemplate, glib::Properties)]
15    #[template(resource = "/org/gnome/Fractal/ui/identity_verification_view/completed_page.ui")]
16    #[properties(wrapper_type = super::CompletedPage)]
17    pub struct CompletedPage {
18        /// The current identity verification.
19        #[property(get, set = Self::set_verification, explicit_notify, nullable)]
20        pub verification: glib::WeakRef<IdentityVerification>,
21        pub display_name_handler: RefCell<Option<glib::SignalHandlerId>>,
22        #[template_child]
23        pub title: TemplateChild<gtk::Label>,
24        #[template_child]
25        pub message: TemplateChild<gtk::Label>,
26        #[template_child]
27        pub dismiss_btn: TemplateChild<gtk::Button>,
28    }
29
30    #[glib::object_subclass]
31    impl ObjectSubclass for CompletedPage {
32        const NAME: &'static str = "IdentityVerificationCompletedPage";
33        type Type = super::CompletedPage;
34        type ParentType = adw::Bin;
35
36        fn class_init(klass: &mut Self::Class) {
37            Self::bind_template(klass);
38            Self::Type::bind_template_callbacks(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 CompletedPage {
48        fn dispose(&self) {
49            if let Some(verification) = self.verification.upgrade()
50                && let Some(handler) = self.display_name_handler.take()
51            {
52                verification.user().disconnect(handler);
53            }
54        }
55    }
56
57    impl WidgetImpl for CompletedPage {
58        fn grab_focus(&self) -> bool {
59            self.dismiss_btn.grab_focus()
60        }
61    }
62
63    impl BinImpl for CompletedPage {}
64
65    impl CompletedPage {
66        /// Set the current identity verification.
67        fn set_verification(&self, verification: Option<&IdentityVerification>) {
68            let prev_verification = self.verification.upgrade();
69
70            if prev_verification.as_ref() == verification {
71                return;
72            }
73            let obj = self.obj();
74
75            if let Some(verification) = prev_verification
76                && let Some(handler) = self.display_name_handler.take()
77            {
78                verification.user().disconnect(handler);
79            }
80
81            if let Some(verification) = verification {
82                let display_name_handler = verification.user().connect_display_name_notify(clone!(
83                    #[weak]
84                    obj,
85                    move |_| {
86                        obj.update_labels();
87                    }
88                ));
89                self.display_name_handler
90                    .replace(Some(display_name_handler));
91            }
92
93            self.verification.set(verification);
94
95            obj.update_labels();
96            obj.notify_verification();
97        }
98    }
99}
100
101glib::wrapper! {
102    /// A page to show when the verification was completed.
103    pub struct CompletedPage(ObjectSubclass<imp::CompletedPage>)
104        @extends gtk::Widget, adw::Bin,
105        @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
106}
107
108#[gtk::template_callbacks]
109impl CompletedPage {
110    pub fn new() -> Self {
111        glib::Object::new()
112    }
113
114    /// Update the labels for the current verification.
115    fn update_labels(&self) {
116        let Some(verification) = self.verification() else {
117            return;
118        };
119        let imp = self.imp();
120
121        if verification.is_self_verification() {
122            imp.title.set_label(&gettext("Request Complete"));
123            imp.message.set_label(&gettext(
124                "The new session is now ready to send and receive secure messages.",
125            ));
126        } else {
127            let name = verification.user().display_name();
128            imp.title.set_markup(&gettext("Verification Complete"));
129            // Translators: Do NOT translate the content between '{' and '}', this is a
130            // variable name.
131            imp.message.set_markup(&gettext_f("{user} is verified and you can now be sure that your communication will be private.", &[("user", &format!("<b>{name}</b>"))]));
132        }
133    }
134
135    /// Dismiss the verification.
136    #[template_callback]
137    fn dismiss(&self) {
138        let Some(verification) = self.verification() else {
139            return;
140        };
141        verification.dismiss();
142    }
143}