diff --git a/lib/shared/messages/add-members-message-spec.js b/lib/shared/messages/add-members-message-spec.js --- a/lib/shared/messages/add-members-message-spec.js +++ b/lib/shared/messages/add-members-message-spec.js @@ -25,7 +25,6 @@ } from '../../types/messages/add-members.js'; import type { ThreadInfo } from '../../types/minimally-encoded-thread-permissions-types.js'; import type { NotifTexts } from '../../types/notif-types.js'; -import { threadIDIsThick } from '../../types/thread-types.js'; import type { RelativeUserInfo } from '../../types/user-types.js'; import { type EntityText, @@ -34,6 +33,7 @@ } from '../../utils/entity-text.js'; import { values } from '../../utils/objects.js'; import { notifRobotextForMessageInfo } from '../notif-utils.js'; +import { getProtocolByThreadID } from '../threads/protocols/thread-protocols.js'; import { threadSpecs } from '../threads/thread-specs.js'; function getAddMembersRobotext(messageInfo: AddMembersMessageInfo): EntityText { @@ -246,7 +246,6 @@ : null, getMessageNotifyType: async (rawMessageInfo: RawAddMembersMessageInfo) => - threadIDIsThick(rawMessageInfo.threadID) - ? messageNotifyTypes.SET_UNREAD - : messageNotifyTypes.NONE, + getProtocolByThreadID(rawMessageInfo.threadID) + ?.membershipMessageNotifAction ?? messageNotifyTypes.NONE, }); diff --git a/lib/shared/messages/join-thread-message-spec.js b/lib/shared/messages/join-thread-message-spec.js --- a/lib/shared/messages/join-thread-message-spec.js +++ b/lib/shared/messages/join-thread-message-spec.js @@ -24,7 +24,6 @@ } from '../../types/messages/join-thread.js'; import type { ThreadInfo } from '../../types/minimally-encoded-thread-permissions-types.js'; import type { NotifTexts } from '../../types/notif-types.js'; -import { threadIDIsThick } from '../../types/thread-types.js'; import type { RelativeUserInfo } from '../../types/user-types.js'; import { type EntityText, @@ -32,6 +31,7 @@ pluralizeEntityText, } from '../../utils/entity-text.js'; import { values } from '../../utils/objects.js'; +import { getProtocolByThreadID } from '../threads/protocols/thread-protocols.js'; import { threadSpecs } from '../threads/thread-specs.js'; function getJoinThreadRobotext( @@ -192,7 +192,6 @@ : null, getMessageNotifyType: async (rawMessageInfo: RawJoinThreadMessageInfo) => - threadIDIsThick(rawMessageInfo.threadID) - ? messageNotifyTypes.SET_UNREAD - : messageNotifyTypes.NONE, + getProtocolByThreadID(rawMessageInfo.threadID) + ?.membershipMessageNotifAction ?? messageNotifyTypes.NONE, }); diff --git a/lib/shared/messages/leave-thread-message-spec.js b/lib/shared/messages/leave-thread-message-spec.js --- a/lib/shared/messages/leave-thread-message-spec.js +++ b/lib/shared/messages/leave-thread-message-spec.js @@ -24,7 +24,6 @@ } from '../../types/messages/leave-thread.js'; import type { ThreadInfo } from '../../types/minimally-encoded-thread-permissions-types.js'; import type { NotifTexts } from '../../types/notif-types.js'; -import { threadIDIsThick } from '../../types/thread-types.js'; import type { RelativeUserInfo } from '../../types/user-types.js'; import { type EntityText, @@ -32,6 +31,7 @@ pluralizeEntityText, } from '../../utils/entity-text.js'; import { values } from '../../utils/objects.js'; +import { getProtocolByThreadID } from '../threads/protocols/thread-protocols.js'; import { threadSpecs } from '../threads/thread-specs.js'; function getLeaveThreadRobotext( @@ -192,7 +192,6 @@ : null, getMessageNotifyType: async (rawMessageInfo: RawLeaveThreadMessageInfo) => - threadIDIsThick(rawMessageInfo.threadID) - ? messageNotifyTypes.SET_UNREAD - : messageNotifyTypes.NONE, + getProtocolByThreadID(rawMessageInfo.threadID) + ?.membershipMessageNotifAction ?? messageNotifyTypes.NONE, }); diff --git a/lib/shared/messages/remove-members-message-spec.js b/lib/shared/messages/remove-members-message-spec.js --- a/lib/shared/messages/remove-members-message-spec.js +++ b/lib/shared/messages/remove-members-message-spec.js @@ -25,7 +25,6 @@ } from '../../types/messages/remove-members.js'; import type { ThreadInfo } from '../../types/minimally-encoded-thread-permissions-types.js'; import type { NotifTexts } from '../../types/notif-types.js'; -import { threadIDIsThick } from '../../types/thread-types.js'; import type { RelativeUserInfo } from '../../types/user-types.js'; import { type EntityText, @@ -34,6 +33,7 @@ } from '../../utils/entity-text.js'; import { values } from '../../utils/objects.js'; import { notifRobotextForMessageInfo } from '../notif-utils.js'; +import { getProtocolByThreadID } from '../threads/protocols/thread-protocols.js'; import { threadSpecs } from '../threads/thread-specs.js'; function getRemoveMembersRobotext( @@ -251,11 +251,8 @@ ? rawMessageInfo.time : null, - getMessageNotifyType: async ( - rawMessageInfo: RawRemoveMembersMessageInfo, - ) => - threadIDIsThick(rawMessageInfo.threadID) - ? messageNotifyTypes.SET_UNREAD - : messageNotifyTypes.NONE, + getMessageNotifyType: async (rawMessageInfo: RawRemoveMembersMessageInfo) => + getProtocolByThreadID(rawMessageInfo.threadID) + ?.membershipMessageNotifAction ?? messageNotifyTypes.NONE, }, ); diff --git a/lib/shared/threads/protocols/dm-thread-protocol.js b/lib/shared/threads/protocols/dm-thread-protocol.js --- a/lib/shared/threads/protocols/dm-thread-protocol.js +++ b/lib/shared/threads/protocols/dm-thread-protocol.js @@ -51,6 +51,7 @@ import { assertWithValidator, pendingThickSidebarURLPrefix, + thickIDRegex, } from '../../../utils/validation-utils.js'; import { generatePendingThreadColor } from '../../color-utils.js'; import { @@ -58,6 +59,7 @@ type OutboundDMOperationSpecification, } from '../../dm-ops/dm-op-types.js'; import { getIDFromLocalID } from '../../id-utils.js'; +import { messageNotifyTypes } from '../../messages/message-spec.js'; import { createThreadTimestamps, getContainingThreadID, @@ -881,6 +883,8 @@ }: ThreadJoinPayload); }, + threadIDMatchesProtocol: (threadID: string) => thickIDRegex.test(threadID), + allowsDeletingSidebarSource: false, presentationDetails: { @@ -909,6 +913,8 @@ arePendingThreadsDescendantsOfGenesis: false, threadActivityUpdatedByDMActivityHandler: true, + + membershipMessageNotifAction: messageNotifyTypes.SET_UNREAD, }); function pendingThreadType(numberOfOtherMembers: number) { diff --git a/lib/shared/threads/protocols/keyserver-thread-protocol.js b/lib/shared/threads/protocols/keyserver-thread-protocol.js --- a/lib/shared/threads/protocols/keyserver-thread-protocol.js +++ b/lib/shared/threads/protocols/keyserver-thread-protocol.js @@ -68,9 +68,14 @@ getMessageForException, SendMessageError, } from '../../../utils/errors.js'; -import { pendingSidebarURLPrefix } from '../../../utils/validation-utils.js'; +import { + isSchemaRegExp, + pendingSidebarURLPrefix, + thickIDRegex, +} from '../../../utils/validation-utils.js'; import { generatePendingThreadColor } from '../../color-utils.js'; import { getNextLocalID } from '../../id-utils.js'; +import { messageNotifyTypes } from '../../messages/message-spec.js'; import { getCommunity, getContainingThreadID, @@ -634,6 +639,10 @@ return await utils.keyserverJoinThread(request); }, + threadIDMatchesProtocol: (threadID: string) => { + return isSchemaRegExp.test(threadID) && !thickIDRegex.test(threadID); + }, + allowsDeletingSidebarSource: true, presentationDetails: { @@ -662,6 +671,8 @@ arePendingThreadsDescendantsOfGenesis: true, threadActivityUpdatedByDMActivityHandler: false, + + membershipMessageNotifAction: messageNotifyTypes.NONE, }); function pendingThreadType(numberOfOtherMembers: number) { diff --git a/lib/shared/threads/protocols/thread-protocols.js b/lib/shared/threads/protocols/thread-protocols.js --- a/lib/shared/threads/protocols/thread-protocols.js +++ b/lib/shared/threads/protocols/thread-protocols.js @@ -9,4 +9,8 @@ keyserverThreadProtocol, ]; -export { protocols }; +function getProtocolByThreadID(threadID: string): ?ThreadProtocol { + return protocols().find(p => p.threadIDMatchesProtocol(threadID)); +} + +export { protocols, getProtocolByThreadID }; diff --git a/lib/shared/threads/thread-spec.js b/lib/shared/threads/thread-spec.js --- a/lib/shared/threads/thread-spec.js +++ b/lib/shared/threads/thread-spec.js @@ -85,6 +85,7 @@ OutboundDMOperationSpecification, } from '../dm-ops/dm-op-types.js'; import type { FetchThickMessagesType } from '../message-utils.js'; +import type { MessageNotifyType } from '../messages/message-spec.js'; import type { CreatePendingThreadArgs } from '../thread-utils.js'; export type ThreadTrait = @@ -371,6 +372,7 @@ input: ProtocolJoinThreadInput, utils: JoinThreadUtils, ) => Promise, + +threadIDMatchesProtocol: string => boolean, +allowsDeletingSidebarSource: boolean, +presentationDetails: { +membershipChangesShownInThreadPreview: boolean, @@ -393,6 +395,7 @@ // This flag is temporary. It should be deleted as a part of // https://linear.app/comm/issue/ENG-10729/consider-merging-activity-handlers +threadActivityUpdatedByDMActivityHandler: boolean, + +membershipMessageNotifAction: MessageNotifyType, }; export type ThreadSpec< diff --git a/lib/utils/validation-utils.js b/lib/utils/validation-utils.js --- a/lib/utils/validation-utils.js +++ b/lib/utils/validation-utils.js @@ -111,6 +111,7 @@ const uuidRegex = '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}'; const idSchemaRegex = `(?:(?:[0-9]+|${uuidRegex})\\|)?(?:[0-9]+|${uuidRegex})`; +const isSchemaRegExp: RegExp = new RegExp(`^${idSchemaRegex}$`); const pendingSidebarURLPrefix = 'sidebar'; const pendingThickSidebarURLPrefix = 'dm_sidebar'; @@ -156,4 +157,5 @@ validChatNameRegex, validChatNameRegexString, chatNameMaxLength, + isSchemaRegExp, };