Show host and early stop
This commit is contained in:
parent
1d8c08a680
commit
eee3e7e47b
3 changed files with 34 additions and 6 deletions
1
App.tsx
1
App.tsx
|
|
@ -182,6 +182,7 @@ function App() {
|
||||||
onStart={startGame}
|
onStart={startGame}
|
||||||
onEndGame={role === 'HOST' ? endGame : undefined}
|
onEndGame={role === 'HOST' ? endGame : undefined}
|
||||||
currentPlayerId={currentPlayerId}
|
currentPlayerId={currentPlayerId}
|
||||||
|
hostParticipates={gameConfig.hostParticipates}
|
||||||
/>
|
/>
|
||||||
{auth.isAuthenticated && pendingQuizToSave && (
|
{auth.isAuthenticated && pendingQuizToSave && (
|
||||||
<SaveQuizPrompt
|
<SaveQuizPrompt
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,12 @@ interface LobbyProps {
|
||||||
onStart: () => void;
|
onStart: () => void;
|
||||||
onEndGame?: () => void;
|
onEndGame?: () => void;
|
||||||
currentPlayerId?: string | null;
|
currentPlayerId?: string | null;
|
||||||
|
hostParticipates?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Lobby: React.FC<LobbyProps> = ({ quizTitle, players, gamePin, role, onStart, onEndGame, currentPlayerId }) => {
|
export const Lobby: React.FC<LobbyProps> = ({ quizTitle, players, gamePin, role, onStart, onEndGame, currentPlayerId, hostParticipates = false }) => {
|
||||||
const isHost = role === 'HOST';
|
const isHost = role === 'HOST';
|
||||||
|
const hostPlayer = players.find(p => p.id === 'host');
|
||||||
const realPlayers = players.filter(p => p.id !== 'host');
|
const realPlayers = players.filter(p => p.id !== 'host');
|
||||||
const currentPlayer = currentPlayerId ? players.find(p => p.id === currentPlayerId) : null;
|
const currentPlayer = currentPlayerId ? players.find(p => p.id === currentPlayerId) : null;
|
||||||
|
|
||||||
|
|
@ -48,7 +50,7 @@ export const Lobby: React.FC<LobbyProps> = ({ quizTitle, players, gamePin, role,
|
||||||
<>
|
<>
|
||||||
<div className="flex flex-wrap gap-3 md:gap-4 justify-center w-full max-w-6xl pb-24 md:pb-28 overflow-y-auto content-start">
|
<div className="flex flex-wrap gap-3 md:gap-4 justify-center w-full max-w-6xl pb-24 md:pb-28 overflow-y-auto content-start">
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{realPlayers.length === 0 && (
|
{realPlayers.length === 0 && !hostParticipates && (
|
||||||
<div className="flex flex-col items-center opacity-60 mt-8 md:mt-12">
|
<div className="flex flex-col items-center opacity-60 mt-8 md:mt-12">
|
||||||
<div className="bg-white/10 p-4 md:p-6 rounded-full mb-4 animate-bounce">
|
<div className="bg-white/10 p-4 md:p-6 rounded-full mb-4 animate-bounce">
|
||||||
<Sparkles size={36} className="md:w-12 md:h-12" />
|
<Sparkles size={36} className="md:w-12 md:h-12" />
|
||||||
|
|
@ -56,6 +58,19 @@ export const Lobby: React.FC<LobbyProps> = ({ quizTitle, players, gamePin, role,
|
||||||
<div className="text-xl md:text-3xl font-bold font-display text-center px-4">Waiting for players to join...</div>
|
<div className="text-xl md:text-3xl font-bold font-display text-center px-4">Waiting for players to join...</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{hostParticipates && hostPlayer && (
|
||||||
|
<motion.div
|
||||||
|
key="host"
|
||||||
|
initial={{ scale: 0, rotate: -10 }}
|
||||||
|
animate={{ scale: 1, rotate: 0 }}
|
||||||
|
exit={{ scale: 0, opacity: 0 }}
|
||||||
|
className="bg-yellow-400 text-black px-4 md:px-6 py-2 md:py-3 rounded-full font-black text-base md:text-xl shadow-[0_4px_0_rgba(0,0,0,0.2)] flex items-center gap-2 md:gap-3 border-b-4 border-yellow-500"
|
||||||
|
>
|
||||||
|
<PlayerAvatar seed={hostPlayer.avatarSeed} size={20} />
|
||||||
|
{hostPlayer.name}
|
||||||
|
<span className="text-xs bg-black/20 px-2 py-0.5 rounded-full">HOST</span>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
{realPlayers.map((player) => (
|
{realPlayers.map((player) => (
|
||||||
<motion.div
|
<motion.div
|
||||||
key={player.id}
|
key={player.id}
|
||||||
|
|
|
||||||
|
|
@ -850,12 +850,18 @@ export const useGame = () => {
|
||||||
});
|
});
|
||||||
const newScore = Math.max(0, currentPlayer.score + breakdown.total);
|
const newScore = Math.max(0, currentPlayer.score + breakdown.total);
|
||||||
|
|
||||||
setPlayers(prev => prev.map(p => {
|
const updatedPlayers = playersRef.current.map(p => {
|
||||||
if (p.id !== playerId) return p;
|
if (p.id !== playerId) return p;
|
||||||
return { ...p, score: newScore, previousScore: p.score, streak: newStreak, lastAnswerCorrect: isCorrect, selectedShape, pointsBreakdown: breakdown };
|
return { ...p, score: newScore, previousScore: p.score, streak: newStreak, lastAnswerCorrect: isCorrect, selectedShape, pointsBreakdown: breakdown };
|
||||||
}));
|
});
|
||||||
|
setPlayers(updatedPlayers);
|
||||||
|
|
||||||
conn.send({ type: 'RESULT', payload: { isCorrect, scoreAdded: breakdown.total, newScore, breakdown } });
|
conn.send({ type: 'RESULT', payload: { isCorrect, scoreAdded: breakdown.total, newScore, breakdown } });
|
||||||
|
|
||||||
|
const allAnswered = updatedPlayers.every(p => p.lastAnswerCorrect !== null);
|
||||||
|
if (allAnswered && gameStateRef.current === 'QUESTION') {
|
||||||
|
endQuestion();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1369,10 +1375,16 @@ export const useGame = () => {
|
||||||
setCurrentPlayerScore(newScore);
|
setCurrentPlayerScore(newScore);
|
||||||
setCurrentStreak(newStreak);
|
setCurrentStreak(newStreak);
|
||||||
|
|
||||||
setPlayers(prev => prev.map(p => {
|
const updatedPlayers = playersRef.current.map(p => {
|
||||||
if (p.id !== 'host') return p;
|
if (p.id !== 'host') return p;
|
||||||
return { ...p, score: newScore, previousScore: p.score, streak: newStreak, lastAnswerCorrect: isCorrect, selectedShape: option.shape, pointsBreakdown: breakdown };
|
return { ...p, score: newScore, previousScore: p.score, streak: newStreak, lastAnswerCorrect: isCorrect, selectedShape: option.shape, pointsBreakdown: breakdown };
|
||||||
}));
|
});
|
||||||
|
setPlayers(updatedPlayers);
|
||||||
|
|
||||||
|
const allAnswered = updatedPlayers.every(p => p.lastAnswerCorrect !== null);
|
||||||
|
if (allAnswered && gameStateRef.current === 'QUESTION') {
|
||||||
|
endQuestion();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const option = arg as AnswerOption;
|
const option = arg as AnswerOption;
|
||||||
setSelectedOption(option);
|
setSelectedOption(option);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue