implement exit button as trait, set disconnect button status update by total

This commit is contained in:
yggverse 2025-01-29 20:37:56 +02:00
parent e1345a4922
commit 91cd9cbae9
4 changed files with 41 additions and 26 deletions

View file

@ -14,19 +14,22 @@ use save::Save;
use super::WidgetAction; use super::WidgetAction;
use crate::Profile; use crate::Profile;
use gtk::{glib::Uri, prelude::BoxExt, Box, Orientation}; use gtk::{
glib::Uri,
prelude::{BoxExt, WidgetExt},
Box, Button, Orientation,
};
use std::rc::Rc; use std::rc::Rc;
pub struct Form { pub struct Form {
// pub action_widget: Rc<Action>, // pub action_widget: Rc<Action>,
pub drop: Rc<Drop>, pub drop: Rc<Drop>,
pub exit: Rc<Exit>, pub exit: Button,
pub file: Rc<File>, pub file: Rc<File>,
pub list: Rc<List>, pub list: Rc<List>,
pub name: Rc<Name>, pub name: Rc<Name>,
pub save: Rc<Save>, pub save: Rc<Save>,
pub g_box: Box, pub g_box: Box,
request: Uri,
profile: Rc<Profile>, profile: Rc<Profile>,
} }
@ -41,7 +44,7 @@ impl Form {
let name = Rc::new(Name::build(widget_action)); let name = Rc::new(Name::build(widget_action));
let save = Rc::new(Save::build(profile, &list)); let save = Rc::new(Save::build(profile, &list));
let drop = Rc::new(Drop::build(profile, &list)); let drop = Rc::new(Drop::build(profile, &list));
let exit = Rc::new(Exit::build(widget_action, profile, &list, request)); let exit = Button::exit(widget_action, profile, &list, request);
// Init main container // Init main container
let g_box = Box::builder().orientation(Orientation::Vertical).build(); let g_box = Box::builder().orientation(Orientation::Vertical).build();
@ -49,7 +52,7 @@ impl Form {
g_box.append(&list.dropdown); g_box.append(&list.dropdown);
g_box.append(&name.entry); g_box.append(&name.entry);
g_box.append(&file.button); g_box.append(&file.button);
g_box.append(&exit.button); g_box.append(&exit);
g_box.append(&drop.button); g_box.append(&drop.button);
g_box.append(&save.button); g_box.append(&save.button);
@ -63,7 +66,6 @@ impl Form {
name, name,
save, save,
g_box, g_box,
request: request.clone(),
profile: profile.clone(), profile: profile.clone(),
} }
} }
@ -90,18 +92,15 @@ impl Form {
match value { match value {
Value::ProfileIdentityId(profile_identity_id) => { Value::ProfileIdentityId(profile_identity_id) => {
self.drop.update(true); self.drop.update(true);
self.exit.update( self.exit.set_visible(true);
true, self.exit
self.profile .set_sensitive(self.profile.identity.auth.total(profile_identity_id) > 0);
.identity
.auth
.is_matches(&self.request.to_string(), profile_identity_id),
);
self.save.update(true); self.save.update(true);
} }
_ => { _ => {
self.drop.update(false); self.drop.update(false);
self.exit.update(false, false); self.exit.set_visible(false);
self.exit.set_sensitive(false);
self.save.update(false); self.save.update(false);
} }
} }

View file

@ -25,15 +25,20 @@ const BODY: &str = "Stop use selected identity for all scopes?";
const RESPONSE_CANCEL: (&str, &str) = ("cancel", "Cancel"); const RESPONSE_CANCEL: (&str, &str) = ("cancel", "Cancel");
const RESPONSE_CONFIRM: (&str, &str) = ("confirm", "Confirm"); const RESPONSE_CONFIRM: (&str, &str) = ("confirm", "Confirm");
pub struct Exit { pub trait Exit {
pub button: Button, fn exit(
widget_action: &Rc<WidgetAction>,
profile: &Rc<Profile>,
list: &Rc<List>,
request: &Uri,
) -> Self;
} }
impl Exit { impl Exit for Button {
// Constructors // Constructors
/// Create new `Self` /// Create new `Self`
pub fn build( fn exit(
widget_action: &Rc<WidgetAction>, widget_action: &Rc<WidgetAction>,
profile: &Rc<Profile>, profile: &Rc<Profile>,
list: &Rc<List>, list: &Rc<List>,
@ -122,13 +127,6 @@ impl Exit {
}); });
// Return activated `Self` // Return activated `Self`
Self { button } button
}
// Actions
pub fn update(&self, is_visible: bool, is_sensitive: bool) {
self.button.set_visible(is_visible);
self.button.set_sensitive(is_sensitive);
} }
} }

View file

@ -124,6 +124,11 @@ impl Auth {
.is_some_and(|auth| auth.profile_identity_id == profile_identity_id) .is_some_and(|auth| auth.profile_identity_id == profile_identity_id)
} }
/// Check request string matches condition
pub fn total(&self, profile_identity_id: i64) -> usize {
self.memory.total(profile_identity_id)
}
/// Collect certificate scope vector from `Profile` database for `profile_identity_id` /// Collect certificate scope vector from `Profile` database for `profile_identity_id`
pub fn scope(&self, profile_identity_id: i64) -> Vec<String> { pub fn scope(&self, profile_identity_id: i64) -> Vec<String> {
let mut scope = Vec::new(); let mut scope = Vec::new();

View file

@ -79,4 +79,17 @@ impl Memory {
// Get first copy // Get first copy
result.first().cloned() result.first().cloned()
} }
/// Get identity exactly match `scope`
/// * [Client certificates specification](https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates)
/// * see also parent `is_match_request`
pub fn total(&self, profile_identity_id: i64) -> usize {
let mut total = 0;
for (_, _profile_identity_id) in self.index.borrow().iter() {
if *_profile_identity_id == profile_identity_id {
total += 1
}
}
total
}
} }