fractal/identity_verification_view/
completed_page.rs1use 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 #[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 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 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 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 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 #[template_callback]
137 fn dismiss(&self) {
138 let Some(verification) = self.verification() else {
139 return;
140 };
141 verification.dismiss();
142 }
143}