mirror of
https://github.com/rommapp/romm.git
synced 2026-02-18 00:27:41 +01:00
Refactor save and state selection logic; improve empty cover image aspect ratio handling
This commit is contained in:
@@ -66,7 +66,7 @@ function onCardClick(save: SaveSchema, event: MouseEvent) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-row class="ma-2" no-gutters>
|
||||
<v-row class="my-2 mx-4" no-gutters>
|
||||
<v-col class="pa-1">
|
||||
<v-btn-group divided density="default">
|
||||
<v-btn
|
||||
@@ -107,7 +107,7 @@ function onCardClick(save: SaveSchema, event: MouseEvent) {
|
||||
</v-btn-group>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="rom.user_saves.length > 0" class="ma-2" no-gutters>
|
||||
<v-row v-if="rom.user_saves.length > 0" class="my-2 mx-4" no-gutters>
|
||||
<v-col
|
||||
v-for="save in rom.user_saves"
|
||||
:key="save.id"
|
||||
@@ -125,52 +125,35 @@ function onCardClick(save: SaveSchema, event: MouseEvent) {
|
||||
@click="(e: MouseEvent) => onCardClick(save, e)"
|
||||
>
|
||||
<v-card-text class="pa-2">
|
||||
<v-row no-gutters>
|
||||
<v-col cols="12">
|
||||
<v-img
|
||||
rounded
|
||||
:src="
|
||||
save.screenshot?.download_path ??
|
||||
getEmptyCoverImage(save.file_name)
|
||||
<v-slide-x-transition>
|
||||
<v-btn-group
|
||||
v-if="isHovering"
|
||||
class="position-absolute"
|
||||
density="compact"
|
||||
style="bottom: 4px; right: 4px"
|
||||
>
|
||||
<v-btn drawer :href="save.download_path" download size="small">
|
||||
<v-icon>mdi-download</v-icon>
|
||||
</v-btn>
|
||||
<v-btn
|
||||
v-if="scopes.includes('assets.write')"
|
||||
drawer
|
||||
size="small"
|
||||
@click="
|
||||
emitter?.emit('showDeleteSavesDialog', {
|
||||
rom: props.rom,
|
||||
saves: [save],
|
||||
})
|
||||
"
|
||||
>
|
||||
<v-slide-x-transition>
|
||||
<v-btn-group
|
||||
v-if="isHovering"
|
||||
class="position-absolute"
|
||||
density="compact"
|
||||
style="bottom: 4px; right: 4px"
|
||||
>
|
||||
<v-btn
|
||||
drawer
|
||||
:href="save.download_path"
|
||||
download
|
||||
size="small"
|
||||
>
|
||||
<v-icon>mdi-download</v-icon>
|
||||
</v-btn>
|
||||
<v-btn
|
||||
v-if="scopes.includes('assets.write')"
|
||||
drawer
|
||||
size="small"
|
||||
@click="
|
||||
emitter?.emit('showDeleteSavesDialog', {
|
||||
rom: props.rom,
|
||||
saves: [save],
|
||||
})
|
||||
"
|
||||
>
|
||||
<v-icon class="text-romm-red"> mdi-delete </v-icon>
|
||||
</v-btn>
|
||||
</v-btn-group>
|
||||
</v-slide-x-transition>
|
||||
</v-img>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row class="py-2 text-caption" no-gutters>
|
||||
<v-icon class="text-romm-red"> mdi-delete </v-icon>
|
||||
</v-btn>
|
||||
</v-btn-group>
|
||||
</v-slide-x-transition>
|
||||
<v-row class="pa-1 text-caption" no-gutters>
|
||||
{{ save.file_name }}
|
||||
</v-row>
|
||||
<v-row class="ga-1" no-gutters>
|
||||
<v-row class="ga-1 pa-1" no-gutters>
|
||||
<v-col v-if="save.emulator" cols="12">
|
||||
<v-chip size="x-small" color="orange" label>
|
||||
{{ save.emulator }}
|
||||
|
||||
@@ -68,7 +68,7 @@ function onCardClick(state: StateSchema, event: MouseEvent) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-row class="ma-2" no-gutters>
|
||||
<v-row class="my-2 mx-4" no-gutters>
|
||||
<v-col class="pa-1">
|
||||
<v-btn-group divided density="default">
|
||||
<v-btn
|
||||
@@ -109,7 +109,7 @@ function onCardClick(state: StateSchema, event: MouseEvent) {
|
||||
</v-btn-group>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="rom.user_states.length > 0" class="ma-2" no-gutters>
|
||||
<v-row v-if="rom.user_states.length > 0" class="my-2 mx-4" no-gutters>
|
||||
<v-col
|
||||
v-for="state in rom.user_states"
|
||||
:key="state.id"
|
||||
@@ -133,8 +133,9 @@ function onCardClick(state: StateSchema, event: MouseEvent) {
|
||||
rounded
|
||||
:src="
|
||||
state.screenshot?.download_path ??
|
||||
getEmptyCoverImage(state.file_name)
|
||||
getEmptyCoverImage(state.file_name, 16 / 9)
|
||||
"
|
||||
:aspect-ratio="16 / 9"
|
||||
>
|
||||
<v-slide-x-transition>
|
||||
<v-btn-group
|
||||
|
||||
@@ -67,11 +67,19 @@ export function getUnmatchedCoverImage(name: string): string {
|
||||
return strToObjUrl(svgString);
|
||||
}
|
||||
|
||||
export function getEmptyCoverImage(name: string): string {
|
||||
export function getEmptyCoverImage(
|
||||
name: string,
|
||||
aspectRatio: number = 2 / 3,
|
||||
): string {
|
||||
const tbgs = translatedBGs(name);
|
||||
const bgr = bgRotation(name);
|
||||
|
||||
const svgString = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 800"><g fill="none" mask="url(#a)"><path fill="#553E98" d="M0 0h600v800H0z"/><path fill="#371f69" d="M0 580c120 10 180-130 270-190s220-70 290-150c80-90 140-210 120-320S520-250 420-310C340 30 250 0 160-20S-10-50-90-20s-150 70-200 140-60 150-85 230c-30 100-130 200-90 290s190 70 270 130c45-340 85-200 195-190" style="transform-origin:center;transform:translate(${tbgs.left.x}px,${tbgs.left.y}px) rotate(${bgr}deg);"/><path fill="#FF9B85" d="M600 1060c100 30 230 40 310-40s30-210 70-310c35-90 130-150 140-240 10-100-10-220-90-290s-200-40-300-60c-90-20-180-60-270-30S310 200 240 260C170 330 50 380 40 480s110 160 170 240c50 70 90 130 150 180 70 60 140 140 230 160" style="transform-origin:center;transform:translate(${tbgs.right.x}px,${tbgs.right.y}px) rotate(${bgr}deg);"/></g><defs><mask id="a"><path fill="#fff" d="M0 0h600v800H0z"/></mask></defs></svg>`;
|
||||
const width = 600;
|
||||
const height = width / aspectRatio;
|
||||
const designHeight = 800; // Original design height
|
||||
const yOffset = (designHeight - height) / 2;
|
||||
|
||||
const svgString = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 ${yOffset} ${width} ${height}"><g fill="none" mask="url(#a)"><path fill="#553E98" d="M0 0h${width}v${designHeight}H0z"/><path fill="#371f69" d="M0 580c120 10 180-130 270-190s220-70 290-150c80-90 140-210 120-320S520-250 420-310C340 30 250 0 160-20S-10-50-90-20s-150 70-200 140-60 150-85 230c-30 100-130 200-90 290s190 70 270 130c45-340 85-200 195-190" style="transform-origin:center;transform:translate(${tbgs.left.x}px,${tbgs.left.y}px) rotate(${bgr}deg);"/><path fill="#FF9B85" d="M600 1060c100 30 230 40 310-40s30-210 70-310c35-90 130-150 140-240 10-100-10-220-90-290s-200-40-300-60c-90-20-180-60-270-30S310 200 240 260C170 330 50 380 40 480s110 160 170 240c50 70 90 130 150 180 70 60 140 140 230 160" style="transform-origin:center;transform:translate(${tbgs.right.x}px,${tbgs.right.y}px) rotate(${bgr}deg);"/></g><defs><mask id="a"><path fill="#fff" d="M0 0h${width}v${designHeight}H0z"/></mask></defs></svg>`;
|
||||
|
||||
return strToObjUrl(svgString);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user