ui: rework selection/heap visuals, contextual shortcut hints, inline scan activity

- Selection now reads as a blue ring + tint with a springy scale-down,
  hover stays a subtle gray ring so keyboard-driven and mouse-driven
  states are tellable apart.
- Heap membership is signalled with a green tint only (no badge, no
  ring, no scale).
- Discard/restore is optimistic and non-yanking: photos stay in the
  grid greyed out until the next reload, X toggles based on the
  current state, and the same treatment applies in preview.
- Filmstrip mirrors the grid styling (selection blue, heap green,
  discarded grey).
- Preview close restores the LAST viewed photo as the focused/selected
  one in the grid.
- Right sidebar collapses on view change and re-opens when a photo is
  in focus; Esc clears active selection so the panel collapses too.
- Keyboard hints panel is context-aware (grid / preview / discarded
  section), collapsible with H, persisted, and rendered inside the
  preview column above the filmstrip.
- "Pick (P)" renamed to "Select (S)" everywhere.
- Needs review moved into the Flag pill dropdown.
- Fixed vertical videos overflowing the preview column (min-h-0).
- Replaced the bottom-right ScanProgress popover with an inline
  spinner next to the FOLDERS sidebar header (and on the specific
  folder row being scanned). ScanProgress is now a headless
  invalidator; useScanActivity exposes the live status.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-14 23:45:36 +02:00
parent a6eb406052
commit 8529771122
17 changed files with 501 additions and 408 deletions

View File

@@ -92,8 +92,14 @@ export function ActiveHeapCard() {
}}
>
{visible.length === 0 ? (
<div className="flex h-full items-center justify-center px-2 text-center text-[11px] text-text-faint">
Pick photos with P to fill the heap
<div className="flex h-full items-center justify-center px-2 text-center">
<span className="rounded bg-black/70 px-2 py-1 text-[11px] font-medium text-white shadow-sm backdrop-blur-sm">
Select photos with{' '}
<kbd className="rounded bg-white/20 px-1 font-mono text-[10px] text-white">
S
</kbd>{' '}
to fill the heap
</span>
</div>
) : (
<div className="relative h-full">

View File

@@ -273,7 +273,7 @@ export function HeapsPanel() {
'group relative flex h-[24px] cursor-pointer items-center gap-1 rounded px-2 text-[12px] leading-none',
isFiltered ? 'bg-primary/20 text-primary' : 'text-text hover:bg-surface-2',
// Active-heap row gets a soft primary wash so the
// user always knows where Pick / T will land, even
// user always knows where Select / T will land, even
// when viewing a different section.
isActive && !isFiltered && 'bg-primary/8 text-text',
isDropTarget && 'ring-2 ring-primary bg-primary/10'
@@ -350,7 +350,7 @@ export function HeapsPanel() {
{isActive && (
<span
className="ml-1 flex-shrink-0 rounded-full bg-primary/25 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-primary"
title="Active heap — Pick (P) and the basket badge on photos point here"
title="Active heap — Select (S) and the basket badge on photos point here"
>
Active
</span>