import { useCallback, useMemo, useState, type ReactNode } from "react"; import { LS, setAccountRaw } from "../lib/storage"; import { useUrlMirror } from "../lib/useUrlMirror"; import { useNavigation } from "./navigationContext"; import { readSelectedId } from "./playlistsInit"; import { PlaylistsActionsContext, PlaylistsStateContext, type PlaylistsActions, type PlaylistsState, } from "./playlistsContext"; // Owns the Playlists module's shared local state — the rail's name filter and the selected playlist // — lifted out of the App god component so the header search box, the PlaylistsRail, and the // Playlists detail pane read it via hooks instead of prop-drilling through App. Mirrors // FeedFiltersProvider / NavigationProvider (split State + Actions contexts, one-line hooks; composed // in main.tsx around ). // // The `search` term is ephemeral (resets on reload, like the other list filters); the selected // playlist is per-account persisted (LS.playlist) so a reload returns you to it. Neither is // server-synced, and an account switch does a full reload, so init-from-storage is all the // hydration these need — no per-account load effect (unlike the server-backed feed filters). // // The contexts + hooks live in playlistsContext.ts. export function PlaylistsProvider({ children }: { children: ReactNode }) { const [search, setSearchState] = useState(""); const [selectedId, setSelectedIdState] = useState(readSelectedId); const setSearch = useCallback((q: string) => setSearchState(q), []); const setSelectedId = useCallback((id: number | null) => { setSelectedIdState(id); if (id != null) setAccountRaw(LS.playlist, String(id)); }, []); // Mirror the selected playlist to ?pl on the Playlists page so it's bookmarkable; clear it elsewhere // (the localStorage copy still restores it on return). useUrlMirror keeps ?page and the other nav // params intact. const { page } = useNavigation(); useUrlMirror({ pl: page === "playlists" && selectedId != null ? String(selectedId) : null }); const state = useMemo(() => ({ search, selectedId }), [search, selectedId]); const actions = useMemo( () => ({ setSearch, setSelectedId }), [setSearch, setSelectedId], ); return ( {children} ); }