diff --git a/src/api/gramjs/apiBuilders/messages.ts b/src/api/gramjs/apiBuilders/messages.ts index d959dc1e6..4c25253c2 100644 --- a/src/api/gramjs/apiBuilders/messages.ts +++ b/src/api/gramjs/apiBuilders/messages.ts @@ -144,7 +144,7 @@ type UniversalMessage = ( & Pick, ( 'out' | 'message' | 'entities' | 'fromId' | 'peerId' | 'fwdFrom' | 'replyTo' | 'replyMarkup' | 'post' | 'media' | 'action' | 'views' | 'editDate' | 'editHide' | 'mediaUnread' | 'groupedId' | 'mentioned' | 'viaBotId' | - 'replies' | 'fromScheduled' | 'postAuthor' | 'noforwards' | 'reactions' | 'forwards' + 'replies' | 'fromScheduled' | 'postAuthor' | 'noforwards' | 'reactions' | 'forwards' | 'silent' )> ); @@ -181,6 +181,7 @@ export function buildApiMessageWithChatId(chatId: string, mtpMessage: UniversalM views: mtpMessage.views, forwards: mtpMessage.forwards, isFromScheduled: mtpMessage.fromScheduled, + isSilent: mtpMessage.silent, reactions: mtpMessage.reactions && buildMessageReactions(mtpMessage.reactions), ...(replyToMsgId && { replyToMessageId: replyToMsgId }), ...(replyToPeerId && { replyToChatId: getApiChatIdFromMtpPeer(replyToPeerId) }), diff --git a/src/api/types/messages.ts b/src/api/types/messages.ts index 64cbc8e1d..9e6337fcb 100644 --- a/src/api/types/messages.ts +++ b/src/api/types/messages.ts @@ -396,6 +396,7 @@ export interface ApiMessage { isScheduled?: boolean; shouldHideKeyboardButtons?: boolean; isFromScheduled?: boolean; + isSilent?: boolean; seenByUserIds?: string[]; isProtected?: boolean; transcriptionId?: string; diff --git a/src/serviceWorker/pushNotification.ts b/src/serviceWorker/pushNotification.ts index cac6573b8..04801cc2f 100644 --- a/src/serviceWorker/pushNotification.ts +++ b/src/serviceWorker/pushNotification.ts @@ -10,6 +10,7 @@ enum Boolean { type PushData = { custom: { msg_id?: string; + silent?: string; channel_id?: string; chat_id?: string; from_id?: string; @@ -28,6 +29,7 @@ type NotificationData = { chatId?: string; title: string; body: string; + isSilent?: boolean; icon?: string; reaction?: string; shouldReplaceHistory?: boolean; @@ -80,11 +82,17 @@ function getMessageId(data: PushData) { } function getNotificationData(data: PushData): NotificationData { + let title = data.title || APP_NAME; + const isSilent = data.custom?.silent === Boolean.True; + if (isSilent) { + title += ' 🔕'; + } return { chatId: getChatId(data), messageId: getMessageId(data), - title: data.title || APP_NAME, body: data.description, + isSilent, + title, }; } @@ -113,6 +121,7 @@ function showNotification({ title, icon, reaction, + isSilent, shouldReplaceHistory, }: NotificationData) { const isFirstBatch = new Date().valueOf() - lastSyncAt < 1000; @@ -133,8 +142,8 @@ function showNotification({ }; return Promise.all([ - // TODO Remove condition when reaction badges are implemented - !reaction ? playNotificationSound(String(messageId) || chatId || '') : undefined, + // TODO Update condition when reaction badges are implemented + (!reaction && !isSilent) ? playNotificationSound(String(messageId) || chatId || '') : undefined, self.registration.showNotification(title, options), ]); } diff --git a/src/util/notifications.ts b/src/util/notifications.ts index a5dc00fa0..581512630 100644 --- a/src/util/notifications.ts +++ b/src/util/notifications.ts @@ -321,10 +321,13 @@ function getNotificationContent(chat: ApiChat, message: ApiMessage, reaction?: A body = 'New message'; } - return { - title: isScreenLocked ? APP_NAME : getChatTitle(getTranslation, chat, privateChatUser), - body, - }; + let title = isScreenLocked ? APP_NAME : getChatTitle(getTranslation, chat, privateChatUser); + + if (message.isSilent) { + title += ' 🔕'; + } + + return { title, body }; } async function getAvatar(chat: ApiChat | ApiUser) { @@ -380,10 +383,11 @@ export async function notifyAboutMessage({ if (!checkIfShouldNotify(chat)) return; const areNotificationsSupported = checkIfNotificationsSupported(); if (!hasWebNotifications || !areNotificationsSupported) { - // Do not play notification sound for reactions if web notifications are disabled - if (isReaction) return; - // Only play sound if web notifications are disabled - playNotifySoundDebounced(String(message.id) || chat.id); + if (!message.isSilent && !isReaction) { + // Only play sound if web notifications are disabled + playNotifySoundDebounced(String(message.id) || chat.id); + } + return; } if (!areNotificationsSupported) return; @@ -413,6 +417,7 @@ export async function notifyAboutMessage({ chatId: chat.id, messageId: message.id, shouldReplaceHistory: true, + isSilent: message.isSilent, reaction: activeReaction?.reaction, }, }); @@ -446,8 +451,8 @@ export async function notifyAboutMessage({ // Play sound when notification is displayed notification.onshow = () => { - // TODO Remove when reaction badges are implemented - if (isReaction) return; + // TODO Update when reaction badges are implemented + if (isReaction || message.isSilent) return; playNotifySoundDebounced(String(message.id) || chat.id); }; }