Skip to content

Commit 9d1183b

Browse files
authored
Merge pull request #2785 from rommapp/feat/emujs-ui-revamped
feat: Emujs UI revamped
2 parents be3615b + 8a686be commit 9d1183b

File tree

11 files changed

+709
-770
lines changed

11 files changed

+709
-770
lines changed

frontend/src/components/Details/Info/GameInfo.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,10 @@ function onFilterClick(filter: FilterType, value: string) {
246246
</v-row>
247247
</template>
248248
<v-row v-if="rom.is_identified">
249-
<v-col class="mt-4 text-right">
250-
<div v-if="dataSources.length > 0" class="text-grey">
249+
<v-col
250+
class="mt-4 text-right text-medium-emphasis text-caption font-italic"
251+
>
252+
<div v-if="dataSources.length > 0">
251253
Data provided by
252254
<template v-for="(source, index) in dataSources" :key="source.name">
253255
<a
@@ -263,7 +265,7 @@ function onFilterClick(filter: FilterType, value: string) {
263265
</span> </template
264266
>.
265267
</div>
266-
<div v-if="rom.url_cover && coverImageSource" class="text-grey mt-1">
268+
<div v-if="rom.url_cover && coverImageSource" class="mt-1">
267269
Cover art provided by
268270
<a :href="rom.url_cover" target="_blank" style="color: inherit">
269271
{{ coverImageSource }}</a

frontend/src/components/Details/Saves.vue

Lines changed: 10 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22
import type { Emitter } from "mitt";
33
import { storeToRefs } from "pinia";
44
import { inject, ref } from "vue";
5-
import { useI18n } from "vue-i18n";
65
import type { SaveSchema } from "@/__generated__";
76
import EmptySaves from "@/components/common/EmptyStates/EmptySaves.vue";
7+
import AssetCard from "@/components/common/Game/AssetCard.vue";
88
import storeAuth from "@/stores/auth";
99
import { type DetailedRom } from "@/stores/roms";
1010
import type { Events } from "@/types/emitter";
11-
import { formatBytes, formatTimestamp, formatRelativeDate } from "@/utils";
1211
13-
const { t, locale } = useI18n();
1412
const auth = storeAuth();
1513
const { scopes } = storeToRefs(auth);
1614
const props = defineProps<{ rom: DetailedRom }>();
@@ -112,70 +110,16 @@ function onCardClick(save: SaveSchema, event: MouseEvent) {
112110
:key="save.id"
113111
cols="6"
114112
sm="4"
115-
class="pa-1"
113+
class="pa-1 align-self-end"
116114
>
117-
<v-hover v-slot="{ isHovering, props: saveProps }">
118-
<v-card
119-
v-bind="saveProps"
120-
class="bg-toplayer transform-scale"
121-
:class="{
122-
'border-selected': selectedSaves.some((s) => s.id === save.id),
123-
}"
124-
@click="(e: MouseEvent) => onCardClick(save, e)"
125-
>
126-
<v-card-text class="pa-2">
127-
<v-slide-x-transition>
128-
<v-btn-group
129-
v-if="isHovering"
130-
class="position-absolute"
131-
density="compact"
132-
style="bottom: 4px; right: 4px"
133-
>
134-
<v-btn drawer :href="save.download_path" download size="small">
135-
<v-icon>mdi-download</v-icon>
136-
</v-btn>
137-
<v-btn
138-
v-if="scopes.includes('assets.write')"
139-
drawer
140-
size="small"
141-
@click="
142-
emitter?.emit('showDeleteSavesDialog', {
143-
rom: props.rom,
144-
saves: [save],
145-
})
146-
"
147-
>
148-
<v-icon class="text-romm-red"> mdi-delete </v-icon>
149-
</v-btn>
150-
</v-btn-group>
151-
</v-slide-x-transition>
152-
<v-row class="pa-1 text-caption" no-gutters>
153-
{{ save.file_name }}
154-
</v-row>
155-
<v-row class="ga-1 pa-1" no-gutters>
156-
<v-col v-if="save.emulator" cols="12">
157-
<v-chip size="x-small" color="orange" label>
158-
{{ save.emulator }}
159-
</v-chip>
160-
</v-col>
161-
<v-col cols="12">
162-
<v-chip size="x-small" label>
163-
{{ formatBytes(save.file_size_bytes) }}
164-
</v-chip>
165-
</v-col>
166-
<v-col cols="12">
167-
<div class="mt-1">
168-
{{ t("rom.updated") }}:
169-
{{ formatTimestamp(save.updated_at, locale) }}
170-
<span class="ml-1 text-grey text-caption"
171-
>({{ formatRelativeDate(save.updated_at) }})</span
172-
>
173-
</div>
174-
</v-col>
175-
</v-row>
176-
</v-card-text>
177-
</v-card>
178-
</v-hover>
115+
<AssetCard
116+
:asset="save"
117+
type="save"
118+
:selected="selectedSaves.some((s) => s.id === save.id)"
119+
:rom="props.rom"
120+
:scopes="scopes"
121+
@click="(e: MouseEvent) => onCardClick(save, e)"
122+
/>
179123
</v-col>
180124
</v-row>
181125
<EmptySaves v-else />

frontend/src/components/Details/States.vue

Lines changed: 10 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,13 @@
22
import type { Emitter } from "mitt";
33
import { storeToRefs } from "pinia";
44
import { inject, ref } from "vue";
5-
import { useI18n } from "vue-i18n";
65
import type { StateSchema } from "@/__generated__";
76
import EmptySates from "@/components/common/EmptyStates/EmptyStates.vue";
7+
import AssetCard from "@/components/common/Game/AssetCard.vue";
88
import storeAuth from "@/stores/auth";
99
import { type DetailedRom } from "@/stores/roms";
1010
import type { Events } from "@/types/emitter";
11-
import { formatBytes, formatTimestamp, formatRelativeDate } from "@/utils";
12-
import { getEmptyCoverImage } from "@/utils/covers";
1311
14-
const { t, locale } = useI18n();
1512
const auth = storeAuth();
1613
const { scopes } = storeToRefs(auth);
1714
const props = defineProps<{ rom: DetailedRom }>();
@@ -115,88 +112,16 @@ function onCardClick(state: StateSchema, event: MouseEvent) {
115112
:key="state.id"
116113
cols="6"
117114
sm="4"
118-
class="pa-1"
115+
class="pa-1 align-self-end"
119116
>
120-
<v-hover v-slot="{ isHovering, props: stateProps }">
121-
<v-card
122-
v-bind="stateProps"
123-
class="bg-toplayer transform-scale"
124-
:class="{
125-
'border-selected': selectedStates.some((s) => s.id === state.id),
126-
}"
127-
@click="(e: MouseEvent) => onCardClick(state, e)"
128-
>
129-
<v-card-text class="pa-2">
130-
<v-row no-gutters>
131-
<v-col cols="12">
132-
<v-img
133-
rounded
134-
:src="
135-
state.screenshot?.download_path ??
136-
getEmptyCoverImage(state.file_name, 16 / 9)
137-
"
138-
:aspect-ratio="16 / 9"
139-
>
140-
<v-slide-x-transition>
141-
<v-btn-group
142-
v-if="isHovering"
143-
class="position-absolute"
144-
density="compact"
145-
style="bottom: 4px; right: 4px"
146-
>
147-
<v-btn
148-
drawer
149-
:href="state.download_path"
150-
download
151-
size="small"
152-
>
153-
<v-icon>mdi-download</v-icon>
154-
</v-btn>
155-
<v-btn
156-
v-if="scopes.includes('assets.write')"
157-
drawer
158-
size="small"
159-
@click="
160-
emitter?.emit('showDeleteStatesDialog', {
161-
rom: props.rom,
162-
states: [state],
163-
})
164-
"
165-
>
166-
<v-icon class="text-romm-red"> mdi-delete </v-icon>
167-
</v-btn>
168-
</v-btn-group>
169-
</v-slide-x-transition>
170-
</v-img>
171-
</v-col>
172-
</v-row>
173-
<v-row class="py-2 text-caption" no-gutters>
174-
{{ state.file_name }}
175-
</v-row>
176-
<v-row class="ga-1" no-gutters>
177-
<v-col v-if="state.emulator" cols="12">
178-
<v-chip size="x-small" color="orange" label>
179-
{{ state.emulator }}
180-
</v-chip>
181-
</v-col>
182-
<v-col cols="12">
183-
<v-chip size="x-small" label>
184-
{{ formatBytes(state.file_size_bytes) }}
185-
</v-chip>
186-
</v-col>
187-
<v-col cols="12">
188-
<div class="mt-1">
189-
{{ t("rom.updated") }}:
190-
{{ formatTimestamp(state.updated_at, locale) }}
191-
<span class="ml-1 text-grey text-caption"
192-
>({{ formatRelativeDate(state.updated_at) }})</span
193-
>
194-
</div>
195-
</v-col>
196-
</v-row>
197-
</v-card-text>
198-
</v-card>
199-
</v-hover>
117+
<AssetCard
118+
:asset="state"
119+
type="state"
120+
:selected="selectedStates.some((s) => s.id === state.id)"
121+
:rom="props.rom"
122+
:scopes="scopes"
123+
@click="(e: MouseEvent) => onCardClick(state, e)"
124+
/>
200125
</v-col>
201126
</v-row>
202127
<EmptySates v-else />

0 commit comments

Comments
 (0)