mirror of
https://github.com/movie-web/movie-web.git
synced 2024-11-13 09:25:07 +01:00
Merge pull request #1098 from dro-1/fix/next-episode
Fixed next episode button not loading new season
This commit is contained in:
commit
527b473835
@ -362,7 +362,8 @@
|
||||
},
|
||||
"nextEpisode": {
|
||||
"cancel": "Cancel",
|
||||
"next": "Next episode"
|
||||
"next": "Next episode",
|
||||
"nextSeason": "Next season"
|
||||
},
|
||||
"playbackError": {
|
||||
"badge": "Playback error",
|
||||
|
@ -1,7 +1,10 @@
|
||||
import classNames from "classnames";
|
||||
import { useCallback } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAsync } from "react-use";
|
||||
|
||||
import { getMetaFromId } from "@/backend/metadata/getmeta";
|
||||
import { MWMediaType, MWSeasonMeta } from "@/backend/metadata/types/mw";
|
||||
import { Icon, Icons } from "@/components/Icon";
|
||||
import { usePlayerMeta } from "@/components/player/hooks/usePlayerMeta";
|
||||
import { Transition } from "@/components/utils/Transition";
|
||||
@ -9,6 +12,8 @@ import { PlayerMeta } from "@/stores/player/slices/source";
|
||||
import { usePlayerStore } from "@/stores/player/store";
|
||||
import { useProgressStore } from "@/stores/progress";
|
||||
|
||||
import { hasAired } from "../utils/aired";
|
||||
|
||||
function shouldShowNextEpisodeButton(
|
||||
time: number,
|
||||
duration: number,
|
||||
@ -39,6 +44,45 @@ function Button(props: {
|
||||
);
|
||||
}
|
||||
|
||||
function useSeasons(mediaId: string, isLastEpisode: boolean = false) {
|
||||
const state = useAsync(async () => {
|
||||
if (isLastEpisode) {
|
||||
const data = await getMetaFromId(MWMediaType.SERIES, mediaId ?? "");
|
||||
if (data?.meta.type !== MWMediaType.SERIES) return null;
|
||||
return data.meta.seasons;
|
||||
}
|
||||
}, [mediaId, isLastEpisode]);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
function useNextSeasonEpisode(
|
||||
nextSeason: MWSeasonMeta | undefined,
|
||||
mediaId: string,
|
||||
) {
|
||||
const state = useAsync(async () => {
|
||||
if (nextSeason) {
|
||||
const data = await getMetaFromId(
|
||||
MWMediaType.SERIES,
|
||||
mediaId ?? "",
|
||||
nextSeason?.id,
|
||||
);
|
||||
if (data?.meta.type !== MWMediaType.SERIES) return null;
|
||||
|
||||
const nextSeasonEpisodes = data?.meta?.seasonData?.episodes
|
||||
.filter((episode) => hasAired(episode.air_date))
|
||||
.map((episode) => ({
|
||||
number: episode.number,
|
||||
title: episode.title,
|
||||
tmdbId: episode.id,
|
||||
}));
|
||||
|
||||
if (nextSeasonEpisodes.length > 0) return nextSeasonEpisodes[0];
|
||||
}
|
||||
}, [mediaId, nextSeason?.id]);
|
||||
return state;
|
||||
}
|
||||
|
||||
export function NextEpisodeButton(props: {
|
||||
controlsShowing: boolean;
|
||||
onChange?: (meta: PlayerMeta) => void;
|
||||
@ -58,6 +102,20 @@ export function NextEpisodeButton(props: {
|
||||
);
|
||||
const updateItem = useProgressStore((s) => s.updateItem);
|
||||
|
||||
const isLastEpisode =
|
||||
meta?.episode?.number === meta?.episodes?.at(-1)?.number;
|
||||
|
||||
const seasons = useSeasons(meta?.tmdbId ?? "", isLastEpisode);
|
||||
|
||||
const nextSeason = seasons.value?.find(
|
||||
(season) => season.number === (meta?.season?.number ?? 0) + 1,
|
||||
);
|
||||
|
||||
const nextSeasonEpisode = useNextSeasonEpisode(
|
||||
nextSeason,
|
||||
meta?.tmdbId ?? "",
|
||||
);
|
||||
|
||||
let show = false;
|
||||
if (showingState === "always") show = true;
|
||||
else if (showingState === "hover" && props.controlsShowing) show = true;
|
||||
@ -70,14 +128,23 @@ export function NextEpisodeButton(props: {
|
||||
? bottom
|
||||
: "bottom-[calc(3rem+env(safe-area-inset-bottom))]";
|
||||
|
||||
const nextEp = meta?.episodes?.find(
|
||||
(v) => v.number === (meta?.episode?.number ?? 0) + 1,
|
||||
);
|
||||
const nextEp = isLastEpisode
|
||||
? nextSeasonEpisode.value
|
||||
: meta?.episodes?.find(
|
||||
(v) => v.number === (meta?.episode?.number ?? 0) + 1,
|
||||
);
|
||||
|
||||
const loadNextEpisode = useCallback(() => {
|
||||
if (!meta || !nextEp) return;
|
||||
const metaCopy = { ...meta };
|
||||
metaCopy.episode = nextEp;
|
||||
metaCopy.season =
|
||||
isLastEpisode && nextSeason
|
||||
? {
|
||||
...nextSeason,
|
||||
tmdbId: nextSeason.id,
|
||||
}
|
||||
: metaCopy.season;
|
||||
setShouldStartFromBeginning(true);
|
||||
setDirectMeta(metaCopy);
|
||||
props.onChange?.(metaCopy);
|
||||
@ -93,6 +160,8 @@ export function NextEpisodeButton(props: {
|
||||
props,
|
||||
setShouldStartFromBeginning,
|
||||
updateItem,
|
||||
isLastEpisode,
|
||||
nextSeason,
|
||||
]);
|
||||
|
||||
if (!meta?.episode || !nextEp) return null;
|
||||
@ -121,7 +190,9 @@ export function NextEpisodeButton(props: {
|
||||
className="bg-buttons-primary hover:bg-buttons-primaryHover text-buttons-primaryText flex justify-center items-center"
|
||||
>
|
||||
<Icon className="text-xl mr-1" icon={Icons.SKIP_EPISODE} />
|
||||
{t("player.nextEpisode.next")}
|
||||
{isLastEpisode && nextEp
|
||||
? t("player.nextEpisode.nextSeason")
|
||||
: t("player.nextEpisode.next")}
|
||||
</Button>
|
||||
</div>
|
||||
</Transition>
|
||||
|
Loading…
Reference in New Issue
Block a user