import type { Infer } from "@char/lexicon.ts"; import type { VideoLexiconUniverse } from "../common/lexicons.ts"; import { resolveDid, resolveHandle } from "../common/identity.ts"; import { VIDEO_PATTERN } from "../common/routes.ts"; import type { ATProtoUniverse } from "@char/lexicon.ts/atproto"; import { XRPC } from "@char/lexicon.ts/rpc"; type VideoRecord = Infer; const fetchVideoRecord = async (did: string, rkey: string): Promise => { const didDoc = await resolveDid(did); const pds = didDoc.service?.find(it => it.id === "#atproto_pds")?.serviceEndpoint as | string | undefined; if (!pds) throw new Error("could not resolve pds for requested repo"); const xrpc = new XRPC(pds); const record = await xrpc.get("com.atproto.repo.getRecord", { params: { collection: "blue.cerulea.video.video", repo: did, rkey, }, }); // TODO: replace this cast with a lexicon.ts validation check return record.value as VideoRecord; }; const resolveVideoURL = async (repo: `did:${string}`, blob: string): Promise => { try { const xrpc = new XRPC(globalThis.location.href); const res = await xrpc.call("blue.cerulea.video.fetchVideo", { input: { repo, blob }, }); return `/user-content/${res.filename}`; } catch { throw new Error("got error fetching URL of video at CDN"); } }; const main = async () => { const player = document.querySelector("#player")! as HTMLElement; const location = VIDEO_PATTERN.exec(globalThis.location.href); if (!location) throw new Error("video pattern did not match url"); const { repo, rkey } = location.pathname.groups as { repo: string; rkey: string; }; const isDid = (s: string): s is `did:${string}` => s.startsWith("did:"); const did = isDid(repo) ? repo : await resolveHandle(repo); const record = await fetchVideoRecord(did, rkey); const videoURL = await resolveVideoURL( did, "ref" in record.video ? record.video.ref.$link : record.video.cid, ); const video = ( ) as HTMLVideoElement; video.volume = 0.8; player.append(video); if (record.title) { player.append(

{record.title}

); document.title = `${record.title} | video.cerulea.blue`; } if (record.description) player.append(

{record.description}

); }; main();