PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.13
Yatra – Travel Booking & Tour Operator Software v3.0.13
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
yatra / assets / js / tour-viewer.js

tour-viewer.js in Yatra – Travel Booking & Tour Operator Software 3.0.13, at assets/js/tour-viewer.js

194 lines 6.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Yatra 360° Tour Viewer Module
3 * Reusable 360° virtual tour viewer
4 *
5 * @package Yatra
6 * @version 1.0.0
7 */
8
9 (function() {
10 'use strict';
11
12 // Translation helper. Resolves through wp.i18n.__() when wp-i18n is
13 // enqueued (FrontendAssetsProvider registers it as a dependency for
14 // this script); falls back to identity so the page never breaks
15 // when the i18n runtime is unavailable on older builds.
16 //
17 // IMPORTANT — call sites MUST pass `'yatra'` as the second arg even
18 // though the shim ignores it. `wp i18n make-pot --domain=yatra`
19 // filters extraction to calls whose LITERAL second argument is the
20 // domain, so a bare `__('x')` is silently dropped from the .pot.
21 var __ = (window.wp && window.wp.i18n && window.wp.i18n.__)
22 ? function (text, domain) { return window.wp.i18n.__(text, domain || 'yatra'); }
23 : function (text) { return text; };
24
25 class YatraTourViewer {
26 constructor() {
27 this.modal = null;
28 this.iframe = null;
29 this.currentTour = null;
30 this.init();
31 }
32
33 init() {
34 this.createModal();
35 this.attachEventListeners();
36 }
37
38 createModal() {
39 // Check if modal already exists
40 if (document.getElementById('yatra-tour-viewer-modal')) {
41 this.modal = document.getElementById('yatra-tour-viewer-modal');
42 this.iframe = document.getElementById('yatra-tour-viewer-iframe');
43 return;
44 }
45
46 // Pre-compute translated labels OUT of the template literal so
47 // makepot extracts them reliably. `wp i18n make-pot` doesn't
48 // always traverse into `${ }` interpolations; calls at top-
49 // level statements are always picked up.
50 var closeTourLabel = __('Close Tour', 'yatra');
51 var fullscreenLabel = __('Fullscreen', 'yatra');
52
53 // Create modal HTML
54 const modalHTML = `
55 <div id="yatra-tour-viewer-modal" class="yatra-tour-viewer-modal" style="display: none;">
56 <div class="yatra-tour-viewer-overlay"></div>
57 <div class="yatra-tour-viewer-content">
58 <button type="button" class="yatra-tour-viewer-close" aria-label="${closeTourLabel}">
59 <svg width="24" height="24" fill="none" stroke="currentColor" viewBox="0 0 24 24">
60 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
61 </svg>
62 </button>
63 <div class="yatra-tour-viewer-header">
64 <h3 class="yatra-tour-viewer-title"></h3>
65 <div class="yatra-tour-viewer-controls">
66 <button type="button" class="yatra-tour-viewer-fullscreen" aria-label="${fullscreenLabel}">
67 <svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
68 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"/>
69 </svg>
70 </button>
71 </div>
72 </div>
73 <div class="yatra-tour-viewer-wrapper">
74 <iframe id="yatra-tour-viewer-iframe"
75 width="100%"
76 height="100%"
77 frameborder="0"
78 allowfullscreen
79 allow="gyroscope; accelerometer; xr-spatial-tracking">
80 </iframe>
81 </div>
82 </div>
83 </div>
84 `;
85
86 // Append to body
87 document.body.insertAdjacentHTML('beforeend', modalHTML);
88
89 this.modal = document.getElementById('yatra-tour-viewer-modal');
90 this.iframe = document.getElementById('yatra-tour-viewer-iframe');
91 }
92
93 attachEventListeners() {
94 // Close button
95 const closeBtn = this.modal.querySelector('.yatra-tour-viewer-close');
96 if (closeBtn) {
97 closeBtn.addEventListener('click', () => this.close());
98 }
99
100 // Overlay click to close
101 const overlay = this.modal.querySelector('.yatra-tour-viewer-overlay');
102 if (overlay) {
103 overlay.addEventListener('click', () => this.close());
104 }
105
106 // Fullscreen button
107 const fullscreenBtn = this.modal.querySelector('.yatra-tour-viewer-fullscreen');
108 if (fullscreenBtn) {
109 fullscreenBtn.addEventListener('click', () => this.toggleFullscreen());
110 }
111
112 // ESC key to close
113 document.addEventListener('keydown', (e) => {
114 if (e.key === 'Escape' && this.modal.style.display === 'flex') {
115 this.close();
116 }
117 });
118 }
119
120 /**
121 * View a 360° tour
122 * @param {Object} tour - Tour object with url, title, tour_type
123 */
124 view(tour) {
125 if (!tour || !tour.url) {
126 console.error('YatraTourViewer: Invalid tour object');
127 return;
128 }
129
130 this.currentTour = tour;
131
132 // Set title
133 const titleElement = this.modal.querySelector('.yatra-tour-viewer-title');
134 if (titleElement) {
135 titleElement.textContent = tour.title || __('360° Virtual Tour', 'yatra');
136 }
137
138 // Set iframe source
139 this.iframe.src = tour.url;
140
141 // Show modal
142 this.open();
143 }
144
145 open() {
146 this.modal.style.display = 'flex';
147 document.body.style.overflow = 'hidden';
148 }
149
150 close() {
151 this.modal.style.display = 'none';
152 document.body.style.overflow = '';
153
154 // Stop tour by clearing iframe src
155 this.iframe.src = '';
156 this.currentTour = null;
157
158 // Exit fullscreen if active
159 if (document.fullscreenElement) {
160 document.exitFullscreen();
161 }
162 }
163
164 toggleFullscreen() {
165 const wrapper = this.modal.querySelector('.yatra-tour-viewer-wrapper');
166
167 if (!document.fullscreenElement) {
168 if (wrapper.requestFullscreen) {
169 wrapper.requestFullscreen();
170 } else if (wrapper.webkitRequestFullscreen) {
171 wrapper.webkitRequestFullscreen();
172 } else if (wrapper.msRequestFullscreen) {
173 wrapper.msRequestFullscreen();
174 }
175 } else {
176 if (document.exitFullscreen) {
177 document.exitFullscreen();
178 } else if (document.webkitExitFullscreen) {
179 document.webkitExitFullscreen();
180 } else if (document.msExitFullscreen) {
181 document.msExitFullscreen();
182 }
183 }
184 }
185 }
186
187 // Create global instance
188 window.YatraTourViewer = new YatraTourViewer();
189
190 // Log successful initialization
191
192
193 })();
194