diff --git a/lib/shared/messages/message-spec.js b/lib/shared/messages/message-spec.js --- a/lib/shared/messages/message-spec.js +++ b/lib/shared/messages/message-spec.js @@ -103,7 +103,7 @@ +notificationCollapseKey?: ( rawMessageInfo: RawInfo, messageData: Data, - ) => string, + ) => ?string, +generatesNotifs: ( rawMessageInfo: RawInfo, messageData: Data, diff --git a/lib/shared/messages/text-message-spec.js b/lib/shared/messages/text-message-spec.js --- a/lib/shared/messages/text-message-spec.js +++ b/lib/shared/messages/text-message-spec.js @@ -7,8 +7,9 @@ pushTypes, type MessageSpec, type RawMessageInfoFromServerDBRowParams, + type NotificationTextsParams, } from './message-spec.js'; -import { assertSingleMessageInfo } from './utils.js'; +import { assertSingleMessageInfo, joinResult } from './utils.js'; import { changeThreadSettingsActionTypes, changeThreadSettings, @@ -38,6 +39,8 @@ stripSpoilersFromNotifications, stripSpoilersFromMarkdownAST, } from '../markdown.js'; +import { isMentioned } from '../mention-utils.js'; +import { notifTextsForSidebarCreation } from '../notif-utils.js'; import { threadIsGroupChat, extractNewMentionedParentMembers, @@ -186,7 +189,55 @@ async notificationTexts( messageInfos: $ReadOnlyArray, threadInfo: ThreadInfo, - ): Promise { + params: NotificationTextsParams, + ): Promise { + // We special-case sidebarCreations. Usually we don't send any notifs in + // that case to avoid a double-notif, but we need to update the original + // notif if somebody was @-tagged in this message + if ( + messageInfos.length === 3 && + messageInfos[2].type === messageTypes.SIDEBAR_SOURCE && + messageInfos[1].type === messageTypes.CREATE_SIDEBAR + ) { + const sidebarSourceMessageInfo = messageInfos[2]; + const createSidebarMessageInfo = messageInfos[1]; + + const sourceMessage = messageInfos[2].sourceMessage; + const { username } = params.notifTargetUserInfo; + if (!username) { + // If we couldn't fetch the username for some reason, we won't be able + // to extract @-mentions anyways, so we'll give up on updating the notif + return null; + } + + if ( + sourceMessage.type === messageTypes.TEXT && + isMentioned(username, sourceMessage.text) + ) { + // If the notif target was already mentioned in the source message, + // there's no need to update the notif + return null; + } + + const messageInfo = messageInfos[0]; + invariant( + messageInfo.type === messageTypes.TEXT, + 'messageInfo should be messageTypes.TEXT!', + ); + if (!isMentioned(username, messageInfo.text)) { + // We only need to update the notif if the notif target is mentioned + return null; + } + + return notifTextsForSidebarCreation({ + createSidebarMessageInfo, + sidebarSourceMessageInfo, + firstSidebarMessageInfo: messageInfo, + threadInfo, + params, + }); + } + const messageInfo = assertSingleMessageInfo(messageInfos); invariant( messageInfo.type === messageTypes.TEXT, @@ -214,10 +265,17 @@ } }, - generatesNotifs: async ( + notificationCollapseKey( rawMessageInfo: RawTextMessageInfo, messageData: TextMessageData, - ) => (messageData.sidebarCreation ? undefined : pushTypes.NOTIF), + ): ?string { + if (!messageData.sidebarCreation) { + return null; + } + return joinResult(messageTypes.CREATE_SIDEBAR, rawMessageInfo.threadID); + }, + + generatesNotifs: async () => pushTypes.NOTIF, includedInRepliesCount: true, diff --git a/lib/shared/notif-utils.js b/lib/shared/notif-utils.js --- a/lib/shared/notif-utils.js +++ b/lib/shared/notif-utils.js @@ -17,6 +17,7 @@ messageTypes, } from '../types/message-types.js'; import type { CreateSidebarMessageInfo } from '../types/messages/create-sidebar.js'; +import type { TextMessageInfo } from '../types/messages/text.js'; import type { NotifTexts, ResolvedNotifTexts } from '../types/notif-types.js'; import type { ThreadInfo, ThreadType } from '../types/thread-types.js'; import type { RelativeUserInfo, UserInfo } from '../types/user-types.js'; @@ -143,6 +144,7 @@ type NotifTextsForSidebarCreationInput = { +createSidebarMessageInfo: CreateSidebarMessageInfo, +sidebarSourceMessageInfo?: ?SidebarSourceMessageInfo, + +firstSidebarMessageInfo?: ?TextMessageInfo, +threadInfo: ThreadInfo, +params: NotificationTextsParams, }; @@ -152,6 +154,7 @@ const { sidebarSourceMessageInfo, createSidebarMessageInfo, + firstSidebarMessageInfo, threadInfo, params, } = input; @@ -177,6 +180,12 @@ isMentioned(username, sidebarSourceMessageInfo.sourceMessage.text) ) { body = ET`${body} that tagged you`; + } else if ( + username && + firstSidebarMessageInfo && + isMentioned(username, firstSidebarMessageInfo.text) + ) { + body = ET`${body} and tagged you`; } else if (initialName) { body = ET`${body} "${initialName}"`; }