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 (
readonly context: DocNotifyContext | undefined,
private context: DocNotifyContext | undefined,
readonly space: Ref<Space>,
chatId: Ref<Doc>,
_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 (
selectedMsg?: Ref<ActivityMessage>,
loadAll = false,

View File

@ -26,7 +26,7 @@
messageInFocus,
sortActivityMessages
} 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 { InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
import { getResource } from '@hcengineering/platform'
@ -72,6 +72,7 @@
const minMsgHeightRem = 2
const loadMoreThreshold = 40
const me = getCurrentAccount()
const client = getClient()
const inboxClient = InboxNotificationsClientImpl.getClient()
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 {
return freeze
return freeze || isPageHidden
}
$: 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> {
saveScrollPosition()
updateDownButtonVisibility($metadataStore, displayMessages, scrollElement)
@ -555,8 +603,12 @@
return
}
const prevCount = messagesCount
messagesCount = newCount
if (isFreeze()) {
messagesCount = newCount
await wait()
scrollToStartOfNew()
return
}
@ -565,15 +617,13 @@
} else if (dateToJump !== undefined) {
await wait()
scrollToDate(dateToJump)
} else if (shouldScrollToNew && messagesCount > 0 && newCount > messagesCount) {
} else if (shouldScrollToNew && prevCount > 0 && newCount > prevCount) {
await wait()
scrollToNewMessages()
} else {
await wait()
readViewportMessages()
}
messagesCount = newCount
}
$: void handleMessagesUpdated(displayMessages.length)
@ -610,10 +660,12 @@
afterUpdate(() => {
if (!scrollElement) return
const { scrollHeight } = scrollElement
const { offsetHeight, scrollHeight, scrollTop } = scrollElement
if (!isInitialScrolling && prevScrollHeight < scrollHeight && isScrollAtBottom) {
if (!isInitialScrolling && !isFreeze() && prevScrollHeight < scrollHeight && isScrollAtBottom) {
scrollToBottom()
} else if (isFreeze()) {
isScrollAtBottom = scrollHeight <= Math.ceil(scrollTop + offsetHeight)
}
})
@ -641,10 +693,12 @@
onMount(() => {
chatReadMessagesStore.update(() => new Set())
document.addEventListener('visibilitychange', handleVisibilityChange)
})
onDestroy(() => {
unsubscribe()
document.removeEventListener('visibilitychange', handleVisibilityChange)
})
let showScrollDownButton = false
@ -715,7 +769,7 @@
const canLoadNextForwardStore = provider.canLoadNextForwardStore
$: if (!freeze) {
$: if (!freeze && !isPageHidden && isScrollInitialized) {
readViewportMessages()
}
</script>