Notifications: Various fixes, support local notifications (#1064)
This commit is contained in:
parent
146a0db3c2
commit
1a017f2750
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
@ -5,25 +5,22 @@
|
||||
"gcm_sender_id": "795646555577",
|
||||
"icons": [
|
||||
{
|
||||
"src": "android-chrome-192x192.png",
|
||||
"src": "icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "android-chrome-384x384.png",
|
||||
"src": "icon-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "android-chrome-512x512.png",
|
||||
"src": "icon-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone",
|
||||
"permissions": [
|
||||
"notifications"
|
||||
]
|
||||
"display": "standalone"
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ import {
|
||||
MEDIA_PROGRESSIVE_CACHE_NAME,
|
||||
} from '../../../config';
|
||||
import { initApi, callApi } from '../../../api/gramjs';
|
||||
import { unsubscribeFromPush } from '../../../util/pushNotifications';
|
||||
import { unsubscribe } from '../../../util/notifications';
|
||||
import * as cacheApi from '../../../util/cacheApi';
|
||||
|
||||
addReducer('initApi', (global: GlobalState, actions) => {
|
||||
@ -107,7 +107,7 @@ addReducer('saveSession', (global, actions, payload) => {
|
||||
|
||||
addReducer('signOut', () => {
|
||||
(async () => {
|
||||
await unsubscribeFromPush();
|
||||
await unsubscribe();
|
||||
await callApi('destroy');
|
||||
|
||||
getDispatch().reset();
|
||||
|
||||
@ -12,7 +12,7 @@ import {
|
||||
} from '../../../config';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { notifyClientReady } from '../../../util/pushNotifications';
|
||||
import { notifyClientReady } from '../../../util/notifications';
|
||||
import {
|
||||
replaceChatListIds,
|
||||
replaceChats,
|
||||
|
||||
@ -4,6 +4,7 @@ import { ApiUpdate } from '../../../api/types';
|
||||
|
||||
import { ARCHIVED_FOLDER_ID, MAX_ACTIVE_PINNED_CHATS } from '../../../config';
|
||||
import { pick } from '../../../util/iteratees';
|
||||
import { showNewMessageNotification } from '../../../util/notifications';
|
||||
import {
|
||||
updateChat,
|
||||
replaceChatListIds,
|
||||
@ -110,6 +111,7 @@ addReducer('apiUpdate', (global, actions, update: ApiUpdate) => {
|
||||
actions.requestChatUpdate({ chatId: update.chatId });
|
||||
}, CURRENT_CHAT_UNREAD_DELAY);
|
||||
} else {
|
||||
showNewMessageNotification({ chat, message });
|
||||
setGlobal(updateChat(global, update.chatId, {
|
||||
unreadCount: chat.unreadCount ? chat.unreadCount + 1 : 1,
|
||||
...(update.message.hasUnreadMention && {
|
||||
|
||||
@ -12,7 +12,7 @@ import {
|
||||
ApiUpdateCurrentUser,
|
||||
} from '../../../api/types';
|
||||
import { DEBUG } from '../../../config';
|
||||
import { subscribeToPush } from '../../../util/pushNotifications';
|
||||
import { subscribe } from '../../../util/notifications';
|
||||
import { updateUser } from '../../reducers';
|
||||
import { setLanguage } from '../../../util/langProvider';
|
||||
|
||||
@ -57,7 +57,7 @@ addReducer('apiUpdate', (global, actions, update: ApiUpdate) => {
|
||||
});
|
||||
|
||||
function onUpdateApiReady(global: GlobalState) {
|
||||
subscribeToPush();
|
||||
subscribe();
|
||||
setLanguage(global.settings.byKey.language);
|
||||
}
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@ export function getMessageSummaryText(message: ApiMessage, noEmoji = false) {
|
||||
}
|
||||
|
||||
if (sticker) {
|
||||
return `Sticker ${sticker.emoji}`;
|
||||
return `${sticker.emoji} Sticker`;
|
||||
}
|
||||
|
||||
if (audio) {
|
||||
@ -107,6 +107,60 @@ export function getMessageSummaryText(message: ApiMessage, noEmoji = false) {
|
||||
return CONTENT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
export function getNotificationText(message: ApiMessage) {
|
||||
const {
|
||||
text, photo, video, audio, voice, document, sticker, contact, poll, invoice,
|
||||
} = message.content;
|
||||
|
||||
if (message.groupedId) {
|
||||
return `🖼 ${text ? text.text : 'Album'}`;
|
||||
}
|
||||
|
||||
if (photo) {
|
||||
return `🖼 ${text ? text.text : 'Photo'}`;
|
||||
}
|
||||
|
||||
if (video) {
|
||||
return `📹 ${text ? text.text : video.isGif ? 'GIF' : 'Video'}`;
|
||||
}
|
||||
|
||||
if (sticker) {
|
||||
return `${sticker.emoji} Sticker `;
|
||||
}
|
||||
|
||||
if (audio) {
|
||||
const caption = [audio.title, audio.performer].filter(Boolean).join(' — ') || (text && text.text);
|
||||
return `🎧 ${caption || 'Audio'}`;
|
||||
}
|
||||
|
||||
if (voice) {
|
||||
return `🎤 ${text ? text.text : 'Voice Message'}`;
|
||||
}
|
||||
|
||||
if (document) {
|
||||
return `📎 ${text ? text.text : document.fileName}`;
|
||||
}
|
||||
|
||||
if (contact) {
|
||||
return 'Contact';
|
||||
}
|
||||
|
||||
if (poll) {
|
||||
return `📊 ${poll.summary.question}`;
|
||||
}
|
||||
|
||||
if (invoice) {
|
||||
return 'Invoice';
|
||||
}
|
||||
|
||||
if (text) {
|
||||
return text.text;
|
||||
}
|
||||
|
||||
return CONTENT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
export function getMessageText(message: ApiMessage) {
|
||||
const {
|
||||
text, sticker, photo, video, audio, voice, document, poll, webPage, contact, invoice,
|
||||
|
||||
@ -24,6 +24,7 @@ export type NotificationData = {
|
||||
};
|
||||
|
||||
const clickBuffer: Record<string, NotificationData> = {};
|
||||
const shownNotifications = new Set();
|
||||
|
||||
function getPushData(e: PushEvent | Notification): NotificationData | undefined {
|
||||
try {
|
||||
@ -51,6 +52,13 @@ export function handlePush(e: PushEvent) {
|
||||
// Do not show muted notifications
|
||||
if (!data || data.mute === Boolean.True) return;
|
||||
|
||||
// Dont show already triggered notification
|
||||
const messageId = getMessageId(data);
|
||||
if (shownNotifications.has(messageId)) {
|
||||
shownNotifications.delete(messageId);
|
||||
return;
|
||||
}
|
||||
|
||||
const title = data.title || process.env.APP_INFO!;
|
||||
const body = data.description;
|
||||
|
||||
@ -58,7 +66,9 @@ export function handlePush(e: PushEvent) {
|
||||
self.registration.showNotification(title, {
|
||||
body,
|
||||
data,
|
||||
icon: 'android-chrome-192x192.png',
|
||||
icon: 'icon-192x192.png',
|
||||
badge: 'icon-192x192.png',
|
||||
vibrate: [200, 100, 200],
|
||||
}),
|
||||
);
|
||||
}
|
||||
@ -103,7 +113,6 @@ function focusChatMessage(client: WindowClient, data: NotificationData) {
|
||||
export function handleNotificationClick(e: NotificationEvent) {
|
||||
const appUrl = process.env.APP_URL!;
|
||||
e.notification.close(); // Android needs explicit close.
|
||||
|
||||
const { data } = e.notification;
|
||||
const notifyClients = async () => {
|
||||
const clients = await self.clients.matchAll({ type: 'window' }) as WindowClient[];
|
||||
@ -127,13 +136,18 @@ export function handleClientMessage(e: ExtendableMessageEvent) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[SW] New message from client', e);
|
||||
}
|
||||
if (e.data && e.data.type === 'clientReady') {
|
||||
const source = e.source as WindowClient;
|
||||
|
||||
if (!e.data) return;
|
||||
const source = e.source as WindowClient;
|
||||
if (e.data.type === 'clientReady') {
|
||||
// focus on chat message when client is fully ready
|
||||
if (clickBuffer[source.id]) {
|
||||
focusChatMessage(source, clickBuffer[source.id]);
|
||||
delete clickBuffer[source.id];
|
||||
}
|
||||
}
|
||||
if (e.data.type === 'newMessageNotification') {
|
||||
// store messageId for already shown notification
|
||||
const { messageId } = e.data.payload;
|
||||
shownNotifications.add(messageId);
|
||||
}
|
||||
}
|
||||
|
||||
272
src/util/notifications.ts
Normal file
272
src/util/notifications.ts
Normal file
@ -0,0 +1,272 @@
|
||||
import { callApi } from '../api/gramjs';
|
||||
import { ApiChat, ApiMessage } from '../api/types';
|
||||
import { renderActionMessageText } from '../components/common/helpers/renderActionMessageText';
|
||||
import { DEBUG } from '../config';
|
||||
import { getDispatch, getGlobal } from '../lib/teact/teactn';
|
||||
import {
|
||||
getChatTitle,
|
||||
getMessageAction,
|
||||
getMessageSenderName,
|
||||
getNotificationText,
|
||||
getPrivateChatUserId,
|
||||
isActionMessage,
|
||||
isChatChannel,
|
||||
} from '../modules/helpers';
|
||||
import { selectChatMessage, selectUser } from '../modules/selectors';
|
||||
import { IS_SERVICE_WORKER_SUPPORTED } from './environment';
|
||||
|
||||
function getDeviceToken(subscription: PushSubscription) {
|
||||
const data = subscription.toJSON();
|
||||
return JSON.stringify({
|
||||
endpoint: data.endpoint,
|
||||
keys: data.keys,
|
||||
});
|
||||
}
|
||||
|
||||
function checkIfPushSupported() {
|
||||
if (!IS_SERVICE_WORKER_SUPPORTED) return false;
|
||||
if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('[PUSH] Push notifications aren\'t supported.');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the current Notification permission.
|
||||
// If its denied, it's a permanent block until the
|
||||
// user changes the permission
|
||||
if (Notification.permission === 'denied') {
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('[PUSH] The user has blocked push notifications.');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if push messaging is supported
|
||||
if (!('PushManager' in window)) {
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('[PUSH] Push messaging isn\'t supported.');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkIfNotificationsSupported() {
|
||||
// Let's check if the browser supports notifications
|
||||
if (!('Notification' in window)) {
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('[PUSH] This browser does not support desktop notification');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Notification.permission === 'denied' as NotificationPermission) {
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('[PUSH] The user has blocked push notifications.');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const expirationTime = 12 * 60 * 60 * 1000; // 12 hours
|
||||
|
||||
function checkIfShouldResubscribe(subscription: PushSubscription | null) {
|
||||
const global = getGlobal();
|
||||
if (!global.push || !subscription) return true;
|
||||
if (getDeviceToken(subscription) !== global.push.deviceToken) return true;
|
||||
return Date.now() - global.push.subscribedAt > expirationTime;
|
||||
}
|
||||
|
||||
async function requestPermission() {
|
||||
if (!('Notification' in window)) return;
|
||||
if (!['granted', 'denied'].includes(Notification.permission)) {
|
||||
await Notification.requestPermission();
|
||||
}
|
||||
}
|
||||
|
||||
async function unsubscribeFromPush(subscription: PushSubscription | null) {
|
||||
const global = getGlobal();
|
||||
const dispatch = getDispatch();
|
||||
if (subscription) {
|
||||
try {
|
||||
const deviceToken = getDeviceToken(subscription);
|
||||
await callApi('unregisterDevice', deviceToken);
|
||||
await subscription.unsubscribe();
|
||||
dispatch.deleteDeviceToken();
|
||||
return;
|
||||
} catch (error) {
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[PUSH] Unable to unsubscribe from push.', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (global.push) {
|
||||
await callApi('unregisterDevice', global.push.deviceToken);
|
||||
dispatch.deleteDeviceToken();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function unsubscribe() {
|
||||
if (!checkIfPushSupported()) return;
|
||||
const serviceWorkerRegistration = await navigator.serviceWorker.ready;
|
||||
const subscription = await serviceWorkerRegistration.pushManager.getSubscription();
|
||||
await unsubscribeFromPush(subscription);
|
||||
}
|
||||
|
||||
export async function subscribe() {
|
||||
await requestPermission();
|
||||
if (!checkIfPushSupported()) return;
|
||||
const serviceWorkerRegistration = await navigator.serviceWorker.ready;
|
||||
let subscription = await serviceWorkerRegistration.pushManager.getSubscription();
|
||||
if (!checkIfShouldResubscribe(subscription)) return;
|
||||
await unsubscribeFromPush(subscription);
|
||||
try {
|
||||
subscription = await serviceWorkerRegistration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
});
|
||||
const deviceToken = getDeviceToken(subscription);
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[PUSH] Received push subscription: ', deviceToken);
|
||||
}
|
||||
await callApi('registerDevice', deviceToken);
|
||||
getDispatch()
|
||||
.setDeviceToken(deviceToken);
|
||||
} catch (error) {
|
||||
if (Notification.permission === 'denied' as NotificationPermission) {
|
||||
// The user denied the notification permission which
|
||||
// means we failed to subscribe and the user will need
|
||||
// to manually change the notification permission to
|
||||
// subscribe to push messages
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('[PUSH] The user has blocked push notifications.');
|
||||
}
|
||||
} else if (DEBUG) {
|
||||
// A problem occurred with the subscription, this can
|
||||
// often be down to an issue or lack of the gcm_sender_id
|
||||
// and / or gcm_user_visible_only
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[PUSH] Unable to subscribe to push.', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function checkIfShouldNotify(chat: ApiChat) {
|
||||
if (chat.isMuted) return false;
|
||||
await getDispatch().loadNotificationsSettings();
|
||||
const global = getGlobal();
|
||||
switch (chat.type) {
|
||||
case 'chatTypePrivate':
|
||||
case 'chatTypeSecret':
|
||||
return Boolean(global.settings.byKey.hasPrivateChatsNotifications);
|
||||
case 'chatTypeBasicGroup':
|
||||
case 'chatTypeSuperGroup':
|
||||
return Boolean(global.settings.byKey.hasGroupNotifications);
|
||||
case 'chatTypeChannel':
|
||||
return Boolean(global.settings.byKey.hasBroadcastNotifications);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getNotificationContent(chat: ApiChat, message: ApiMessage) {
|
||||
const global = getGlobal();
|
||||
const {
|
||||
senderId,
|
||||
replyToMessageId,
|
||||
} = message;
|
||||
const messageSender = senderId ? selectUser(global, senderId) : undefined;
|
||||
const messageAction = getMessageAction(message as ApiMessage);
|
||||
const actionTargetMessage = messageAction && replyToMessageId
|
||||
? selectChatMessage(global, chat.id, replyToMessageId)
|
||||
: undefined;
|
||||
const {
|
||||
targetUserId: actionTargetUserId,
|
||||
targetChatId: actionTargetChatId,
|
||||
} = messageAction || {};
|
||||
const actionTargetUser = actionTargetUserId ? selectUser(global, actionTargetUserId) : undefined;
|
||||
const privateChatUserId = getPrivateChatUserId(chat);
|
||||
const privateChatUser = privateChatUserId ? selectUser(global, privateChatUserId) : undefined;
|
||||
let body: string;
|
||||
if (isActionMessage(message)) {
|
||||
const actionOrigin = chat && (isChatChannel(chat) || message.senderId === message.chatId)
|
||||
? chat
|
||||
: messageSender;
|
||||
body = renderActionMessageText(
|
||||
message,
|
||||
actionOrigin,
|
||||
actionTargetUser,
|
||||
actionTargetMessage,
|
||||
actionTargetChatId,
|
||||
{ asPlain: true },
|
||||
) as string;
|
||||
} else {
|
||||
const senderName = getMessageSenderName(chat.id, messageSender);
|
||||
const summary = getNotificationText(message);
|
||||
|
||||
body = senderName ? `${senderName}: ${summary}` : summary;
|
||||
}
|
||||
|
||||
return {
|
||||
title: getChatTitle(chat, privateChatUser),
|
||||
body,
|
||||
};
|
||||
}
|
||||
|
||||
export async function showNewMessageNotification({
|
||||
chat,
|
||||
message,
|
||||
}: { chat: ApiChat; message: Partial<ApiMessage> }) {
|
||||
if (!checkIfNotificationsSupported()) return;
|
||||
if (!message.id) return;
|
||||
|
||||
const shouldNotify = await checkIfShouldNotify(chat);
|
||||
if (!shouldNotify) return;
|
||||
|
||||
const {
|
||||
title,
|
||||
body,
|
||||
} = getNotificationContent(chat, message as ApiMessage);
|
||||
|
||||
const notification = new Notification(title, {
|
||||
body,
|
||||
icon: 'icon-192x192.png',
|
||||
badge: 'icon-192x192.png',
|
||||
tag: message.id.toString(),
|
||||
vibrate: [200, 100, 200],
|
||||
});
|
||||
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// notify service worker about new message notification
|
||||
navigator.serviceWorker.controller.postMessage({
|
||||
type: 'newMessageNotification',
|
||||
payload: { messageId: message.id },
|
||||
});
|
||||
}
|
||||
const dispatch = getDispatch();
|
||||
|
||||
notification.onclick = () => {
|
||||
notification.close();
|
||||
dispatch.focusMessage({
|
||||
chatId: chat.id,
|
||||
messageId: message.id,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// Notify service worker that client is fully loaded
|
||||
export function notifyClientReady() {
|
||||
if (!navigator.serviceWorker.controller) return;
|
||||
navigator.serviceWorker.controller.postMessage({
|
||||
type: 'clientReady',
|
||||
});
|
||||
}
|
||||
@ -1,125 +0,0 @@
|
||||
import { callApi } from '../api/gramjs';
|
||||
import { DEBUG } from '../config';
|
||||
import { getDispatch, getGlobal } from '../lib/teact/teactn';
|
||||
import { IS_SERVICE_WORKER_SUPPORTED } from './environment';
|
||||
|
||||
function getDeviceToken(subscription: PushSubscription) {
|
||||
const data = subscription.toJSON();
|
||||
return JSON.stringify({ endpoint: data.endpoint, keys: data.keys });
|
||||
}
|
||||
|
||||
function checkIfSupported() {
|
||||
if (!IS_SERVICE_WORKER_SUPPORTED) return false;
|
||||
if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[PUSH] Push notifications aren\'t supported.');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the current Notification permission.
|
||||
// If its denied, it's a permanent block until the
|
||||
// user changes the permission
|
||||
if (Notification.permission === 'denied') {
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[PUSH] The user has blocked push notifications.');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if push messaging is supported
|
||||
if (!('PushManager' in window)) {
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[PUSH] Push messaging isn\'t supported.');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const expirationTime = 12 * 60 * 60 * 1000; // 12 hours
|
||||
|
||||
function checkIfShouldResubscribe(subscription: PushSubscription | null) {
|
||||
const global = getGlobal();
|
||||
if (!global.push || !subscription) return true;
|
||||
if (getDeviceToken(subscription) !== global.push.deviceToken) return true;
|
||||
return Date.now() - global.push.subscribedAt > expirationTime;
|
||||
}
|
||||
|
||||
async function unsubscribe(subscription: PushSubscription | null) {
|
||||
const global = getGlobal();
|
||||
const dispatch = getDispatch();
|
||||
if (subscription) {
|
||||
try {
|
||||
const deviceToken = getDeviceToken(subscription);
|
||||
await callApi('unregisterDevice', deviceToken);
|
||||
await subscription.unsubscribe();
|
||||
dispatch.deleteDeviceToken();
|
||||
return;
|
||||
} catch (error) {
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[PUSH] Unable to unsubscribe from push.', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (global.push) {
|
||||
await callApi('unregisterDevice', global.push.deviceToken);
|
||||
dispatch.deleteDeviceToken();
|
||||
}
|
||||
}
|
||||
|
||||
export async function unsubscribeFromPush() {
|
||||
if (!checkIfSupported()) return;
|
||||
const serviceWorkerRegistration = await navigator.serviceWorker.ready;
|
||||
const subscription = await serviceWorkerRegistration.pushManager.getSubscription();
|
||||
await unsubscribe(subscription);
|
||||
}
|
||||
|
||||
export async function subscribeToPush() {
|
||||
if (!checkIfSupported()) return;
|
||||
const serviceWorkerRegistration = await navigator.serviceWorker.ready;
|
||||
let subscription = await serviceWorkerRegistration.pushManager.getSubscription();
|
||||
if (!checkIfShouldResubscribe(subscription)) return;
|
||||
await unsubscribe(subscription);
|
||||
try {
|
||||
subscription = await serviceWorkerRegistration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
});
|
||||
const deviceToken = getDeviceToken(subscription);
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[PUSH] Received push subscription: ', deviceToken);
|
||||
}
|
||||
await callApi('registerDevice', deviceToken);
|
||||
getDispatch().setDeviceToken(deviceToken);
|
||||
} catch (error) {
|
||||
if (Notification.permission === 'denied' as NotificationPermission) {
|
||||
// The user denied the notification permission which
|
||||
// means we failed to subscribe and the user will need
|
||||
// to manually change the notification permission to
|
||||
// subscribe to push messages
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[PUSH] Permission for Notifications was denied');
|
||||
}
|
||||
} else if (DEBUG) {
|
||||
// A problem occurred with the subscription, this can
|
||||
// often be down to an issue or lack of the gcm_sender_id
|
||||
// and / or gcm_user_visible_only
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[PUSH] Unable to subscribe to push.', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Notify service worker that client is fully loaded
|
||||
export function notifyClientReady() {
|
||||
if (!navigator.serviceWorker.controller) return;
|
||||
navigator.serviceWorker.controller.postMessage({
|
||||
type: 'clientReady',
|
||||
});
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user