diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index 7c160bc42..e8e52c7d1 100644 --- a/src/components/conversation/conversation.js +++ b/src/components/conversation/conversation.js @@ -80,6 +80,19 @@ export default { ) } + const tryScrollTo = async (id) => { + if (!id) { + return + } + if (isPage.value) { + router.push({ name: 'conversation', params: { statusId: id } }) + } + setFocused(id) + const target = document.querySelector(`.Status[data-status-id=${id}]`) + await nextTick() + target.scrollIntoView({ behavior: 'smooth', block: 'center' }) + } + const { statusId } = toRefs(props) const router = useRouter() @@ -105,6 +118,7 @@ export default { } provide('isExpanded', isExpanded) provide('isPage', isPage) + provide('expandable', true) // # Focus const focusedId = ref(statusId.value) @@ -133,12 +147,13 @@ export default { } = useConversation(focusedId, isExpanded) watch(expanded, (value) => { + tryScrollTo(currentStatus.value.id) if (value) { fetchConversation() } else { resetDisplayState() } - }) + }, { flush: 'post' }) const resetDisplayState = () => { setFocused(statusId.value) @@ -181,7 +196,7 @@ export default { heightChart: heightChartLinear, changeSuspendState: changeSuspendStateLinear, updateVirtualHeight: updateVirtualHeightLinear, - } = useVirtualScrolling(conversation, linearElement) + } = useVirtualScrolling(conversation, linearElement, currentStatus) // # Tree style stuff const isTreeView = computed(() => displayStyle.value === 'tree') @@ -205,9 +220,10 @@ export default { const currentLevelElement = useTemplateRef('currentLevel') const { heightChart: heightChartCurrentLevel, + totalHeight: totalHeightCurrentLevel, changeSuspendState: changeSuspendStateCurrentLevel, updateVirtualHeight: updateVirtualHeightCurrentLevel, - } = useVirtualScrolling(currentLevel, currentLevelElement) + } = useVirtualScrolling(currentLevel, currentLevelElement, currentStatus) const treeViewIsSimple = computed( () => !mergedConfig.value.conversationTreeAdvanced, @@ -223,32 +239,6 @@ export default { ) // # Scrolling - const tryScrollTo = (id) => { - if (!id) { - return - } - if (isPage.value) { - router.push({ name: 'conversation', params: { statusId: id } }) - } - // Because the conversation can be unmounted when out of sight - // and mounted again when it comes into sight, - // the `mounted` or `created` function in `status` should not - // contain scrolling calls, as we do not want the page to jump - // when we scroll with an expanded conversation. - // - // Now the method is to rely solely on the `focused` watcher - // in `status` components. - // In linear views, all statuses are rendered at all times, but - // in tree views, it is possible that a change in active status - // removes and adds status components (e.g. an originally child - // status becomes an ancestor status, and thus they will be - // different). - // Here, let the components be rendered first, in order to trigger - // the `focused` watcher. - nextTick(() => { - setFocused(id) - }) - } const diveIntoStatus = (id) => { tryScrollTo(id) } @@ -261,6 +251,11 @@ export default { loadError, mobileLayout, + // # Conversation Expansion + isPage, + isExpanded, + toggleExpanded, + // # Focus focused, setFocused, @@ -270,11 +265,6 @@ export default { currentStatus, getReplies, - // # Conversation Expansion - isPage, - isExpanded, - toggleExpanded, - // # Misc UI things getStatusClasses, diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue index 6c3421033..3a61decf5 100644 --- a/src/components/conversation/conversation.vue +++ b/src/components/conversation/conversation.vue @@ -106,6 +106,7 @@ :focused="focused === element.status.id" conversation-rank="ancestor" + :data-status-id="element.id" @goto="setFocused" @dive="diveIntoStatus(element.status.id)" @@ -165,6 +166,7 @@ :focused="focused === element.id || focused === element.status.retweeted_status?.id" + :data-status-id="element.id" @goto="setFocused" @toggle-expanded="toggleExpanded" @suspendable-state-change="changeSuspendStateLinear" diff --git a/src/components/status/status.js b/src/components/status/status.js index 92c887386..7b4649b6a 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -121,19 +121,15 @@ const Status = { ], inject: { profileUserId: { - type: String, default: null, }, isPage: { - type: Boolean, default: false, }, isExpanded: { - type: Boolean, default: false, }, expandable: { - type: Boolean, default: false, }, }, diff --git a/src/components/status/status.vue b/src/components/status/status.vue index 2adbf5d41..c0a1b0238 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -199,7 +199,7 @@ />