fix(modal) (9374214): Modal TagPanel chip rail now refreshes after accepting a suggestion — the chip used to look unchanged even though the backend had recorded the application.
fix(showcase) (412edec): Infinite scroll no longer surrenders on the first all-duplicate random batch. Retries up to 8 times before falling back to "End." (graceful tiny-library handling). Showcase is endless by intent.
fix(download) (91be9df): attach_in_place now dispatches archive/non-media to _import_archive/_capture_attachment, mirroring import_one. Without this, gallery-dl-downloaded zips/PDFs/audio bounced back as skipped+invalid_image and flipped otherwise-successful runs to status="error" (Lustria patreon event #38998: 21 image attaches + 1 OST zip = red). Same commit also reshuffles the showcase on every mount, not just when the store is empty.
Test Plan
Open an image with suggestions, accept one — chip rail updates immediately
Scroll the showcase deep enough that prior random batches collide on seen; should keep loading instead of showing "End."
Navigate away from /showcase and back — fresh shuffle, not the same tiles
Run a patreon subscription tick on a source that includes non-media (zip/PDF) — event lands status=ok and the non-media is recorded as a PostAttachment
## Summary
Three operator-flagged UX/integrity fixes.
- **fix(modal)** (9374214): Modal TagPanel chip rail now refreshes after accepting a suggestion — the chip used to look unchanged even though the backend had recorded the application.
- **fix(showcase)** (412edec): Infinite scroll no longer surrenders on the first all-duplicate random batch. Retries up to 8 times before falling back to "End." (graceful tiny-library handling). Showcase is endless by intent.
- **fix(download)** (91be9df): `attach_in_place` now dispatches archive/non-media to `_import_archive`/`_capture_attachment`, mirroring `import_one`. Without this, gallery-dl-downloaded zips/PDFs/audio bounced back as `skipped+invalid_image` and flipped otherwise-successful runs to status="error" (Lustria patreon event #38998: 21 image attaches + 1 OST zip = red). Same commit also reshuffles the showcase on every mount, not just when the store is empty.
## Test Plan
- [ ] Open an image with suggestions, accept one — chip rail updates immediately
- [ ] Scroll the showcase deep enough that prior random batches collide on `seen`; should keep loading instead of showing "End."
- [ ] Navigate away from /showcase and back — fresh shuffle, not the same tiles
- [ ] Run a patreon subscription tick on a source that includes non-media (zip/PDF) — event lands status=ok and the non-media is recorded as a PostAttachment
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Operator-flagged 2026-06-01: clicking Accept on a suggestion added
the tag to the database but the modal's chip rail kept showing the
old set. Suggestion would disappear from the suggestions list
(suggestionsStore drops it from byCategory) and the toast would
confirm "Tagged: …", but visually the modal looked unchanged
until you closed and reopened it.
Root cause: useSuggestionsStore.accept() POSTs to the backend and
updates its own state, but never tells useModalStore that the
backing image's tag set has changed. The addExistingTag and
createAndAdd flows in TagPanel already call modal.reloadTags()
after applying — the suggestions path needed the same refresh.
Two-line fix in SuggestionsPanel: after store.accept() and
store.aliasAccept(), call modal.reloadTags() so TagPanel's
`modal.current?.tags` rebinds.
/api/showcase returns a random sample; after enough scrolling, an
unlucky 3-item batch can be entirely in the `seen` Set, which was
flipping `exhausted=true` and surfacing "End." mid-scroll. The
showcase is endless by intent — only a genuinely empty API response
(library has 0 images) should mark it exhausted. Tiny-library
fallback: cap retries at 8 to avoid spinning forever.
attach_in_place mirrored only the media flow, so gallery-dl-downloaded
zips/PDFs/audio bounced back as `skipped+invalid_image`, which
download_service counted as an ingest error and flipped runs to
status="error" despite N successful image attaches. Lustria patreon
event #38998 (21 images + 1 OST zip) went red for exactly this reason.
Now attach_in_place dispatches the same way as import_one: archives →
_import_archive (extracts media members, captures archive as
PostAttachment), non-media → _capture_attachment. Download_service
accepts the new `attached` result and treats non-duplicate skips as
soft skips, not ingest errors.
Also: ShowcaseView always loadInitial() on mount, not just when the
store is empty — Pinia persists across navigations and operator wants
a fresh shuffle every time the showcase loads.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Three operator-flagged UX/integrity fixes.
9374214): Modal TagPanel chip rail now refreshes after accepting a suggestion — the chip used to look unchanged even though the backend had recorded the application.412edec): Infinite scroll no longer surrenders on the first all-duplicate random batch. Retries up to 8 times before falling back to "End." (graceful tiny-library handling). Showcase is endless by intent.91be9df):attach_in_placenow dispatches archive/non-media to_import_archive/_capture_attachment, mirroringimport_one. Without this, gallery-dl-downloaded zips/PDFs/audio bounced back asskipped+invalid_imageand flipped otherwise-successful runs to status="error" (Lustria patreon event #38998: 21 image attaches + 1 OST zip = red). Same commit also reshuffles the showcase on every mount, not just when the store is empty.Test Plan
seen; should keep loading instead of showing "End."🤖 Generated with Claude Code