From 2f0dc8a38862483b8cd3e77d9fedc29f61d4f66e Mon Sep 17 00:00:00 2001 From: Chili Palmer Date: Fri, 14 Aug 2026 18:38:04 +0200 Subject: [PATCH] Show password counts on iPhone --- crates/storage/src/mobile_passwords.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/crates/storage/src/mobile_passwords.rs b/crates/storage/src/mobile_passwords.rs index 87ff06f..f902d58 100644 --- a/crates/storage/src/mobile_passwords.rs +++ b/crates/storage/src/mobile_passwords.rs @@ -179,13 +179,13 @@ fn mobile_row(node: &TreeNode) -> MobilePasswordRow { TreeNodeKind::Directory => ( MobilePasswordRowKind::Directory, "directory", - "Folder", + entry_count_detail(node), "folder", ), TreeNodeKind::Entry => ( MobilePasswordRowKind::Entry, "entry", - "Locked password", + "Locked password".to_owned(), "key.fill", ), }; @@ -193,12 +193,24 @@ fn mobile_row(node: &TreeNode) -> MobilePasswordRow { id: format!("{prefix}:{path}"), path, title: node.name().to_owned(), - detail: detail.to_owned(), + detail, system_image: system_image.to_owned(), kind, } } +fn entry_count_detail(node: &TreeNode) -> String { + let count = entry_count(node); + format!("{count} {}", if count == 1 { "entry" } else { "entries" }) +} + +fn entry_count(node: &TreeNode) -> usize { + match node.kind() { + TreeNodeKind::Directory => node.children().iter().map(entry_count).sum(), + TreeNodeKind::Entry => 1, + } +} + #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum MobilePasswordErrorKind { MissingConfiguration, @@ -311,12 +323,16 @@ mod tests { .join("Personal/a very long password entry name.gpg"), b"ciphertext", )?; + fs::create_dir_all(temporary.path().join("Solo"))?; + fs::write(temporary.path().join("Solo/only.gpg"), b"ciphertext")?; let repository = Repository::open(temporary.path())?; let root = MobilePasswordPage::from_repository(&repository, None)?; assert_eq!(root.title(), "Passwords"); assert_eq!(root.rows()[0].id(), "directory:Personal"); assert_eq!(root.rows()[0].kind(), MobilePasswordRowKind::Directory); + assert_eq!(root.rows()[0].detail(), "2 entries"); + assert_eq!(root.rows()[1].detail(), "1 entry"); let finance = MobilePasswordPage::from_repository(&repository, Some("Personal/Finance"))?; assert_eq!(finance.id(), "directory:Personal/Finance"); @@ -325,6 +341,7 @@ mod tests { finance.rows()[0].id(), "directory:Personal/Finance/Very Deep" ); + assert_eq!(finance.rows()[0].detail(), "0 entries"); assert_eq!(finance.rows()[1].id(), "entry:Personal/Finance/bank"); assert_eq!(finance.rows()[1].detail(), "Locked password");