diff --git a/src/components/player/atoms/Episodes.tsx b/src/components/player/atoms/Episodes.tsx index c8c7515b..782d0f75 100644 --- a/src/components/player/atoms/Episodes.tsx +++ b/src/components/player/atoms/Episodes.tsx @@ -1,4 +1,4 @@ -import { ReactNode, useCallback, useEffect, useState } from "react"; +import { ReactNode, useCallback, useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { useAsync } from "react-use"; @@ -13,6 +13,7 @@ import { usePlayerMeta } from "@/components/player/hooks/usePlayerMeta"; import { VideoPlayerButton } from "@/components/player/internals/Button"; import { Context } from "@/components/player/internals/ContextUtils"; import { useOverlayRouter } from "@/hooks/useOverlayRouter"; +import { PlayerMeta } from "@/stores/player/slices/source"; import { usePlayerStore } from "@/stores/player/store"; function CenteredText(props: { children: React.ReactNode }) { @@ -83,10 +84,12 @@ function EpisodesView({ id, selectedSeason, goBack, + onChange, }: { id: string; selectedSeason: string; goBack?: () => void; + onChange?: (meta: PlayerMeta) => void; }) { const { t } = useTranslation(); const router = useOverlayRouter(id); @@ -96,11 +99,13 @@ function EpisodesView({ const playEpisode = useCallback( (episodeId: string) => { - if (loadingState.value) - setPlayerMeta(loadingState.value.fullData, episodeId); + if (loadingState.value) { + const newData = setPlayerMeta(loadingState.value.fullData, episodeId); + if (newData) onChange?.(newData); + } router.close(); }, - [setPlayerMeta, loadingState, router] + [setPlayerMeta, loadingState, router, onChange] ); let content: ReactNode = null; @@ -144,7 +149,13 @@ function EpisodesView({ ); } -function EpisodesOverlay({ id }: { id: string }) { +function EpisodesOverlay({ + id, + onChange, +}: { + id: string; + onChange?: (meta: PlayerMeta) => void; +}) { const router = useOverlayRouter(id); const meta = usePlayerStore((s) => s.meta); const [selectedSeason, setSelectedSeason] = useState( @@ -170,6 +181,7 @@ function EpisodesOverlay({ id }: { id: string }) { selectedSeason={selectedSeason} id={id} goBack={() => router.navigate("/")} + onChange={onChange} /> @@ -177,7 +189,11 @@ function EpisodesOverlay({ id }: { id: string }) { ); } -export function Episodes() { +interface EpisodesProps { + onChange?: (meta: PlayerMeta) => void; +} + +export function Episodes(props: EpisodesProps) { const { t } = useTranslation(); const router = useOverlayRouter("episodes"); const setHasOpenOverlay = usePlayerStore((s) => s.setHasOpenOverlay); @@ -186,7 +202,6 @@ export function Episodes() { useEffect(() => { setHasOpenOverlay(router.isRouterActive); }, [setHasOpenOverlay, router.isRouterActive]); - if (type !== "show") return null; return ( @@ -197,7 +212,7 @@ export function Episodes() { > {t("videoPlayer.buttons.episodes")} - + ); } diff --git a/src/components/player/hooks/usePlayer.ts b/src/components/player/hooks/usePlayer.ts index ff9fd41f..13428a9b 100644 --- a/src/components/player/hooks/usePlayer.ts +++ b/src/components/player/hooks/usePlayer.ts @@ -14,14 +14,15 @@ export function usePlayer() { const setMeta = usePlayerStore((s) => s.setMeta); const setSource = usePlayerStore((s) => s.setSource); const status = usePlayerStore((s) => s.status); + const meta = usePlayerStore((s) => s.meta); const reset = usePlayerStore((s) => s.reset); const { init } = useInitializePlayer(); return { reset, status, - setMeta(meta: PlayerMeta) { - setMeta(meta); + setMeta(m: PlayerMeta) { + setMeta(m); }, playMedia(source: SourceSliceSource) { setSource(source); diff --git a/src/components/player/hooks/usePlayerMeta.ts b/src/components/player/hooks/usePlayerMeta.ts index 2c5bb7cb..6aac4c1c 100644 --- a/src/components/player/hooks/usePlayerMeta.ts +++ b/src/components/player/hooks/usePlayerMeta.ts @@ -18,7 +18,7 @@ export function usePlayerMeta() { let playerMeta: PlayerMeta; if (m.meta.type === MWMediaType.SERIES) { const ep = m.meta.seasonData.episodes.find((v) => v.id === episodeId); - if (!ep) return false; + if (!ep) return null; playerMeta = { type: "show", releaseYear: +(m.meta.year ?? 0), @@ -48,7 +48,7 @@ export function usePlayerMeta() { _setPlayerMeta(playerMeta); setMeta(playerMeta); setScrapeStatus(); - return true; + return playerMeta; }, [_setPlayerMeta, setMeta, setScrapeStatus] ); diff --git a/src/pages/PlayerView.tsx b/src/pages/PlayerView.tsx index cea1a60c..6ac39e14 100644 --- a/src/pages/PlayerView.tsx +++ b/src/pages/PlayerView.tsx @@ -1,6 +1,6 @@ import { RunOutput } from "@movie-web/providers"; -import { useCallback, useEffect, useRef, useState } from "react"; -import { useParams } from "react-router-dom"; +import { useCallback, useEffect, useState } from "react"; +import { useHistory, useParams } from "react-router-dom"; import { usePlayer } from "@/components/player/hooks/usePlayer"; import { usePlayerMeta } from "@/components/player/hooks/usePlayerMeta"; @@ -8,9 +8,10 @@ import { convertRunoutputToSource } from "@/components/player/utils/convertRunou import { MetaPart } from "@/pages/parts/player/MetaPart"; import { PlayerPart } from "@/pages/parts/player/PlayerPart"; import { ScrapingPart } from "@/pages/parts/player/ScrapingPart"; -import { playerStatus } from "@/stores/player/slices/source"; +import { PlayerMeta, playerStatus } from "@/stores/player/slices/source"; export function PlayerView() { + const history = useHistory(); const params = useParams<{ media: string; episode?: string; @@ -20,13 +21,25 @@ export function PlayerView() { const { setPlayerMeta, scrapeMedia } = usePlayerMeta(); const [backUrl] = useState("/"); // TODO redirect to search when needed - const lastMedia = useRef(params.media); + const paramsData = JSON.stringify({ + media: params.media, + season: params.season, + episode: params.episode, + }); useEffect(() => { - if (params.media === lastMedia.current) return; - lastMedia.current = params.media; - console.log("resetting"); reset(); - }, [params, reset]); + }, [paramsData, reset]); + + const metaChange = useCallback( + (meta: PlayerMeta) => { + if (meta?.type === "show") + history.push( + `/media/${params.media}/${meta.season?.tmdbId}/${meta.episode?.tmdbId}` + ); + else history.push(`/media/${params.media}`); + }, + [history, params] + ); const playAfterScrape = useCallback( (out: RunOutput | null) => { @@ -37,7 +50,7 @@ export function PlayerView() { ); return ( - + {status === playerStatus.IDLE ? ( ) : null} diff --git a/src/pages/parts/player/PlayerPart.tsx b/src/pages/parts/player/PlayerPart.tsx index da3064a4..f1f5be28 100644 --- a/src/pages/parts/player/PlayerPart.tsx +++ b/src/pages/parts/player/PlayerPart.tsx @@ -3,11 +3,13 @@ import { ReactNode } from "react"; import { BrandPill } from "@/components/layout/BrandPill"; import { Player } from "@/components/player"; import { useShouldShowControls } from "@/components/player/hooks/useShouldShowControls"; +import { PlayerMeta } from "@/stores/player/slices/source"; export interface PlayerPartProps { children?: ReactNode; backUrl: string; onLoad?: () => void; + onMetaChange?: (meta: PlayerMeta) => void; } export function PlayerPart(props: PlayerPartProps) { @@ -64,7 +66,7 @@ export function PlayerPart(props: PlayerPartProps) {
- +