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