Retro Bulletin Board Systems on atproto. Web app and TUI.
lazy mirror of alyraffauf/atbbs
atbbs.xyz
forums
python
tui
atproto
bbs
1export function formatFullDate(iso: string): string {
2 const date = new Date(iso);
3 const pad = (num: number) => String(num).padStart(2, "0");
4 return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`;
5}
6
7export function relativeDate(iso: string): string {
8 const seconds = Math.floor((Date.now() - new Date(iso).getTime()) / 1000);
9 if (seconds < 60) return "just now";
10 if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;
11 if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;
12 if (seconds < 604800) return `${Math.floor(seconds / 86400)}d ago`;
13 return formatFullDate(iso);
14}
15
16/** ISO datetime branded so it's assignable to atcute's `datetimeString` types. */
17type IsoDatetime = `${number}-${number}-${number}T${string}`;
18
19export function nowIso(): IsoDatetime {
20 return new Date().toISOString() as IsoDatetime;
21}
22
23export function parseAtUri(uri: string): {
24 did: string;
25 collection: string;
26 rkey: string;
27} {
28 const parts = uri.split("/");
29 return { did: parts[2], collection: parts[3], rkey: parts[4] };
30}
31
32export function truncate(text: string, maxLength: number): string {
33 if (text.length <= maxLength) return text;
34 return text.substring(0, maxLength) + "...";
35}
36
37import type { Did } from "@atcute/lexicons/syntax";
38
39export function makeAtUri(
40 did: string,
41 collection: string,
42 rkey: string,
43): `at://${Did}/${string}/${string}` {
44 return `at://${did as Did}/${collection}/${rkey}`;
45}