This repository has no description
1<script lang="ts">
2 import { untrack } from "svelte";
3 import { resolve } from "$app/paths";
4 import { getAuth } from "$lib/auth.svelte";
5 import { createBobbinClient } from "$lib/api/client";
6 import { IdentityCache } from "$lib/api/identity";
7 import { fetchStarredPage } from "../pages";
8 import RepoCard from "$lib/components/repo/RepoCard.svelte";
9 import Card from "$lib/components/ui/Card.svelte";
10 import Section from "$lib/components/ui/Section.svelte";
11 import LoadMore from "$lib/components/ui/LoadMore.svelte";
12 import type { StarData } from "../types";
13
14 interface Props {
15 initial: StarData[];
16 cursor?: string;
17 did: string;
18 }
19
20 let { initial, cursor: initialCursor, did }: Props = $props();
21
22 const auth = getAuth();
23
24 let extra = $state<StarData[]>([]);
25 let cursor = $state(untrack(() => initialCursor));
26 let loading = $state(false);
27 let failed = $state(false);
28 // shared across pages so repeat repo owners only resolve once
29 let identityCache: IdentityCache | undefined;
30
31 const stars = $derived([...initial, ...extra]);
32
33 const loadMore = async () => {
34 if (loading || !cursor) return;
35 loading = true;
36 failed = false;
37 try {
38 const ctx = createBobbinClient({ serviceUrl: auth.bobbinUrl });
39 identityCache ??= new IdentityCache(ctx);
40 const next = await fetchStarredPage(ctx, {
41 did,
42 viewerDid: auth.currentDid ?? undefined,
43 cursor,
44 cache: identityCache
45 });
46 extra = [...extra, ...next.items];
47 cursor = next.cursor;
48 } catch {
49 failed = true;
50 } finally {
51 loading = false;
52 }
53 };
54</script>
55
56<Section title="Starred" empty={stars.length === 0} emptyMessage="No stars yet.">
57 {#each stars as star (star.uri)}
58 {#if star.kind === "repo"}
59 <RepoCard repo={star.repo} />
60 {:else}
61 <Card shadow={false} class="flex items-center gap-2">
62 <a
63 href={resolve(`/${star.ownerHandle}/strings/${star.rkey}` as "/")}
64 class="truncate font-bold text-foreground-default no-underline hover:underline"
65 >
66 {star.ownerHandle}/{star.rkey}
67 </a>
68 </Card>
69 {/if}
70 {/each}
71 {#if cursor}
72 <LoadMore {loading} {failed} onclick={loadMore} />
73 {/if}
74</Section>