virtual scrolling improvements

This commit is contained in:
Henry Jameson 2026-08-24 16:04:40 +03:00
commit 6adc4ef2c6
7 changed files with 34 additions and 15 deletions

View file

@ -433,12 +433,6 @@ const conversation = {
virtualHidden() { virtualHidden() {
this.updateVirtualHeight() this.updateVirtualHeight()
}, },
status: {
handler() {
this.updateVirtualHeight()
},
deep: true,
}
}, },
methods: { methods: {
fetchConversation() { fetchConversation() {
@ -615,9 +609,6 @@ const conversation = {
this.threadDisplayStatusObject = {} this.threadDisplayStatusObject = {}
}, },
onStatusSuspendStateChange({ id, suspend }) { onStatusSuspendStateChange({ id, suspend }) {
this.$nextTick(() => {
this.virtualHeight = this.$refs.body.clientHeight
})
if (!suspend) { if (!suspend) {
this.unsuspendibleIds.add(id) this.unsuspendibleIds.add(id)
} else { } else {
@ -630,8 +621,11 @@ const conversation = {
} }
}, },
updateVirtualHeight() { updateVirtualHeight() {
this.$emit('update:virtualHeight', { id: this.status.id, height: this.virtualHeight }) this.$nextTick(() => {
this.virtualHeight = this.$refs.body.clientHeight console.log('LMAO', this.$refs.body.clientHeight)
this.virtualHeight = this.$refs.body.clientHeight
this.$emit('update:virtualHeight', { id: this.status.id, height: this.virtualHeight, top: this.$el.clientTop })
})
}, },
}, },
} }

View file

@ -118,6 +118,7 @@
@goto="setFocused" @goto="setFocused"
@dive="() => diveIntoStatus(status.id)" @dive="() => diveIntoStatus(status.id)"
@suspendable-state-change="onStatusSuspendStateChange" @suspendable-state-change="onStatusSuspendStateChange"
@height-change="updateVirtualHeight"
/> />
<div <div
v-if="showOtherRepliesButtonBelowStatus && getReplies(status.id).length > 1" v-if="showOtherRepliesButtonBelowStatus && getReplies(status.id).length > 1"
@ -176,6 +177,7 @@
@goto="setFocused" @goto="setFocused"
@dive="diveIntoStatus" @dive="diveIntoStatus"
@suspendable-state-change="onStatusSuspendStateChange" @suspendable-state-change="onStatusSuspendStateChange"
@height-change="updateVirtualHeight"
/> />
</div> </div>
<div <div
@ -202,6 +204,7 @@
@goto="setFocused" @goto="setFocused"
@toggle-expanded="toggleExpanded" @toggle-expanded="toggleExpanded"
@suspendable-state-change="onStatusSuspendStateChange" @suspendable-state-change="onStatusSuspendStateChange"
@height-change="updateVirtualHeight"
/> />
</article> </article>
</div> </div>

View file

@ -118,7 +118,7 @@ const Status = {
threadDisplayStatus: String, threadDisplayStatus: String,
}, },
emits: ['goto', 'dive', 'toggleExpanded', 'suspendableStateChange'], emits: ['goto', 'dive', 'toggleExpanded', 'suspendableStateChange', 'heightChange'],
data() { data() {
return { return {
replying: false, replying: false,
@ -539,6 +539,7 @@ const Status = {
this.headTailLinks = headTailLinks this.headTailLinks = headTailLinks
}, },
toggleThreadDisplay() { toggleThreadDisplay() {
// FIXME
this.controlledToggleThreadDisplay() this.controlledToggleThreadDisplay()
}, },
scrollIfFocused(focused) { scrollIfFocused(focused) {
@ -557,8 +558,22 @@ const Status = {
} }
} }
}, },
onTransitionEnd() {
this.$nextTick(() => {
this.$emit('heightChange')
})
},
}, },
watch: { watch: {
status: {
deep: true,
handler() {
this.$emit('heightChange')
},
},
replying() {
this.$emit('heightChange')
},
focused: function (id) { focused: function (id) {
this.scrollIfFocused(id) this.scrollIfFocused(id)
}, },
@ -584,6 +599,7 @@ const Status = {
}, },
isSuspendable: function (suspend) { isSuspendable: function (suspend) {
this.$emit('suspendableStateChange', { id: this.status.id, suspend }) this.$emit('suspendableStateChange', { id: this.status.id, suspend })
this.$emit('heightChange')
}, },
}, },
} }

View file

@ -454,7 +454,10 @@
</StatusPopover> </StatusPopover>
</div> </div>
<transition name="fade"> <Transition
@after-leave="onTransitionEnd"
name="fade"
>
<div <div
v-if="shouldDisplayFavsAndRepeats" v-if="shouldDisplayFavsAndRepeats"
class="favs-repeated-users" class="favs-repeated-users"
@ -502,7 +505,7 @@
</div> </div>
</div> </div>
</div> </div>
</transition> </Transition>
<EmojiReactions <EmojiReactions
v-if="(mergedConfig.emojiReactionsOnTimeline || focused) && (!noHeading && !isPreview)" v-if="(mergedConfig.emojiReactionsOnTimeline || focused) && (!noHeading && !isPreview)"

View file

@ -30,7 +30,7 @@ const ThreadTree = {
totalReplyCount: Object, totalReplyCount: Object,
totalReplyDepth: Object, totalReplyDepth: Object,
}, },
emits: ['suspendableStateChange', 'goto', 'dive'], emits: ['suspendableStateChange', 'goto', 'dive', 'heightChange'],
computed: { computed: {
currentReplies() { currentReplies() {
return this.getReplies(this.statusId).map(({ id }) => id) return this.getReplies(this.statusId).map(({ id }) => id)

View file

@ -22,6 +22,7 @@
@goto="$emit('goto', statusId)" @goto="$emit('goto', statusId)"
@toggle-expanded="toggleExpanded" @toggle-expanded="toggleExpanded"
@suspendable-state-change="e => $emit('suspendableStateChange', e)" @suspendable-state-change="e => $emit('suspendableStateChange', e)"
@height-change="e => $emit('height-change', e)"
/> />
<div <div
v-if="currentReplies.length > 0 && threadShowing" v-if="currentReplies.length > 0 && threadShowing"
@ -55,6 +56,7 @@
@goto="(e) => $emit('goto', e)" @goto="(e) => $emit('goto', e)"
@dive="(e) => $emit('dive', e)" @dive="(e) => $emit('dive', e)"
@suspendable-state-change="e => $emit('suspendableStateChange', e)" @suspendable-state-change="e => $emit('suspendableStateChange', e)"
@height-change="e => $emit('height-change', e)"
/> />
</div> </div>
<div <div

View file

@ -99,6 +99,7 @@ const Timeline = {
} }
}, },
statusesToDisplay() { statusesToDisplay() {
if (!this.virtualScrollingEnabled) return this.visibleStatusIds
const amount = this.timeline.visibleStatusIds.size const amount = this.timeline.visibleStatusIds.size
const statusesPerSide = Math.ceil(Math.max(3, window.innerHeight / 80)) const statusesPerSide = Math.ceil(Math.max(3, window.innerHeight / 80))
const min = Math.max(0, this.virtualScrollIndex - statusesPerSide) const min = Math.max(0, this.virtualScrollIndex - statusesPerSide)