fractal/identity_verification_view/
completed_page.rs

1use adw::subclass::prelude::*;
2use gettextrs::gettext;
3use gtk::{CompositeTemplate, glib, glib::clone, prelude::*};
4
5use crate::{gettext_f, prelude::*, session::model::IdentityVerification};
6
7mod imp {
8    use std::cell::RefCell;
9
10    use glib::subclass::InitializingObject;
11
12    use super::*;
13
14    #[derive(Debug, Default, 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                if let Some(handler) = self.display_name_handler.take() {
51                    verification.user().disconnect(handler);
52                }
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                if let Some(handler) = self.display_name_handler.take() {
77                    verification.user().disconnect(handler);
78                }
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, @implements gtk::Accessible;
105}
106
107#[gtk::template_callbacks]
108impl CompletedPage {
109    pub fn new() -> Self {
110        glib::Object::new()
111    }
112
113    /// Update the labels for the current verification.
114    fn update_labels(&self) {
115        let Some(verification) = self.verification() else {
116            return;
117        };
118        let imp = self.imp();
119
120        if verification.is_self_verification() {
121            imp.title.set_label(&gettext("Request Complete"));
122            imp.message.set_label(&gettext(
123                "The new session is now ready to send and receive secure messages.",
124            ));
125        } else {
126            let name = verification.user().display_name();
127            imp.title.set_markup(&gettext("Verification Complete"));
128            // Translators: Do NOT translate the content between '{' and '}', this is a
129            // variable name.
130            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>"))]));
131        }
132    }
133
134    /// Dismiss the verification.
135    #[template_callback]
136    fn dismiss(&self) {
137        let Some(verification) = self.verification() else {
138            return;
139        };
140        verification.dismiss();
141    }
142}