refactor(plex): scope module state in PlexProvider

Lift the Plex module's shared local state (scope / watch-state / sort / expanded
filters / search term / open-playlist hand-off) out of App into a split-context
PlexProvider with stable useCallback setters. PlexSidebar, PlexBrowse, and the
header search box read it via usePlex()/usePlexActions() instead of props drilled
through App; PlexBrowse is now prop-free. App loses six useStates + the filters
JSON memo/serialise helpers. (Platform S6b.2)
This commit is contained in:
2026-07-18 23:53:10 +02:00
parent d0fc061795
commit 6c32e5c8d6
6 changed files with 148 additions and 98 deletions
+5 -6
View File
@@ -9,23 +9,19 @@ import SyncStatus from "./SyncStatus";
import { useNavigation, useNavigationActions } from "./NavigationProvider";
import { useFeedFilters, useFeedFiltersActions } from "./FeedFiltersProvider";
import { usePlaylists, usePlaylistsActions } from "./PlaylistsProvider";
import { usePlex, usePlexActions } from "./PlexProvider";
// The floating top header: a row of glass pills over the content — a ModuleName pill (label +
// accent dot + back/forward arrows), the module's SearchBar where it has one, and the per-user
// sync chip at the right end.
export default function Header({
me,
plexQ,
setPlexQ,
channelsSearch,
setChannelsSearch,
onYtSearch,
onGoToFullHistory,
}: {
me: Me;
// Plex has its own ephemeral search term (see App) — the box is shared UI, the state is not.
plexQ: string;
setPlexQ: (q: string) => void;
channelsSearch: string;
setChannelsSearch: (q: string) => void;
// Trigger a live YouTube search for the current term (feed only; hidden for the demo account,
@@ -39,9 +35,12 @@ export default function Header({
const { setPage } = useNavigationActions();
const filters = useFeedFilters();
const { setFilters } = useFeedFiltersActions();
// The playlists name filter lives in PlaylistsProvider (shared with its rail + detail pane).
// The playlists name filter lives in PlaylistsProvider (shared with its rail + detail pane); the
// Plex search term lives in PlexProvider (shared with its rail + browse grid).
const { search: playlistsSearch } = usePlaylists();
const { setSearch: setPlaylistsSearch } = usePlaylistsActions();
const { q: plexQ } = usePlex();
const { setQ: setPlexQ } = usePlexActions();
// The ◀/▶ arrows step cyclically through the user's available modules (derived from `me`, so
// it stays correct as modules are added/gated). Labels of every active module feed ModuleName's
// dynamic width so the pill is sized to the widest reachable title in the current language.