2023-01-23 22:38:05 +01:00
|
|
|
import { useEffect, useRef } from "react";
|
|
|
|
import { useVideoPlayerState } from "../VideoContext";
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
children?: React.ReactNode;
|
|
|
|
id?: string;
|
|
|
|
className?: string;
|
|
|
|
}
|
|
|
|
|
2023-01-23 23:58:40 +01:00
|
|
|
// TODO store popout in router history so you can press back to yeet
|
2023-01-24 18:12:37 +01:00
|
|
|
// TODO add transition
|
2023-01-23 22:38:05 +01:00
|
|
|
export function VideoPopout(props: Props) {
|
|
|
|
const { videoState } = useVideoPlayerState();
|
|
|
|
const popoutRef = useRef<HTMLDivElement>(null);
|
|
|
|
const isOpen = videoState.popout === props.id;
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (!isOpen) return;
|
|
|
|
const popoutEl = popoutRef.current;
|
2023-01-24 18:12:37 +01:00
|
|
|
function windowClick(e: MouseEvent) {
|
|
|
|
const rect = popoutEl?.getBoundingClientRect();
|
|
|
|
if (rect) {
|
|
|
|
if (
|
|
|
|
e.pageX >= rect.x &&
|
|
|
|
e.pageX <= rect.x + rect.width &&
|
|
|
|
e.pageY >= rect.y &&
|
|
|
|
e.pageY <= rect.y + rect.height
|
|
|
|
) {
|
|
|
|
// inside bounding box of popout
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
videoState.closePopout();
|
2023-01-23 22:38:05 +01:00
|
|
|
}
|
2023-01-24 18:12:37 +01:00
|
|
|
|
2023-01-23 22:38:05 +01:00
|
|
|
window.addEventListener("click", windowClick);
|
|
|
|
return () => {
|
|
|
|
window.removeEventListener("click", windowClick);
|
|
|
|
};
|
|
|
|
}, [isOpen, videoState]);
|
|
|
|
|
|
|
|
return (
|
2023-01-24 18:12:37 +01:00
|
|
|
<div
|
|
|
|
className={[
|
|
|
|
"is-popout absolute inset-x-0 h-0",
|
|
|
|
!isOpen ? "hidden" : "",
|
|
|
|
].join(" ")}
|
|
|
|
>
|
2023-01-23 22:38:05 +01:00
|
|
|
<div className="absolute bottom-10 right-0 h-96 w-72 rounded-lg bg-denim-400">
|
|
|
|
<div
|
|
|
|
ref={popoutRef}
|
|
|
|
className={["h-full w-full", props.className].join(" ")}
|
|
|
|
>
|
2023-01-24 18:12:37 +01:00
|
|
|
{isOpen ? props.children : null}
|
2023-01-23 22:38:05 +01:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|