mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-12 20:57:45 +02:00
Implement @everyone/@here (#8890)
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
@@ -47,7 +47,6 @@ import core, {
|
||||
} from '@hcengineering/core'
|
||||
import notification, {
|
||||
ActivityInboxNotification,
|
||||
BaseNotificationType,
|
||||
ClassCollaborators,
|
||||
Collaborators,
|
||||
CommonInboxNotification,
|
||||
@@ -87,6 +86,7 @@ import {
|
||||
isMixinTx,
|
||||
isShouldNotifyTx,
|
||||
isUserEmployeeInFieldValueTypeMatch,
|
||||
mentionTypeMatch,
|
||||
messageToMarkup,
|
||||
type NotificationProviderControl,
|
||||
replaceAll,
|
||||
@@ -147,6 +147,7 @@ export async function getCommonNotificationTxes (
|
||||
data,
|
||||
_class,
|
||||
modifiedOn,
|
||||
[],
|
||||
true,
|
||||
tx
|
||||
)
|
||||
@@ -191,7 +192,7 @@ function fillTemplate (
|
||||
export async function getContentByTemplate (
|
||||
doc: Doc | undefined,
|
||||
sender: string,
|
||||
type: Ref<BaseNotificationType>,
|
||||
type: Ref<NotificationType>,
|
||||
control: TriggerControl,
|
||||
data: string,
|
||||
notificationData?: InboxNotification,
|
||||
@@ -352,6 +353,7 @@ export async function pushInboxNotifications (
|
||||
data: Partial<Data<InboxNotification>>,
|
||||
_class: Ref<Class<InboxNotification>>,
|
||||
modifiedOn: Timestamp,
|
||||
types: Ref<NotificationType>[],
|
||||
shouldUpdateTimestamp = true,
|
||||
tx?: TxCUD<Doc>
|
||||
): Promise<TxCreateDoc<InboxNotification> | undefined> {
|
||||
@@ -381,6 +383,7 @@ export async function pushInboxNotifications (
|
||||
archived: false,
|
||||
objectId,
|
||||
objectClass,
|
||||
types,
|
||||
...data
|
||||
}
|
||||
const notificationTx = control.txFactory.createTxCreateDoc(_class, receiver.space, notificationData)
|
||||
@@ -500,6 +503,7 @@ export async function pushActivityInboxNotifications (
|
||||
object: Doc,
|
||||
docNotifyContexts: DocNotifyContext[],
|
||||
activityMessage: ActivityMessage,
|
||||
types: Ref<NotificationType>[],
|
||||
shouldUpdateTimestamp: boolean
|
||||
): Promise<TxCreateDoc<InboxNotification> | undefined> {
|
||||
const content = await getNotificationContent(originTx, receiver.employee, sender, object, control)
|
||||
@@ -522,6 +526,7 @@ export async function pushActivityInboxNotifications (
|
||||
data,
|
||||
notification.class.ActivityInboxNotification,
|
||||
activityMessage.modifiedOn,
|
||||
types,
|
||||
shouldUpdateTimestamp,
|
||||
originTx
|
||||
)
|
||||
@@ -590,8 +595,7 @@ export async function getNotificationTxes (
|
||||
control,
|
||||
tx,
|
||||
object,
|
||||
receiver.employee,
|
||||
receiver.socialIds,
|
||||
receiver,
|
||||
params.isOwn,
|
||||
params.isSpace,
|
||||
settings,
|
||||
@@ -599,6 +603,7 @@ export async function getNotificationTxes (
|
||||
)
|
||||
|
||||
if (notifyResult.has(notification.providers.InboxNotificationProvider)) {
|
||||
const types = (notifyResult.get(notification.providers.InboxNotificationProvider) ?? []).map((it) => it._id)
|
||||
const notificationTx = await pushActivityInboxNotifications(
|
||||
ctx,
|
||||
tx,
|
||||
@@ -609,6 +614,7 @@ export async function getNotificationTxes (
|
||||
object,
|
||||
docNotifyContexts,
|
||||
message,
|
||||
types,
|
||||
params.shouldUpdateTimestamp
|
||||
)
|
||||
|
||||
@@ -753,7 +759,7 @@ export async function createCollabDocInfo (
|
||||
|
||||
cache.set(space._id, space)
|
||||
|
||||
const filteredCollaborators = control.hierarchy.isDerived(object._class, core.class.SystemSpace)
|
||||
const filteredCollaborators = !space.private
|
||||
? collaborators
|
||||
: collaborators.filter(
|
||||
(it) =>
|
||||
@@ -1028,7 +1034,7 @@ async function updateCollaboratorsMixin (
|
||||
prevCollabs = mixin !== undefined ? new Set(await getDocCollaborators(ctx, prevDoc, mixin, control)) : new Set()
|
||||
}
|
||||
|
||||
const type = await control.modelDb.findOne(notification.class.BaseNotificationType, {
|
||||
const type = await control.modelDb.findOne(notification.class.NotificationType, {
|
||||
_id: notification.ids.CollaboratoAddNotification
|
||||
})
|
||||
|
||||
@@ -1091,6 +1097,7 @@ async function updateCollaboratorsMixin (
|
||||
prevDoc,
|
||||
docNotifyContexts,
|
||||
message,
|
||||
[],
|
||||
true
|
||||
)
|
||||
}
|
||||
@@ -1712,6 +1719,7 @@ export default async () => ({
|
||||
PushNotificationsHandler
|
||||
},
|
||||
function: {
|
||||
IsUserEmployeeInFieldValueTypeMatch: isUserEmployeeInFieldValueTypeMatch
|
||||
IsUserEmployeeInFieldValueTypeMatch: isUserEmployeeInFieldValueTypeMatch,
|
||||
MentionTypeMatch: mentionTypeMatch
|
||||
}
|
||||
})
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
import {
|
||||
BaseNotificationType,
|
||||
NotificationType,
|
||||
DocNotifyContext,
|
||||
InboxNotification,
|
||||
NotificationProvider
|
||||
@@ -32,7 +32,7 @@ export interface Content {
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type NotifyResult = Map<Ref<NotificationProvider>, BaseNotificationType[]>
|
||||
export type NotifyResult = Map<Ref<NotificationProvider>, NotificationType[]>
|
||||
|
||||
export interface NotifyParams {
|
||||
isOwn: boolean
|
||||
|
||||
@@ -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) ?? []
|
||||
|
||||
Reference in New Issue
Block a user