fixes
This commit is contained in:
parent
625c5837ee
commit
35c5fb8cd8
5 changed files with 55 additions and 18 deletions
|
|
@ -305,7 +305,14 @@ export class GameGateway implements OnGatewayConnection, OnGatewayDisconnect, On
|
|||
const isHost = await this.isHost(payload.roomId, payload.userId);
|
||||
const isCurrentPlayer = room.currentPlayerId === payload.participantId;
|
||||
|
||||
if (!isHost && !isCurrentPlayer) {
|
||||
// Только хост может открывать ответы
|
||||
if (payload.action === 'revealAnswer' && !isHost) {
|
||||
client.emit('error', { message: 'Only the host can reveal answers' });
|
||||
return;
|
||||
}
|
||||
|
||||
// Для других действий проверяем права (хост или текущий игрок)
|
||||
if (payload.action !== 'revealAnswer' && !isHost && !isCurrentPlayer) {
|
||||
client.emit('error', { message: 'Not your turn!' });
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ export class RoomsService {
|
|||
include: {
|
||||
host: true,
|
||||
participants: {
|
||||
where: { isActive: true },
|
||||
orderBy: { joinedAt: 'asc' },
|
||||
include: { user: true },
|
||||
},
|
||||
questionPack: true,
|
||||
|
|
@ -133,12 +135,14 @@ export class RoomsService {
|
|||
},
|
||||
});
|
||||
|
||||
// Получаем обновленную комнату со всеми участниками
|
||||
// Получаем обновленную комнату со всеми активными участниками
|
||||
const updatedRoom = await this.prisma.room.findUnique({
|
||||
where: { id: roomId },
|
||||
include: {
|
||||
host: true,
|
||||
participants: {
|
||||
where: { isActive: true },
|
||||
orderBy: { joinedAt: 'asc' },
|
||||
include: { user: true },
|
||||
},
|
||||
questionPack: true,
|
||||
|
|
@ -221,12 +225,14 @@ export class RoomsService {
|
|||
},
|
||||
});
|
||||
|
||||
// Получаем обновленную комнату со всеми участниками
|
||||
// Получаем обновленную комнату со всеми активными участниками
|
||||
const updatedRoom = await this.prisma.room.findUnique({
|
||||
where: { id: roomId },
|
||||
include: {
|
||||
host: true,
|
||||
participants: {
|
||||
where: { isActive: true },
|
||||
orderBy: { joinedAt: 'asc' },
|
||||
include: { user: true },
|
||||
},
|
||||
questionPack: true,
|
||||
|
|
@ -291,6 +297,8 @@ export class RoomsService {
|
|||
include: {
|
||||
host: true,
|
||||
participants: {
|
||||
where: { isActive: true },
|
||||
orderBy: { joinedAt: 'asc' },
|
||||
include: { user: true },
|
||||
},
|
||||
questionPack: true,
|
||||
|
|
@ -320,6 +328,8 @@ export class RoomsService {
|
|||
include: {
|
||||
host: true,
|
||||
participants: {
|
||||
where: { isActive: true },
|
||||
orderBy: { joinedAt: 'asc' },
|
||||
include: { user: true },
|
||||
},
|
||||
questionPack: true,
|
||||
|
|
@ -367,6 +377,8 @@ export class RoomsService {
|
|||
include: {
|
||||
host: true,
|
||||
participants: {
|
||||
where: { isActive: true },
|
||||
orderBy: { joinedAt: 'asc' },
|
||||
include: { user: true },
|
||||
},
|
||||
questionPack: true,
|
||||
|
|
@ -404,9 +416,13 @@ export class RoomsService {
|
|||
include: {
|
||||
host: true,
|
||||
participants: {
|
||||
where: { isActive: true },
|
||||
orderBy: { joinedAt: 'asc' },
|
||||
include: { user: true },
|
||||
},
|
||||
questionPack: true,
|
||||
roomPack: true,
|
||||
theme: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -424,9 +440,13 @@ export class RoomsService {
|
|||
include: {
|
||||
host: true,
|
||||
participants: {
|
||||
where: { isActive: true },
|
||||
orderBy: { joinedAt: 'asc' },
|
||||
include: { user: true },
|
||||
},
|
||||
questionPack: true,
|
||||
roomPack: true,
|
||||
theme: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -445,6 +465,8 @@ export class RoomsService {
|
|||
include: {
|
||||
host: true,
|
||||
participants: {
|
||||
where: { isActive: true },
|
||||
orderBy: { joinedAt: 'asc' },
|
||||
include: { user: true },
|
||||
},
|
||||
questionPack: true,
|
||||
|
|
@ -537,12 +559,14 @@ export class RoomsService {
|
|||
data: { role: newRole },
|
||||
});
|
||||
|
||||
// Получаем обновленную комнату со всеми участниками
|
||||
// Получаем обновленную комнату со всеми активными участниками
|
||||
const room = await this.prisma.room.findUnique({
|
||||
where: { id: roomId },
|
||||
include: {
|
||||
host: true,
|
||||
participants: {
|
||||
where: { isActive: true },
|
||||
orderBy: { joinedAt: 'asc' },
|
||||
include: { user: true },
|
||||
},
|
||||
questionPack: true,
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.question-box {
|
||||
|
|
@ -130,8 +130,9 @@
|
|||
grid-auto-rows: minmax(auto, clamp(120px, 18vh, 200px));
|
||||
column-gap: clamp(6px, 1.2vw, 12px);
|
||||
row-gap: clamp(6px, 0.8vh, 12px);
|
||||
flex: 1 1 0;
|
||||
flex: 0 1 auto;
|
||||
min-height: 0;
|
||||
max-height: 100%;
|
||||
overflow-y: auto;
|
||||
align-content: start;
|
||||
/* Scrollbar styling */
|
||||
|
|
|
|||
|
|
@ -175,20 +175,13 @@ const GamePage = () => {
|
|||
// === Handlers для действий игрока ===
|
||||
|
||||
const handleAnswerClick = (answerId, points) => {
|
||||
if (!gameState.roomId || !user || !canPerformActions) return;
|
||||
if (!gameState.roomId || !user) return;
|
||||
|
||||
const myParticipant = gameState.participants.find(p => p.userId === user.id);
|
||||
if (!myParticipant) return;
|
||||
|
||||
// Зрители не могут отвечать на вопросы
|
||||
if (isSpectator) {
|
||||
alert('Зрители не могут отвечать на вопросы');
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверка очереди (только для не-хостов)
|
||||
if (!isHost && gameState.currentPlayerId !== myParticipant.id) {
|
||||
alert('Сейчас не ваша очередь!');
|
||||
// Только хост может кликать на ответы
|
||||
if (!isHost) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -550,7 +543,7 @@ const GamePage = () => {
|
|||
revealedAnswers={revealedForCurrentQ}
|
||||
playerScores={playerScores}
|
||||
currentPlayerId={gameState.currentPlayerId}
|
||||
onAnswerClick={canPerformActions ? handleAnswerClick : null}
|
||||
onAnswerClick={isHost ? handleAnswerClick : null}
|
||||
onPreviousQuestion={isHost && canGoPrev ? handlePrevQuestion : null}
|
||||
onNextQuestion={isHost && canGoNext ? handleNextQuestion : null}
|
||||
onSelectPlayer={isHost ? handleSelectPlayer : null}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@ const RoomPage = () => {
|
|||
const [selectedRole, setSelectedRole] = useState('PLAYER');
|
||||
const [questionPacks, setQuestionPacks] = useState([]);
|
||||
|
||||
// Ref для отслеживания попытки присоединения (защита от двойного запроса)
|
||||
const joinAttemptedRef = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
const generateQR = async () => {
|
||||
try {
|
||||
|
|
@ -131,19 +134,25 @@ const RoomPage = () => {
|
|||
const isParticipant = participants.some((p) => p.userId === user.id);
|
||||
if (isParticipant) {
|
||||
setJoined(true);
|
||||
joinAttemptedRef.current = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Защита от повторной попытки присоединения
|
||||
if (joinAttemptedRef.current) return;
|
||||
|
||||
// Если зрители разрешены, показываем модальное окно выбора роли
|
||||
if (room.allowSpectators) {
|
||||
if (!isRoleSelectionModalOpen) {
|
||||
setIsRoleSelectionModalOpen(true);
|
||||
joinAttemptedRef.current = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Если зрители не разрешены, автоматически присоединяемся как PLAYER
|
||||
// Присоединение разрешено независимо от статуса игры (WAITING, PLAYING, FINISHED)
|
||||
joinAttemptedRef.current = true;
|
||||
try {
|
||||
setJoinError(null);
|
||||
await joinRoom(room.id, user.id, user.name || 'Гость', 'PLAYER');
|
||||
|
|
@ -154,6 +163,8 @@ const RoomPage = () => {
|
|||
const errorMessage = error.response?.data?.message || error.message || 'Ошибка при присоединении к комнате';
|
||||
setJoinError(errorMessage);
|
||||
alert(errorMessage);
|
||||
// Сбрасываем флаг при ошибке, чтобы можно было попробовать снова
|
||||
joinAttemptedRef.current = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -177,7 +188,8 @@ const RoomPage = () => {
|
|||
const errorMessage = error.response?.data?.message || error.message || 'Ошибка при присоединении к комнате';
|
||||
setJoinError(errorMessage);
|
||||
alert(errorMessage);
|
||||
// Открываем модальное окно снова при ошибке
|
||||
// Сбрасываем флаг и открываем модальное окно снова при ошибке
|
||||
joinAttemptedRef.current = false;
|
||||
setIsRoleSelectionModalOpen(true);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue