appview-less bluesky client
24
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix initial loading on timelines

dawn 3579176e 740f9836

+19 -10
+3 -2
src/components/FollowingTimelineView.svelte
··· 10 10 accountPreferences, 11 11 fetchInteractionsToFollowingTimelineEnd, 12 12 follows, 13 - followingCursors 13 + followingCursors, 14 + initialDone 14 15 } from '$lib/state.svelte'; 15 16 import { buildThreads, filterThreads } from '$lib/thread'; 16 17 import type { Did } from '@atcute/lexicons/syntax'; ··· 121 122 bind:postComposerState 122 123 class={className} 123 124 isLoggedIn={!!(userDid || $accounts.length > 0)} 124 - canLoad={!!(client && userDid)} 125 + canLoad={!!(client && userDid && initialDone.has(userDid))} 125 126 onLoadMore={loadMore} 126 127 {isComplete} 127 128 />
+14 -8
src/components/GenericTimelineView.svelte
··· 2 2 import BskyPost from './BskyPost.svelte'; 3 3 import { type State as PostComposerState } from './PostComposer.svelte'; 4 4 import { AtpClient } from '$lib/at/client.svelte'; 5 - import { accounts } from '$lib/accounts'; 6 5 import { type ResourceUri } from '@atcute/lexicons'; 7 6 import { SvelteSet } from 'svelte/reactivity'; 8 7 import { InfiniteLoader, LoaderState } from 'svelte-infinite'; 9 8 import Icon from '@iconify/svelte'; 10 9 import { type ThreadPost, type Thread } from '$lib/thread'; 11 - import type { Did } from '@atcute/lexicons/syntax'; 12 10 import NotLoggedIn from './NotLoggedIn.svelte'; 13 11 import LoadingSpinner from './LoadingSpinner.svelte'; 14 12 import EndOfList from './EndOfList.svelte'; 15 13 import LoadError from './LoadError.svelte'; 16 14 import LoadNewPosts from './LoadNewPosts.svelte'; 15 + import { onMount } from 'svelte'; 16 + import { initialDone } from '$lib/state.svelte'; 17 17 18 18 interface Props { 19 19 client?: AtpClient | null; ··· 37 37 isComplete = false 38 38 }: Props = $props(); 39 39 40 - // Default canLoad to isLoggedIn if not provided, for backward compatibility/simpler usage 41 40 const shouldLoad = $derived(canLoad ?? isLoggedIn); 42 41 43 42 let reverseChronological = $state(true); ··· 53 52 54 53 $effect(() => { 55 54 if (threads.length > 0) { 56 - if (isAtTop) { 57 - boundaryTime = threads[0].newestTime; 58 - } else if (boundaryTime === null) { 59 - boundaryTime = threads[0].newestTime; 60 - } 55 + if (isAtTop) boundaryTime = threads[0].newestTime; 56 + else if (boundaryTime === null) boundaryTime = threads[0].newestTime; 61 57 } 62 58 }); 63 59 ··· 95 91 $effect(() => { 96 92 const isEmpty = threads.length < 15; 97 93 if (isEmpty && !loading && shouldLoad && !isComplete) loadMore(); 94 + }); 95 + 96 + $effect(() => { 97 + if (!initialDone.has(client?.user?.did ?? 'did:plc:invalid')) { 98 + loading = true; 99 + loaderState.status = 'LOADING'; 100 + } else { 101 + loading = false; 102 + loaderState.loaded(); 103 + } 98 104 }); 99 105 </script> 100 106
+2
src/lib/state.svelte.ts
··· 967 967 ); 968 968 }; 969 969 970 + export const initialDone = new SvelteSet<Did>(); 970 971 export const fetchInitial = async (account: Account) => { 971 972 const client = clients.get(account.did)!; 972 973 await Promise.all([ ··· 976 977 Promise.all(follows.map((follow) => fetchForInteractions(client, follow.subject)) ?? []) 977 978 ) 978 979 ]); 980 + initialDone.add(account.did); 979 981 }; 980 982 981 983 export const handleJetstreamEvent = async (event: JetstreamEvent) => {