diff --git a/client/src/common/styles/components/voting-screen.sass b/client/src/common/styles/components/voting-screen.sass
index 6929420..db94b07 100644
--- a/client/src/common/styles/components/voting-screen.sass
+++ b/client/src/common/styles/components/voting-screen.sass
@@ -124,6 +124,12 @@
color: $accent
font-weight: bold
text-align: center
+
+ .host-info
+ margin-top: 0.5rem
+ color: #fff
+ font-style: italic
+ font-size: 0.7rem
.video-container
margin-top: 1rem
@@ -267,6 +273,16 @@
font-family: 'Press Start 2P', monospace
font-size: 0.9rem
color: $text
+
+ .auto-advance-notice
+ margin: 1rem auto
+ max-width: 400px
+ padding: 0.75rem
+ background-color: rgba($secondary, 0.2)
+ border: 2px solid $secondary
+ text-align: center
+ color: $text-muted
+ font-style: italic
.votes-count
display: flex
diff --git a/client/src/components/VotingScreen.jsx b/client/src/components/VotingScreen.jsx
index b3c6047..9bfb82c 100644
--- a/client/src/components/VotingScreen.jsx
+++ b/client/src/components/VotingScreen.jsx
@@ -6,7 +6,7 @@ import { faVoteYea, faTrophy, faMusic, faCheck, faMedal, faCrown } from '@fortaw
import YouTubeEmbed from './YouTubeEmbed';
function VotingScreen() {
- const { lobby, currentPlayer, submitVote } = useGame();
+ const { lobby, currentPlayer, submitVote, isHost } = useGame();
const [hasVoted, setHasVoted] = useState(false);
const [selectedSong, setSelectedSong] = useState(null);
const [countdown, setCountdown] = useState(null);
@@ -65,11 +65,11 @@ function VotingScreen() {
// Handle bye round advancement - für automatisches Weiterkommen
const handleByeAdvance = async () => {
- if (processingByeAdvance) return;
+ if (processingByeAdvance || !isHost) return;
setProcessingByeAdvance(true);
try {
- // Alle Spieler im Bye-Modus "stimmen" automatisch für das einzige Lied
+ // Nur der Host kann im Bye-Modus weiterschaltenNNULL
if (battle && battle.song1 && !battle.song2 && battle.song1.id) {
await submitVote(battle.song1.id);
}
@@ -122,6 +122,7 @@ function VotingScreen() {
{battle.song1.artist}
Dieses Lied kommt automatisch in die nächste Runde!
+
{isHost ? 'Du kannst als Host zum nächsten Kampf weitergehen.' : 'Warte auf den Host, um fortzufahren.'}
@@ -139,17 +140,21 @@ function VotingScreen() {
-
+ {isHost ? (
+
+ ) : (
+
Warte auf den Host, um fortzufahren...
+ )}
);
diff --git a/server/game.js b/server/game.js
index 78e2b18..b572542 100644
--- a/server/game.js
+++ b/server/game.js
@@ -539,13 +539,19 @@ class GameManager {
return { error: 'No active battle' };
}
+ // For bye battles (automatic advancement), only allow the host to vote/advance
+ if (lobby.currentBattle.bye === true && playerId !== lobby.hostId) {
+ return { error: 'Only the host can advance bye rounds' };
+ }
+
// Check if player has already voted in this battle
- if (lobby.currentBattle.votes.has(playerId)) {
+ if (lobby.currentBattle.votes && lobby.currentBattle.votes.has(playerId)) {
return { error: 'Already voted in this battle' };
}
// Check if the voted song is part of the current battle
- if (songId !== lobby.currentBattle.song1.id && songId !== lobby.currentBattle.song2.id) {
+ if (songId !== lobby.currentBattle.song1.id &&
+ (lobby.currentBattle.song2 && songId !== lobby.currentBattle.song2.id)) {
return { error: 'Invalid song ID' };
}
@@ -553,6 +559,11 @@ class GameManager {
const player = lobby.players.find(p => p.id === playerId);
const playerName = player ? player.name : 'Unknown Player';
+ // Initialize votes Map if it doesn't exist
+ if (!lobby.currentBattle.votes) {
+ lobby.currentBattle.votes = new Map();
+ }
+
// Record the vote with player name for UI display
lobby.currentBattle.votes.set(playerId, {
songId,
@@ -561,15 +572,38 @@ class GameManager {
// Update vote counts
if (songId === lobby.currentBattle.song1.id) {
- lobby.currentBattle.song1Votes++;
- } else {
- lobby.currentBattle.song2Votes++;
+ lobby.currentBattle.song1Votes = (lobby.currentBattle.song1Votes || 0) + 1;
+ } else if (lobby.currentBattle.song2) {
+ lobby.currentBattle.song2Votes = (lobby.currentBattle.song2Votes || 0) + 1;
}
// Add a voteCount attribute for easier UI rendering
lobby.currentBattle.voteCount = lobby.currentBattle.votes.size;
- // Check if all connected players have voted
+ // For bye battles, the host's vote is all that's needed
+ if (lobby.currentBattle.bye === true && playerId === lobby.hostId) {
+ // Determine winner (in bye battles, it's always song1)
+ const winnerSongId = lobby.currentBattle.song1.id;
+
+ lobby.currentBattle.winner = winnerSongId;
+
+ // Save battle to history
+ lobby.battles.push({
+ round: lobby.currentBattle.round,
+ song1: lobby.currentBattle.song1,
+ song2: lobby.currentBattle.song2,
+ song1Votes: lobby.currentBattle.song1Votes,
+ song2Votes: 0,
+ winner: winnerSongId
+ });
+
+ // Move to next battle or finish tournament
+ this._moveToNextBattle(lobby);
+
+ return { lobby, lobbyId };
+ }
+
+ // For regular battles, check if all connected players have voted
const connectedPlayers = lobby.players.filter(p => p.isConnected).length;
const voteCount = lobby.currentBattle.votes.size;
@@ -728,9 +762,10 @@ class GameManager {
song1: byeSong,
song2: null, // Bye
bye: true,
- winner: byeSong.id,
+ winner: null, // Set to null until host advances it
song1Votes: 0,
- song2Votes: 0
+ song2Votes: 0,
+ votes: new Map() // Initialize votes as a Map
});
}
@@ -825,9 +860,10 @@ class GameManager {
song1: byeSong,
song2: null,
bye: true,
- winner: byeSong.id,
+ winner: null, // Set to null until host advances it
song1Votes: 0,
- song2Votes: 0
+ song2Votes: 0,
+ votes: new Map() // Initialize votes as a Map
});
}
@@ -853,6 +889,14 @@ class GameManager {
// Set first battle of new round
if (nextRound.length > 0) {
lobby.currentBattle = nextRound[0];
+
+ // Ensure votes is initialized as a Map
+ if (!lobby.currentBattle.votes) {
+ lobby.currentBattle.votes = new Map();
+ }
+
+ // Initialize vote count for UI
+ lobby.currentBattle.voteCount = 0;
}
}
diff --git a/server/index.js b/server/index.js
index baa13d0..0b66bbb 100644
--- a/server/index.js
+++ b/server/index.js
@@ -315,7 +315,7 @@ io.on('connection', (socket) => {
});
// If battle is finished, notify about new battle
- if (result.lobby.currentBattle) {
+ if (result.lobby.currentBattle && result.lobby.currentBattle !== result.lobby.battles[result.lobby.battles.length - 1]) {
io.to(result.lobbyId).emit('new_battle', {
battle: result.lobby.currentBattle
});