update callback function, fix auth status update

This commit is contained in:
yggverse 2025-01-29 19:24:35 +02:00
parent 1316f32343
commit 873e642b10
4 changed files with 90 additions and 88 deletions

View file

@ -247,14 +247,20 @@ impl Request for Entry {
fn identity(&self, profile: &Rc<Profile>) { fn identity(&self, profile: &Rc<Profile>) {
if let Some(uri) = self.uri() { if let Some(uri) = self.uri() {
if ["gemini", "titan"].contains(&uri.scheme().as_str()) { if ["gemini", "titan"].contains(&uri.scheme().as_str()) {
return identity::default(profile, &uri, { return identity::default(
profile,
&uri,
&Rc::new({
let profile = profile.clone(); let profile = profile.clone();
let this = self.clone(); let this = self.clone();
move || { move |is_reload| {
this.update(&profile); this.update(&profile);
if is_reload {
this.emit_activate(); this.emit_activate();
} // on apply }
}) }
}),
)
.present(Some(self)); .present(Some(self));
} }
} }

View file

@ -10,8 +10,12 @@ use gtk::glib::Uri;
use std::rc::Rc; use std::rc::Rc;
/// Create new identity widget for Gemini protocol match given URI /// Create new identity widget for Gemini protocol match given URI
pub fn default(profile: &Rc<Profile>, request: &Uri, on_apply: impl Fn() + 'static) -> Default { pub fn default(
Default::build(profile, request, on_apply) profile: &Rc<Profile>,
request: &Uri,
callback: &Rc<impl Fn(bool) + 'static>,
) -> Default {
Default::build(profile, request, callback)
} }
/// Create new identity widget for unknown request /// Create new identity widget for unknown request

View file

@ -1,5 +1,5 @@
mod widget; mod widget;
use widget::{form::list::item::value::Value, Widget}; use widget::Widget;
use super::Profile; use super::Profile;
use gtk::{glib::Uri, prelude::IsA}; use gtk::{glib::Uri, prelude::IsA};
@ -14,59 +14,13 @@ impl Default {
// Construct // Construct
/// Create new `Self` for given `Profile` /// Create new `Self` for given `Profile`
pub fn build(profile: &Rc<Profile>, request: &Uri, on_apply: impl Fn() + 'static) -> Self { pub fn build(
profile: &Rc<Profile>,
request: &Uri,
callback: &Rc<impl Fn(bool) + 'static>,
) -> Self {
// Init widget // Init widget
let widget = Rc::new(Widget::build(profile, request)); let widget = Rc::new(Widget::build(profile, request, callback));
// Init events
widget.on_apply({
let profile = profile.clone();
let request = request.clone();
let widget = widget.clone();
move |response| {
// Get option match user choice
let option = match response {
Value::ProfileIdentityId(value) => Some(value),
Value::GuestSession => None,
Value::GeneratePem => Some(
profile
.identity
.make(None, &widget.form.name.value().unwrap())
.unwrap(), // @TODO handle
),
Value::ImportPem => Some(
profile
.identity
.add(&widget.form.file.pem.take().unwrap())
.unwrap(), // @TODO handle
),
};
// Apply auth
match option {
// Activate identity for `scope`
Some(profile_identity_id) => {
if profile
.identity
.auth
.apply(profile_identity_id, &request.to_string())
.is_err()
{
panic!() // unexpected @TODO
}
}
// Remove all identity auths for `scope`
None => {
if profile.identity.auth.remove(&request.to_string()).is_err() {
panic!() // unexpected @TODO
}
}
}
// Run callback function
on_apply()
}
});
// Return activated `Self` // Return activated `Self`
Self { Self {

View file

@ -24,16 +24,18 @@ const RESPONSE_CANCEL: (&str, &str) = ("cancel", "Cancel");
// Select options // Select options
pub struct Widget { pub struct Widget {
// pub action: Rc<Action>, alert_dialog: AlertDialog,
pub form: Rc<Form>,
pub alert_dialog: AlertDialog,
} }
impl Widget { impl Widget {
// Constructors // Constructors
/// Create new `Self` /// Create new `Self`
pub fn build(profile: &Rc<Profile>, request: &Uri) -> Self { pub fn build(
profile: &Rc<Profile>,
request: &Uri,
callback: &Rc<impl Fn(bool) + 'static>,
) -> Self {
// Init actions // Init actions
let action = Rc::new(WidgetAction::new()); let action = Rc::new(WidgetAction::new());
@ -49,13 +51,65 @@ impl Widget {
.extra_child(&form.g_box) .extra_child(&form.g_box)
.build(); .build();
// Set response variants
alert_dialog.add_responses(&[ alert_dialog.add_responses(&[
RESPONSE_CANCEL, RESPONSE_CANCEL,
// RESPONSE_MANAGE, // RESPONSE_MANAGE,
RESPONSE_APPLY, RESPONSE_APPLY,
]); ]);
alert_dialog.connect_response(Some(RESPONSE_APPLY.0), {
let callback = callback.clone();
let form = form.clone();
let profile = profile.clone();
let request = request.clone();
move |this, response| {
// Prevent double-click action
this.set_response_enabled(response, false);
// Get option match user choice
let option = match form.list.selected().value_enum() {
Value::ProfileIdentityId(value) => Some(value),
Value::GuestSession => None,
Value::GeneratePem => Some(
profile
.identity
.make(None, &form.name.value().unwrap())
.unwrap(), // @TODO handle
),
Value::ImportPem => Some(
profile
.identity
.add(&form.file.pem.take().unwrap())
.unwrap(), // @TODO handle
),
};
// Apply auth
match option {
// Activate identity for `scope`
Some(profile_identity_id) => {
if profile
.identity
.auth
.apply(profile_identity_id, &request.to_string())
.is_err()
{
panic!() // unexpected @TODO
}
}
// Remove all identity auths for `scope`
None => {
if profile.identity.auth.remove(&request.to_string()).is_err() {
panic!() // unexpected @TODO
}
}
}
// Run callback function
callback(true)
}
});
// Deactivate not implemented feature @TODO // Deactivate not implemented feature @TODO
// alert_dialog.set_response_enabled(RESPONSE_MANAGE.0, false); // alert_dialog.set_response_enabled(RESPONSE_MANAGE.0, false);
@ -67,6 +121,7 @@ impl Widget {
// Init events // Init events
action.update.connect_activate({ action.update.connect_activate({
let form = form.clone(); let form = form.clone();
let callback = callback.clone();
let alert_dialog = alert_dialog.clone(); let alert_dialog = alert_dialog.clone();
move || { move || {
// Update child components // Update child components
@ -74,6 +129,8 @@ impl Widget {
// Deactivate apply button if the form values could not be processed // Deactivate apply button if the form values could not be processed
alert_dialog.set_response_enabled(RESPONSE_APPLY.0, form.is_applicable()); alert_dialog.set_response_enabled(RESPONSE_APPLY.0, form.is_applicable());
callback(false);
} }
}); });
@ -81,30 +138,11 @@ impl Widget {
action.update.activate(); action.update.activate();
// Return new activated `Self` // Return new activated `Self`
Self { Self { alert_dialog }
// action,
form,
alert_dialog,
}
} }
// Actions // Actions
/// Callback wrapper to apply
/// [response](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/signal.AlertDialog.response.html)
pub fn on_apply(&self, callback: impl Fn(Value) + 'static) {
self.alert_dialog.connect_response(Some(RESPONSE_APPLY.0), {
let form = self.form.clone();
move |this, response| {
// Prevent double-click action
this.set_response_enabled(response, false);
// Result
callback(form.list.selected().value_enum())
}
});
}
/// Show dialog with new preset /// Show dialog with new preset
pub fn present(&self, parent: Option<&impl IsA<gtk::Widget>>) { pub fn present(&self, parent: Option<&impl IsA<gtk::Widget>>) {
self.alert_dialog.present(parent) self.alert_dialog.present(parent)