import React, { useState, useEffect } from "react"; import Navbar from "../components/Navigation/Navbar"; import { ToggleButton } from "../components/Input/Button"; import ChatPanel from "../components/Video/ChatPanel"; import { useNavigate, useParams } from "react-router-dom"; import { useAuthModal } from "../hooks/useAuthModal"; import { useAuth } from "../context/AuthContext"; import { useFollow } from "../hooks/useFollow"; import VideoPlayer from "../components/Video/VideoPlayer"; import { SocketProvider } from "../context/SocketContext"; import AuthModal from "../components/Auth/AuthModal"; import CheckoutForm, { Return } from "../components/Checkout/CheckoutForm"; interface VideoPageProps { streamerId: number; } interface StreamDataProps { streamTitle: string; streamerName: string; startTime: string; categoryName: string; } const VideoPage: React.FC = ({ streamerId }) => { const { isLoggedIn } = useAuth(); const { streamerName } = useParams<{ streamerName: string }>(); const [streamData, setStreamData] = useState(); const [viewerCount, setViewerCount] = useState(0); const [isChatOpen, setIsChatOpen] = useState(true); const [isInputFocused, setIsInputFocused] = useState(false); const { isFollowing, checkFollowStatus, followUser, unfollowUser } = useFollow(); const { showAuthModal, setShowAuthModal } = useAuthModal(); const [showCheckout, setShowCheckout] = useState(false); const showReturn = window.location.search.includes("session_id"); const navigate = useNavigate(); useEffect(() => { // Prevent scrolling when checkout is open if (showCheckout) { document.body.style.overflow = "hidden"; } else { document.body.style.overflow = "unset"; } // Cleanup function to ensure overflow is restored when component unmounts return () => { document.body.style.overflow = "unset"; }; }, [showCheckout]); useEffect(() => { // Fetch stream data for this streamer fetch(`/api/streams/${streamerId}/data`).then((res) => { if (!res.ok) { console.error("Failed to load stream data:", res.statusText); } res .json() .then((data) => { // Transform snake_case to camelCase const transformedData: StreamDataProps = { streamerName: data.username, streamTitle: data.title, startTime: data.start_time, categoryName: data.category_name, }; setStreamData(transformedData); // Check if the logged-in user is following this streamer if (isLoggedIn) checkFollowStatus(data.username); }) .catch((error) => { console.error("Error fetching stream data:", error); }); }); }, [streamerId]); // Keyboard shortcut to toggle chat useEffect(() => { const handleKeyPress = (e: KeyboardEvent) => { if (e.key === "c" && !isInputFocused) { setIsChatOpen((prev) => !prev); } }; document.addEventListener("keydown", handleKeyPress); return () => { document.removeEventListener("keydown", handleKeyPress); }; }, [isInputFocused]); const toggleChat = () => { setIsChatOpen((prev) => !prev); }; return (
{isChatOpen ? "Hide Chat" : "Show Chat"} Press C setViewerCount(count)} onInputFocus={setIsInputFocused} />
{/* Stream Data */}
{/* Streamer Icon */}
streamer profile picture navigate(`/user/${streamerName}`)} />
{/* Stream Title */}

{streamData ? streamData.streamTitle : "Loading..."}

{streamData ? streamData.categoryName : "Loading..."}
{/* Streamer Info */}
{!isFollowing ? ( ) : ( )}
{/* Stream Stats */}
Viewers Icon {viewerCount}
Started {streamData ? `${Math.floor( (Date.now() - new Date(streamData.startTime).getTime()) / 3600000 )} hours ago` : "Loading..."}
{/* Subscribe Button */}
{showCheckout && ( setShowCheckout(false)} streamerID={streamerId} /> )} {showReturn && } {showAuthModal && setShowAuthModal(false)} />}
); }; export default VideoPage;