Archive/delete now flash a red cross then drop tiles from the grid
immediately, instead of a green check that lingered until the slow
server-reconcile refetch landed. Keyboard `x` archive previously never
called markRemoved, so tiles only vanished on refetch — that lag is gone.
- Add 'removed' bulk state + removedBulk() helper (red cross overlay)
- gridKeyNav archive/delete: removedBulk -> 500ms flash -> markRemoved,
clearRemoved once refetch settles; restore stays green check
- BulkActionBar: BulkConfig.removing routes archive/delete through the
red flash; approve/restore/label/note unchanged
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Problem 1 — per-photo progress overlay never rendered on the grid:
- bulkPhotoStates was `$state(new Map())`; a `.get(uid)` read in PhotoTile
didn't reliably re-run when the entry flipped, so the spinner/check/X
overlay never appeared. Switch to SvelteMap (svelte/reactivity).
Problem 2 — Notes / Colors / Ratings only showed the newest ~1000 photos:
- All three derived from `listPhotos({ count: 1000 })`, silently hiding
older marked/noted photos.
- listPhotosWithNotes now pages the whole library.
- Add listPhotosByUids() and resolve the Colors/Ratings marks-pool from the
complete marked-UID set (from getAllMarks) instead of the newest slice;
wire it into the TagsBrowserSidebar panel and the tag drill page.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Issue 1 — colors/labels not applying in bulk:
- sidecar validColors only accepted 4 of the 8 UI swatches, so teal/blue/
purple/pink returned "invalid color" and rolled back the whole bulk txn.
Add teal, blue, purple, pink to validColors.
- Add invalidateFacets() and call it on the success path of bulk marks,
patchTargets, and single-photo edits so the Colors/Ratings/Notes facet
sections refresh immediately instead of waiting out staleTime.
Issue 2 — archived photos linger in the grid:
- Add a UI-only removedIds set to the bulkAction store; archive/delete/
restore/keep call markRemoved() on success so tiles vanish instantly,
cleared once the server-reconcile refetch lands (no cache eviction).
Issue 3 — per-photo progress state:
- Wire startBulk/doneBulk/failBulk into all metadata applies, bulk
(BulkMetadataSidebar) and single (RightSidebar), so colors/ratings/
notes/dates/keywords show the spinner -> check -> X overlay.
Issue 4 — remove Left-sidebar count badges:
- Drop count badges from root folder, Archive, heaps, Notes, and the
folder tree, plus the now-dead count queries and unused imports. Facet
drill-panel counts are unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- New bulkAction store: tracks active/label/detail state for the pill
and a Map<uid, pending|done|error> for per-tile overlays
- Extract StatusPill.svelte from IndexerStatusPill (generic active/label/detail
props); IndexerStatusPill becomes a one-line wrapper
- +layout.svelte: render a second StatusPill driven by bulkAction store,
alongside the indexer pill in the AnimatedMule header
- BulkActionBar: extend withBusy with optional BulkConfig (ids/label/doneLabel);
pending tiles dim + spinner on start, green checkmark flashes for 400ms before
cache invalidation removes them; red overlay on error, auto-clears after 2s
- onApprove/batchEdit: wire onProgress callback to setDetail so the pill shows
the filename currently being processed during fan-out keep operations
- batch.ts: add completedId as third arg to onProgress (backwards-compatible)
- PhotoTile: derive bulkState from store; pending/done/error overlays sit above
the selection tint; hover-video guarded against pending tiles
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>