diff --git a/packages/text/src/markup/utils.ts b/packages/text/src/markup/utils.ts index 55b537ee39..4c6a4c0055 100644 --- a/packages/text/src/markup/utils.ts +++ b/packages/text/src/markup/utils.ts @@ -228,6 +228,19 @@ export function stripTags (markup: Markup, textLimit = 0, extensions: Extensions let charCount = 0 let isHardStop = false + const pushText = (text: string): void => { + if (textLimit > 0 && charCount + text.length > textLimit) { + const toAddCount = textLimit - charCount + const textPart = text.substring(0, toAddCount) + textParts.push(textPart) + textParts.push(ELLIPSIS_CHAR) + isHardStop = true + } else { + textParts.push(text) + charCount += text.length + } + } + parsed.descendants((node, _pos, parent): boolean => { if (isHardStop) { return false @@ -235,22 +248,16 @@ export function stripTags (markup: Markup, textLimit = 0, extensions: Extensions if (node.type.isText) { const text = node.text ?? '' - if (textLimit > 0 && charCount + text.length > textLimit) { - const toAddCount = textLimit - charCount - const textPart = text.substring(0, toAddCount) - textParts.push(textPart) - textParts.push(ELLIPSIS_CHAR) - isHardStop = true - } else { - textParts.push(text) - charCount += text.length - } + pushText(text) return false } else if (node.type.isBlock) { if (textParts.length > 0 && textParts[textParts.length - 1] !== WHITESPACE) { textParts.push(WHITESPACE) charCount++ } + } else if (node.type.name === 'reference') { + const label = node.attrs.label ?? '' + pushText(label.length > 0 ? `@${label}` : '') } return true }) diff --git a/server-plugins/activity-resources/src/references.ts b/server-plugins/activity-resources/src/references.ts index 1268325772..7c313a80c0 100644 --- a/server-plugins/activity-resources/src/references.ts +++ b/server-plugins/activity-resources/src/references.ts @@ -49,8 +49,10 @@ import contact, { Person, PersonAccount } from '@hcengineering/contact' import { getCommonNotificationTxes, getPushCollaboratorTx, - isMessageAlreadyNotified, - shouldNotifyCommon + shouldNotifyCommon, + isShouldNotifyTx, + NotifyResult, + createPushFromInbox } from '@hcengineering/server-notification-resources' async function getPersonAccount (person: Ref, control: TriggerControl): Promise { @@ -147,18 +149,27 @@ export async function getPersonNotificationTxes ( ) } - const data: Partial> = { + const data: Omit, 'docNotifyContext'> = { header: activity.string.MentionedYouIn, messageHtml: reference.message, - mentionedIn: reference.attachedDocId, - mentionedInClass: reference.attachedDocClass + mentionedIn: reference.attachedDocId ?? reference.srcDocId, + mentionedInClass: reference.attachedDocClass ?? reference.srcDocClass, + user: receiver._id, + isViewed: false } const notifyResult = await shouldNotifyCommon(control, receiver._id, notification.ids.MentionCommonNotificationType) + const messageNotifyResult = await getMessageNotifyResult(reference, receiver._id, control, originTx, doc) - if (await isReferenceAlreadyNotified(reference, receiver._id, control)) { + if (messageNotifyResult.allowed) { notifyResult.allowed = false } + if (messageNotifyResult.push) { + notifyResult.push = false + } + if (messageNotifyResult.emails.length > 0) { + notifyResult.emails = [] + } const txes = await getCommonNotificationTxes( control, @@ -174,6 +185,32 @@ export async function getPersonNotificationTxes ( notification.class.MentionInboxNotification ) + if (!notifyResult.allowed && notifyResult.push) { + const exists = ( + await control.findAll( + notification.class.ActivityInboxNotification, + { attachedTo: reference.attachedDocId as Ref, user: receiver._id }, + { limit: 1, projection: { _id: 1 } } + ) + )[0] + + if (exists !== undefined) { + const pushTx = await createPushFromInbox( + control, + receiver._id, + reference.srcDocId, + reference.srcDocClass, + { ...data, docNotifyContext: exists.docNotifyContext }, + notification.class.MentionInboxNotification, + senderId as Ref, + exists._id, + new Map() + ) + if (pushTx !== undefined) { + res.push(pushTx) + } + } + } res.push(...txes) return res } @@ -238,22 +275,29 @@ async function getCollaboratorsTxes ( return res } -async function isReferenceAlreadyNotified ( +async function getMessageNotifyResult ( reference: Data, receiver: Ref, - control: TriggerControl -): Promise { + control: TriggerControl, + originTx: TxCUD, + doc: Doc +): Promise { const { hierarchy } = control + const tx = TxProcessor.extractTx(originTx) as TxCUD - if (reference.attachedDocClass === undefined || reference.attachedDocId === undefined) { - return false + if ( + reference.attachedDocClass === undefined || + reference.attachedDocId === undefined || + tx._class !== core.class.TxCreateDoc + ) { + return { allowed: false, emails: [], push: false } } if (!hierarchy.isDerived(reference.attachedDocClass, activity.class.ActivityMessage)) { - return false + return { allowed: false, emails: [], push: false } } - return await isMessageAlreadyNotified(reference.attachedDocId as Ref, receiver, control) + return await isShouldNotifyTx(control, tx, originTx, doc, receiver, false, false, undefined) } function isMarkupType (type: Ref>>): boolean { diff --git a/server-plugins/notification-resources/src/index.ts b/server-plugins/notification-resources/src/index.ts index 71b8ac2dea..cf9b30e152 100644 --- a/server-plugins/notification-resources/src/index.ts +++ b/server-plugins/notification-resources/src/index.ts @@ -110,20 +110,6 @@ export function getPushCollaboratorTx ( return undefined } -export async function isMessageAlreadyNotified ( - _id: Ref, - user: Ref, - control: TriggerControl -): Promise { - const exists = await control.findAll( - notification.class.ActivityInboxNotification, - { attachedTo: _id, user }, - { limit: 1, projection: { _id: 1 } } - ) - - return exists.length > 0 -} - export async function getCommonNotificationTxes ( control: TriggerControl, doc: Doc, @@ -531,7 +517,7 @@ export async function createPushFromInbox ( _class: Ref>, senderId: Ref, _id: Ref, - cache: Map, Doc> + cache: Map, Doc> = new Map, Doc>() ): Promise { let title: string = '' let body: string = ''