UBERF-4360: rewrite chat (#4265)

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
Kristina
2024-01-11 21:46:11 +07:00
committed by GitHub
parent 06f6f6a222
commit 7f6f5e28a6
183 changed files with 6360 additions and 5051 deletions
@@ -36,7 +36,7 @@
export let isSelected: boolean = false
export let shouldScroll: boolean = false
export let embedded: boolean = false
export let hasActionsMenu: boolean = true
export let withActions: boolean = true
export let onClick: (() => void) | undefined = undefined
$: personAccount = $personAccountByIdStore.get((value.createdBy ?? value.modifiedBy) as Ref<PersonAccount>)
@@ -65,7 +65,7 @@
{isSelected}
{shouldScroll}
{embedded}
{hasActionsMenu}
{withActions}
viewlet={undefined}
{onClick}
>
@@ -16,7 +16,7 @@
import { DisplayActivityMessage } from '@hcengineering/activity'
import view from '@hcengineering/view'
import { getClient } from '@hcengineering/presentation'
import { Component } from '@hcengineering/ui'
import { Action, Component } from '@hcengineering/ui'
import { Class, Doc, Ref } from '@hcengineering/core'
export let value: DisplayActivityMessage
@@ -25,8 +25,14 @@
export let isSelected: boolean = false
export let shouldScroll: boolean = false
export let embedded: boolean = false
export let hasActionsMenu: boolean = true
export let withActions: boolean = true
export let showEmbedded = false
export let hideReplies = false
export let skipLabel = false
export let actions: Action[] = []
export let onClick: (() => void) | undefined = undefined
export let onReply: (() => void) | undefined = undefined
const client = getClient()
const hierarchy = client.getHierarchy()
@@ -40,12 +46,17 @@
props={{
value,
showNotify,
skipLabel,
isHighlighted,
isSelected,
shouldScroll,
embedded,
hasActionsMenu,
onClick
withActions,
showEmbedded,
hideReplies,
actions,
onClick,
onReply
}}
/>
{/if}
@@ -30,6 +30,8 @@
import ActivityMessageExtensionComponent from './ActivityMessageExtension.svelte'
import ActivityMessagePresenter from './ActivityMessagePresenter.svelte'
import PinMessageAction from './PinMessageAction.svelte'
import Replies from '../Replies.svelte'
import SaveMessageAction from '../SaveMessageAction.svelte'
export let message: DisplayActivityMessage
export let parentMessage: DisplayActivityMessage | undefined
@@ -43,8 +45,11 @@
export let isSelected: boolean = false
export let shouldScroll: boolean = false
export let embedded: boolean = false
export let hasActionsMenu: boolean = true
export let withActions: boolean = true
export let showEmbedded = false
export let hideReplies = false
export let onClick: (() => void) | undefined = undefined
export let onReply: (() => void) | undefined = undefined
const client = getClient()
let allActionIds: string[] = []
@@ -53,9 +58,10 @@
let extensions: ActivityMessageExtension[] = []
let isActionMenuOpened = false
$: void getActions(client, message, activity.class.ActivityMessage).then((res) => {
allActionIds = res.map(({ _id }) => _id)
})
$: withActions &&
getActions(client, message, activity.class.ActivityMessage).then((res) => {
allActionIds = res.map(({ _id }) => _id)
})
function scrollToMessage (): void {
if (element != null && shouldScroll) {
@@ -101,7 +107,7 @@
$: isHidden = !!viewlet?.onlyWithParent && parentMessage === undefined
$: withActionMenu =
!embedded && hasActionsMenu && (actions.length > 0 || allActionIds.some((id) => !excludedActions.includes(id)))
withActions && !embedded && (actions.length > 0 || allActionIds.some((id) => !excludedActions.includes(id)))
</script>
{#if !isHidden}
@@ -151,32 +157,38 @@
<slot name="content" />
{#if !hideReplies && message.replies && message.replies > 0}
<div class="mt-2" />
<Replies {message} {onReply} />
{/if}
<ActivityMessageExtensionComponent kind="footer" {extensions} props={{ object: message }} />
<ReactionsPresenter object={message} />
{#if parentMessage}
{#if parentMessage && showEmbedded}
<div class="mt-2" />
<ActivityMessagePresenter value={parentMessage} embedded />
<ActivityMessagePresenter value={parentMessage} embedded hideReplies withActions={false} />
{/if}
</div>
<div
class="actions clear-mins flex flex-gap-2 items-center"
class:menuShowed={isActionMenuOpened || message.isPinned}
class:opened={isActionMenuOpened || message.isPinned}
>
<AddReactionAction object={message} />
<PinMessageAction object={message} />
{#if withActions}
<AddReactionAction object={message} />
<PinMessageAction object={message} />
<SaveMessageAction object={message} />
<ActivityMessageExtensionComponent
kind="action"
{extensions}
props={{ object: message }}
on:close={handleActionMenuClosed}
on:open={handleActionMenuOpened}
/>
{#if withActionMenu}
<ActionIcon icon={IconMoreH} size="small" action={showMenu} />
<ActivityMessageExtensionComponent
kind="action"
{extensions}
props={{ object: message }}
on:close={handleActionMenuClosed}
on:open={handleActionMenuOpened}
/>
{#if withActionMenu}
<ActionIcon icon={IconMoreH} size="small" action={showMenu} />
{/if}
{/if}
</div>
</div>
@@ -195,8 +207,8 @@
display: flex;
flex-shrink: 0;
padding: 0.75rem 0.75rem 0.75rem 1.25rem;
border-radius: 8px;
gap: 1rem;
overflow: hidden;
border: 1px solid transparent;
border-radius: 0.25rem;
@@ -228,7 +240,7 @@
right: 0.75rem;
color: var(--theme-halfcontent-color);
&.menuShowed {
&.opened {
visibility: visible;
}
}
@@ -0,0 +1,51 @@
<!--
// Copyright © 2023 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.
-->
<script lang="ts">
import type { IntlString } from '@hcengineering/platform'
import { Label } from '@hcengineering/ui'
export let title: IntlString
export let line: boolean = false
export let params: any = undefined
export let reverse: boolean = false
export let isNew: boolean = false
export let element: HTMLDivElement | undefined = undefined
</script>
<div
class="w-full text-sm flex-center whitespace-nowrap"
class:flex-reverse={reverse}
class:new={isNew}
bind:this={element}
>
<div class:ml-8={!reverse} class:mr-4={reverse}><Label label={title} {params} /></div>
<div class:ml-4={!reverse} class:mr-4={reverse} class:line />
</div>
<style lang="scss">
.line {
position: relative;
width: 100%;
height: 1px;
background-color: var(--divider-color);
}
.new {
.line {
background-color: var(--highlight-red);
}
color: var(--highlight-red);
}
</style>