import { treaty } from '@elysiajs/eden'; import type { App } from './server'; // Create Eden Treaty client using current page origin const client = treaty(window.location.origin); interface LastSongImage { size: 'small' | 'medium' | 'large' | 'extralarge'; '#text': string; } interface LastSong { name: string; artist: string; album: string; url: string; nowPlaying: boolean; image: LastSongImage[]; } // Function to fetch and display last song async function fetchLastSong(): Promise { try { const { data, error } = await client.api['last-song'].get(); if (error) { console.error('Error fetching last song:', error); updateLastSongDisplay(null, 'Failed to load song data'); return; } const song = data as LastSong; updateLastSongDisplay(song); } catch (error) { console.error('Network error:', error); updateLastSongDisplay(null, 'Network error occurred'); } } // Function to select appropriate image size based on screen width function getOptimalImageUrl(images: LastSongImage[]): string { if (!images || images.length === 0) return ''; const screenWidth = window.innerWidth; // Select image size based on screen width and device pixel ratio const pixelRatio = window.devicePixelRatio || 1; const effectiveWidth = screenWidth * pixelRatio; let targetSize: string; if (effectiveWidth <= 400) { targetSize = 'small'; // 34px } else if (effectiveWidth <= 800) { targetSize = 'medium'; // 64px } else if (effectiveWidth <= 1400) { targetSize = 'large'; // 174px } else { targetSize = 'extralarge'; // 300px } // Find the target size, fallback to largest available const targetImage = images.find(img => img.size === targetSize); if (targetImage) return targetImage['#text']; // Fallback: return the largest available image const fallbackOrder = ['extralarge', 'large', 'medium', 'small']; for (const size of fallbackOrder) { const image = images.find(img => img.size === size); if (image) return image['#text']; } return ''; } // Function to update the UI with song information function updateLastSongDisplay(song: LastSong | null, errorMessage?: string): void { const containers = [ document.getElementById('last-song-container'), document.getElementById('last-song-container-mobile') ]; containers.forEach(container => { if (!container) return; if (errorMessage || !song) { container.innerHTML = `
${errorMessage || 'No song data available'}
`; return; } const statusText = song.nowPlaying ? 'Currently listening to' : 'Last listened to'; const imageUrl = getOptimalImageUrl(song.image); const imageElement = imageUrl ? `${song.name}` : `
`; container.innerHTML = ` `; }); } // Auto-refresh functionality let refreshInterval: number; function startAutoRefresh(): void { // Fetch immediately fetchLastSong(); // Then fetch every 30 seconds refreshInterval = window.setInterval(fetchLastSong, 30000); } function stopAutoRefresh(): void { if (refreshInterval) { clearInterval(refreshInterval); } } // Initialize when DOM is loaded document.addEventListener('DOMContentLoaded', () => { startAutoRefresh(); }); // Clean up on page unload window.addEventListener('beforeunload', () => { stopAutoRefresh(); }); // Export functions for manual control if needed export { fetchLastSong, startAutoRefresh, stopAutoRefresh };