Skip to content

Commit e9af8d0

Browse files
authored
Merge pull request #120 from iMattPro/fixes
More improvements to popup prompt
2 parents db06ede + 4d45624 commit e9af8d0

File tree

14 files changed

+396
-25
lines changed

14 files changed

+396
-25
lines changed

config/wpn_ucp.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@ phpbb_webpushnotifications_ucp_push_subscribe_controller:
1313
phpbb_webpushnotifications_ucp_push_unsubscribe_controller:
1414
path: /push/unsubscribe
1515
defaults: { _controller: phpbb.wpn.ucp.controller.webpush:unsubscribe }
16+
17+
phpbb_webpushnotifications_ucp_push_toggle_popup_controller:
18+
path: /push/toggle-popup
19+
defaults: { _controller: phpbb.wpn.ucp.controller.webpush:toggle_popup }

controller/manifest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function handle(): JsonResponse
4444
{
4545
// Get the board URL and extract the path component
4646
$board_url = generate_board_url();
47-
$board_path = $this->config['force_server_vars'] ? $this->config['script_path'] : (parse_url($board_url)['path'] ?? '');
47+
$board_path = $this->config['force_server_vars'] ? $this->config['script_path'] : (parse_url($board_url, PHP_URL_PATH) ?? '');
4848

4949
// Ensure path ends with '/' for PWA scope
5050
$scope = rtrim($board_path, '/\\') . '/';

language/en/webpushnotifications_module_ucp.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,10 @@
4949
'NOTIFY_WEBPUSH_DROPDOWN_TITLE' => 'Visit notifications settings to set your preferred push notifications.',
5050
'NOTIFY_WEBPUSH_DENIED' => 'You have denied notifications from this site. To enable push notifications, allow notifications from this site in your browser settings.',
5151
'NOTIFY_WEBPUSH_NOT_SUPPORTED' => 'Push notifications not supported',
52-
'NOTIFY_WEBPUSH_POPUP_TITLE' => 'Allow browser notifications?',
52+
'NOTIFY_WEBPUSH_POPUP_TITLE' => 'Allow browser notifications',
5353
'NOTIFY_WEBPUSH_POPUP_MESSAGE' => 'We would like to send you browser notifications for replies, private messages, and relevant forum activity. Optional — you can manage these settings at any time.',
5454
'NOTIFY_WEBPUSH_POPUP_ALLOW' => 'Allow',
5555
'NOTIFY_WEBPUSH_POPUP_DENY' => 'Deny',
56+
'NOTIFY_WEBPUSH_POPUP_DISABLE' => 'Disable “Allow Browser Notifications” prompts',
57+
'NOTIFY_WEBPUSH_POPUP_DISABLE_EXPLAIN' => 'Toggle this on to stop us from asking you to enable web push notifications on any of your devices. Note that we won’t be able to alert you if your web push notifications ever become disabled.',
5658
]);

language/ru/webpushnotifications_module_ucp.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,12 @@
4747
'NOTIFY_WEBPUSH_SUBSCRIBE' => 'Подписаться',
4848
'NOTIFY_WEBPUSH_UNSUBSCRIBE' => 'Отписаться',
4949
'NOTIFY_WEBPUSH_DROPDOWN_TITLE' => 'Посетите настройки уведомлений, чтобы установить предпочтительные типы браузерных уведомлений.',
50-
'NOTIFY_WEBPUSH_DENIED' => 'Вы запретили браузерные уведомления для даного сайта. Для того, чтобы подписаться, необходимо их разрешить в настройках браузера.',
50+
'NOTIFY_WEBPUSH_DENIED' => 'Вы запретили браузерные уведомления для данного сайта. Для того, чтобы подписаться, необходимо их разрешить в настройках браузера.',
5151
'NOTIFY_WEBPUSH_NOT_SUPPORTED' => 'Не поддерживается',
52-
'NOTIFY_WEBPUSH_POPUP_TITLE' => 'Включить браузерные уведомления?',
52+
'NOTIFY_WEBPUSH_POPUP_TITLE' => 'Включить браузерные уведомления',
5353
'NOTIFY_WEBPUSH_POPUP_MESSAGE' => 'Браузерные уведомления позволяют быстро получать информацию о новых ответах, личных сообщениях и других активностях на данной конференции. Функцию можно отключить или включить в любое время в настройках уведомлений в Личном разделе.',
5454
'NOTIFY_WEBPUSH_POPUP_ALLOW' => 'Включить',
5555
'NOTIFY_WEBPUSH_POPUP_DENY' => 'Отклонить',
56+
'NOTIFY_WEBPUSH_POPUP_DISABLE' => 'Отключить запросы «Включить браузерные уведомления»',
57+
'NOTIFY_WEBPUSH_POPUP_DISABLE_EXPLAIN' => 'Включите этот параметр, чтобы мы больше не спрашивали вас о включении веб-push-уведомлений на любом из ваших устройств. Обратите внимание, что в этом случае мы не сможем предупредить вас, если веб-push-уведомления будут отключены.',
5658
]);
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
/**
3+
*
4+
* phpBB Browser Push Notifications. An extension for the phpBB Forum Software package.
5+
*
6+
* @copyright (c) 2025, phpBB Limited <https://www.phpbb.com>
7+
* @license GNU General Public License, version 2 (GPL-2.0)
8+
*
9+
*/
10+
11+
namespace phpbb\webpushnotifications\migrations;
12+
13+
use phpbb\db\migration\migration;
14+
15+
class add_user_popup_preference extends migration
16+
{
17+
public function effectively_installed()
18+
{
19+
return $this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_wpn_popup_disabled');
20+
}
21+
22+
public static function depends_on()
23+
{
24+
return ['\phpbb\webpushnotifications\migrations\add_popup_prompt'];
25+
}
26+
27+
public function update_schema()
28+
{
29+
return [
30+
'add_columns' => [
31+
$this->table_prefix . 'users' => [
32+
'user_wpn_popup_disabled' => ['BOOL', 0],
33+
],
34+
],
35+
];
36+
}
37+
38+
public function revert_schema()
39+
{
40+
return [
41+
'drop_columns' => [
42+
$this->table_prefix . 'users' => [
43+
'user_wpn_popup_disabled',
44+
],
45+
],
46+
];
47+
}
48+
}

notification/method/webpush.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,11 +390,13 @@ public function get_ucp_template_data(helper $controller_helper, form_helper $fo
390390
'NOTIFICATIONS_WEBPUSH_ENABLE' => ($this->config['load_notifications'] && $this->config['allow_board_notifications'] && $this->config['wpn_webpush_dropdown_subscribe']) || stripos($this->user->page['page'], 'notification_options'),
391391
'U_WEBPUSH_SUBSCRIBE' => $controller_helper->route('phpbb_webpushnotifications_ucp_push_subscribe_controller'),
392392
'U_WEBPUSH_UNSUBSCRIBE' => $controller_helper->route('phpbb_webpushnotifications_ucp_push_unsubscribe_controller'),
393+
'U_WEBPUSH_TOGGLE_POPUP' => $controller_helper->route('phpbb_webpushnotifications_ucp_push_toggle_popup_controller'),
393394
'VAPID_PUBLIC_KEY' => $this->config['wpn_webpush_vapid_public'],
394395
'U_WEBPUSH_WORKER_URL' => $controller_helper->route('phpbb_webpushnotifications_ucp_push_worker_controller'),
395396
'SUBSCRIPTIONS' => $subscriptions,
396397
'WEBPUSH_FORM_TOKENS' => $form_helper->get_form_tokens(\phpbb\webpushnotifications\ucp\controller\webpush::FORM_TOKEN_UCP),
397-
'S_WEBPUSH_POPUP_PROMPT' => $this->config['wpn_webpush_popup_prompt'] && $this->user->id() != ANONYMOUS && $this->user->data['user_type'] != USER_IGNORE,
398+
'S_WEBPUSH_POPUP_PROMPT' => $this->config['wpn_webpush_popup_prompt'] && $this->user->id() != ANONYMOUS && $this->user->data['user_type'] != USER_IGNORE && !($this->user->data['user_wpn_popup_disabled'] ?? 0),
399+
'S_WEBPUSH_POPUP_DISABLED' => $this->user->data['user_wpn_popup_disabled'] ?? 0,
398400
];
399401
}
400402

styles/all/template/ucp_notifications_webpush.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
serviceWorkerUrl: '{{ U_WEBPUSH_WORKER_URL }}',
44
subscribeUrl: '{{ U_WEBPUSH_SUBSCRIBE }}',
55
unsubscribeUrl: '{{ U_WEBPUSH_UNSUBSCRIBE }}',
6+
togglePopupUrl: '{{ U_WEBPUSH_TOGGLE_POPUP }}',
67
ajaxErrorTitle: '{{ lang_js('AJAX_ERROR_TITLE') }}',
78
vapidPublicKey: '{{ VAPID_PUBLIC_KEY }}',
89
formTokens: {

styles/all/template/webpush.js

Lines changed: 91 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ function PhpbbWebpush() {
3333
/** @type {HTMLElement} Unsubscribe button */
3434
let unsubscribeButton;
3535

36+
/** @type {HTMLElement} Toggle popup button */
37+
let togglePopupButton;
38+
39+
/** @type {string} URL to toggle popup prompt preference */
40+
let togglePopupUrl = '';
41+
42+
/** @type {function} Escape key handler for popup */
43+
let popupEscapeHandler;
44+
3645
/**
3746
* Init function for phpBB Web Push
3847
* @type {array} options
@@ -41,13 +50,20 @@ function PhpbbWebpush() {
4150
serviceWorkerUrl = options.serviceWorkerUrl;
4251
subscribeUrl = options.subscribeUrl;
4352
unsubscribeUrl = options.unsubscribeUrl;
53+
togglePopupUrl = options.togglePopupUrl;
4454
this.formTokens = options.formTokens;
4555
subscriptions = options.subscriptions;
4656
ajaxErrorTitle = options.ajaxErrorTitle;
4757
vapidPublicKey = options.vapidPublicKey;
4858

4959
subscribeButton = document.querySelector('#subscribe_webpush');
5060
unsubscribeButton = document.querySelector('#unsubscribe_webpush');
61+
togglePopupButton = document.querySelector('#toggle_popup_prompt');
62+
63+
// Set up toggle popup button handler if it exists (on UCP settings page)
64+
if (togglePopupButton) {
65+
togglePopupButton.addEventListener('click', togglePopupHandler);
66+
}
5167

5268
// Service workers are only supported in secure context
5369
if (window.isSecureContext !== true) {
@@ -163,7 +179,7 @@ function PhpbbWebpush() {
163179
if (allowBtn) {
164180
allowBtn.addEventListener('click', (event) => {
165181
event.stopPropagation();
166-
popup.style.display = 'none';
182+
hidePopup(popup);
167183
subscribeButtonHandler(event).catch(error => {
168184
console.error('Subscription handler error:', error);
169185
});
@@ -173,19 +189,40 @@ function PhpbbWebpush() {
173189
if (denyBtn) {
174190
denyBtn.addEventListener('click', (event) => {
175191
event.stopPropagation();
176-
popup.style.display = 'none';
192+
hidePopup(popup);
177193
promptDenied.set();
178194
});
179195
}
180196

181197
if (overlay) {
182198
overlay.addEventListener('click', (event) => {
183199
if (event.target === overlay) {
184-
popup.style.display = 'none';
200+
hidePopup(popup);
185201
promptDenied.set();
186202
}
187203
});
204+
205+
popupEscapeHandler = (event) => {
206+
if (event.key === 'Escape') {
207+
hidePopup(popup);
208+
promptDenied.set();
209+
}
210+
};
211+
212+
document.addEventListener('keydown', popupEscapeHandler);
213+
}
214+
}
215+
216+
/**
217+
* Hide popup
218+
* @param popup
219+
*/
220+
function hidePopup(popup) {
221+
if (popup) {
222+
popup.style.display = 'none';
188223
}
224+
document.removeEventListener('keydown', popupEscapeHandler);
225+
popupEscapeHandler = null;
189226
}
190227

191228
/**
@@ -282,10 +319,7 @@ function PhpbbWebpush() {
282319
});
283320
} catch (error) {
284321
promptDenied.set(); // deny the prompt on error to prevent repeated prompting
285-
const popup = document.getElementById('wpn_popup_prompt');
286-
if (popup) {
287-
popup.style.display = 'none';
288-
}
322+
hidePopup(document.getElementById('wpn_popup_prompt'));
289323
console.error('Push subscription error:', error);
290324
phpbb.alert(subscribeButton.getAttribute('data-l-err'), error.message || subscribeButton.getAttribute('data-l-unsupported'));
291325
} finally {
@@ -331,6 +365,55 @@ function PhpbbWebpush() {
331365
});
332366
}
333367

368+
/**
369+
* Handler for toggle popup prompt button
370+
*
371+
* @param {Object} event Toggle button push event
372+
*/
373+
function togglePopupHandler(event) {
374+
event.preventDefault();
375+
376+
const loadingIndicator = phpbb.loadingIndicator();
377+
const formData = new FormData();
378+
formData.append('form_token', phpbb.webpush.formTokens.formToken);
379+
formData.append('creation_time', phpbb.webpush.formTokens.creationTime.toString());
380+
381+
fetch(togglePopupUrl, {
382+
method: 'POST',
383+
headers: {
384+
'X-Requested-With': 'XMLHttpRequest',
385+
},
386+
body: formData,
387+
})
388+
.then(response => response.json())
389+
.then(data => {
390+
loadingIndicator.fadeOut(phpbb.alertTime);
391+
if (data.success) {
392+
// Update toggle icon based on new state
393+
const button = document.getElementById('toggle_popup_prompt');
394+
if (button) {
395+
const icon = button.querySelector('i');
396+
if (icon) {
397+
if (data.disabled) {
398+
icon.classList.remove('fa-toggle-off');
399+
icon.classList.add('fa-toggle-on');
400+
} else {
401+
icon.classList.remove('fa-toggle-on');
402+
icon.classList.add('fa-toggle-off');
403+
}
404+
}
405+
}
406+
if ('form_tokens' in data) {
407+
updateFormTokens(data.form_tokens);
408+
}
409+
}
410+
})
411+
.catch(error => {
412+
loadingIndicator.fadeOut(phpbb.alertTime);
413+
phpbb.alert(ajaxErrorTitle, error);
414+
});
415+
}
416+
334417
/**
335418
* Handle subscribe response
336419
*
@@ -343,10 +426,7 @@ function PhpbbWebpush() {
343426
updateFormTokens(response.form_tokens);
344427
}
345428
promptDenied.remove();
346-
const popup = document.getElementById('wpn_popup_prompt');
347-
if (popup) {
348-
popup.style.display = 'none';
349-
}
429+
hidePopup(document.getElementById('wpn_popup_prompt'));
350430
}
351431
}
352432

styles/all/template/webpush_popup.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{% if S_WEBPUSH_POPUP_PROMPT %}
2-
<div id="wpn_popup_prompt" class="wpn-popup-overlay" style="display:none;">
2+
<div id="wpn_popup_prompt" class="wpn-popup-overlay" style="display:none;" role="dialog" aria-modal="true" aria-labelledby="wpn_popup_title" aria-describedby="wpn_popup_message">
33
<div class="wpn-popup-container">
44
<div class="wpn-popup-content">
5-
<h3 class="wpn-popup-title">
5+
<h3 id="wpn_popup_title" class="wpn-popup-title">
66
<span>{{ lang('NOTIFY_WEBPUSH_POPUP_TITLE') }}</span>
7-
<span class="fa-stack fa-lg">
7+
<span class="fa-stack fa-lg" aria-hidden="true">
88
<i class="fa fa-circle fa-stack-2x"></i>
99
<i class="fa fa-bell fa-stack-1x fa-inverse"></i>
1010
</span>
1111
</h3>
12-
<p class="wpn-popup-message">{{ lang('NOTIFY_WEBPUSH_POPUP_MESSAGE') }}</p>
12+
<p id="wpn_popup_message" class="wpn-popup-message">{{ lang('NOTIFY_WEBPUSH_POPUP_MESSAGE') }}</p>
1313
<div class="wpn-popup-buttons">
1414
<button id="wpn_popup_allow" class="wpn-popup-btn wpn-popup-btn-allow">{{ lang('NOTIFY_WEBPUSH_POPUP_ALLOW') }}</button>
1515
<button id="wpn_popup_deny" class="wpn-popup-btn wpn-popup-btn-deny">{{ lang('NOTIFY_WEBPUSH_POPUP_DENY') }}</button>

styles/all/theme/phpbb_wpn.css

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,43 @@
1616
margin: 0 0 8px;
1717
}
1818

19+
.wpn-fieldset {
20+
display: grid;
21+
column-gap: 1rem;
22+
grid-template-columns: 1fr 320px;
23+
row-gap: 1.25rem;
24+
}
25+
26+
.wpn-fieldset > dl {
27+
display: contents;
28+
}
29+
30+
/* Optional styling */
31+
.wpn-fieldset dt {
32+
float: none;
33+
align-self: start;
34+
width: auto;
35+
}
36+
37+
.wpn-fieldset dd {
38+
display: flex;
39+
align-items: center;
40+
margin: 0;
41+
}
42+
43+
.wpn-fieldset dt label {
44+
line-height: 1.4;
45+
display: inline-block;
46+
}
47+
48+
.wpn-fieldset .fa-toggle-on {
49+
color: #105289;
50+
}
51+
52+
.wpn-fieldset .fa-toggle-off {
53+
color: #5d5d5d;
54+
}
55+
1956
.wpn-notification-dropdown-footer {
2057
font-size: 12px;
2158
white-space: nowrap;
@@ -47,8 +84,17 @@
4784
}
4885

4986
@media (max-width: 700px) {
50-
.wpn.button {
51-
margin-top: 8px;
87+
.wpn-fieldset {
88+
grid-template-columns: 1fr;
89+
row-gap: 0.5rem;
90+
}
91+
92+
.wpn-fieldset dt {
93+
grid-column: 1;
94+
}
95+
96+
.wpn-fieldset dd {
97+
grid-column: 1;
5298
}
5399
}
54100

0 commit comments

Comments
 (0)