diff --git a/changelog.d/virtual-scrolling-2.change b/changelog.d/virtual-scrolling-2.change new file mode 100644 index 000000000..74a47c6a9 --- /dev/null +++ b/changelog.d/virtual-scrolling-2.change @@ -0,0 +1 @@ +Implemented new virtual scrolling. Opening huge threads should be faster now diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index 1fed4c458..863e4f61e 100644 --- a/src/components/conversation/conversation.js +++ b/src/components/conversation/conversation.js @@ -19,6 +19,7 @@ import { useConversation } from 'src/composables/useConversation.js' import { useScrollPosition } from 'src/composables/useScrollPosition.js' import { useTreeConversationTopology } from 'src/composables/useTreeConversationTopology.js' import { useVirtualScrolling } from 'src/composables/useVirtualScrolling.js' +import { useInterfaceSizes } from 'src/composables/useInterfaceSizes.js' import { WSConnectionStatus } from 'src/api/websocket.js' @@ -83,7 +84,7 @@ export default { } setFocused(id) const target = document.querySelector(`.Status[data-status-id=${id}]`) - return await scroller.scrollIntoView(target, { block: 'start' }) + return await scroller.scrollIntoView(target, { block: 'nearest' }) } const { statusId } = toRefs(props) @@ -132,6 +133,7 @@ export default { // # Main things const { currentStatus, + mainStatus, conversation, replies, getReplies, @@ -148,7 +150,6 @@ export default { resetDisplayState() } if (isPage.value) return - await tryScrollTo(currentStatus.value.id) }, { flush: 'post' }, ) @@ -187,23 +188,37 @@ export default { '-last': status.id === lastStatus.value?.id, }) + const { fontSize } = useInterfaceSizes() + + // Placeholder heights. + const mutedStatusHeight = computed(() => fontSize.value * 1.5) + const normalStatusHeight = computed(() => fontSize.value * 10) + const getPlaceholderHeight = (id) => + conversation.value.find((item) => item.id === id)?.muted + ? mutedStatusHeight + : normalStatusHeight + // # Linear style stuff const isLinearView = computed(() => displayStyle.value !== 'tree') const linearElement = useTemplateRef('linear') const linearScrollCompensation = computed( - () => isLinearView.value && isExpanded.value, + () => isLinearView.value, ) const { heightChart: heightChartLinear, changeSuspendState: changeSuspendStateLinear, updateVirtualHeight: updateVirtualHeightLinear, - } = useVirtualScrolling( - conversation, - linearElement, - scroller, - linearScrollCompensation, - currentStatus, - ) + pauseWatchers, + resumeWatchers, + } = useVirtualScrolling({ + list: conversation, + body: linearElement, + scrollPositionInstance: scroller, + scrollCompensation: linearScrollCompensation, + anchorId: mainStatus.value?.id, + anchorRepeatId: currentStatus.value?.id, + getPlaceholderHeight, + }) // # Tree style stuff const isTreeView = computed(() => displayStyle.value === 'tree') @@ -218,18 +233,19 @@ export default { const ancestorsElement = useTemplateRef('ancestors') const treeScrollCompensation = computed( - () => isTreeView.value && isExpanded.value, + () => isTreeView.value, ) const { heightChart: heightChartAncestors, changeSuspendState: changeSuspendStateAncestors, updateVirtualHeight: updateVirtualHeightAncestors, - } = useVirtualScrolling( - currentAncestors, - ancestorsElement, - scroller, - treeScrollCompensation, - ) + } = useVirtualScrolling({ + list: currentAncestors, + body: ancestorsElement, + scrollPositionInstance: scroller, + scrollCompensation: treeScrollCompensation, + getPlaceholderHeight, + }) const currentLevel = computed(() => [currentStatus.value].filter(Boolean)) const currentLevelElement = useTemplateRef('currentLevel') @@ -237,7 +253,13 @@ export default { heightChart: heightChartCurrentLevel, changeSuspendState: changeSuspendStateCurrentLevel, updateVirtualHeight: updateVirtualHeightCurrentLevel, - } = useVirtualScrolling(currentLevel, currentLevelElement, scroller, false) + } = useVirtualScrolling({ + list: currentLevel, + body: currentLevelElement, + scrollPositionInstance: scroller, + scrollCompensation: false, + getPlaceholderHeight, + }) const treeViewIsSimple = computed( () => !mergedConfig.value.conversationTreeAdvanced, diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue index 3a61decf5..8d4c4f967 100644 --- a/src/components/conversation/conversation.vue +++ b/src/components/conversation/conversation.vue @@ -97,19 +97,21 @@ :class="{'thread-ancestor-has-other-replies': getReplies(element.id).size > 1, '-faded': shouldFadeAncestors}" > @@ -128,7 +130,7 @@