EZQMS-278: update comments popups (#3849)

Signed-off-by: Anna No <anna.no@xored.com>
This commit is contained in:
Anna No 2023-10-17 19:14:05 +07:00 committed by GitHub
parent 0d1ba6a28a
commit d39f81600a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 65 additions and 60 deletions

View File

@ -9,6 +9,7 @@ export const InlinePopupExtension: Extension<BubbleMenuOptions> = BubbleMenu.ext
element: null,
tippyOptions: {
maxWidth: '38rem',
zIndex: 500,
appendTo: () => document.body
}
}

View File

@ -682,6 +682,7 @@ input.search {
.min-w-0 { min-width: 0; }
.min-w-2 { min-width: .5rem; }
.min-w-4 { min-width: 1rem; }
.min-w-6 { min-width: 1.5rem; }
.min-w-8 { min-width: 2rem; }
.min-w-9 { min-width: 2.25rem; }
.min-w-12 { min-width: 3rem; }
@ -718,6 +719,7 @@ input.search {
.max-h-30 { max-height: 7.5rem; }
.max-h-50 { max-height: 12.5rem; }
.max-h-60 { max-height: 15rem; }
.max-h-80 { max-height: 20rem; }
.max-h-125 { max-height: 31.25rem; }
.max-h-30vh { max-height: 30vh; }
.clear-mins {

View File

@ -78,6 +78,7 @@
"YouHaveJoinedTheConversation": "You have joined the conversation",
"NoMessages": "There are no messages yet",
"DirectNotificationTitle": "{senderName}",
"DirectNotificationBody": "{message}"
"DirectNotificationBody": "{message}",
"AddCommentPlaceholder": "Add comment..."
}
}

View File

@ -78,6 +78,7 @@
"YouHaveJoinedTheConversation": "Вы присоединились к диалогу",
"NoMessages": "Сообщений пока нет",
"DirectNotificationTitle": "{senderName}",
"DirectNotificationBody": "{message}"
"DirectNotificationBody": "{message}",
"AddCommentPlaceholder": "Добавить комментарий..."
}
}

View File

@ -104,6 +104,6 @@
<style lang="scss">
.reference {
margin: 1.25rem 2.5rem;
margin: 1.25rem 1rem;
}
</style>

View File

@ -204,15 +204,15 @@
</script>
<div class="container clear-mins" class:highlighted={isHighlighted} id={message._id}>
<div class="avatar">
<Avatar size={'medium'} avatar={employee?.avatar} name={employee?.name} />
<div class="min-w-6">
<Avatar size="x-small" avatar={employee?.avatar} name={employee?.name} />
</div>
<div class="message clear-mins">
<div class="message ml-2 w-full clear-mins">
<div class="header clear-mins">
{#if employee}
<EmployeePresenter value={employee} shouldShowAvatar={false} />
{/if}
<span>{getTime(message.createdOn ?? 0)}</span>
<span class="text-sm">{getTime(message.createdOn ?? 0)}</span>
{#if message.editedOn}
<span use:tooltip={{ label: ui.string.TimeTooltip, props: { value: getTime(message.editedOn) } }}>
<Label label={chunter.string.Edited} />
@ -290,36 +290,30 @@
position: relative;
display: flex;
flex-shrink: 0;
padding: 0.5rem 2rem;
padding: 0.5rem 1rem;
&.highlighted {
animation: highlight 2000ms ease-in-out;
}
.avatar {
min-width: 2.25rem;
}
.message {
display: flex;
flex-direction: column;
width: 100%;
margin-left: 1rem;
.header {
display: flex;
align-items: baseline;
font-weight: 500;
font-size: 1rem;
font-size: 0.875rem;
line-height: 150%;
color: var(--theme-caption-color);
margin-bottom: 0.25rem;
span {
margin-left: 0.5rem;
margin-left: 0.25rem;
font-weight: 400;
line-height: 1.125rem;
line-height: 1.25rem;
opacity: 0.4;
}
}

View File

@ -15,14 +15,14 @@
<script lang="ts">
import attachment, { Attachment } from '@hcengineering/attachment'
import { AttachmentRefInput } from '@hcengineering/attachment-resources'
import { type ChunterSpace, type Message, type ThreadMessage } from '@hcengineering/chunter'
import chunter, { type ChunterSpace, type Message, type ThreadMessage } from '@hcengineering/chunter'
import contact, { Person, PersonAccount, getName } from '@hcengineering/contact'
import { personByIdStore } from '@hcengineering/contact-resources'
import { Avatar, personByIdStore } from '@hcengineering/contact-resources'
import core, { FindOptions, IdMap, Ref, SortingOrder, generateId, getCurrentAccount } from '@hcengineering/core'
import { NotificationClientImpl } from '@hcengineering/notification-resources'
import { createQuery, getClient } from '@hcengineering/presentation'
import { Label } from '@hcengineering/ui'
import chunter from '../plugin'
import plugin from '../plugin'
import ChannelPresenter from './ChannelPresenter.svelte'
import DmPresenter from './DmPresenter.svelte'
import MsgView from './Message.svelte'
@ -30,9 +30,12 @@
const client = getClient()
const query = createQuery()
const messageQuery = createQuery()
const currentPerson = (getCurrentAccount() as PersonAccount)?.person
const currentEmployee = currentPerson !== undefined ? $personByIdStore.get(currentPerson) : undefined
export let savedAttachmentsIds: Ref<Attachment>[]
export let _id: Ref<Message>
export let showHeader = true
let parent: Message | undefined
let commentId = generateId() as Ref<ThreadMessage>
@ -51,7 +54,7 @@
function updateQuery (id: Ref<Message>) {
messageQuery.query(
chunter.class.Message,
plugin.class.Message,
{
_id: id
},
@ -77,7 +80,7 @@
options.limit = 4
}
query.query(
chunter.class.ThreadMessage,
plugin.class.ThreadMessage,
{
attachedTo: id
},
@ -122,11 +125,11 @@
const { message, attachments } = event.detail
const me = getCurrentAccount()._id
await client.createDoc(
chunter.class.ThreadMessage,
plugin.class.ThreadMessage,
parent.space,
{
attachedTo: _id,
attachedToClass: chunter.class.Message,
attachedToClass: plugin.class.Message,
collection: 'repliesCount',
content: message,
createBy: me,
@ -141,27 +144,29 @@
let comments: ThreadMessage[] = []
async function getChannel (_id: Ref<ChunterSpace>): Promise<ChunterSpace | undefined> {
return await client.findOne(chunter.class.ChunterSpace, { _id })
return await client.findOne(plugin.class.ChunterSpace, { _id })
}
let loading = false
</script>
<div class="flex-col ml-8 mt-4 flex-no-shrink">
{#if parent}
<div class="flex-col ml-4 mt-4 flex-no-shrink">
{#if showHeader && parent}
{#await getChannel(parent.space) then channel}
{#if channel?._class === chunter.class.Channel}
{#if channel?._class === plugin.class.Channel}
<ChannelPresenter value={channel} />
{:else if channel}
<DmPresenter value={channel} />
{/if}
{/await}
{#await getParticipants(comments, parent, $personByIdStore) then participants}
{participants.join(', ')}
<Label label={chunter.string.AndYou} params={{ participants: participants.length }} />
{/await}
<div class="text-sm">
{#await getParticipants(comments, parent, $personByIdStore) then participants}
{participants.join(', ')}
<Label label={plugin.string.AndYou} params={{ participants: participants.length }} />
{/await}
</div>
{/if}
</div>
<div class="flex-col content flex-no-shrink">
<div class="flex-col content mt-2 flex-no-shrink">
{#if parent}
<MsgView message={parent} thread {savedAttachmentsIds} />
{#if total > comments.length}
@ -172,33 +177,33 @@
showAll = true
}}
>
<Label label={chunter.string.ShowMoreReplies} params={{ count: total - comments.length }} />
<Label label={plugin.string.ShowMoreReplies} params={{ count: total - comments.length }} />
</div>
{/if}
{#each comments as comment (comment._id)}
<MsgView message={comment} thread {savedAttachmentsIds} />
{/each}
<div class="mr-4 ml-4 pb-4 mt-2 clear-mins">
<AttachmentRefInput
space={parent.space}
_class={chunter.class.ThreadMessage}
objectId={commentId}
on:message={onMessage}
bind:loading
/>
<div class="flex mr-4 ml-4 pb-4 mt-2 clear-mins">
<div class="min-w-6">
<Avatar size="x-small" avatar={currentEmployee?.avatar} name={currentEmployee?.name} />
</div>
<div class="ml-2 w-full">
<AttachmentRefInput
space={parent.space}
_class={plugin.class.ThreadMessage}
objectId={commentId}
placeholder={chunter.string.AddCommentPlaceholder}
on:message={onMessage}
bind:loading
/>
</div>
</div>
{/if}
</div>
<div class="min-h-4 max-h-4 h-4 flex-no-shrink" />
<style lang="scss">
.content {
overflow: hidden;
margin: 1rem 1rem 0;
padding-top: 0.5rem;
background-color: var(--theme-list-row-color);
border: 1px solid var(--theme-divider-color);
border-radius: 0.75rem;
}
.label:hover {

View File

@ -24,7 +24,6 @@
import { afterUpdate, beforeUpdate, createEventDispatcher } from 'svelte'
import chunter from '../plugin'
import { isMessageHighlighted, messageIdForScroll, scrollAndHighLight, shouldScrollToMessage } from '../utils'
import ChannelSeparator from './ChannelSeparator.svelte'
import MsgView from './Message.svelte'
const client = getClient()
@ -193,13 +192,7 @@
<div class="flex-col vScroll content" bind:this={div}>
{#if message}
<MsgView {message} thread isSaved={savedMessagesIds.includes(message._id)} {savedAttachmentsIds} />
{#if comments.length}
<ChannelSeparator title={chunter.string.RepliesCount} line params={{ replies: comments.length }} />
{/if}
{#each comments as comment, i (comment._id)}
{#if newMessagesPos === i}
<ChannelSeparator title={chunter.string.New} line reverse isNew />
{/if}
{#each comments as comment}
<MsgView
isHighlighted={$messageIdForScroll === comment._id && $isMessageHighlighted}
message={comment}
@ -216,6 +209,7 @@
space={currentSpace}
_class={chunter.class.ThreadMessage}
objectId={commentId}
placeholder={chunter.string.AddCommentPlaceholder}
on:message={onMessage}
bind:loading
/>
@ -226,7 +220,7 @@
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 1.75rem 0 2.5rem;
padding: 0 1.75rem 0 1rem;
height: 4rem;
min-height: 4rem;
@ -247,6 +241,6 @@
}
}
.ref-input {
margin: 1.25rem 2.5rem;
margin: 1.25rem 1rem;
}
</style>

View File

@ -54,9 +54,12 @@
<span class="ac-header__title"><Label label={chunter.string.Threads} /></span>
</div>
</div>
<Scroller>
{#each threads as thread, i (thread)}
<Thread _id={thread} {savedAttachmentsIds} />
<div class="ml-4 mr-4">
<Thread _id={thread} {savedAttachmentsIds} />
</div>
{#if i < threads.length - 1}
<div class="antiDivider" />
{/if}

View File

@ -54,6 +54,7 @@ import SavedMessages from './components/SavedMessages.svelte'
import ThreadParentPresenter from './components/ThreadParentPresenter.svelte'
import ThreadView from './components/ThreadView.svelte'
import ThreadViewPanel from './components/ThreadViewPanel.svelte'
import Thread from './components/Thread.svelte'
import Threads from './components/Threads.svelte'
import TxBacklinkCreate from './components/activity/TxBacklinkCreate.svelte'
import TxBacklinkReference from './components/activity/TxBacklinkReference.svelte'
@ -291,6 +292,7 @@ export default async (): Promise<Resources> => ({
DmPresenter,
DirectMessageInput,
EditChannel,
Thread,
Threads,
ThreadView,
SavedMessages,

View File

@ -151,6 +151,7 @@ export default plugin(chunterId, {
DmHeader: '' as AnyComponent,
ChannelView: '' as AnyComponent,
ThreadView: '' as AnyComponent,
Thread: '' as AnyComponent,
CommentsPresenter: '' as AnyComponent
},
class: {
@ -184,7 +185,8 @@ export default plugin(chunterId, {
UnarchiveConfirm: '' as IntlString,
ConvertToPrivate: '' as IntlString,
DirectNotificationTitle: '' as IntlString,
DirectNotificationBody: '' as IntlString
DirectNotificationBody: '' as IntlString,
AddCommentPlaceholder: '' as IntlString
},
resolver: {
Location: '' as Resource<(loc: Location) => Promise<ResolvedLocation | undefined>>