feat(plex): P1.5 — Plex as a nav module + integrated search + filter sidebar
Per user feedback: promote Plex from a hidden feed-Source option to a first-class left-nav module, with its own filter sidebar and the shared top search box. - Plex is now a nav-rail module (page='plex', gated on me.plex_enabled) — its own page → correct browser Back/Forward; removed the Feed Source-dropdown 'plex' hack. - PlexSidebar.tsx: left filter column (library scope, watch-state for movies: all/unwatched/in_progress/watched, sort) — per-account persisted (App state). - Header search box now also serves the Plex page (integrated search); the live YouTube-search escalation stays feed-only. - PlexBrowse.tsx reworked: infinite scroll (IntersectionObserver, no 'Load more'), content-visibility for smoother long-list scroll, show drill-down rides history (useHistorySubview) so Back returns to the grid; dropped the stray 'YouTube feed' button on the show page. - backend /browse gains a per-user watch-state filter (show=, movies only). - plex i18n (navLabel + filter.*) en/hu/de. Note: episode-title 'Episode N' on some shows (e.g. Westworld) is Plex-side (unmatched show) — we mirror what Plex has; Match/Refresh in Plex + re-sync fixes it.
This commit is contained in:
parent
62636319b1
commit
219a935121
14 changed files with 290 additions and 133 deletions
|
|
@ -63,6 +63,7 @@ import { CURRENT_VERSION } from "./lib/releaseNotes";
|
|||
// never reach non-admins. All are rendered inside a <Suspense> boundary below.
|
||||
const Feed = lazy(() => import("./components/Feed"));
|
||||
const PlexBrowse = lazy(() => import("./components/PlexBrowse"));
|
||||
const PlexSidebar = lazy(() => import("./components/PlexSidebar"));
|
||||
const ChannelPage = lazy(() => import("./components/ChannelPage"));
|
||||
const Channels = lazy(() => import("./components/Channels"));
|
||||
const Playlists = lazy(() => import("./components/Playlists"));
|
||||
|
|
@ -242,6 +243,10 @@ export default function App() {
|
|||
const [channelsViewRaw, setChannelsView] = useAccountPersistedState(LS.channelsView, "subscribed");
|
||||
const channelsView: ChannelsView =
|
||||
channelsViewRaw === "discovery" ? "discovery" : "subscribed";
|
||||
// Plex module filters (its own left-sidebar filter section) — per-account persisted.
|
||||
const [plexLib, setPlexLib] = useAccountPersistedState(LS.plexLibrary, "");
|
||||
const [plexShowFilter, setPlexShowFilter] = useAccountPersistedState(LS.plexShow, "all");
|
||||
const [plexSort, setPlexSort] = useAccountPersistedState(LS.plexSort, "added");
|
||||
// Bumped to tell the channel manager to drop a stale column filter when we send the user
|
||||
// there to see a specific set (the header's "without full history" link).
|
||||
const [channelsFilterReset, setChannelsFilterReset] = useState(0);
|
||||
|
|
@ -713,6 +718,20 @@ export default function App() {
|
|||
onToggleCollapse={() => setFilterCollapsed(!filterCollapsed)}
|
||||
/>
|
||||
)}
|
||||
{page === "plex" && meQuery.data!.plex_enabled && (
|
||||
<Suspense fallback={null}>
|
||||
<PlexSidebar
|
||||
library={plexLib}
|
||||
setLibrary={setPlexLib}
|
||||
show={plexShowFilter}
|
||||
setShow={setPlexShowFilter}
|
||||
sort={plexSort}
|
||||
setSort={setPlexSort}
|
||||
collapsed={filterCollapsed}
|
||||
onToggleCollapse={() => setFilterCollapsed(!filterCollapsed)}
|
||||
/>
|
||||
</Suspense>
|
||||
)}
|
||||
<div className="relative flex-1 min-w-0 flex flex-col">
|
||||
{channelView ? (
|
||||
<Suspense fallback={pageFallback}>
|
||||
|
|
@ -782,8 +801,8 @@ export default function App() {
|
|||
prefs={prefsCtl}
|
||||
onOpenWizard={() => setWizardOpen(true)}
|
||||
/>
|
||||
) : meQuery.data!.plex_enabled && filters.librarySource === "plex" ? (
|
||||
<PlexBrowse filters={filters} setFilters={setFilters} />
|
||||
) : page === "plex" && meQuery.data!.plex_enabled ? (
|
||||
<PlexBrowse q={filters.q} library={plexLib} show={plexShowFilter} sort={plexSort} />
|
||||
) : (
|
||||
<Feed
|
||||
filters={filters}
|
||||
|
|
@ -791,7 +810,6 @@ export default function App() {
|
|||
view={view}
|
||||
canRead={meQuery.data!.can_read}
|
||||
isDemo={meQuery.data!.is_demo}
|
||||
plexEnabled={meQuery.data!.plex_enabled}
|
||||
onOpenWizard={() => setWizardOpen(true)}
|
||||
ytSearch={ytSearch}
|
||||
onYtSearch={enterYtSearch}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue