PluginProbe
VikBooking Hotel Booking Engine & PMS / trunk
VikBooking Hotel Booking Engine & PMS vtrunk
1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 All 36 releases
vikbooking / admin / layouts / sidepanel / notificationscenter.php

notificationscenter.php in VikBooking Hotel Booking Engine & PMS trunk, at admin/layouts/sidepanel/notificationscenter.php

297 lines 9.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage com_vikbooking
5 * @author Alessio Gaggii - E4J srl
6 * @copyright Copyright (C) 2024 E4J srl. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 * @link https://vikwp.com
9 */
10
11 defined('ABSPATH') or die('No script kiddies please!');
12
13 /**
14 * Obtain vars from arguments received in the layout file.
15 * This layout file should be called once at most per page.
16 *
17 * @var string $vbo_page the name of the current View in VBO.
18 * @var string $btn_trigger the CSS selector of the button that opens the panel.
19 * @var int $badge_count the total number of unread notifications.
20 * @var string $badge_c_attr the handler data attribute for the badge counter.
21 * @var string $badge_r_attr the handler data attribute for the readable badge counter.
22 */
23 extract($displayData);
24
25 ?>
26
27 <div class="vbo-notifications-center-wrap vbo-notifications-center-off">
28 <div class="vbo-notifications-center-inner"></div>
29 </div>
30
31 <script type="text/javascript">
32
33 /**
34 * @var bool
35 */
36 var vbo_notifs_center_on = false;
37
38 /**
39 * @var string
40 */
41 var vbo_notifs_center_last_keydown = null;
42
43 /**
44 * @var number
45 */
46 var vbo_notifs_center_widget_js_id = 0;
47
48 jQuery(function() {
49
50 /**
51 * Register the button trigger click handler.
52 */
53 jQuery('<?php echo $btn_trigger; ?>').on('click', function() {
54 let wrapper = jQuery('.vbo-notifications-center-wrap');
55 let suggest_push = (VBOCore.notificationsEnabled() === false);
56
57 if (!vbo_notifs_center_widget_js_id) {
58 vbo_notifs_center_widget_js_id = Math.floor(Math.random() * 100000);
59 }
60
61 if (wrapper.hasClass('vbo-notifications-center-off')) {
62 // show notifications center
63 vbo_notifs_center_on = true;
64
65 wrapper.removeClass('vbo-notifications-center-off');
66 wrapper.addClass('vbo-notifications-center-on');
67
68 // build loading string
69 let vbo_notifs_center_loading_html = '<div class="vbo-notifications-center-loading">' + "\n";
70 vbo_notifs_center_loading_html += '<span><?php VikBookingIcons::e('circle-notch', 'fa-spin fa-fw fa-3x'); ?></span>' + "\n";
71 vbo_notifs_center_loading_html += '</div>' + "\n";
72
73 // display loading
74 wrapper
75 .find('.vbo-notifications-center-inner')
76 .html(vbo_notifs_center_loading_html);
77
78 // render admin-widget
79 VBOCore.renderAdminWidget('notifications_center', {
80 _modalRendering: 1,
81 _modalJsId: vbo_notifs_center_widget_js_id,
82 _options: {
83 inMenu: true,
84 suggestPush: suggest_push,
85 },
86 }).then((content) => {
87 // populate content
88 wrapper
89 .find('.vbo-notifications-center-inner')
90 .html(content);
91 }).catch((error) => {
92 // display error
93 alert(error);
94 });
95 } else {
96 // hide notifications center
97 vbo_notifs_center_on = false;
98
99 wrapper.removeClass('vbo-notifications-center-on');
100 wrapper.addClass('vbo-notifications-center-off');
101
102 // destroy the wrapper content
103 wrapper
104 .find('.vbo-notifications-center-inner')
105 .html('');
106
107 // emit the dismissed event
108 VBOCore.emitEvent(VBOCore.options.widget_modal_dismissed + vbo_notifs_center_widget_js_id);
109 }
110 });
111
112 // register listener for esc key pressed to close the notifications center
113 jQuery(document).keyup(function(e) {
114 if (!vbo_notifs_center_on) {
115 return;
116 }
117 if ((e.key && e.key === "Escape") || (e.keyCode && e.keyCode == 27)) {
118 jQuery('<?php echo $btn_trigger; ?>').trigger('click');
119 }
120 });
121
122 // register listener for click on menu to close the notifications center
123 jQuery('.vbo-menu-right').click(function(e) {
124 if (!vbo_notifs_center_on || jQuery(e.target).closest('.vbo-menu-updates').length) {
125 return;
126 }
127 jQuery('<?php echo $btn_trigger; ?>').trigger('click');
128 });
129
130 // register shortcut for toggling the notifications center (CMD + K, CMD + C)
131 window.addEventListener('keydown', (e) => {
132 e = e || window.event;
133 if (!e.key) {
134 return;
135 }
136 if (e.key === 'k' && e.metaKey) {
137 // set special key listener for sequences of combos
138 e.preventDefault();
139 vbo_notifs_center_last_keydown = 'k';
140 return;
141 }
142 if (vbo_notifs_center_last_keydown === 'k' && e.metaKey && e.key === 'c') {
143 // trigger event to change color scheme preferences
144 e.preventDefault();
145 // unset special key
146 vbo_notifs_center_last_keydown = '';
147 // toggle notifications center
148 jQuery('<?php echo $btn_trigger; ?>').trigger('click');
149 return;
150 }
151 // always unset last key if this point gets reached
152 vbo_notifs_center_last_keydown = '';
153 }, true);
154
155 /**
156 * Listen to the global event for updating the badge counter. This listener will never have to be removed.
157 */
158 document.addEventListener('vbo-badge-count', (e) => {
159 if (!e || !e.detail || !e.detail.hasOwnProperty('badge_count') || isNaN(e.detail['badge_count'])) {
160 return;
161 }
162
163 // get the trigger button element
164 let btn_trigger = document
165 .querySelector('<?php echo $btn_trigger; ?>');
166
167 // get the current badge counter value
168 let badge_count_now = parseInt(btn_trigger.getAttribute('<?php echo $badge_c_attr; ?>'));
169
170 // get the new badge counter value
171 let badge_count_new = parseInt(e.detail['badge_count']);
172
173 // update badge attributes
174 if (badge_count_new <= 0) {
175 // no notifications to be read
176 btn_trigger.setAttribute('<?php echo $badge_c_attr; ?>', 0);
177 btn_trigger.setAttribute('<?php echo $badge_r_attr; ?>', '');
178 } else {
179 // update badge counter
180 btn_trigger.setAttribute('<?php echo $badge_c_attr; ?>', badge_count_new);
181 btn_trigger.setAttribute('<?php echo $badge_r_attr; ?>', (badge_count_new > 99 ? '99+' : badge_count_new));
182 }
183
184 // check if we had new notifications
185 if (badge_count_new > badge_count_now) {
186 // add shaking class
187 btn_trigger.classList.add('shaking');
188
189 // remove shaking class after some time
190 setTimeout(() => {
191 btn_trigger.classList.remove('shaking');
192 }, 2000);
193 }
194
195 // check if support for Web App badge is available
196 if (typeof navigator.setAppBadge !== 'undefined') {
197 if (badge_count_new > 0) {
198 navigator.setAppBadge(badge_count_new);
199 } else {
200 navigator.clearAppBadge();
201 }
202 }
203 });
204
205 /**
206 * Listen to the event for reloading the badge counter. This listener will never have to be removed.
207 * Reloading the badge counter is helpful when clicking on a Push notification from the ServiceWorker.
208 */
209 document.addEventListener('vbo-badge-count-reload', (e) => {
210 // the widget method to call
211 var call_method = 'countUnreadNotifications';
212
213 // make a request to the admin-widget "notifications center" to count the unread notifications
214 VBOCore.doAjax(
215 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=exec_admin_widget'); ?>",
216 {
217 widget_id: 'notifications_center',
218 call: call_method,
219 return: 1,
220 },
221 (response) => {
222 try {
223 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
224 if (!obj_res.hasOwnProperty(call_method) || typeof obj_res[call_method] !== 'object') {
225 console.error('Unexpected JSON response', obj_res);
226 return false;
227 }
228
229 // scan all the events to dispatch
230 for (let ev_name in obj_res[call_method]) {
231 if (!obj_res[call_method].hasOwnProperty(ev_name)) {
232 continue;
233 }
234 // emit the event
235 VBOCore.emitEvent(ev_name, {
236 badge_count: obj_res[call_method][ev_name],
237 });
238 }
239 } catch(err) {
240 console.error('could not parse JSON response', err, response);
241 }
242 },
243 (error) => {
244 // silently log the error
245 console.error(error);
246 }
247 );
248 });
249
250 /**
251 * Listen to the event for reading notifications matching certain criterias.
252 * This listener will never have to be removed.
253 */
254 document.addEventListener('vbo-nc-read-notifications', (e) => {
255 if (!e || !e.detail || !e.detail.hasOwnProperty('criteria') || !e.detail['criteria']) {
256 return;
257 }
258
259 // the widget method to call
260 var call_method = 'readMatchingNotifications';
261
262 // make a request to the admin-widget "notifications center" to read any matching notification
263 VBOCore.doAjax(
264 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=exec_admin_widget'); ?>",
265 {
266 widget_id: 'notifications_center',
267 call: call_method,
268 return: 1,
269 criteria: e.detail['criteria'],
270 },
271 (response) => {
272 try {
273 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
274 if (!obj_res.hasOwnProperty(call_method) || typeof obj_res[call_method] !== 'object') {
275 console.error('Unexpected JSON response', obj_res);
276 return false;
277 }
278
279 if (obj_res[call_method].hasOwnProperty('read_count') && obj_res[call_method]['read_count']) {
280 // trigger the event to reload the badge count after having read some notifications
281 VBOCore.emitEvent('vbo-badge-count-reload');
282 }
283 } catch(err) {
284 console.error('could not parse JSON response', err, response);
285 }
286 },
287 (error) => {
288 // silently log the error
289 console.error(error);
290 }
291 );
292 });
293
294 });
295
296 </script>
297