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) {