mirror of
https://github.com/hcengineering/platform.git
synced 2026-08-30 11:49:42 +02:00
175 lines
5.4 KiB
TypeScript
175 lines
5.4 KiB
TypeScript
//
|
|
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
|
// Copyright © 2021, 2022 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, Class, Doc, getCurrentAccount, Ref } from '@hcengineering/core'
|
|
import notification, { Collaborators, DocUpdates, NotificationClient } from '@hcengineering/notification'
|
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
|
import { writable } from 'svelte/store'
|
|
|
|
/**
|
|
* @public
|
|
*/
|
|
export class NotificationClientImpl implements NotificationClient {
|
|
protected static _instance: NotificationClientImpl | undefined = undefined
|
|
readonly docUpdatesStore = writable<Map<Ref<Doc>, DocUpdates>>(new Map())
|
|
docUpdatesMap: Map<Ref<Doc>, DocUpdates> = new Map()
|
|
readonly docUpdates = writable<DocUpdates[]>([])
|
|
|
|
private readonly docUpdatesQuery = createQuery(true)
|
|
|
|
private readonly user: Ref<Account>
|
|
|
|
private constructor () {
|
|
this.user = getCurrentAccount()._id
|
|
this.docUpdatesQuery.query(
|
|
notification.class.DocUpdates,
|
|
{
|
|
user: this.user
|
|
},
|
|
(result) => {
|
|
this.docUpdates.set(result)
|
|
this.docUpdatesMap = new Map(result.map((p) => [p.attachedTo, p]))
|
|
this.docUpdatesStore.set(this.docUpdatesMap)
|
|
}
|
|
)
|
|
}
|
|
|
|
static createClient (): void {
|
|
NotificationClientImpl._instance = new NotificationClientImpl()
|
|
}
|
|
|
|
static getClient (): NotificationClientImpl {
|
|
if (NotificationClientImpl._instance === undefined) {
|
|
NotificationClientImpl._instance = new NotificationClientImpl()
|
|
}
|
|
return NotificationClientImpl._instance
|
|
}
|
|
|
|
async read (_id: Ref<Doc>): Promise<void> {
|
|
const client = getClient()
|
|
const docUpdate = this.docUpdatesMap.get(_id)
|
|
if (docUpdate !== undefined) {
|
|
if (docUpdate.txes.some((p) => p.isNew)) {
|
|
docUpdate.txes.forEach((p) => (p.isNew = false))
|
|
await client.update(docUpdate, { txes: docUpdate.txes })
|
|
}
|
|
}
|
|
}
|
|
|
|
async forceRead (_id: Ref<Doc>, _class: Ref<Class<Doc>>): Promise<void> {
|
|
const client = getClient()
|
|
const docUpdate = this.docUpdatesMap.get(_id)
|
|
if (docUpdate !== undefined) {
|
|
if (docUpdate.txes.some((p) => p.isNew)) {
|
|
docUpdate.txes.forEach((p) => (p.isNew = false))
|
|
await client.update(docUpdate, { txes: docUpdate.txes })
|
|
}
|
|
} else {
|
|
const doc = await client.findOne(_class, { _id })
|
|
if (doc !== undefined) {
|
|
const hiearachy = client.getHierarchy()
|
|
const collab = hiearachy.as<Doc, Collaborators>(doc, notification.mixin.Collaborators)
|
|
if (collab.collaborators === undefined) {
|
|
await client.createMixin<Doc, Collaborators>(
|
|
collab._id,
|
|
collab._class,
|
|
collab.space,
|
|
notification.mixin.Collaborators,
|
|
{
|
|
collaborators: [this.user]
|
|
}
|
|
)
|
|
} else if (!collab.collaborators.includes(this.user)) {
|
|
await client.updateMixin(collab._id, collab._class, collab.space, notification.mixin.Collaborators, {
|
|
$push: {
|
|
collaborators: this.user
|
|
}
|
|
})
|
|
}
|
|
await client.createDoc(notification.class.DocUpdates, doc.space, {
|
|
attachedTo: _id,
|
|
attachedToClass: _class,
|
|
user: this.user,
|
|
hidden: true,
|
|
txes: []
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @public
|
|
*/
|
|
export async function hasntNotifications (object: DocUpdates): Promise<boolean> {
|
|
if (object._class !== notification.class.DocUpdates) return false
|
|
return !object.txes.some((p) => p.isNew)
|
|
}
|
|
|
|
/**
|
|
* @public
|
|
*/
|
|
export async function unsubscribe (object: DocUpdates): Promise<void> {
|
|
const me = getCurrentAccount()._id
|
|
const client = getClient()
|
|
const hierarchy = client.getHierarchy()
|
|
const target = await client.findOne(object.attachedToClass, { _id: object.attachedTo })
|
|
if (target !== undefined) {
|
|
if (hierarchy.hasMixin(target, notification.mixin.Collaborators)) {
|
|
const collab = hierarchy.as(target, notification.mixin.Collaborators)
|
|
if (collab.collaborators.includes(me)) {
|
|
await client.updateMixin(collab._id, collab._class, collab.space, notification.mixin.Collaborators, {
|
|
$pull: {
|
|
collaborators: me
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
await client.remove(object)
|
|
}
|
|
|
|
/**
|
|
* @public
|
|
*/
|
|
export async function hide (object: DocUpdates | DocUpdates[]): Promise<void> {
|
|
const client = getClient()
|
|
if (Array.isArray(object)) {
|
|
for (const value of object) {
|
|
await client.update(value, {
|
|
hidden: true
|
|
})
|
|
}
|
|
} else {
|
|
await client.update(object, {
|
|
hidden: true
|
|
})
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @public
|
|
*/
|
|
export async function markAsUnread (object: DocUpdates): Promise<void> {
|
|
const client = getClient()
|
|
if (object.txes.length === 0) return
|
|
const txes = object.txes
|
|
txes[0].isNew = true
|
|
await client.update(object, {
|
|
txes
|
|
})
|
|
}
|