mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-28 05:56:02 +03:00
Fix thread messages pin (#6129)
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
parent
27c626857a
commit
3b9318e34a
@ -92,7 +92,7 @@
|
||||
skipLabels={!isDocChannel}
|
||||
selectedFilters={filters}
|
||||
startFromBottom
|
||||
{selectedMessageId}
|
||||
bind:selectedMessageId
|
||||
{collection}
|
||||
provider={dataProvider}
|
||||
{isAsideOpened}
|
||||
|
@ -78,7 +78,7 @@
|
||||
on:aside-toggled
|
||||
on:close
|
||||
>
|
||||
<PinnedMessages {_id} {_class} />
|
||||
<PinnedMessages {_id} {_class} on:select />
|
||||
</Header>
|
||||
</div>
|
||||
|
||||
|
@ -55,7 +55,7 @@
|
||||
export let scrollElement: HTMLDivElement | undefined = undefined
|
||||
export let startFromBottom = false
|
||||
export let selectedFilters: Ref<ActivityMessagesFilter>[] = []
|
||||
export let withDates: boolean = true
|
||||
export let embedded = false
|
||||
export let collection: string | undefined = undefined
|
||||
export let showEmbedded = false
|
||||
export let skipLabels = false
|
||||
@ -355,7 +355,7 @@
|
||||
}
|
||||
|
||||
function updateSelectedDate (): void {
|
||||
if (!withDates) {
|
||||
if (embedded) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -468,13 +468,13 @@
|
||||
if (isLoading || !isScrollInitialized || isInitialScrolling) {
|
||||
return
|
||||
}
|
||||
const msg = messages.find(({ _id }) => _id === selectedMessageId)
|
||||
const msg = $metadataStore.find(({ _id }) => _id === selectedMessageId)
|
||||
if (msg !== undefined) {
|
||||
const isReload = provider.jumpToMessage(msg)
|
||||
if (isReload) {
|
||||
reinitializeScroll()
|
||||
}
|
||||
} else {
|
||||
} else if (selectedMessageId === undefined) {
|
||||
provider.jumpToEnd()
|
||||
reinitializeScroll()
|
||||
}
|
||||
@ -677,7 +677,7 @@
|
||||
{#if startFromBottom}
|
||||
<div class="grower" />
|
||||
{/if}
|
||||
{#if withDates && displayMessages.length > 0 && selectedDate}
|
||||
{#if !embedded && displayMessages.length > 0 && selectedDate}
|
||||
<div class="selectedDate">
|
||||
<JumpToDateSelector {selectedDate} fixed on:jumpToDate={jumpToDate} />
|
||||
</div>
|
||||
@ -702,7 +702,7 @@
|
||||
{/if}
|
||||
<slot name="header" />
|
||||
|
||||
{#if displayMessages.length === 0 && !hierarchy.isDerived(objectClass, activity.class.ActivityMessage)}
|
||||
{#if displayMessages.length === 0 && !embedded}
|
||||
<BlankView
|
||||
icon={chunter.icon.Thread}
|
||||
header={chunter.string.NoMessagesInChannel}
|
||||
@ -717,7 +717,7 @@
|
||||
<ActivityMessagesSeparator bind:element={separatorElement} label={activity.string.New} />
|
||||
{/if}
|
||||
|
||||
{#if withDates && message.createdOn && $datesStore.includes(message.createdOn)}
|
||||
{#if !embedded && message.createdOn && $datesStore.includes(message.createdOn)}
|
||||
<JumpToDateSelector selectedDate={message.createdOn} on:jumpToDate={jumpToDate} />
|
||||
{/if}
|
||||
|
||||
@ -741,7 +741,7 @@
|
||||
{/if}
|
||||
</Scroller>
|
||||
|
||||
{#if showScrollDownButton}
|
||||
{#if !embedded && showScrollDownButton}
|
||||
<div class="down-button absolute">
|
||||
<ModernButton
|
||||
label={chunter.string.LatestMessages}
|
||||
|
@ -16,23 +16,27 @@
|
||||
import core, { Doc, getCurrentAccount, Ref, Space } from '@hcengineering/core'
|
||||
import {
|
||||
defineSeparators,
|
||||
getCurrentLocation,
|
||||
Label,
|
||||
location as locationStore,
|
||||
ModernButton,
|
||||
navigate,
|
||||
panelSeparators,
|
||||
Separator
|
||||
} from '@hcengineering/ui'
|
||||
import { DocNotifyContext } from '@hcengineering/notification'
|
||||
import { ActivityMessagesFilter } from '@hcengineering/activity'
|
||||
import { ActivityMessage, ActivityMessagesFilter } from '@hcengineering/activity'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { Channel } from '@hcengineering/chunter'
|
||||
import view from '@hcengineering/view'
|
||||
import { messageInFocus } from '@hcengineering/activity-resources'
|
||||
|
||||
import ChannelComponent from './Channel.svelte'
|
||||
import ChannelHeader from './ChannelHeader.svelte'
|
||||
import DocAside from './chat/DocAside.svelte'
|
||||
import chunter from '../plugin'
|
||||
import ChannelAside from './chat/ChannelAside.svelte'
|
||||
import { isThreadMessage } from '../utils'
|
||||
|
||||
export let object: Doc
|
||||
export let context: DocNotifyContext | undefined
|
||||
@ -76,6 +80,18 @@
|
||||
}
|
||||
|
||||
defineSeparators('aside', panelSeparators)
|
||||
|
||||
async function handleMessageSelect (event: CustomEvent<ActivityMessage>): Promise<void> {
|
||||
const message = event.detail
|
||||
|
||||
if (isThreadMessage(message)) {
|
||||
const location = getCurrentLocation()
|
||||
location.path[4] = message.attachedTo
|
||||
navigate(location)
|
||||
}
|
||||
|
||||
messageInFocus.set(message._id)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="popupPanel panel" class:embedded>
|
||||
@ -89,6 +105,7 @@
|
||||
canOpen={isDocChat}
|
||||
{isAsideShown}
|
||||
on:close
|
||||
on:select={handleMessageSelect}
|
||||
on:aside-toggled={() => {
|
||||
isAsideShown = !isAsideShown
|
||||
}}
|
||||
|
@ -19,32 +19,53 @@
|
||||
import activity, { ActivityMessage } from '@hcengineering/activity'
|
||||
import { Class, Doc, Ref } from '@hcengineering/core'
|
||||
import view from '@hcengineering/view'
|
||||
import { ThreadMessage } from '@hcengineering/chunter'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
import chunter from '../plugin'
|
||||
|
||||
export let _class: Ref<Class<Doc>>
|
||||
export let _id: Ref<Doc>
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const pinnedQuery = createQuery()
|
||||
const pinnedThreadsQuery = createQuery()
|
||||
|
||||
let pinnedMessagesCount = 0
|
||||
let pinnedThreadsCount = 0
|
||||
|
||||
$: pinnedQuery.query(
|
||||
activity.class.ActivityMessage,
|
||||
{ attachedTo: _id, isPinned: true },
|
||||
(res: ActivityMessage[]) => {
|
||||
pinnedMessagesCount = res.length
|
||||
}
|
||||
},
|
||||
{ projection: { _id: 1, attachedTo: 1, isPinned: 1 } }
|
||||
)
|
||||
|
||||
$: pinnedThreadsQuery.query(
|
||||
chunter.class.ThreadMessage,
|
||||
{ objectId: _id, isPinned: true },
|
||||
(res: ThreadMessage[]) => {
|
||||
pinnedThreadsCount = res.length
|
||||
},
|
||||
{ projection: { _id: 1, objectId: 1, isPinned: 1 } }
|
||||
)
|
||||
|
||||
function openMessagesPopup (ev: MouseEvent) {
|
||||
showPopup(PinnedMessagesPopup, { attachedTo: _id, attachedToClass: _class }, eventToHTMLElement(ev))
|
||||
showPopup(PinnedMessagesPopup, { attachedTo: _id, attachedToClass: _class }, eventToHTMLElement(ev), (result) => {
|
||||
if (result == null) return
|
||||
dispatch('select', result)
|
||||
})
|
||||
}
|
||||
|
||||
$: count = pinnedMessagesCount + pinnedThreadsCount
|
||||
</script>
|
||||
|
||||
{#if pinnedMessagesCount > 0}
|
||||
{#if count > 0}
|
||||
<div class="antiHSpacer x2" />
|
||||
<ModernButton size={'extra-small'} on:click={openMessagesPopup}>
|
||||
<Icon icon={view.icon.Pin} size={'x-small'} />
|
||||
<span class="text-sm"><Label label={chunter.string.PinnedCount} params={{ count: pinnedMessagesCount }} /></span>
|
||||
<span class="text-sm"><Label label={chunter.string.PinnedCount} params={{ count }} /></span>
|
||||
</ModernButton>
|
||||
{/if}
|
||||
|
@ -13,12 +13,13 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Class, Doc, Ref } from '@hcengineering/core'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import activity, { ActivityMessage, DisplayActivityMessage } from '@hcengineering/activity'
|
||||
import { ActivityMessagePresenter } from '@hcengineering/activity-resources'
|
||||
import { ActivityMessagePresenter, sortActivityMessages } from '@hcengineering/activity-resources'
|
||||
import { ActionIcon, IconClose } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { ThreadMessage } from '@hcengineering/chunter'
|
||||
import { Class, Doc, Ref, SortingOrder } from '@hcengineering/core'
|
||||
|
||||
import chunter from '../plugin'
|
||||
|
||||
@ -26,40 +27,54 @@
|
||||
export let attachedToClass: Ref<Class<Doc>>
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
const messagesQuery = createQuery()
|
||||
const dispatch = createEventDispatcher()
|
||||
const pinnedQuery = createQuery()
|
||||
const pinnedThreadsQuery = createQuery()
|
||||
|
||||
let pinnedMessages: DisplayActivityMessage[] = []
|
||||
let pinnedMessages: ActivityMessage[] = []
|
||||
let pinnedThreads: ThreadMessage[] = []
|
||||
|
||||
$: messagesQuery.query(activity.class.ActivityMessage, { attachedTo, isPinned: true }, (res: ActivityMessage[]) => {
|
||||
pinnedMessages = res as DisplayActivityMessage[]
|
||||
|
||||
if (pinnedMessages.length === 0) {
|
||||
dispatch('close')
|
||||
}
|
||||
$: pinnedQuery.query(activity.class.ActivityMessage, { attachedTo, isPinned: true }, (res: ActivityMessage[]) => {
|
||||
pinnedMessages = res
|
||||
})
|
||||
|
||||
async function unPinMessaage (message: ActivityMessage): Promise<void> {
|
||||
$: pinnedThreadsQuery.query(
|
||||
chunter.class.ThreadMessage,
|
||||
{ objectId: attachedTo, isPinned: true },
|
||||
(res: ThreadMessage[]) => {
|
||||
pinnedThreads = res
|
||||
}
|
||||
)
|
||||
|
||||
$: if (pinnedMessages.length === 0 && pinnedThreads.length === 0) {
|
||||
dispatch('close', undefined)
|
||||
}
|
||||
|
||||
async function unpinMessage (message: ActivityMessage): Promise<void> {
|
||||
await client.update(message, { isPinned: false })
|
||||
}
|
||||
|
||||
$: displayMessages = sortActivityMessages(pinnedMessages.concat(pinnedThreads), SortingOrder.Descending)
|
||||
</script>
|
||||
|
||||
<div class="antiPopup vScroll popup">
|
||||
{#each pinnedMessages as message}
|
||||
{#each displayMessages as message}
|
||||
<div class="message relative">
|
||||
<ActivityMessagePresenter
|
||||
value={message}
|
||||
withActions={false}
|
||||
hoverable={false}
|
||||
skipLabel={!hierarchy.isDerived(attachedToClass, chunter.class.ChunterSpace)}
|
||||
skipLabel={true}
|
||||
onClick={() => {
|
||||
dispatch('close', message)
|
||||
}}
|
||||
/>
|
||||
<div class="actions">
|
||||
<ActionIcon
|
||||
size="small"
|
||||
icon={IconClose}
|
||||
action={() => {
|
||||
unPinMessaage(message)
|
||||
unpinMessage(message)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
@ -16,9 +16,9 @@
|
||||
import { Doc, Ref } from '@hcengineering/core'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { Breadcrumbs, IconClose, Label, location as locationStore } from '@hcengineering/ui'
|
||||
import { createEventDispatcher, onMount } from 'svelte'
|
||||
import { createEventDispatcher, onDestroy } from 'svelte'
|
||||
import activity, { ActivityMessage, DisplayActivityMessage } from '@hcengineering/activity'
|
||||
import { getMessageFromLoc } from '@hcengineering/activity-resources'
|
||||
import { getMessageFromLoc, messageInFocus } from '@hcengineering/activity-resources'
|
||||
import contact from '@hcengineering/contact'
|
||||
|
||||
import chunter from '../../plugin'
|
||||
@ -45,8 +45,23 @@
|
||||
let channelName: string | undefined = undefined
|
||||
let dataProvider: ChannelDataProvider | undefined = undefined
|
||||
|
||||
locationStore.subscribe((newLocation) => {
|
||||
selectedMessageId = getMessageFromLoc(newLocation)
|
||||
const unsubscribe = messageInFocus.subscribe((id) => {
|
||||
if (id !== undefined && id !== selectedMessageId) {
|
||||
selectedMessageId = id
|
||||
}
|
||||
|
||||
messageInFocus.set(undefined)
|
||||
})
|
||||
|
||||
const unsubscribeLocation = locationStore.subscribe((newLocation) => {
|
||||
const id = getMessageFromLoc(newLocation)
|
||||
selectedMessageId = id
|
||||
messageInFocus.set(id)
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
unsubscribe()
|
||||
unsubscribeLocation()
|
||||
})
|
||||
|
||||
$: messageQuery.query(activity.class.ActivityMessage, { _id }, (result: ActivityMessage[]) => {
|
||||
@ -111,14 +126,13 @@
|
||||
<div class="container">
|
||||
{#if message && dataProvider !== undefined}
|
||||
<ChannelScrollView
|
||||
{selectedMessageId}
|
||||
withDates={false}
|
||||
bind:selectedMessageId
|
||||
embedded
|
||||
skipLabels
|
||||
object={message}
|
||||
objectId={message._id}
|
||||
objectClass={message._class}
|
||||
provider={dataProvider}
|
||||
loadMoreAllowed={false}
|
||||
>
|
||||
<svelte:fragment slot="header">
|
||||
<div class="mt-3">
|
||||
|
Loading…
Reference in New Issue
Block a user