/** * Yatra Video Player Module * Reusable video player for YouTube and other video sources * * @package Yatra * @version 1.0.0 */ (function() { 'use strict'; // Translation helper. Same shim as tour-viewer.js — resolves // through wp.i18n when available, falls back to identity otherwise. // Call sites must pass `'yatra'` so wp i18n make-pot --domain=yatra // picks them up (see tour-viewer.js for the full rationale). var __ = (window.wp && window.wp.i18n && window.wp.i18n.__) ? function (text, domain) { return window.wp.i18n.__(text, domain || 'yatra'); } : function (text) { return text; }; class YatraVideoPlayer { constructor() { this.modal = null; this.iframe = null; this.currentVideo = null; this.init(); } init() { this.createModal(); this.attachEventListeners(); } createModal() { // Check if modal already exists if (document.getElementById('yatra-video-player-modal')) { this.modal = document.getElementById('yatra-video-player-modal'); this.iframe = document.getElementById('yatra-video-player-iframe'); return; } // Pre-compute the translated label OUT of the template literal // so makepot extracts it reliably (see tour-viewer.js note). var closeVideoLabel = __('Close Video', 'yatra'); // Create modal HTML const modalHTML = `
`; // Append to body document.body.insertAdjacentHTML('beforeend', modalHTML); this.modal = document.getElementById('yatra-video-player-modal'); this.iframe = document.getElementById('yatra-video-player-iframe'); } attachEventListeners() { // Close button const closeBtn = this.modal.querySelector('.yatra-video-player-close'); if (closeBtn) { closeBtn.addEventListener('click', () => this.close()); } // Overlay click to close const overlay = this.modal.querySelector('.yatra-video-player-overlay'); if (overlay) { overlay.addEventListener('click', () => this.close()); } // ESC key to close document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && this.modal.style.display === 'flex') { this.close(); } }); } /** * Play a video * @param {Object} video - Video object with url, embed_url, video_id, title */ play(video) { if (!video || !video.url) { console.error('YatraVideoPlayer: Invalid video object'); return; } this.currentVideo = video; // Determine the embed URL let embedUrl = ''; if (video.embed_url) { // Use provided embed URL embedUrl = video.embed_url; } else if (video.video_id) { // YouTube video ID provided embedUrl = `https://www.youtube.com/embed/${video.video_id}?autoplay=1&rel=0`; } else if (video.url.includes('youtube.com') || video.url.includes('youtu.be')) { // Extract YouTube video ID from URL const videoId = this.extractYoutubeVideoId(video.url); if (videoId) { embedUrl = `https://www.youtube.com/embed/${videoId}?autoplay=1&rel=0`; } } else if (video.url.includes('vimeo.com')) { // Vimeo video const vimeoId = video.url.split('/').pop(); embedUrl = `https://player.vimeo.com/video/${vimeoId}?autoplay=1`; } else { // Direct video URL embedUrl = video.url; } // Add load event handlers for debugging this.iframe.onload = () => { }; this.iframe.onerror = (error) => { console.error('YouTube iframe failed to load:', error); }; // Set iframe source this.iframe.src = embedUrl; // Verify iframe src was set setTimeout(() => { }, 100); // Show modal this.open(); } /** * Extract YouTube video ID from various URL formats * @param {string} url - YouTube URL * @returns {string|null} Video ID or null */ extractYoutubeVideoId(url) { const patterns = [ /youtube\.com\/watch\?v=([^&]+)/, /youtube\.com\/embed\/([^?]+)/, /youtu\.be\/([^?]+)/, /youtube\.com\/v\/([^?]+)/ ]; for (const pattern of patterns) { const match = url.match(pattern); if (match) { return match[1]; } } return null; } open() { this.modal.style.display = 'flex'; document.body.style.overflow = 'hidden'; } close() { this.modal.style.display = 'none'; document.body.style.overflow = ''; // Stop video playback by clearing iframe src this.iframe.src = ''; this.currentVideo = null; } } // Create global instance window.YatraVideoPlayer = new YatraVideoPlayer(); // Log successful initialization })();