/** * Overlay Video Player * A popup overlay video player that extends BaseVideoPlayer * Used for random video playback in overlay/popup windows */ class OverlayVideoPlayer extends BaseVideoPlayer { constructor(options = {}) { // Create the overlay container first const overlayContainer = OverlayVideoPlayer.createOverlayContainer(); // Add it to DOM temporarily so we can query it document.body.appendChild(overlayContainer); // Create a unique ID for the video container const containerId = `overlay-video-container-${Date.now()}`; const videoContainer = overlayContainer.querySelector('.overlay-video-container'); videoContainer.id = containerId; // Initialize BaseVideoPlayer with the CSS selector super(`#${containerId}`, { showControls: true, autoHide: true, showProgress: true, showVolume: true, showFullscreen: true, showQuality: false, // Keep it simple for overlay showSpeed: false, // Keep it simple for overlay keyboardShortcuts: true, minimal: false, ...options }); this.overlayElement = overlayContainer; this.isVisible = false; this.currentVideo = null; // Remove from DOM initially (will be added back when shown) document.body.removeChild(overlayContainer); // Setup overlay-specific events this.setupOverlayEvents(); console.log('🎬 OverlayVideoPlayer created'); } static createOverlayContainer() { const overlay = document.createElement('div'); overlay.className = 'video-overlay-popup'; overlay.innerHTML = `
`; return overlay; } setupOverlayEvents() { // Close button const closeBtn = this.overlayElement.querySelector('#overlay-close-btn'); closeBtn.addEventListener('click', () => this.hide()); // Backdrop click to close const backdrop = this.overlayElement.querySelector('#overlay-backdrop'); backdrop.addEventListener('click', () => this.hide()); // Escape key to close document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && this.isVisible) { this.hide(); } }); // Random video button const randomBtn = this.overlayElement.querySelector('.random-video-btn'); if (randomBtn) { randomBtn.addEventListener('click', () => this.playRandomVideo()); } // Prevent video container clicks from closing overlay const videoContainer = this.overlayElement.querySelector('.overlay-video-container'); videoContainer.addEventListener('click', (e) => { e.stopPropagation(); }); } async show() { if (this.isVisible) return; // Add to DOM if not already there if (!document.body.contains(this.overlayElement)) { document.body.appendChild(this.overlayElement); } // Show overlay this.overlayElement.style.display = 'flex'; this.isVisible = true; // Fade in animation setTimeout(() => { this.overlayElement.classList.add('visible'); }, 10); // Load a random video if none is currently loaded if (!this.currentVideo) { await this.playRandomVideo(); } console.log('🎬 Overlay video player shown'); } hide() { if (!this.isVisible) return; // Fade out animation this.overlayElement.classList.remove('visible'); // Hide after animation setTimeout(() => { this.overlayElement.style.display = 'none'; this.isVisible = false; // Pause video when hidden if (this.videoElement) { this.videoElement.pause(); } }, 300); console.log('🎬 Overlay video player hidden'); } async playRandomVideo() { try { // Get all available videos let allVideos = []; if (window.desktopFileManager) { allVideos = window.desktopFileManager.getAllVideos(); } // Fallback to unified storage if (allVideos.length === 0) { const unifiedData = JSON.parse(localStorage.getItem('unifiedVideoLibrary') || '{}'); allVideos = unifiedData.allVideos || []; } // Fallback to legacy storage if (allVideos.length === 0) { const storedVideos = JSON.parse(localStorage.getItem('videoFiles') || '{}'); allVideos = Object.values(storedVideos).flat(); } if (allVideos.length === 0) { this.showError('No videos available for random playback'); return; } // Select random video const randomIndex = Math.floor(Math.random() * allVideos.length); const randomVideo = allVideos[randomIndex]; console.log(`🎲 Playing random video: ${randomVideo.name || randomVideo.title}`); // Update video info this.updateVideoInfo(randomVideo); // Load and play the video this.loadVideo(randomVideo.path || randomVideo.filePath, true); this.currentVideo = randomVideo; } catch (error) { console.error('Error playing random video:', error); this.showError('Error loading random video'); } } updateVideoInfo(video) { const titleElement = this.overlayElement.querySelector('.video-title'); const infoElement = this.overlayElement.querySelector('.video-info'); const nameElement = this.overlayElement.querySelector('.video-name'); const videoName = video.name || video.title || 'Unknown Video'; const videoSize = this.formatFileSize(video.size || 0); const videoDuration = this.formatDuration(video.duration || 0); if (titleElement) { titleElement.textContent = videoName; } if (infoElement) { infoElement.textContent = `${videoSize} • ${videoDuration}`; } if (nameElement) { nameElement.textContent = videoName; } // Update overlay window title const overlayTitle = this.overlayElement.querySelector('.overlay-title'); if (overlayTitle) { overlayTitle.textContent = `🎬 ${videoName}`; } } showError(message) { const titleElement = this.overlayElement.querySelector('.video-title'); const infoElement = this.overlayElement.querySelector('.video-info'); if (titleElement) { titleElement.textContent = 'Error'; } if (infoElement) { infoElement.textContent = message; } } formatFileSize(bytes) { if (!bytes || bytes === 0) return '--'; const sizes = ['B', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(1024)); return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`; } formatDuration(seconds) { if (!seconds || seconds === 0) return '--:--'; const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); const secs = Math.floor(seconds % 60); if (hours > 0) { return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; } else { return `${minutes}:${secs.toString().padStart(2, '0')}`; } } // Public methods isOpen() { return this.isVisible; } getCurrentVideo() { return this.currentVideo; } // Static method to create and show overlay static async showOverlay(options = {}) { const overlay = new OverlayVideoPlayer(options); await overlay.show(); return overlay; } } // Export for global access window.OverlayVideoPlayer = OverlayVideoPlayer;