60 lines
1.4 KiB
TypeScript
60 lines
1.4 KiB
TypeScript
import { z } from "zod";
|
|
import { browser } from "$app/environment";
|
|
import type { Track } from "./types";
|
|
|
|
const STORAGE_KEY = "amqtrain:player:v2";
|
|
|
|
export const trackSchema: z.ZodType<Track> = z.object({
|
|
id: z.number(),
|
|
src: z.string(),
|
|
title: z.string(),
|
|
artist: z.string(),
|
|
album: z.string(),
|
|
animeName: z.string().optional(),
|
|
type: z.number(),
|
|
number: z.number(),
|
|
fileName: z.string().nullable().optional(),
|
|
dub: z.boolean(),
|
|
rebroadcast: z.boolean(),
|
|
globalPercent: z.number(),
|
|
});
|
|
|
|
export const persistedStateSchema = z.object({
|
|
queue: z.array(trackSchema),
|
|
currentId: z.number().nullable(),
|
|
volume: z.number(),
|
|
isMuted: z.boolean(),
|
|
minimized: z.boolean(),
|
|
});
|
|
|
|
export type PersistedState = z.infer<typeof persistedStateSchema>;
|
|
|
|
export function loadState(): PersistedState | null {
|
|
if (!browser) return null;
|
|
try {
|
|
const raw = localStorage.getItem(STORAGE_KEY);
|
|
if (!raw) return null;
|
|
|
|
const parsed = JSON.parse(raw);
|
|
const result = persistedStateSchema.safeParse(parsed);
|
|
if (result.success) {
|
|
return result.data;
|
|
}
|
|
|
|
console.error("Failed to parse player state", result.error);
|
|
return null;
|
|
} catch (e) {
|
|
console.error("Failed to load player state", e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export function saveState(state: PersistedState) {
|
|
if (!browser) return;
|
|
try {
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
|
|
} catch (e) {
|
|
console.error("Failed to save player state", e);
|
|
}
|
|
}
|