From edaf1d6d82737d7e61fd1e3f93950fa31c544227 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 19 Feb 2026 19:55:36 +0000 Subject: [PATCH] feat: add delete all user fingerprints option - Add `DeleteAllUsersPrints` variant to `Page` enum. - Implement `delete_fingers` function in `fprint.rs` for bulk deletion. - Update UI and logic in `mod.rs` to handle the new "Delete All" page. - Add localization key for the new page. - Update `as_finger_id()` to return `Option<&'static str>`. --- i18n/en/cosmic_ext_fprint.ftl | 1 + src/app/fprint.rs | 15 ++++++++ src/app/mod.rs | 65 ++++++++++++++++++++++------------- src/app/page.rs | 51 +++++++++++++++------------ 4 files changed, 86 insertions(+), 46 deletions(-) diff --git a/i18n/en/cosmic_ext_fprint.ftl b/i18n/en/cosmic_ext_fprint.ftl index 96b4dc4..d726dd4 100644 --- a/i18n/en/cosmic_ext_fprint.ftl +++ b/i18n/en/cosmic_ext_fprint.ftl @@ -20,6 +20,7 @@ page-left-index-finger = Left Index Finger page-left-middle-finger = Left Middle Finger page-left-ring-finger = Left Ring Finger page-left-little-finger = Left Little Finger +page-delete-all-users-prints = Delete All User's Prints status-connecting = Connecting to system bus... status-searching-device = Searching for fingerprint reader... diff --git a/src/app/fprint.rs b/src/app/fprint.rs index 51c02a7..89c49eb 100644 --- a/src/app/fprint.rs +++ b/src/app/fprint.rs @@ -39,6 +39,21 @@ pub async fn delete_fingerprint_dbus( res.and(rel_res) } +pub async fn delete_fingers( + connection: &zbus::Connection, + path: zbus::zvariant::OwnedObjectPath, + username: String, +) -> zbus::Result<()> { + let device = DeviceProxy::builder(connection).path(path)?.build().await?; + + device.claim(&username).await?; + let enrolled = device.list_enrolled_fingers(&username).await?; + for finger in enrolled { + device.delete_enrolled_finger(&finger).await?; + } + device.release().await +} + pub async fn enroll_fingerprint_process( connection: zbus::Connection, path: zbus::zvariant::OwnedObjectPath, diff --git a/src/app/mod.rs b/src/app/mod.rs index e0ae5fa..0245691 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -26,7 +26,8 @@ pub mod error; use page::{ContextPage, Page}; use message::{Message, UserOption}; use fprint::{ - delete_fingerprint_dbus, enroll_fingerprint_process, find_device, list_enrolled_fingers_dbus, + delete_fingerprint_dbus, delete_fingers, enroll_fingerprint_process, find_device, + list_enrolled_fingers_dbus, }; use error::AppError; @@ -339,13 +340,13 @@ impl cosmic::Application for AppModel { Message::DeleteComplete => { self.status = fl!("deleted"); self.busy = false; - self.enrolled_fingers.retain(|f| { - f != self - .nav - .data::(self.nav.active()) - .map(|p| p.as_finger_id()) - .unwrap_or_default() - }); + if let Some(page) = self.nav.data::(self.nav.active()) { + if let Some(finger_id) = page.as_finger_id() { + self.enrolled_fingers.retain(|f| f != finger_id); + } else { + self.enrolled_fingers.clear(); + } + } Task::none() } @@ -660,29 +661,43 @@ impl AppModel { { self.status = fl!("deleting"); self.busy = true; - let finger_name = page.as_finger_id().to_string(); let path = (*path).clone(); let username = (*user.username).clone(); - return Task::perform( - async move { - match delete_fingerprint_dbus(&conn, path, finger_name, username).await { - Ok(_) => Message::DeleteComplete, - Err(e) => Message::OperationError(AppError::from(e)), - } - }, - cosmic::Action::App, - ); + + if let Some(finger_name) = page.as_finger_id() { + let finger_name = finger_name.to_string(); + return Task::perform( + async move { + match delete_fingerprint_dbus(&conn, path, finger_name, username).await { + Ok(_) => Message::DeleteComplete, + Err(e) => Message::OperationError(AppError::from(e)), + } + }, + cosmic::Action::App, + ); + } else { + return Task::perform( + async move { + match delete_fingers(&conn, path, username).await { + Ok(_) => Message::DeleteComplete, + Err(e) => Message::OperationError(AppError::from(e)), + } + }, + cosmic::Action::App, + ); + } } Task::none() } fn on_register(&mut self) -> Task> { if let Some(page) = self.nav.data::(self.nav.active()) + && let Some(finger_id) = page.as_finger_id() && self.device_path.is_some() && self.selected_user.is_some() { self.busy = true; - self.enrolling_finger = Some(Arc::new(page.as_finger_id().to_string())); + self.enrolling_finger = Some(Arc::new(finger_id.to_string())); self.status = fl!("status-starting-enrollment"); } Task::none() @@ -764,15 +779,17 @@ impl AppModel { !self.busy && self.device_path.is_some() && self.enrolling_finger.is_none(); let current_page = self.nav.data::(self.nav.active()); - let current_finger = current_page.map(|p| p.as_finger_id()); - let is_enrolled = current_finger - .map(|f| self.enrolled_fingers.iter().any(|ef| ef == f)) - .unwrap_or(false); + let current_finger = current_page.and_then(|p| p.as_finger_id()); + let is_enrolled = if let Some(f) = current_finger { + self.enrolled_fingers.iter().any(|ef| ef == f) + } else { + !self.enrolled_fingers.is_empty() + }; let register_btn = widget::button::text(fl!("register")); let delete_btn = widget::button::text(fl!("delete")); - let register_btn = if buttons_enabled { + let register_btn = if buttons_enabled && current_finger.is_some() { register_btn.on_press(Message::Register) } else { register_btn diff --git a/src/app/page.rs b/src/app/page.rs index 5103f64..c8782e0 100644 --- a/src/app/page.rs +++ b/src/app/page.rs @@ -16,6 +16,7 @@ pub enum Page { LeftMiddle, LeftRing, LeftPinky, + DeleteAllUsersPrints, } impl Page { @@ -31,6 +32,7 @@ impl Page { Self::LeftMiddle, Self::LeftRing, Self::LeftPinky, + Self::DeleteAllUsersPrints, ] } @@ -46,21 +48,23 @@ impl Page { Self::LeftMiddle => fl!("page-left-middle-finger"), Self::LeftRing => fl!("page-left-ring-finger"), Self::LeftPinky => fl!("page-left-little-finger"), + Self::DeleteAllUsersPrints => fl!("page-delete-all-users-prints"), } } - pub fn as_finger_id(&self) -> &'static str { + pub fn as_finger_id(&self) -> Option<&'static str> { match self { - Page::RightThumb => "right-thumb", - Page::RightIndex => "right-index-finger", - Page::RightMiddle => "right-middle-finger", - Page::RightRing => "right-ring-finger", - Page::RightPinky => "right-little-finger", - Page::LeftThumb => "left-thumb", - Page::LeftIndex => "left-index-finger", - Page::LeftMiddle => "left-middle-finger", - Page::LeftRing => "left-ring-finger", - Page::LeftPinky => "left-little-finger", + Page::RightThumb => Some("right-thumb"), + Page::RightIndex => Some("right-index-finger"), + Page::RightMiddle => Some("right-middle-finger"), + Page::RightRing => Some("right-ring-finger"), + Page::RightPinky => Some("right-little-finger"), + Page::LeftThumb => Some("left-thumb"), + Page::LeftIndex => Some("left-index-finger"), + Page::LeftMiddle => Some("left-middle-finger"), + Page::LeftRing => Some("left-ring-finger"), + Page::LeftPinky => Some("left-little-finger"), + Page::DeleteAllUsersPrints => None, } } } @@ -79,7 +83,7 @@ mod tests { #[test] fn test_page_all() { let pages = Page::all(); - assert_eq!(pages.len(), 10); + assert_eq!(pages.len(), 11); assert_eq!(pages[0], Page::RightThumb); assert_eq!(pages[1], Page::RightIndex); assert_eq!(pages[2], Page::RightMiddle); @@ -90,6 +94,7 @@ mod tests { assert_eq!(pages[7], Page::LeftMiddle); assert_eq!(pages[8], Page::LeftRing); assert_eq!(pages[9], Page::LeftPinky); + assert_eq!(pages[10], Page::DeleteAllUsersPrints); } #[test] @@ -106,19 +111,21 @@ mod tests { assert!(!Page::LeftMiddle.localized_name().is_empty()); assert!(!Page::LeftRing.localized_name().is_empty()); assert!(!Page::LeftPinky.localized_name().is_empty()); + assert!(!Page::DeleteAllUsersPrints.localized_name().is_empty()); } #[test] fn test_page_as_finger_id() { - assert_eq!(Page::RightThumb.as_finger_id(), "right-thumb"); - assert_eq!(Page::RightIndex.as_finger_id(), "right-index-finger"); - assert_eq!(Page::RightMiddle.as_finger_id(), "right-middle-finger"); - assert_eq!(Page::RightRing.as_finger_id(), "right-ring-finger"); - assert_eq!(Page::RightPinky.as_finger_id(), "right-little-finger"); - assert_eq!(Page::LeftThumb.as_finger_id(), "left-thumb"); - assert_eq!(Page::LeftIndex.as_finger_id(), "left-index-finger"); - assert_eq!(Page::LeftMiddle.as_finger_id(), "left-middle-finger"); - assert_eq!(Page::LeftRing.as_finger_id(), "left-ring-finger"); - assert_eq!(Page::LeftPinky.as_finger_id(), "left-little-finger"); + assert_eq!(Page::RightThumb.as_finger_id(), Some("right-thumb")); + assert_eq!(Page::RightIndex.as_finger_id(), Some("right-index-finger")); + assert_eq!(Page::RightMiddle.as_finger_id(), Some("right-middle-finger")); + assert_eq!(Page::RightRing.as_finger_id(), Some("right-ring-finger")); + assert_eq!(Page::RightPinky.as_finger_id(), Some("right-little-finger")); + assert_eq!(Page::LeftThumb.as_finger_id(), Some("left-thumb")); + assert_eq!(Page::LeftIndex.as_finger_id(), Some("left-index-finger")); + assert_eq!(Page::LeftMiddle.as_finger_id(), Some("left-middle-finger")); + assert_eq!(Page::LeftRing.as_finger_id(), Some("left-ring-finger")); + assert_eq!(Page::LeftPinky.as_finger_id(), Some("left-little-finger")); + assert_eq!(Page::DeleteAllUsersPrints.as_finger_id(), None); } }