ATProto forum built with ESAV

fix replies

rimar1337 2d2089a7 22ccfe59

Changed files
+77 -5
src
routes
f
$forumHandle
t
$userHandle
+67 -4
src/routes/f/$forumHandle.tsx
··· 23 23 }; 24 24 }; 25 25 26 + type ResolvedForum = ForumDoc & { 27 + resolvedIdentity?: { 28 + handle: string; 29 + pdsUrl: string; 30 + }; 31 + }; 26 32 type ResolvedForumData = { 27 33 forumDoc: ForumDoc; 28 34 identity: ResolvedIdentity; ··· 74 80 }); 75 81 76 82 export const Route = createFileRoute("/f/$forumHandle")({ 77 - loader: ({ context: { queryClient }, params }) => 78 - queryClient.ensureQueryData( 79 - forumQueryOptions(queryClient, params.forumHandle) 80 - ), 83 + loader: async ({ context: { queryClient }, params }) => { 84 + const normalizedHandle = decodeURIComponent(params.forumHandle).replace(/^@/, ""); 85 + 86 + const identity = await queryClient.fetchQuery({ 87 + queryKey: ["identity", normalizedHandle], 88 + queryFn: () => resolveIdentity({ didOrHandle: normalizedHandle }), 89 + staleTime: 1000 * 60 * 60 * 24, 90 + }); 91 + 92 + if (!identity) { 93 + throw new Error(`Could not resolve forum handle: @${normalizedHandle}`); 94 + } 95 + 96 + const forums = queryClient.getQueryData<ResolvedForum[]>(["forums", "list"]); 97 + const forumFromList = forums?.find(f => f["$metadata.did"] === identity.did) 98 + 99 + const initialData: ResolvedForumData | undefined = forumFromList 100 + ? { 101 + forumDoc: forumFromList, 102 + identity: { 103 + handle: forumFromList.resolvedIdentity!.handle, 104 + did: forumFromList["$metadata.did"], 105 + pdsUrl: forumFromList.resolvedIdentity!.pdsUrl, 106 + bskyPds: false, 107 + }, 108 + } 109 + : undefined 110 + 111 + if (initialData) { 112 + return initialData; 113 + } 114 + 115 + // Fallback to direct fetch 116 + const forumRes = await esavQuery<{ 117 + hits: { hits: { _source: ForumDoc }[] }; 118 + }>({ 119 + query: { 120 + bool: { 121 + must: [ 122 + { term: { "$metadata.did": identity.did } }, 123 + { 124 + term: { 125 + "$metadata.collection": "com.example.ft.forum.definition", 126 + }, 127 + }, 128 + { term: { "$metadata.rkey": "self" } }, 129 + ], 130 + }, 131 + }, 132 + }); 133 + 134 + const forumDoc = forumRes.hits.hits[0]?._source; 135 + if (!forumDoc) { 136 + throw new Error("Forum definition not found."); 137 + } 138 + 139 + return { 140 + forumDoc, 141 + identity, 142 + }; 143 + }, 81 144 component: ForumHeader, 82 145 pendingComponent: ForumHeaderContentSkeleton, 83 146 errorComponent: ({ error }) => (
+10 -1
src/routes/f/$forumHandle/t/$userHandle/$topicRKey.tsx
··· 502 502 try { 503 503 const rootPost = posts[0]; 504 504 const parentPost = replyingTo || rootPost; 505 + const identity = await queryClient.fetchQuery({ 506 + queryKey: ["identity", forumHandle], 507 + queryFn: () => resolveIdentity({ didOrHandle: forumHandle }), 508 + staleTime: 1000 * 60 * 60 * 24, 509 + }); 510 + const forumDid = identity?.did; 511 + if (!forumDid) { 512 + throw new Error("Could not resolve forum handle to DID."); 513 + } 505 514 await agent.com.atproto.repo.createRecord({ 506 515 repo: agent.did, 507 516 collection: "com.example.ft.topic.post", 508 517 record: { 509 518 $type: "com.example.ft.topic.post", 510 519 text: replyText, 511 - forum: forumHandle, 520 + forum: forumDid, 512 521 reply: { 513 522 root: { 514 523 uri: rootPost["$metadata.uri"],