// HoopScores Rotator 3000 - Main Application Script class BoxscoreRotator { constructor() { this.games = []; this.currentGameIndex = 0; this.rotationInterval = null; this.isRotating = true; this.lastFetchDate = null; this.initializeElements(); this.setupEventListeners(); this.loadYesterdayGames(); } initializeElements() { this.boxscoreContainer = document.getElementById('boxscore-container'); this.currentGameNumber = document.getElementById('current-game-number'); this.totalGames = document.getElementById('total-games'); this.gameInfo = document.getElementById('game-info'); this.lastUpdated = document.getElementById('last-updated'); // Control buttons this.prevButton = document.getElementById('prev-game'); this.nextButton = document.getElementById('next-game'); this.toggleButton = document.getElementById('toggle-rotation'); } setupEventListeners() { this.prevButton.addEventListener('click', () => this.previousGame()); this.nextButton.addEventListener('click', () => this.nextGame()); this.toggleButton.addEventListener('click', () => this.toggleRotation()); // Keyboard navigation document.addEventListener('keydown', (e) => { if (e.key === 'ArrowLeft') this.previousGame(); if (e.key === 'ArrowRight') this.nextGame(); if (e.key === ' ') this.toggleRotation(); }); } async loadYesterdayGames() { try { // Get yesterday's date in EST const yesterday = this.getYesterdayDateEST(); this.lastFetchDate = yesterday; const scoreboardUrl = `https://corsproxy.io/?https://site.api.espn.com/apis/site/v2/sports/basketball/nba/scoreboard?dates=${yesterday}`; const response = await fetch(scoreboardUrl); const data = await response.json(); // Filter for completed games from yesterday this.games = (data.events || []).filter(event => { const status = event.status?.type?.state; return status === 'post'; // Only finished games }); this.updateGameCount(); if (this.games.length > 0) { this.displayCurrentGame(); this.startRotation(); } else { this.showNoGamesMessage(); } this.updateLastUpdatedTime(); } catch (error) { console.error('Error loading games:', error); this.showErrorMessage('Failed to load boxscores. Please try again later.'); } } getYesterdayDateEST() { const now = new Date(); const estOffset = -5 * 60; // EST is UTC-5 const estTime = new Date(now.getTime() + (estOffset + now.getTimezoneOffset()) * 60000); // Subtract one day estTime.setDate(estTime.getDate() - 1); // Format as YYYYMMDD const year = estTime.getFullYear(); const month = String(estTime.getMonth() + 1).padStart(2, '0'); const day = String(estTime.getDate()).padStart(2, '0'); return `${year}${month}${day}`; } async displayCurrentGame() { if (this.games.length === 0) return; const game = this.games[this.currentGameIndex]; this.boxscoreContainer.innerHTML = this.createLoadingHTML(); try { const boxscoreData = await this.fetchBoxscore(game.id); if (boxscoreData) { this.renderBoxscore(boxscoreData, game); } } catch (error) { console.error('Error displaying game:', error); this.showErrorMessage('Failed to load boxscore for this game.'); } } async fetchBoxscore(gameId) { const boxscoreUrl = `https://corsproxy.io/?https://site.api.espn.com/apis/site/v2/sports/basketball/nba/summary?event=${gameId}`; const response = await fetch(boxscoreUrl); return await response.json(); } renderBoxscore(boxscoreData, game) { const competition = game.competitions[0]; const homeTeam = competition.competitors.find(c => c.homeAway === 'home'); const awayTeam = competition.competitors.find(c => c.homeAway === 'away'); const playersByTeam = boxscoreData.boxscore?.players || []; const homePlayers = playersByTeam.find(p => p.team.id === homeTeam.team.id); const awayPlayers = playersByTeam.find(p => p.team.id === awayTeam.team.id); const html = `
No player data available
| Player | ${filteredHeaders.map(header => `${header} | `).join('')}
|---|---|
| ${athlete.athlete.displayName} | ${athlete.stats.map(stat => `${stat} | `).join('')}
${venue} • ${date}
`; } nextGame() { this.currentGameIndex = (this.currentGameIndex + 1) % this.games.length; this.displayCurrentGame(); this.updateGameCount(); } previousGame() { this.currentGameIndex = this.currentGameIndex === 0 ? this.games.length - 1 : this.currentGameIndex - 1; this.displayCurrentGame(); this.updateGameCount(); } startRotation() { if (this.rotationInterval) { clearInterval(this.rotationInterval); } this.rotationInterval = setInterval(() => { if (this.isRotating) { this.nextGame(); } }, 15000); // 15 seconds per game } toggleRotation() { this.isRotating = !this.isRotating; const icon = this.isRotating ? 'pause' : 'play'; const text = this.isRotating ? 'Pause' : 'Resume'; this.toggleButton.innerHTML = ` ${text} `; feather.replace(); } updateGameCount() { this.currentGameNumber.textContent = this.currentGameIndex + 1; this.totalGames.textContent = this.games.length; } updateLastUpdatedTime() { const now = new Date(); this.lastUpdated.textContent = now.toLocaleString('en-US', { timeZone: 'America/New_York', dateStyle: 'medium', timeStyle: 'medium' }); } createLoadingHTML() { return `Loading boxscore data...
There were no NBA games played yesterday.
${message}