web: three panels — Generate, Gallery, Collections — and a layout

ported from the standalone app's hash-tab UI. The panels do not coordinate through props (the panel
contract only ever hands a component its panelId) or usePanelChannel-as-selection:

- Gallery's lightbox is ?selected=<id>, Collections' detail is ?collection=<id> — different names
  since both panels render on the same route at once
- Generate bumps useAtelierRefresh (added to officerdev/src/channels.ts) when a job finishes;
  Gallery subscribes to it — a genuine signal, not a selection, so it stays a channel

images render through GET /files/:filename with a ?token= query param appended client-side
(lib/api.ts's fileUrl), the same escape hatch FileViewer and the music plugin use for exactly this:
a browser cannot set an Authorization header on an <img src>.

Providers is not here — see PLUGIN.md for why it became a platform settings screen instead.

assets/icon.png and assets/splash.png are [placeholder] flat swatches, not real artwork — see
assets/PLACEHOLDER.md.
This commit is contained in:
2026-08-20 04:01:10 +00:00
parent f23ec1283b
commit 859fb5767c
14 changed files with 1211 additions and 0 deletions
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB