diff --git a/models/server-chunter/src/index.ts b/models/server-chunter/src/index.ts index 640fc49ccf..cda4ede775 100644 --- a/models/server-chunter/src/index.ts +++ b/models/server-chunter/src/index.ts @@ -20,7 +20,6 @@ import chunter from '@hcengineering/chunter' import serverNotification from '@hcengineering/server-notification' import serverCore, { type ObjectDDParticipant } from '@hcengineering/server-core' import serverChunter from '@hcengineering/server-chunter' -import notification from '@hcengineering/notification' export { serverChunterId } from '@hcengineering/server-chunter' @@ -78,25 +77,12 @@ export function createModel (builder: Builder): void { } }) - builder.mixin(chunter.ids.DMNotification, notification.class.NotificationType, serverNotification.mixin.TypeMatch, { - func: serverChunter.function.IsDirectMessage + builder.createDoc(serverCore.class.Trigger, core.space.Model, { + trigger: serverChunter.trigger.OnChatMessageCreate, + txMatch: { + _class: core.class.TxCollectionCUD, + 'tx._class': core.class.TxCreateDoc, + 'tx.objectClass': chunter.class.ChatMessage + } }) - - builder.mixin( - chunter.ids.ThreadNotification, - notification.class.NotificationType, - serverNotification.mixin.TypeMatch, - { - func: serverChunter.function.IsThreadMessage - } - ) - - builder.mixin( - chunter.ids.ChannelNotification, - notification.class.NotificationType, - serverNotification.mixin.TypeMatch, - { - func: serverChunter.function.IsChannelMessage - } - ) } diff --git a/models/server-notification/src/index.ts b/models/server-notification/src/index.ts index f3864cf94e..a3323f6b18 100644 --- a/models/server-notification/src/index.ts +++ b/models/server-notification/src/index.ts @@ -30,7 +30,6 @@ import serverNotification, { type TypeMatch, type NotificationContentProvider } from '@hcengineering/server-notification' -import chunter from '@hcengineering/model-chunter' export { serverNotificationId } from '@hcengineering/server-notification' @@ -67,15 +66,6 @@ export function createModel (builder: Builder): void { } }) - builder.createDoc(serverCore.class.Trigger, core.space.Model, { - trigger: serverNotification.trigger.OnChatMessageCreate, - txMatch: { - _class: core.class.TxCollectionCUD, - 'tx._class': core.class.TxCreateDoc, - 'tx.objectClass': chunter.class.ChatMessage - } - }) - builder.createDoc(serverCore.class.Trigger, core.space.Model, { trigger: serverNotification.trigger.OnAttributeCreate, txMatch: { diff --git a/server-plugins/activity-resources/src/index.ts b/server-plugins/activity-resources/src/index.ts index 698c8c6975..87745cbfb8 100644 --- a/server-plugins/activity-resources/src/index.ts +++ b/server-plugins/activity-resources/src/index.ts @@ -125,7 +125,16 @@ export async function createReactionNotifications ( const docUpdateMessage = TxProcessor.createDoc2Doc(messageTx.tx as TxCreateDoc) res = res.concat( - await createCollabDocInfo([user], control, tx.tx, tx, parentMessage, [docUpdateMessage], true, false, false) + await createCollabDocInfo( + [user], + control, + tx.tx, + tx, + parentMessage, + [docUpdateMessage], + { isOwn: true, isSpace: false, shouldUpdateTimestamp: false }, + new Map() + ) ) return res diff --git a/server-plugins/chunter-resources/src/index.ts b/server-plugins/chunter-resources/src/index.ts index 1a28744f15..316663913e 100644 --- a/server-plugins/chunter-resources/src/index.ts +++ b/server-plugins/chunter-resources/src/index.ts @@ -41,20 +41,20 @@ import core, { TxRemoveDoc, TxUpdateDoc } from '@hcengineering/core' -import notification, { Collaborators, NotificationContent } from '@hcengineering/notification' +import notification, { ClassCollaborators, Collaborators, NotificationContent } from '@hcengineering/notification' import { getMetadata, IntlString } from '@hcengineering/platform' import serverCore, { TriggerControl } from '@hcengineering/server-core' import { getDocCollaborators, getMixinTx, - pushActivityInboxNotifications + pushActivityInboxNotifications, + createCollaboratorNotifications } from '@hcengineering/server-notification-resources' import { workbenchId } from '@hcengineering/workbench' import { stripTags } from '@hcengineering/text' import { Person, PersonAccount } from '@hcengineering/contact' import activity, { ActivityMessage, ActivityReference } from '@hcengineering/activity' -import { IsChannelMessage, IsDirectMessage, IsThreadMessage } from './utils' import { NOTIFICATION_BODY_SIZE } from '@hcengineering/server-notification' /** @@ -143,37 +143,21 @@ async function OnThreadMessageCreated (tx: Tx, control: TriggerControl): Promise return [lastReplyTx, employeeTx] } -async function OnChatMessageCreated (tx: TxCUD, control: TriggerControl): Promise { +async function updateCollaborators ( + targetDoc: Doc | undefined, + tx: TxCUD, + control: TriggerControl, + message: ChatMessage, + mixin?: ClassCollaborators +): Promise { + if (targetDoc === undefined || mixin === undefined) return [] const hierarchy = control.hierarchy - const actualTx = TxProcessor.extractTx(tx) as TxCreateDoc - - if ( - actualTx._class !== core.class.TxCreateDoc || - !hierarchy.isDerived(actualTx.objectClass, chunter.class.ChatMessage) - ) { - return [] - } - - const chatMessage = TxProcessor.createDoc2Doc(actualTx) - const mixin = hierarchy.classHierarchyMixin(chatMessage.attachedToClass, notification.mixin.ClassCollaborators) - - if (mixin === undefined) { - return [] - } - - const targetDoc = ( - await control.findAll(chatMessage.attachedToClass, { _id: chatMessage.attachedTo }, { limit: 1 }) - )[0] - - if (targetDoc === undefined) { - return [] - } - const res: Tx[] = [] const isChannel = hierarchy.isDerived(targetDoc._class, chunter.class.Channel) + const res: Tx[] = [] if (hierarchy.hasMixin(targetDoc, notification.mixin.Collaborators)) { const collaboratorsMixin = hierarchy.as(targetDoc, notification.mixin.Collaborators) - if (!collaboratorsMixin.collaborators.includes(chatMessage.modifiedBy)) { + if (!collaboratorsMixin.collaborators.includes(message.modifiedBy)) { res.push( control.txFactory.createTxMixin( targetDoc._id, @@ -182,7 +166,7 @@ async function OnChatMessageCreated (tx: TxCUD, control: TriggerControl): P notification.mixin.Collaborators, { $push: { - collaborators: chatMessage.modifiedBy + collaborators: message.modifiedBy } } ) @@ -190,19 +174,50 @@ async function OnChatMessageCreated (tx: TxCUD, control: TriggerControl): P } } else { const collaborators = await getDocCollaborators(targetDoc, mixin, control) - if (!collaborators.includes(chatMessage.modifiedBy)) { - collaborators.push(chatMessage.modifiedBy) + if (!collaborators.includes(message.modifiedBy)) { + collaborators.push(message.modifiedBy) } res.push(getMixinTx(tx, control, collaborators)) } - if (isChannel && !(targetDoc as Channel).members.includes(chatMessage.modifiedBy)) { - res.push(...joinChannel(control, targetDoc as Channel, chatMessage.modifiedBy)) + if (isChannel && !(targetDoc as Channel).members.includes(message.modifiedBy)) { + res.push(...joinChannel(control, targetDoc as Channel, message.modifiedBy)) } return res } +async function OnChatMessageCreate (tx: TxCUD, control: TriggerControl): Promise { + const hierarchy = control.hierarchy + const actualTx = TxProcessor.extractTx(tx) as TxCreateDoc + + if (actualTx._class !== core.class.TxCreateDoc) { + return [] + } + + const chatMessage = TxProcessor.createDoc2Doc(actualTx) + const cache = new Map, Doc>() + + const mixin = hierarchy.classHierarchyMixin(chatMessage.attachedToClass, notification.mixin.ClassCollaborators) + + let targetDoc: Doc | undefined + + if (mixin !== undefined) { + targetDoc = (await control.findAll(chatMessage.attachedToClass, { _id: chatMessage.attachedTo }, { limit: 1 }))[0] + } + + if (targetDoc !== undefined) { + cache.set(targetDoc._id, targetDoc) + } + + const res = await Promise.all([ + createCollaboratorNotifications(control.ctx, tx, control, [chatMessage], undefined, cache), + updateCollaborators(targetDoc, tx, control, chatMessage, mixin) + ]) + + return res.flat() +} + function joinChannel (control: TriggerControl, channel: Channel, user: Ref): Tx[] { if (channel.members.includes(user)) { return [] @@ -260,7 +275,6 @@ export async function ChunterTrigger (tx: Tx, control: TriggerControl): Promise< const res = await Promise.all([ OnThreadMessageCreated(tx, control), OnThreadMessageDeleted(tx, control), - OnChatMessageCreated(tx as TxCUD, control), OnCollaboratorsChanged(tx as TxMixin, control) ]) return res.flat() @@ -516,15 +530,13 @@ export default async () => ({ ChunterTrigger, OnDirectMessageSent, OnChatMessageRemoved, - OnChannelMembersChanged + OnChannelMembersChanged, + OnChatMessageCreate }, function: { CommentRemove, ChannelHTMLPresenter: channelHTMLPresenter, ChannelTextPresenter: channelTextPresenter, - ChunterNotificationContentProvider: getChunterNotificationContent, - IsDirectMessage, - IsThreadMessage, - IsChannelMessage + ChunterNotificationContentProvider: getChunterNotificationContent } }) diff --git a/server-plugins/chunter-resources/src/utils.ts b/server-plugins/chunter-resources/src/utils.ts deleted file mode 100644 index dd11b970ff..0000000000 --- a/server-plugins/chunter-resources/src/utils.ts +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright © 2023 Hardcore Engineering Inc. -// -// Licensed under the Eclipse Public License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. You may -// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// -import { Account, Doc, Ref, Tx, TxCreateDoc } from '@hcengineering/core' -import { NotificationType } from '@hcengineering/notification' -import { TriggerControl } from '@hcengineering/server-core' -import chunter, { DirectMessage } from '@hcengineering/chunter' -import activity from '@hcengineering/activity' - -/** - * @public - */ -export async function IsChannelMessage ( - tx: Tx, - doc: Doc, - user: Ref, - type: NotificationType, - control: TriggerControl -): Promise { - const hierarchy = control.hierarchy - const isDirect = await IsDirectMessage(tx, doc, user, type, control) - - if (isDirect) { - return false - } - - return hierarchy.isDerived(doc._class, chunter.class.Channel) || hierarchy.hasMixin(doc, activity.mixin.ActivityDoc) -} - -/** - * @public - */ -export async function IsThreadMessage (tx: TxCreateDoc): Promise { - return tx.objectClass === chunter.class.ThreadMessage -} - -/** - * @public - */ -export async function IsDirectMessage ( - tx: Tx, - doc: Doc, - user: Ref, - type: NotificationType, - control: TriggerControl -): Promise { - const dm = (await control.findAll(chunter.class.DirectMessage, { _id: doc._id as Ref }))[0] - return dm !== undefined -} diff --git a/server-plugins/chunter/src/index.ts b/server-plugins/chunter/src/index.ts index 32943eb1a0..2f0b939094 100644 --- a/server-plugins/chunter/src/index.ts +++ b/server-plugins/chunter/src/index.ts @@ -16,7 +16,7 @@ import type { Plugin, Resource } from '@hcengineering/platform' import { plugin } from '@hcengineering/platform' import { ObjectDDParticipantFunc, TriggerFunc } from '@hcengineering/server-core' -import { NotificationContentProvider, Presenter, TypeMatchFunc } from '@hcengineering/server-notification' +import { NotificationContentProvider, Presenter } from '@hcengineering/server-notification' /** * @public @@ -31,15 +31,13 @@ export default plugin(serverChunterId, { ChunterTrigger: '' as Resource, OnDirectMessageSent: '' as Resource, OnChatMessageRemoved: '' as Resource, - OnChannelMembersChanged: '' as Resource + OnChannelMembersChanged: '' as Resource, + OnChatMessageCreate: '' as Resource }, function: { CommentRemove: '' as Resource, ChannelHTMLPresenter: '' as Resource, ChannelTextPresenter: '' as Resource, - IsDirectMessage: '' as TypeMatchFunc, - IsChannelMessage: '' as TypeMatchFunc, - IsThreadMessage: '' as TypeMatchFunc, ChunterNotificationContentProvider: '' as Resource } }) diff --git a/server-plugins/notification-resources/src/index.ts b/server-plugins/notification-resources/src/index.ts index b51a587989..09c03d6c58 100644 --- a/server-plugins/notification-resources/src/index.ts +++ b/server-plugins/notification-resources/src/index.ts @@ -78,7 +78,7 @@ import serverNotification, { import { stripTags } from '@hcengineering/text' import { workbenchId } from '@hcengineering/workbench' import webpush, { WebPushError } from 'web-push' -import { Content, NotifyResult } from './types' +import { Content, NotifyResult, NotifyParams } from './types' import { getHTMLPresenter, getNotificationContent, @@ -386,7 +386,8 @@ export async function pushInboxNotifications ( modifiedOn: Timestamp, senderId: Ref, shouldPush: boolean, - shouldUpdateTimestamp = true + shouldUpdateTimestamp = true, + cache: Map, Doc> = new Map, Doc>() ): Promise { const context = getDocNotifyContext(contexts, targetUser, attachedTo, res) @@ -434,7 +435,8 @@ export async function pushInboxNotifications ( notificationData, _class, senderId, - notificationTx.objectId + notificationTx.objectId, + cache ) console.log('Push takes', Date.now() - now, 'ms') if (pushTx !== undefined) { @@ -528,7 +530,8 @@ export async function createPushFromInbox ( data: Data, _class: Ref>, senderId: Ref, - _id: Ref + _id: Ref, + cache: Map, Doc> ): Promise { let title: string = '' let body: string = '' @@ -547,8 +550,14 @@ export async function createPushFromInbox ( let senderPerson: Person | undefined if (sender !== undefined) { - senderPerson = (await control.findAll(contact.class.Person, { _id: sender.person }))[0] + senderPerson = + (cache.get(sender.person) as Person) ?? (await control.findAll(contact.class.Person, { _id: sender.person }))[0] } + + if (senderPerson !== undefined) { + cache.set(senderPerson._id, senderPerson) + } + const path = [ workbenchId, control.workspace.workspaceUrl, @@ -650,19 +659,11 @@ export async function pushActivityInboxNotifications ( docNotifyContexts: DocNotifyContext[], activityMessages: ActivityMessage[], shouldUpdateTimestamp: boolean, - shouldPush: boolean + shouldPush: boolean, + cache: Map, Doc> = new Map, Doc>() ): Promise { for (const activityMessage of activityMessages) { - const existNotifications = await control.findAll(notification.class.ActivityInboxNotification, { - user: targetUser, - attachedTo: activityMessage._id - }) - - if (existNotifications.length > 0) { - return - } - - const content = await getNotificationContent(originTx, targetUser, object, control) + const content = await getNotificationContent(originTx, targetUser, object, control, cache) const data: Partial> = { ...content, attachedTo: activityMessage._id, @@ -682,7 +683,8 @@ export async function pushActivityInboxNotifications ( activityMessage.modifiedOn, originTx.modifiedBy as Ref, shouldPush, - shouldUpdateTimestamp + shouldUpdateTimestamp, + cache ) } } @@ -693,14 +695,13 @@ export async function getNotificationTxes ( tx: TxCUD, originTx: TxCUD, target: Ref, - isOwn: boolean, - isSpace: boolean, + params: NotifyParams, docNotifyContexts: DocNotifyContext[], activityMessages: ActivityMessage[], - shouldUpdateTimestamp = true + cache: Map, Doc> ): Promise { const res: Tx[] = [] - const notifyResult = await isShouldNotifyTx(control, tx, originTx, object, target, isOwn, isSpace) + const notifyResult = await isShouldNotifyTx(control, tx, originTx, object, target, params.isOwn, params.isSpace) if (notifyResult.allowed) { await pushActivityInboxNotifications( @@ -711,8 +712,9 @@ export async function getNotificationTxes ( object, docNotifyContexts, activityMessages, - shouldUpdateTimestamp, - notifyResult.push + params.shouldUpdateTimestamp, + notifyResult.push, + cache ) } @@ -745,18 +747,17 @@ export async function createCollabDocInfo ( tx: TxCUD, originTx: TxCUD, object: Doc, - activityMessage: ActivityMessage[], - isOwn: boolean, - isSpace: boolean = false, - shouldUpdateTimestamp = true + activityMessages: ActivityMessage[], + params: NotifyParams, + cache: Map, Doc> ): Promise { let res: Tx[] = [] - if (originTx.space === core.space.DerivedTx) { + if (originTx.space === core.space.DerivedTx || collaborators.length === 0) { return res } - const docMessages = activityMessage.filter((message) => message.attachedTo === object._id) + const docMessages = activityMessages.filter((message) => message.attachedTo === object._id) if (docMessages.length === 0) { return res @@ -778,18 +779,7 @@ export async function createCollabDocInfo ( for (const target of targets) { res = res.concat( - await getNotificationTxes( - control, - object, - tx, - originTx, - target, - isOwn, - isSpace, - notifyContexts, - docMessages, - shouldUpdateTimestamp - ) + await getNotificationTxes(control, object, tx, originTx, target, params, notifyContexts, docMessages, cache) ) } return res @@ -819,8 +809,13 @@ async function getSpaceCollabTxes ( doc: Doc, tx: TxCUD, originTx: TxCUD, - activityMessages: ActivityMessage[] + activityMessages: ActivityMessage[], + cache: Map, Doc> ): Promise { + if (doc.space === core.space.Space) { + return [] + } + const space = (await control.findAll(core.class.Space, { _id: doc.space }))[0] if (space === undefined) return [] const mixin = control.hierarchy.classHierarchyMixin( @@ -830,7 +825,16 @@ async function getSpaceCollabTxes ( if (mixin !== undefined) { const collabs = control.hierarchy.as(space, notification.mixin.Collaborators) if (collabs.collaborators !== undefined) { - return await createCollabDocInfo(collabs.collaborators, control, tx, originTx, doc, activityMessages, false, true) + return await createCollabDocInfo( + collabs.collaborators, + control, + tx, + originTx, + doc, + activityMessages, + { isSpace: true, isOwn: false, shouldUpdateTimestamp: true }, + cache + ) } } return [] @@ -840,7 +844,8 @@ async function createCollaboratorDoc ( tx: TxCreateDoc, control: TriggerControl, activityMessage: ActivityMessage[], - originTx: TxCUD + originTx: TxCUD, + cache: Map, Doc> ): Promise { const res: Tx[] = [] const hierarchy = control.hierarchy @@ -854,11 +859,20 @@ async function createCollaboratorDoc ( const collaborators = await getDocCollaborators(doc, mixin, control) const mixinTx = getMixinTx(tx, control, collaborators) - const notificationTxes = await createCollabDocInfo(collaborators, control, tx, originTx, doc, activityMessage, true) + const notificationTxes = await createCollabDocInfo( + collaborators, + control, + tx, + originTx, + doc, + activityMessage, + { isOwn: true, isSpace: false, shouldUpdateTimestamp: true }, + cache + ) res.push(mixinTx) res.push(...notificationTxes) - res.push(...(await getSpaceCollabTxes(control, doc, tx, originTx, activityMessage))) + res.push(...(await getSpaceCollabTxes(control, doc, tx, originTx, activityMessage, cache))) return res } @@ -867,7 +881,8 @@ async function updateCollaboratorsMixin ( tx: TxMixin, control: TriggerControl, activityMessages: ActivityMessage[], - originTx: TxCUD + originTx: TxCUD, + cache: Map, Doc> ): Promise { const { hierarchy } = control @@ -936,7 +951,8 @@ async function updateCollaboratorsMixin ( docNotifyContexts, activityMessages, true, - true + true, + cache ) } } @@ -947,10 +963,11 @@ async function updateCollaboratorsMixin ( async function collectionCollabDoc ( tx: TxCollectionCUD, control: TriggerControl, - activityMessages: ActivityMessage[] + activityMessages: ActivityMessage[], + cache: Map, Doc> ): Promise { const actualTx = TxProcessor.extractTx(tx) as TxCUD - let res = await createCollaboratorNotifications(control.ctx, actualTx, control, activityMessages, tx) + let res = await createCollaboratorNotifications(control.ctx, actualTx, control, activityMessages, tx, cache) if (![core.class.TxCreateDoc, core.class.TxRemoveDoc, core.class.TxUpdateDoc].includes(actualTx._class)) { return res @@ -962,15 +979,28 @@ async function collectionCollabDoc ( return res } - const doc = (await control.findAll(tx.objectClass, { _id: tx.objectId }, { limit: 1 }))[0] + const doc = cache.get(tx.objectId) ?? (await control.findAll(tx.objectClass, { _id: tx.objectId }, { limit: 1 }))[0] if (doc === undefined) { return res } + cache.set(doc._id, doc) + const collaborators = await getCollaborators(doc, control, tx, res) - res = res.concat(await createCollabDocInfo(collaborators, control, actualTx, tx, doc, activityMessages, false)) + res = res.concat( + await createCollabDocInfo( + collaborators, + control, + actualTx, + tx, + doc, + activityMessages, + { isOwn: false, isSpace: false, shouldUpdateTimestamp: true }, + cache + ) + ) return res } @@ -1068,7 +1098,8 @@ async function updateCollaboratorDoc ( tx: TxUpdateDoc | TxMixin, control: TriggerControl, originTx: TxCUD, - activityMessages: ActivityMessage[] + activityMessages: ActivityMessage[], + cache: Map, Doc> ): Promise { const hierarchy = control.hierarchy let res: Tx[] = [] @@ -1076,6 +1107,7 @@ async function updateCollaboratorDoc ( if (mixin === undefined) return [] const doc = (await control.findAll(tx.objectClass, { _id: tx.objectId }, { limit: 1 }))[0] if (doc === undefined) return [] + const params: NotifyParams = { isOwn: true, isSpace: false, shouldUpdateTimestamp: true } if (hierarchy.hasMixin(doc, notification.mixin.Collaborators)) { // we should handle change field and subscribe new collaborators const collabMixin = hierarchy.as(doc, notification.mixin.Collaborators) @@ -1103,19 +1135,19 @@ async function updateCollaboratorDoc ( originTx, doc, activityMessages, - true, - false + params, + cache ) ) } else { const collaborators = await getDocCollaborators(doc, mixin, control) res.push(getMixinTx(tx, control, collaborators)) res = res.concat( - await createCollabDocInfo(collaborators, control, tx, originTx, doc, activityMessages, true, false) + await createCollabDocInfo(collaborators, control, tx, originTx, doc, activityMessages, params, cache) ) } - res = res.concat(await getSpaceCollabTxes(control, doc, tx, originTx, activityMessages)) + res = res.concat(await getSpaceCollabTxes(control, doc, tx, originTx, activityMessages, cache)) res = res.concat(await updateNotifyContextsSpace(control, tx)) return res @@ -1176,7 +1208,8 @@ export async function createCollaboratorNotifications ( tx: TxCUD, control: TriggerControl, activityMessages: ActivityMessage[], - originTx?: TxCUD + originTx?: TxCUD, + cache: Map, Doc> = new Map, Doc>() ): Promise { if (tx.space === core.space.DerivedTx) { return [] @@ -1188,29 +1221,28 @@ export async function createCollaboratorNotifications ( switch (tx._class) { case core.class.TxCreateDoc: - return await createCollaboratorDoc(tx as TxCreateDoc, control, activityMessages, originTx ?? tx) + return await createCollaboratorDoc(tx as TxCreateDoc, control, activityMessages, originTx ?? tx, cache) case core.class.TxUpdateDoc: case core.class.TxMixin: { - let res = await updateCollaboratorDoc(tx as TxUpdateDoc, control, originTx ?? tx, activityMessages) + let res = await updateCollaboratorDoc(tx as TxUpdateDoc, control, originTx ?? tx, activityMessages, cache) res = res.concat( - await updateCollaboratorsMixin(tx as TxMixin, control, activityMessages, originTx ?? tx) + await updateCollaboratorsMixin( + tx as TxMixin, + control, + activityMessages, + originTx ?? tx, + cache + ) ) return res } case core.class.TxCollectionCUD: - return await collectionCollabDoc(tx as TxCollectionCUD, control, activityMessages) + return await collectionCollabDoc(tx as TxCollectionCUD, control, activityMessages, cache) } return [] } -async function OnChatMessageCreate (tx: TxCollectionCUD, control: TriggerControl): Promise { - const createTx = TxProcessor.extractTx(tx) as TxCreateDoc - const message = (await control.findAll(chunter.class.ChatMessage, { _id: createTx.objectId }))[0] - - return await createCollaboratorNotifications(control.ctx, tx, control, [message]) -} - /** * @public */ @@ -1314,7 +1346,6 @@ export * from './utils' // eslint-disable-next-line @typescript-eslint/explicit-function-return-type export default async () => ({ trigger: { - OnChatMessageCreate, OnAttributeCreate, OnAttributeUpdate, OnActivityNotificationViewed, diff --git a/server-plugins/notification-resources/src/types.ts b/server-plugins/notification-resources/src/types.ts index c40f164ee2..91ef93d58e 100644 --- a/server-plugins/notification-resources/src/types.ts +++ b/server-plugins/notification-resources/src/types.ts @@ -31,3 +31,9 @@ export interface NotifyResult { push: boolean emails: BaseNotificationType[] } + +export interface NotifyParams { + isOwn: boolean + isSpace: boolean + shouldUpdateTimestamp: boolean +} diff --git a/server-plugins/notification-resources/src/utils.ts b/server-plugins/notification-resources/src/utils.ts index 508392577e..4290a5aa50 100644 --- a/server-plugins/notification-resources/src/utils.ts +++ b/server-plugins/notification-resources/src/utils.ts @@ -309,7 +309,8 @@ export function getTextPresenter (_class: Ref>, hierarchy: Hierarchy) async function getFallbackNotificationFullfillment ( object: Doc, originTx: TxCUD, - control: TriggerControl + control: TriggerControl, + cache: Map, Doc> ): Promise { const title: IntlString = notification.string.CommonNotificationTitle let body: IntlString = notification.string.CommonNotificationBody @@ -324,9 +325,10 @@ async function getFallbackNotificationFullfillment ( const account = control.modelDb.getObject(originTx.modifiedBy) as PersonAccount if (account !== undefined) { - const senderPerson = await findPersonForAccount(control, account.person) + const senderPerson = (cache.get(account.person) as Person) ?? (await findPersonForAccount(control, account.person)) if (senderPerson !== undefined) { intlParams.senderName = formatName(senderPerson.name) + cache.set(senderPerson._id, senderPerson) } } @@ -364,12 +366,14 @@ export async function getNotificationContent ( originTx: TxCUD, targetUser: Ref, object: Doc, - control: TriggerControl + control: TriggerControl, + cache: Map, Doc> = new Map, Doc>() ): Promise { let { title, body, intlParams, intlParamsNotLocalized } = await getFallbackNotificationFullfillment( object, originTx, - control + control, + cache ) const actualTx = TxProcessor.extractTx(originTx) diff --git a/server-plugins/notification/src/index.ts b/server-plugins/notification/src/index.ts index b60c9c2feb..35de21e6ff 100644 --- a/server-plugins/notification/src/index.ts +++ b/server-plugins/notification/src/index.ts @@ -150,7 +150,6 @@ export default plugin(serverNotificationId, { OnAttributeCreate: '' as Resource, OnAttributeUpdate: '' as Resource, OnReactionChanged: '' as Resource, - OnChatMessageCreate: '' as Resource, OnActivityNotificationViewed: '' as Resource, OnDocRemove: '' as Resource }, diff --git a/server-plugins/request-resources/src/index.ts b/server-plugins/request-resources/src/index.ts index 4306b56c9c..04dc71e67b 100644 --- a/server-plugins/request-resources/src/index.ts +++ b/server-plugins/request-resources/src/index.ts @@ -113,7 +113,17 @@ async function getRequestNotificationTx (tx: TxCollectionCUD, cont }) for (const target of collaborators) { - const txes = await getNotificationTxes(control, request, tx.tx, tx, target, true, false, notifyContexts, messages) + const txes = await getNotificationTxes( + control, + request, + tx.tx, + tx, + target, + { isOwn: true, isSpace: false, shouldUpdateTimestamp: true }, + notifyContexts, + messages, + new Map() + ) res.push(...txes) }