diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 454e26b..e792daa 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -228,9 +228,8 @@ export default function App() { useEffect(() => { const prefs = meQuery.data?.preferences; if (!prefs) return; - const prefsRec = prefs as Record; (["feed", "plex", "playlists"] as PanelId[]).forEach((p) => { - const raw = prefsRec[PREF_KEY[p]]; + const raw = prefs[PREF_KEY[p]]; if (raw) { const l = normalizeLayout(p, raw); setPanelLayouts((prev) => ({ ...prev, [p]: l })); @@ -245,9 +244,9 @@ export default function App() { setFilterCollapsedState(prefs.filterCollapsed); writeAccount(LS.filterCollapsed, prefs.filterCollapsed); } - if (typeof prefsRec.playlistsCollapsed === "boolean") { - setPlaylistsCollapsedState(prefsRec.playlistsCollapsed); - writeAccount(LS.playlistsCollapsed, prefsRec.playlistsCollapsed); + if (typeof prefs.playlistsCollapsed === "boolean") { + setPlaylistsCollapsedState(prefs.playlistsCollapsed); + writeAccount(LS.playlistsCollapsed, prefs.playlistsCollapsed); } const lang = prefs.language; if (typeof lang === "string" && isSupported(lang)) setLanguage(lang); diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 79619ba..baf0105 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -18,14 +18,18 @@ export { setUnauthorizedHandler, }; -// Domain modules split out of this file, re-exported so their types + the `api` façade stay -// importable from "./api". Their method slices are spread into `api` below. +// Domain modules split out of this file. Their TYPES are re-exported so consumers keep importing +// them from "./api" unchanged; their method slices stay internal (`export type *`, not `export *`) +// and reach consumers only through the `api` façade they're spread into below. Runtime value +// exports a domain genuinely owns (e.g. plex's EMPTY_PLEX_FILTERS/plexFilterCount) are re-exported +// explicitly. import { downloadsApi } from "./api/downloads"; -export * from "./api/downloads"; +export type * from "./api/downloads"; import { plexApi } from "./api/plex"; -export * from "./api/plex"; +export type * from "./api/plex"; +export { EMPTY_PLEX_FILTERS, plexFilterCount } from "./api/plex"; import { messagingApi } from "./api/messaging"; -export * from "./api/messaging"; +export type * from "./api/messaging"; export interface Me { id: number; diff --git a/frontend/src/lib/api/plex.ts b/frontend/src/lib/api/plex.ts index e1c8059..0a9eab4 100644 --- a/frontend/src/lib/api/plex.ts +++ b/frontend/src/lib/api/plex.ts @@ -460,6 +460,8 @@ export const plexApi = { duration_seconds, final, }), + // Inline union (matches api.ts's VideoStatus by design) rather than importing VideoStatus — that + // lives in the api.ts barrel, which imports this module, so reusing it would make a type cycle. plexSetState: (id: string, status: "new" | "watched" | "hidden"): Promise => req(`/api/plex/item/${encodeURIComponent(id)}/state`, { method: "POST",