diff --git a/src/components/LeftSidebar/LeftSidebar.vue b/src/components/LeftSidebar/LeftSidebar.vue index 469571312d2..94def556e4e 100644 --- a/src/components/LeftSidebar/LeftSidebar.vue +++ b/src/components/LeftSidebar/LeftSidebar.vue @@ -341,7 +341,7 @@ class="scroller" @scroll="debounceHandleScroll" /> @@ -633,7 +633,6 @@ export default { * @type {number|null} */ lastUnreadMentionBelowViewportIndex: null, - preventFindingUnread: false, roomListModifiedBefore: 0, forceFullRoomListRefreshAfterXLoops: 0, isFetchingConversations: false, @@ -661,6 +660,16 @@ export default { return sortConversationsList(this.filteredConversationsList, this.groupMode, this.sortOrder) }, + unreadMentionIndices() { + const indices = [] + for (const i in this.sortedConversationsList) { + if (hasUnreadMentions(this.sortedConversationsList[i])) { + indices.push(i) + } + } + return indices + }, + emptyContentLabel() { if (this.showThreadsList) { return t('spreed', 'No followed threads') @@ -752,7 +761,7 @@ export default { }, showEmptyContent() { - return (this.conversationsInitialised && !this.filteredConversationsList.length) + return (this.conversationsInitialised && !this.sortedConversationsList.length) || (this.showThreadsList && this.followedThreadsInitialised && !this.followedThreads.length) }, }, @@ -770,6 +779,10 @@ export default { this.chatExtrasStore.fetchFollowedThreadsList() } }, + + unreadMentionIndices() { + this.debounceHandleScroll() + }, }, beforeMount() { @@ -817,7 +830,7 @@ export default { mounted() { this.debounceFetchSearchResults = debounce(this.fetchSearchResults, 250) this.debounceFetchConversations = debounce(this.fetchConversations, 3000) - this.debounceHandleScroll = debounce(this.handleScroll, 50) + this.debounceHandleScroll = debounce(this.handleScroll, 100) if (supportTags) { // Fetch conversation tags @@ -914,17 +927,10 @@ export default { this.searchText = '' // Initiate the navigation status this.isNavigating = false - - this.handleUnreadMention() }, scrollBottomUnread() { - this.preventFindingUnread = true this.$refs.scroller.scrollToItem(this.lastUnreadMentionBelowViewportIndex) - setTimeout(() => { - this.handleUnreadMention() - this.preventFindingUnread = false - }, 500) }, async fetchPossibleConversations() { @@ -1142,33 +1148,29 @@ export default { }, handleConversationsReceived() { - this.handleUnreadMention() if (this.$route.params.token) { this.showArchived = this.$store.getters.conversation(this.$route.params.token)?.isArchived ?? false this.scrollToConversation(this.$route.params.token) } }, - // Checks whether the conversations list is scrolled all the way to the top - // or not handleScroll() { - this.handleUnreadMention() + this.computeLastUnreadMention() }, /** - * Find position of the last unread conversation below viewport + * Find position of the last unread conversation below viewport. + * Iterates only over indices with unread mentions (cached via the + * unreadMentionIndices computed) instead of the full list. */ - async handleUnreadMention() { - await this.$nextTick() - - this.lastUnreadMentionBelowViewportIndex = null - const lastConversationInViewport = this.$refs.scroller.getLastItemInViewportIndex() - for (let i = this.filteredConversationsList.length - 1; i > lastConversationInViewport; i--) { - if (hasUnreadMentions(this.filteredConversationsList[i])) { - this.lastUnreadMentionBelowViewportIndex = i - return - } + computeLastUnreadMention() { + if (!this.$refs.scroller) { + this.lastUnreadMentionBelowViewportIndex = null + return } + const lastInViewport = this.$refs.scroller.getLastItemInViewportIndex() + this.lastUnreadMentionBelowViewportIndex = this.unreadMentionIndices + .findLast((idx) => idx > lastInViewport) ?? null }, async scrollToConversation(token) {