focusedId shenanigans

This commit is contained in:
Henry Jameson 2026-09-16 03:06:29 +03:00
commit c4b3eff348
3 changed files with 37 additions and 46 deletions

View file

@ -102,7 +102,6 @@ export default {
// # Main things
const {
focusedId,
focusedIdRaw,
conversationId,
setFocused,
currentStatus,
@ -321,8 +320,8 @@ export default {
}
const diveIntoStatus = (id) => scrollTo(new Set([id]))
const diveToTopLevel = () => scrollTo(new Set([currentAncestors.value[0].id]))
watch(focusedIdRaw, async (neu) => {
if (!isPage.value) return
watch(focusedId, async (neu, old) => {
if (neu) scrollTo(new Set([neu]))
})

View file

@ -1,5 +1,5 @@
import { storeToRefs } from 'pinia'
import { computed, provide, ref, watch } from 'vue'
import { computed, provide, ref, watch, nextTick } from 'vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useOAuthStore } from 'src/stores/oauth.js'
@ -28,49 +28,12 @@ export function useConversation(statusId, expanded) {
mastoUserSocketStatus === WSConnectionStatus.JOINED,
)
// # Focus
const focused = ref(null)
const { mainStatus: focusedStatus } = useMainStatus(focused)
const setFocused = (id) => {
focused.value = id
}
watch(mainStatusId, (val) => setFocused(val))
const focusedId = computed(() => expanded.value ? focusedStatus.value?.id : null)
provide('focusedId', focusedId)
watch(statusId, (neu, old) => {
if (neu) setFocused(neu)
}, { immediate: true })
watch(statusId, (neu, old) => {
if (neu !== old) {
fetchConversation()
}
})
watch(
expanded,
(value) => {
setFocused(value ? mainStatusId.value : null)
},
{ immediate: true },
)
watch(
focusedStatus,
(newVal, oldVal) => {
if (!newVal) return
if (newVal?.id === oldVal?.id) return // prevents infinite loop
if (!streamingEnabled.value) {
useStatusesStore().fetchStatus(newVal.id)
}
useStatusesStore().fetchFavsAndRepeats(newVal.id)
useStatusesStore().fetchEmojiReactions(newVal.id)
},
{ immediate: true },
)
const sortById = (a, b) => {
const idA = a.type === 'retweet' ? a.retweeted_status.id : a.id
const idB = b.type === 'retweet' ? b.retweeted_status.id : b.id
@ -89,9 +52,13 @@ export function useConversation(statusId, expanded) {
}
}
const fullConversation = ref(new Set([currentStatus.value?.id].filter(Boolean)))
const fullyLoaded = ref(false)
const conversationId = computed(
() => mainStatus.value?.statusnet_conversation_id,
)
watch(conversationId, (neu, old) => {
if (neu !== old) fullyLoaded.value = false
})
const conversation = computed(() => {
if (!currentStatus.value) {
return []
@ -101,13 +68,12 @@ export function useConversation(statusId, expanded) {
return [currentStatus.value]
}
const conversation = fullConversation.value
return [...conversation.keys()]
return [...fullConversation.value.keys()]
.map((k) => useStatusesStore().allStatuses.get(k))
.filter((status) => status.type != 'repeat') // Old backend behavior?
.toSorted(sortById)
})
const replies = computed(() =>
conversation.value.reduce(
(result, { id, in_reply_to_status_id: irid }, index) => {
@ -151,6 +117,8 @@ export function useConversation(statusId, expanded) {
...descendants
].map(({ id }) => id))
await nextTick()
fullyLoaded.value = true
} else {
try {
loadError.value = null
@ -172,9 +140,34 @@ export function useConversation(statusId, expanded) {
}
}
// # Focus
const focused = ref(null)
const { mainStatus: focusedStatus } = useMainStatus(focused)
const setFocused = (id) => {
focused.value = id
}
watch(statusId, (val) => setFocused(val), { immediate: true })
const focusedId = computed(() => (expanded.value && fullyLoaded.value) ? focusedStatus.value?.id : null)
provide('focusedId', focusedId)
watch(
focusedStatus,
(newVal, oldVal) => {
if (!newVal) return
if (newVal?.id === oldVal?.id) return // prevents infinite loop
if (!streamingEnabled.value) {
useStatusesStore().fetchStatus(newVal.id)
}
useStatusesStore().fetchFavsAndRepeats(newVal.id)
useStatusesStore().fetchEmojiReactions(newVal.id)
},
{ immediate: true },
)
return {
focusedId,
focusedIdRaw: focused,
conversationId,
setFocused,
currentStatus,

View file

@ -297,7 +297,6 @@ export function useVirtualScrolling({
const elementMiddle = element.top + element.height / 2
const desiredTopBoundary = Math.min(element.top, elementMiddle - (windowHeight.value - offset.value) / 2)
console.log(element, desiredTopBoundary, topScrollBoundary.value)
scrollBy(0, desiredTopBoundary - topScrollBoundary.value)
resumeWatchers()