basic support for push messages with actions
This commit is contained in:
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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) {
|
||||||
|
Reference in New Issue
Block a user