refactor(playlists): scope module state in PlaylistsProvider

Lift the Playlists module's shared local state (rail name filter + selected
playlist) out of App into a split-context PlaylistsProvider, mirroring
FeedFiltersProvider. Header, PlaylistsRail, and the Playlists detail pane read
it via usePlaylists()/usePlaylistsActions() instead of props drilled through
App; the modules take only a uniform `me` prop now. App loses two useStates and
the selected-playlist persistence helper. (Platform S6b.2)
This commit is contained in:
2026-07-18 23:43:19 +02:00
parent f4a68575c5
commit d0fc061795
6 changed files with 95 additions and 48 deletions
+4 -4
View File
@@ -8,6 +8,7 @@ import SearchBar from "./SearchBar";
import SyncStatus from "./SyncStatus";
import { useNavigation, useNavigationActions } from "./NavigationProvider";
import { useFeedFilters, useFeedFiltersActions } from "./FeedFiltersProvider";
import { usePlaylists, usePlaylistsActions } from "./PlaylistsProvider";
// 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
@@ -18,8 +19,6 @@ export default function Header({
setPlexQ,
channelsSearch,
setChannelsSearch,
playlistsSearch,
setPlaylistsSearch,
onYtSearch,
onGoToFullHistory,
}: {
@@ -29,8 +28,6 @@ export default function Header({
setPlexQ: (q: string) => void;
channelsSearch: string;
setChannelsSearch: (q: string) => void;
playlistsSearch: string;
setPlaylistsSearch: (q: string) => void;
// Trigger a live YouTube search for the current term (feed only; hidden for the demo account,
// which can't spend the shared quota).
onYtSearch: (q: string) => void;
@@ -42,6 +39,9 @@ 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).
const { search: playlistsSearch } = usePlaylists();
const { setSearch: setPlaylistsSearch } = usePlaylistsActions();
// 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.