import "./styles.sass"; import {SocketContext} from "@/common/contexts/SocketContext"; import {useContext, useState, useEffect, useRef, useCallback} from "react"; import MusicSlider from "@/pages/Game/components/MusicSlider"; import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; import {faMessage, faMusic, faHeadphones, faClock, faCrown, faPaperPlane} from "@fortawesome/free-solid-svg-icons"; export const Game = () => { const {send, on, socket, connected, connect} = useContext(SocketContext); useEffect(() => { if (!connected) { connect(); } }, [connected, connect]); const [role, setRole] = useState(null); const [round, setRound] = useState(1); const [phase, setPhase] = useState("waiting"); const [timeLeft, setTimeLeft] = useState(30); const [frequency, setFrequency] = useState(440); const [currentSong, setCurrentSong] = useState(null); const [songOptions, setSongOptions] = useState([]); const [scores, setScores] = useState({}); const [selectedSong, setSelectedSong] = useState(null); const [guessResult, setGuessResult] = useState(null); const [isHost, setIsHost] = useState(false); const [hasGuessed, setHasGuessed] = useState(false); const [messages, setMessages] = useState([]); const [inputValue, setInputValue] = useState(""); const [connectedUsers, setConnectedUsers] = useState([]); const [username, setUsername] = useState(""); const messageEndRef = useRef(null); const timerIntervalRef = useRef(null); useEffect(() => { if (!connected) return; const eventHandlers = { "roles-assigned": (roles) => { const myRole = roles[socket?.id]; if (myRole) { setRole(myRole); setMessages(prev => [...prev, { system: true, text: myRole === "composer" ? "Du bist der Komponist! Spiele den Song mit dem Tonregler." : "Du bist ein Rater! Höre die Frequenzen und versuche, den Song zu erkennen." }]); } }, "song-selected": setCurrentSong, "round-started": (data) => { setRound(data.round); setPhase("composing"); setTimeLeft(data.timeRemaining); }, "guessing-phase-started": (data) => { console.log("Guessing phase started:", data); setPhase("guessing"); setTimeLeft(data.timeRemaining); setSongOptions(data.songOptions || []); }, "guess-result": (result) => { setGuessResult(result.isCorrect); setCurrentSong(result.correctSong); }, "round-results": (results) => { setPhase("results"); setScores(results.scores); if (!currentSong) { setCurrentSong(results.selectedSong); } }, "room-users-update": (users) => { setConnectedUsers(users); const currentUser = users.find(u => u.id === socket?.id); if (currentUser) setUsername(currentUser.name); }, "host-status": (status) => setIsHost(status.isHost), "chat-message": (msg) => setMessages(prev => [...prev, msg]), "user-connected": (userData) => { setMessages(prev => [...prev, { system: true, text: `${userData.name} ist beigetreten` }]); setConnectedUsers(prev => [...prev, userData]); }, "user-disconnected": (userId) => { setConnectedUsers(prev => { const user = prev.find(u => u.id === userId); if (user) { setMessages(prevMsgs => [...prevMsgs, { system: true, text: `${user.name} hat den Raum verlassen` }]); } return prev.filter(u => u.id !== userId); }); }, "frequency-update": (data) => { if (phase === "composing") { console.log("Received frequency update:", data.frequency); setFrequency(data.frequency); } }, "phase-changed": (data) => { console.log("Phase changed:", data); setPhase(data.phase); if (data.timeRemaining) { setTimeLeft(data.timeRemaining); } } }; const cleanupFunctions = Object.entries(eventHandlers).map( ([event, handler]) => on(event, handler) ); if (connected) { send("get-room-users"); send("check-host-status"); } return () => cleanupFunctions.forEach(cleanup => cleanup()); }, [socket, on, send, role, currentSong, phase, connected]); useEffect(() => { if (timerIntervalRef.current) clearInterval(timerIntervalRef.current); if (phase !== "waiting" && phase !== "results") { timerIntervalRef.current = setInterval(() => { setTimeLeft(prev => Math.max(0, prev - 1)); }, 1000); } return () => { if (timerIntervalRef.current) clearInterval(timerIntervalRef.current); }; }, [phase]); useEffect(() => { messageEndRef.current?.scrollIntoView({behavior: "smooth"}); }, [messages]); const handleFrequencyChange = useCallback((newFrequency) => { setFrequency(newFrequency); if (role === "composer") { send("submit-frequency", { frequency: newFrequency }); } }, [role, send]); const handleSendMessage = useCallback(() => { if (inputValue.trim()) { const messageData = { text: inputValue, sender: username }; send("send-message", messageData); setMessages(prev => [...prev, messageData]); setInputValue(""); } }, [inputValue, username, send]); const handleSongSelect = useCallback((song) => { setSelectedSong(song); }, []); const handleSubmitGuess = useCallback(() => { if (!selectedSong || phase !== 'guessing') return; console.log("Submitting guess:", selectedSong.id); send("submit-guess", { songId: selectedSong.id }); setMessages(prev => [...prev, { system: true, text: `Du hast "${selectedSong.title}" von ${selectedSong.artist} gewählt.` }]); setHasGuessed(true); }, [selectedSong, send, phase]); const handleNextRound = useCallback(() => { send("next-round"); setSelectedSong(null); setGuessResult(null); setTimeLeft(0); }, [send]); // Phase-specific content rendering const renderPhaseContent = () => { switch (phase) { case "waiting": return (
Spiele diesen Song mit dem Tonregler!
Höre genau zu und versuche, den Song zu erkennen!
Die Rater versuchen nun, deinen Song zu erraten...
Welchen Song hat der Komponist gespielt?
{songOptions.length === 0 ? (Lade Songoptionen...
Deine Antwort wurde eingereicht!
) : ( )}Die Rater haben versucht, deinen Song zu erraten.
Der richtige Song war:
Warten auf Rundenwechsel durch Host...
)}