diff --git a/src/global/actions/ui/messages.ts b/src/global/actions/ui/messages.ts index 0d2d9386d..51d40b194 100644 --- a/src/global/actions/ui/messages.ts +++ b/src/global/actions/ui/messages.ts @@ -855,7 +855,7 @@ function copyTextForMessages(global: GlobalState, chatId: string, messageIds: nu const resultText = messages.reduce((acc, message) => { const sender = selectSender(global, message); acc.push(`> ${sender ? getSenderTitle(lang, sender) : ''}:`); - acc.push(`${getMessageSummaryText(lang, message, false, 0, undefined, true)}\n`); + acc.push(`${getMessageSummaryText(lang, message, false, 0, true)}\n`); return acc; }, [] as string[]); diff --git a/src/global/helpers/messageSummary.ts b/src/global/helpers/messageSummary.ts index 041851ef8..0663e04fb 100644 --- a/src/global/helpers/messageSummary.ts +++ b/src/global/helpers/messageSummary.ts @@ -7,7 +7,6 @@ import type { LangFn } from '../../hooks/useLang'; import trimText from '../../util/trimText'; import { getMessageText, getMessageTranscription } from './messages'; -import { getMessageRecentReaction } from './reactions'; const SPOILER_CHARS = ['⠺', '⠵', '⠞', '⠟']; export const TRUNCATED_SUMMARY_LENGTH = 80; @@ -17,13 +16,12 @@ export function getMessageSummaryText( message: ApiMessage, noEmoji = false, truncateLength = TRUNCATED_SUMMARY_LENGTH, - noReactions = true, isExtended = false, ) { - const emoji = !noEmoji && getMessageSummaryEmoji(message, noReactions); + const emoji = !noEmoji && getMessageSummaryEmoji(message); const emojiWithSpace = emoji ? `${emoji} ` : ''; const text = trimText(getMessageTextWithSpoilers(message), truncateLength); - const description = getMessageSummaryDescription(lang, message, text, noReactions, isExtended); + const description = getMessageSummaryDescription(lang, message, text, isExtended); return `${emojiWithSpace}${description}`; } @@ -58,7 +56,7 @@ export function getMessageTextWithSpoilers(message: ApiMessage) { return transcription ? `${transcription}\n${text}` : text; } -export function getMessageSummaryEmoji(message: ApiMessage, noReactions = true) { +export function getMessageSummaryEmoji(message: ApiMessage) { const { photo, video, @@ -97,11 +95,6 @@ export function getMessageSummaryEmoji(message: ApiMessage, noReactions = true) return '📊'; } - const reaction = !noReactions && getMessageRecentReaction(message); - if (reaction) { - return reaction.reaction; - } - return undefined; } @@ -109,7 +102,6 @@ export function getMessageSummaryDescription( lang: LangFn, message: ApiMessage, truncatedText?: string | TeactNode, - noReactions = true, isExtended = false, ) { const { @@ -189,11 +181,6 @@ export function getMessageSummaryDescription( summary = `🎮 ${game.title}`; } - const reaction = !noReactions && getMessageRecentReaction(message); - if (summary && reaction) { - summary = `to your "${summary}"`; - } - return summary || CONTENT_NOT_SUPPORTED; } diff --git a/src/global/helpers/renderMessageSummaryHtml.ts b/src/global/helpers/renderMessageSummaryHtml.ts index b018e4683..a5e8ecba4 100644 --- a/src/global/helpers/renderMessageSummaryHtml.ts +++ b/src/global/helpers/renderMessageSummaryHtml.ts @@ -12,7 +12,7 @@ export function renderMessageSummaryHtml( const text = renderMessageText( message, undefined, undefined, undefined, undefined, undefined, true, )?.join(''); - const description = getMessageSummaryDescription(lang, message, text, true, true); + const description = getMessageSummaryDescription(lang, message, text, true); return `${emojiWithSpace}${description}`; } diff --git a/src/util/notifications.ts b/src/util/notifications.ts index 85320e9de..93b54402e 100644 --- a/src/util/notifications.ts +++ b/src/util/notifications.ts @@ -32,6 +32,7 @@ import { IS_SERVICE_WORKER_SUPPORTED, IS_TOUCH_ENV } from './windowEnvironment'; import { translate } from './langProvider'; import * as mediaLoader from './mediaLoader'; import { debounce } from './schedulers'; +import { buildCollectionByKey } from './iteratees'; function getDeviceToken(subscription: PushSubscription) { const data = subscription.toJSON(); @@ -191,6 +192,28 @@ async function loadNotificationSettings() { return selectNotifySettings(global); } +// Load custom emoji from the api if it's not cached already +async function loadCustomEmoji(id: string) { + let global = getGlobal(); + if (global.customEmojis.byId[id]) return; + const customEmoji = await callApi('fetchCustomEmoji', { + documentId: [id], + }); + if (!customEmoji) return; + global = getGlobal(); + global = { + ...global, + customEmojis: { + ...global.customEmojis, + byId: { + ...global.customEmojis.byId, + ...buildCollectionByKey(customEmoji, 'id'), + }, + }, + }; + setGlobal(global); +} + export async function subscribe() { if (!checkIfPushSupported()) { // Ask for notification permissions only if service worker notifications are not supported @@ -267,7 +290,8 @@ function getNotificationContent(chat: ApiChat, message: ApiMessage, reaction?: A let { senderId, } = message; - if (reaction) senderId = reaction.userId; + const hasReaction = Boolean(reaction); + if (hasReaction) senderId = reaction.userId; const { isScreenLocked } = global.passcode; const messageSender = senderId ? selectUser(global, senderId) : undefined; @@ -311,7 +335,12 @@ function getNotificationContent(chat: ApiChat, message: ApiMessage, reaction?: A } else { // TODO[forums] Support ApiChat const senderName = getMessageSenderName(translate, chat.id, messageSender); - const summary = getMessageSummaryText(translate, message, false, 60, false); + let summary = getMessageSummaryText(translate, message, hasReaction, 60); + + if (hasReaction) { + const emoji = getReactionEmoji(reaction); + summary = translate('PushReactText', [emoji, summary]); + } body = senderName ? `${senderName}: ${summary}` : summary; } @@ -339,6 +368,18 @@ async function getAvatar(chat: ApiChat | ApiUser) { return mediaData; } +function getReactionEmoji(reaction: ApiUserReaction) { + let emoji; + if ('emoticon' in reaction.reaction) { + emoji = reaction.reaction.emoticon; + } + if ('documentId' in reaction.reaction) { + // eslint-disable-next-line eslint-multitab-tt/no-immediate-global + emoji = getGlobal().customEmojis.byId[reaction.reaction.documentId]?.emoji; + } + return emoji || '❤️'; +} + export async function notifyAboutCall({ call, user, }: { @@ -396,6 +437,11 @@ export async function notifyAboutMessage({ // Do not notify about reactions on messages that are not outgoing if (isReaction && !activeReaction) return; + // If this is a custom emoji reaction we need to make sure it is loaded + if (isReaction && activeReaction && 'documentId' in activeReaction.reaction) { + await loadCustomEmoji(activeReaction.reaction.documentId); + } + const icon = await getAvatar(chat); const {