Retro Bulletin Board Systems on atproto. Web app and TUI.
lazy mirror of alyraffauf/atbbs
atbbs.xyz
forums
python
tui
atproto
bbs
1/** Fetch the user's own root posts (threads) across all BBSes. */
2
3import { listRecords, resolveIdentitiesBatch } from "./atproto";
4import { POST } from "./lexicon";
5import { parseAtUri } from "./util";
6import { isPostRecord } from "./recordGuards";
7
8export interface MyThread {
9 uri: string;
10 rkey: string;
11 title: string;
12 body: string;
13 createdAt: string;
14 bbsDid: string;
15 bbsHandle: string;
16}
17
18export async function fetchMyThreads(
19 pdsUrl: string,
20 did: string,
21): Promise<MyThread[]> {
22 const records = await listRecords(pdsUrl, did, POST);
23 const rootPosts = records
24 .filter(isPostRecord)
25 .filter((record) => !record.value.root && record.value.title);
26 if (!rootPosts.length) return [];
27
28 const bbsDids = new Set(
29 rootPosts.map((record) => parseAtUri(record.value.scope).did),
30 );
31 const identities = await resolveIdentitiesBatch([...bbsDids]);
32
33 const results: MyThread[] = [];
34 for (const record of rootPosts) {
35 const bbsDid = parseAtUri(record.value.scope).did;
36 const identity = identities[bbsDid];
37 if (!identity) continue;
38 results.push({
39 uri: record.uri,
40 rkey: parseAtUri(record.uri).rkey,
41 title: record.value.title ?? "",
42 body: record.value.body,
43 createdAt: record.value.createdAt,
44 bbsDid,
45 bbsHandle: identity.handle,
46 });
47 }
48 results.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
49 return results;
50}