EZQMS-306: add extensions for chunter message version (#3882)

* EZQMS-306: add extensions for chunter message version

Signed-off-by: Anna No <anna.no@xored.com>

* EZQMS-306: add extensions for chunter message version

Signed-off-by: Anna No <anna.no@xored.com>

* EZQMS-306: add extensions for chunter message version

Signed-off-by: Anna No <anna.no@xored.com>

* EZQMS-306: add extensions for chunter message version

Signed-off-by: Anna No <anna.no@xored.com>

---------

Signed-off-by: Anna No <anna.no@xored.com>
This commit is contained in:
Anna No 2023-10-26 00:00:08 +07:00 committed by GitHub
parent f64901cfd5
commit 73e927876c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 56 additions and 35 deletions

View File

@ -19,6 +19,7 @@ import {
Channel, Channel,
chunterId, chunterId,
ChunterMessage, ChunterMessage,
ChunterMessageExtension,
ChunterSpace, ChunterSpace,
Comment, Comment,
DirectMessage, DirectMessage,
@ -101,6 +102,9 @@ export class TChunterMessage extends TAttachedDoc implements ChunterMessage {
reactions?: number reactions?: number
} }
@Mixin(chunter.mixin.ChunterMessageExtension, chunter.class.ChunterMessage)
export class TChunterMessageExtension extends TChunterMessage implements ChunterMessageExtension {}
@Model(chunter.class.ThreadMessage, chunter.class.ChunterMessage) @Model(chunter.class.ThreadMessage, chunter.class.ChunterMessage)
@UX(chunter.string.ThreadMessage, undefined, 'TMSG') @UX(chunter.string.ThreadMessage, undefined, 'TMSG')
export class TThreadMessage extends TChunterMessage implements ThreadMessage { export class TThreadMessage extends TChunterMessage implements ThreadMessage {
@ -173,6 +177,7 @@ export function createModel (builder: Builder, options = { addApplication: true
TMessage, TMessage,
TThreadMessage, TThreadMessage,
TChunterMessage, TChunterMessage,
TChunterMessageExtension,
TComment, TComment,
TBacklink, TBacklink,
TDirectMessage, TDirectMessage,

View File

@ -15,16 +15,15 @@
<script lang="ts"> <script lang="ts">
import { Attachment } from '@hcengineering/attachment' import { Attachment } from '@hcengineering/attachment'
import { AttachmentList, AttachmentRefInput } from '@hcengineering/attachment-resources' import { AttachmentList, AttachmentRefInput } from '@hcengineering/attachment-resources'
import type { ChunterMessage, Message, Reaction } from '@hcengineering/chunter' import type { ChunterMessage, ChunterMessageExtension, Message, Reaction } from '@hcengineering/chunter'
import { PersonAccount } from '@hcengineering/contact' import { PersonAccount } from '@hcengineering/contact'
import { Avatar, personByIdStore, EmployeePresenter } from '@hcengineering/contact-resources' import { Avatar, personByIdStore, EmployeePresenter } from '@hcengineering/contact-resources'
import { getCurrentAccount, Ref, WithLookup } from '@hcengineering/core' import { getCurrentAccount, Mixin, Ref, WithLookup } from '@hcengineering/core'
import { getResource } from '@hcengineering/platform' import { getResource } from '@hcengineering/platform'
import { getClient, MessageViewer } from '@hcengineering/presentation' import { getClient, MessageViewer } from '@hcengineering/presentation'
import { EmojiPopup } from '@hcengineering/ui' import ui, { ActionIcon, Button, EmojiPopup, IconMoreV, Label, showPopup, tooltip } from '@hcengineering/ui'
import ui, { ActionIcon, Button, IconMoreH, Label, showPopup, tooltip } from '@hcengineering/ui'
import { Action } from '@hcengineering/view' import { Action } from '@hcengineering/view'
import { LinkPresenter, Menu } from '@hcengineering/view-resources' import { LinkPresenter, Menu, ObjectPresenter } from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import { AddMessageToSaved, DeleteMessageFromSaved, UnpinMessage } from '../index' import { AddMessageToSaved, DeleteMessageFromSaved, UnpinMessage } from '../index'
import chunter from '../plugin' import chunter from '../plugin'
@ -52,14 +51,14 @@
$: attachments = (message.$lookup?.attachments ?? []) as Attachment[] $: attachments = (message.$lookup?.attachments ?? []) as Attachment[]
const client = getClient() const client = getClient()
const hieararchy = client.getHierarchy() const hierarchy = client.getHierarchy()
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const me = getCurrentAccount()._id const me = getCurrentAccount()._id
$: reactions = message.$lookup?.reactions as Reaction[] | undefined $: reactions = message.$lookup?.reactions as Reaction[] | undefined
$: subscribed = ( $: subscribed = (
hieararchy.as(message, notification.mixin.Collaborators) as any as Collaborators hierarchy.as(message, notification.mixin.Collaborators) as any as Collaborators
).collaborators?.includes(me) ).collaborators?.includes(me)
$: subscribeAction = subscribed $: subscribeAction = subscribed
? ({ ? ({
@ -83,6 +82,16 @@
$: isEditing = false $: isEditing = false
let extensions: Ref<Mixin<ChunterMessageExtension>>[] = []
$: if (message) {
extensions = []
for (const extension of hierarchy.getDescendants(chunter.mixin.ChunterMessageExtension)) {
if (hierarchy.hasMixin(message, extension)) {
extensions.push(extension as Ref<Mixin<ChunterMessageExtension>>)
}
}
}
const editAction = { const editAction = {
label: chunter.string.EditMessage, label: chunter.string.EditMessage,
action: () => (isEditing = true) action: () => (isEditing = true)
@ -255,21 +264,14 @@
</div> </div>
{/if} {/if}
</div> </div>
{#if !readOnly}
<div class="buttons clear-mins" class:menuShowed> <div class="buttons clear-mins flex flex-gap-1 items-center" class:menuShowed>
<div class="tool"> {#each extensions as mixinClass}
<ActionIcon <ObjectPresenter _class={mixinClass} value={hierarchy.as(message, mixinClass)} exact />
icon={IconMoreH} {/each}
size={'medium'} {#if !readOnly}
action={(e) => { <ActionIcon icon={Emoji} size={'medium'} action={openEmojiPalette} />
showMenu(e) <div class="book">
}}
/>
</div>
{#if !thread}
<div class="tool"><ActionIcon icon={Thread} size={'medium'} action={openThread} /></div>
{/if}
<div class="tool book">
<ActionIcon <ActionIcon
icon={Bookmark} icon={Bookmark}
size={'medium'} size={'medium'}
@ -277,10 +279,19 @@
label={isSaved ? chunter.string.RemoveFromSaved : chunter.string.AddToSaved} label={isSaved ? chunter.string.RemoveFromSaved : chunter.string.AddToSaved}
/> />
</div> </div>
<!-- <div class="tool"><ActionIcon icon={Share} size={'medium'}/></div> --> {#if !thread}
<div class="tool"><ActionIcon icon={Emoji} size={'medium'} action={openEmojiPalette} /></div> <ActionIcon icon={Thread} size={'medium'} action={openThread} />
</div> {/if}
{/if}
<ActionIcon
icon={IconMoreV}
size={'medium'}
action={(e) => {
showMenu(e)
}}
/>
{/if}
</div>
</div> </div>
<style lang="scss"> <style lang="scss">
@ -343,13 +354,8 @@
visibility: hidden; visibility: hidden;
top: 0.5rem; top: 0.5rem;
right: 1rem; right: 1rem;
display: flex;
flex-direction: row-reverse;
user-select: none; user-select: none;
color: var(--theme-halfcontent-color);
.tool + .tool {
margin-right: 0.5rem;
}
&.menuShowed { &.menuShowed {
visibility: visible; visibility: visible;

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from 'svelte'
import attachment, { Attachment } from '@hcengineering/attachment' import attachment, { Attachment } from '@hcengineering/attachment'
import { AttachmentRefInput } from '@hcengineering/attachment-resources' import { AttachmentRefInput } from '@hcengineering/attachment-resources'
import chunter, { type ChunterSpace, type Message, type ThreadMessage } from '@hcengineering/chunter' import chunter, { type ChunterSpace, type Message, type ThreadMessage } from '@hcengineering/chunter'
@ -42,6 +43,7 @@
let commentId = generateId() as Ref<ThreadMessage> let commentId = generateId() as Ref<ThreadMessage>
const notificationClient = NotificationClientImpl.getClient() const notificationClient = NotificationClientImpl.getClient()
const dispatch = createEventDispatcher()
const lookup = { const lookup = {
_id: { attachments: attachment.class.Attachment }, _id: { attachments: attachment.class.Attachment },
@ -142,6 +144,7 @@
}, },
commentId commentId
) )
dispatch('added', commentId)
commentId = generateId() commentId = generateId()
loading = false loading = false

View File

@ -68,7 +68,7 @@ import { getDmName, getLink, getTitle, resolveLocation } from './utils'
export { default as Header } from './components/Header.svelte' export { default as Header } from './components/Header.svelte'
export { classIcon } from './utils' export { classIcon } from './utils'
export { CommentPopup, CommentsPresenter } export { CommentPopup, CommentsPresenter, Thread }
async function MarkUnread (object: Message): Promise<void> { async function MarkUnread (object: Message): Promise<void> {
const client = NotificationClientImpl.getClient() const client = NotificationClientImpl.getClient()

View File

@ -62,6 +62,11 @@ export interface ChunterMessage extends AttachedDoc {
reactions?: number reactions?: number
} }
/**
* @public
*/
export interface ChunterMessageExtension extends ChunterMessage {}
/** /**
* @public * @public
*/ */
@ -167,7 +172,8 @@ export default plugin(chunterId, {
Reaction: '' as Ref<Class<Reaction>> Reaction: '' as Ref<Class<Reaction>>
}, },
mixin: { mixin: {
DirectMessageInput: '' as Ref<Mixin<DirectMessageInput>> DirectMessageInput: '' as Ref<Mixin<DirectMessageInput>>,
ChunterMessageExtension: '' as Ref<Mixin<ChunterMessageExtension>>
}, },
space: { space: {
Backlinks: '' as Ref<Space> Backlinks: '' as Ref<Space>

View File

@ -29,6 +29,7 @@
export let disabled: boolean = false export let disabled: boolean = false
export let shouldShowName: boolean = true export let shouldShowName: boolean = true
export let shrink: number = 0 export let shrink: number = 0
export let exact = false
const client = getClient() const client = getClient()
let presenter: AttributeModel | undefined let presenter: AttributeModel | undefined
@ -56,7 +57,7 @@
} }
$: if (doc !== undefined) { $: if (doc !== undefined) {
getObjectPresenter(client, doc._class, { key: '' }) getObjectPresenter(client, exact && _class ? _class : doc._class, { key: '' })
.then((p) => { .then((p) => {
presenter = p presenter = p
}) })