67 lines
1.8 KiB
TypeScript
67 lines
1.8 KiB
TypeScript
import { useState } from 'react';
|
|
|
|
type CommitAuthorUser = {
|
|
login?: string;
|
|
username?: string;
|
|
full_name?: string;
|
|
name?: string;
|
|
avatar_url?: string;
|
|
avatarUrl?: string;
|
|
} | null | undefined;
|
|
|
|
export type CommitAuthorLike = {
|
|
commit?: {
|
|
author?: {
|
|
name?: string;
|
|
};
|
|
};
|
|
author?: CommitAuthorUser;
|
|
committer?: CommitAuthorUser;
|
|
};
|
|
|
|
export function commitAuthorName(commit: CommitAuthorLike) {
|
|
return commit.author?.login
|
|
|| commit.author?.username
|
|
|| commit.author?.full_name
|
|
|| commit.author?.name
|
|
|| commit.commit?.author?.name
|
|
|| commit.committer?.login
|
|
|| commit.committer?.username
|
|
|| commit.committer?.full_name
|
|
|| commit.committer?.name
|
|
|| '-';
|
|
}
|
|
|
|
function commitAuthorAvatarUrl(commit: CommitAuthorLike) {
|
|
return commit.author?.avatar_url
|
|
|| commit.author?.avatarUrl
|
|
|| commit.committer?.avatar_url
|
|
|| commit.committer?.avatarUrl
|
|
|| '';
|
|
}
|
|
|
|
export function CommitAuthor({ commit }: { commit: CommitAuthorLike }) {
|
|
const [failed, setFailed] = useState(false);
|
|
const name = commitAuthorName(commit);
|
|
const avatarUrl = commitAuthorAvatarUrl(commit);
|
|
const initial = name === '-' ? '?' : name.trim().charAt(0).toUpperCase() || '?';
|
|
|
|
return (
|
|
<span className="flex min-w-0 items-center gap-2">
|
|
{avatarUrl && !failed ? (
|
|
<img
|
|
src={avatarUrl}
|
|
alt=""
|
|
className="size-7 shrink-0 rounded-full border border-border bg-muted object-cover"
|
|
onError={() => setFailed(true)}
|
|
/>
|
|
) : (
|
|
<span className="inline-flex size-7 shrink-0 items-center justify-center rounded-full border border-border bg-muted text-xs font-semibold text-muted-foreground">
|
|
{initial}
|
|
</span>
|
|
)}
|
|
<span className="truncate font-medium">{name}</span>
|
|
</span>
|
|
);
|
|
}
|