Исправлен клик по push-уведомлению: открытие задачи/чата из тела, Ответить и Прочитано; controlled-clients + fallback openWindow
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
const CACHE_NAME = 'iistwin-pwa-v10';
|
||||
const CACHE_NAME = 'iistwin-pwa-v11';
|
||||
const STATIC_ASSETS = [
|
||||
'/',
|
||||
'/index.html',
|
||||
@@ -568,23 +568,38 @@ self.addEventListener('push', (event) => {
|
||||
});
|
||||
|
||||
async function openOrFocusChat(url) {
|
||||
const clientList = await clients.matchAll({ type: 'window', includeUncontrolled: true });
|
||||
// Prefer a client that already has the same path (ignoring query string).
|
||||
const targetPath = url.split('?')[0];
|
||||
// Only controlled clients can be navigated/focused reliably from a SW.
|
||||
const clientList = await clients.matchAll({ type: 'window', includeUncontrolled: false });
|
||||
const absoluteUrl = new URL(url, self.location.origin).href;
|
||||
const targetPath = new URL(absoluteUrl).pathname;
|
||||
|
||||
// Prefer a controlled client that already has the same path (ignoring query string).
|
||||
for (const client of clientList) {
|
||||
if (client.url.includes(self.location.origin) && client.url.split('?')[0] === targetPath && 'focus' in client) {
|
||||
await client.navigate(url);
|
||||
return client.focus();
|
||||
try {
|
||||
const clientPath = new URL(client.url).pathname;
|
||||
if (clientPath === targetPath && 'focus' in client) {
|
||||
await client.navigate(absoluteUrl);
|
||||
return await client.focus();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[SW] Failed to navigate matching client:', err);
|
||||
}
|
||||
}
|
||||
// Otherwise focus any same-origin client and navigate it.
|
||||
|
||||
// Otherwise focus any controlled same-origin client and navigate it.
|
||||
for (const client of clientList) {
|
||||
if (client.url.includes(self.location.origin) && 'focus' in client) {
|
||||
await client.navigate(url);
|
||||
return client.focus();
|
||||
try {
|
||||
if ('focus' in client) {
|
||||
await client.navigate(absoluteUrl);
|
||||
return await client.focus();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[SW] Failed to navigate client:', err);
|
||||
}
|
||||
}
|
||||
return clients.openWindow(url);
|
||||
|
||||
// No usable client — open a new window/tab. This is always allowed in notificationclick.
|
||||
return await clients.openWindow(absoluteUrl);
|
||||
}
|
||||
|
||||
async function markNotificationRead(data) {
|
||||
@@ -615,11 +630,18 @@ self.addEventListener('notificationclick', (event) => {
|
||||
const urlToOpen = data.url || '/';
|
||||
|
||||
if (event.action === 'read') {
|
||||
event.waitUntil(markNotificationRead(data));
|
||||
// "Прочитано": помечаем прочитанным и всё равно открываем задачу/чат, как ожидает пользователь.
|
||||
event.waitUntil(
|
||||
Promise.all([
|
||||
navigator.clearAppBadge ? navigator.clearAppBadge() : Promise.resolve(),
|
||||
markNotificationRead(data),
|
||||
openOrFocusChat(urlToOpen),
|
||||
])
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// 'reply' or body click: open the chat and focus an existing tab if possible.
|
||||
// Body click or 'reply' action: open the linked task/chat and focus an existing tab if possible.
|
||||
event.waitUntil(
|
||||
Promise.all([
|
||||
navigator.clearAppBadge ? navigator.clearAppBadge() : Promise.resolve(),
|
||||
|
||||
Reference in New Issue
Block a user