From 3579176ecc18d44bb234d9d2cedaab5c40eb0ff3 Mon Sep 17 00:00:00 2001 From: dawn <90008@gaze.systems> Date: Wed, 21 Jan 2026 14:15:34 +0000 Subject: [PATCH] fix initial loading on timelines --- src/components/FollowingTimelineView.svelte | 5 +++-- src/components/GenericTimelineView.svelte | 22 ++++++++++++++-------- src/lib/state.svelte.ts | 2 ++ 3 file(s) changed, 19 insertion(s)(+), 10 deletion(s)(-) diff --git a/src/components/FollowingTimelineView.svelte b/src/components/FollowingTimelineView.svelte --- a/src/components/FollowingTimelineView.svelte +++ b/src/components/FollowingTimelineView.svelte @@ -10,7 +10,8 @@ accountPreferences, fetchInteractionsToFollowingTimelineEnd, follows, - followingCursors + followingCursors, + initialDone } from '$lib/state.svelte'; import { buildThreads, filterThreads } from '$lib/thread'; import type { Did } from '@atcute/lexicons/syntax'; @@ -121,7 +122,7 @@ bind:postComposerState class={className} isLoggedIn={!!(userDid || $accounts.length > 0)} - canLoad={!!(client && userDid)} + canLoad={!!(client && userDid && initialDone.has(userDid))} onLoadMore={loadMore} {isComplete} /> diff --git a/src/components/GenericTimelineView.svelte b/src/components/GenericTimelineView.svelte --- a/src/components/GenericTimelineView.svelte +++ b/src/components/GenericTimelineView.svelte @@ -2,18 +2,18 @@ import BskyPost from './BskyPost.svelte'; import { type State as PostComposerState } from './PostComposer.svelte'; import { AtpClient } from '$lib/at/client.svelte'; - import { accounts } from '$lib/accounts'; import { type ResourceUri } from '@atcute/lexicons'; import { SvelteSet } from 'svelte/reactivity'; import { InfiniteLoader, LoaderState } from 'svelte-infinite'; import Icon from '@iconify/svelte'; import { type ThreadPost, type Thread } from '$lib/thread'; - import type { Did } from '@atcute/lexicons/syntax'; import NotLoggedIn from './NotLoggedIn.svelte'; import LoadingSpinner from './LoadingSpinner.svelte'; import EndOfList from './EndOfList.svelte'; import LoadError from './LoadError.svelte'; import LoadNewPosts from './LoadNewPosts.svelte'; + import { onMount } from 'svelte'; + import { initialDone } from '$lib/state.svelte'; interface Props { client?: AtpClient | null; @@ -37,7 +37,6 @@ isComplete = false }: Props = $props(); - // Default canLoad to isLoggedIn if not provided, for backward compatibility/simpler usage const shouldLoad = $derived(canLoad ?? isLoggedIn); let reverseChronological = $state(true); @@ -53,11 +52,8 @@ $effect(() => { if (threads.length > 0) { - if (isAtTop) { - boundaryTime = threads[0].newestTime; - } else if (boundaryTime === null) { - boundaryTime = threads[0].newestTime; - } + if (isAtTop) boundaryTime = threads[0].newestTime; + else if (boundaryTime === null) boundaryTime = threads[0].newestTime; } }); @@ -95,6 +91,16 @@ $effect(() => { const isEmpty = threads.length < 15; if (isEmpty && !loading && shouldLoad && !isComplete) loadMore(); + }); + + $effect(() => { + if (!initialDone.has(client?.user?.did ?? 'did:plc:invalid')) { + loading = true; + loaderState.status = 'LOADING'; + } else { + loading = false; + loaderState.loaded(); + } }); diff --git a/src/lib/state.svelte.ts b/src/lib/state.svelte.ts --- a/src/lib/state.svelte.ts +++ b/src/lib/state.svelte.ts @@ -967,6 +967,7 @@ ); }; +export const initialDone = new SvelteSet(); export const fetchInitial = async (account: Account) => { const client = clients.get(account.did)!; await Promise.all([ @@ -976,6 +977,7 @@ Promise.all(follows.map((follow) => fetchForInteractions(client, follow.subject)) ?? []) ) ]); + initialDone.add(account.did); }; export const handleJetstreamEvent = async (event: JetstreamEvent) => { -- tangled.sh