mirror of
https://github.com/YGGverse/Yoda.git
synced 2026-04-01 17:15:28 +00:00
implement Common identity as trait for AlertDialog
This commit is contained in:
parent
a6d84908cc
commit
fc8c967891
22 changed files with 131 additions and 175 deletions
|
|
@ -14,8 +14,8 @@ pub fn common(
|
||||||
profile: &Rc<Profile>,
|
profile: &Rc<Profile>,
|
||||||
request: &Uri,
|
request: &Uri,
|
||||||
callback: &Rc<impl Fn(bool) + 'static>,
|
callback: &Rc<impl Fn(bool) + 'static>,
|
||||||
) -> Common {
|
) -> AlertDialog {
|
||||||
Common::build(profile, request, callback)
|
AlertDialog::common(profile, request, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create new identity widget for unknown request
|
/// Create new identity widget for unknown request
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,144 @@
|
||||||
mod widget;
|
mod action;
|
||||||
use widget::Widget;
|
pub mod form;
|
||||||
|
|
||||||
use super::Profile;
|
use action::Action as WidgetAction;
|
||||||
use gtk::{glib::Uri, prelude::IsA};
|
use form::{list::item::value::Value, Form};
|
||||||
|
|
||||||
|
use crate::Profile;
|
||||||
|
use adw::{
|
||||||
|
prelude::{AlertDialogExt, AlertDialogExtManual},
|
||||||
|
AlertDialog, ResponseAppearance,
|
||||||
|
};
|
||||||
|
use gtk::glib::Uri;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct Common {
|
// Defaults
|
||||||
// profile: Rc<Profile>,
|
const HEADING: &str = "Identity";
|
||||||
widget: Rc<Widget>,
|
const BODY: &str = "Select identity certificate";
|
||||||
|
|
||||||
|
// Response variants
|
||||||
|
const RESPONSE_APPLY: (&str, &str) = ("apply", "Apply");
|
||||||
|
const RESPONSE_CANCEL: (&str, &str) = ("cancel", "Cancel");
|
||||||
|
// const RESPONSE_MANAGE: (&str, &str) = ("manage", "Manage");
|
||||||
|
|
||||||
|
// Select options
|
||||||
|
|
||||||
|
pub trait Common {
|
||||||
|
fn common(profile: &Rc<Profile>, request: &Uri, callback: &Rc<impl Fn(bool) + 'static>)
|
||||||
|
-> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Common {
|
impl Common for AlertDialog {
|
||||||
// Construct
|
// Constructors
|
||||||
|
|
||||||
/// Create new `Self` for given `Profile`
|
/// Create new `Self`
|
||||||
pub fn build(
|
fn common(
|
||||||
profile: &Rc<Profile>,
|
profile: &Rc<Profile>,
|
||||||
request: &Uri,
|
request: &Uri,
|
||||||
callback: &Rc<impl Fn(bool) + 'static>,
|
callback: &Rc<impl Fn(bool) + 'static>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// Init widget
|
// Init actions
|
||||||
let widget = Rc::new(Widget::build(profile, request, callback));
|
let action = Rc::new(WidgetAction::new());
|
||||||
|
|
||||||
// Return activated `Self`
|
// Init child container
|
||||||
Self {
|
let form = Rc::new(Form::build(&action, profile, request));
|
||||||
// profile,
|
|
||||||
widget,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actions
|
// Init main widget
|
||||||
|
let alert_dialog = AlertDialog::builder()
|
||||||
|
.heading(HEADING)
|
||||||
|
.body(BODY)
|
||||||
|
.close_response(RESPONSE_CANCEL.0)
|
||||||
|
.default_response(RESPONSE_APPLY.0)
|
||||||
|
.extra_child(&form.g_box)
|
||||||
|
.build();
|
||||||
|
|
||||||
/// Show dialog for parent [Widget](https://docs.gtk.org/gtk4/class.Widget.html)
|
alert_dialog.add_responses(&[
|
||||||
pub fn present(&self, parent: Option<&impl IsA<gtk::Widget>>) {
|
RESPONSE_CANCEL,
|
||||||
self.widget.present(parent);
|
// RESPONSE_MANAGE,
|
||||||
|
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
|
||||||
|
// alert_dialog.set_response_enabled(RESPONSE_MANAGE.0, false);
|
||||||
|
|
||||||
|
// Decorate default response preset
|
||||||
|
alert_dialog.set_response_appearance(RESPONSE_APPLY.0, ResponseAppearance::Suggested);
|
||||||
|
/* contrast issue with Ubuntu orange accents
|
||||||
|
alert_dialog.set_response_appearance(RESPONSE_CANCEL.0, ResponseAppearance::Destructive); */
|
||||||
|
|
||||||
|
// Init events
|
||||||
|
action.update.connect_activate({
|
||||||
|
let form = form.clone();
|
||||||
|
let callback = callback.clone();
|
||||||
|
let alert_dialog = alert_dialog.clone();
|
||||||
|
move || {
|
||||||
|
// Update child components
|
||||||
|
form.update();
|
||||||
|
|
||||||
|
// Deactivate apply button if the form values could not be processed
|
||||||
|
alert_dialog.set_response_enabled(RESPONSE_APPLY.0, form.is_applicable());
|
||||||
|
|
||||||
|
callback(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Make initial update
|
||||||
|
action.update.activate();
|
||||||
|
|
||||||
|
// Return new activated `Self`
|
||||||
|
alert_dialog
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,150 +0,0 @@
|
||||||
mod action;
|
|
||||||
pub mod form;
|
|
||||||
|
|
||||||
use action::Action as WidgetAction;
|
|
||||||
use form::{list::item::value::Value, Form};
|
|
||||||
|
|
||||||
use crate::Profile;
|
|
||||||
use adw::{
|
|
||||||
prelude::{AdwDialogExt, AlertDialogExt, AlertDialogExtManual},
|
|
||||||
AlertDialog, ResponseAppearance,
|
|
||||||
};
|
|
||||||
use gtk::{glib::Uri, prelude::IsA};
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
// Defaults
|
|
||||||
const HEADING: &str = "Identity";
|
|
||||||
const BODY: &str = "Select identity certificate";
|
|
||||||
|
|
||||||
// Response variants
|
|
||||||
const RESPONSE_APPLY: (&str, &str) = ("apply", "Apply");
|
|
||||||
const RESPONSE_CANCEL: (&str, &str) = ("cancel", "Cancel");
|
|
||||||
// const RESPONSE_MANAGE: (&str, &str) = ("manage", "Manage");
|
|
||||||
|
|
||||||
// Select options
|
|
||||||
|
|
||||||
pub struct Widget {
|
|
||||||
alert_dialog: AlertDialog,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Widget {
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
/// Create new `Self`
|
|
||||||
pub fn build(
|
|
||||||
profile: &Rc<Profile>,
|
|
||||||
request: &Uri,
|
|
||||||
callback: &Rc<impl Fn(bool) + 'static>,
|
|
||||||
) -> Self {
|
|
||||||
// Init actions
|
|
||||||
let action = Rc::new(WidgetAction::new());
|
|
||||||
|
|
||||||
// Init child container
|
|
||||||
let form = Rc::new(Form::build(&action, profile, request));
|
|
||||||
|
|
||||||
// Init main widget
|
|
||||||
let alert_dialog = AlertDialog::builder()
|
|
||||||
.heading(HEADING)
|
|
||||||
.body(BODY)
|
|
||||||
.close_response(RESPONSE_CANCEL.0)
|
|
||||||
.default_response(RESPONSE_APPLY.0)
|
|
||||||
.extra_child(&form.g_box)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
alert_dialog.add_responses(&[
|
|
||||||
RESPONSE_CANCEL,
|
|
||||||
// RESPONSE_MANAGE,
|
|
||||||
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
|
|
||||||
// alert_dialog.set_response_enabled(RESPONSE_MANAGE.0, false);
|
|
||||||
|
|
||||||
// Decorate default response preset
|
|
||||||
alert_dialog.set_response_appearance(RESPONSE_APPLY.0, ResponseAppearance::Suggested);
|
|
||||||
/* contrast issue with Ubuntu orange accents
|
|
||||||
alert_dialog.set_response_appearance(RESPONSE_CANCEL.0, ResponseAppearance::Destructive); */
|
|
||||||
|
|
||||||
// Init events
|
|
||||||
action.update.connect_activate({
|
|
||||||
let form = form.clone();
|
|
||||||
let callback = callback.clone();
|
|
||||||
let alert_dialog = alert_dialog.clone();
|
|
||||||
move || {
|
|
||||||
// Update child components
|
|
||||||
form.update();
|
|
||||||
|
|
||||||
// Deactivate apply button if the form values could not be processed
|
|
||||||
alert_dialog.set_response_enabled(RESPONSE_APPLY.0, form.is_applicable());
|
|
||||||
|
|
||||||
callback(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Make initial update
|
|
||||||
action.update.activate();
|
|
||||||
|
|
||||||
// Return new activated `Self`
|
|
||||||
Self { alert_dialog }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actions
|
|
||||||
|
|
||||||
/// Show dialog with new preset
|
|
||||||
pub fn present(&self, parent: Option<&impl IsA<gtk::Widget>>) {
|
|
||||||
self.alert_dialog.present(parent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue