Refactor draft messaging to unified enum-based protocol
- Replaced scattered message strings with `DraftMessage` `StrEnum` and numeric `DraftPhase` `IntEnum` for clear, centralized definitions. - Added Python→JS constants sync via `scripts/generate_js_constants.py` to ensure backend/frontend parity. - Refactored WebSocket consumers to use `broadcast.*` and `direct.message` handlers with `_dispatch_broadcast` for consistent event delivery. - Enhanced `DraftStateManager` to store `draft_index` and explicitly manage `connected_participants`. - Added colored logging config in settings for improved debugging. - Frontend: split UI into `ParticipantList` and `DraftMoviePool`, extracted message handlers (`handleDraftStatusMessages`, `handleUserIdentifyMessages`), and updated components to use new message/phase enums.
This commit is contained in:
@@ -3,29 +3,18 @@ import React, { useEffect, useState } from "react";
|
||||
|
||||
import { useWebSocket } from "../WebSocketContext.jsx";
|
||||
import { WebSocketStatus } from "../common/WebSocketStatus.jsx";
|
||||
import { DraftMessage, DraftPhases } from '../constants.js';
|
||||
import { fetchDraftDetails } from "../common/utils.js"
|
||||
import { DraftMessage, DraftPhases} from '../constants.js';
|
||||
import { fetchDraftDetails } from "../common/utils.js";
|
||||
import { DraftMoviePool } from "../common/DraftMoviePool.jsx";
|
||||
import { ParticipantList } from "../common/ParticipantList.jsx";
|
||||
import { handleDraftStatusMessages } from '../common/utils.js'
|
||||
|
||||
const DraftMoviePool = ({ movies }) => {
|
||||
return (
|
||||
<div className="movie-pool-container">
|
||||
<ul>
|
||||
{movies.map(m => (
|
||||
<li id={m?.id}>
|
||||
<a href={`/api/movie/${m.id}/detail`}>
|
||||
{m.title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const DraftParticipant = ({ draftSessionId }) => {
|
||||
const socket = useWebSocket();
|
||||
const [participants, setParticipants] = useState([]);
|
||||
const [draftPhase, setDraftPhase] = useState();
|
||||
const [draftState, setDraftState] = useState({});
|
||||
const [draftDetails, setDraftDetails] = useState({});
|
||||
|
||||
const [movies, setMovies] = useState([]);
|
||||
console.log(socket)
|
||||
|
||||
@@ -34,65 +23,41 @@ export const DraftParticipant = ({ draftSessionId }) => {
|
||||
.then((data) => {
|
||||
console.log("Fetched draft data", data)
|
||||
setMovies(data.movies)
|
||||
setDraftDetails(data)
|
||||
})
|
||||
}, [])
|
||||
}, [draftSessionId])
|
||||
|
||||
useEffect(()=>{
|
||||
if (!socket) return;
|
||||
socket.onclose = (event) => {
|
||||
console.log('Websocket Closed')
|
||||
}
|
||||
}, [socket])
|
||||
|
||||
useEffect(() => {
|
||||
if (!socket) return;
|
||||
else {
|
||||
console.warn("socket doesn't exist")
|
||||
}
|
||||
console.log('socket created', socket)
|
||||
|
||||
const handleMessage = (event) => {
|
||||
const message = JSON.parse(event.data)
|
||||
const { type, payload } = message;
|
||||
console.log(type, event)
|
||||
if (type == DraftMessage.REQUEST.JOIN_PARTICIPANT) {
|
||||
console.log('join request', data)
|
||||
}
|
||||
else if (type == DraftMessage.CONFIRM.JOIN_PARTICIPANT) {
|
||||
setConnectedParticipants(data.connected_participants)
|
||||
}
|
||||
else if (type == DraftMessage.CONFIRM.PHASE_CHANGE || type == DraftMessage.INFORM.PHASE) {
|
||||
console.log('phase_change')
|
||||
setDraftPhase(payload.phase)
|
||||
}
|
||||
}
|
||||
|
||||
socket.addEventListener('message', handleMessage);
|
||||
|
||||
socket.onclose = (event) => {
|
||||
console.log('Websocket Closed')
|
||||
socket = null;
|
||||
}
|
||||
const handler = (event) => handleDraftStatusMessages(event, setDraftState)
|
||||
socket.addEventListener('message', handler );
|
||||
|
||||
return () => {
|
||||
socket.removeEventListener('message', handleMessage)
|
||||
socket.addEventListener('message', handler );
|
||||
socket.close();
|
||||
};
|
||||
}, [socket]);
|
||||
|
||||
const handlePhaseChange = (destinationPhase) => {
|
||||
socket.send(
|
||||
JSON.stringify({ type: DraftMessage.REQUEST.PHASE_CHANGE, "destination": destinationPhase })
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const handleRequestDraftSummary = () => {
|
||||
socket.send(JSON.stringify({ type: 'request_summary' }))
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container draft-panel">
|
||||
<div className="d-flex justify-content-between border-bottom mb-2 p-1">
|
||||
<h3>Draft Panel</h3>
|
||||
<WebSocketStatus socket={socket} />
|
||||
</div>
|
||||
|
||||
<DraftMoviePool movies={movies}></DraftMoviePool>
|
||||
<ParticipantList
|
||||
draftState={draftState}
|
||||
draftDetails={draftDetails}
|
||||
isAdmin={false}
|
||||
/>
|
||||
<DraftMoviePool draftDetails={draftDetails}></DraftMoviePool>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user