fractal/components/dialogs/auth/
in_browser_page.rs1use std::fmt::Debug;
2
3use adw::{prelude::*, subclass::prelude::*};
4use gtk::glib;
5use tracing::error;
6
7use crate::components::LoadingButton;
8
9mod imp {
10 use std::cell::OnceCell;
11
12 use glib::subclass::InitializingObject;
13
14 use super::*;
15
16 #[derive(Debug, Default, gtk::CompositeTemplate, glib::Properties)]
17 #[template(resource = "/org/gnome/Fractal/ui/components/dialogs/auth/in_browser_page.ui")]
18 #[properties(wrapper_type = super::AuthDialogInBrowserPage)]
19 pub struct AuthDialogInBrowserPage {
20 #[template_child]
21 pub(super) confirm_button: TemplateChild<LoadingButton>,
22 #[property(get, construct_only)]
24 url: OnceCell<String>,
25 }
26
27 #[glib::object_subclass]
28 impl ObjectSubclass for AuthDialogInBrowserPage {
29 const NAME: &'static str = "AuthDialogInBrowserPage";
30 type Type = super::AuthDialogInBrowserPage;
31 type ParentType = adw::Bin;
32
33 fn class_init(klass: &mut Self::Class) {
34 Self::bind_template(klass);
35 Self::bind_template_callbacks(klass);
36 }
37
38 fn instance_init(obj: &InitializingObject<Self>) {
39 obj.init_template();
40 }
41 }
42
43 #[glib::derived_properties]
44 impl ObjectImpl for AuthDialogInBrowserPage {}
45
46 impl WidgetImpl for AuthDialogInBrowserPage {}
47 impl BinImpl for AuthDialogInBrowserPage {}
48
49 #[gtk::template_callbacks]
50 impl AuthDialogInBrowserPage {
51 #[template_callback]
53 async fn launch_url(&self) {
54 let url = self
55 .url
56 .get()
57 .expect("URL should be set during construction");
58
59 if let Err(error) = gtk::UriLauncher::new(url)
60 .launch_future(self.obj().root().and_downcast_ref::<gtk::Window>())
61 .await
62 {
63 error!("Could not launch authentication URI: {error}");
64 }
65
66 self.confirm_button.set_sensitive(true);
67 }
68
69 #[template_callback]
71 fn proceed(&self) {
72 self.confirm_button.set_is_loading(true);
73 let _ = self.obj().activate_action("auth-dialog.continue", None);
74 }
75
76 pub(super) fn retry(&self) {
78 self.confirm_button.set_is_loading(false);
79 }
80 }
81}
82
83glib::wrapper! {
84 pub struct AuthDialogInBrowserPage(ObjectSubclass<imp::AuthDialogInBrowserPage>)
86 @extends gtk::Widget, adw::Bin,
87 @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
88}
89
90impl AuthDialogInBrowserPage {
91 pub fn new(url: String) -> Self {
93 glib::Object::builder().property("url", url).build()
94 }
95
96 pub fn default_widget(&self) -> >k::Widget {
98 self.imp().confirm_button.upcast_ref()
99 }
100
101 pub fn retry(&self) {
103 self.imp().retry();
104 }
105}