Skip to content

fix(macos): Duplicates pane speaks the app's design language — selectable copies, Trash flow#266

Merged
caezium merged 1 commit into
mainfrom
fix/dupes-ux
Jul 11, 2026
Merged

fix(macos): Duplicates pane speaks the app's design language — selectable copies, Trash flow#266
caezium merged 1 commit into
mainfrom
fix/dupes-ux

Conversation

@caezium

@caezium caezium commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Addresses the hand-test feedback (no selection; UX inconsistent with the clean/purge/apps choosing pages and Analyze's folder selection). The pane now copies the app's idioms wholesale:

  • Clean-review checklist: tri-state group cards over checkbox copy rows (same 17px/15px box anatomy, card fill, reveal buttons), biggest 3 groups open by default.
  • Selection with a keep-one invariant (DupesSelection, pure + TDD'd): defaults to all-but-first per group; the last unticked copy of a group can't be ticked and wears a kept badge.
  • Clean's Trash flow verbatim: alert → FileManager.trashItem (recoverable) → HUD + DoneBanner → rescan. This is the 'select ones to remove' ask — reversible, unlike fclones' hard remove (stays CLI-only).
  • Analyze's toolbar idiom: up arrow + clickable breadcrumbs + mono summary + folder/refresh icon buttons.
  • Reclaim via clones… kept as the secondary pill (non-destructive, cp -c plan confirm).

4 new DupesSelection tests; full local Debug build compiles clean.

…able copies, Trash flow

Addresses the hand-test feedback: the pane was its own island (no selection, foreign UX).
Now it copies the app's established idioms wholesale:

- Clean-review CHECKLIST: each group is a tri-state card (17px box, checkmark/minus) over
  15px-checkbox copy rows (name + abbreviated path + size + reveal), collapsed by default
  with the biggest three open — the same anatomy as the clean choosing page.
- SELECTION with a keep-one invariant (DupesSelection, pure + TDD'd): defaults to all-but-
  first per group; ticking a group's last unticked copy is refused and that copy wears a
  "kept" badge; group boxes cycle none/mixed/all like Clean categories.
- Clean's TRASH flow verbatim: "Move N duplicate copies (X) to the Trash?" alert ->
  FileManager.trashItem per path (recoverable) -> HUD + DoneBanner -> rescan. This is the
  "select ones to remove" ask — reversible, unlike fclones' hard remove which stays CLI-only.
- Analyze's TOOLBAR idiom: up arrow + clickable breadcrumbs over the scanned folder +
  right-aligned mono summary + folder/refresh icon buttons (was a one-off capsule button).
- "Reclaim via clones…" (non-destructive dedupe with the cp -c plan confirm) kept as the
  secondary action in the footer, Clean-review pill style.

Tests: DupesSelection default/guard/tri-state/order (4 new); existing parser tests stand.
Compiles clean in a full local Debug build; UI is Henry-hand-tested territory.
@caezium
caezium merged commit 5e3b025 into main Jul 11, 2026
1 check passed
@caezium
caezium deleted the fix/dupes-ux branch July 11, 2026 20:12
caezium added a commit that referenced this pull request Jul 12, 2026
…scovery) (#273)

Three new read-only tool panes copying the post-#266 Duplicates pattern —
Analyze-style toolbar, the conductorMissing/idle/scanning/error/clean state
ladder, BurrowConductor.capture off-main with a scanGen supersede token,
OperationCenter begin/end, NSLocalizedString throughout, Brand styling:

* Leftovers (`burrow orphans <dir>`): folder picker + Caches/Logs quick
  chips; hits grouped into confidence tiers (medium > low > weak) with
  evidence on hover and Reveal in Finder. Pure OrphansReport.parse.
* Similar Photos (`burrow photos <dir>`, 600 s timeout — dHash is slow):
  clusters as cards, members with async ImageIO thumbnails (bounded
  NSCache, never a main-thread decode), 100-group render cap. Pure
  PhotosReport.parse.
* Network (`burrow net`): refresh-driven ranked table of nettop byte
  counters (name / pid / in / out / total via Fmt.bytes), metric_note
  surfaced when a degraded source swaps bytes for connection counts;
  auto-samples on first activation (PortsView's isActive idiom). Pure
  NetReport.parse.

Tool gains orphans/photos/net cases (olive/orchid/indigo accents, dark
tint tops, taglines); navOrder slots the discovery pair after Duplicates
and Network beside Ports. No exhaustive Tool switches exist outside
Tool.swift, so the enum growth is additive.

Tests first: OrphansModelTests / PhotosModelTests / NetModelTests cover
the spine, tier/size/total ordering, loose-field degradation, Int64
precision, and garbage-to-nil for every parser. Local Debug build +
build-for-testing both verified green.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant