feat(plex): move the Discover/Browse toggle into the header
The Discover ⟷ Browse switch now sits in the header next to the library-scope pill (All / Movies / Shows), instead of on the chip row / atop the Discover surface. It's driven through a small one-way PlexViewBridge: PlexBrowse still OWNS the sub-view (useHistorySubview) and publishes its top-level view + opener to the bridge; the always-mounted Header reads it to render PlexViewToggle. A global sub-view provider was deliberately avoided — PlexBrowse's hook remounts on every plex entry and re-seeds from history (a page switch clears ?v + drops _sub), so each entry starts at the Discover root; lifting it out would let the view go stale across navigation. The toggle hides on deeper views (show/info/person/…) and on non-plex pages (bridge cleared on unmount). sortView is just SortControl now; the grid toolbar no longer carries the toggle. Verified: toggle in the header, switches discover⟷grid, hides on info + on Feed, and Feed→Plex resets to Discover (no stale view); no console errors.
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
import { createContext, useContext, useState, type ReactNode } from "react";
|
||||
import { type Sub } from "./plexSubUrl";
|
||||
|
||||
// A one-way bridge so the always-mounted Header can host the Plex Discover ⟷ Browse toggle even though
|
||||
// the sub-view state lives in (and is owned by) the plex-only PlexBrowse. PlexBrowse PUBLISHES its
|
||||
// current top-level view + opener here (on mount and on view change) and clears it on unmount; the
|
||||
// Header READS it to render the toggle beside the library-scope pill.
|
||||
//
|
||||
// Why a bridge and not a global sub-view provider: PlexBrowse's `useHistorySubview` REMOUNTS every time
|
||||
// you enter the plex page, re-seeding the view from history (a page switch clears ?v + drops _sub, so
|
||||
// each plex entry starts at the Discover root). Lifting that hook to an always-mounted provider would
|
||||
// lose the remount and let the view go stale across navigation. Keeping it in PlexBrowse preserves the
|
||||
// reseed; the bridge only mirrors the small slice the header needs.
|
||||
export type PlexViewControls = {
|
||||
isDiscover: boolean; // the Discover landing vs the flat Browse grid
|
||||
toggleable: boolean; // only discover|grid host the toggle; deeper views (show/info/person/…) hide it
|
||||
open: (v: Sub) => void;
|
||||
};
|
||||
|
||||
const ReadCtx = createContext<PlexViewControls | null>(null);
|
||||
const PublishCtx = createContext<(c: PlexViewControls | null) => void>(() => {});
|
||||
|
||||
export function PlexViewBridge({ children }: { children: ReactNode }) {
|
||||
const [controls, setControls] = useState<PlexViewControls | null>(null);
|
||||
return (
|
||||
<PublishCtx.Provider value={setControls}>
|
||||
<ReadCtx.Provider value={controls}>{children}</ReadCtx.Provider>
|
||||
</PublishCtx.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export const usePlexViewControls = () => useContext(ReadCtx);
|
||||
export const usePublishPlexView = () => useContext(PublishCtx);
|
||||
Reference in New Issue
Block a user