Merge branch 'master' into universal-slugs

This commit is contained in:
Georges-Antoine Assi
2025-08-01 21:51:40 -04:00
34 changed files with 616 additions and 51 deletions

View File

@@ -60,6 +60,7 @@ EJS_SUPPORTED_PLATFORMS = [
UPS.GB,
UPS.GBA,
UPS.PC_FX,
UPS.PHILIPS_CD_I,
UPS.PSX,
UPS.PSP,
UPS.SEGACD,

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 500 117.57"><path d="M8.41 113.35V5.36h85.76q6.15 0 11.19 3c3.35 2 6.06 4.71 8.11 8.11s3.08 7.11 3.08 11.11v27.94c0 4.01-1.03 7.71-3.08 11.11s-4.76 6.11-8.11 8.11c-3.36 2-7.08 3-11.19 3l-62.48.15v35.45H8.41Zm84.56-59.03V28.64H31.69v25.68zm-.6 59.03-31.39-37.4h30.49l24.93 29.44v7.96zm52.87 0c-4.01 0-7.71-1-11.11-3-3.41-2-6.11-4.71-8.11-8.11s-3-7.11-3-11.12V27.44q0-6.15 3-11.19c2-3.35 4.71-6.03 8.11-8.04 3.4-2 7.11-3 11.11-3h63.68q6 0 11.04 3c3.35 2 6.06 4.68 8.11 8.04s3.08 7.08 3.08 11.19v63.68c0 4.01-1.03 7.71-3.08 11.12s-4.76 6.11-8.11 8.11q-5.04 3-11.04 3zm62.33-23.43V28.64h-61.28v61.28zm31.09 23.43V5.21h24.03l36.65 43.71 36.5-43.71h24.18v108.14h-23.43V40.81l-37.25 44.46-37.4-44.31v72.39zm130.37 0V5.21h24.03l36.65 43.71 36.5-43.71h24.18v108.14h-23.43V40.81l-37.25 44.46-37.4-44.31v72.39z" style="fill:#553e98"/></svg>

After

Width:  |  Height:  |  Size: 902 B

View File

@@ -27,7 +27,7 @@
"vue-i18n": "^11.1.10",
"vue-router": "^4.3.2",
"vue3-pdf-app": "^1.0.3",
"vuetify": "^3.7.18"
"vuetify": "^3.9.2"
},
"devDependencies": {
"@eslint/js": "^9.21.0",
@@ -8373,9 +8373,9 @@
}
},
"node_modules/vuetify": {
"version": "3.7.18",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.7.18.tgz",
"integrity": "sha512-JDkPIaug4hP9c+K/wxSgmTiLTMjBTYv2ATPvudhkRKuhsoym89aWCXb1CVbs7FRYuRsJEOGojpwpL5rBfDDy9g==",
"version": "3.9.2",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.9.2.tgz",
"integrity": "sha512-Pax7YCgbE5SArY8CDM0A9dTVHnG1oU79eIBA+FEEg3dDFV7bc+0AppJJLfG2+aoaBlJf2UH7tOCflJ/U23YU1Q==",
"license": "MIT",
"engines": {
"node": "^12.20 || >=14.13"
@@ -8386,9 +8386,9 @@
},
"peerDependencies": {
"typescript": ">=4.7",
"vite-plugin-vuetify": ">=1.0.0",
"vue": "^3.3.0",
"webpack-plugin-vuetify": ">=2.0.0"
"vite-plugin-vuetify": ">=2.1.0",
"vue": "^3.5.0",
"webpack-plugin-vuetify": ">=3.1.0"
},
"peerDependenciesMeta": {
"typescript": {

View File

@@ -45,7 +45,7 @@
"vue-i18n": "^11.1.10",
"vue-router": "^4.3.2",
"vue3-pdf-app": "^1.0.3",
"vuetify": "^3.7.18"
"vuetify": "^3.9.2"
},
"devDependencies": {
"@eslint/js": "^9.21.0",

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import RSection from "@/components/common/RSection.vue";
import CreateExclusionDialog from "@/components/Settings/LibraryManagement/Dialog/CreateExclusion.vue";
import ExcludedCard from "@/components/Settings/LibraryManagement/ExcludedCard.vue";
import CreateExclusionDialog from "@/components/Settings/LibraryManagement/Config/Dialog/CreateExclusion.vue";
import ExcludedCard from "@/components/Settings/LibraryManagement/Config/ExcludedCard.vue";
import storeAuth from "@/stores/auth";
import storeConfig from "@/stores/config";
import { ref } from "vue";
@@ -52,11 +52,7 @@ const exclusions = [
const editable = ref(false);
</script>
<template>
<r-section
icon="mdi-cancel"
:title="t('settings.excluded')"
class="mx-2 mt-4 mb-2"
>
<r-section icon="mdi-cancel" :title="t('settings.excluded')">
<template #toolbar-append>
<v-btn
v-if="authStore.scopes.includes('platforms.write')"
@@ -78,8 +74,7 @@ const editable = ref(false);
:icon="exclusion.icon"
:editable="editable && authStore.scopes.includes('platforms.write')"
/>
<create-exclusion-dialog />
</template>
</r-section>
<create-exclusion-dialog />
</template>

View File

@@ -1,8 +1,8 @@
<script setup lang="ts">
import AddBtn from "@/components/Settings/LibraryManagement/AddBtn.vue";
import CreatePlatformBindingDialog from "@/components/Settings/LibraryManagement/Dialog/CreatePlatformBinding.vue";
import DeletePlatformBindingDialog from "@/components/Settings/LibraryManagement/Dialog/DeletePlatformBinding.vue";
import PlatformBindCard from "@/components/Settings/LibraryManagement/PlatformBindCard.vue";
import AddBtn from "@/components/Settings/LibraryManagement/Config/AddBtn.vue";
import CreatePlatformBindingDialog from "@/components/Settings/LibraryManagement/Config/Dialog/CreatePlatformBinding.vue";
import DeletePlatformBindingDialog from "@/components/Settings/LibraryManagement/Config/Dialog/DeletePlatformBinding.vue";
import PlatformBindCard from "@/components/Settings/LibraryManagement/Config/PlatformBindCard.vue";
import RSection from "@/components/common/RSection.vue";
import storeAuth from "@/stores/auth";
import storeConfig from "@/stores/config";
@@ -22,11 +22,7 @@ const editable = ref(false);
</script>
<template>
<r-section
icon="mdi-controller"
:title="t('settings.platforms-bindings')"
class="ma-2"
>
<r-section icon="mdi-controller" :title="t('settings.platforms-bindings')">
<template #toolbar-title-append>
<v-tooltip bottom max-width="400">
<template #activator="{ props }">
@@ -97,9 +93,8 @@ const editable = ref(false);
/>
</v-col>
</v-row>
<create-platform-binding-dialog />
<delete-platform-binding-dialog />
</template>
</r-section>
<create-platform-binding-dialog />
<delete-platform-binding-dialog />
</template>

View File

@@ -1,8 +1,8 @@
<script setup lang="ts">
import AddBtn from "@/components/Settings/LibraryManagement/AddBtn.vue";
import CreatePlatformVersionDialog from "@/components/Settings/LibraryManagement/Dialog/CreatePlatformVersion.vue";
import DeletePlatformVersionDialog from "@/components/Settings/LibraryManagement/Dialog/DeletePlatformVersion.vue";
import PlatformBindCard from "@/components/Settings/LibraryManagement/PlatformBindCard.vue";
import AddBtn from "@/components/Settings/LibraryManagement/Config/AddBtn.vue";
import CreatePlatformVersionDialog from "@/components/Settings/LibraryManagement/Config/Dialog/CreatePlatformVersion.vue";
import DeletePlatformVersionDialog from "@/components/Settings/LibraryManagement/Config/Dialog/DeletePlatformVersion.vue";
import PlatformBindCard from "@/components/Settings/LibraryManagement/Config/PlatformBindCard.vue";
import RSection from "@/components/common/RSection.vue";
import storeAuth from "@/stores/auth";
import storeConfig from "@/stores/config";
@@ -25,7 +25,6 @@ const editable = ref(false);
<r-section
icon="mdi-gamepad-variant"
:title="t('settings.platforms-versions')"
class="mx-2 mt-4 mb-2"
>
<template #toolbar-title-append>
<v-tooltip bottom max-width="400">
@@ -98,9 +97,8 @@ const editable = ref(false);
/>
</v-col>
</v-row>
<create-platform-version-dialog />
<delete-platform-version-dialog />
</template>
</r-section>
<create-platform-version-dialog />
<delete-platform-version-dialog />
</template>

View File

@@ -207,9 +207,7 @@ onBeforeUnmount(() => {
<div
v-if="
isHovering ||
(romsStore.isSimpleRom(rom) &&
rom.is_unidentified &&
!rom.path_cover_large) ||
(romsStore.isSimpleRom(rom) && !rom.path_cover_large) ||
(!romsStore.isSimpleRom(rom) &&
!rom.igdb_url_cover &&
!rom.moby_url_cover &&
@@ -219,8 +217,13 @@ onBeforeUnmount(() => {
:class="
sizeActionBar === 1 ? 'text-subtitle-1' : 'text-caption'
"
:title="
romsStore.isSimpleRom(rom) && rom.name === rom.fs_name
? rom.fs_name_no_tags
: rom.name || ''
"
>
<div class="pa-2">
<div class="pa-2 text-truncate">
{{
romsStore.isSimpleRom(rom) && rom.name === rom.fs_name
? rom.fs_name_no_tags

View File

@@ -152,7 +152,7 @@ function updateOptions({ sortBy }: { sortBy: SortBy }) {
</script>
<template>
<v-data-table-server
<v-data-table-virtual
@update:options="updateOptions"
@click:row="rowClick"
:items-per-page="72"
@@ -365,7 +365,7 @@ function updateOptions({ sortBy }: { sortBy: SortBy }) {
</v-menu>
</v-btn-group>
</template>
</v-data-table-server>
</v-data-table-virtual>
</template>
<style scoped>

View File

@@ -0,0 +1,16 @@
{
"add-collection": "Dodaj kolekcje",
"danger-zone": "Strefa Śmierci",
"delete-collection": "Usuń kolekcje",
"description": "Opis",
"edit-collection": "Edytuj kolekcje",
"name": "Nazwa",
"owner": "Właściciel",
"private": "Prywatne",
"private-desc": "Prywatne (Widoczne tylko dla mnie)",
"public": "Publiczne",
"public-desc": "Publiczne (widoczne dla każdego)",
"removing-collection-1": "Usuwanie kolekcji",
"removing-collection-2": "z RomM. Czy potwierdzasz?",
"search-collection": "Przeszukaj kolekcje"
}

View File

@@ -0,0 +1,47 @@
{
"about": "O aplikacji",
"add": "Dodaj",
"administration": "Administracja",
"apply": "Zastosuj",
"ascii-only": "Tylko znaki ASCII",
"cancel": "Anuluj",
"collection": "Kolekcja",
"collections": "Kolekcje",
"confirm": "Potwierdź",
"core": "Rdzeń",
"create": "Utwórz",
"edit": "Edytuj",
"exclude-on-delete": "Wyklucz przy usunięciu",
"filter": "Filtruj",
"firmware": "Oprogramowanie",
"games-n": "{n} Gra | {n} Gry | {n} Gier",
"library-management": "Zarządzanie biblioteką",
"logout": "Wyloguj się",
"name": "Nazwa",
"platform": "Platforma",
"platforms": "Platformy",
"platforms-n": "{n} Platforma | {n} Platformy | {n} Platform",
"platforms-size": "Rozmiar na platformę",
"profile": "Profil",
"random": "Losowo",
"required": "Wymagane",
"invalid-name": "Nieprawidłowa nazwa",
"invalid-email": "Nieprawidłowy email",
"save": "Zapisz",
"saves": "Zapisane stany",
"saves-n": "{n} Zapis | {n} Zapisy | {n} Zapisów",
"screenshots-n": "{n} Zrzut ekranu | {n} Zrzuty ekranu | {n} Zrzutów ekranu",
"search": "Szukaj",
"server-stats": "Statystyki serwera",
"size-on-disk": "Rozmiar na dysku",
"slug": "Identyfikator (slug)",
"state": "Stan",
"states": "Stany",
"states-n": "{n} Stan | {n} Stany | {n} Stanów",
"sync": "Synchronizuj",
"update": "Aktualizuj",
"upload": "Prześlij",
"user-interface": "Interfejs użytkownika",
"virtual-collection": "Automatycznie wygenerowana kolekcja",
"virtual-collections": "Automatycznie wygenerowane kolekcje"
}

View File

@@ -0,0 +1,9 @@
{
"404-subtitle": "Strona, której szukasz, nie istnieje",
"404-title": "Nie znaleziono strony",
"search-for-games": "Wyszukaj gry na wszystkich platformach",
"manual-match": "Wyszukaj gry we wszystkich źródłach metadanych",
"home-headline": "Brak gier w Twojej bibliotece",
"home-title": "Uruchom szybkie skanowanie, aby automatycznie wykryć gry na swoim systemie",
"home-text": "Gotowy do gry?"
}

View File

@@ -0,0 +1,4 @@
{
"load-more": "Załaduj więcej",
"all-loaded": "Wszystkie gry zostały załadowane"
}

View File

@@ -0,0 +1,4 @@
{
"continue-playing": "Kontynuuj grę",
"recently-added": "Ostatnio dodane"
}

View File

@@ -0,0 +1,16 @@
{
"login": "Zaloguj się",
"login-oidc": "Zaloguj się przez {oidc}",
"or": "lub",
"password": "Hasło",
"username": "Nazwa użytkownika",
"forgot-password": "Zapomniałeś hasła?",
"send-reset-link": "Wyślij link do resetu",
"reset-sent": "Link do resetu został wysłany. Skontaktuj się z administratorem.",
"new-password": "Nowe hasło",
"confirm-new-password": "Potwierdź nowe hasło",
"reset-password": "Zresetuj hasło",
"back-to-login": "Powrót do logowania",
"setup-wizard": "Kreator konfiguracji",
"register": "Zarejestruj się"
}

View File

@@ -0,0 +1,37 @@
{
"active-multi-select": "Aktywny wybór wielokrotny",
"age-rating": "Kategoria wiekowa",
"category": "Kategoria",
"change-view": "Zmień widok",
"collection": "Kolekcja",
"company": "Firma",
"cover-style": "Styl okładki",
"danger-zone": "Strefa zagrożenia",
"delete-platform": "Usuń platformę",
"family": "Rodzina",
"filter-gallery": "Filtruj galerię",
"franchise": "Seria",
"generation": "Generacja",
"genre": "Gatunek",
"language": "Język",
"no-firmware-found": "Nie znaleziono oprogramowania",
"old-horizontal-cases": "Stare poziome pudełka",
"old-squared-cases": "Stare kwadratowe pudełka",
"region": "Region",
"removing-platform-1": "Usuwanie platformy",
"removing-platform-2": " z RomM. Czy potwierdzasz?",
"reset-filters": "Zresetuj filtry",
"search-platform": "Szukaj platformy",
"settings": "Ustawienia",
"show-duplicates": "Pokaż duplikaty",
"show-favourites": "Pokaż ulubione",
"show-firmwares": "Pokaż oprogramowanie/BIOS",
"show-matched": "Pokaż dopasowane",
"show-unmatched": "Pokaż niedopasowane",
"show-playables": "Pokaż grywalne",
"show-ra": "Pokaż Retroachievements",
"show-missing": "Pokaż brakujące",
"show-verified": "Pokaż zweryfikowane",
"status": "Status",
"upload-roms": "Prześlij ROMy"
}

View File

@@ -0,0 +1,20 @@
{
"back-to-gallery": "Powrót do galerii",
"back-to-game-details": "Powrót do szczegółów gry",
"clear-cache": "Wyczyść pamięć podręczną EmulatorJS",
"clear-cache-description": "Zapisane stany i pliki przechowywane na serwerze nie zostaną usunięte.",
"clear-cache-title": "Czy na pewno chcesz wyczyścić pamięć podręczną EmulatorJS?",
"clear-cache-warning": "To usunie wszystkie zapisy i stany przechowywane w przeglądarce.",
"full-screen": "Pełny ekran",
"play": "Graj",
"quit": "Zakończ",
"save-and-quit": "Zapisz i zakończ",
"select-save": "Wybierz zapis",
"change-save": "Zmień zapis",
"deselect-save": "Odznacz zapis",
"select-state": "Wybierz stan",
"change-state": "Zmień stan",
"deselect-state": "Odznacz stan",
"background-color": "Kolor tła",
"select-background-color": "Wybierz kolor tła"
}

View File

@@ -0,0 +1,62 @@
{
"add-to-collection": "Dodaj do kolekcji",
"add-to-fav": "Dodaj do ulubionych",
"adding-to-collection-part1": "Dodawanie",
"adding-to-collection-part2": "ROM-ów do kolekcji",
"additional-content": "Dodatkowa zawartość",
"age-rating": "Kategoria wiekowa",
"backlogged": "Zaległe",
"by": "przez",
"cant-copy-link": "Nie można skopiować linku do schowka, skopiuj go ręcznie",
"collections": "Kolekcje",
"companies": "Firmy",
"completion": "Ukończenie",
"copy-link": "Kopiuj link do pobrania",
"default": "Ustaw jako domyślne",
"delete-rom": "Usuń",
"details": "Szczegóły",
"difficulty": "Poziom trudności",
"edit-rom": "Edytuj",
"file": "Plik",
"filename": "Nazwa pliku",
"files": "Pliki",
"folder-name": "Nazwa folderu",
"franchises": "Serie",
"genres": "Gatunki",
"hidden": "Ukryte",
"info": "Informacje",
"languages": "Języki",
"manual": "Instrukcja",
"manual-match": "Ręczne dopasowanie",
"my-notes": "Moje notatki",
"no-metadata-source": "Brak aktywnego źródła metadanych",
"no-saves-found": "Nie znaleziono zapisów",
"no-states-found": "Nie znaleziono stanów",
"now-playing": "Aktualnie grane",
"personal": "Osobiste",
"public-notes": "Notatki publiczne",
"rating": "Ocena",
"refresh-metadata": "Odśwież metadane",
"regions": "Regiony",
"related-content": "Powiązana zawartość",
"remove-from-collection": "Usuń z kolekcji",
"remove-from-fav": "Usuń z ulubionych",
"remove-from-playing": "Usuń z aktualnie granych",
"removing-from-collection-part1": "Usuwanie",
"removing-from-collection-part2": "ROM-ów z kolekcji",
"rename-file-part1": "Zmień nazwę pliku, aby pasowała do tytułu źródłowego {source}",
"rename-file-part2": "Plik zostanie przemianowany",
"rename-file-part3": "z",
"rename-file-part4": "na",
"rename-file-part5": "Tagi w nazwie pliku nie zostaną zmienione",
"results-found": "Znalezione wyniki",
"select-cover-image": "Wybierz obraz okładki",
"set-as-default": "Ustaw ROM jako domyślny",
"size": "Rozmiar",
"show-earned-only": "Pokaż tylko zdobyte",
"status": "Status",
"summary": "Podsumowanie",
"switch-version": "Zmień wersję",
"tags": "Tagi",
"unmatch-rom": "Odłącz ROM"
}

View File

@@ -0,0 +1,27 @@
{
"abort": "Przerwij",
"api-key-missing": "Brak lub nieprawidłowy klucz API",
"complete-rescan": "Pełne ponowne skanowanie",
"complete-rescan-desc": "Całkowite skanowanie wszystkich platform i plików (najwolniejsze)",
"disabled-by-admin": "Wyłączone przez administratora",
"hashes": "Przelicz sumy kontrolne",
"hashes-desc": "Przelicza sumy kontrolne dla wszystkich plików",
"manage-library": "Zarządzaj biblioteką",
"metadata-sources": "Źródła metadanych",
"new-platforms": "Nowe platformy",
"new-platforms-desc": "Skanuj tylko nowe platformy (najszybsze)",
"no-new-roms": "Nie znaleziono nowych ani zmodyfikowanych ROM-ów",
"partial-metadata": "Częściowe metadane",
"partial-metadata-desc": "Skanuj gry z częściowym dopasowaniem metadanych",
"platforms-scanned-n": "Platformy: zeskanowano {n}",
"platforms-scanned-with-details": "Platformy: zeskanowano {n_platforms}, dodano {n_added_platforms} nowych i zidentyfikowano {n_identified_platforms}",
"quick-scan": "Szybkie skanowanie",
"quick-scan-desc": "Skanuj tylko nowe pliki",
"roms-scanned-n": "ROM-y: zeskanowano {n}",
"roms-scanned-with-details": "ROM-y: zeskanowano {n_roms}, dodano {n_added_roms} nowych i zidentyfikowano {n_identified_roms}",
"scan": "Skanuj",
"scan-options": "Opcje skanowania",
"select-one-source": "Wybierz co najmniej jedno źródło metadanych, jeśli chcesz wzbogacić bibliotekę o grafiki i informacje",
"unidentified-games": "Niezidentyfikowane gry",
"unidentified-games-desc": "Skanuj gry bez dopasowanych metadanych"
}

View File

@@ -0,0 +1,64 @@
{
"continue-playing-as-grid": "Kontynuuj grę w widoku siatki",
"continue-playing-as-grid-desc": "Wyświetl karty „kontynuuj grę” w formie siatki na stronie głównej",
"email": "E-mail",
"enable-3d-effect": "Włącz efekt 3D",
"enable-3d-effect-desc": "Włącz efekt 3D dla kart gier/platform/kolekcji",
"excluded": "Wykluczone",
"excluded-multi-rom-files": "Pliki multi-ROM",
"excluded-multi-rom-parts-extensions": "Rozszerzenia części multi-ROM",
"excluded-multi-rom-parts-files": "Pliki części multi-ROM",
"excluded-single-rom-extensions": "Rozszerzenia pojedynczego ROM-u",
"excluded-single-rom-files": "Pliki pojedynczego ROM-u",
"folder-name": "Nazwa folderu",
"gallery": "Galeria",
"group-roms": "Grupuj ROM-y",
"group-roms-desc": "Grupuj wersje tego samego ROM-u razem w galerii",
"home": "Strona główna",
"interface": "Interfejs",
"invite-link": "Link zaproszenia",
"language": "Język",
"main-platform": "Główna platforma",
"password": "Hasło",
"platforms-drawer": "Menu platform",
"platforms-drawer-group-by": "Grupuj według",
"platform-version": "Wersja platformy",
"platforms-bindings": "Powiązania platform",
"platforms-versions": "Wersje platform",
"recently-added-as-grid": "Ostatnio dodane ROM-y w widoku siatki",
"recently-added-as-grid-desc": "Wyświetl ostatnio dodane ROM-y w formie siatki na stronie głównej",
"role": "Rola",
"romm-platform": "Platforma RomM",
"show-collections": "Pokaż kolekcje",
"show-collections-as-grid": "Kolekcje w widoku siatki",
"show-collections-as-grid-desc": "Wyświetl karty kolekcji w formie siatki na stronie głównej",
"show-collections-desc": "Pokaż sekcję kolekcji na stronie głównej",
"show-continue-playing": "Pokaż kontynuowane gry",
"show-continue-playing-desc": "Pokaż sekcję kontynuowania gry na stronie głównej",
"show-languages": "Pokaż języki",
"show-languages-desc": "Pokaż flagi językowe w galerii",
"show-platforms": "Pokaż platformy",
"show-platforms-as-grid": "Platformy w widoku siatki",
"show-platforms-as-grid-desc": "Wyświetl karty platform w formie siatki na stronie głównej",
"show-platforms-desc": "Pokaż sekcję platform na stronie głównej",
"show-recently-added": "Pokaż ostatnio dodane ROM-y",
"show-recently-added-desc": "Pokaż sekcję ostatnio dodanych ROM-ów na stronie głównej",
"show-regions": "Pokaż regiony",
"show-regions-desc": "Pokaż flagi regionów w galerii",
"show-siblings": "Pokaż pokrewne",
"show-siblings-desc": "Pokaż liczbę pokrewnych w galerii, gdy włączona jest opcja „Grupuj ROM-y”",
"show-status": "Pokaż status",
"show-status-desc": "Pokaż ikony statusów w galerii (zaległe, grane, ukończone itd.)",
"show-stats": "Pokaż statystyki",
"show-stats-desc": "Pokaż podsumowanie statystyk na stronie głównej",
"show-actionbar": "Pokaż pasek akcji",
"show-actionbar-desc": "Zawsze pokazuj pasek akcji na karcie gry",
"show-virtual-collections": "Pokaż automatyczne kolekcje",
"show-virtual-collections-desc": "Wyświetlane na stronie głównej i w panelu kolekcji",
"theme": "Motyw",
"theme-auto": "Automatyczny",
"theme-dark": "Ciemny",
"theme-light": "Jasny",
"username": "Nazwa użytkownika",
"virtual-collection-type": "Typ automatycznej kolekcji (metoda grupowania ROM-ów)"
}

View File

@@ -16,6 +16,7 @@ const defaultLanguageState = {
{ value: "ko_KR", name: "한국어 (대한민국)" },
{ value: "ja_JP", name: "日本語 (日本)" },
{ value: "it_IT", name: "Italiano" },
{ value: "pl_PL", name: "Polski" },
].sort((a, b) => a.name.localeCompare(b.name)),
};

View File

@@ -12,6 +12,7 @@ type GalleryFilterStore = ExtractPiniaStoreType<typeof storeGalleryFilter>;
export type SimpleRom = SimpleRomSchema;
export type DetailedRom = DetailedRomSchema;
export const MAX_FETCH_LIMIT = 10000;
const defaultRomsState = {
currentPlatform: null as Platform | null,
@@ -98,7 +99,11 @@ export default defineStore("roms", {
}
}
},
fetchRoms(galleryFilter: GalleryFilterStore, concat = true) {
fetchRoms(
galleryFilter: GalleryFilterStore,
groupRoms?: boolean,
concat = true,
) {
if (this.fetchingRoms) return Promise.resolve();
this.fetchingRoms = true;
@@ -116,7 +121,7 @@ export default defineStore("roms", {
offset: this.fetchOffset,
orderBy: this.orderBy,
orderDir: this.orderDir,
groupByMetaId: this._shouldGroupRoms(),
groupByMetaId: groupRoms ?? this._shouldGroupRoms(),
})
.then(({ data: { items, offset, total, char_index } }) => {
if (!concat || this.fetchOffset === 0) {
@@ -232,6 +237,9 @@ export default defineStore("roms", {
setOrderDir(orderDir: "asc" | "desc") {
this.orderDir = orderDir;
},
setLimit(limit: number) {
this.fetchLimit = limit;
},
isSimpleRom(rom: SimpleRom | SearchRomSchema): rom is SimpleRom {
return !isNull(rom.id) && !isUndefined(rom.id);
},

View File

@@ -387,6 +387,7 @@ const _EJS_CORES_MAP = {
gbc: ["gambatte", "mgba"],
"pc-fx": ["mednafen_pcfx"],
psx: ["pcsx_rearmed", "mednafen_psx_hw"],
"philips-cd-i": ["same_cdi"],
psp: ["ppsspp"],
segacd: ["genesis_plus_gx", "picodrive"],
sega32: ["picodrive"],

View File

@@ -1,11 +1,267 @@
<script setup lang="ts">
import Excluded from "@/components/Settings/LibraryManagement/Excluded.vue";
import PlatformBinding from "@/components/Settings/LibraryManagement/PlatformBinding.vue";
import PlatformVersions from "@/components/Settings/LibraryManagement/PlatformVersions.vue";
import Excluded from "@/components/Settings/LibraryManagement/Config/Excluded.vue";
import PlatformBinding from "@/components/Settings/LibraryManagement/Config/PlatformBinding.vue";
import PlatformVersions from "@/components/Settings/LibraryManagement/Config/PlatformVersions.vue";
import GameTable from "@/components/common/Game/Table.vue";
import PlatformIcon from "@/components/common/Platform/Icon.vue";
import MissingFromFSIcon from "@/components/common/MissingFromFSIcon.vue";
import LoadMoreBtn from "@/components/Gallery/LoadMoreBtn.vue";
import FabOverlay from "@/components/Gallery/FabOverlay.vue";
import storeRoms, { MAX_FETCH_LIMIT } from "@/stores/roms";
import storeGalleryFilter from "@/stores/galleryFilter";
import type { Emitter } from "mitt";
import storeGalleryView from "@/stores/galleryView";
import storePlatforms from "@/stores/platforms";
import type { Events } from "@/types/emitter";
import { storeToRefs } from "pinia";
import { ref, onMounted, inject, onBeforeUnmount, computed } from "vue";
import { useI18n } from "vue-i18n";
import { debounce } from "lodash";
const { t } = useI18n();
const tab = ref<"config" | "missing">("config");
const romsStore = storeRoms();
const { allRoms, fetchingRoms, fetchTotalRoms, filteredRoms } =
storeToRefs(romsStore);
const galleryViewStore = storeGalleryView();
const { scrolledToTop } = storeToRefs(galleryViewStore);
const galleryFilterStore = storeGalleryFilter();
const { selectedPlatform } = storeToRefs(galleryFilterStore);
const platformsStore = storePlatforms();
const missingGamesLoading = ref(false);
const emitter = inject<Emitter<Events>>("emitter");
let timeout: ReturnType<typeof setTimeout> = setTimeout(() => {}, 400);
const allPlatforms = computed(() =>
[
...new Map(
allRoms.value
.map((rom) => platformsStore.get(rom.platform_id))
.filter((platform) => !!platform)
.map((platform) => [platform!.id, platform]),
).values(),
].sort((a, b) => a!.name.localeCompare(b!.name)),
);
const onFilterChange = debounce(
() => {
romsStore.resetPagination();
galleryFilterStore.setFilterMissing(true);
romsStore.fetchRoms(galleryFilterStore, false);
const url = new URL(window.location.href);
// Update URL with filters
Object.entries({
platform: selectedPlatform.value
? String(selectedPlatform.value.id)
: null,
}).forEach(([key, value]) => {
if (value) {
url.searchParams.set(key, value);
} else {
url.searchParams.delete(key);
}
});
galleryFilterStore.setFilterMissing(false);
},
500,
// If leading and trailing options are true, this is invoked on the trailing edge of
// the timeout only if the the function is invoked more than once during the wait
{ leading: true, trailing: true },
);
async function fetchRoms() {
if (fetchingRoms.value) return;
emitter?.emit("showLoadingDialog", {
loading: true,
scrim: false,
});
galleryFilterStore.setFilterMissing(true);
romsStore
.fetchRoms(galleryFilterStore, false)
.then(() => {
emitter?.emit("showLoadingDialog", {
loading: false,
scrim: false,
});
})
.catch((error) => {
console.error("Error fetching missing games:", error);
emitter?.emit("snackbarShow", {
msg: `Couldn't fetch missing ROMs: ${error}`,
icon: "mdi-close-circle",
color: "red",
timeout: 4000,
});
})
.finally(() => {
galleryFilterStore.setFilterMissing(false);
if (romsStore.fetchOffset === romsStore.fetchLimit) {
missingGamesLoading.value = false;
}
});
}
function cleanupAll() {
romsStore.setLimit(MAX_FETCH_LIMIT);
galleryFilterStore.setFilterMissing(true);
romsStore
.fetchRoms(galleryFilterStore, false)
.then(() => {
emitter?.emit("showLoadingDialog", {
loading: false,
scrim: false,
});
emitter?.emit("showDeleteRomDialog", romsStore.filteredRoms);
})
.catch((error) => {
console.error("Error fetching missing games:", error);
emitter?.emit("snackbarShow", {
msg: `Couldn't fetch missing ROMs: ${error}`,
icon: "mdi-close-circle",
color: "red",
timeout: 4000,
});
})
.finally(() => {
galleryFilterStore.setFilterMissing(false);
});
}
function resetMissingRoms() {
romsStore.reset();
galleryFilterStore.resetFilters();
}
function onScroll() {
clearTimeout(timeout);
window.setTimeout(async () => {
scrolledToTop.value = window.scrollY === 0;
if (
window.innerHeight + window.scrollY >= document.body.offsetHeight - 60 &&
fetchTotalRoms.value > filteredRoms.value.length
) {
await fetchRoms();
}
}, 100);
}
onMounted(() => {
resetMissingRoms();
fetchRoms();
window.addEventListener("scroll", onScroll);
});
onBeforeUnmount(() => {
resetMissingRoms();
window.removeEventListener("scroll", onScroll);
});
</script>
<template>
<platform-binding />
<platform-versions />
<excluded />
<v-row no-gutters class="pa-2">
<v-col cols="12">
<v-tabs
v-model="tab"
align-tabs="start"
slider-color="secondary"
selected-class="bg-toplayer"
>
<v-tab prepend-icon="mdi-cog" class="rounded" value="config"
>Config</v-tab
>
<v-tab
prepend-icon="mdi-folder-question"
class="rounded"
value="missing"
>Missing games</v-tab
>
</v-tabs>
</v-col>
<v-col>
<v-tabs-window v-model="tab">
<v-tabs-window-item value="config">
<platform-binding class="mt-2" />
<platform-versions class="mt-4" />
<excluded class="mt-4" />
</v-tabs-window-item>
<v-tabs-window-item value="missing">
<v-row class="mt-2 mr-2 align-center" no-gutters>
<v-col>
<v-select
class="mx-2"
v-model="selectedPlatform"
hide-details
prepend-inner-icon="mdi-controller"
clearable
:label="t('common.platform')"
variant="outlined"
density="comfortable"
:items="allPlatforms"
@update:model-value="onFilterChange"
>
<template #item="{ props, item }">
<v-list-item
v-bind="props"
class="py-4"
:title="item.raw.name ?? ''"
:subtitle="item.raw.fs_slug"
>
<template #prepend>
<platform-icon
:key="item.raw.slug"
:size="35"
:slug="item.raw.slug"
:name="item.raw.name"
:fs-slug="item.raw.fs_slug"
/>
</template>
<template #append>
<missing-from-f-s-icon
v-if="item.raw.missing_from_fs"
text="Missing platform from filesystem"
chip
chip-label
chipDensity="compact"
class="ml-2"
/>
<v-chip class="ml-2" size="x-small" label>
{{ item.raw.rom_count }}
</v-chip>
</template>
</v-list-item>
</template>
<template #chip="{ item }">
<platform-icon
:key="item.raw.slug"
:slug="item.raw.slug"
:name="item.raw.name"
:fs-slug="item.raw.fs_slug"
:size="20"
class="mx-2"
/>
{{ item.raw.name }}
</template>
</v-select>
</v-col>
<v-col cols="auto">
<v-btn
prepend-icon="mdi-delete"
size="large"
class="text-romm-red bg-toplayer"
variant="flat"
@click="cleanupAll"
>Clean up all</v-btn
>
</v-col>
</v-row>
<game-table class="mx-2 mt-2" show-platform-icon />
<load-more-btn :fetchRoms="fetchRoms" />
<fab-overlay />
</v-tabs-window-item>
</v-tabs-window>
</v-col>
</v-row>
</template>