fix: Streams slowing down page loads or not loading at all (#620)

zio/stable
Jacob Hands 2022-12-28 15:43:46 -06:00 committed by GitHub
parent e9b1f17235
commit b6f0bd356a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 62 additions and 47 deletions

View File

@ -15,7 +15,7 @@ const {
paginator: Paginator<any, any[]> paginator: Paginator<any, any[]>
keyProp?: string keyProp?: string
virtualScroller?: boolean virtualScroller?: boolean
stream?: WsEvents stream?: Promise<WsEvents>
eventType?: 'notification' | 'update' eventType?: 'notification' | 'update'
preprocess?: (items: any[]) => any[] preprocess?: (items: any[]) => any[]
}>() }>()

View File

@ -4,7 +4,7 @@ import type { GroupedAccountLike, NotificationSlot } from '~/types'
const { paginator, stream } = defineProps<{ const { paginator, stream } = defineProps<{
paginator: Paginator<any, Notification[]> paginator: Paginator<any, Notification[]>
stream?: WsEvents stream?: Promise<WsEvents>
}>() }>()
const groupCapacity = Number.MAX_VALUE // No limit const groupCapacity = Number.MAX_VALUE // No limit

View File

@ -1,8 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import type { Status } from 'masto' import type { Status } from 'masto'
const paginator = useMasto().timelines.iterateHome() const paginator = useMasto().timelines.iterateHome()
const stream = await useMasto().stream.streamUser() const stream = useMasto().stream.streamUser()
onBeforeUnmount(() => stream.disconnect()) onBeforeUnmount(() => stream?.then(s => s.disconnect()))
const maxDistance = 10 const maxDistance = 10
function preprocess(items: Status[]) { function preprocess(items: Status[]) {

View File

@ -5,7 +5,7 @@ const paginator = useMasto().notifications.iterate({ limit: 30, types: ['mention
const { clearNotifications } = useNotifications() const { clearNotifications } = useNotifications()
onActivated(clearNotifications) onActivated(clearNotifications)
const stream = await useMasto().stream.streamUser() const stream = useMasto().stream.streamUser()
</script> </script>
<template> <template>

View File

@ -5,7 +5,7 @@ const paginator = useMasto().notifications.iterate({ limit: 30 })
const { clearNotifications } = useNotifications() const { clearNotifications } = useNotifications()
onActivated(clearNotifications) onActivated(clearNotifications)
const stream = await useMasto().stream.streamUser() const stream = useMasto().stream.streamUser()
</script> </script>
<template> <template>

View File

@ -6,7 +6,7 @@ import type { FilterContext, Paginator, Status, WsEvents } from 'masto'
const { paginator, stream } = defineProps<{ const { paginator, stream } = defineProps<{
paginator: Paginator<any, Status[]> paginator: Paginator<any, Status[]>
stream?: WsEvents stream?: Promise<WsEvents>
context?: FilterContext context?: FilterContext
preprocess?: (items: any[]) => any[] preprocess?: (items: any[]) => any[]
}>() }>()

View File

@ -0,0 +1,11 @@
<script setup lang="ts">
const paginator = useMasto().timelines.iteratePublic()
const stream = useMasto().stream.streamPublicTimeline()
onBeforeUnmount(() => stream.then(s => s.disconnect()))
</script>
<template>
<div>
<TimelinePaginator v-bind="{ paginator, stream }" context="public" />
</div>
</template>

View File

@ -0,0 +1,11 @@
<script setup lang="ts">
const paginator = useMasto().timelines.iteratePublic({ local: true })
const stream = useMasto().stream.streamCommunityTimeline()
onBeforeUnmount(() => stream.then(s => s.disconnect()))
</script>
<template>
<div>
<TimelinePaginator v-bind="{ paginator, stream }" context="public" />
</div>
</template>

View File

@ -4,7 +4,7 @@ import type { PaginatorState } from '~/types'
export function usePaginator<T>( export function usePaginator<T>(
paginator: Paginator<any, T[]>, paginator: Paginator<any, T[]>,
stream?: WsEvents, stream?: Promise<WsEvents>,
eventType: 'notification' | 'update' = 'update', eventType: 'notification' | 'update' = 'update',
preprocess: (items: T[]) => T[] = (items: T[]) => items, preprocess: (items: T[]) => T[] = (items: T[]) => items,
) { ) {
@ -24,32 +24,34 @@ export function usePaginator<T>(
prevItems.value = [] prevItems.value = []
} }
stream?.on(eventType, (status) => { stream?.then((s) => {
if ('uri' in status) s.on(eventType, (status) => {
if ('uri' in status)
cacheStatus(status, undefined, true)
const index = prevItems.value.findIndex((i: any) => i.id === status.id)
if (index >= 0)
prevItems.value.splice(index, 1)
prevItems.value.unshift(status as any)
})
// TODO: update statuses
s.on('status.update', (status) => {
cacheStatus(status, undefined, true) cacheStatus(status, undefined, true)
const index = prevItems.value.findIndex((i: any) => i.id === status.id) const index = items.value.findIndex((s: any) => s.id === status.id)
if (index >= 0) if (index >= 0)
prevItems.value.splice(index, 1) items.value[index] = status as any
})
prevItems.value.unshift(status as any) s.on('delete', (id) => {
}) removeCachedStatus(id)
// TODO: update statuses const index = items.value.findIndex((s: any) => s.id === id)
stream?.on('status.update', (status) => { if (index >= 0)
cacheStatus(status, undefined, true) items.value.splice(index, 1)
})
const index = items.value.findIndex((s: any) => s.id === status.id)
if (index >= 0)
items.value[index] = status as any
})
stream?.on('delete', (id) => {
removeCachedStatus(id)
const index = items.value.findIndex((s: any) => s.id === id)
if (index >= 0)
items.value.splice(index, 1)
}) })
async function loadNext() { async function loadNext() {
@ -95,9 +97,9 @@ export function usePaginator<T>(
() => { () => {
if ( if (
isInScreen isInScreen
&& state.value === 'idle' && state.value === 'idle'
// No new content is loaded when the keepAlive page enters the background // No new content is loaded when the keepAlive page enters the background
&& deactivated.value === false && deactivated.value === false
) )
loadNext() loadNext()
}, },

View File

@ -1,7 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
const paginator = useMasto().timelines.iteratePublic()
const stream = await useMasto().stream.streamPublicTimeline()
onBeforeUnmount(() => stream.disconnect())
const { t } = useI18n() const { t } = useI18n()
@ -19,8 +17,6 @@ useHeadFixed({
</NuxtLink> </NuxtLink>
</template> </template>
<slot> <TimelinePublic v-if="isMastoInitialised" />
<TimelinePaginator v-bind="{ paginator, stream }" context="public" />
</slot>
</MainContent> </MainContent>
</template> </template>

View File

@ -1,7 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
const paginator = useMasto().timelines.iteratePublic({ local: true })
const stream = await useMasto().stream.streamCommunityTimeline()
onBeforeUnmount(() => stream.disconnect())
const { t } = useI18n() const { t } = useI18n()
@ -19,8 +16,6 @@ useHeadFixed({
</NuxtLink> </NuxtLink>
</template> </template>
<slot> <TimelinePublicLocal v-if="isMastoInitialised" />
<TimelinePaginator v-bind="{ paginator, stream }" context="public" />
</slot>
</MainContent> </MainContent>
</template> </template>

View File

@ -6,8 +6,8 @@ const masto = useMasto()
const { data: tag, refresh } = $(await useAsyncData(() => masto.tags.fetch(tagName), { watch: [isMastoInitialised], immediate: isMastoInitialised.value })) const { data: tag, refresh } = $(await useAsyncData(() => masto.tags.fetch(tagName), { watch: [isMastoInitialised], immediate: isMastoInitialised.value }))
const paginator = masto.timelines.iterateHashtag(tagName) const paginator = masto.timelines.iterateHashtag(tagName)
const stream = await masto.stream.streamTagTimeline(tagName) const stream = masto.stream.streamTagTimeline(tagName)
onBeforeUnmount(() => stream.disconnect()) onBeforeUnmount(() => stream.then(s => s.disconnect()))
if (tag) { if (tag) {
useHeadFixed({ useHeadFixed({