basic support for push messages with actions

This commit is contained in:
Dobromir Popov
2024-05-07 11:31:59 +03:00
parent d8c11915fa
commit a8a50c76a8
3 changed files with 82 additions and 21 deletions

View File

@ -201,6 +201,42 @@ function PwaManager() {
}); });
}; };
async function sendTestReminder(event: MouseEvent<HTMLButtonElement, MouseEvent>): Promise<void> {
event.preventDefault();
if (!subscription) {
console.error('Web push not subscribed');
return;
}
await fetch('/api/notify', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ broadcast: true, message: 'Моля, въведете вашите предпочитания за юни до 25-ти май.' })
});
}
async function sendTestCoverMe(event: MouseEvent<HTMLButtonElement, MouseEvent>): Promise<void> {
event.preventDefault();
if (!subscription) {
console.error('Web push not subscribed');
return;
}
await fetch('/api/notify', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
broadcast: true, message: "Брат ТЕСТ търси заместник за 24-ти май от 10:00 ч. Можеш ли да го покриеш?",
//use fontawesome icons for actions
actions: [{ action: 'covermeaccepted', title: 'Да ', icon: '✅' }]
})
});
}
return ( return (
<> <>
<div> <div>
@ -216,24 +252,12 @@ function PwaManager() {
{isPWAInstalled && <p>App is installed!</p>} {isPWAInstalled && <p>App is installed!</p>}
{isStandAlone && <p>PWA App</p>} {isStandAlone && <p>PWA App</p>}
<button <button
onClick={subscribeToNotifications} onClick={isSubscribed ? unsubscribeFromNotifications : subscribeToNotifications}
disabled={isSubscribed} disabled={false} // Since the button itself acts as a toggle, the disabled attribute might not be needed
className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${isSubscribed ? 'cursor-not-allowed bg-gray-300 text-gray-500' : 'bg-green-500 hover:bg-green-700 text-white' className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${isSubscribed ? 'bg-red-500 hover:bg-red-700 text-white' : 'bg-green-500 hover:bg-green-700 text-white'}`} >
}`} {isSubscribed ? 'Unsubscribe from Notifications' : 'Subscribe to Notifications'}
>
Subscribe to Notifications
</button> </button>
<button </div >
onClick={unsubscribeFromNotifications}
disabled={!isSubscribed}
className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${!isSubscribed ? 'cursor-not-allowed bg-gray-300 text-gray-500' : 'bg-red-500 hover:bg-red-700 text-white'
}`}
>
Unsubscribe from Notifications
</button>
</div>
<div> <div>
<button <button
onClick={sendTestNotification} onClick={sendTestNotification}
@ -243,6 +267,22 @@ function PwaManager() {
> >
Send Test Notification Send Test Notification
</button> </button>
<button
onClick={sendTestReminder}
disabled={!isSubscribed}
className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${!isSubscribed ? 'cursor-not-allowed bg-gray-300 text-gray-500' : 'bg-yellow-500 hover:bg-yellow-600 text-white'
}`}
>
Send Reminder
</button>
<button
onClick={sendTestCoverMe}
disabled={!isSubscribed}
className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${!isSubscribed ? 'cursor-not-allowed bg-gray-300 text-gray-500' : 'bg-yellow-500 hover:bg-yellow-600 text-white'
}`}
>
Send CoverMe
</button>
{notificationPermission !== "granted" && ( {notificationPermission !== "granted" && (
<button <button

View File

@ -59,7 +59,7 @@ const Notification = async (req, res) => {
if (req.method == 'POST') {//title = "ССС", message = "Ще получите уведомление по този начин.") if (req.method == 'POST') {//title = "ССС", message = "Ще получите уведомление по този начин.")
const { subscription, id, broadcast, title = 'ССОМ', message = 'Ще получавате уведомления така.' } = req.body const { subscription, id, broadcast, title = 'ССОМ', message = 'Ще получавате уведомления така.', actions } = req.body
if (broadcast) { if (broadcast) {
await broadcastPush(title, message) await broadcastPush(title, message)
res.statusCode = 200 res.statusCode = 200
@ -75,7 +75,7 @@ const Notification = async (req, res) => {
await webPush await webPush
.sendNotification( .sendNotification(
subscription, subscription,
JSON.stringify({ title, message }) JSON.stringify({ title, message, actions })
) )
.then(response => { .then(response => {
res.writeHead(response.statusCode, response.headers).end(response.body) res.writeHead(response.statusCode, response.headers).end(response.body)

View File

@ -21,18 +21,39 @@ self.addEventListener('push', function (event) {
return return
} }
const data = JSON.parse(event.data.text()) const data = JSON.parse(event.data.text())
console.log('SW: Push data', data)
actions: [
//font awesome icons
{ action: 'accept', title: 'Accept', icon: 'fa fa-check' },
{ action: 'decline', title: 'Decline', icon: 'fa fa-times' }
]
event.waitUntil( event.waitUntil(
registration.showNotification(data.title, { registration.showNotification(data.title, {
body: data.message, body: data.message,
icon: '/favicon.ico', icon: '/favicon.ico',
actions: data.actions, actions: [...data.actions, { action: 'close', title: 'Close', icon: 'fa fa-times' }],
data: data.url,
}) })
) )
}) })
self.addEventListener('notificationclick', function (event) { self.addEventListener('notificationclick', function (event) {
console.log('Notification click: tag', event.notification.tag) console.log('Notification click: tag', event.notification.tag, 'action', event.action)
event.notification.close() event.notification.close()
switch (event.action) {
case 'accept':
console.log('User accepted the action.');
// handle acceptance
break;
case 'decline':
console.log('User declined the action.');
// handle decline
break;
default:
// handle other cases
break;
}
console.log(event)
event.waitUntil( event.waitUntil(
clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function (clientList) { clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function (clientList) {
if (clientList.length > 0) { if (clientList.length > 0) {