A small web app for watching movies and shows easily
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

78 lines
2.6 KiB

import { Transition } from "@/components/Transition";
import { useSyncPopouts } from "@/video/components/hooks/useSyncPopouts";
import { EpisodeSelectionPopout } from "@/video/components/popouts/EpisodeSelectionPopout";
import { CaptionSelectionPopout } from "@/video/components/popouts/CaptionSelectionPopout";
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
import { useControls } from "@/video/state/logic/controls";
import { useInterface } from "@/video/state/logic/interface";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import "./Popouts.css";
function ShowPopout(props: { popoutId: string | null }) {
// only updates popout id when a new one is set, so transitions look good
const [popoutId, setPopoutId] = useState<string | null>(props.popoutId);
useEffect(() => {
if (!props.popoutId) return;
setPopoutId(props.popoutId);
}, [props]);
if (popoutId === "episodes") return <EpisodeSelectionPopout />;
if (popoutId === "captions") return <CaptionSelectionPopout />;
return null;
}
// TODO bug: coords are sometimes completely broken
export function PopoutProviderAction() {
const ref = useRef<HTMLDivElement>(null);
const descriptor = useVideoPlayerDescriptor();
const videoInterface = useInterface(descriptor);
const controls = useControls(descriptor);
useSyncPopouts(descriptor);
const handleClick = useCallback(() => {
controls.closePopout();
}, [controls]);
const distanceFromRight = useMemo(() => {
if (!videoInterface.popoutBounds) return 30;
const buttonCenter =
videoInterface.popoutBounds.left + videoInterface.popoutBounds.width / 2;
return Math.max(
window.innerWidth -
buttonCenter -
(ref.current?.getBoundingClientRect().width ?? 0) / 2,
30
);
}, [videoInterface.popoutBounds]);
const distanceFromBottom = useMemo(() => {
return videoInterface.popoutBounds
? videoInterface.popoutBounds.height + 30
: 30;
}, [videoInterface.popoutBounds]);
return (
<Transition
show={!!videoInterface.popout}
animation="slide-up"
className="h-full"
>
<div className="popout-wrapper pointer-events-auto absolute inset-0">
<div onClick={handleClick} className="absolute inset-0" />
<div
ref={ref}
className="absolute z-10 grid h-[500px] w-80 grid-rows-[auto,minmax(0,1fr)] overflow-hidden rounded-lg bg-ash-200"
style={{
right: `${distanceFromRight}px`,
bottom: `${distanceFromBottom}px`,
}}
>
<ShowPopout popoutId={videoInterface.popout} />
</div>
</div>
</Transition>
);
}