diff --git a/packages/presentation/src/utils.ts b/packages/presentation/src/utils.ts
index 39ee4b1eee..2ee4072fd0 100644
--- a/packages/presentation/src/utils.ts
+++ b/packages/presentation/src/utils.ts
@@ -54,9 +54,11 @@ import view, { type AttributeCategory, type AttributeEditor } from '@hcengineeri
import { deepEqual } from 'fast-equals'
import { onDestroy } from 'svelte'
import { get, writable, type Writable } from 'svelte/store'
+
import { type KeyedAttribute } from '..'
import { OptimizeQueryMiddleware, PresentationPipelineImpl, type PresentationPipeline } from './pipeline'
import plugin from './plugin'
+
export { reduceCalls } from '@hcengineering/core'
let liveQuery: LQ
diff --git a/packages/ui/src/components/Scroller.svelte b/packages/ui/src/components/Scroller.svelte
index 05372851e9..a19a6cee4a 100644
--- a/packages/ui/src/components/Scroller.svelte
+++ b/packages/ui/src/components/Scroller.svelte
@@ -31,6 +31,7 @@
export let fade: FadeOptions = defaultSP
export let noFade: boolean = true
export let invertScroll: boolean = false
+ export let scrollDirection: 'vertical' | 'vertical-reverse' = 'vertical'
export let contentDirection: 'vertical' | 'vertical-reverse' | 'horizontal' = 'vertical'
export let horizontal: boolean = contentDirection === 'horizontal'
export let align: 'start' | 'center' | 'end' | 'stretch' = 'stretch'
@@ -39,7 +40,7 @@
export let buttons: 'normal' | 'union' | false = false
export let shrink: boolean = false
export let divScroll: HTMLElement | undefined | null = undefined
- export let divBox: HTMLElement | undefined = undefined
+ export let divBox: HTMLElement | undefined | null = undefined
export let checkForHeaders: boolean = false
export let stickedScrollBars: boolean = false
export let thinScrollBars: boolean = false
@@ -50,7 +51,7 @@
export function scroll (top: number, left?: number, behavior: 'auto' | 'smooth' = 'auto') {
if (divScroll) {
if (top !== 0) divScroll.scroll({ top, left: 0, behavior })
- if (left !== 0 || left !== undefined) divScroll.scroll({ top: 0, left, behavior })
+ if (left !== 0 && left !== undefined) divScroll.scroll({ top: 0, left, behavior })
}
}
export function scrollBy (top: number, left?: number, behavior: 'auto' | 'smooth' = 'auto') {
@@ -102,11 +103,19 @@
const scrollH = divScroll.scrollHeight
const proc = scrollH / trackH
- const newHeight = (divScroll.clientHeight - 4) / proc + 'px'
+ const newHeight = (divScroll.clientHeight - 4) / proc
+ const newHeightPx = newHeight + 'px'
if (divBar.style.height !== 'newHeight') {
- divBar.style.height = newHeight
+ divBar.style.height = newHeightPx
+ }
+
+ let newTop = '0px'
+
+ if (scrollDirection === 'vertical-reverse') {
+ newTop = divScroll.clientHeight + divScroll.scrollTop / proc - newHeight - shiftTop - 2 + 'px'
+ } else {
+ newTop = divScroll.scrollTop / proc + shiftTop + 2 + 'px'
}
- const newTop = divScroll.scrollTop / proc + shiftTop + 2 + 'px'
if (divBar.style.top !== newTop) {
divBar.style.top = newTop
}
@@ -542,7 +551,8 @@
divHeight = element.clientHeight
onResize?.()
}}
- class="scroll relative flex-shrink"
+ class="scroll relative flex-shrink flex-col"
+ style:flex-direction={scrollDirection === 'vertical-reverse' ? 'column-reverse' : 'column'}
class:disableOverscroll
style:overflow-x={horizontal ? 'auto' : 'hidden'}
on:scroll={() => {
diff --git a/plugins/activity-resources/src/activity.ts b/plugins/activity-resources/src/activity.ts
index 0d748dafd0..89125e90b7 100644
--- a/plugins/activity-resources/src/activity.ts
+++ b/plugins/activity-resources/src/activity.ts
@@ -1,3 +1,17 @@
+//
+// Copyright © 2024 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.
+//
import activity, { type ActivityMessage, type SavedMessage } from '@hcengineering/activity'
import core, { type Ref, SortingOrder, type WithLookup } from '@hcengineering/core'
import { writable } from 'svelte/store'
diff --git a/plugins/activity-resources/src/components/Activity.svelte b/plugins/activity-resources/src/components/Activity.svelte
index 5a2cc7db4f..1444af2fa8 100644
--- a/plugins/activity-resources/src/components/Activity.svelte
+++ b/plugins/activity-resources/src/components/Activity.svelte
@@ -279,6 +279,7 @@
hideLink={true}
type={canGroup ? 'short' : 'default'}
isHighlighted={selectedMessageId === message._id}
+ withShowMore
/>
{:else}
@@ -288,6 +289,7 @@
hideLink={true}
type={canGroup ? 'short' : 'default'}
isHighlighted={selectedMessageId === message._id}
+ withShowMore
/>
{/if}
diff --git a/plugins/activity-resources/src/components/activity-message/ActivityMessagePresenter.svelte b/plugins/activity-resources/src/components/activity-message/ActivityMessagePresenter.svelte
index a81e8ac830..3069850236 100644
--- a/plugins/activity-resources/src/components/activity-message/ActivityMessagePresenter.svelte
+++ b/plugins/activity-resources/src/components/activity-message/ActivityMessagePresenter.svelte
@@ -33,7 +33,7 @@
export let actions: Action[] = []
export let hoverable = true
export let hoverStyles: 'borderedHover' | 'filledHover' = 'borderedHover'
- export let withShowMore: boolean = true
+ export let withShowMore: boolean = false
export let attachmentImageSize: 'x-large' | undefined = undefined
export let type: ActivityMessageViewType = 'default'
export let videoPreload = true
diff --git a/plugins/activity-resources/src/components/reactions/Reactions.svelte b/plugins/activity-resources/src/components/reactions/Reactions.svelte
index 440cb291ba..d7ecf51871 100644
--- a/plugins/activity-resources/src/components/reactions/Reactions.svelte
+++ b/plugins/activity-resources/src/components/reactions/Reactions.svelte
@@ -27,7 +27,6 @@
export let readonly: boolean = false
const dispatch = createEventDispatcher()
- const client = getClient()
const me = getCurrentAccount()
let reactionsAccounts = new Map[]>()
diff --git a/plugins/activity-resources/src/components/reactions/ReactionsPresenter.svelte b/plugins/activity-resources/src/components/reactions/ReactionsPresenter.svelte
index 86eb49e3a1..0a2c4cabbf 100644
--- a/plugins/activity-resources/src/components/reactions/ReactionsPresenter.svelte
+++ b/plugins/activity-resources/src/components/reactions/ReactionsPresenter.svelte
@@ -55,7 +55,7 @@
}
-{#if object && reactions.length > 0}
+{#if object && (reactions.length > 0 || (object?.reactions ?? 0) > 0)}
diff --git a/plugins/chunter-resources/src/channelDataProvider.ts b/plugins/chunter-resources/src/channelDataProvider.ts
index c095d0e855..ed79fa65d5 100644
--- a/plugins/chunter-resources/src/channelDataProvider.ts
+++ b/plugins/chunter-resources/src/channelDataProvider.ts
@@ -330,12 +330,11 @@ export class ChannelDataProvider implements IChannelDataProvider {
const client = getClient()
const skipIds = this.getChunkSkipIds(loadAfter)
- const messages = await client.findAll(
+ let messages: ActivityMessage[] = await client.findAll(
this.msgClass,
{
attachedTo: this.chatId,
space: this.space,
- _id: { $nin: skipIds },
createdOn: equal
? isBackward
? { $lte: loadAfter }
@@ -351,6 +350,8 @@ export class ChannelDataProvider implements IChannelDataProvider {
}
)
+ messages = messages.filter(({ _id }) => !skipIds.includes(_id))
+
if (messages.length === 0) {
return
}
diff --git a/plugins/chunter-resources/src/components/BaseChatScroller.svelte b/plugins/chunter-resources/src/components/BaseChatScroller.svelte
new file mode 100644
index 0000000000..36426376a5
--- /dev/null
+++ b/plugins/chunter-resources/src/components/BaseChatScroller.svelte
@@ -0,0 +1,56 @@
+
+
+
+{#if loadingOverlay}
+
+
+
+{/if}
+
+
+
+
+
diff --git a/plugins/chunter-resources/src/components/Channel.svelte b/plugins/chunter-resources/src/components/Channel.svelte
index ec2ff01215..3273498461 100644
--- a/plugins/chunter-resources/src/components/Channel.svelte
+++ b/plugins/chunter-resources/src/components/Channel.svelte
@@ -19,11 +19,11 @@
import { getClient, isSpace } from '@hcengineering/presentation'
import { getMessageFromLoc, messageInFocus } from '@hcengineering/activity-resources'
import { location as locationStore } from '@hcengineering/ui'
+ import { onDestroy } from 'svelte'
import chunter from '../plugin'
- import ChannelScrollView from './ChannelScrollView.svelte'
import { ChannelDataProvider } from '../channelDataProvider'
- import { onDestroy } from 'svelte'
+ import ReverseChannelScrollView from './ReverseChannelScrollView.svelte'
export let object: Doc
export let context: DocNotifyContext | undefined
@@ -101,17 +101,13 @@
{#if dataProvider}
-
{/if}
diff --git a/plugins/chunter-resources/src/components/ChannelHeader.svelte b/plugins/chunter-resources/src/components/ChannelHeader.svelte
index 284153a4eb..d59c9cc794 100644
--- a/plugins/chunter-resources/src/components/ChannelHeader.svelte
+++ b/plugins/chunter-resources/src/components/ChannelHeader.svelte
@@ -74,7 +74,7 @@
intlLabel={chunter.string.Channel}
{description}
titleKind={isPerson ? 'default' : 'breadcrumbs'}
- withFilters={!hierarchy.isDerived(_class, chunter.class.ChunterSpace)}
+ withFilters={false}
{allowClose}
{canOpen}
{withAside}
diff --git a/plugins/chunter-resources/src/components/ChannelInput.svelte b/plugins/chunter-resources/src/components/ChannelInput.svelte
index 218d13237d..e4fbfa8503 100644
--- a/plugins/chunter-resources/src/components/ChannelInput.svelte
+++ b/plugins/chunter-resources/src/components/ChannelInput.svelte
@@ -92,7 +92,7 @@
diff --git a/plugins/chunter-resources/src/components/threads/ThreadContent.svelte b/plugins/chunter-resources/src/components/threads/ThreadContent.svelte
index 827da56d96..5f10008a09 100644
--- a/plugins/chunter-resources/src/components/threads/ThreadContent.svelte
+++ b/plugins/chunter-resources/src/components/threads/ThreadContent.svelte
@@ -1,20 +1,24 @@