From 69730bfc5fd141038c649d07799637c0dfaaad74 Mon Sep 17 00:00:00 2001 From: Brain Wang Date: Thu, 29 Oct 2026 10:23:03 +0800 Subject: [PATCH] Issue #3251: People card badge shows the full photo count; drop the count line under the name Co-Authored-By: Claude Sonnet 5.5 --- crates/ui-egui/src/panels/people.rs | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/crates/ui-egui/src/panels/people.rs b/crates/ui-egui/src/panels/people.rs index 73d19cbaa..f495deb03 100644 --- a/crates/ui-egui/src/panels/people.rs +++ b/crates/ui-egui/src/panels/people.rs @@ -153,11 +153,21 @@ pub fn show(app: &mut LightcraftApp, ui: &mut egui::Ui) { }); } +/// The badge on a person's picture: the full number of photos (the app has no digit-grouping helper, so counts elsewhere are plain too). +fn badge_count(count: usize) -> String { + count.to_string() +} + +/// "6110 photos", for what assistive tools announce. +fn photo_count_text(count: usize) -> String { + crate::i18n::tr_format!("{n} photo{}", if count == 1 { "" } else { "s" }, n = count) +} + fn card(app: &mut LightcraftApp, ui: &mut egui::Ui, person: &Person, r: Rect, edge: f32, ppp: f32, selected: bool) { let t = Tokens::get(ui.ctx()); let face = Rect::from_min_size(r.min, vec2(edge, edge)); let resp = ui.interact(r, egui::Id::unique(("person-card", &person.name)), Sense::click()); - crate::widgets::announce(&resp, person.name.clone()); + crate::widgets::announce(&resp, format!("{}, {}", person.name, photo_count_text(person.count))); register(ui, format!("person:{}", person.name), r); let view = app.session.face_view(person.photo, person.face); let p = ui.painter(); @@ -168,9 +178,11 @@ fn card(app: &mut LightcraftApp, ui: &mut egui::Ui, person: &Person, r: Rect, ed p.image(tex.tex.id(), face, Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0)), Color32::WHITE); } // how many photos they are in, on the picture - let count = if person.count > 999 { "999+".to_string() } else { person.count.to_string() }; - let g = p.layout_no_wrap(count, t.font(11.5), Color32::WHITE); - let pill = Rect::from_min_size(pos2(face.right() - g.size().x - 14.0, face.bottom() - g.size().y - 11.0), g.size() + vec2(10.0, 6.0)); + let g = p.layout_no_wrap(badge_count(person.count), t.font(11.5), Color32::WHITE); + let pill = Rect::from_min_size( + pos2((face.right() - g.size().x - 14.0).max(face.left() + 2.0), face.bottom() - g.size().y - 11.0), + g.size() + vec2(10.0, 6.0), + ); p.rect_filled(pill, 4.0, Color32::from_black_alpha(175)); p.galley(pill.min + vec2(5.0, 3.0), g, Color32::WHITE); if selected { @@ -181,8 +193,6 @@ fn card(app: &mut LightcraftApp, ui: &mut egui::Ui, person: &Person, r: Rect, ed // a long name must not run past the card let name = fit(p, &person.name, t.semibold(13.0), edge); p.text(pos2(r.left() + 2.0, face.bottom() + 14.0), Align2::LEFT_CENTER, name, t.semibold(13.0), t.text); - let photos = crate::i18n::tr_format!("{n} photo{}", if person.count == 1 { "" } else { "s" }, n = person.count); - p.text(pos2(r.left() + 2.0, face.bottom() + 32.0), Align2::LEFT_CENTER, photos, t.font(12.0), t.text_dim); let resp = resp.on_hover_text(crate::i18n::tr_format!("{} — show their photos", person.name)); let full = person.name.clone(); crate::widgets::context_menu(&resp, |ui| { @@ -206,6 +216,13 @@ pub(crate) fn open_rename(app: &mut LightcraftApp, name: &str) { mod tests { use super::*; + #[test] + fn the_badge_shows_the_full_count_not_a_capped_one() { + assert_eq!((badge_count(6110), badge_count(1), badge_count(999_999)), ("6110".to_string(), "1".to_string(), "999999".to_string())); + assert_eq!(photo_count_text(6110), "6110 photos"); + assert_eq!(photo_count_text(1), "1 photo"); + } + #[test] fn faces_follow_the_thumbnail_slider_within_their_own_limits() { assert_eq!((card_edge(90.0), card_edge(480.0)), (84.0, 260.0));