diff --git a/web/src/lib/api/repo.ts b/web/src/lib/api/repo.ts index ce1e1048..76597d18 100644 --- a/web/src/lib/api/repo.ts +++ b/web/src/lib/api/repo.ts @@ -143,10 +143,18 @@ export interface CommitSummary { body: string; authorName: string; authorEmail: string; + // a commit made through tangled signs with the author's did instead of an + // email, so unlike a git name that author is an account we can link to + authorDid?: string; + // filled in by the loader, since resolving the did takes a round trip + authorHandle?: string; when: string; changeId?: string; } +export const didFromSignature = (email: string): string | undefined => + email.startsWith("did:") ? email : undefined; + export const splitMessage = (message: string): [string, string] => { const separator = message.indexOf("\n\n"); if (separator === -1) return [message.trim(), ""]; @@ -173,13 +181,15 @@ export const coAuthorsFrom = (message: string, when: string): GitSignature[] => export const toCommitSummary = (commit: LogCommit): CommitSummary => { const [subject, body] = splitMessage(commit.message ?? ""); const hash = commit.this ?? ""; + const authorEmail = commit.author?.Email ?? ""; return { hash, shortHash: hash.slice(0, 8), subject, body, authorName: commit.author?.Name ?? "", - authorEmail: commit.author?.Email ?? "", + authorEmail, + authorDid: didFromSignature(authorEmail), when: commit.committer?.When ?? commit.author?.When ?? "", changeId: commit.change_id }; diff --git a/web/src/lib/api/repoIndex.ts b/web/src/lib/api/repoIndex.ts index 77269024..0d36ddde 100644 --- a/web/src/lib/api/repoIndex.ts +++ b/web/src/lib/api/repoIndex.ts @@ -1,5 +1,6 @@ import { error } from "@sveltejs/kit"; -import { ClientResponseError } from "$lib/api/client"; +import { ClientResponseError, createBobbinClient } from "$lib/api/client"; +import { resolveMiniDoc } from "$lib/api/identity"; import { branches as gitBranches, gitTarget, @@ -19,7 +20,7 @@ import { toTreeEntrySummary } from "$lib/api/repo"; import { renderDocument } from "$lib/markup"; -import type { LanguageSlice, RepoInfo } from "$lib/components/repo/types"; +import type { CommitSummary, LanguageSlice, RepoInfo } from "$lib/components/repo/types"; // `/tree/{ref}` is this same page at another ref, so they share a load const COMMIT_LIMIT = 10; @@ -119,6 +120,29 @@ export interface RepoIndexOptions { requireRef?: boolean; } +// a did-signed commit points at a real account, so trade the git author name +// for the handle and the row reads like the rest of the site. one round trip +// per distinct author, and a name we can't resolve just stays a name +const withAuthorHandles = async ( + commits: CommitSummary[], + bobbinUrl: string, + fetch: typeof globalThis.fetch +): Promise => { + const dids = [...new Set(commits.flatMap((commit) => commit.authorDid ?? []))]; + if (dids.length === 0) return commits; + + const ctx = createBobbinClient({ serviceUrl: bobbinUrl, fetch }); + const docs = await Promise.all(dids.map((did) => orNull(resolveMiniDoc(ctx, did)))); + const handles = new Map(); + for (const doc of docs) { + if (doc && !doc.handle.endsWith(".invalid")) handles.set(doc.did, doc.handle); + } + + return commits.map((commit) => + commit.authorDid ? { ...commit, authorHandle: handles.get(commit.authorDid) } : commit + ); +}; + export const loadRepoIndex = async ( event: RepoLoadEvent, parent: RepoParent, @@ -140,7 +164,11 @@ export const loadRepoIndex = async ( const branches = (results.branches.value?.branches ?? []).map(toBranchSummary); const tags = (results.tags.value?.tags ?? []).map(toTagSummary); - const commits = (results.log.value?.commits ?? []).map(toCommitSummary); + const commits = await withAuthorHandles( + (results.log.value?.commits ?? []).map(toCommitSummary), + parent.publicConfig.bobbinUrl, + event.fetch + ); const files = sortTreeEntries((results.tree.value?.files ?? []).map(toTreeEntrySummary)); const languages = toLanguageSlices(results.languages.value?.languages ?? []); diff --git a/web/src/lib/components/repo/CommitList.svelte b/web/src/lib/components/repo/CommitList.svelte index 8b56864e..80eb05e0 100644 --- a/web/src/lib/components/repo/CommitList.svelte +++ b/web/src/lib/components/repo/CommitList.svelte @@ -62,31 +62,20 @@ > {commit.shortHash} - {#if commit.authorName} - - {@const authorDid = commit.authorEmail.startsWith("did:") - ? commit.authorEmail - : undefined} - {#if authorDid} - - - - {:else if commit.authorEmail} - - - - {:else} + + {#if commit.authorHandle} + + {:else if commit.authorName && commit.authorEmail && !commit.authorDid} + - {/if} + + {:else if commit.authorName} + {/if} {#if commit.when}