movie-web/__old/DecoratedVideoPlayer.tsx

185 lines
6.7 KiB
TypeScript
Raw Normal View History

import { DetailedMeta } from "@/backend/metadata/getmeta";
import { useIsMobile } from "@/hooks/useIsMobile";
2023-01-10 19:53:55 +01:00
import { useCallback, useRef, useState } from "react";
import { CSSTransition } from "react-transition-group";
import { AirplayControl } from "./controls/AirplayControl";
2023-01-08 22:29:38 +01:00
import { BackdropControl } from "./controls/BackdropControl";
import { ChromeCastControl } from "./controls/ChromeCastControl";
2023-01-08 22:29:38 +01:00
import { FullscreenControl } from "./controls/FullscreenControl";
import { LoadingControl } from "./controls/LoadingControl";
2023-01-10 19:53:55 +01:00
import { MiddlePauseControl } from "./controls/MiddlePauseControl";
import { MobileCenterControl } from "./controls/MobileCenterControl";
import { PageTitleControl } from "./controls/PageTitleControl";
2023-01-08 22:29:38 +01:00
import { PauseControl } from "./controls/PauseControl";
import { ProgressControl } from "./controls/ProgressControl";
import { QualityDisplayControl } from "./controls/QualityDisplayControl";
import { SeriesSelectionControl } from "./controls/SeriesSelectionControl";
import { ShowTitleControl } from "./controls/ShowTitleControl";
import { SkipTime } from "./controls/SkipTime";
import { SourceSelectionControl } from "./controls/SourceSelectionControl";
2023-01-08 22:29:38 +01:00
import { TimeControl } from "./controls/TimeControl";
import { VolumeControl } from "./controls/VolumeControl";
2023-01-15 16:51:55 +01:00
import { VideoPlayerError } from "./parts/VideoPlayerError";
2023-01-10 00:27:04 +01:00
import { VideoPlayerHeader } from "./parts/VideoPlayerHeader";
2023-01-10 19:53:55 +01:00
import { useVideoPlayerState } from "./VideoContext";
2023-01-08 22:29:38 +01:00
import { VideoPlayer, VideoPlayerProps } from "./VideoPlayer";
2023-01-10 21:18:10 +01:00
interface DecoratedVideoPlayerProps {
media?: DetailedMeta;
2023-01-10 21:18:10 +01:00
onGoBack?: () => void;
}
2023-01-10 19:53:55 +01:00
function LeftSideControls() {
const { videoState } = useVideoPlayerState();
const handleMouseEnter = useCallback(() => {
videoState.setLeftControlsHover(true);
}, [videoState]);
const handleMouseLeave = useCallback(() => {
videoState.setLeftControlsHover(false);
}, [videoState]);
return (
<>
<div
className="flex items-center px-2"
onMouseLeave={handleMouseLeave}
onMouseEnter={handleMouseEnter}
>
<PauseControl />
<TimeControl />
<VolumeControl className="mr-2" />
<SkipTime />
</div>
<ShowTitleControl />
</>
2023-01-10 19:53:55 +01:00
);
}
2023-01-10 00:27:04 +01:00
2023-01-10 21:18:10 +01:00
export function DecoratedVideoPlayer(
props: VideoPlayerProps & DecoratedVideoPlayerProps
) {
2023-01-10 19:53:55 +01:00
const top = useRef<HTMLDivElement>(null);
const center = useRef<HTMLDivElement>(null);
2023-01-10 19:53:55 +01:00
const bottom = useRef<HTMLDivElement>(null);
const [show, setShow] = useState(false);
const { isMobile } = useIsMobile();
2023-01-10 19:53:55 +01:00
const onBackdropChange = useCallback(
(showing: boolean) => {
setShow(showing);
},
[setShow]
);
2023-01-08 22:29:38 +01:00
return (
<VideoPlayer autoPlay={props.autoPlay}>
<PageTitleControl media={props.media?.meta} />
<VideoPlayerError media={props.media?.meta} onGoBack={props.onGoBack}>
2023-01-15 16:51:55 +01:00
<BackdropControl onBackdropChange={onBackdropChange}>
<div className="absolute inset-0 flex items-center justify-center">
<LoadingControl />
</div>
<div className="absolute inset-0 flex items-center justify-center">
<MiddlePauseControl />
</div>
{isMobile ? (
<CSSTransition
nodeRef={center}
in={show}
timeout={200}
classNames={{
exit: "transition-[transform,opacity] duration-200 opacity-100",
exitActive: "!opacity-0",
exitDone: "hidden",
enter: "transition-[transform,opacity] duration-200 opacity-0",
enterActive: "!opacity-100",
}}
>
<div
ref={center}
className="absolute inset-0 flex items-center justify-center"
>
<MobileCenterControl />
</div>
</CSSTransition>
) : (
""
)}
2023-01-15 16:51:55 +01:00
<CSSTransition
nodeRef={top}
2023-01-15 16:51:55 +01:00
in={show}
timeout={200}
classNames={{
exit: "transition-[transform,opacity] translate-y-0 duration-200 opacity-100",
exitActive: "!-translate-y-4 !opacity-0",
2023-01-15 16:51:55 +01:00
exitDone: "hidden",
enter:
"transition-[transform,opacity] -translate-y-4 duration-200 opacity-0",
2023-01-15 16:51:55 +01:00
enterActive: "!translate-y-0 !opacity-100",
}}
2023-01-10 19:53:55 +01:00
>
2023-01-15 16:51:55 +01:00
<div
ref={top}
className="pointer-events-auto absolute inset-x-0 top-0 flex flex-col py-6 px-8 pb-2"
2023-01-15 16:51:55 +01:00
>
<VideoPlayerHeader
media={props.media?.meta}
onClick={props.onGoBack}
isMobile={isMobile}
/>
2023-01-10 19:53:55 +01:00
</div>
2023-01-15 16:51:55 +01:00
</CSSTransition>
<CSSTransition
nodeRef={bottom}
2023-01-15 16:51:55 +01:00
in={show}
timeout={200}
classNames={{
exit: "transition-[transform,opacity] translate-y-0 duration-200 opacity-100",
exitActive: "!translate-y-4 !opacity-0",
2023-01-15 16:51:55 +01:00
exitDone: "hidden",
enter:
"transition-[transform,opacity] translate-y-4 duration-200 opacity-0",
2023-01-15 16:51:55 +01:00
enterActive: "!translate-y-0 !opacity-100",
}}
2023-01-10 19:53:55 +01:00
>
2023-01-15 16:51:55 +01:00
<div
ref={bottom}
className="pointer-events-auto absolute inset-x-0 bottom-0 flex flex-col px-4 pb-2 [margin-bottom:env(safe-area-inset-bottom)]"
2023-01-15 16:51:55 +01:00
>
<div className="flex w-full items-center space-x-3">
{isMobile && <SkipTime noDuration />}
<ProgressControl />
</div>
<div className="flex items-center">
{isMobile ? (
<div className="grid w-full grid-cols-[56px,1fr,56px] items-center">
<div />
<div className="flex items-center justify-center">
<SeriesSelectionControl />
<SourceSelectionControl media={props.media} />
</div>
<FullscreenControl />
</div>
) : (
<>
<LeftSideControls />
<div className="flex-1" />
<QualityDisplayControl />
<SeriesSelectionControl />
<SourceSelectionControl media={props.media} />
<AirplayControl />
<ChromeCastControl />
<FullscreenControl />
</>
)}
</div>
2023-01-15 16:51:55 +01:00
</div>
</CSSTransition>
</BackdropControl>
{props.children}
</VideoPlayerError>
2023-01-08 22:29:38 +01:00
</VideoPlayer>
);
}