// Common functionality // Initialize on page load document.addEventListener('DOMContentLoaded', () => { // Display recent videos in the footer on page load loadFooterRecentVideos(); // Handle theme switching const themeItems = document.querySelectorAll('.theme-item'); themeItems.forEach(item => { item.addEventListener('click', () => { const theme = item.dataset.theme; document.documentElement.setAttribute('data-theme', theme); localStorage.setItem('theme', theme); }); }); // Apply saved theme from localStorage if available const savedTheme = localStorage.getItem('theme'); if (savedTheme) { document.documentElement.setAttribute('data-theme', savedTheme); } }); // Format seconds to MM:SS format function formatTime(seconds) { const minutes = Math.floor(seconds / 60); const secs = Math.floor(seconds % 60); return `${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; } // Error handling function function handleError(error) { console.error('Error:', error); return ``; } // Toast notification function function showToast(message, type = 'info') { const toast = document.createElement('div'); toast.className = `alert alert-${type} fixed bottom-4 right-4 max-w-xs z-50 shadow-lg`; // Different icon based on type let icon = ''; switch(type) { case 'success': icon = ` `; break; case 'warning': icon = ` `; break; case 'error': icon = ` `; break; default: // info icon = ` `; } toast.innerHTML = ` ${icon} ${message}
`; document.body.appendChild(toast); // Auto-dismiss after 3 seconds setTimeout(() => { toast.classList.add('opacity-0', 'transition-opacity', 'duration-500'); setTimeout(() => toast.remove(), 500); }, 3000); } // Extract video ID from YouTube URL function extractVideoId(url) { const regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/; const match = url.match(regExp); return (match && match[7].length === 11) ? match[7] : null; } // Load recent videos into the footer from the API function loadFooterRecentVideos() { const footerRecentVideos = document.getElementById('footer-recent-videos'); if (!footerRecentVideos) return; // Show loading state footerRecentVideos.innerHTML = '

Loading recent videos...

'; // Fetch recent videos from server API fetch('/api/video/recent?limit=3') .then(response => { if (!response.ok) { throw new Error('Failed to fetch recent videos'); } return response.json(); }) .then(videos => { if (videos && videos.length > 0) { // Generate HTML for recent videos const videoLinks = videos.map(video => { return ` ${video.title || `Video ${video.video_id}`} `; }).join(''); // Add videos to the footer footerRecentVideos.innerHTML = videoLinks; } else { footerRecentVideos.innerHTML = '

No recent videos

'; } }) .catch(error => { console.error('Error loading footer videos:', error); footerRecentVideos.innerHTML = '

Failed to load recent videos

'; }); }