Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const Room = () => {
- const {
- hasWindow,
- setHasWindow,
- isPlayerReady,
- setIsPlayerReady,
- play,
- setPlay,
- isFullScreen,
- setIsFullScreen,
- volume,
- setVolume,
- url,
- setUrl,
- isDropdownOpen,
- setIsDropdownOpen,
- speed,
- setSpeed,
- playtime,
- setPlaytime,
- setActiveMenu,
- fileUrl,
- setFileUrl,
- } = useContext(playerContext);
- const [showControls, setShowControls] = useState(true);
- const [isMouseVisible, setIsMouseVisible] = useState(true);
- const [isRoomConnected, setIsRoomConnected] = useState(false);
- const [message, setMessage] = useState("");
- const [room, setRoom] = useState("");
- const timerRef = useRef(null);
- const playerRef = useRef();
- const rangeInputRef = useRef();
- const vidSectionRef = useRef();
- const fullScreenBtnRef = useRef();
- const volumeInputRef = useRef();
- const urlInputRef = useRef();
- const socket = useRef(null);
- const ChatMessage = useRef();
- const controlsDeactivationTime = 3000;
- const router = useRouter();
- const handlePlayerReady = () => {
- if (playerRef.current) {
- setIsPlayerReady(true);
- }
- };
- const handleRangeChange = (e) => {
- playerRef.current.seekTo(e.target.value, "seconds");
- setPlaytime(e.target.value);
- socket.current.emit("update-progress", roomID, e.target.value);
- };
- const handleProgressChange = () => {
- // get the current time of video
- // update the value of range input to current time of video
- if (rangeInputRef.current) {
- rangeInputRef.current.value = Math.round(
- playerRef.current.getCurrentTime()
- );
- if (
- formatTime(playerRef.current.getDuration()) ===
- formatTime(Math.round(playerRef.current.getCurrentTime()))
- ) {
- setPlay(false);
- }
- }
- setPlaytime(Math.round(playerRef.current.getCurrentTime()));
- };
- const handleOnPlay = () => {
- setPlay(true);
- socket.current.emit("play-video", roomID);
- };
- const handleOnPause = () => {
- setPlay(false);
- socket.current.emit("pause-video", roomID);
- };
- const handleFullScreen = (e) => {
- if (isFullScreen) {
- if (document.exitFullscreen) {
- document.exitFullscreen();
- }
- } else {
- if (vidSectionRef.current.requestFullscreen) {
- vidSectionRef.current.requestFullscreen();
- document.activeElement.blur(); // remove focus from the fullscreen button
- }
- }
- };
- const toggleFullscreen = () => {
- if (vidSectionRef.current) {
- if (!(document.fullscreenElement === vidSectionRef.current)) {
- vidSectionRef.current.requestFullscreen();
- } else {
- if (document.exitFullscreen) {
- document.exitFullscreen();
- }
- }
- setIsFullScreen(!isFullScreen);
- }
- };
- const togglePlayState = () => {
- setPlay((prevPlay) => !prevPlay);
- document.activeElement.blur();
- // setShowControls(true);
- };
- const handleVolumeChange = (e) => {
- setVolume(parseFloat(e.target.value));
- };
- const handleMouseMove = () => {
- clearTimeout(timerRef.current);
- setShowControls(true);
- setIsMouseVisible(true);
- timerRef.current = setTimeout(() => {
- setShowControls(false);
- setIsDropdownOpen(false);
- setIsMouseVisible(false);
- }, controlsDeactivationTime); // Adjust the timeout value according to your preference (in milliseconds)
- };
- const formatTime = (seconds) => {
- const date = new Date(null);
- date.setSeconds(seconds);
- if (date instanceof Date && !isNaN(date)) {
- // Checking for a valid date object.
- if (seconds > 3600) {
- return date.toISOString().slice(-13, -5);
- } else {
- return date.toISOString().slice(-10, -5);
- }
- }
- };
- useEffect(() => {
- if (typeof window !== "undefined") {
- setHasWindow(true);
- }
- const handleFullScreenChange = () => {
- setIsFullScreen(
- document.fullscreenElement === vidSectionRef.current
- );
- };
- // using debounce to prevent this from firing a lot of times if the arrow keys are pressed rapidly.
- const handleKeyPress = debounce((event) => {
- const activeElement = document.activeElement;
- const excludedTags = ["INPUT", "TEXTAREA", "SELECT"];
- if (
- excludedTags.includes(activeElement.tagName) &&
- !(activeElement.type === "range")
- ) {
- return;
- }
- switch (event.key) {
- case "f":
- toggleFullscreen();
- break;
- case " ":
- event.preventDefault();
- togglePlayState();
- handleMouseMove();
- break;
- default:
- break;
- }
- }, 250);
- document.addEventListener("keydown", handleKeyPress);
- document.addEventListener("fullscreenchange", handleFullScreenChange);
- // Cleanup
- return () => {
- document.removeEventListener(
- "fullscreenchange",
- handleFullScreenChange
- );
- document.removeEventListener("keydown", handleKeyPress);
- handleKeyPress.cancel();
- };
- }, []);
- useEffect(() => {
- if (vidSectionRef.current) {
- vidSectionRef.current.addEventListener(
- "mousemove",
- handleMouseMove
- );
- }
- return () => {
- if (vidSectionRef.current) {
- vidSectionRef.current.removeEventListener(
- "mousemove",
- handleMouseMove
- );
- }
- clearTimeout(timerRef.current);
- };
- }, [vidSectionRef.current]);
- const roomID = router.query.id;
- useEffect(() => {
- if (roomID) {
- // Use the socket ID to join the room
- // You can establish the socket connection here and join the room
- socket.current = io("http://localhost:8080");
- // Join a room using the socket ID
- socket.current.on("connect", () => {
- socket.current.emit("join-room", roomID, (response) => {
- if (response.success) {
- setIsRoomConnected(true);
- }
- });
- });
- socket.current.on("update-url", (roomID, url) => {
- setUrl(url);
- });
- socket.current.on("play-video", (roomID) => {
- setPlay(true);
- });
- socket.current.on("pause-video", (roomID) => {
- setPlay(false);
- });
- socket.current.on("update-progress", (roomID, progress) => {
- setPlaytime(Math.round(progress));
- if (playerRef.current) {
- playerRef.current.seekTo(progress, "seconds");
- }
- });
- socket.current.on("disconnect", () => {
- setUrl("");
- });
- }
- }, [roomID]);
- useEffect(() => {
- if (isPlayerReady && playerRef.current && playtime !== null) {
- playerRef.current.seekTo(playtime, "seconds");
- }
- }, [isPlayerReady, playtime]);
- const handleSubmit = () => {
- setUrl(urlInputRef.current.value);
- setFileUrl("");
- socket.current.emit("update-url", roomID, urlInputRef.current.value);
- };
- return (
- <main className="mb-5 mt-7 flex flex-col gap-6 px-5 md:flex-row">
- {/* Section 1: Video */}
- {isRoomConnected && (
- <div
- className={`flex w-full flex-col gap-2 md:w-2/3 ${
- isFullScreen
- ? isMouseVisible
- ? ""
- : "cursor-none"
- : ""
- }`}
- >
- <div>
- <Tab.Group>
- <Tab.List className="flex h-12 items-center gap-4 rounded-md bg-gray-200 p-2">
- <Tab as={Fragment}>
- {({ selected }) => (
- <button
- className={`${
- selected ? "bg-black/20" : ""
- } rounded-md px-2 py-1 outline-none transition-colors hover:bg-black/20`}
- >
- Video URL
- </button>
- )}
- </Tab>
- <Tab as={Fragment}>
- {({ selected }) => (
- <button
- className={`${
- selected ? "bg-black/20" : ""
- } rounded-md px-2 py-1 outline-none transition-colors hover:bg-black/20`}
- >
- Custom Video
- </button>
- )}
- </Tab>
- </Tab.List>
- <Tab.Panels>
- <Tab.Panel className="mt-2 flex gap-2">
- <input
- ref={urlInputRef}
- type="text"
- className="w-full rounded-md border border-gray-400 bg-transparent px-3 py-2 font-light text-white outline-none placeholder:font-light"
- placeholder="Enter Video URL here."
- />
- <button
- onClick={handleSubmit}
- className="rounded-md bg-red-600 px-2 py-1 text-white"
- >
- Submit
- </button>
- </Tab.Panel>
- <Tab.Panel className="mt-2">
- <label
- htmlFor="file-choose"
- className="cursor-pointer rounded-md bg-red-600 px-3 py-2 text-left text-white"
- >
- Choose File
- <input
- accept="video/*"
- onChange={(e) => {
- const file = e.target.files[0];
- if (file) {
- const videoUrl =
- URL.createObjectURL(
- file
- );
- setFileUrl(videoUrl);
- setUrl("");
- }
- }}
- id="file-choose"
- type="file"
- className="w-0 opacity-0"
- />
- </label>
- </Tab.Panel>
- </Tab.Panels>
- </Tab.Group>
- </div>
- <section
- ref={vidSectionRef}
- className="relative flex w-full select-none flex-col gap-3"
- >
- {hasWindow && (
- <>
- {url && (
- <ReactPlayer
- ref={playerRef}
- url={url}
- onReady={handlePlayerReady}
- config={{
- youtube: {
- playerVars: { disablekb: 1 },
- },
- }}
- className="pointer-events-none aspect-video"
- width="100%"
- height="100%"
- playing={play}
- onProgress={handleProgressChange}
- onPlay={handleOnPlay}
- onPause={handleOnPause}
- volume={volume}
- playbackRate={speed}
- />
- )}
- {fileUrl && (
- <ReactPlayer
- ref={playerRef}
- url={fileUrl}
- onReady={handlePlayerReady}
- className="pointer-events-none aspect-video"
- width="100%"
- height="100%"
- playing={play}
- onProgress={handleProgressChange}
- onPlay={() => setPlay(true)}
- onPause={() => setPlay(false)}
- volume={volume}
- playbackRate={speed}
- config={{
- file: {
- attributes: { controls: false },
- },
- }}
- />
- )}
- </>
- )}
- {/* Controls */}
- {isPlayerReady &&
- ReactPlayer.canPlay(url) |
- ReactPlayer.canPlay(fileUrl) &&
- playerRef.current && (
- <div
- className={`${
- showControls && "opacity-100"
- } absolute bottom-0 flex w-full flex-col items-center gap-3 bg-gradient-to-t from-black via-black/70 to-transparent px-3 py-1 opacity-0 transition-opacity duration-300 md:px-5 md:py-2`}
- >
- <input
- className="range-input w-full accent-red-600"
- type="range"
- min={0}
- max={playerRef.current.getDuration()}
- onChange={handleRangeChange}
- ref={rangeInputRef}
- />
- <div className="flex w-full items-center gap-3">
- <button onClick={() => setPlay(!play)}>
- {play ? (
- <BsPauseFill className="text-3xl text-white" />
- ) : (
- <BsFillPlayFill className="text-3xl text-white" />
- )}
- </button>
- <button className="hidden md:block">
- {volume > 0.5 ? (
- <BsVolumeUpFill className="text-3xl text-white" />
- ) : volume > 0 ? (
- <BsVolumeDownFill className="text-3xl text-white" />
- ) : (
- <BsVolumeMuteFill className="text-3xl text-white" />
- )}
- </button>
- <input
- className="volume-input hidden w-1/5 accent-red-600 md:block"
- type="range"
- min={0}
- max={1}
- step={"0.01"}
- ref={volumeInputRef}
- onChange={handleVolumeChange}
- />
- <span
- className={`${poppins.className} mr-auto text-sm text-white`}
- >
- {formatTime(playtime)} /{" "}
- {formatTime(
- playerRef.current.getDuration()
- )}
- </span>
- <div className="absolute bottom-10 right-5">
- <DropdownMenu />
- </div>
- <button
- onClick={() => {
- setIsDropdownOpen(
- (prevState) => !prevState
- );
- setActiveMenu("main");
- }}
- >
- <MdSettings className="text-2xl text-white" />
- </button>
- <button
- ref={fullScreenBtnRef}
- onClick={handleFullScreen}
- // className="ml-auto"
- >
- {isFullScreen ? (
- <BsFullscreenExit className="text-xl text-white" />
- ) : (
- <BsFullscreen className=" text-xl text-white" />
- )}
- </button>
- </div>
- </div>
- )}
- </section>
- </div>
- )}
- </main>
- );
- };
Advertisement
Add Comment
Please, Sign In to add comment