checkpoint

This commit is contained in:
Michael Freno
2026-02-04 12:10:30 -05:00
parent b8549777ba
commit cdabf2c3e0
22 changed files with 1176 additions and 18 deletions

109
src/stores/app.ts Normal file
View File

@@ -0,0 +1,109 @@
import { createSignal } from "solid-js"
import { DEFAULT_THEME, THEMES } from "../constants/themes"
import type { AppSettings, AppState, ThemeColors, ThemeName, UserPreferences } from "../types/settings"
const STORAGE_KEY = "podtui_app_state"
const defaultSettings: AppSettings = {
theme: "system",
fontSize: 14,
playbackSpeed: 1,
downloadPath: "",
}
const defaultPreferences: UserPreferences = {
showExplicit: false,
autoDownload: false,
}
const defaultState: AppState = {
settings: defaultSettings,
preferences: defaultPreferences,
customTheme: DEFAULT_THEME,
}
const loadState = (): AppState => {
if (typeof localStorage === "undefined") return defaultState
try {
const raw = localStorage.getItem(STORAGE_KEY)
if (!raw) return defaultState
const parsed = JSON.parse(raw) as Partial<AppState>
return {
settings: { ...defaultSettings, ...parsed.settings },
preferences: { ...defaultPreferences, ...parsed.preferences },
customTheme: { ...DEFAULT_THEME, ...parsed.customTheme },
}
} catch {
return defaultState
}
}
const saveState = (state: AppState) => {
if (typeof localStorage === "undefined") return
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(state))
} catch {
// ignore storage errors
}
}
export function createAppStore() {
const [state, setState] = createSignal<AppState>(loadState())
const updateState = (next: AppState) => {
setState(next)
saveState(next)
}
const updateSettings = (updates: Partial<AppSettings>) => {
const next = {
...state(),
settings: { ...state().settings, ...updates },
}
updateState(next)
}
const updatePreferences = (updates: Partial<UserPreferences>) => {
const next = {
...state(),
preferences: { ...state().preferences, ...updates },
}
updateState(next)
}
const updateCustomTheme = (updates: Partial<ThemeColors>) => {
const next = {
...state(),
customTheme: { ...state().customTheme, ...updates },
}
updateState(next)
}
const setTheme = (theme: ThemeName) => {
updateSettings({ theme })
}
const resolveTheme = (): ThemeColors => {
const theme = state().settings.theme
if (theme === "custom") return state().customTheme
return THEMES[theme] ?? DEFAULT_THEME
}
return {
state,
updateSettings,
updatePreferences,
updateCustomTheme,
setTheme,
resolveTheme,
}
}
let appStoreInstance: ReturnType<typeof createAppStore> | null = null
export function useAppStore() {
if (!appStoreInstance) {
appStoreInstance = createAppStore()
}
return appStoreInstance
}