a tool for shared writing and social publishing

hydrate mentions with @handles

+29 -1
+3 -1
app/(home-pages)/notifications/MentionNotification.tsx
··· 21 21 let mentionedDocRecord = props.mentionedDocument 22 22 ?.data as PubLeafletDocument.Record; 23 23 24 - let mentioner = "placeholder"; 24 + const mentioner = props.documentCreatorHandle 25 + ? `@${props.documentCreatorHandle}` 26 + : "Someone"; 25 27 26 28 if (props.mention_type === "did") { 27 29 actionText = <>{mentioner} mentioned you</>;
+26
src/notifications.ts
··· 2 2 3 3 import { supabaseServerClient } from "supabase/serverClient"; 4 4 import { Tables, TablesInsert } from "supabase/database.types"; 5 + import { AtUri } from "@atproto/syntax"; 6 + import { idResolver } from "app/(home-pages)/reader/idResolver"; 5 7 6 8 type NotificationRow = Tables<"notifications">; 7 9 ··· 191 193 .select("*, documents_in_publications(publications(*))") 192 194 .in("uri", documentUris); 193 195 196 + // Extract unique DIDs from document URIs to resolve handles 197 + const documentCreatorDids = [...new Set(documentUris.map((uri) => new AtUri(uri).host))]; 198 + 199 + // Resolve DIDs to handles in parallel 200 + const didToHandleMap = new Map<string, string | null>(); 201 + await Promise.all( 202 + documentCreatorDids.map(async (did) => { 203 + try { 204 + const resolved = await idResolver.did.resolve(did); 205 + const handle = resolved?.alsoKnownAs?.[0] 206 + ? resolved.alsoKnownAs[0].slice(5) // Remove "at://" prefix 207 + : null; 208 + didToHandleMap.set(did, handle); 209 + } catch (error) { 210 + console.error(`Failed to resolve DID ${did}:`, error); 211 + didToHandleMap.set(did, null); 212 + } 213 + }), 214 + ); 215 + 194 216 // Fetch mentioned publications and documents 195 217 const mentionedPublicationUris = mentionNotifications 196 218 .filter((n) => n.data.mention_type === "publication") ··· 220 242 ? (notification.data as Extract<ExtractNotificationType<"mention">, { mentioned_uri: string }>).mentioned_uri 221 243 : undefined; 222 244 245 + const documentCreatorDid = new AtUri(notification.data.document_uri).host; 246 + const documentCreatorHandle = didToHandleMap.get(documentCreatorDid) ?? null; 247 + 223 248 return { 224 249 id: notification.id, 225 250 recipient: notification.recipient, ··· 229 254 mention_type: notification.data.mention_type, 230 255 mentioned_uri: mentionedUri, 231 256 document: documents?.find((d) => d.uri === notification.data.document_uri)!, 257 + documentCreatorHandle, 232 258 mentionedPublication: mentionedUri ? mentionedPublications?.find((p) => p.uri === mentionedUri) : undefined, 233 259 mentionedDocument: mentionedUri ? mentionedDocuments?.find((d) => d.uri === mentionedUri) : undefined, 234 260 };