feat: web push notifications, image fullscreen, public room browser
- Web Push: push_sw.js service worker + VAPID subscription registered on login; Matrix pusher registered pointing to Sygnal on https://matrix.m8chat.au/_matrix/push/v1/notify - Chat: tap image -> fullscreen InteractiveViewer (pinch/zoom) - Rooms: public room browser via Matrix room directory (FAB + empty state) Build fixes applied to web_push_service.dart: - dart:js_interop_unsafe import added for getProperty on JSObject - client.setPusher -> client.postPusher (matrix 0.33.0 API) - keyBytes.toJS removed (JSUint8Array already a JS type) - register() script URL coerced with .toJS (String -> JSAny) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
64
web/push_sw.js
Normal file
64
web/push_sw.js
Normal file
@@ -0,0 +1,64 @@
|
||||
// Version: 1.0.0 | Created: 2026-04-27
|
||||
// Web Push service worker for M8Chat.
|
||||
// Receives push events from the browser and shows system notifications.
|
||||
// This script is registered separately from flutter_service_worker.js.
|
||||
|
||||
'use strict';
|
||||
|
||||
self.addEventListener('push', function (event) {
|
||||
if (!event.data) return;
|
||||
|
||||
let data = {};
|
||||
try {
|
||||
data = event.data.json();
|
||||
} catch (_) {
|
||||
data = { notification: { body: event.data.text() } };
|
||||
}
|
||||
|
||||
// Sygnal delivers: { notification: { content: { body, msgtype, ... }, room_name, sender_display_name, ... } }
|
||||
const notif = data.notification || {};
|
||||
const content = notif.content || {};
|
||||
|
||||
const sender = notif.sender_display_name || notif.sender || 'M8Chat';
|
||||
const room = notif.room_name || notif.room_alias || '';
|
||||
const body = content.body || notif.body || 'New message';
|
||||
|
||||
const title = room ? `${sender} in ${room}` : sender;
|
||||
|
||||
const options = {
|
||||
body: body,
|
||||
icon: '/icons/Icon-192.png',
|
||||
badge: '/icons/Icon-192.png',
|
||||
tag: notif.room_id || 'm8chat',
|
||||
data: {
|
||||
roomId: notif.room_id,
|
||||
url: self.location.origin + (notif.room_id
|
||||
? '/rooms/' + encodeURIComponent(notif.room_id)
|
||||
: '/rooms'),
|
||||
},
|
||||
requireInteraction: false,
|
||||
};
|
||||
|
||||
event.waitUntil(self.registration.showNotification(title, options));
|
||||
});
|
||||
|
||||
self.addEventListener('notificationclick', function (event) {
|
||||
event.notification.close();
|
||||
|
||||
const url = (event.notification.data && event.notification.data.url)
|
||||
? event.notification.data.url
|
||||
: self.location.origin + '/rooms';
|
||||
|
||||
event.waitUntil(
|
||||
clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function (clientList) {
|
||||
for (const client of clientList) {
|
||||
if (client.url === url && 'focus' in client) {
|
||||
return client.focus();
|
||||
}
|
||||
}
|
||||
if (clients.openWindow) {
|
||||
return clients.openWindow(url);
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user