diff --git a/web/src/routes/[handle]/+page.ts b/web/src/routes/[handle]/+page.ts --- a/web/src/routes/[handle]/+page.ts +++ b/web/src/routes/[handle]/+page.ts @@ -141,33 +141,39 @@ byDid.set( did, doc ? { - did: doc.did, - handle: doc.handle, - avatar: doc.avatar, - followers, - following, - isSelf, - viewerFollowRkey - } + did: doc.did, + handle: doc.handle, + avatar: doc.avatar, + followers, + following, + isSelf, + viewerFollowRkey + } : { did, handle: did, followers, following, isSelf, viewerFollowRkey } ); }); return unique.map((did) => byDid.get(did) as PersonData); }; -const resolveVouches = async (ctx: BobbinContext, items: ListItem[]): Promise => { +const resolveVouches = async ( + ctx: BobbinContext, + items: ListItem[], + direction: "incoming" | "outgoing" +): Promise => { const cache = new IdentityCache(ctx); return Promise.all( items.map(async (item): Promise => { const value = item.value as VouchRecord; - const voucher = didFromUri(item.uri); - const doc = await cache.resolve(voucher).catch(() => null); + const otherDid = + direction === "incoming" ? didFromUri(item.uri) : rkeyFromUri(item.uri); + const doc = await cache.resolve(otherDid).catch(() => null); return { uri: item.uri, - did: voucher, - handle: doc?.handle ?? voucher, + did: otherDid, + handle: doc?.handle ?? otherDid, avatar: doc?.avatar, kind: value.kind === "denounce" ? "denounce" : "vouch", + direction, reason: value.reason, createdAt: value.createdAt }; @@ -234,11 +240,11 @@ const q = event.url.searchParams.get("q")?.trim(); const [found, viewerStarRkeys] = await Promise.all([ q ? search(ctx, { q, nsid: "sh.tangled.repo", author: did, limit: PAGE_LIMIT }).then( - (page) => page.hits - ) + (page) => page.hits + ) : fetchPage(ctx, "sh.tangled.repo.listRepos", { subject: did, limit: PAGE_LIMIT }).then( - (page) => page.items - ), + (page) => page.items + ), parent.auth?.did ? listStarRkeys(ctx, parent.auth.did) : undefined ]); return { @@ -278,11 +284,23 @@ people: await resolvePeople(ctx, dids, parent.auth?.did) }; } case "vouches": { - const page = await fetchPage(ctx, "sh.tangled.graph.listVouches", { - subject: did, - limit: PAGE_LIMIT - }); - return { tab, vouches: await resolveVouches(ctx, page.items) }; + const [incomingPage, outgoingPage] = await Promise.all([ + fetchPage(ctx, "sh.tangled.graph.listVouches", { subject: did, limit: PAGE_LIMIT }), + fetchPage(ctx, "sh.tangled.graph.listVouchesBy", { subject: did, limit: PAGE_LIMIT }) + ]); + const [incoming, outgoing] = await Promise.all([ + resolveVouches(ctx, incomingPage.items, "incoming"), + resolveVouches(ctx, outgoingPage.items, "outgoing") + ]); + const vouches = [...incoming, ...outgoing].sort( + (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime() + ); + return { + tab, + vouches, + isSelf: parent.auth?.did === did, + profileHandle: handle + }; } case "starred": { const [page, viewerStarRkeys] = await Promise.all([