mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-03 14:19:56 +00:00
UBERF-6802: Improve create chat message performance (#5530)
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
parent
0c4ff22173
commit
9d47b22a17
@ -20,7 +20,6 @@ import chunter from '@hcengineering/chunter'
|
|||||||
import serverNotification from '@hcengineering/server-notification'
|
import serverNotification from '@hcengineering/server-notification'
|
||||||
import serverCore, { type ObjectDDParticipant } from '@hcengineering/server-core'
|
import serverCore, { type ObjectDDParticipant } from '@hcengineering/server-core'
|
||||||
import serverChunter from '@hcengineering/server-chunter'
|
import serverChunter from '@hcengineering/server-chunter'
|
||||||
import notification from '@hcengineering/notification'
|
|
||||||
|
|
||||||
export { serverChunterId } from '@hcengineering/server-chunter'
|
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, {
|
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||||
func: serverChunter.function.IsDirectMessage
|
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
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ import serverNotification, {
|
|||||||
type TypeMatch,
|
type TypeMatch,
|
||||||
type NotificationContentProvider
|
type NotificationContentProvider
|
||||||
} from '@hcengineering/server-notification'
|
} from '@hcengineering/server-notification'
|
||||||
import chunter from '@hcengineering/model-chunter'
|
|
||||||
|
|
||||||
export { serverNotificationId } from '@hcengineering/server-notification'
|
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, {
|
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||||
trigger: serverNotification.trigger.OnAttributeCreate,
|
trigger: serverNotification.trigger.OnAttributeCreate,
|
||||||
txMatch: {
|
txMatch: {
|
||||||
|
@ -125,7 +125,16 @@ export async function createReactionNotifications (
|
|||||||
const docUpdateMessage = TxProcessor.createDoc2Doc(messageTx.tx as TxCreateDoc<DocUpdateMessage>)
|
const docUpdateMessage = TxProcessor.createDoc2Doc(messageTx.tx as TxCreateDoc<DocUpdateMessage>)
|
||||||
|
|
||||||
res = res.concat(
|
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
|
return res
|
||||||
|
@ -41,20 +41,20 @@ import core, {
|
|||||||
TxRemoveDoc,
|
TxRemoveDoc,
|
||||||
TxUpdateDoc
|
TxUpdateDoc
|
||||||
} from '@hcengineering/core'
|
} 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 { getMetadata, IntlString } from '@hcengineering/platform'
|
||||||
import serverCore, { TriggerControl } from '@hcengineering/server-core'
|
import serverCore, { TriggerControl } from '@hcengineering/server-core'
|
||||||
import {
|
import {
|
||||||
getDocCollaborators,
|
getDocCollaborators,
|
||||||
getMixinTx,
|
getMixinTx,
|
||||||
pushActivityInboxNotifications
|
pushActivityInboxNotifications,
|
||||||
|
createCollaboratorNotifications
|
||||||
} from '@hcengineering/server-notification-resources'
|
} from '@hcengineering/server-notification-resources'
|
||||||
import { workbenchId } from '@hcengineering/workbench'
|
import { workbenchId } from '@hcengineering/workbench'
|
||||||
import { stripTags } from '@hcengineering/text'
|
import { stripTags } from '@hcengineering/text'
|
||||||
import { Person, PersonAccount } from '@hcengineering/contact'
|
import { Person, PersonAccount } from '@hcengineering/contact'
|
||||||
import activity, { ActivityMessage, ActivityReference } from '@hcengineering/activity'
|
import activity, { ActivityMessage, ActivityReference } from '@hcengineering/activity'
|
||||||
|
|
||||||
import { IsChannelMessage, IsDirectMessage, IsThreadMessage } from './utils'
|
|
||||||
import { NOTIFICATION_BODY_SIZE } from '@hcengineering/server-notification'
|
import { NOTIFICATION_BODY_SIZE } from '@hcengineering/server-notification'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -143,37 +143,21 @@ async function OnThreadMessageCreated (tx: Tx, control: TriggerControl): Promise
|
|||||||
return [lastReplyTx, employeeTx]
|
return [lastReplyTx, employeeTx]
|
||||||
}
|
}
|
||||||
|
|
||||||
async function OnChatMessageCreated (tx: TxCUD<Doc>, control: TriggerControl): Promise<Tx[]> {
|
async function updateCollaborators (
|
||||||
|
targetDoc: Doc | undefined,
|
||||||
|
tx: TxCUD<Doc>,
|
||||||
|
control: TriggerControl,
|
||||||
|
message: ChatMessage,
|
||||||
|
mixin?: ClassCollaborators
|
||||||
|
): Promise<Tx[]> {
|
||||||
|
if (targetDoc === undefined || mixin === undefined) return []
|
||||||
const hierarchy = control.hierarchy
|
const hierarchy = control.hierarchy
|
||||||
const actualTx = TxProcessor.extractTx(tx) as TxCreateDoc<ChatMessage>
|
|
||||||
|
|
||||||
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 isChannel = hierarchy.isDerived(targetDoc._class, chunter.class.Channel)
|
||||||
|
const res: Tx[] = []
|
||||||
|
|
||||||
if (hierarchy.hasMixin(targetDoc, notification.mixin.Collaborators)) {
|
if (hierarchy.hasMixin(targetDoc, notification.mixin.Collaborators)) {
|
||||||
const collaboratorsMixin = hierarchy.as(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(
|
res.push(
|
||||||
control.txFactory.createTxMixin(
|
control.txFactory.createTxMixin(
|
||||||
targetDoc._id,
|
targetDoc._id,
|
||||||
@ -182,7 +166,7 @@ async function OnChatMessageCreated (tx: TxCUD<Doc>, control: TriggerControl): P
|
|||||||
notification.mixin.Collaborators,
|
notification.mixin.Collaborators,
|
||||||
{
|
{
|
||||||
$push: {
|
$push: {
|
||||||
collaborators: chatMessage.modifiedBy
|
collaborators: message.modifiedBy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -190,19 +174,50 @@ async function OnChatMessageCreated (tx: TxCUD<Doc>, control: TriggerControl): P
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const collaborators = await getDocCollaborators(targetDoc, mixin, control)
|
const collaborators = await getDocCollaborators(targetDoc, mixin, control)
|
||||||
if (!collaborators.includes(chatMessage.modifiedBy)) {
|
if (!collaborators.includes(message.modifiedBy)) {
|
||||||
collaborators.push(chatMessage.modifiedBy)
|
collaborators.push(message.modifiedBy)
|
||||||
}
|
}
|
||||||
res.push(getMixinTx(tx, control, collaborators))
|
res.push(getMixinTx(tx, control, collaborators))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isChannel && !(targetDoc as Channel).members.includes(chatMessage.modifiedBy)) {
|
if (isChannel && !(targetDoc as Channel).members.includes(message.modifiedBy)) {
|
||||||
res.push(...joinChannel(control, targetDoc as Channel, chatMessage.modifiedBy))
|
res.push(...joinChannel(control, targetDoc as Channel, message.modifiedBy))
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function OnChatMessageCreate (tx: TxCUD<Doc>, control: TriggerControl): Promise<Tx[]> {
|
||||||
|
const hierarchy = control.hierarchy
|
||||||
|
const actualTx = TxProcessor.extractTx(tx) as TxCreateDoc<ChatMessage>
|
||||||
|
|
||||||
|
if (actualTx._class !== core.class.TxCreateDoc) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const chatMessage = TxProcessor.createDoc2Doc(actualTx)
|
||||||
|
const cache = new Map<Ref<Doc>, 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<Account>): Tx[] {
|
function joinChannel (control: TriggerControl, channel: Channel, user: Ref<Account>): Tx[] {
|
||||||
if (channel.members.includes(user)) {
|
if (channel.members.includes(user)) {
|
||||||
return []
|
return []
|
||||||
@ -260,7 +275,6 @@ export async function ChunterTrigger (tx: Tx, control: TriggerControl): Promise<
|
|||||||
const res = await Promise.all([
|
const res = await Promise.all([
|
||||||
OnThreadMessageCreated(tx, control),
|
OnThreadMessageCreated(tx, control),
|
||||||
OnThreadMessageDeleted(tx, control),
|
OnThreadMessageDeleted(tx, control),
|
||||||
OnChatMessageCreated(tx as TxCUD<Doc>, control),
|
|
||||||
OnCollaboratorsChanged(tx as TxMixin<Doc, Collaborators>, control)
|
OnCollaboratorsChanged(tx as TxMixin<Doc, Collaborators>, control)
|
||||||
])
|
])
|
||||||
return res.flat()
|
return res.flat()
|
||||||
@ -516,15 +530,13 @@ export default async () => ({
|
|||||||
ChunterTrigger,
|
ChunterTrigger,
|
||||||
OnDirectMessageSent,
|
OnDirectMessageSent,
|
||||||
OnChatMessageRemoved,
|
OnChatMessageRemoved,
|
||||||
OnChannelMembersChanged
|
OnChannelMembersChanged,
|
||||||
|
OnChatMessageCreate
|
||||||
},
|
},
|
||||||
function: {
|
function: {
|
||||||
CommentRemove,
|
CommentRemove,
|
||||||
ChannelHTMLPresenter: channelHTMLPresenter,
|
ChannelHTMLPresenter: channelHTMLPresenter,
|
||||||
ChannelTextPresenter: channelTextPresenter,
|
ChannelTextPresenter: channelTextPresenter,
|
||||||
ChunterNotificationContentProvider: getChunterNotificationContent,
|
ChunterNotificationContentProvider: getChunterNotificationContent
|
||||||
IsDirectMessage,
|
|
||||||
IsThreadMessage,
|
|
||||||
IsChannelMessage
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -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<Account>,
|
|
||||||
type: NotificationType,
|
|
||||||
control: TriggerControl
|
|
||||||
): Promise<boolean> {
|
|
||||||
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<Doc>): Promise<boolean> {
|
|
||||||
return tx.objectClass === chunter.class.ThreadMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
export async function IsDirectMessage (
|
|
||||||
tx: Tx,
|
|
||||||
doc: Doc,
|
|
||||||
user: Ref<Account>,
|
|
||||||
type: NotificationType,
|
|
||||||
control: TriggerControl
|
|
||||||
): Promise<boolean> {
|
|
||||||
const dm = (await control.findAll(chunter.class.DirectMessage, { _id: doc._id as Ref<DirectMessage> }))[0]
|
|
||||||
return dm !== undefined
|
|
||||||
}
|
|
@ -16,7 +16,7 @@
|
|||||||
import type { Plugin, Resource } from '@hcengineering/platform'
|
import type { Plugin, Resource } from '@hcengineering/platform'
|
||||||
import { plugin } from '@hcengineering/platform'
|
import { plugin } from '@hcengineering/platform'
|
||||||
import { ObjectDDParticipantFunc, TriggerFunc } from '@hcengineering/server-core'
|
import { ObjectDDParticipantFunc, TriggerFunc } from '@hcengineering/server-core'
|
||||||
import { NotificationContentProvider, Presenter, TypeMatchFunc } from '@hcengineering/server-notification'
|
import { NotificationContentProvider, Presenter } from '@hcengineering/server-notification'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
@ -31,15 +31,13 @@ export default plugin(serverChunterId, {
|
|||||||
ChunterTrigger: '' as Resource<TriggerFunc>,
|
ChunterTrigger: '' as Resource<TriggerFunc>,
|
||||||
OnDirectMessageSent: '' as Resource<TriggerFunc>,
|
OnDirectMessageSent: '' as Resource<TriggerFunc>,
|
||||||
OnChatMessageRemoved: '' as Resource<TriggerFunc>,
|
OnChatMessageRemoved: '' as Resource<TriggerFunc>,
|
||||||
OnChannelMembersChanged: '' as Resource<TriggerFunc>
|
OnChannelMembersChanged: '' as Resource<TriggerFunc>,
|
||||||
|
OnChatMessageCreate: '' as Resource<TriggerFunc>
|
||||||
},
|
},
|
||||||
function: {
|
function: {
|
||||||
CommentRemove: '' as Resource<ObjectDDParticipantFunc>,
|
CommentRemove: '' as Resource<ObjectDDParticipantFunc>,
|
||||||
ChannelHTMLPresenter: '' as Resource<Presenter>,
|
ChannelHTMLPresenter: '' as Resource<Presenter>,
|
||||||
ChannelTextPresenter: '' as Resource<Presenter>,
|
ChannelTextPresenter: '' as Resource<Presenter>,
|
||||||
IsDirectMessage: '' as TypeMatchFunc,
|
|
||||||
IsChannelMessage: '' as TypeMatchFunc,
|
|
||||||
IsThreadMessage: '' as TypeMatchFunc,
|
|
||||||
ChunterNotificationContentProvider: '' as Resource<NotificationContentProvider>
|
ChunterNotificationContentProvider: '' as Resource<NotificationContentProvider>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -78,7 +78,7 @@ import serverNotification, {
|
|||||||
import { stripTags } from '@hcengineering/text'
|
import { stripTags } from '@hcengineering/text'
|
||||||
import { workbenchId } from '@hcengineering/workbench'
|
import { workbenchId } from '@hcengineering/workbench'
|
||||||
import webpush, { WebPushError } from 'web-push'
|
import webpush, { WebPushError } from 'web-push'
|
||||||
import { Content, NotifyResult } from './types'
|
import { Content, NotifyResult, NotifyParams } from './types'
|
||||||
import {
|
import {
|
||||||
getHTMLPresenter,
|
getHTMLPresenter,
|
||||||
getNotificationContent,
|
getNotificationContent,
|
||||||
@ -386,7 +386,8 @@ export async function pushInboxNotifications (
|
|||||||
modifiedOn: Timestamp,
|
modifiedOn: Timestamp,
|
||||||
senderId: Ref<PersonAccount>,
|
senderId: Ref<PersonAccount>,
|
||||||
shouldPush: boolean,
|
shouldPush: boolean,
|
||||||
shouldUpdateTimestamp = true
|
shouldUpdateTimestamp = true,
|
||||||
|
cache: Map<Ref<Doc>, Doc> = new Map<Ref<Doc>, Doc>()
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const context = getDocNotifyContext(contexts, targetUser, attachedTo, res)
|
const context = getDocNotifyContext(contexts, targetUser, attachedTo, res)
|
||||||
|
|
||||||
@ -434,7 +435,8 @@ export async function pushInboxNotifications (
|
|||||||
notificationData,
|
notificationData,
|
||||||
_class,
|
_class,
|
||||||
senderId,
|
senderId,
|
||||||
notificationTx.objectId
|
notificationTx.objectId,
|
||||||
|
cache
|
||||||
)
|
)
|
||||||
console.log('Push takes', Date.now() - now, 'ms')
|
console.log('Push takes', Date.now() - now, 'ms')
|
||||||
if (pushTx !== undefined) {
|
if (pushTx !== undefined) {
|
||||||
@ -528,7 +530,8 @@ export async function createPushFromInbox (
|
|||||||
data: Data<InboxNotification>,
|
data: Data<InboxNotification>,
|
||||||
_class: Ref<Class<InboxNotification>>,
|
_class: Ref<Class<InboxNotification>>,
|
||||||
senderId: Ref<PersonAccount>,
|
senderId: Ref<PersonAccount>,
|
||||||
_id: Ref<Doc>
|
_id: Ref<Doc>,
|
||||||
|
cache: Map<Ref<Doc>, Doc>
|
||||||
): Promise<Tx | undefined> {
|
): Promise<Tx | undefined> {
|
||||||
let title: string = ''
|
let title: string = ''
|
||||||
let body: string = ''
|
let body: string = ''
|
||||||
@ -547,8 +550,14 @@ export async function createPushFromInbox (
|
|||||||
let senderPerson: Person | undefined
|
let senderPerson: Person | undefined
|
||||||
|
|
||||||
if (sender !== 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 = [
|
const path = [
|
||||||
workbenchId,
|
workbenchId,
|
||||||
control.workspace.workspaceUrl,
|
control.workspace.workspaceUrl,
|
||||||
@ -650,19 +659,11 @@ export async function pushActivityInboxNotifications (
|
|||||||
docNotifyContexts: DocNotifyContext[],
|
docNotifyContexts: DocNotifyContext[],
|
||||||
activityMessages: ActivityMessage[],
|
activityMessages: ActivityMessage[],
|
||||||
shouldUpdateTimestamp: boolean,
|
shouldUpdateTimestamp: boolean,
|
||||||
shouldPush: boolean
|
shouldPush: boolean,
|
||||||
|
cache: Map<Ref<Doc>, Doc> = new Map<Ref<Doc>, Doc>()
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
for (const activityMessage of activityMessages) {
|
for (const activityMessage of activityMessages) {
|
||||||
const existNotifications = await control.findAll(notification.class.ActivityInboxNotification, {
|
const content = await getNotificationContent(originTx, targetUser, object, control, cache)
|
||||||
user: targetUser,
|
|
||||||
attachedTo: activityMessage._id
|
|
||||||
})
|
|
||||||
|
|
||||||
if (existNotifications.length > 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const content = await getNotificationContent(originTx, targetUser, object, control)
|
|
||||||
const data: Partial<Data<ActivityInboxNotification>> = {
|
const data: Partial<Data<ActivityInboxNotification>> = {
|
||||||
...content,
|
...content,
|
||||||
attachedTo: activityMessage._id,
|
attachedTo: activityMessage._id,
|
||||||
@ -682,7 +683,8 @@ export async function pushActivityInboxNotifications (
|
|||||||
activityMessage.modifiedOn,
|
activityMessage.modifiedOn,
|
||||||
originTx.modifiedBy as Ref<PersonAccount>,
|
originTx.modifiedBy as Ref<PersonAccount>,
|
||||||
shouldPush,
|
shouldPush,
|
||||||
shouldUpdateTimestamp
|
shouldUpdateTimestamp,
|
||||||
|
cache
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -693,14 +695,13 @@ export async function getNotificationTxes (
|
|||||||
tx: TxCUD<Doc>,
|
tx: TxCUD<Doc>,
|
||||||
originTx: TxCUD<Doc>,
|
originTx: TxCUD<Doc>,
|
||||||
target: Ref<Account>,
|
target: Ref<Account>,
|
||||||
isOwn: boolean,
|
params: NotifyParams,
|
||||||
isSpace: boolean,
|
|
||||||
docNotifyContexts: DocNotifyContext[],
|
docNotifyContexts: DocNotifyContext[],
|
||||||
activityMessages: ActivityMessage[],
|
activityMessages: ActivityMessage[],
|
||||||
shouldUpdateTimestamp = true
|
cache: Map<Ref<Doc>, Doc>
|
||||||
): Promise<Tx[]> {
|
): Promise<Tx[]> {
|
||||||
const res: Tx[] = []
|
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) {
|
if (notifyResult.allowed) {
|
||||||
await pushActivityInboxNotifications(
|
await pushActivityInboxNotifications(
|
||||||
@ -711,8 +712,9 @@ export async function getNotificationTxes (
|
|||||||
object,
|
object,
|
||||||
docNotifyContexts,
|
docNotifyContexts,
|
||||||
activityMessages,
|
activityMessages,
|
||||||
shouldUpdateTimestamp,
|
params.shouldUpdateTimestamp,
|
||||||
notifyResult.push
|
notifyResult.push,
|
||||||
|
cache
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -745,18 +747,17 @@ export async function createCollabDocInfo (
|
|||||||
tx: TxCUD<Doc>,
|
tx: TxCUD<Doc>,
|
||||||
originTx: TxCUD<Doc>,
|
originTx: TxCUD<Doc>,
|
||||||
object: Doc,
|
object: Doc,
|
||||||
activityMessage: ActivityMessage[],
|
activityMessages: ActivityMessage[],
|
||||||
isOwn: boolean,
|
params: NotifyParams,
|
||||||
isSpace: boolean = false,
|
cache: Map<Ref<Doc>, Doc>
|
||||||
shouldUpdateTimestamp = true
|
|
||||||
): Promise<Tx[]> {
|
): Promise<Tx[]> {
|
||||||
let res: Tx[] = []
|
let res: Tx[] = []
|
||||||
|
|
||||||
if (originTx.space === core.space.DerivedTx) {
|
if (originTx.space === core.space.DerivedTx || collaborators.length === 0) {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
const docMessages = activityMessage.filter((message) => message.attachedTo === object._id)
|
const docMessages = activityMessages.filter((message) => message.attachedTo === object._id)
|
||||||
|
|
||||||
if (docMessages.length === 0) {
|
if (docMessages.length === 0) {
|
||||||
return res
|
return res
|
||||||
@ -778,18 +779,7 @@ export async function createCollabDocInfo (
|
|||||||
|
|
||||||
for (const target of targets) {
|
for (const target of targets) {
|
||||||
res = res.concat(
|
res = res.concat(
|
||||||
await getNotificationTxes(
|
await getNotificationTxes(control, object, tx, originTx, target, params, notifyContexts, docMessages, cache)
|
||||||
control,
|
|
||||||
object,
|
|
||||||
tx,
|
|
||||||
originTx,
|
|
||||||
target,
|
|
||||||
isOwn,
|
|
||||||
isSpace,
|
|
||||||
notifyContexts,
|
|
||||||
docMessages,
|
|
||||||
shouldUpdateTimestamp
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
@ -819,8 +809,13 @@ async function getSpaceCollabTxes (
|
|||||||
doc: Doc,
|
doc: Doc,
|
||||||
tx: TxCUD<Doc>,
|
tx: TxCUD<Doc>,
|
||||||
originTx: TxCUD<Doc>,
|
originTx: TxCUD<Doc>,
|
||||||
activityMessages: ActivityMessage[]
|
activityMessages: ActivityMessage[],
|
||||||
|
cache: Map<Ref<Doc>, Doc>
|
||||||
): Promise<Tx[]> {
|
): Promise<Tx[]> {
|
||||||
|
if (doc.space === core.space.Space) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
const space = (await control.findAll(core.class.Space, { _id: doc.space }))[0]
|
const space = (await control.findAll(core.class.Space, { _id: doc.space }))[0]
|
||||||
if (space === undefined) return []
|
if (space === undefined) return []
|
||||||
const mixin = control.hierarchy.classHierarchyMixin<Doc, ClassCollaborators>(
|
const mixin = control.hierarchy.classHierarchyMixin<Doc, ClassCollaborators>(
|
||||||
@ -830,7 +825,16 @@ async function getSpaceCollabTxes (
|
|||||||
if (mixin !== undefined) {
|
if (mixin !== undefined) {
|
||||||
const collabs = control.hierarchy.as<Doc, Collaborators>(space, notification.mixin.Collaborators)
|
const collabs = control.hierarchy.as<Doc, Collaborators>(space, notification.mixin.Collaborators)
|
||||||
if (collabs.collaborators !== undefined) {
|
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 []
|
return []
|
||||||
@ -840,7 +844,8 @@ async function createCollaboratorDoc (
|
|||||||
tx: TxCreateDoc<Doc>,
|
tx: TxCreateDoc<Doc>,
|
||||||
control: TriggerControl,
|
control: TriggerControl,
|
||||||
activityMessage: ActivityMessage[],
|
activityMessage: ActivityMessage[],
|
||||||
originTx: TxCUD<Doc>
|
originTx: TxCUD<Doc>,
|
||||||
|
cache: Map<Ref<Doc>, Doc>
|
||||||
): Promise<Tx[]> {
|
): Promise<Tx[]> {
|
||||||
const res: Tx[] = []
|
const res: Tx[] = []
|
||||||
const hierarchy = control.hierarchy
|
const hierarchy = control.hierarchy
|
||||||
@ -854,11 +859,20 @@ async function createCollaboratorDoc (
|
|||||||
const collaborators = await getDocCollaborators(doc, mixin, control)
|
const collaborators = await getDocCollaborators(doc, mixin, control)
|
||||||
const mixinTx = getMixinTx(tx, control, collaborators)
|
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(mixinTx)
|
||||||
res.push(...notificationTxes)
|
res.push(...notificationTxes)
|
||||||
|
|
||||||
res.push(...(await getSpaceCollabTxes(control, doc, tx, originTx, activityMessage)))
|
res.push(...(await getSpaceCollabTxes(control, doc, tx, originTx, activityMessage, cache)))
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
@ -867,7 +881,8 @@ async function updateCollaboratorsMixin (
|
|||||||
tx: TxMixin<Doc, Collaborators>,
|
tx: TxMixin<Doc, Collaborators>,
|
||||||
control: TriggerControl,
|
control: TriggerControl,
|
||||||
activityMessages: ActivityMessage[],
|
activityMessages: ActivityMessage[],
|
||||||
originTx: TxCUD<Doc>
|
originTx: TxCUD<Doc>,
|
||||||
|
cache: Map<Ref<Doc>, Doc>
|
||||||
): Promise<Tx[]> {
|
): Promise<Tx[]> {
|
||||||
const { hierarchy } = control
|
const { hierarchy } = control
|
||||||
|
|
||||||
@ -936,7 +951,8 @@ async function updateCollaboratorsMixin (
|
|||||||
docNotifyContexts,
|
docNotifyContexts,
|
||||||
activityMessages,
|
activityMessages,
|
||||||
true,
|
true,
|
||||||
true
|
true,
|
||||||
|
cache
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -947,10 +963,11 @@ async function updateCollaboratorsMixin (
|
|||||||
async function collectionCollabDoc (
|
async function collectionCollabDoc (
|
||||||
tx: TxCollectionCUD<Doc, AttachedDoc>,
|
tx: TxCollectionCUD<Doc, AttachedDoc>,
|
||||||
control: TriggerControl,
|
control: TriggerControl,
|
||||||
activityMessages: ActivityMessage[]
|
activityMessages: ActivityMessage[],
|
||||||
|
cache: Map<Ref<Doc>, Doc>
|
||||||
): Promise<Tx[]> {
|
): Promise<Tx[]> {
|
||||||
const actualTx = TxProcessor.extractTx(tx) as TxCUD<Doc>
|
const actualTx = TxProcessor.extractTx(tx) as TxCUD<Doc>
|
||||||
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)) {
|
if (![core.class.TxCreateDoc, core.class.TxRemoveDoc, core.class.TxUpdateDoc].includes(actualTx._class)) {
|
||||||
return res
|
return res
|
||||||
@ -962,15 +979,28 @@ async function collectionCollabDoc (
|
|||||||
return res
|
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) {
|
if (doc === undefined) {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cache.set(doc._id, doc)
|
||||||
|
|
||||||
const collaborators = await getCollaborators(doc, control, tx, res)
|
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
|
return res
|
||||||
}
|
}
|
||||||
@ -1068,7 +1098,8 @@ async function updateCollaboratorDoc (
|
|||||||
tx: TxUpdateDoc<Doc> | TxMixin<Doc, Doc>,
|
tx: TxUpdateDoc<Doc> | TxMixin<Doc, Doc>,
|
||||||
control: TriggerControl,
|
control: TriggerControl,
|
||||||
originTx: TxCUD<Doc>,
|
originTx: TxCUD<Doc>,
|
||||||
activityMessages: ActivityMessage[]
|
activityMessages: ActivityMessage[],
|
||||||
|
cache: Map<Ref<Doc>, Doc>
|
||||||
): Promise<Tx[]> {
|
): Promise<Tx[]> {
|
||||||
const hierarchy = control.hierarchy
|
const hierarchy = control.hierarchy
|
||||||
let res: Tx[] = []
|
let res: Tx[] = []
|
||||||
@ -1076,6 +1107,7 @@ async function updateCollaboratorDoc (
|
|||||||
if (mixin === undefined) return []
|
if (mixin === undefined) return []
|
||||||
const doc = (await control.findAll(tx.objectClass, { _id: tx.objectId }, { limit: 1 }))[0]
|
const doc = (await control.findAll(tx.objectClass, { _id: tx.objectId }, { limit: 1 }))[0]
|
||||||
if (doc === undefined) return []
|
if (doc === undefined) return []
|
||||||
|
const params: NotifyParams = { isOwn: true, isSpace: false, shouldUpdateTimestamp: true }
|
||||||
if (hierarchy.hasMixin(doc, notification.mixin.Collaborators)) {
|
if (hierarchy.hasMixin(doc, notification.mixin.Collaborators)) {
|
||||||
// we should handle change field and subscribe new collaborators
|
// we should handle change field and subscribe new collaborators
|
||||||
const collabMixin = hierarchy.as(doc, notification.mixin.Collaborators)
|
const collabMixin = hierarchy.as(doc, notification.mixin.Collaborators)
|
||||||
@ -1103,19 +1135,19 @@ async function updateCollaboratorDoc (
|
|||||||
originTx,
|
originTx,
|
||||||
doc,
|
doc,
|
||||||
activityMessages,
|
activityMessages,
|
||||||
true,
|
params,
|
||||||
false
|
cache
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
const collaborators = await getDocCollaborators(doc, mixin, control)
|
const collaborators = await getDocCollaborators(doc, mixin, control)
|
||||||
res.push(getMixinTx(tx, control, collaborators))
|
res.push(getMixinTx(tx, control, collaborators))
|
||||||
res = res.concat(
|
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))
|
res = res.concat(await updateNotifyContextsSpace(control, tx))
|
||||||
|
|
||||||
return res
|
return res
|
||||||
@ -1176,7 +1208,8 @@ export async function createCollaboratorNotifications (
|
|||||||
tx: TxCUD<Doc>,
|
tx: TxCUD<Doc>,
|
||||||
control: TriggerControl,
|
control: TriggerControl,
|
||||||
activityMessages: ActivityMessage[],
|
activityMessages: ActivityMessage[],
|
||||||
originTx?: TxCUD<Doc>
|
originTx?: TxCUD<Doc>,
|
||||||
|
cache: Map<Ref<Doc>, Doc> = new Map<Ref<Doc>, Doc>()
|
||||||
): Promise<Tx[]> {
|
): Promise<Tx[]> {
|
||||||
if (tx.space === core.space.DerivedTx) {
|
if (tx.space === core.space.DerivedTx) {
|
||||||
return []
|
return []
|
||||||
@ -1188,29 +1221,28 @@ export async function createCollaboratorNotifications (
|
|||||||
|
|
||||||
switch (tx._class) {
|
switch (tx._class) {
|
||||||
case core.class.TxCreateDoc:
|
case core.class.TxCreateDoc:
|
||||||
return await createCollaboratorDoc(tx as TxCreateDoc<Doc>, control, activityMessages, originTx ?? tx)
|
return await createCollaboratorDoc(tx as TxCreateDoc<Doc>, control, activityMessages, originTx ?? tx, cache)
|
||||||
case core.class.TxUpdateDoc:
|
case core.class.TxUpdateDoc:
|
||||||
case core.class.TxMixin: {
|
case core.class.TxMixin: {
|
||||||
let res = await updateCollaboratorDoc(tx as TxUpdateDoc<Doc>, control, originTx ?? tx, activityMessages)
|
let res = await updateCollaboratorDoc(tx as TxUpdateDoc<Doc>, control, originTx ?? tx, activityMessages, cache)
|
||||||
res = res.concat(
|
res = res.concat(
|
||||||
await updateCollaboratorsMixin(tx as TxMixin<Doc, Collaborators>, control, activityMessages, originTx ?? tx)
|
await updateCollaboratorsMixin(
|
||||||
|
tx as TxMixin<Doc, Collaborators>,
|
||||||
|
control,
|
||||||
|
activityMessages,
|
||||||
|
originTx ?? tx,
|
||||||
|
cache
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
case core.class.TxCollectionCUD:
|
case core.class.TxCollectionCUD:
|
||||||
return await collectionCollabDoc(tx as TxCollectionCUD<Doc, AttachedDoc>, control, activityMessages)
|
return await collectionCollabDoc(tx as TxCollectionCUD<Doc, AttachedDoc>, control, activityMessages, cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
async function OnChatMessageCreate (tx: TxCollectionCUD<Doc, ChatMessage>, control: TriggerControl): Promise<Tx[]> {
|
|
||||||
const createTx = TxProcessor.extractTx(tx) as TxCreateDoc<ChatMessage>
|
|
||||||
const message = (await control.findAll(chunter.class.ChatMessage, { _id: createTx.objectId }))[0]
|
|
||||||
|
|
||||||
return await createCollaboratorNotifications(control.ctx, tx, control, [message])
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
@ -1314,7 +1346,6 @@ export * from './utils'
|
|||||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||||
export default async () => ({
|
export default async () => ({
|
||||||
trigger: {
|
trigger: {
|
||||||
OnChatMessageCreate,
|
|
||||||
OnAttributeCreate,
|
OnAttributeCreate,
|
||||||
OnAttributeUpdate,
|
OnAttributeUpdate,
|
||||||
OnActivityNotificationViewed,
|
OnActivityNotificationViewed,
|
||||||
|
@ -31,3 +31,9 @@ export interface NotifyResult {
|
|||||||
push: boolean
|
push: boolean
|
||||||
emails: BaseNotificationType[]
|
emails: BaseNotificationType[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface NotifyParams {
|
||||||
|
isOwn: boolean
|
||||||
|
isSpace: boolean
|
||||||
|
shouldUpdateTimestamp: boolean
|
||||||
|
}
|
||||||
|
@ -309,7 +309,8 @@ export function getTextPresenter (_class: Ref<Class<Doc>>, hierarchy: Hierarchy)
|
|||||||
async function getFallbackNotificationFullfillment (
|
async function getFallbackNotificationFullfillment (
|
||||||
object: Doc,
|
object: Doc,
|
||||||
originTx: TxCUD<Doc>,
|
originTx: TxCUD<Doc>,
|
||||||
control: TriggerControl
|
control: TriggerControl,
|
||||||
|
cache: Map<Ref<Doc>, Doc>
|
||||||
): Promise<NotificationContent> {
|
): Promise<NotificationContent> {
|
||||||
const title: IntlString = notification.string.CommonNotificationTitle
|
const title: IntlString = notification.string.CommonNotificationTitle
|
||||||
let body: IntlString = notification.string.CommonNotificationBody
|
let body: IntlString = notification.string.CommonNotificationBody
|
||||||
@ -324,9 +325,10 @@ async function getFallbackNotificationFullfillment (
|
|||||||
|
|
||||||
const account = control.modelDb.getObject(originTx.modifiedBy) as PersonAccount
|
const account = control.modelDb.getObject(originTx.modifiedBy) as PersonAccount
|
||||||
if (account !== undefined) {
|
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) {
|
if (senderPerson !== undefined) {
|
||||||
intlParams.senderName = formatName(senderPerson.name)
|
intlParams.senderName = formatName(senderPerson.name)
|
||||||
|
cache.set(senderPerson._id, senderPerson)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,12 +366,14 @@ export async function getNotificationContent (
|
|||||||
originTx: TxCUD<Doc>,
|
originTx: TxCUD<Doc>,
|
||||||
targetUser: Ref<Account>,
|
targetUser: Ref<Account>,
|
||||||
object: Doc,
|
object: Doc,
|
||||||
control: TriggerControl
|
control: TriggerControl,
|
||||||
|
cache: Map<Ref<Doc>, Doc> = new Map<Ref<Doc>, Doc>()
|
||||||
): Promise<NotificationContent> {
|
): Promise<NotificationContent> {
|
||||||
let { title, body, intlParams, intlParamsNotLocalized } = await getFallbackNotificationFullfillment(
|
let { title, body, intlParams, intlParamsNotLocalized } = await getFallbackNotificationFullfillment(
|
||||||
object,
|
object,
|
||||||
originTx,
|
originTx,
|
||||||
control
|
control,
|
||||||
|
cache
|
||||||
)
|
)
|
||||||
|
|
||||||
const actualTx = TxProcessor.extractTx(originTx)
|
const actualTx = TxProcessor.extractTx(originTx)
|
||||||
|
@ -150,7 +150,6 @@ export default plugin(serverNotificationId, {
|
|||||||
OnAttributeCreate: '' as Resource<TriggerFunc>,
|
OnAttributeCreate: '' as Resource<TriggerFunc>,
|
||||||
OnAttributeUpdate: '' as Resource<TriggerFunc>,
|
OnAttributeUpdate: '' as Resource<TriggerFunc>,
|
||||||
OnReactionChanged: '' as Resource<TriggerFunc>,
|
OnReactionChanged: '' as Resource<TriggerFunc>,
|
||||||
OnChatMessageCreate: '' as Resource<TriggerFunc>,
|
|
||||||
OnActivityNotificationViewed: '' as Resource<TriggerFunc>,
|
OnActivityNotificationViewed: '' as Resource<TriggerFunc>,
|
||||||
OnDocRemove: '' as Resource<TriggerFunc>
|
OnDocRemove: '' as Resource<TriggerFunc>
|
||||||
},
|
},
|
||||||
|
@ -113,7 +113,17 @@ async function getRequestNotificationTx (tx: TxCollectionCUD<Doc, Request>, cont
|
|||||||
})
|
})
|
||||||
|
|
||||||
for (const target of collaborators) {
|
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)
|
res.push(...txes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user