import videojs from 'video.js'; import './AutoplayCountdownOverlay.css'; // Get the Component base class from Video.js const Component = videojs.getComponent('Component'); class AutoplayCountdownOverlay extends Component { constructor(player, options) { super(player, options); this.nextVideoData = options.nextVideoData || null; this.countdownSeconds = options.countdownSeconds || 5; this.onPlayNext = options.onPlayNext || (() => {}); this.onCancel = options.onCancel || (() => {}); this.currentCountdown = this.countdownSeconds; this.countdownInterval = null; this.isActive = false; // Bind methods this.startCountdown = this.startCountdown.bind(this); this.stopCountdown = this.stopCountdown.bind(this); this.handlePlayNext = this.handlePlayNext.bind(this); this.handleCancel = this.handleCancel.bind(this); this.updateCountdownDisplay = this.updateCountdownDisplay.bind(this); } createEl() { const overlay = super.createEl('div', { className: 'vjs-autoplay-countdown-overlay', }); // Get next video title or fallback const nextVideoTitle = this.nextVideoData?.title || 'Next Video'; const nextVideoThumbnail = this.nextVideoData?.thumbnail || ''; overlay.innerHTML = `

Up next in ${this.countdownSeconds}

${ nextVideoThumbnail ? `
${nextVideoTitle}
` : '' }

${nextVideoTitle}

${this.nextVideoData?.author ? `

${this.nextVideoData.author}

` : ''} ${this.nextVideoData?.duration ? `

${this.formatDuration(this.nextVideoData.duration)}

` : ''}
`; // Add event listeners with explicit binding const playButton = overlay.querySelector('.autoplay-play-button'); const cancelButton = overlay.querySelector('.autoplay-cancel-button'); if (playButton) { playButton.addEventListener('click', (e) => { e.preventDefault(); this.handlePlayNext(); }); } if (cancelButton) { cancelButton.addEventListener('click', (e) => { e.preventDefault(); this.handleCancel(); }); } // Initially hide the overlay overlay.style.display = 'none'; return overlay; } startCountdown() { this.isActive = true; this.currentCountdown = this.countdownSeconds; this.show(); this.updateCountdownDisplay(); // Start countdown interval this.countdownInterval = setInterval(() => { this.currentCountdown--; this.updateCountdownDisplay(); if (this.currentCountdown <= 0) { this.stopCountdown(); // Auto-play next video when countdown reaches 0 this.handlePlayNext(); } }, 1000); console.log('Autoplay countdown started:', this.countdownSeconds, 'seconds'); } stopCountdown() { this.isActive = false; if (this.countdownInterval) { clearInterval(this.countdownInterval); this.countdownInterval = null; } this.hide(); console.log('Autoplay countdown stopped'); } updateCountdownDisplay() { const timerElement = this.el().querySelector('.countdown-timer'); if (timerElement) { timerElement.textContent = this.currentCountdown; } } handlePlayNext() { console.log('Autoplay: Playing next video immediately'); try { this.stopCountdown(); this.onPlayNext(); } catch (error) { console.error('Error in handlePlayNext:', error); } } handleCancel() { console.log('Autoplay: Cancelled by user'); try { this.stopCountdown(); this.onCancel(); } catch (error) { console.error('Error in handleCancel:', error); } } show() { if (this.el()) { this.el().style.display = 'flex'; // Add animation class for smooth entrance this.el().classList.add('autoplay-countdown-show'); } } hide() { if (this.el()) { this.el().style.display = 'none'; this.el().classList.remove('autoplay-countdown-show'); } } formatDuration(seconds) { if (!seconds || seconds === 0) return ''; const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); const secs = 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')}`; } } // Update next video data updateNextVideoData(nextVideoData) { this.nextVideoData = nextVideoData; // Re-render the content if the overlay exists if (this.el()) { const nextVideoTitle = this.nextVideoData?.title || 'Next Video'; const nextVideoThumbnail = this.nextVideoData?.thumbnail || ''; const videoInfoElement = this.el().querySelector('.autoplay-countdown-video-info'); if (videoInfoElement) { videoInfoElement.innerHTML = ` ${ nextVideoThumbnail ? `
${nextVideoTitle}
` : '' }

${nextVideoTitle}

${this.nextVideoData?.author ? `

${this.nextVideoData.author}

` : ''} ${this.nextVideoData?.duration ? `

${this.formatDuration(this.nextVideoData.duration)}

` : ''}
`; } } } // Cleanup method dispose() { this.stopCountdown(); super.dispose(); } } // Register the component videojs.registerComponent('AutoplayCountdownOverlay', AutoplayCountdownOverlay); export default AutoplayCountdownOverlay;