This repository has no description
0

Configure Feed

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

core / web / src / lib / components / profile / tabs / PeopleTab.svelte
2.1 kB 77 lines
1<script lang="ts"> 2 import { untrack } from "svelte"; 3 import { getAuth } from "$lib/auth.svelte"; 4 import { createBobbinClient } from "$lib/api/client"; 5 import { IdentityCache } from "$lib/api/identity"; 6 import FollowCard from "../FollowCard.svelte"; 7 import Section from "$lib/components/ui/Section.svelte"; 8 import Pagination from "$lib/components/ui/Pagination.svelte"; 9 import Error from "$lib/components/ui/Error.svelte"; 10 import { createCursorPager, pageCount } from "../pagination.svelte"; 11 import { PROFILE_PAGE_LIMIT, fetchPeoplePage } from "../pages"; 12 import type { PersonData } from "../types"; 13 14 interface Props { 15 initial: PersonData[]; 16 cursor?: string; 17 total: number; 18 did: string; 19 direction: "followers" | "following"; 20 title: string; 21 emptyMessage: string; 22 } 23 24 let { 25 initial, 26 cursor: initialCursor, 27 total, 28 did, 29 direction, 30 title, 31 emptyMessage 32 }: Props = $props(); 33 34 const auth = getAuth(); 35 36 // shared across pages so repeat dids only resolve once 37 let identityCache: IdentityCache | undefined; 38 const pager = createCursorPager( 39 { items: untrack(() => initial), cursor: untrack(() => initialCursor) }, 40 (cursor) => { 41 const ctx = createBobbinClient({ serviceUrl: auth.bobbinUrl }); 42 identityCache ??= new IdentityCache(ctx); 43 return fetchPeoplePage(ctx, { 44 did, 45 viewerDid: auth.currentDid ?? undefined, 46 direction, 47 cursor, 48 cache: identityCache 49 }); 50 } 51 ); 52 const people = $derived(pager.items); 53 const pages = $derived(pageCount(total, PROFILE_PAGE_LIMIT)); 54</script> 55 56<Section {title} empty={people.length === 0} {emptyMessage} listClass="flex flex-col gap-8"> 57 {#each people as person (person.did)} 58 <FollowCard {person} /> 59 {/each} 60 {#snippet footer()} 61 {#if pages > 1} 62 <div class="mt-4 flex justify-center"> 63 <Pagination 64 page={pager.state.page} 65 total={pages} 66 labels 67 disabled={pager.state.kind === "loading"} 68 onchange={pager.select} 69 class="gap-5" 70 /> 71 </div> 72 {/if} 73 {#if pager.state.kind === "failed"} 74 <Error label="couldn't load that page. try again." class="mt-2" /> 75 {/if} 76 {/snippet} 77</Section>