mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-16 16:20:04 +00:00
Improve user preference caching logic in frontend
This commit is contained in:
@@ -4,8 +4,8 @@ import {Button, Card, Divider, Select, Selection, SelectItem} from "@heroui/reac
|
|||||||
import {themes} from "Frontend/theming/themes";
|
import {themes} from "Frontend/theming/themes";
|
||||||
import {Theme} from "Frontend/theming/theme";
|
import {Theme} from "Frontend/theming/theme";
|
||||||
import ThemePreview from "Frontend/components/theming/ThemePreview";
|
import ThemePreview from "Frontend/components/theming/ThemePreview";
|
||||||
import {UserPreferencesEndpoint} from "Frontend/generated/endpoints";
|
|
||||||
import {toTitleCase} from "Frontend/util/utils";
|
import {toTitleCase} from "Frontend/util/utils";
|
||||||
|
import {UserPreferenceService} from "Frontend/util/user-preference-service";
|
||||||
|
|
||||||
export function ThemeSelector() {
|
export function ThemeSelector() {
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ export function ThemeSelector() {
|
|||||||
if (selectedMode instanceof Set) {
|
if (selectedMode instanceof Set) {
|
||||||
let theme = `${selectedTheme}-${selectedMode.values().next().value}`;
|
let theme = `${selectedTheme}-${selectedMode.values().next().value}`;
|
||||||
setTheme(theme);
|
setTheme(theme);
|
||||||
UserPreferencesEndpoint.set("preferred-theme", theme).catch(console.error);
|
UserPreferenceService.set("preferred-theme", theme).catch(console.error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import {UserPreferencesEndpoint} from "Frontend/generated/endpoints";
|
||||||
|
|
||||||
|
export class UserPreferenceService {
|
||||||
|
static LOCAL_STORAGE_PREFIX = "gameyfin.";
|
||||||
|
|
||||||
|
static async sync(): Promise<void> {
|
||||||
|
let keys = Object.keys(localStorage);
|
||||||
|
for (let key of keys) {
|
||||||
|
if (!key.startsWith(`${this.LOCAL_STORAGE_PREFIX}`)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let value = await UserPreferencesEndpoint.get(key.replace(this.LOCAL_STORAGE_PREFIX, ""));
|
||||||
|
if (value) {
|
||||||
|
localStorage.setItem(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async get(key: string): Promise<string | undefined> {
|
||||||
|
let localPreference = localStorage.getItem(`${this.LOCAL_STORAGE_PREFIX}${key}`);
|
||||||
|
|
||||||
|
if (localPreference) {
|
||||||
|
return localPreference;
|
||||||
|
} else {
|
||||||
|
let syncedPreference = await UserPreferencesEndpoint.get(key);
|
||||||
|
if (syncedPreference) {
|
||||||
|
localStorage.setItem(`${this.LOCAL_STORAGE_PREFIX}${key}`, syncedPreference);
|
||||||
|
return syncedPreference;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async set(key: string, value: string) {
|
||||||
|
await UserPreferencesEndpoint.set(key, value);
|
||||||
|
localStorage.setItem(`${this.LOCAL_STORAGE_PREFIX}${key}`, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,8 +8,8 @@ import {Outlet, useNavigate} from "react-router";
|
|||||||
import {useAuth} from "Frontend/util/auth";
|
import {useAuth} from "Frontend/util/auth";
|
||||||
import {Heart} from "@phosphor-icons/react";
|
import {Heart} from "@phosphor-icons/react";
|
||||||
import Confetti, {ConfettiProps} from "react-confetti-boom";
|
import Confetti, {ConfettiProps} from "react-confetti-boom";
|
||||||
import {UserPreferencesEndpoint} from "Frontend/generated/endpoints";
|
|
||||||
import {useTheme} from "next-themes";
|
import {useTheme} from "next-themes";
|
||||||
|
import {UserPreferenceService} from "Frontend/util/user-preference-service";
|
||||||
|
|
||||||
export default function MainLayout() {
|
export default function MainLayout() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -21,7 +21,10 @@ export default function MainLayout() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let newTitle = `Gameyfin - ${routeMetadata?.title}`;
|
let newTitle = `Gameyfin - ${routeMetadata?.title}`;
|
||||||
window.addEventListener('popstate', () => document.title = newTitle);
|
window.addEventListener('popstate', () => document.title = newTitle);
|
||||||
loadUserTheme().catch(console.error);
|
|
||||||
|
UserPreferenceService.sync()
|
||||||
|
.then(() => loadUserTheme().catch(console.error))
|
||||||
|
.catch(console.error);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const confettiProps: ConfettiProps = {
|
const confettiProps: ConfettiProps = {
|
||||||
@@ -35,16 +38,9 @@ export default function MainLayout() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function loadUserTheme() {
|
async function loadUserTheme() {
|
||||||
let syncedTheme = await UserPreferencesEndpoint.get("preferred-theme");
|
let syncedTheme = await UserPreferenceService.get("preferred-theme")
|
||||||
|
if (syncedTheme !== undefined) {
|
||||||
if (syncedTheme) {
|
|
||||||
setTheme(syncedTheme);
|
setTheme(syncedTheme);
|
||||||
} else {
|
|
||||||
let localTheme = localStorage.getItem('theme');
|
|
||||||
if (localTheme) {
|
|
||||||
setTheme(localTheme);
|
|
||||||
await UserPreferencesEndpoint.set("preferred-theme", localTheme);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ sealed class UserPreferences<T : Serializable>(
|
|||||||
val allowedValues: List<T>? = null
|
val allowedValues: List<T>? = null
|
||||||
) {
|
) {
|
||||||
data object PreferredTheme : UserPreferences<String>(String::class, "preferred-theme")
|
data object PreferredTheme : UserPreferences<String>(String::class, "preferred-theme")
|
||||||
|
data object PreferredDownloadMethod : UserPreferences<String>(String::class, "preferred-download-method")
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user