diff --git a/src/server.ts b/src/server.ts index a9efd7c..a47b4f9 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,4 +1,4 @@ -import { Elysia, t } from 'elysia'; +import { Elysia } from 'elysia'; import { staticPlugin } from '@elysiajs/static'; import path from 'path'; @@ -15,6 +15,7 @@ interface LastSong { // Current song state let currentSong: LastSong | null = null; let lastSongId: string | null = null; +let pollTimer: ReturnType | null = null; // WebSocket connections const connections = new Set(); @@ -53,39 +54,52 @@ async function fetchLastFmSong(): Promise { // Function to check for song changes and notify clients async function checkAndUpdateSong(): Promise { const newSong = await fetchLastFmSong(); - - if (!newSong) return; - - // Create a unique identifier for the song - const newSongId = `${newSong.artist}-${newSong.name}-${newSong.nowPlaying}`; - - // Check if song has changed - if (newSongId !== lastSongId) { - console.log('Song changed:', newSong.name, 'by', newSong.artist); - currentSong = newSong; - lastSongId = newSongId; - - // Notify all connected WebSocket clients - const message = JSON.stringify({ - type: 'song-update', - data: newSong - }); - - connections.forEach(ws => { - try { - ws.send(message); - } catch (error) { - console.error('Error sending to WebSocket client:', error); - connections.delete(ws); - } - }); + + // Default to not currently playing if we couldn't fetch anything + let nowPlaying = false; + + if (newSong) { + // Create a unique identifier for the song (include nowPlaying state) + const newSongId = `${newSong.artist}-${newSong.name}-${newSong.nowPlaying}`; + + // Check if song has changed + if (newSongId !== lastSongId) { + console.log('Song changed:', newSong.name, 'by', newSong.artist); + // Update state and notify clients + currentSong = newSong; + lastSongId = newSongId; + + const message = JSON.stringify({ + type: 'song-update', + data: newSong + }); + + connections.forEach(ws => { + try { + ws.send(message); + } catch (error) { + console.error('Error sending to WebSocket client:', error); + connections.delete(ws); + } + }); + } else { + // Keep currentSong updated even if no change to ID (e.g., image/url may vary) + currentSong = newSong; + } + + nowPlaying = !!newSong.nowPlaying; + } else { + // If fetch failed, keep existing currentSong and fall back to slower polling + nowPlaying = currentSong?.nowPlaying ?? false; } + + // Schedule next poll based on whether a track is currently playing + const delayMs = nowPlaying ? 5000 : 30000; + if (pollTimer) clearTimeout(pollTimer); + pollTimer = setTimeout(checkAndUpdateSong, delayMs); } -// Start polling Last.fm every second -setInterval(checkAndUpdateSong, 1000); - -// Initial fetch +// Kick off adaptive polling with an immediate check checkAndUpdateSong(); // Determine static assets path - adjust for compiled executable diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..1bf46ff --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "Bundler", + "strict": true, + "noEmit": true, + "skipLibCheck": true, + "types": [ + "bun-types", + "vite/client" + ], + "jsx": "react-jsx", + "allowJs": true, + "resolveJsonModule": true + }, + "include": [ + "src", + "vite.config.*" + ] +}