appview-less bluesky client
24
fork

Configure Feed

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

at main 103 lines 2.6 kB view raw
1<script lang="ts"> 2 import { type State as PostComposerState } from './PostComposer.svelte'; 3 import { AtpClient } from '$lib/at/client.svelte'; 4 import { accounts } from '$lib/accounts'; 5 import { 6 postCursors, 7 fetchTimeline, 8 allPosts, 9 timelines, 10 fetchInteractionsToTimelineEnd, 11 accountPreferences 12 } from '$lib/state.svelte'; 13 import { buildThreadsFiltered } from '$lib/thread'; 14 import type { Did } from '@atcute/lexicons/syntax'; 15 import GenericTimelineView from './GenericTimelineView.svelte'; 16 17 interface Props { 18 client?: AtpClient | null; 19 targetDid?: Did; 20 postComposerState: PostComposerState; 21 class?: string; 22 showReplies?: boolean; 23 } 24 25 let { 26 client = null, 27 targetDid = undefined, 28 showReplies = true, 29 postComposerState = $bindable(), 30 class: className = '' 31 }: Props = $props(); 32 33 let viewOwnPosts = $state(true); 34 let displayCount = $state(10); 35 36 const userDid = $derived(client?.user?.did); 37 const did = $derived(targetDid ?? userDid); 38 39 const currentPrefs = $derived(userDid ? accountPreferences.get(userDid) : null); 40 const mutes = $derived(new Set(currentPrefs?.mutes ?? [])); 41 42 const threads = $derived( 43 did && timelines.has(did) 44 ? buildThreadsFiltered( 45 did, 46 timelines.get(did)!, 47 allPosts, 48 mutes, 49 $accounts, 50 { viewOwnPosts }, 51 displayCount 52 ) 53 : [] 54 ); 55 56 let fetchingInteractions = $state(false); 57 let scheduledFetchInteractions = $state(false); 58 59 const loadMore = async () => { 60 if (!client || !userDid || !did) return; 61 62 await fetchTimeline(client, did, 7, showReplies, { 63 downwards: userDid === did ? 'sameAuthor' : 'none' 64 }); 65 if (client.user && userDid) { 66 if (!fetchingInteractions) { 67 scheduledFetchInteractions = false; 68 fetchingInteractions = true; 69 await fetchInteractionsToTimelineEnd(client, userDid, did); 70 fetchingInteractions = false; 71 } else { 72 scheduledFetchInteractions = true; 73 } 74 } 75 }; 76 77 $effect(() => { 78 if (client && scheduledFetchInteractions && userDid && did && did !== userDid) { 79 if (!fetchingInteractions) { 80 scheduledFetchInteractions = false; 81 fetchingInteractions = true; 82 fetchInteractionsToTimelineEnd(client, userDid, did).finally( 83 () => (fetchingInteractions = false) 84 ); 85 } else { 86 scheduledFetchInteractions = true; 87 } 88 } 89 }); 90</script> 91 92<GenericTimelineView 93 {client} 94 {threads} 95 timelineId={`replies:${did}`} 96 bind:postComposerState 97 bind:displayCount 98 class={className} 99 isLoggedIn={!!(did || $accounts.length > 0)} 100 canLoad={!!(client && userDid && did)} 101 onLoadMore={loadMore} 102 isComplete={did ? postCursors.get(did)?.end : false} 103/>