diff --git a/examples/config.batocera-retrobat.yml b/examples/config.batocera-retrobat.yml
index 52a9630df..0c125064c 100644
--- a/examples/config.batocera-retrobat.yml
+++ b/examples/config.batocera-retrobat.yml
@@ -113,7 +113,7 @@ system:
ps4: ps4
psp: psp
psvita: psvita
- psx: ps
+ psx: psx
pv1000: casio-pv-1000
samcoupe: sam-coupe
satellaview: satellaview
diff --git a/frontend/src/RomM.vue b/frontend/src/RomM.vue
index b2d0a5404..6a9e908fb 100644
--- a/frontend/src/RomM.vue
+++ b/frontend/src/RomM.vue
@@ -1,7 +1,7 @@
diff --git a/frontend/src/components/Home/RecentAdded.vue b/frontend/src/components/Home/RecentAdded.vue
index 4bfde3f16..a665addcb 100644
--- a/frontend/src/components/Home/RecentAdded.vue
+++ b/frontend/src/components/Home/RecentAdded.vue
@@ -3,7 +3,7 @@ import GameCard from "@/components/common/Game/Card/Base.vue";
import RSection from "@/components/common/RSection.vue";
import storeRoms from "@/stores/roms";
import { views } from "@/utils";
-import { isNull } from "lodash";
+import { useLocalStorage } from "@vueuse/core";
import { storeToRefs } from "pinia";
import { ref } from "vue";
import { useI18n } from "vue-i18n";
@@ -11,14 +11,8 @@ import { useI18n } from "vue-i18n";
const { t } = useI18n();
const romsStore = storeRoms();
const { recentRoms } = storeToRefs(romsStore);
-const storedGridRecentRoms = localStorage.getItem("settings.gridRecentRoms");
-const gridRecentRoms = ref(
- isNull(storedGridRecentRoms) ? false : storedGridRecentRoms === "true",
-);
-const storedEnable3DEffect = localStorage.getItem("settings.enable3DEffect");
-const enable3DEffect = ref(
- isNull(storedEnable3DEffect) ? false : storedEnable3DEffect === "true",
-);
+const gridRecentRoms = useLocalStorage("settings.gridRecentRoms", false);
+const enable3DEffect = useLocalStorage("settings.enable3DEffect", false);
const isHovering = ref(false);
const hoveringRomId = ref();
const openedMenu = ref(false);
@@ -26,10 +20,6 @@ const openedMenuRomId = ref();
function toggleGridRecentRoms() {
gridRecentRoms.value = !gridRecentRoms.value;
- localStorage.setItem(
- "settings.gridRecentRoms",
- gridRecentRoms.value.toString(),
- );
}
function onHover(emitData: { isHovering: boolean; id: number }) {
diff --git a/frontend/src/components/Settings/UserInterface/Interface.vue b/frontend/src/components/Settings/UserInterface/Interface.vue
index ffede7d11..ca005f85a 100644
--- a/frontend/src/components/Settings/UserInterface/Interface.vue
+++ b/frontend/src/components/Settings/UserInterface/Interface.vue
@@ -2,8 +2,8 @@
import InterfaceOption from "@/components/Settings/UserInterface/InterfaceOption.vue";
import RSection from "@/components/common/RSection.vue";
import storeCollections from "@/stores/collections";
-import { isNull } from "lodash";
-import { computed, ref } from "vue";
+import { useLocalStorage } from "@vueuse/core";
+import { computed } from "vue";
import { useI18n } from "vue-i18n";
import { useDisplay } from "vuetify";
@@ -11,89 +11,40 @@ const { t } = useI18n();
const { smAndDown } = useDisplay();
const collectionsStore = storeCollections();
-// Initialize refs from localStorage
-
// Home
-const storedShowStats = localStorage.getItem("settings.showStats");
-const showStatsRef = ref(
- isNull(storedShowStats) ? true : storedShowStats === "true",
-);
-const storedShowRecentRoms = localStorage.getItem("settings.showRecentRoms");
-const showRecentRomsRef = ref(
- isNull(storedShowRecentRoms) ? true : storedShowRecentRoms === "true",
-);
-
-const storedShowContinuePlaying = localStorage.getItem(
+const showStatsRef = useLocalStorage("settings.showStats", true);
+const showRecentRomsRef = useLocalStorage("settings.showRecentRoms", true);
+const showContinuePlayingRef = useLocalStorage(
"settings.showContinuePlaying",
+ true,
);
-const showContinuePlayingRef = ref(
- isNull(storedShowContinuePlaying)
- ? true
- : storedShowContinuePlaying === "true",
-);
-const storedShowPlatforms = localStorage.getItem("settings.showPlatforms");
-const showPlatformsRef = ref(
- isNull(storedShowPlatforms) ? true : storedShowPlatforms === "true",
-);
-const storedShowCollections = localStorage.getItem("settings.showCollections");
-const showCollectionsRef = ref(
- isNull(storedShowCollections) ? true : storedShowCollections === "true",
-);
+const showPlatformsRef = useLocalStorage("settings.showPlatforms", true);
+const showCollectionsRef = useLocalStorage("settings.showCollections", true);
// Virtual collections
-const storedShowVirtualCollections = localStorage.getItem(
+const showVirtualCollectionsRef = useLocalStorage(
"settings.showVirtualCollections",
+ true,
);
-const showVirtualCollectionsRef = ref(
- isNull(storedShowVirtualCollections)
- ? true
- : storedShowVirtualCollections === "true",
-);
-const storedVirtualCollectionType = localStorage.getItem(
+const virtualCollectionTypeRef = useLocalStorage(
"settings.virtualCollectionType",
-);
-const virtualCollectionTypeRef = ref(
- isNull(storedVirtualCollectionType)
- ? "collection"
- : storedVirtualCollectionType,
+ "collection",
);
// Platforms drawer
-const storedPlatformsGroupBy = localStorage.getItem(
+const platformsGroupByRef = useLocalStorage(
"settings.platformsGroupBy",
-);
-const platformsGroupByRef = ref(
- isNull(storedPlatformsGroupBy) || storedPlatformsGroupBy === "null"
- ? null
- : storedPlatformsGroupBy,
+ null,
);
// Gallery
-const storedGroupRoms = localStorage.getItem("settings.groupRoms");
-const groupRomsRef = ref(
- isNull(storedGroupRoms) ? true : storedGroupRoms === "true",
-);
-const storedSiblings = localStorage.getItem("settings.showSiblings");
-const siblingsRef = ref(
- isNull(storedSiblings) ? true : storedSiblings === "true",
-);
-const storedRegions = localStorage.getItem("settings.showRegions");
-const regionsRef = ref(isNull(storedRegions) ? true : storedRegions === "true");
-const storedLanguages = localStorage.getItem("settings.showLanguages");
-const languagesRef = ref(
- isNull(storedLanguages) ? true : storedLanguages === "true",
-);
-const storedStatus = localStorage.getItem("settings.showStatus");
-const statusRef = ref(isNull(storedStatus) ? true : storedStatus === "true");
-
-const storedActionBar = localStorage.getItem("settings.showActionBar");
-const actionBarRef = ref(
- isNull(storedActionBar) ? false : storedActionBar === "true",
-);
-const stored3DEffect = localStorage.getItem("settings.enable3DEffect");
-const enable3DEffectRef = ref(
- isNull(stored3DEffect) ? false : stored3DEffect === "true",
-);
+const groupRomsRef = useLocalStorage("settings.groupRoms", true);
+const siblingsRef = useLocalStorage("settings.showSiblings", true);
+const regionsRef = useLocalStorage("settings.showRegions", true);
+const languagesRef = useLocalStorage("settings.showLanguages", true);
+const statusRef = useLocalStorage("settings.showStatus", true);
+const actionBarRef = useLocalStorage("settings.showActionBar", false);
+const enable3DEffectRef = useLocalStorage("settings.enable3DEffect", false);
const homeOptions = computed(() => [
{
@@ -211,72 +162,57 @@ const galleryOptions = computed(() => [
const setPlatformDrawerGroupBy = (value: string) => {
platformsGroupByRef.value = value;
- localStorage.setItem("settings.platformsGroupBy", value);
};
const toggleShowContinuePlaying = (value: boolean) => {
showContinuePlayingRef.value = value;
- localStorage.setItem("settings.showContinuePlaying", value.toString());
};
const toggleShowPlatforms = (value: boolean) => {
showPlatformsRef.value = value;
- localStorage.setItem("settings.showPlatforms", value.toString());
};
const toggleShowCollections = (value: boolean) => {
showCollectionsRef.value = value;
- localStorage.setItem("settings.showCollections", value.toString());
};
const toggleShowVirtualCollections = (value: boolean) => {
showVirtualCollectionsRef.value = value;
- localStorage.setItem("settings.showVirtualCollections", value.toString());
};
const setVirtualCollectionType = async (value: string) => {
virtualCollectionTypeRef.value = value;
- localStorage.setItem("settings.virtualCollectionType", value);
collectionsStore.fetchVirtualCollections(value);
};
const toggleShowStats = (value: boolean) => {
showStatsRef.value = value;
- localStorage.setItem("settings.showStats", value.toString());
};
const toggleShowRecentRoms = (value: boolean) => {
showRecentRomsRef.value = value;
- localStorage.setItem("settings.showRecentRoms", value.toString());
};
const toggleGroupRoms = (value: boolean) => {
groupRomsRef.value = value;
- localStorage.setItem("settings.groupRoms", value.toString());
};
const toggleSiblings = (value: boolean) => {
siblingsRef.value = value;
- localStorage.setItem("settings.showSiblings", value.toString());
};
const toggleRegions = (value: boolean) => {
regionsRef.value = value;
- localStorage.setItem("settings.showRegions", value.toString());
};
const toggleLanguages = (value: boolean) => {
languagesRef.value = value;
- localStorage.setItem("settings.showLanguages", value.toString());
};
const toggleStatus = (value: boolean) => {
statusRef.value = value;
- localStorage.setItem("settings.showStatus", value.toString());
};
const toggleActionBar = (value: boolean) => {
actionBarRef.value = value;
- localStorage.setItem("settings.showActionBar", value.toString());
};
const toggle3DEffect = (value: boolean) => {
enable3DEffectRef.value = value;
- localStorage.setItem("settings.enable3DEffect", value.toString());
};
diff --git a/frontend/src/components/Settings/UserInterface/LanguageSelector.vue b/frontend/src/components/Settings/UserInterface/LanguageSelector.vue
index 85f03aa81..36a43a488 100644
--- a/frontend/src/components/Settings/UserInterface/LanguageSelector.vue
+++ b/frontend/src/components/Settings/UserInterface/LanguageSelector.vue
@@ -1,16 +1,18 @@
diff --git a/frontend/src/components/Settings/UserInterface/Theme.vue b/frontend/src/components/Settings/UserInterface/Theme.vue
index 4522c91e8..f8806bd8d 100644
--- a/frontend/src/components/Settings/UserInterface/Theme.vue
+++ b/frontend/src/components/Settings/UserInterface/Theme.vue
@@ -3,14 +3,14 @@ import ThemeOption from "@/components/Settings/UserInterface/ThemeOption.vue";
import RSection from "@/components/common/RSection.vue";
import { autoThemeKey, themes } from "@/styles/themes";
import { isKeyof } from "@/types";
-import { computed, ref } from "vue";
+import { useLocalStorage } from "@vueuse/core";
+import { computed } from "vue";
import { useI18n } from "vue-i18n";
import { useTheme } from "vuetify";
const { t } = useI18n();
const theme = useTheme();
-const storedTheme = parseInt(localStorage.getItem("settings.theme") ?? "");
-const selectedTheme = ref(isNaN(storedTheme) ? autoThemeKey : storedTheme);
+const selectedTheme = useLocalStorage("settings.theme", autoThemeKey);
const themeOptions = computed(() => [
{
name: "dark",
@@ -27,7 +27,6 @@ const themeOptions = computed(() => [
]);
function toggleTheme() {
- localStorage.setItem("settings.theme", selectedTheme.value.toString());
const mediaMatch = window.matchMedia("(prefers-color-scheme: dark)");
if (selectedTheme.value === autoThemeKey) {
theme.global.name.value = mediaMatch.matches ? "dark" : "light";
diff --git a/frontend/src/components/common/Game/Card/Base.vue b/frontend/src/components/common/Game/Card/Base.vue
index 6ec85d380..f737ab592 100644
--- a/frontend/src/components/common/Game/Card/Base.vue
+++ b/frontend/src/components/common/Game/Card/Base.vue
@@ -15,7 +15,7 @@ import storeRoms from "@/stores/roms";
import { type SimpleRom } from "@/stores/roms";
import type { Events } from "@/types/emitter";
import { getMissingCoverImage, getUnmatchedCoverImage } from "@/utils/covers";
-import { isNull } from "lodash";
+import { useLocalStorage } from "@vueuse/core";
import type { Emitter } from "mitt";
import VanillaTilt from "vanilla-tilt";
import { computed, ref, onMounted, onBeforeUnmount, inject } from "vue";
@@ -110,15 +110,8 @@ const fallbackCoverImage = computed(() =>
);
const activeMenu = ref(false);
-const showActionBarAlways = isNull(
- localStorage.getItem("settings.showActionBar"),
-)
- ? false
- : localStorage.getItem("settings.showActionBar") === "true";
-
-const showSiblings = isNull(localStorage.getItem("settings.showSiblings"))
- ? true
- : localStorage.getItem("settings.showSiblings") === "true";
+const showActionBarAlways = useLocalStorage("settings.showActionBar", false);
+const showSiblings = useLocalStorage("settings.showSiblings", true);
const hasNotes = computed(() => {
if (!romsStore.isSimpleRom(props.rom)) return false;
diff --git a/frontend/src/components/common/Game/Card/Flags.vue b/frontend/src/components/common/Game/Card/Flags.vue
index 270ddf01e..b36f92781 100644
--- a/frontend/src/components/common/Game/Card/Flags.vue
+++ b/frontend/src/components/common/Game/Card/Flags.vue
@@ -6,19 +6,14 @@ import {
getEmojiForStatus,
getTextForStatus,
} from "@/utils";
-import { identity, isNull } from "lodash";
+import { useLocalStorage } from "@vueuse/core";
+import { identity } from "lodash";
import { computed } from "vue";
const props = defineProps<{ rom: SimpleRom }>();
-const showRegions = isNull(localStorage.getItem("settings.showRegions"))
- ? true
- : localStorage.getItem("settings.showRegions") === "true";
-const showLanguages = isNull(localStorage.getItem("settings.showLanguages"))
- ? true
- : localStorage.getItem("settings.showLanguages") === "true";
-const showStatus = isNull(localStorage.getItem("settings.showStatus"))
- ? true
- : localStorage.getItem("settings.showStatus") === "true";
+const showRegions = useLocalStorage("settings.showRegions", true);
+const showLanguages = useLocalStorage("settings.showLanguages", true);
+const showStatus = useLocalStorage("settings.showStatus", true);
const playingStatus = computed(() => {
const { now_playing, backlogged, status } = props.rom?.rom_user ?? {};
diff --git a/frontend/src/components/common/Game/Card/Skeleton.vue b/frontend/src/components/common/Game/Card/Skeleton.vue
index 9ba765861..ffcba98d1 100644
--- a/frontend/src/components/common/Game/Card/Skeleton.vue
+++ b/frontend/src/components/common/Game/Card/Skeleton.vue
@@ -1,7 +1,7 @@
diff --git a/frontend/src/components/common/Navigation/PlatformsDrawer.vue b/frontend/src/components/common/Navigation/PlatformsDrawer.vue
index 056a2368b..5fc3a7331 100644
--- a/frontend/src/components/common/Navigation/PlatformsDrawer.vue
+++ b/frontend/src/components/common/Navigation/PlatformsDrawer.vue
@@ -3,34 +3,28 @@ import PlatformListItem from "@/components/common/Platform/ListItem.vue";
import storeNavigation from "@/stores/navigation";
import type { Platform } from "@/stores/platforms";
import storePlatforms from "@/stores/platforms";
+import { useLocalStorage } from "@vueuse/core";
import { storeToRefs } from "pinia";
import { ref, watch, computed } from "vue";
import { useI18n } from "vue-i18n";
import { useDisplay } from "vuetify";
+type GroupByType = "family_name" | "generation" | "category" | null;
+
const { t } = useI18n();
const { mdAndUp, smAndDown } = useDisplay();
-
const navigationStore = storeNavigation();
const platformsStore = storePlatforms();
const { filteredPlatforms, filterText } = storeToRefs(platformsStore);
const { activePlatformsDrawer } = storeToRefs(navigationStore);
-
-const ALLOWED_GROUP_BY = ["family_name", "generation", "category"] as const;
-type GroupByType = (typeof ALLOWED_GROUP_BY)[number] | null;
-
const textFieldRef = ref();
const triggerElement = ref(null);
const openPanels = ref([]);
-const initializeGroupBy = (): GroupByType => {
- const stored = localStorage.getItem("settings.platformsGroupBy");
- return stored && ALLOWED_GROUP_BY.includes(stored as any)
- ? (stored as GroupByType)
- : null;
-};
-
-const groupBy = ref(initializeGroupBy());
+const groupBy = useLocalStorage(
+ "settings.platformsGroupBy",
+ null,
+);
const tabIndex = computed(() => (activePlatformsDrawer.value ? 0 : -1));
diff --git a/frontend/src/components/common/NewVersionDialog.vue b/frontend/src/components/common/NewVersionDialog.vue
index e6c7dc71f..1e108473d 100644
--- a/frontend/src/components/common/NewVersionDialog.vue
+++ b/frontend/src/components/common/NewVersionDialog.vue
@@ -1,5 +1,6 @@