When a ROM is rescanned and its file IDs change, disc IDs stored in
localStorage become stale. This caused file_ids query params with invalid
IDs to be sent to /api/roms/{id}/content/{name}, resulting in 404 errors.
Validate the stored disc ID against the actual ROM files before use. If
stale, clear localStorage and fall back to the first available file.
Agent-Logs-Url: https://github.com/rommapp/romm/sessions/3579d577-13ff-4288-9a9c-909b6f891c9e
Co-authored-by: gantoine <3247106+gantoine@users.noreply.github.com>
Covers now use object-fit: contain inside a fixed slot, so each image
keeps its own aspect ratio (letterboxed where needed) instead of being
cropped to the platform's configured ratio. The slot itself still uses
a single default aspect ratio for grid stability, so cards don't reflow
as images load.
With per-platform aspect ratio no longer doing anything visible, remove
the Cover style picker from the platform info drawer and clean up dead
plumbing: galleryViewStore.getAspectRatio no longer reads
platform.aspect_ratio, platformId is dropped from Skeleton / SearchCover
/ MatchRom / showSearchCoverDialog, and the orphaned i18n keys
(cover-style, settings, old-squared-cases, old-horizontal-cases) are
stripped from all platform.json locale files.
Backend aspect_ratio column is left in place; no client sends it anymore.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The animated SVG background causes lag on Firefox. Swap in the static
variant via @-moz-document url-prefix() so other engines keep the
animation.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Use CollectionSchema instead of ReturnType<typeof collectionsStore.getCollection>
in AddRoms.vue and RemoveRoms.vue (simpler, per gantoine review)
- Wrap bulk INSERT in a savepoint so a concurrent duplicate-key violation
is caught via IntegrityError and ignored rather than aborting the transaction
- Only bump Collection.updated_at in remove_roms_from_collection when rows
were actually deleted (rowcount > 0), matching add_roms_to_collection behavior
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace full rom_ids list replacement with atomic POST/DELETE endpoints
that add or remove individual ROMs from a collection. This prevents
concurrent rapid clicks from overwriting each other (last-write-wins).
Also fix missing session.flush() in add_rom_user() and add collection
endpoint tests.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds the libretro thumbnail repository as a first-class artwork source so
region-correct box art (PAL/Europe, Japan, etc.) can be matched directly
to ROM filenames, addressing rommapp/romm#3239.
Implementation follows the SGDB handler pattern (artwork-only, no game
metadata): MetadataSource enum entry, scan-time fetch wired into the
SCAN_ARTWORK_PRIORITY loop, /search/roms integration, MatchRom dialog
chip + cover selection, and a heartbeat flag.
Matching is exact case-insensitive against the directory listing first
(so a ROM named "(Europe)" lands on the (Europe) artwork), with a
JaroWinkler fuzzy fallback at 0.8 that strips parenthetical tags from
both sides. Listings are cached in Redis with a 24h TTL.
`libretro_id` is persisted on the Rom model as the SHA1 hex of the
matched libretro filename — stable across scans, distinct per region,
indexed for lookup. Migration 0077 adds the column.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>