Implement @everyone/@here (#8890)

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
Kristina
2025-05-12 14:42:58 +07:00
committed by GitHub
parent 137260fe5b
commit 3295adee57
47 changed files with 675 additions and 351 deletions
@@ -40,14 +40,14 @@ import core, {
Ref,
Space,
Tx,
TxCreateDoc,
TxCUD,
TxMixin,
TxProcessor,
TxUpdateDoc
} from '@hcengineering/core'
import notification, {
BaseNotificationType,
Collaborators,
CommonNotificationType,
NotificationContent,
notificationId,
NotificationProvider,
@@ -67,9 +67,10 @@ import serverNotification, {
import serverView from '@hcengineering/server-view'
import { encodeObjectURI } from '@hcengineering/view'
import { workbenchId } from '@hcengineering/workbench'
import { extractReferences, markupToJSON, Reference } from '@hcengineering/text-core'
import { getPersonSpaces } from '@hcengineering/server-contact'
import { NotifyResult } from './types'
import { getPersonSpaces } from '@hcengineering/server-contact'
/**
* @public
@@ -94,6 +95,36 @@ export function isUserEmployeeInFieldValueTypeMatch (
}
}
export const mentionTypeMatch = (
tx: TxCreateDoc<ChatMessage>,
doc: Doc,
person: Ref<Person>,
socialIds: PersonId[],
type: NotificationType,
control: TriggerControl,
account: AccountUuid
): boolean => {
const hierarchy = control.hierarchy
if (tx._class !== core.class.TxCreateDoc) return false
if (!hierarchy.isDerived(tx.objectClass, chunter.class.ChatMessage)) return false
const message = TxProcessor.createDoc2Doc(tx)
const content: string = message.message
const references: Reference[] =
control.contextCache.get(`${message._id}_references`) ?? extractReferences(markupToJSON(content))
control.contextCache.set(`${message._id}_references`, references)
if (references.length === 0) return false
if (references.some(({ objectId }) => objectId === contact.mention.Everyone)) return true
if (references.some(({ objectId }) => objectId === contact.mention.Here)) {
const isOnline = Array.from(control.userStatusMap.values()).some(({ user, online }) => user === account && online)
if (isOnline) return true
}
return references.some(({ objectId }) => objectId === person)
}
/**
* @public
*/
@@ -119,27 +150,20 @@ function escapeRegExp (str: string): string {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
}
export async function shouldNotifyCommon (
export function getAllowedProviders (
control: TriggerControl,
socialIds: PersonId[],
typeId: Ref<CommonNotificationType>,
type: NotificationType,
notificationControl: NotificationProviderControl
): Promise<NotifyResult> {
const type = (await control.modelDb.findAll(notification.class.CommonNotificationType, { _id: typeId }))[0]
if (type === undefined) {
return new Map()
}
const result = new Map<Ref<NotificationProvider>, BaseNotificationType[]>()
const providers = await control.modelDb.findAll(notification.class.NotificationProvider, {})
): Ref<NotificationProvider>[] {
const result: Ref<NotificationProvider>[] = []
const providers = control.modelDb.findAllSync(notification.class.NotificationProvider, {})
for (const provider of providers) {
const allowed = isAllowed(control, socialIds, type, provider, notificationControl)
if (allowed) {
const cur = result.get(provider._id) ?? []
result.set(provider._id, [...cur, type])
result.push(provider._id)
}
}
@@ -149,7 +173,7 @@ export async function shouldNotifyCommon (
export function isAllowed (
control: TriggerControl,
receiverIds: PersonId[],
type: BaseNotificationType,
type: NotificationType,
provider: NotificationProvider,
notificationControl: NotificationProviderControl
): boolean {
@@ -192,8 +216,7 @@ export async function isShouldNotifyTx (
control: TriggerControl,
tx: TxCUD<Doc>,
object: Doc,
person: Ref<Person>,
personIds: PersonId[],
receiver: ReceiverInfo,
isOwn: boolean,
isSpace: boolean,
notificationControl: NotificationProviderControl,
@@ -201,7 +224,7 @@ export async function isShouldNotifyTx (
): Promise<NotifyResult> {
const types = getMatchedTypes(control, tx, isOwn, isSpace, docUpdateMessage?.attributeUpdates?.attrKey)
const modifiedByPersonId = tx.modifiedBy
const result = new Map<Ref<NotificationProvider>, BaseNotificationType[]>()
const result = new Map<Ref<NotificationProvider>, NotificationType[]>()
let providers: NotificationProvider[] = control.modelDb.findAllSync(notification.class.NotificationProvider, {})
if (getMetadata(serverNotification.metadata.InboxOnlyNotifications) === true) {
@@ -209,7 +232,7 @@ export async function isShouldNotifyTx (
}
for (const type of types) {
if (type.allowedForAuthor !== true && personIds.includes(modifiedByPersonId)) {
if (type.allowedForAuthor !== true && receiver.socialIds.includes(modifiedByPersonId)) {
continue
}
@@ -217,7 +240,7 @@ export async function isShouldNotifyTx (
const mixin = control.hierarchy.as(type, serverNotification.mixin.TypeMatch)
if (mixin.func !== undefined) {
const f = await getResource(mixin.func)
let res = f(tx, object, person, personIds, type, control)
let res = f(tx, object, receiver.employee, receiver.socialIds, type, control, receiver.account)
if (res instanceof Promise) {
res = await res
}
@@ -225,7 +248,7 @@ export async function isShouldNotifyTx (
}
}
for (const provider of providers) {
const allowed = isAllowed(control, personIds, type, provider, notificationControl)
const allowed = isAllowed(control, receiver.socialIds, type, provider, notificationControl)
if (allowed) {
const cur = result.get(provider._id) ?? []