Skip to content

Commit

Permalink
Load webpush JS globally to request notification permission from user…
Browse files Browse the repository at this point in the history
… on any page.
  • Loading branch information
rxu committed Jan 11, 2024
1 parent a092642 commit 37ac4fd
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 35 deletions.
1 change: 1 addition & 0 deletions config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ services:
- '@phpbb.wpn.form_helper'
- '@language'
- '@template'
- '@notification.method.phpbb.wpn.webpush'
tags:
- { name: event.listener }

Expand Down
17 changes: 10 additions & 7 deletions event/listener.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use phpbb\controller\helper as controller_helper;
use phpbb\webpushnotifications\form\form_helper;
use phpbb\webpushnotifications\notification\method\webpush;
use phpbb\language\language;
use phpbb\template\template;

Expand All @@ -27,7 +28,7 @@ class listener implements EventSubscriberInterface
public static function getSubscribedEvents()
{
return [
'core.ucp_notifications_output_notification_types_modify_template_vars' => 'load_template_data',
'core.page_header' => 'load_template_data',
'core.ucp_display_module_before' => 'load_language',
'core.acp_main_notice' => 'compatibility_notice',
];
Expand All @@ -45,20 +46,25 @@ public static function getSubscribedEvents()
/* @var template */
protected $template;

/* @var webpush */
protected $webpush;

/**
* Constructor
*
* @param controller_helper $controller_helper Controller helper object
* @param form_helper $form_helper Form helper object
* @param language $language Language object
* @param template $template Template object
* @param webpush $webpush Webpush notification method object
*/
public function __construct(controller_helper $controller_helper, form_helper $form_helper, language $language, template $template)
public function __construct(controller_helper $controller_helper, form_helper $form_helper, language $language, template $template, webpush $webpush)
{
$this->controller_helper = $controller_helper;
$this->form_helper = $form_helper;
$this->language = $language;
$this->template = $template;
$this->webpush = $webpush;
}

/**
Expand All @@ -68,11 +74,8 @@ public function __construct(controller_helper $controller_helper, form_helper $f
*/
public function load_template_data($event)
{
if ($event['method_data']['id'] === 'notification.method.phpbb.wpn.webpush')
{
$template_ary = $event['method_data']['method']->get_ucp_template_data($this->controller_helper, $this->form_helper);
$this->template->assign_vars($template_ary);
}
$template_ary = $this->webpush->get_ucp_template_data($this->controller_helper, $this->form_helper);
$this->template->assign_vars($template_ary);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
{% if NOTIFICATIONS_WEBPUSH_ENABLE %}
{% include('@phpbb_webpushnotifications/ucp_notifications_webpush.html') %}
{% endif %}
112 changes: 86 additions & 26 deletions styles/all/template/webpush.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,27 +49,29 @@ function PhpbbWebpush() {
subscribeButton = document.querySelector('#subscribe_webpush');
unsubscribeButton = document.querySelector('#unsubscribe_webpush');

// Service workers are only supported in secure context
if (window.isSecureContext !== true) {
subscribeButton.disabled = true;
return;
}

if ('serviceWorker' in navigator && 'PushManager' in window) {
navigator.serviceWorker.register(serviceWorkerUrl)
.then(() => {
subscribeButton.addEventListener('click', subscribeButtonHandler);
unsubscribeButton.addEventListener('click', unsubscribeButtonHandler);
if (subscribeButton && unsubscribeButton) {
// Service workers are only supported in secure context
if (window.isSecureContext !== true) {
subscribeButton.disabled = true;
return;
}

updateButtonState();
})
.catch(error => {
console.info(error);
// Service worker could not be registered
subscribeButton.disabled = true;
});
} else {
subscribeButton.disabled = true;
if ('serviceWorker' in navigator && 'PushManager' in window) {
navigator.serviceWorker.register(serviceWorkerUrl)
.then(() => {
subscribeButton.addEventListener('click', subscribeButtonHandler);
unsubscribeButton.addEventListener('click', unsubscribeButtonHandler);

updateButtonState();
})
.catch(error => {
console.info(error);
// Service worker could not be registered
subscribeButton.disabled = true;
});
} else {
subscribeButton.disabled = true;
}
}
};

Expand Down Expand Up @@ -127,12 +129,14 @@ function PhpbbWebpush() {
* @param {boolean} subscribed True if subscribed, false if not
*/
function setSubscriptionState(subscribed) {
if (subscribed) {
subscribeButton.classList.add('hidden');
unsubscribeButton.classList.remove('hidden');
} else {
subscribeButton.classList.remove('hidden');
unsubscribeButton.classList.add('hidden');
if (subscribeButton && unsubscribeButton) {
if (subscribed) {
subscribeButton.classList.add('hidden');
unsubscribeButton.classList.remove('hidden');
} else {
subscribeButton.classList.remove('hidden');
unsubscribeButton.classList.add('hidden');
}
}
}

Expand Down Expand Up @@ -282,6 +286,61 @@ function PhpbbWebpush() {

return outputArray;
}

/**
* Handler for sending web push notification request to browser
*
* @returns {Promise<void>}
*/
this.sendWebpushRequestToBrowser = async function() {

const permission = Notification.permission;
if (permission !== 'granted' && permission !== 'denied') {
// Prevent the user from clicking the subscribe button multiple times.
const result = await Notification.requestPermission();
if (result === 'denied') {
return;
} else if (result === 'granted') {

subscribeButton = document.querySelector('#subscribe_webpush');
unsubscribeButton = document.querySelector('#unsubscribe_webpush');

const registration = await navigator.serviceWorker.getRegistration(serviceWorkerUrl);

// We might already have a subscription that is unknown to this instance of phpBB.
// Unsubscribe before trying to subscribe again.
if (typeof registration !== 'undefined') {
const subscribed = await registration.pushManager.getSubscription();
if (subscribed) {
await subscribed.unsubscribe();
}
}

const newSubscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlB64ToUint8Array(vapidPublicKey),
});

fetch(subscribeUrl, {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest',
},
body: getFormData(newSubscription),
})
.then(response => {
if (subscribeButton && unsubscribeButton) {
updateButtonState();
}
return response.json();
})
.then(handleSubscribe)
.catch(error => {
phpbb.alert(ajaxErrorTitle, error);
});
}
}
}
}

function domReady(callBack) {
Expand All @@ -297,4 +356,5 @@ phpbb.webpush = new PhpbbWebpush();
domReady(() => {
/* global phpbbWebpushOptions */
phpbb.webpush.init(phpbbWebpushOptions);
phpbb.webpush.sendWebpushRequestToBrowser();
});

0 comments on commit 37ac4fd

Please sign in to comment.