Fix chat forward pagination (#5869)

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
Kristina 2024-06-20 19:37:37 +04:00 committed by GitHub
parent 58af65e29d
commit 30753b4a7a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 16 deletions

View File

@ -17,6 +17,7 @@ import {
type Account,
type Class,
type Doc,
type DocumentQuery,
getCurrentAccount,
isOtherDay,
type Ref,
@ -31,6 +32,7 @@ import attachment from '@hcengineering/attachment'
import { combineActivityMessages } from '@hcengineering/activity-resources'
import chunter from './plugin'
import { type ChatMessage } from '@hcengineering/chunter'
export type LoadMode = 'forward' | 'backward'
@ -213,7 +215,7 @@ export class ChannelDataProvider implements IChannelDataProvider {
const start = metadata[startPosition]?.createdOn
if (startPosition === 0) {
await this.loadMore('forward', metadata[startPosition]?.createdOn, this.limit, true)
await this.loadMore('forward', metadata[startPosition]?.createdOn, this.limit)
} else {
await this.loadMore('backward', start, this.limit / 2)
await this.loadMore('forward', metadata[startPosition - 1]?.createdOn, this.limit / 2)
@ -224,7 +226,11 @@ export class ChannelDataProvider implements IChannelDataProvider {
this.isInitialLoadedStore.set(true)
}
private loadTail (start?: Timestamp, afterLoad?: (msgs: ActivityMessage[]) => Promise<ActivityMessage[]>): void {
private loadTail (
start?: Timestamp,
afterLoad?: (msgs: ActivityMessage[]) => Promise<ActivityMessage[]>,
query?: DocumentQuery<ActivityMessage>
): void {
if (this.chatId === undefined) {
this.isTailLoading.set(false)
return
@ -238,6 +244,7 @@ export class ChannelDataProvider implements IChannelDataProvider {
this.msgClass,
{
attachedTo: this.chatId,
...query,
...(this.tailStart !== undefined ? { createdOn: { $gte: this.tailStart } } : {})
},
async (res) => {
@ -259,7 +266,7 @@ export class ChannelDataProvider implements IChannelDataProvider {
)
}
public async loadMore (mode: LoadMode, loadAfter?: Timestamp, limit?: number, loadEqual = false): Promise<void> {
public async loadMore (mode: LoadMode, loadAfter?: Timestamp, limit?: number): Promise<void> {
if (this.chatId === undefined || loadAfter === undefined) {
return
}
@ -273,13 +280,21 @@ export class ChannelDataProvider implements IChannelDataProvider {
const isBackward = mode === 'backward'
const isForward = mode === 'forward'
const chunks = get(this.chunksStore)
const tail = get(this.tailStore)
const lastChunk: Chunk | undefined = isBackward ? chunks[0] : chunks[chunks.length - 1]
const skipIds = (lastChunk?.data ?? [])
.concat(tail)
.filter(({ createdOn }) => createdOn === loadAfter)
.map(({ _id }) => _id) as Array<Ref<ChatMessage>>
if (isForward) {
const metadata = get(this.metadataStore)
const metaIndex = metadata.findIndex(({ createdOn }) => createdOn === loadAfter)
const shouldLoadTail = metaIndex >= 0 && metaIndex + this.limit >= metadata.length
if (shouldLoadTail) {
this.loadTail(metadata[metaIndex + 1]?.createdOn)
this.loadTail(metadata[metaIndex + 1]?.createdOn, undefined, { _id: { $nin: skipIds } })
this.isLoadingMoreStore.set(false)
return
}
@ -290,14 +305,8 @@ export class ChannelDataProvider implements IChannelDataProvider {
chunter.class.ChatMessage,
{
attachedTo: this.chatId,
hidden: { $ne: true },
createdOn: isBackward
? loadEqual
? { $lte: loadAfter }
: { $lt: loadAfter }
: loadEqual
? { $gte: loadAfter }
: { $gt: loadAfter }
_id: { $nin: skipIds },
createdOn: isBackward ? { $lte: loadAfter } : { $gte: loadAfter }
},
{
limit: limit ?? this.limit,
@ -322,8 +331,6 @@ export class ChannelDataProvider implements IChannelDataProvider {
data: isBackward ? messages.reverse() : messages
}
const chunks = get(this.chunksStore)
this.chunksStore.set(isBackward ? [chunk, ...chunks] : [...chunks, chunk])
this.isLoadingMoreStore.set(false)
}

View File

@ -55,7 +55,7 @@
const dateSelectorHeight = 30
const headerHeight = 52
const minMsgHeightRem = 4.375
const minMsgHeightRem = 2
const client = getClient()
const inboxClient = InboxNotificationsClientImpl.getClient()
@ -236,7 +236,7 @@
const { scrollHeight, scrollTop, clientHeight } = scrollElement
return scrollTop + clientHeight === scrollHeight
return Math.ceil(scrollTop + clientHeight) === scrollHeight
}
let scrollToRestore = 0