mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-20 14:37:43 +01:00
show the episode info in the page title
This commit is contained in:
parent
6d9a963592
commit
3604a2f0d7
5 changed files with 63 additions and 21 deletions
|
@ -14,6 +14,7 @@ import { ShowTitleControl } from "./controls/ShowTitleControl";
|
|||
import { SkipTime } from "./controls/SkipTime";
|
||||
import { TimeControl } from "./controls/TimeControl";
|
||||
import { VolumeControl } from "./controls/VolumeControl";
|
||||
import { PageTitleControl } from "./controls/PageTitleControl";
|
||||
import { VideoPlayerError } from "./parts/VideoPlayerError";
|
||||
import { VideoPlayerHeader } from "./parts/VideoPlayerHeader";
|
||||
import { useVideoPlayerState } from "./VideoContext";
|
||||
|
@ -67,6 +68,7 @@ export function DecoratedVideoPlayer(
|
|||
|
||||
return (
|
||||
<VideoPlayer autoPlay={props.autoPlay}>
|
||||
<PageTitleControl media={props.media} />
|
||||
<VideoPlayerError media={props.media} onGoBack={props.onGoBack}>
|
||||
<BackdropControl onBackdropChange={onBackdropChange}>
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
|
|
23
src/components/video/controls/PageTitleControl.tsx
Normal file
23
src/components/video/controls/PageTitleControl.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { MWMediaMeta } from "@/backend/metadata/types";
|
||||
import { Helmet } from "react-helmet";
|
||||
import { useCurrentSeriesEpisodeInfo } from "../hooks/useCurrentSeriesEpisodeInfo";
|
||||
|
||||
interface PageTitleControlProps {
|
||||
media?: MWMediaMeta;
|
||||
}
|
||||
|
||||
export function PageTitleControl(props: PageTitleControlProps) {
|
||||
const { isSeries, episodeIdentifier } = useCurrentSeriesEpisodeInfo();
|
||||
|
||||
if (!props.media) return null;
|
||||
|
||||
const title = isSeries
|
||||
? `${props.media.title} - ${episodeIdentifier}`
|
||||
: props.media.title;
|
||||
|
||||
return (
|
||||
<Helmet>
|
||||
<title>{title}</title>
|
||||
</Helmet>
|
||||
);
|
||||
}
|
|
@ -1,29 +1,14 @@
|
|||
import { useMemo } from "react";
|
||||
import { useVideoPlayerState } from "../VideoContext";
|
||||
import { useCurrentSeriesEpisodeInfo } from "../hooks/useCurrentSeriesEpisodeInfo";
|
||||
|
||||
export function ShowTitleControl() {
|
||||
const { videoState } = useVideoPlayerState();
|
||||
const { isSeries, currentEpisodeInfo, episodeIdentifier } =
|
||||
useCurrentSeriesEpisodeInfo();
|
||||
|
||||
const { current, seasons } = videoState.seasonData;
|
||||
|
||||
const currentSeasonInfo = useMemo(() => {
|
||||
return seasons?.find((season) => season.id === current?.seasonId);
|
||||
}, [seasons, current]);
|
||||
|
||||
const currentEpisodeInfo = useMemo(() => {
|
||||
return currentSeasonInfo?.episodes?.find(
|
||||
(episode) => episode.id === current?.episodeId
|
||||
);
|
||||
}, [currentSeasonInfo, current]);
|
||||
|
||||
if (!videoState.seasonData.isSeries) return null;
|
||||
if (!videoState.seasonData.current) return null;
|
||||
|
||||
const selectedText = `S${currentSeasonInfo?.number} E${currentEpisodeInfo?.number}`;
|
||||
if (!isSeries) return null;
|
||||
|
||||
return (
|
||||
<p className="ml-8 select-none space-x-2 text-white">
|
||||
<span>{selectedText}</span>
|
||||
<span>{episodeIdentifier}</span>
|
||||
<span className="opacity-50">{currentEpisodeInfo?.title}</span>
|
||||
</p>
|
||||
);
|
||||
|
|
33
src/components/video/hooks/useCurrentSeriesEpisodeInfo.ts
Normal file
33
src/components/video/hooks/useCurrentSeriesEpisodeInfo.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { useMemo } from "react";
|
||||
import { useVideoPlayerState } from "../VideoContext";
|
||||
|
||||
export function useCurrentSeriesEpisodeInfo() {
|
||||
const { videoState } = useVideoPlayerState();
|
||||
|
||||
const { current, seasons } = videoState.seasonData;
|
||||
|
||||
const currentSeasonInfo = useMemo(() => {
|
||||
return seasons?.find((season) => season.id === current?.seasonId);
|
||||
}, [seasons, current]);
|
||||
|
||||
const currentEpisodeInfo = useMemo(() => {
|
||||
return currentSeasonInfo?.episodes?.find(
|
||||
(episode) => episode.id === current?.episodeId
|
||||
);
|
||||
}, [currentSeasonInfo, current]);
|
||||
|
||||
const isSeries = Boolean(
|
||||
videoState.seasonData.isSeries && videoState.seasonData.current
|
||||
);
|
||||
|
||||
if (!isSeries) return { isSeries: false };
|
||||
|
||||
const episodeIdentifier = `S${currentSeasonInfo?.number} E${currentEpisodeInfo?.number}`;
|
||||
|
||||
return {
|
||||
isSeries: true,
|
||||
episodeIdentifier,
|
||||
currentSeasonInfo,
|
||||
currentEpisodeInfo,
|
||||
};
|
||||
}
|
|
@ -111,7 +111,6 @@ export function MediaViewPlayer(props: MediaViewPlayerProps) {
|
|||
return (
|
||||
<div className="fixed top-0 left-0 h-[100dvh] w-screen">
|
||||
<Helmet>
|
||||
<title>{props.meta.meta.title}</title>
|
||||
<html data-full="true" />
|
||||
</Helmet>
|
||||
<DecoratedVideoPlayer media={props.meta.meta} onGoBack={goBack} autoPlay>
|
||||
|
|
Loading…
Reference in a new issue