Freeze scroll and reading if tab not active (#6681)

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
Kristina 2024-09-23 10:35:52 +04:00 committed by GitHub
parent fd9d956db9
commit 4bdfaaa28e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 71 additions and 10 deletions

View File

@ -120,7 +120,7 @@ export class ChannelDataProvider implements IChannelDataProvider {
}) })
constructor ( constructor (
readonly context: DocNotifyContext | undefined, private context: DocNotifyContext | undefined,
readonly space: Ref<Space>, readonly space: Ref<Space>,
chatId: Ref<Doc>, chatId: Ref<Doc>,
_class: Ref<Class<ActivityMessage>>, _class: Ref<Class<ActivityMessage>>,
@ -210,6 +210,13 @@ export class ChannelDataProvider implements IChannelDataProvider {
) )
} }
async updateNewTimestamp (context?: DocNotifyContext): Promise<void> {
this.context = context ?? this.context
const firstNewMsgIndex = await this.getFirstNewMsgIndex()
const metadata = get(this.metadataStore)
this.newTimestampStore.set(firstNewMsgIndex !== undefined ? metadata[firstNewMsgIndex]?.createdOn : undefined)
}
private async loadInitialMessages ( private async loadInitialMessages (
selectedMsg?: Ref<ActivityMessage>, selectedMsg?: Ref<ActivityMessage>,
loadAll = false, loadAll = false,

View File

@ -26,7 +26,7 @@
messageInFocus, messageInFocus,
sortActivityMessages sortActivityMessages
} from '@hcengineering/activity-resources' } from '@hcengineering/activity-resources'
import { Doc, getDay, Ref, Timestamp } from '@hcengineering/core' import { Doc, getCurrentAccount, getDay, Ref, Timestamp } from '@hcengineering/core'
import { DocNotifyContext } from '@hcengineering/notification' import { DocNotifyContext } from '@hcengineering/notification'
import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources' import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
import { getResource } from '@hcengineering/platform' import { getResource } from '@hcengineering/platform'
@ -72,6 +72,7 @@
const minMsgHeightRem = 2 const minMsgHeightRem = 2
const loadMoreThreshold = 40 const loadMoreThreshold = 40
const me = getCurrentAccount()
const client = getClient() const client = getClient()
const inboxClient = InboxNotificationsClientImpl.getClient() const inboxClient = InboxNotificationsClientImpl.getClient()
const contextByDocStore = inboxClient.contextByDoc const contextByDocStore = inboxClient.contextByDoc
@ -131,8 +132,23 @@
} }
}) })
let isPageHidden = false
let lastMsgBeforeFreeze: Ref<ActivityMessage> | undefined = undefined
function handleVisibilityChange (): void {
if (document.hidden) {
isPageHidden = true
lastMsgBeforeFreeze = shouldScrollToNew ? displayMessages[displayMessages.length - 1]?._id : undefined
} else {
if (isPageHidden) {
isPageHidden = false
void provider.updateNewTimestamp(notifyContext)
}
}
}
function isFreeze (): boolean { function isFreeze (): boolean {
return freeze return freeze || isPageHidden
} }
$: displayMessages = filterChatMessages(messages, filters, filterResources, doc._class, selectedFilters) $: displayMessages = filterChatMessages(messages, filters, filterResources, doc._class, selectedFilters)
@ -295,6 +311,38 @@
} }
} }
function scrollToStartOfNew (): void {
if (!scrollElement || !lastMsgBeforeFreeze) {
return
}
const lastIndex = displayMessages.findIndex(({ _id }) => _id === lastMsgBeforeFreeze)
if (lastIndex === -1) return
const firstNewMessage = displayMessages.find(({ createdBy }, index) => index > lastIndex && createdBy !== me._id)
if (firstNewMessage === undefined) {
scrollToBottom()
return
}
const messagesElements = scrollContentBox?.getElementsByClassName('activityMessage')
const msgElement = messagesElements?.[firstNewMessage._id as any]
if (!msgElement) {
return
}
const messageRect = msgElement.getBoundingClientRect()
const topOffset = messageRect.top - 150
if (topOffset < 0) {
scroller?.scrollBy(topOffset)
} else if (topOffset > 0) {
scroller?.scrollBy(topOffset)
}
}
async function handleScroll ({ autoScrolling }: ScrollParams): Promise<void> { async function handleScroll ({ autoScrolling }: ScrollParams): Promise<void> {
saveScrollPosition() saveScrollPosition()
updateDownButtonVisibility($metadataStore, displayMessages, scrollElement) updateDownButtonVisibility($metadataStore, displayMessages, scrollElement)
@ -555,8 +603,12 @@
return return
} }
const prevCount = messagesCount
messagesCount = newCount
if (isFreeze()) { if (isFreeze()) {
messagesCount = newCount await wait()
scrollToStartOfNew()
return return
} }
@ -565,15 +617,13 @@
} else if (dateToJump !== undefined) { } else if (dateToJump !== undefined) {
await wait() await wait()
scrollToDate(dateToJump) scrollToDate(dateToJump)
} else if (shouldScrollToNew && messagesCount > 0 && newCount > messagesCount) { } else if (shouldScrollToNew && prevCount > 0 && newCount > prevCount) {
await wait() await wait()
scrollToNewMessages() scrollToNewMessages()
} else { } else {
await wait() await wait()
readViewportMessages() readViewportMessages()
} }
messagesCount = newCount
} }
$: void handleMessagesUpdated(displayMessages.length) $: void handleMessagesUpdated(displayMessages.length)
@ -610,10 +660,12 @@
afterUpdate(() => { afterUpdate(() => {
if (!scrollElement) return if (!scrollElement) return
const { scrollHeight } = scrollElement const { offsetHeight, scrollHeight, scrollTop } = scrollElement
if (!isInitialScrolling && prevScrollHeight < scrollHeight && isScrollAtBottom) { if (!isInitialScrolling && !isFreeze() && prevScrollHeight < scrollHeight && isScrollAtBottom) {
scrollToBottom() scrollToBottom()
} else if (isFreeze()) {
isScrollAtBottom = scrollHeight <= Math.ceil(scrollTop + offsetHeight)
} }
}) })
@ -641,10 +693,12 @@
onMount(() => { onMount(() => {
chatReadMessagesStore.update(() => new Set()) chatReadMessagesStore.update(() => new Set())
document.addEventListener('visibilitychange', handleVisibilityChange)
}) })
onDestroy(() => { onDestroy(() => {
unsubscribe() unsubscribe()
document.removeEventListener('visibilitychange', handleVisibilityChange)
}) })
let showScrollDownButton = false let showScrollDownButton = false
@ -715,7 +769,7 @@
const canLoadNextForwardStore = provider.canLoadNextForwardStore const canLoadNextForwardStore = provider.canLoadNextForwardStore
$: if (!freeze) { $: if (!freeze && !isPageHidden && isScrollInitialized) {
readViewportMessages() readViewportMessages()
} }
</script> </script>