draft identity exit feature

This commit is contained in:
yggverse 2024-12-05 20:26:42 +02:00
parent ddb915c602
commit 36d4673d44
2 changed files with 150 additions and 0 deletions

View File

@ -1,10 +1,12 @@
mod drop;
mod exit;
mod file;
pub mod list;
mod name;
mod save;
use drop::Drop;
use exit::Exit;
use file::File;
use list::{item::value::Value, List};
use name::Name;
@ -18,6 +20,7 @@ use std::rc::Rc;
pub struct Form {
// pub action: Rc<Action>,
// pub drop: Rc<Drop>,
// pub exit: Rc<Exit>,
pub file: Rc<File>,
pub list: Rc<List>,
pub name: Rc<Name>,
@ -36,6 +39,7 @@ impl Form {
let name = Rc::new(Name::new(action.clone()));
let save = Rc::new(Save::new(profile.clone()));
let drop = Rc::new(Drop::new(profile.clone(), action.clone(), list.clone()));
let exit = Rc::new(Exit::new(profile.clone(), action.clone(), list.clone()));
// Init main container
let g_box = Box::builder().orientation(Orientation::Vertical).build();
@ -43,12 +47,14 @@ impl Form {
g_box.append(&list.dropdown);
g_box.append(&name.entry);
g_box.append(&file.button);
g_box.append(&exit.button);
g_box.append(&drop.button);
g_box.append(&save.button);
// Connect events
list.on_select({
let drop = drop.clone();
let exit = exit.clone();
let file = file.clone();
let name = name.clone();
let save = save.clone();
@ -64,10 +70,12 @@ impl Form {
match item {
Value::ProfileIdentityGeminiId(value) => {
drop.update(Some(value));
exit.update(Some(value));
save.update(Some(value));
}
_ => {
drop.update(None);
exit.update(None);
save.update(None);
}
}
@ -81,6 +89,7 @@ impl Form {
Self {
// action,
// drop,
// exit,
file,
list,
name,

View File

@ -0,0 +1,141 @@
use super::Action;
use super::List;
use crate::profile::Profile;
use adw::{
prelude::{AdwDialogExt, AlertDialogExt, AlertDialogExtManual},
AlertDialog, ResponseAppearance,
};
use gtk::{
prelude::{ButtonExt, WidgetExt},
Button,
};
use std::{cell::RefCell, rc::Rc};
// Defaults
const LABEL: &str = "Disconnect";
const TOOLTIP_TEXT: &str = "Stop use selected identity everywhere";
const MARGIN: i32 = 8;
const HEADING: &str = "Disconnect";
const BODY: &str = "Stop use selected identity for all scopes?";
const RESPONSE_CANCEL: (&str, &str) = ("cancel", "Cancel");
const RESPONSE_CONFIRM: (&str, &str) = ("confirm", "Confirm");
pub struct Exit {
profile_identity_gemini_id: Rc<RefCell<Option<i64>>>,
pub button: Button,
}
impl Exit {
// Constructors
/// Create new `Self`
pub fn new(profile: Rc<Profile>, action: Rc<Action>, list: Rc<List>) -> Self {
// Init selected option holder
let profile_identity_gemini_id = Rc::new(RefCell::new(None::<i64>));
// Init main widget
let button = Button::builder()
.label(LABEL)
.margin_top(MARGIN)
.tooltip_text(TOOLTIP_TEXT)
.visible(false)
.build();
// Init events
button.connect_clicked({
let action = action.clone();
let button = button.clone();
let profile_identity_gemini_id = profile_identity_gemini_id.clone();
move |_| {
// Get selected identity from holder
match profile_identity_gemini_id.borrow().as_ref() {
Some(profile_identity_gemini_id) => {
// Init sub-widget
let alert_dialog = AlertDialog::builder()
.heading(HEADING)
.body(BODY)
.close_response(RESPONSE_CANCEL.0)
.default_response(RESPONSE_CANCEL.0)
.build();
// Set response variants
alert_dialog.add_responses(&[RESPONSE_CANCEL, RESPONSE_CONFIRM]);
// Decorate default response preset
alert_dialog.set_response_appearance(
RESPONSE_CONFIRM.0,
ResponseAppearance::Suggested,
);
alert_dialog.set_response_appearance(
RESPONSE_CANCEL.0,
ResponseAppearance::Destructive,
);
// Connect confirmation event
alert_dialog.connect_response(Some(RESPONSE_CONFIRM.0), {
let action = action.clone();
let button = button.clone();
let list = list.clone();
let profile = profile.clone();
let profile_identity_gemini_id = *profile_identity_gemini_id;
move |_, _| {
match profile
.identity
.gemini
.auth
.remove_ref(profile_identity_gemini_id)
{
Ok(_) => {
if list.remove(profile_identity_gemini_id).is_some() {
button.set_css_classes(&["success"]);
button.set_label("Identity successfully disconnected")
} else {
button.set_css_classes(&["error"]);
button.set_label("List item not found")
// @TODO unexpected
}
}
Err(e) => {
button.set_css_classes(&["error"]);
button.set_label(&e.to_string())
}
}
action.update.activate()
}
});
// Show dialog
alert_dialog.present(Some(&button))
}
None => todo!(), // unexpected
}
}
});
// Return activated `Self`
Self {
profile_identity_gemini_id,
button,
}
}
// Actions
/// Update `profile_identity_gemini_id` holder,
/// toggle visibility depending on given value
pub fn update(&self, profile_identity_gemini_id: Option<i64>) {
self.button.set_visible(match profile_identity_gemini_id {
Some(value) => {
self.profile_identity_gemini_id.replace(Some(value));
true
}
None => {
self.profile_identity_gemini_id.replace(None);
false
}
})
}
}