a tool for shared writing and social publishing
1import { AtUri } from "@atproto/api";
2
3/**
4 * Converts a DID to a Bluesky profile URL
5 */
6export function didToBlueskyUrl(did: string): string {
7 return `https://bsky.app/profile/${did}`;
8}
9
10/**
11 * Converts an AT URI (publication or document) to the appropriate URL
12 */
13export function atUriToUrl(atUri: string): string {
14 try {
15 const uri = new AtUri(atUri);
16
17 if (uri.collection === "pub.leaflet.publication") {
18 // Publication URL: /lish/{did}/{rkey}
19 return `/lish/${uri.host}/${uri.rkey}`;
20 } else if (uri.collection === "pub.leaflet.document") {
21 // Document URL - we need to resolve this via the API
22 // For now, create a redirect route that will handle it
23 return `/lish/uri/${encodeURIComponent(atUri)}`;
24 }
25
26 return "#";
27 } catch (e) {
28 console.error("Failed to parse AT URI:", atUri, e);
29 return "#";
30 }
31}
32
33/**
34 * Opens a mention link in the appropriate way
35 * - DID mentions open in a new tab (external Bluesky)
36 * - Publication/document mentions navigate in the same tab
37 */
38export function handleMentionClick(
39 e: MouseEvent | React.MouseEvent,
40 type: "did" | "at-uri",
41 value: string
42) {
43 e.preventDefault();
44 e.stopPropagation();
45
46 if (type === "did") {
47 // Open Bluesky profile in new tab
48 window.open(didToBlueskyUrl(value), "_blank", "noopener,noreferrer");
49 } else {
50 // Navigate to publication/document in same tab
51 const url = atUriToUrl(value);
52 if (url.startsWith("/lish/uri/")) {
53 // Redirect route - navigate to it
54 window.location.href = url;
55 } else {
56 window.location.href = url;
57 }
58 }
59}