mirror of
https://github.com/rommapp/romm.git
synced 2026-02-18 00:27:41 +01:00
first cleanup batch
This commit is contained in:
@@ -29,7 +29,6 @@
|
||||
"ms-python.python",
|
||||
"ms-python.pylint",
|
||||
"ms-python.black-formatter",
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"vue.volar",
|
||||
"ms-vscode.vscode-typescript-next"
|
||||
],
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ROUTES } from "@/plugins/router";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
block?: boolean;
|
||||
@@ -13,7 +16,22 @@ withDefaults(
|
||||
withTag: false,
|
||||
},
|
||||
);
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
function enterConsoleMode() {
|
||||
// Navigate first so route guards run promptly
|
||||
router.push({ name: ROUTES.CONSOLE_HOME });
|
||||
if (!document.fullscreenElement) {
|
||||
// Attempt fullscreen after a small delay to allow navigation transition
|
||||
setTimeout(() => {
|
||||
document.documentElement.requestFullscreen?.().catch(() => {});
|
||||
}, 50);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-btn
|
||||
icon
|
||||
@@ -26,14 +44,14 @@ withDefaults(
|
||||
@click="enterConsoleMode"
|
||||
>
|
||||
<div class="d-flex flex-column align-center">
|
||||
<v-icon :color="$route.path.startsWith('/console') ? 'primary' : ''">
|
||||
<v-icon :color="route.path.startsWith('/console') ? 'primary' : ''">
|
||||
mdi-television-play
|
||||
</v-icon>
|
||||
<v-expand-transition>
|
||||
<span
|
||||
v-if="withTag"
|
||||
class="text-caption text-center"
|
||||
:class="{ 'text-primary': $route.path.startsWith('/console') }"
|
||||
:class="{ 'text-primary': route.path.startsWith('/console') }"
|
||||
>
|
||||
Play
|
||||
</span>
|
||||
@@ -41,29 +59,3 @@ withDefaults(
|
||||
</div>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
methods: {
|
||||
async enterConsoleMode() {
|
||||
try {
|
||||
// navigate first so route guards run promptly
|
||||
this.$router.push({ name: "console-home" });
|
||||
const docEl = document.documentElement as HTMLElement & {
|
||||
requestFullscreen?: () => Promise<void>;
|
||||
};
|
||||
if (!document.fullscreenElement && docEl.requestFullscreen) {
|
||||
// Attempt fullscreen after a small delay to allow navigation transition
|
||||
setTimeout(() => {
|
||||
docEl.requestFullscreen?.().catch(() => {
|
||||
/* ignore */
|
||||
});
|
||||
}, 50);
|
||||
}
|
||||
} catch {
|
||||
/* swallow */
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const props = defineProps<{
|
||||
text?: string;
|
||||
onBack?: () => void;
|
||||
}>();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
function goBack() {
|
||||
props.onBack?.() ?? router.back();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="absolute top-4 left-4 z-30 inline-flex items-center pointer-events-none"
|
||||
@@ -12,27 +27,8 @@
|
||||
<span
|
||||
v-if="text"
|
||||
class="ml-3 text-white/90 text-3xl font-bold drop-shadow select-none"
|
||||
>{{ text }}</span
|
||||
>
|
||||
{{ text }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { toRefs } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const props = defineProps<{
|
||||
text?: string;
|
||||
onBack?: () => void;
|
||||
}>();
|
||||
const { text, onBack } = toRefs(props);
|
||||
|
||||
const router = useRouter();
|
||||
function goBack() {
|
||||
if (onBack?.value) {
|
||||
onBack.value();
|
||||
} else {
|
||||
router.back();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,3 +1,64 @@
|
||||
<script setup lang="ts">
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { computed, onMounted, ref, watchEffect } from "vue";
|
||||
import type { CollectionSchema } from "@/__generated__/models/CollectionSchema";
|
||||
import { getFavoriteCoverImage } from "@/utils/covers";
|
||||
|
||||
const props = defineProps<{
|
||||
collection: CollectionSchema;
|
||||
index: number;
|
||||
selected?: boolean;
|
||||
loaded?: boolean;
|
||||
}>();
|
||||
const emit = defineEmits(["click", "mouseenter", "focus", "loaded"]);
|
||||
const el = ref<HTMLElement>();
|
||||
|
||||
const isFavorite = computed(() => props.collection.is_favorite);
|
||||
const coverSrc = computed(
|
||||
() =>
|
||||
props.collection.path_cover_large ||
|
||||
props.collection.path_cover_small ||
|
||||
props.collection.url_cover ||
|
||||
"",
|
||||
);
|
||||
|
||||
// Composite favourite logic (two diagonally split images)
|
||||
const firstCover = ref("");
|
||||
const secondCover = ref("");
|
||||
const compositeReady = ref(false);
|
||||
|
||||
watchEffect(() => {
|
||||
if (!isFavorite.value) {
|
||||
compositeReady.value = false;
|
||||
return;
|
||||
}
|
||||
const large = props.collection.path_covers_large || [];
|
||||
const small = props.collection.path_covers_small || [];
|
||||
// Choose source list preferring large
|
||||
const source = large.length ? large : small;
|
||||
if (source.length >= 2) {
|
||||
const shuffled = [...source].sort(() => Math.random() - 0.5);
|
||||
firstCover.value = shuffled[0];
|
||||
secondCover.value = shuffled[1];
|
||||
} else if (source.length === 1) {
|
||||
firstCover.value = source[0];
|
||||
secondCover.value = getFavoriteCoverImage(props.collection.name);
|
||||
} else {
|
||||
const gen = getFavoriteCoverImage(props.collection.name);
|
||||
firstCover.value = gen;
|
||||
secondCover.value = gen;
|
||||
}
|
||||
compositeReady.value = true;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
if (!el.value) return;
|
||||
(window as any).collectionCardElements =
|
||||
(window as any).collectionCardElements || [];
|
||||
(window as any).collectionCardElements[props.index] = el.value;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col items-center w-[250px] shrink-0">
|
||||
<button
|
||||
@@ -84,67 +145,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { computed, onMounted, ref, watchEffect } from "vue";
|
||||
import type { CollectionSchema } from "@/__generated__/models/CollectionSchema";
|
||||
import { getFavoriteCoverImage } from "@/utils/covers";
|
||||
|
||||
const props = defineProps<{
|
||||
collection: CollectionSchema;
|
||||
index: number;
|
||||
selected?: boolean;
|
||||
loaded?: boolean;
|
||||
}>();
|
||||
const emit = defineEmits(["click", "mouseenter", "focus", "loaded"]);
|
||||
const el = ref<HTMLElement>();
|
||||
|
||||
const isFavorite = computed(() => props.collection.is_favorite);
|
||||
const coverSrc = computed(
|
||||
() =>
|
||||
props.collection.path_cover_large ||
|
||||
props.collection.path_cover_small ||
|
||||
props.collection.url_cover ||
|
||||
"",
|
||||
);
|
||||
|
||||
// Composite favourite logic (two diagonally split images)
|
||||
const firstCover = ref("");
|
||||
const secondCover = ref("");
|
||||
const compositeReady = ref(false);
|
||||
|
||||
watchEffect(() => {
|
||||
if (!isFavorite.value) {
|
||||
compositeReady.value = false;
|
||||
return;
|
||||
}
|
||||
const large = props.collection.path_covers_large || [];
|
||||
const small = props.collection.path_covers_small || [];
|
||||
// Choose source list preferring large
|
||||
const source = large.length ? large : small;
|
||||
if (source.length >= 2) {
|
||||
const shuffled = [...source].sort(() => Math.random() - 0.5);
|
||||
firstCover.value = shuffled[0];
|
||||
secondCover.value = shuffled[1];
|
||||
} else if (source.length === 1) {
|
||||
firstCover.value = source[0];
|
||||
secondCover.value = getFavoriteCoverImage(props.collection.name);
|
||||
} else {
|
||||
const gen = getFavoriteCoverImage(props.collection.name);
|
||||
firstCover.value = gen;
|
||||
secondCover.value = gen;
|
||||
}
|
||||
compositeReady.value = true;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
if (!el.value) return;
|
||||
(window as any).collectionCardElements =
|
||||
(window as any).collectionCardElements || [];
|
||||
(window as any).collectionCardElements[props.index] = el.value;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
|
||||
@@ -34,6 +34,11 @@ export const ROUTES = {
|
||||
ADMINISTRATION: "administration",
|
||||
SERVER_STATS: "server-stats",
|
||||
NOT_FOUND: "404",
|
||||
CONSOLE_HOME: "console-home",
|
||||
CONSOLE_PLATFORM: "console-platform",
|
||||
CONSOLE_COLLECTION: "console-collection",
|
||||
CONSOLE_ROM: "console-rom",
|
||||
CONSOLE_PLAY: "console-play",
|
||||
} as const;
|
||||
|
||||
const routes = [
|
||||
@@ -231,27 +236,27 @@ const routes = [
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "console-home",
|
||||
name: ROUTES.CONSOLE_HOME,
|
||||
component: () => import("@/console/views/Home.vue"),
|
||||
},
|
||||
{
|
||||
path: "platform/:id",
|
||||
name: "console-platform",
|
||||
name: ROUTES.CONSOLE_PLATFORM,
|
||||
component: () => import("@/console/views/GamesList.vue"),
|
||||
},
|
||||
{
|
||||
path: "collection/:id",
|
||||
name: "console-collection",
|
||||
name: ROUTES.CONSOLE_COLLECTION,
|
||||
component: () => import("@/console/views/GamesList.vue"),
|
||||
},
|
||||
{
|
||||
path: "rom/:rom",
|
||||
name: "console-rom",
|
||||
name: ROUTES.CONSOLE_ROM,
|
||||
component: () => import("@/console/views/Game.vue"),
|
||||
},
|
||||
{
|
||||
path: "rom/:rom/play",
|
||||
name: "console-play",
|
||||
name: ROUTES.CONSOLE_PLAY,
|
||||
component: () => import("@/console/views/Play.vue"),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -11,7 +11,7 @@ import { storeToRefs } from "pinia";
|
||||
import { computed, ref, watch, type DefineComponent } from "vue";
|
||||
import { useDisplay } from "vuetify";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useAutoScroll } from "@/composables/use-auto-scroll";
|
||||
import { useAutoScroll } from "@/composables/useAutoScroll";
|
||||
|
||||
const LOCAL_STORAGE_METADATA_SOURCES_KEY = "scan.metadataSources";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user