69 lines
2.1 KiB
JavaScript
69 lines
2.1 KiB
JavaScript
// static/scoreboard.js - Real-time scoreboard updates
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
// Server-Sent Events for Real-time Updates
|
|
const eventSource = new EventSource('/events');
|
|
|
|
eventSource.onmessage = function(event) {
|
|
try {
|
|
const players = JSON.parse(event.data);
|
|
updateScoreboard(players);
|
|
} catch (error) {
|
|
console.error('Error parsing player data:', error);
|
|
}
|
|
};
|
|
|
|
eventSource.onerror = function(error) {
|
|
console.error('EventSource error:', error);
|
|
// Attempt to reconnect after 5 seconds
|
|
setTimeout(() => {
|
|
location.reload();
|
|
}, 5000);
|
|
};
|
|
|
|
// Update scoreboard display with sorted players
|
|
function updateScoreboard(players) {
|
|
const columns = document.querySelectorAll('.column');
|
|
|
|
// Clear existing rows
|
|
columns.forEach(col => col.innerHTML = '');
|
|
|
|
// Rebuild grid with current rankings
|
|
players.forEach((player, index) => {
|
|
const rank = index + 1;
|
|
const columnIndex = Math.floor(index / 7);
|
|
|
|
if (columnIndex < 2) {
|
|
const scoreRow = createScoreRow(player, rank);
|
|
columns[columnIndex].appendChild(scoreRow);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Create a score row element
|
|
function createScoreRow(player, rank) {
|
|
const row = document.createElement('div');
|
|
row.className = 'score-row';
|
|
row.dataset.id = player.id;
|
|
|
|
// Highlight leader (position 1)
|
|
if (rank === 1) {
|
|
row.classList.add('leader');
|
|
}
|
|
|
|
row.innerHTML = `
|
|
<span class="player-rank">${rank}</span>
|
|
<span class="player-name">${player.name}</span>
|
|
<span class="player-score">${player.score}</span>
|
|
`;
|
|
|
|
return row;
|
|
}
|
|
|
|
// Prevent screen sleep for TV display
|
|
if ('wakeLock' in navigator) {
|
|
navigator.wakeLock.request('screen').catch(err => {
|
|
console.log('Wake lock failed:', err);
|
|
});
|
|
}
|
|
});
|