Skip to content

Add additional cover styles for boxart to prevent cropping#3060

Merged
gantoine merged 4 commits intorommapp:masterfrom
Drarox:master
Mar 8, 2026
Merged

Add additional cover styles for boxart to prevent cropping#3060
gantoine merged 4 commits intorommapp:masterfrom
Drarox:master

Conversation

@Drarox
Copy link
Contributor

@Drarox Drarox commented Mar 2, 2026

Description

This PR adds new Cover style aspect ratio presets so box covers are displayed with the correct proportions instead of being cropped in the gallery.

Added presets:

  • DVD Covers (e.g. PS2, GamCube, Wii Games)
  • Blu-ray (Full artwork) (e.g. PS4 Games)
  • Blu-ray (Plastic header) (e.g. PS3 Games)
  • Nintendo DS / 3DS
  • PSP

It also updates aspect-ratio parsing to support decimal ratios, so these formats are properly saved and rendered.

Why

ScreenScraper commonly returns box cover artwork by default.
Without matching box-art ratios, these covers were being cropped when shown in the UI.
With these new presets (and decimal-ratio support), box covers now display correctly.

Fix

Partially fixes #2795 by adding support for some common boxart formats so they don't get cropped.

Checklist

  • I've tested the changes locally
  • I've updated relevant comments
  • I've assigned reviewers for this PR
  • I've added unit tests that cover the changes

Screenshots

Before:
image (74)
After:
image (73)
New Styles:
image (75)

@greptile-apps
Copy link

greptile-apps bot commented Mar 2, 2026

Greptile Summary

This PR adds platform-specific aspect ratio presets (DVD, Blu-ray, Nintendo DS/3DS, PSP) to the cover style picker and fixes decimal ratio parsing in the gallery store, improving how box art covers are displayed without cropping for platforms like PS2, GameCube, PS3/PS4, and handhelds.

  • galleryView.ts: Correctly changes parseIntparseFloat so decimal strings like "0.71 / 1" parse to 0.71 instead of 0, enabling the new presets to render accurately.
  • PlatformInfoDrawer.vue: aspectRatioOptions is now a computed that conditionally appends platform-specific entries based on the current platform slug — slugs are consistent with those used elsewhere in the codebase (e.g. "ps2", "ngc", "ps3", "psp").
  • Logic bug: The selectedAspectRatio ref stores a numeric index into aspectRatioOptions. Because this list is now dynamic, switching from a platform with more options (e.g. PS2 → 5 items) to one with fewer (4 items) can leave the index out-of-range. When the new platform has no saved aspect_ratio, the watcher's if (aspectRatio) guard prevents resetting the index. Vuetify's mandatory constraint on v-item-group may then auto-select index 0 and fire setAspectRatio, silently overwriting the new platform's aspect ratio with "2 / 3" without user interaction.

Confidence Score: 2/5

  • Not safe to merge — navigating away from a platform-specific preset can silently corrupt another platform's saved aspect ratio.
  • The parseFloat fix and the new preset options are correct, but the dynamic options list introduces a stale-index bug: when moving from a platform with extended options (e.g. PS2) to one without, the mandatory v-item-group can auto-select index 0 and trigger an unintended API write that overwrites the target platform's aspect ratio with the default value.
  • frontend/src/components/Gallery/AppBar/Platform/PlatformInfoDrawer.vue — specifically the watch on aspect_ratio and its interaction with the mandatory v-item-group when options change.

Important Files Changed

Filename Overview
frontend/src/components/Gallery/AppBar/Platform/PlatformInfoDrawer.vue Adds platform-specific aspect ratio presets via dynamic computed options. Contains a logic bug where a stale selectedAspectRatio index can cause Vuetify's mandatory v-item-group to silently overwrite a platform's aspect ratio when navigating between platforms with different option counts.
frontend/src/stores/galleryView.ts Replaces parseInt with parseFloat for aspect ratio parsing — a correct fix that enables decimal values like "0.71 / 1" to parse properly instead of truncating to 0.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User navigates to platform] --> B{currentPlatform slug\nin special set?}
    B -- Yes --> C[aspectRatioOptions: 4 base + N extras]
    B -- No --> D[aspectRatioOptions: 4 base options only]

    C --> E{platform.aspect_ratio set?}
    D --> E

    E -- Yes --> F[watcher: findIndex in options]
    F --> G{match found?}
    G -- Yes --> H[selectedAspectRatio = matched index]
    G -- No --> I[selectedAspectRatio unchanged ⚠️]
    E -- No --> I

    I --> J{selectedAspectRatio\nout of range for new list?}
    J -- Yes --> K["Vuetify mandatory auto-selects index 0\nemits update:model-value"]
    K --> L["setAspectRatio() called\n→ API write: aspect_ratio = '2 / 3' ⚠️"]
    J -- No --> M[UI shows correct selection]
    H --> M
Loading

Comments Outside Diff (1)

  1. frontend/src/components/Gallery/AppBar/Platform/PlatformInfoDrawer.vue, line 226-241 (link)

    Stale selectedAspectRatio index can corrupt aspect ratio on platform switch

    Because aspectRatioOptions is now a dynamic computed (varying by platform slug), selectedAspectRatio — which holds a numeric index into that list — can become out-of-range when navigating from a platform with a longer options list (e.g. PS2 with 5 options, index 4 = DVD) to a platform that only has the base 4 options.

    The watcher only resets selectedAspectRatio when the new platform already has a non-empty aspect_ratio that matches one of its options. If the new platform has aspect_ratio = null (the common case for a freshly visited platform), the if (aspectRatio) guard prevents any update, so selectedAspectRatio stays at its previous stale value (e.g. 4).

    With Vuetify's mandatory prop on v-item-group, having no child v-item mapped to that index means Vuetify may auto-select index 0 and emit update:model-value, which triggers setAspectRatio. That call reads:

    const selectedOption = aspectRatioOptions.value[selectedAspectRatio.value]; // index 0 → "2 / 3"

    …and silently overwrites the new platform's aspect ratio with "2 / 3" without any user interaction.

    The fix is to reset selectedAspectRatio whenever the platform itself changes (not just when aspect_ratio changes). One approach:

    watch(
      () => currentPlatform.value?.aspect_ratio,
      (aspectRatio) => {
        if (aspectRatio) {
          const defaultAspectRatio = aspectRatioOptions.value.findIndex(
            (option) => option.name == aspectRatio,
          );
          selectedAspectRatio.value = defaultAspectRatio !== -1 ? defaultAspectRatio : 0;
        } else {
          selectedAspectRatio.value = 0; // reset to default when no ratio is saved
        }
      },
      { immediate: true },
    );

    This ensures selectedAspectRatio is always a valid index for the current platform's options list, preventing any unintended mandatory auto-selection from corrupting data.

Last reviewed commit: 6b33b58

@gantoine gantoine requested a review from zurdi15 March 2, 2026 19:22
@gantoine gantoine merged commit f25412a into rommapp:master Mar 8, 2026
3 checks passed
@Drarox Drarox mentioned this pull request Mar 9, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[UI/UX] Fix Boxart Cropping

3 participants