diff --git a/plugins/activity-resources/src/components/reactions/ReactionsPresenter.svelte b/plugins/activity-resources/src/components/reactions/ReactionsPresenter.svelte index 4614fbc6da..1a9925fdce 100644 --- a/plugins/activity-resources/src/components/reactions/ReactionsPresenter.svelte +++ b/plugins/activity-resources/src/components/reactions/ReactionsPresenter.svelte @@ -30,14 +30,16 @@ $: hasReactions = object?.reactions && object.reactions > 0 $: if (object && hasReactions) { - reactionsQuery.query(activity.class.Reaction, { attachedTo: object._id }, (res?: Reaction[]) => { - reactions = res || [] + reactionsQuery.query(activity.class.Reaction, { attachedTo: object._id }, (res: Reaction[]) => { + reactions = res }) + } else { + reactionsQuery.unsubscribe() } const handleClick = (ev: CustomEvent) => { if (readonly) return - updateDocReactions(client, reactions, object, ev.detail) + void updateDocReactions(client, reactions, object, ev.detail) } diff --git a/plugins/chunter-resources/src/components/Channel.svelte b/plugins/chunter-resources/src/components/Channel.svelte index 505567cea3..15c7374bd7 100644 --- a/plugins/chunter-resources/src/components/Channel.svelte +++ b/plugins/chunter-resources/src/components/Channel.svelte @@ -27,6 +27,7 @@ export let context: DocNotifyContext export let object: Doc | undefined export let filters: Ref[] = [] + export let isAsideOpened = false const client = getClient() const hierarchy = client.getHierarchy() @@ -70,6 +71,7 @@ {selectedMessageId} {collection} provider={dataProvider} + {isAsideOpened} loadMoreAllowed={!isDocChannel} /> {/if} diff --git a/plugins/chunter-resources/src/components/ChannelScrollView.svelte b/plugins/chunter-resources/src/components/ChannelScrollView.svelte index d3ac2ab699..2bcb5e074c 100644 --- a/plugins/chunter-resources/src/components/ChannelScrollView.svelte +++ b/plugins/chunter-resources/src/components/ChannelScrollView.svelte @@ -28,7 +28,7 @@ } from '@hcengineering/activity-resources' import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources' import { get } from 'svelte/store' - import { tick } from 'svelte' + import { tick, beforeUpdate, afterUpdate } from 'svelte' import ActivityMessagesSeparator from './ChannelMessagesSeparator.svelte' import { filterChatMessages, getClosestDate, readChannelMessages } from '../utils' @@ -49,6 +49,7 @@ export let showEmbedded = false export let skipLabels = false export let loadMoreAllowed = true + export let isAsideOpened = false const dateSelectorHeight = 30 const headerHeight = 50 @@ -83,6 +84,8 @@ let messagesCount = 0 + let wasAsideOpened = isAsideOpened + $: messages = $messagesStore $: isLoading = $isLoadingStore @@ -90,7 +93,7 @@ $: notifyContext = $contextByDocStore.get(objectId) - $: filterChatMessages(messages, filters, objectClass, selectedFilters).then((filteredMessages) => { + $: void filterChatMessages(messages, filters, objectClass, selectedFilters).then((filteredMessages) => { displayMessages = filteredMessages }) @@ -224,10 +227,12 @@ } else if (shouldLoadMoreDown() && provider.canLoadMore('forward', messages[messages.length - 1]?.createdOn)) { shouldScrollToNew = false void provider.loadMore('forward', messages[messages.length - 1]?.createdOn, limit) + isScrollAtBottom = false } } function handleScroll ({ autoScrolling }: ScrollParams) { + saveScrollPosition() if (autoScrolling) { return } @@ -458,6 +463,48 @@ loadMore() } } + + let prevScrollHeight = 0 + let isScrollAtBottom = false + + function saveScrollPosition (): void { + if (!scrollElement) { + return + } + + const { offsetHeight, scrollHeight, scrollTop } = scrollElement + + prevScrollHeight = scrollHeight + isScrollAtBottom = scrollHeight === scrollTop + offsetHeight + } + + beforeUpdate(() => { + if (!scrollElement) return + + if (scrollElement.scrollHeight === scrollElement.clientHeight) { + isScrollAtBottom = true + } + }) + + afterUpdate(() => { + if (!scrollElement) return + const { scrollHeight } = scrollElement + + if (!isInitialScrolling && prevScrollHeight < scrollHeight && isScrollAtBottom) { + scrollToBottom() + } + }) + + async function compensateAside (isOpened: boolean) { + if (!isInitialScrolling && isScrollAtBottom && !wasAsideOpened && isOpened) { + await wait() + scrollToBottom() + } + + wasAsideOpened = isOpened + } + + $: void compensateAside(isAsideOpened) {#if isLoading} diff --git a/plugins/chunter-resources/src/components/ChannelView.svelte b/plugins/chunter-resources/src/components/ChannelView.svelte index 8083294e92..1f5b3dec96 100644 --- a/plugins/chunter-resources/src/components/ChannelView.svelte +++ b/plugins/chunter-resources/src/components/ChannelView.svelte @@ -77,7 +77,7 @@
{#key context._id} - + {/key}