mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-22 03:14:40 +03:00
[UBER-781] Adding chats to inbox after sending messages (#3621)
Signed-off-by: Oleg Solodkov <oleg.solodkov@xored.com>
This commit is contained in:
parent
77f6b3dfd6
commit
04274d1167
@ -46,10 +46,11 @@ export function createModel (builder: Builder): void {
|
||||
})
|
||||
|
||||
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||
trigger: serverChunter.trigger.OnDmCreate,
|
||||
trigger: serverChunter.trigger.OnMessageSent,
|
||||
txMatch: {
|
||||
objectClass: chunter.class.DirectMessage,
|
||||
_class: core.class.TxCreateDoc
|
||||
_class: core.class.TxCollectionCUD,
|
||||
collection: 'messages'
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -73,6 +73,7 @@
|
||||
"ConfigDescription": "Extension to perform text communications",
|
||||
"LastMessage": "Last message",
|
||||
"You": "You",
|
||||
"YouHaveStartedAConversation": "You have started a conversation"
|
||||
"YouHaveJoinedTheConversation": "You have joined the conversation",
|
||||
"NoMessages": "There are no messages yet"
|
||||
}
|
||||
}
|
@ -73,6 +73,7 @@
|
||||
"ConfigDescription": "Расширение для текстовых переписок",
|
||||
"LastMessage": "Последнее сообщение",
|
||||
"You": "Вы",
|
||||
"YouHaveStartedAConversation": "Вы начали диалог"
|
||||
"YouHaveJoinedTheConversation": "Вы присоединились к диалогу",
|
||||
"NoMessages": "Сообщений пока нет"
|
||||
}
|
||||
}
|
@ -55,7 +55,7 @@
|
||||
<MessagePreview value={message} />
|
||||
{/each}
|
||||
{:else}
|
||||
<Label label={chunterResources.string.YouHaveStartedAConversation} />
|
||||
<Label label={chunterResources.string.NoMessages} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
@ -89,6 +89,7 @@ export default mergeIds(chunterId, chunter, {
|
||||
NoResults: '' as IntlString,
|
||||
CopyLink: '' as IntlString,
|
||||
You: '' as IntlString,
|
||||
YouHaveStartedAConversation: '' as IntlString
|
||||
YouHaveJoinedTheConversation: '' as IntlString,
|
||||
NoMessages: '' as IntlString
|
||||
}
|
||||
})
|
||||
|
@ -190,8 +190,7 @@ export default plugin(chunterId, {
|
||||
DMNotification: '' as Ref<NotificationType>,
|
||||
MentionNotification: '' as Ref<NotificationType>,
|
||||
ThreadNotification: '' as Ref<NotificationType>,
|
||||
ChannelNotification: '' as Ref<NotificationType>,
|
||||
DMCreationNotification: '' as Ref<NotificationType>
|
||||
ChannelNotification: '' as Ref<NotificationType>
|
||||
},
|
||||
app: {
|
||||
Chunter: '' as Ref<Doc>
|
||||
|
@ -19,7 +19,7 @@
|
||||
"Change": "Change",
|
||||
"AddedRemoved": "Added/removed",
|
||||
"YouAddedCollaborators": "You have been added to collaborators",
|
||||
"YouHaveStartedAConversation": "You have started a conversation",
|
||||
"YouHaveJoinedTheConversation": "You have joined the conversation",
|
||||
"ChangeCollaborators": "changed collaborators",
|
||||
"Activity": "Activity",
|
||||
"People": "People",
|
||||
|
@ -19,7 +19,7 @@
|
||||
"Change": "Изменено",
|
||||
"AddedRemoved": "Добавлено/удалено",
|
||||
"YouAddedCollaborators": "Вы были добавлены как участник",
|
||||
"YouHaveStartedAConversation": "Вы начали диалог",
|
||||
"YouHaveJoinedTheConversation": "Вы присоединились к диалогу",
|
||||
"ChangeCollaborators": "изменил(а) участники",
|
||||
"Activity": "Активность",
|
||||
"People": "Люди",
|
||||
|
@ -28,6 +28,7 @@
|
||||
import EmployeeInbox from './EmployeeInbox.svelte'
|
||||
import Filter from './Filter.svelte'
|
||||
import People from './People.svelte'
|
||||
import { subscribe } from '../utils'
|
||||
|
||||
export let visibileNav: boolean
|
||||
let filter: 'all' | 'read' | 'unread' = 'all'
|
||||
@ -100,6 +101,10 @@
|
||||
const personAccount = await client.findOne(contact.class.PersonAccount, { person: employee._id })
|
||||
if (personAccount !== undefined) {
|
||||
const channel = await getDirectChannel(client, me._id as Ref<PersonAccount>, personAccount._id)
|
||||
|
||||
// re-subscribing in case DM was removed from notifications
|
||||
await subscribe(chunter.class.DirectMessage, channel)
|
||||
|
||||
openDM(channel)
|
||||
}
|
||||
}
|
||||
|
@ -23,4 +23,4 @@
|
||||
export let value: DirectMessage
|
||||
</script>
|
||||
|
||||
<Label label={notification.string.YouHaveStartedAConversation} />
|
||||
<Label label={notification.string.YouHaveJoinedTheConversation} />
|
||||
|
@ -30,7 +30,7 @@ export default mergeIds(notificationId, notification, {
|
||||
Change: '' as IntlString,
|
||||
AddedRemoved: '' as IntlString,
|
||||
YouAddedCollaborators: '' as IntlString,
|
||||
YouHaveStartedAConversation: '' as IntlString,
|
||||
YouHaveJoinedTheConversation: '' as IntlString,
|
||||
ChangeCollaborators: '' as IntlString,
|
||||
Activity: '' as IntlString,
|
||||
People: '' as IntlString,
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Account, Class, Doc, getCurrentAccount, Ref } from '@hcengineering/core'
|
||||
import { Account, Class, Doc, DocumentUpdate, getCurrentAccount, Ref, TxOperations } from '@hcengineering/core'
|
||||
import notification, { Collaborators, DocUpdates, NotificationClient } from '@hcengineering/notification'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { writable } from 'svelte/store'
|
||||
@ -119,29 +119,69 @@ export async function hasntNotifications (object: DocUpdates): Promise<boolean>
|
||||
return !object.txes.some((p) => p.isNew)
|
||||
}
|
||||
|
||||
enum OpWithMe {
|
||||
Add = 'add',
|
||||
Remove = 'remove'
|
||||
}
|
||||
|
||||
async function updateMeInCollaborators (
|
||||
client: TxOperations,
|
||||
docClass: Ref<Class<Doc>>,
|
||||
docId: Ref<Doc>,
|
||||
op: OpWithMe
|
||||
): Promise<void> {
|
||||
const me = getCurrentAccount()._id
|
||||
const hierarchy = client.getHierarchy()
|
||||
const target = await client.findOne(docClass, { _id: docId })
|
||||
if (target !== undefined) {
|
||||
if (hierarchy.hasMixin(target, notification.mixin.Collaborators)) {
|
||||
const collab = hierarchy.as(target, notification.mixin.Collaborators)
|
||||
let collabUpdate: DocumentUpdate<Collaborators> | undefined
|
||||
|
||||
if (collab.collaborators.includes(me) && op === OpWithMe.Remove) {
|
||||
collabUpdate = {
|
||||
$pull: {
|
||||
collaborators: me
|
||||
}
|
||||
}
|
||||
} else if (!collab.collaborators.includes(me) && op === OpWithMe.Add) {
|
||||
collabUpdate = {
|
||||
$push: {
|
||||
collaborators: me
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (collabUpdate !== undefined) {
|
||||
await client.updateMixin(
|
||||
collab._id,
|
||||
collab._class,
|
||||
collab.space,
|
||||
notification.mixin.Collaborators,
|
||||
collabUpdate
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 updateMeInCollaborators(client, object.attachedToClass, object.attachedTo, OpWithMe.Remove)
|
||||
await client.remove(object)
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export async function subscribe (docClass: Ref<Class<Doc>>, docId: Ref<Doc>): Promise<void> {
|
||||
const client = getClient()
|
||||
await updateMeInCollaborators(client, docClass, docId, OpWithMe.Add)
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
|
@ -13,15 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import chunter, {
|
||||
Backlink,
|
||||
chunterId,
|
||||
ChunterSpace,
|
||||
Comment,
|
||||
DirectMessage,
|
||||
Message,
|
||||
ThreadMessage
|
||||
} from '@hcengineering/chunter'
|
||||
import chunter, { Backlink, chunterId, ChunterSpace, Comment, Message, ThreadMessage } from '@hcengineering/chunter'
|
||||
import contact, { Employee, PersonAccount } from '@hcengineering/contact'
|
||||
import core, {
|
||||
Account,
|
||||
@ -44,7 +36,7 @@ import core, {
|
||||
import notification, { Collaborators, NotificationType } from '@hcengineering/notification'
|
||||
import { getMetadata } from '@hcengineering/platform'
|
||||
import serverCore, { TriggerControl } from '@hcengineering/server-core'
|
||||
import { pushNotification, getDocCollaborators, getMixinTx } from '@hcengineering/server-notification-resources'
|
||||
import { getDocCollaborators, getMixinTx, pushNotification } from '@hcengineering/server-notification-resources'
|
||||
import { workbenchId } from '@hcengineering/workbench'
|
||||
|
||||
/**
|
||||
@ -216,29 +208,50 @@ export async function ChunterTrigger (tx: Tx, control: TriggerControl): Promise<
|
||||
|
||||
/**
|
||||
* @public
|
||||
* Sends notification to the message sender in case when DM
|
||||
* notifications are deleted or hidden. This is required for
|
||||
* the DM to re-appear in the sender's inbox.
|
||||
*/
|
||||
export async function OnDmCreate (tx: Tx, control: TriggerControl): Promise<Tx[]> {
|
||||
const ptx = tx as TxCreateDoc<DirectMessage>
|
||||
export async function OnMessageSent (tx: Tx, control: TriggerControl): Promise<Tx[]> {
|
||||
const ptx = TxProcessor.extractTx(tx) as TxCreateDoc<Message>
|
||||
if (ptx._class !== core.class.TxCreateDoc) return []
|
||||
|
||||
const message = TxProcessor.createDoc2Doc(ptx)
|
||||
if (message.createdBy === undefined) return []
|
||||
|
||||
if (!control.hierarchy.isDerived(message.attachedToClass, chunter.class.DirectMessage)) return []
|
||||
|
||||
const channel = (await control.findAll(chunter.class.DirectMessage, { _id: message.attachedTo })).shift()
|
||||
if (channel === undefined || channel.members.length !== 2 || !channel.private) return []
|
||||
|
||||
const res: Tx[] = []
|
||||
|
||||
if (tx.createdBy == null) return []
|
||||
const docUpdates = await control.findAll(notification.class.DocUpdates, { attachedTo: channel._id })
|
||||
|
||||
const dm = TxProcessor.createDoc2Doc(ptx)
|
||||
// binding notification to the DM creation tx to properly display it in inbox
|
||||
const dmCreationTx = (
|
||||
await control.findAll(core.class.TxCreateDoc, { objectClass: channel._class, objectId: channel._id })
|
||||
).shift()
|
||||
if (dmCreationTx === undefined) return []
|
||||
|
||||
if (dm.members.length > 2) return []
|
||||
|
||||
let dmWithPerson: Ref<Account> | undefined
|
||||
for (const person of dm.members) {
|
||||
if (person !== tx.createdBy) {
|
||||
dmWithPerson = person
|
||||
break
|
||||
const sender = message.createdBy
|
||||
const docUpdate = docUpdates.find((du) => du.user === sender)
|
||||
if (docUpdate === undefined) {
|
||||
let anotherPerson: Ref<Account> | undefined
|
||||
for (const person of channel.members) {
|
||||
if (person !== sender) {
|
||||
anotherPerson = person
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (anotherPerson == null) return []
|
||||
|
||||
pushNotification(control, res, sender, channel, dmCreationTx, docUpdates, anotherPerson)
|
||||
} else if (docUpdate.hidden) {
|
||||
res.push(control.txFactory.createTxUpdateDoc(docUpdate._class, docUpdate.space, docUpdate._id, { hidden: false }))
|
||||
}
|
||||
|
||||
if (dmWithPerson == null) return []
|
||||
|
||||
pushNotification(control, res, tx.createdBy, dm, ptx, [], dmWithPerson)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
@ -309,7 +322,7 @@ export async function IsChannelMessage (
|
||||
export default async () => ({
|
||||
trigger: {
|
||||
ChunterTrigger,
|
||||
OnDmCreate
|
||||
OnMessageSent
|
||||
},
|
||||
function: {
|
||||
CommentRemove,
|
||||
|
@ -30,7 +30,7 @@ export const serverChunterId = 'server-chunter' as Plugin
|
||||
export default plugin(serverChunterId, {
|
||||
trigger: {
|
||||
ChunterTrigger: '' as Resource<TriggerFunc>,
|
||||
OnDmCreate: '' as Resource<TriggerFunc>
|
||||
OnMessageSent: '' as Resource<TriggerFunc>
|
||||
},
|
||||
function: {
|
||||
CommentRemove: '' as Resource<
|
||||
|
Loading…
Reference in New Issue
Block a user