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.
93 lines
3.0 KiB
93 lines
3.0 KiB
"use client";
|
|
|
|
import { useEffect, useState, type FC } from "react";
|
|
import { createPortal } from "react-dom";
|
|
import { useHardwareBackHandler } from "@/hooks/use-hardware-back-handler";
|
|
|
|
type VideoPlayerProps = {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
videoUrl?: string;
|
|
};
|
|
|
|
export const VideoPlayer: FC<VideoPlayerProps> = ({
|
|
isOpen,
|
|
onClose,
|
|
videoUrl,
|
|
}) => {
|
|
const [mounted, setMounted] = useState(false);
|
|
// Default to a responsive landscape layout that adapts nicely
|
|
const [containerStyle, setContainerStyle] = useState(
|
|
"relative w-full max-w-[640px] aspect-video rounded-2xl overflow-hidden bg-black shadow-2xl transition-all duration-300 ease-out",
|
|
);
|
|
|
|
useEffect(() => {
|
|
setMounted(true);
|
|
}, []);
|
|
|
|
useHardwareBackHandler(onClose, isOpen);
|
|
|
|
const handleLoadedMetadata = (e: React.SyntheticEvent<HTMLVideoElement>) => {
|
|
const video = e.currentTarget;
|
|
if (video.videoWidth && video.videoHeight) {
|
|
const ratio = video.videoWidth / video.videoHeight;
|
|
if (ratio < 0.8) {
|
|
// Vertical/portrait video (mobile format like TikTok/selfie)
|
|
setContainerStyle(
|
|
"relative w-full max-w-[340px] sm:max-w-[380px] aspect-[9/16] rounded-2xl overflow-hidden bg-black shadow-2xl max-h-[82vh] transition-all duration-300 ease-out",
|
|
);
|
|
} else {
|
|
// Horizontal/landscape video (standard format)
|
|
setContainerStyle(
|
|
"relative w-full max-w-[640px] sm:max-w-[720px] md:max-w-[800px] aspect-video rounded-2xl overflow-hidden bg-black shadow-2xl max-h-[85vh] transition-all duration-300 ease-out",
|
|
);
|
|
}
|
|
}
|
|
};
|
|
|
|
if (!isOpen || !mounted) return null;
|
|
|
|
return createPortal(
|
|
<div
|
|
className="fixed inset-0 z-50 flex items-center justify-center bg-black/85 backdrop-blur-xs p-4"
|
|
onClick={onClose}
|
|
>
|
|
<div className={containerStyle} onClick={(e) => e.stopPropagation()}>
|
|
<button
|
|
onClick={onClose}
|
|
className="absolute top-3 right-3 sm:top-4 sm:right-4 z-10 flex items-center justify-center w-11 h-11 rounded-full bg-black/40 hover:bg-black/60 text-white transition-all active:scale-95 cursor-pointer backdrop-blur-xs"
|
|
aria-label="Close video player"
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
className="h-6 w-6"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M6 18L18 6M6 6l12 12"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
<video
|
|
src={
|
|
videoUrl ||
|
|
"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
|
|
}
|
|
controls
|
|
autoPlay
|
|
playsInline
|
|
onLoadedMetadata={handleLoadedMetadata}
|
|
className="w-full h-full object-contain"
|
|
/>
|
|
</div>
|
|
</div>,
|
|
document.body,
|
|
);
|
|
};
|
|
|
|
export default VideoPlayer;
|