1import { Client, simpleFetchHandler } from "@atcute/client";
2import { createResource, createSignal, For, Show } from "solid-js";
3import { Button } from "../components/button";
4
5const LIMIT = 1000;
6
7const BlobView = (props: { pds: string; repo: string }) => {
8 const [cursor, setCursor] = createSignal<string>();
9 let rpc: Client;
10
11 const fetchBlobs = async () => {
12 if (!rpc) rpc = new Client({ handler: simpleFetchHandler({ service: props.pds }) });
13 const res = await rpc.get("com.atproto.sync.listBlobs", {
14 params: {
15 did: props.repo as `did:${string}:${string}`,
16 limit: LIMIT,
17 cursor: cursor(),
18 },
19 });
20 if (!res.ok) throw new Error(res.data.error);
21 if (!res.data.cids) return [];
22 setCursor(res.data.cids.length < LIMIT ? undefined : res.data.cursor);
23 setBlobs(blobs()?.concat(res.data.cids) ?? res.data.cids);
24 return res.data.cids;
25 };
26
27 const [response, { refetch }] = createResource(fetchBlobs);
28 const [blobs, setBlobs] = createSignal<string[]>();
29
30 return (
31 <div class="flex flex-col items-center gap-2">
32 <Show when={blobs() || response()}>
33 <div class="flex w-full flex-col gap-0.5 font-mono text-xs wrap-anywhere">
34 <For each={blobs()}>
35 {(cid) => (
36 <a
37 href={`${props.pds}/xrpc/com.atproto.sync.getBlob?did=${props.repo}&cid=${cid}`}
38 target="_blank"
39 class="w-fit rounded px-0.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
40 >
41 <span class="text-blue-400">{cid}</span>
42 </a>
43 )}
44 </For>
45 </div>
46 </Show>
47 <div class="dark:bg-dark-500 fixed bottom-0 z-5 flex w-screen justify-center bg-neutral-100 py-2">
48 <div class="flex flex-col items-center gap-1 pb-2">
49 <p>
50 {blobs()?.length} blob{(blobs()?.length ?? 0 > 1) ? "s" : ""}
51 </p>
52 <Show when={!response.loading && cursor()}>
53 <Button onClick={() => refetch()}>Load More</Button>
54 </Show>
55 <Show when={response.loading}>
56 <span class="iconify lucide--loader-circle animate-spin py-3.5 text-xl"></span>
57 </Show>
58 </div>
59 </div>
60 </div>
61 );
62};
63
64export { BlobView };