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