- Updated `useGameActions` to improve navigation handling during game play.
- Modified `RMenu` to allow modifier-clicks on links to open in new tabs without closing the menu.
- Added new stories and tests for `RMenuItem` to ensure correct behavior for new-tab gestures.
- Introduced `colorCoverArt` for procedural cover-art generation, ensuring consistent styling across missing and unmatched cover images.
- Implemented SVG generation for cover art in `covers.ts`, providing unique visuals for identified and unidentified ROMs.
- Enhanced `EmulatorJS` and `Ruffle` views to support dynamic cover art based on selected styles, improving user experience during gameplay.
- Refactored cover image handling to support animations and maintain aspect ratios.
Adopt master's ROM schema design (sibling_roms + files, batched
get_files_for_roms / get_siblings_for_roms) while preserving the v2-branch
features master lacks: per-user is_main_sibling on siblings and audio_meta
on rom files.
Conflict resolution:
- responses/rom.py: keep master's sibling_roms/files fields; re-graft
is_main_sibling via SiblingRomSchema.from_rom(rom, is_main_sibling=...);
restore the eager-relationship fallback in
SimpleRomSchema.from_orm_with_request (None sentinel) so the v2
/{id}/simple endpoint still returns siblings/files.
- roms_handler.py: get_siblings_for_roms now left-joins RomUser and returns
(Rom, is_main_sibling) tuples; keep both branch and master file helpers.
- drop the redundant branch-only sibling_ids field and
get_sibling_data_for_roms.
- generated types resolved to match (sibling_roms + files; RomFileSchema
keeps audio_meta and gains archive_members).
- update v2 components and the RelatedGameCard mock to read sibling_roms.
- fix stale exclude={"siblings"} -> "sibling_roms" in scan emit payloads.
- re-chain the audio_meta migration as 0083 (after master's 0082) to keep a
single Alembic head.
- package.json: union of branch tooling + master dependency bumps; lock
regenerated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- genesis_plus_gx_wide added alongside genesis_plus_gx for all Sega
MD/MS/GG/CD platforms
- bsnes added alongside snes9x for SNES platforms
- freeintv added for Intellivision
- azahar added for Nintendo 3DS (3ds, new-nintendo-3ds) and marked as
requiring threads
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Updated CreateSmartCollectionDialog to include current collection and virtual collection IDs for better context.
- Enhanced RefreshMetadataDialog with new hash matcher options and improved UI for metadata sources selection.
- Improved SearchCoverDialog to conditionally display provider covers based on selected cover type.
- Added collection and virtual collection lookups in CollectionSettingsDrawer for better filter summaries.
- Updated MatchRom components to handle cases where matches may not have covers, improving user feedback.
- Enhanced smart collection criteria handling in utils to support additional context and summary lookups.
The gallery list endpoint was eager-loading every rom_file row for each
paginated ROM via selectinload, then re-joining each row back to its
parent rom for the is_top_level computation. For platforms with extracted
multi-file ROMs (Xbox 360 ~1394 files/ROM, Switch ~199 files/ROM), this
made /api/roms time out at 120s even with a rom_id index.
Cards never displayed individual files — only the has_simple_single_file
/ has_nested_single_file / has_multiple_files booleans that derive from
the file list. Denormalize the underlying state onto roms as multi_file
(folder-based vs single-file) and top_level_file_count, recompute the
booleans from those columns, drop the selectinload from filter_roms, and
move the files field from SimpleRomSchema to DetailedRomSchema so the
gallery payload no longer ships file rows.
Also drop the redundant joinedload(RomFile.rom) and switch the relation
to lazy="select" so subsequent file.rom accesses resolve from the
session identity map instead of re-JOINing the parent rom per file row.
ShowQRCode.vue's folder-based DS/3DS fallback now fetches the detailed
rom on demand, since SimpleRom no longer carries files.
This list was created based on latest DAT files from No-Intro and
Redump.org.
With all those extracted files in a folder, this command retrieved
language codes from filenames (only considering games with at least two
languages, to avoid false positives):
```shell
rg -N "^.*game name=\"(.*?)\".*" -r '$1' | \
rg -N "^.* \(([A-Z][a-z](,[A-Z][a-z])+)\).*" -r '$1' | \
rg -N -o "[A-Z][a-z]" | \
sort | \
uniq -c
```
Reload page before and after using EmulatorJS to ensure proper COEP/COOP
headers are applied. This is needed to enable multi-threading in
EmulatorJS, by allowing it to use `SharedArrayBuffer`.
The Play button logic was duplicated in three different places,
including when to run either EmulatorJS or Ruffle.
This change centralizes that logic in a new `PlayBtn` component, which
internally decides which player to use, and binds to any arguments
passed to it.
Now all three places also consider platform versions when checking
for emulation support.