feat(library): photo + status badge + ManageImageSheet (Concept A)
CI / test (push) Has been cancelled

Library was rendering one approval chip per device per photo PLUS one
lock chip per approved device. That's O(photos × devices) buttons —
fine at one or two frames, breaks at four+ (see
_bmad-output/.../library-many-frames-design-ideas.md).

Concept A from the design memo:
  - Each photo card stays a square thumb + a single "Manage" row.
  - Manage row summarises state: "3/5 frames · 🔒 Mom's Place".
  - A corner-lock badge sits on the thumb itself when any frame has the
    image locked, so the lock status is glanceable from the grid.
  - Tapping Manage opens the new ManageImageSheet bottom sheet, which
    lists every frame with an approve toggle + per-frame lock pill.
    Lock pill is disabled until the frame is approved.

Per-photo widgets drop from O(photos × devices) to O(photos). Works
identically at 1 or 50 frames. Curation principle stays "manage photos
TO the frame" — same store calls (imagesStore.setApproval,
devicesStore.lockImage/unlockImage), just routed through the sheet
instead of inline chip rows.

10 new ManageImageSheet unit tests + LibraryView tests rewritten to
cover the sheet-open + event-forwarding flow. 358/358 frontend tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-14 15:26:41 -04:00
parent 9854688a49
commit 84642ed13f
13 changed files with 589 additions and 135 deletions
+1 -1
View File
@@ -14,7 +14,7 @@
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="pictureFrame" />
<script type="module" crossorigin src="/build/assets/index-Bx9Y0zPK.js"></script>
<script type="module" crossorigin src="/build/assets/index-Ds9OAB3e.js"></script>
<link rel="modulepreload" crossorigin href="/build/assets/_plugin-vue_export-helper-BNDVmFr7.js">
<link rel="stylesheet" crossorigin href="/build/assets/index-BlLBHR1q.css">
</head>