atproto explorer pdsls.dev
atproto tool
at main 2.3 kB view raw
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 };