tangled
alpha
login
or
join now
leaflet.pub
/
leaflet
289
fork
atom
a tool for shared writing and social publishing
289
fork
atom
overview
issues
29
pulls
pipelines
hydrate mentions with @handles
awarm.space
3 months ago
ba23a8aa
5895efe1
+29
-1
2 changed files
expand all
collapse all
unified
split
app
(home-pages)
notifications
MentionNotification.tsx
src
notifications.ts
+3
-1
app/(home-pages)/notifications/MentionNotification.tsx
···
21
21
let mentionedDocRecord = props.mentionedDocument
22
22
?.data as PubLeafletDocument.Record;
23
23
24
24
-
let mentioner = "placeholder";
24
24
+
const mentioner = props.documentCreatorHandle
25
25
+
? `@${props.documentCreatorHandle}`
26
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
5
+
import { AtUri } from "@atproto/syntax";
6
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
196
+
// Extract unique DIDs from document URIs to resolve handles
197
197
+
const documentCreatorDids = [...new Set(documentUris.map((uri) => new AtUri(uri).host))];
198
198
+
199
199
+
// Resolve DIDs to handles in parallel
200
200
+
const didToHandleMap = new Map<string, string | null>();
201
201
+
await Promise.all(
202
202
+
documentCreatorDids.map(async (did) => {
203
203
+
try {
204
204
+
const resolved = await idResolver.did.resolve(did);
205
205
+
const handle = resolved?.alsoKnownAs?.[0]
206
206
+
? resolved.alsoKnownAs[0].slice(5) // Remove "at://" prefix
207
207
+
: null;
208
208
+
didToHandleMap.set(did, handle);
209
209
+
} catch (error) {
210
210
+
console.error(`Failed to resolve DID ${did}:`, error);
211
211
+
didToHandleMap.set(did, null);
212
212
+
}
213
213
+
}),
214
214
+
);
215
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
245
+
const documentCreatorDid = new AtUri(notification.data.document_uri).host;
246
246
+
const documentCreatorHandle = didToHandleMap.get(documentCreatorDid) ?? null;
247
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
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
};