diff --git a/.vscode/launch.json b/.vscode/launch.json index db975903dc2..b7a3e1428fb 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -50,7 +50,8 @@ "ACCOUNTS_URL": "http://localhost:3000", // "SERVER_PROVIDER":"uweb" "SERVER_PROVIDER":"ws", - "MODEL_VERSION": "" + "MODEL_VERSION": "", + "ELASTIC_INDEX_NAME": "local_storage_index" // "RETRANSLATE_URL": "http://127.0.0.1:4500", //"RETRANSLATE_URL": "https://208.167.249.201", diff --git a/server-plugins/activity-resources/src/references.ts b/server-plugins/activity-resources/src/references.ts index 5d03b7c0183..de6e5308935 100644 --- a/server-plugins/activity-resources/src/references.ts +++ b/server-plugins/activity-resources/src/references.ts @@ -101,13 +101,11 @@ export async function getPersonNotificationTxes ( } const res: Tx[] = [] - const collaboratorsTx = await getCollaboratorsTxes(reference, control, receiver) + const doc = (await control.findAll(reference.srcDocClass, { _id: reference.srcDocId }))[0] - if (collaboratorsTx !== undefined) { - res.push(collaboratorsTx) - } + const collaboratorsTx = await getCollaboratorsTxes(reference, control, receiver, doc) - const doc = (await control.findAll(reference.srcDocClass, { _id: reference.srcDocId }))[0] + res.push(...collaboratorsTx) if (doc === undefined) { return res @@ -157,16 +155,27 @@ async function isSpaceAvailable (user: PersonAccount, spaceId: Ref, contr async function getCollaboratorsTxes ( reference: Data, control: TriggerControl, - receiver: Account -): Promise | undefined> { + receiver: Account, + object?: Doc +): Promise[]> { const { hierarchy } = control + const res: TxMixin[] = [] + + if (object !== undefined) { + // Add user to collaborators of object where user is mentioned + const objectTx = getPushCollaboratorTx(control, receiver._id, object) + + if (objectTx !== undefined) { + res.push(objectTx) + } + } if (reference.attachedDocClass === undefined || reference.attachedDocId === undefined) { - return undefined + return res } if (!hierarchy.isDerived(reference.attachedDocClass, activity.class.ActivityMessage)) { - return undefined + return res } const message = ( @@ -180,10 +189,17 @@ async function getCollaboratorsTxes ( )[0] if (message === undefined) { - return undefined + return res } - return getPushCollaboratorTx(control, receiver._id, message) + // Add user to collaborators of message where user is mentioned + const messageTx = getPushCollaboratorTx(control, receiver._id, message) + + if (messageTx !== undefined) { + res.push(messageTx) + } + + return res } async function isReferenceAlreadyNotified ( diff --git a/server-plugins/chunter-resources/src/index.ts b/server-plugins/chunter-resources/src/index.ts index ad2b6fbeac0..3f9eed56742 100644 --- a/server-plugins/chunter-resources/src/index.ts +++ b/server-plugins/chunter-resources/src/index.ts @@ -36,11 +36,12 @@ import core, { TxCollectionCUD, TxCreateDoc, TxCUD, + TxMixin, TxProcessor, TxRemoveDoc, TxUpdateDoc } from '@hcengineering/core' -import notification, { NotificationContent } from '@hcengineering/notification' +import notification, { Collaborators, NotificationContent } from '@hcengineering/notification' import { getMetadata, IntlString } from '@hcengineering/platform' import serverCore, { TriggerControl } from '@hcengineering/server-core' import { @@ -197,16 +198,24 @@ async function OnChatMessageCreated (tx: TxCUD, control: TriggerControl): P } if (isChannel && !(targetDoc as Channel).members.includes(chatMessage.modifiedBy)) { - res.push( - control.txFactory.createTxUpdateDoc(targetDoc._class, targetDoc.space, targetDoc._id, { - $push: { members: chatMessage.modifiedBy } - }) - ) + res.push(...joinChannel(control, targetDoc as Channel, chatMessage.modifiedBy)) } return res } +function joinChannel (control: TriggerControl, channel: Channel, user: Ref): Tx[] { + if (channel.members.includes(user)) { + return [] + } + + return [ + control.txFactory.createTxUpdateDoc(channel._class, channel.space, channel._id, { + $push: { members: user } + }) + ] +} + async function OnThreadMessageDeleted (tx: Tx, control: TriggerControl): Promise { const hierarchy = control.hierarchy const removeTx = TxProcessor.extractTx(tx) as TxRemoveDoc @@ -252,7 +261,8 @@ 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) + OnChatMessageCreated(tx as TxCUD, control), + OnCollaboratorsChanged(tx as TxMixin, control) ]) return res.flat() } @@ -462,6 +472,26 @@ async function OnChannelMembersChanged (tx: TxUpdateDoc, control: Trigg return res } +async function OnCollaboratorsChanged (tx: TxMixin, control: TriggerControl): Promise { + if (tx._class !== core.class.TxMixin || tx.mixin !== notification.mixin.Collaborators) return [] + + if (!control.hierarchy.isDerived(tx.objectClass, chunter.class.Channel)) return [] + + const doc = (await control.findAll(tx.objectClass, { _id: tx.objectId }))[0] as Channel | undefined + + if (doc === undefined) return [] + if (doc.private) return [] + + const added = combineAttributes([tx.attributes], 'collaborators', '$push', '$each') + const res: Tx[] = [] + + for (const addedMember of added) { + res.push(...joinChannel(control, doc, addedMember)) + } + + return res +} + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type export default async () => ({ trigger: {