fix player not resetting + fix episode selection not switching episode

This commit is contained in:
mrjvs 2023-10-14 22:03:13 +02:00
parent 3c5fb66073
commit b9f79b97c0
5 changed files with 53 additions and 22 deletions

View File

@ -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 { useTranslation } from "react-i18next";
import { useAsync } from "react-use"; import { useAsync } from "react-use";
@ -13,6 +13,7 @@ import { usePlayerMeta } from "@/components/player/hooks/usePlayerMeta";
import { VideoPlayerButton } from "@/components/player/internals/Button"; import { VideoPlayerButton } from "@/components/player/internals/Button";
import { Context } from "@/components/player/internals/ContextUtils"; import { Context } from "@/components/player/internals/ContextUtils";
import { useOverlayRouter } from "@/hooks/useOverlayRouter"; import { useOverlayRouter } from "@/hooks/useOverlayRouter";
import { PlayerMeta } from "@/stores/player/slices/source";
import { usePlayerStore } from "@/stores/player/store"; import { usePlayerStore } from "@/stores/player/store";
function CenteredText(props: { children: React.ReactNode }) { function CenteredText(props: { children: React.ReactNode }) {
@ -83,10 +84,12 @@ function EpisodesView({
id, id,
selectedSeason, selectedSeason,
goBack, goBack,
onChange,
}: { }: {
id: string; id: string;
selectedSeason: string; selectedSeason: string;
goBack?: () => void; goBack?: () => void;
onChange?: (meta: PlayerMeta) => void;
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const router = useOverlayRouter(id); const router = useOverlayRouter(id);
@ -96,11 +99,13 @@ function EpisodesView({
const playEpisode = useCallback( const playEpisode = useCallback(
(episodeId: string) => { (episodeId: string) => {
if (loadingState.value) if (loadingState.value) {
setPlayerMeta(loadingState.value.fullData, episodeId); const newData = setPlayerMeta(loadingState.value.fullData, episodeId);
if (newData) onChange?.(newData);
}
router.close(); router.close();
}, },
[setPlayerMeta, loadingState, router] [setPlayerMeta, loadingState, router, onChange]
); );
let content: ReactNode = null; 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 router = useOverlayRouter(id);
const meta = usePlayerStore((s) => s.meta); const meta = usePlayerStore((s) => s.meta);
const [selectedSeason, setSelectedSeason] = useState( const [selectedSeason, setSelectedSeason] = useState(
@ -170,6 +181,7 @@ function EpisodesOverlay({ id }: { id: string }) {
selectedSeason={selectedSeason} selectedSeason={selectedSeason}
id={id} id={id}
goBack={() => router.navigate("/")} goBack={() => router.navigate("/")}
onChange={onChange}
/> />
</OverlayPage> </OverlayPage>
</OverlayRouter> </OverlayRouter>
@ -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 { t } = useTranslation();
const router = useOverlayRouter("episodes"); const router = useOverlayRouter("episodes");
const setHasOpenOverlay = usePlayerStore((s) => s.setHasOpenOverlay); const setHasOpenOverlay = usePlayerStore((s) => s.setHasOpenOverlay);
@ -186,7 +202,6 @@ export function Episodes() {
useEffect(() => { useEffect(() => {
setHasOpenOverlay(router.isRouterActive); setHasOpenOverlay(router.isRouterActive);
}, [setHasOpenOverlay, router.isRouterActive]); }, [setHasOpenOverlay, router.isRouterActive]);
if (type !== "show") return null; if (type !== "show") return null;
return ( return (
@ -197,7 +212,7 @@ export function Episodes() {
> >
{t("videoPlayer.buttons.episodes")} {t("videoPlayer.buttons.episodes")}
</VideoPlayerButton> </VideoPlayerButton>
<EpisodesOverlay id={router.id} /> <EpisodesOverlay onChange={props.onChange} id={router.id} />
</OverlayAnchor> </OverlayAnchor>
); );
} }

View File

@ -14,14 +14,15 @@ export function usePlayer() {
const setMeta = usePlayerStore((s) => s.setMeta); const setMeta = usePlayerStore((s) => s.setMeta);
const setSource = usePlayerStore((s) => s.setSource); const setSource = usePlayerStore((s) => s.setSource);
const status = usePlayerStore((s) => s.status); const status = usePlayerStore((s) => s.status);
const meta = usePlayerStore((s) => s.meta);
const reset = usePlayerStore((s) => s.reset); const reset = usePlayerStore((s) => s.reset);
const { init } = useInitializePlayer(); const { init } = useInitializePlayer();
return { return {
reset, reset,
status, status,
setMeta(meta: PlayerMeta) { setMeta(m: PlayerMeta) {
setMeta(meta); setMeta(m);
}, },
playMedia(source: SourceSliceSource) { playMedia(source: SourceSliceSource) {
setSource(source); setSource(source);

View File

@ -18,7 +18,7 @@ export function usePlayerMeta() {
let playerMeta: PlayerMeta; let playerMeta: PlayerMeta;
if (m.meta.type === MWMediaType.SERIES) { if (m.meta.type === MWMediaType.SERIES) {
const ep = m.meta.seasonData.episodes.find((v) => v.id === episodeId); const ep = m.meta.seasonData.episodes.find((v) => v.id === episodeId);
if (!ep) return false; if (!ep) return null;
playerMeta = { playerMeta = {
type: "show", type: "show",
releaseYear: +(m.meta.year ?? 0), releaseYear: +(m.meta.year ?? 0),
@ -48,7 +48,7 @@ export function usePlayerMeta() {
_setPlayerMeta(playerMeta); _setPlayerMeta(playerMeta);
setMeta(playerMeta); setMeta(playerMeta);
setScrapeStatus(); setScrapeStatus();
return true; return playerMeta;
}, },
[_setPlayerMeta, setMeta, setScrapeStatus] [_setPlayerMeta, setMeta, setScrapeStatus]
); );

View File

@ -1,6 +1,6 @@
import { RunOutput } from "@movie-web/providers"; import { RunOutput } from "@movie-web/providers";
import { useCallback, useEffect, useRef, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import { useParams } from "react-router-dom"; import { useHistory, useParams } from "react-router-dom";
import { usePlayer } from "@/components/player/hooks/usePlayer"; import { usePlayer } from "@/components/player/hooks/usePlayer";
import { usePlayerMeta } from "@/components/player/hooks/usePlayerMeta"; 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 { MetaPart } from "@/pages/parts/player/MetaPart";
import { PlayerPart } from "@/pages/parts/player/PlayerPart"; import { PlayerPart } from "@/pages/parts/player/PlayerPart";
import { ScrapingPart } from "@/pages/parts/player/ScrapingPart"; 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() { export function PlayerView() {
const history = useHistory();
const params = useParams<{ const params = useParams<{
media: string; media: string;
episode?: string; episode?: string;
@ -20,13 +21,25 @@ export function PlayerView() {
const { setPlayerMeta, scrapeMedia } = usePlayerMeta(); const { setPlayerMeta, scrapeMedia } = usePlayerMeta();
const [backUrl] = useState("/"); // TODO redirect to search when needed 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(() => { useEffect(() => {
if (params.media === lastMedia.current) return;
lastMedia.current = params.media;
console.log("resetting");
reset(); 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( const playAfterScrape = useCallback(
(out: RunOutput | null) => { (out: RunOutput | null) => {
@ -37,7 +50,7 @@ export function PlayerView() {
); );
return ( return (
<PlayerPart backUrl={backUrl}> <PlayerPart backUrl={backUrl} onMetaChange={metaChange}>
{status === playerStatus.IDLE ? ( {status === playerStatus.IDLE ? (
<MetaPart onGetMeta={setPlayerMeta} /> <MetaPart onGetMeta={setPlayerMeta} />
) : null} ) : null}

View File

@ -3,11 +3,13 @@ import { ReactNode } from "react";
import { BrandPill } from "@/components/layout/BrandPill"; import { BrandPill } from "@/components/layout/BrandPill";
import { Player } from "@/components/player"; import { Player } from "@/components/player";
import { useShouldShowControls } from "@/components/player/hooks/useShouldShowControls"; import { useShouldShowControls } from "@/components/player/hooks/useShouldShowControls";
import { PlayerMeta } from "@/stores/player/slices/source";
export interface PlayerPartProps { export interface PlayerPartProps {
children?: ReactNode; children?: ReactNode;
backUrl: string; backUrl: string;
onLoad?: () => void; onLoad?: () => void;
onMetaChange?: (meta: PlayerMeta) => void;
} }
export function PlayerPart(props: PlayerPartProps) { export function PlayerPart(props: PlayerPartProps) {
@ -64,7 +66,7 @@ export function PlayerPart(props: PlayerPartProps) {
<Player.Time /> <Player.Time />
</Player.LeftSideControls> </Player.LeftSideControls>
<div className="flex items-center space-x-3"> <div className="flex items-center space-x-3">
<Player.Episodes /> <Player.Episodes onChange={props.onMetaChange} />
<Player.Settings /> <Player.Settings />
<Player.Fullscreen /> <Player.Fullscreen />
</div> </div>