From 5cabdba72f20d67030c90cf360ed7c0a57f34f4d Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 9 Jan 2026 01:56:11 +0300 Subject: [PATCH] users fix --- backend/src/game/game.gateway.ts | 58 ++++++++++++++++++++++++++++++-- src/components/Game.jsx | 2 ++ src/components/Players.jsx | 4 +-- src/pages/GamePage.jsx | 13 +++++++ 4 files changed, 72 insertions(+), 5 deletions(-) diff --git a/backend/src/game/game.gateway.ts b/backend/src/game/game.gateway.ts index e578408..c920ee9 100644 --- a/backend/src/game/game.gateway.ts +++ b/backend/src/game/game.gateway.ts @@ -121,7 +121,10 @@ export class GameGateway implements OnGatewayConnection, OnGatewayDisconnect, On if (room) { const questions = ((room.roomPack as unknown as { questions?: Question[] } | null)?.questions || []) as Question[]; const firstQuestion = questions[0]; - const firstParticipant = room.participants[0]; + + // Админ (хост) должен быть первым игроком + const hostParticipant = room.participants.find(p => p.userId === room.hostId); + const firstParticipant = hostParticipant || room.participants[0]; // Убеждаемся что firstQuestion.id - строка (UUID) const firstQuestionId = firstQuestion?.id && typeof firstQuestion.id === 'string' @@ -348,12 +351,28 @@ export class GameGateway implements OnGatewayConnection, OnGatewayDisconnect, On } } + // Инициализация currentPlayerId если не установлен + let currentPlayerId = room.currentPlayerId; + if (!currentPlayerId && room.participants.length > 0) { + // Админ (хост) должен быть первым игроком + const hostParticipant = room.participants.find(p => p.userId === room.hostId); + const firstParticipant = hostParticipant || room.participants[0]; + + if (firstParticipant) { + currentPlayerId = firstParticipant.id; + await this.prisma.room.update({ + where: { id: room.id }, + data: { currentPlayerId: currentPlayerId } + }); + } + } + const fullState = { roomId: room.id, roomCode: room.code, status: room.status, currentQuestionId: currentQuestionId, - currentPlayerId: room.currentPlayerId, + currentPlayerId: currentPlayerId, revealedAnswers: room.revealedAnswers as RevealedAnswers, isGameOver: room.isGameOver, hostId: room.hostId, @@ -414,7 +433,10 @@ export class GameGateway implements OnGatewayConnection, OnGatewayDisconnect, On if (room) { const questions = ((room.roomPack as unknown as { questions?: Question[] } | null)?.questions || []) as Question[]; const firstQuestion = questions[0]; - const firstParticipant = room.participants[0]; + + // Админ (хост) должен быть первым игроком + const hostParticipant = room.participants.find(p => p.userId === room.hostId); + const firstParticipant = hostParticipant || room.participants[0]; // Убеждаемся что firstQuestion.id - строка (UUID) const firstQuestionId = firstQuestion?.id && typeof firstQuestion.id === 'string' @@ -443,6 +465,36 @@ export class GameGateway implements OnGatewayConnection, OnGatewayDisconnect, On await this.broadcastFullState(payload.roomCode); } + @SubscribeMessage('setCurrentPlayer') + async handleSetCurrentPlayer(client: Socket, payload: { roomId: string; roomCode: string; userId: string; participantId: string }) { + const isHost = await this.isHost(payload.roomId, payload.userId); + if (!isHost) { + client.emit('error', { message: 'Only the host can set current player' }); + return; + } + + // Проверяем, что участник существует и активен + const participant = await this.prisma.participant.findFirst({ + where: { + id: payload.participantId, + roomId: payload.roomId, + isActive: true + } + }); + + if (!participant) { + client.emit('error', { message: 'Participant not found' }); + return; + } + + await this.prisma.room.update({ + where: { id: payload.roomId }, + data: { currentPlayerId: payload.participantId } + }); + + await this.broadcastFullState(payload.roomCode); + } + @SubscribeMessage('updateRoomPack') async handleUpdateRoomPack(client: Socket, payload: { roomId: string; roomCode: string; userId: string; questions: any[] }) { const isHost = await this.isHost(payload.roomId, payload.userId); diff --git a/src/components/Game.jsx b/src/components/Game.jsx index 5e1babe..3c5d0c1 100644 --- a/src/components/Game.jsx +++ b/src/components/Game.jsx @@ -13,6 +13,7 @@ const Game = forwardRef(({ onAnswerClick = null, onPreviousQuestion = null, onNextQuestion = null, + onSelectPlayer = null, }, ref) => { // Нет локального state - всё из props! // Нет useEffect - нет синхронизации! @@ -42,6 +43,7 @@ const Game = forwardRef(({ players={players} currentPlayerId={currentPlayerId} playerScores={playerScores} + onSelectPlayer={onSelectPlayer} /> )} diff --git a/src/components/Players.jsx b/src/components/Players.jsx index 98559ee..5086007 100644 --- a/src/components/Players.jsx +++ b/src/components/Players.jsx @@ -13,8 +13,8 @@ const Players = ({ players, currentPlayerId, playerScores, onSelectPlayer }) => return (
onSelectPlayer(player.id)} + className={`player-item ${isActive ? 'player-active' : ''} ${onSelectPlayer ? 'player-clickable' : ''}`} + onClick={() => onSelectPlayer && onSelectPlayer(player.id)} > {player.name} {score} diff --git a/src/pages/GamePage.jsx b/src/pages/GamePage.jsx index 01b6b41..d11b9dc 100644 --- a/src/pages/GamePage.jsx +++ b/src/pages/GamePage.jsx @@ -249,6 +249,18 @@ const GamePage = () => { console.warn('Manual point award not implemented yet'); }; + const handleSelectPlayer = (participantId) => { + if (!gameState.roomId || !user) return; + if (!isHost) return; // Только хост может выбирать игрока + + socketService.emit('setCurrentPlayer', { + roomId: gameState.roomId, + roomCode: gameState.roomCode, + userId: user.id, + participantId: participantId + }); + }; + // === Вычисляемые значения === const currentQuestion = gameState.questions.find( @@ -341,6 +353,7 @@ const GamePage = () => { onAnswerClick={handleAnswerClick} onPreviousQuestion={canGoPrev ? handlePrevQuestion : null} onNextQuestion={canGoNext ? handleNextQuestion : null} + onSelectPlayer={isHost ? handleSelectPlayer : null} />