Push notifications: Fix focus on notification click (#1073)

This commit is contained in:
Alexander Zinchuk 2021-05-11 02:57:10 +03:00
parent bb574820a5
commit c2d6c5eae8
3 changed files with 27 additions and 22 deletions

View File

@ -12,7 +12,6 @@ import {
} from '../../../config'; } from '../../../config';
import { callApi } from '../../../api/gramjs'; import { callApi } from '../../../api/gramjs';
import { buildCollectionByKey } from '../../../util/iteratees'; import { buildCollectionByKey } from '../../../util/iteratees';
import { notifyClientReady } from '../../../util/notifications';
import { import {
replaceChatListIds, replaceChatListIds,
replaceChats, replaceChats,
@ -42,9 +41,6 @@ async function sync(afterSyncCallback: () => void) {
console.log('>>> START SYNC'); console.log('>>> START SYNC');
} }
// Notify web worker that client is ready to receive messages
notifyClientReady();
await callApi('fetchCurrentUser'); await callApi('fetchCurrentUser');
// This fetches only active chats and clears archived chats, which will be fetched in `afterSync` // This fetches only active chats and clears archived chats, which will be fetched in `afterSync`

View File

@ -64,7 +64,7 @@ function getMessageId(data: PushData) {
return parseInt(data.custom.msg_id, 10); return parseInt(data.custom.msg_id, 10);
} }
function getNotificationData(data: PushData):NotificationData { function getNotificationData(data: PushData): NotificationData {
return { return {
chatId: getChatId(data), chatId: getChatId(data),
messageId: getMessageId(data), messageId: getMessageId(data),
@ -110,21 +110,16 @@ export function handlePush(e: PushEvent) {
e.waitUntil(showNotification(notification)); e.waitUntil(showNotification(notification));
} }
function focusChatMessage(client: WindowClient, data: {chatId?: number; messageId?: number}) { function focusChatMessage(client: WindowClient, data: { chatId?: number; messageId?: number }) {
const { chatId, messageId } = data; const { chatId, messageId } = data;
if (!chatId) return;
if (chatId) { client.postMessage({
client.postMessage({ type: 'focusMessage',
type: 'focusMessage', payload: {
payload: { chatId,
chatId, messageId,
messageId, },
}, });
});
}
if (client.focus) {
client.focus();
}
} }
export function handleNotificationClick(e: NotificationEvent) { export function handleNotificationClick(e: NotificationEvent) {
@ -134,7 +129,10 @@ export function handleNotificationClick(e: NotificationEvent) {
const notifyClients = async () => { const notifyClients = async () => {
const clients = await self.clients.matchAll({ type: 'window' }) as WindowClient[]; const clients = await self.clients.matchAll({ type: 'window' }) as WindowClient[];
const clientsInScope = clients.filter((client) => client.url === self.registration.scope); const clientsInScope = clients.filter((client) => client.url === self.registration.scope);
clientsInScope.forEach((client) => focusChatMessage(client, data)); await Promise.all(clientsInScope.map(async (client) => {
await client.focus();
clickBuffer[client.id] = data;
}));
if (!self.clients.openWindow || clientsInScope.length > 0) return undefined; if (!self.clients.openWindow || clientsInScope.length > 0) return undefined;
// If there is no opened client we need to open one and wait until it is fully loaded // If there is no opened client we need to open one and wait until it is fully loaded

View File

@ -3,6 +3,7 @@ import { scriptUrl } from 'service-worker-loader!../serviceWorker';
import { DEBUG } from '../config'; import { DEBUG } from '../config';
import { getDispatch } from '../lib/teact/teactn'; import { getDispatch } from '../lib/teact/teactn';
import { IS_SERVICE_WORKER_SUPPORTED } from './environment'; import { IS_SERVICE_WORKER_SUPPORTED } from './environment';
import { notifyClientReady } from './notifications';
type WorkerAction = { type WorkerAction = {
type: string; type: string;
@ -25,6 +26,13 @@ function handleWorkerMessage(e: MessageEvent) {
} }
} }
function subscribeToWorker() {
navigator.serviceWorker.removeEventListener('message', handleWorkerMessage);
navigator.serviceWorker.addEventListener('message', handleWorkerMessage);
// Notify web worker that client is ready to receive messages
notifyClientReady();
}
if (IS_SERVICE_WORKER_SUPPORTED) { if (IS_SERVICE_WORKER_SUPPORTED) {
window.addEventListener('load', async () => { window.addEventListener('load', async () => {
try { try {
@ -42,8 +50,7 @@ if (IS_SERVICE_WORKER_SUPPORTED) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log('[SW] ServiceWorker ready'); console.log('[SW] ServiceWorker ready');
} }
subscribeToWorker();
navigator.serviceWorker.addEventListener('message', handleWorkerMessage);
} else { } else {
if (DEBUG) { if (DEBUG) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
@ -58,4 +65,8 @@ if (IS_SERVICE_WORKER_SUPPORTED) {
} }
} }
}); });
window.addEventListener('focus', async () => {
await navigator.serviceWorker.ready;
subscribeToWorker();
});
} }