From b747eb38c01727f6207b6fb11adba47089e75018 Mon Sep 17 00:00:00 2001 From: Xin shen <363088847@qq.com> Date: Mon, 8 Jun 2026 11:13:08 +0800 Subject: [PATCH] fix(changelog): fallback contributor avatars --- src/pages/Changelog/index.tsx | 4 ++++ src/pages/Changelog/utils.test.ts | 2 ++ src/pages/Changelog/utils.ts | 9 ++++++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/pages/Changelog/index.tsx b/src/pages/Changelog/index.tsx index 0b24c8e..dbf88ec 100644 --- a/src/pages/Changelog/index.tsx +++ b/src/pages/Changelog/index.tsx @@ -405,6 +405,10 @@ function ContributorAvatars({ contributors, showLabel }: { contributors: Contrib {c.name} { + event.currentTarget.onerror = null + event.currentTarget.src = c.fallbackAvatar + }} style={{ width: 24, height: 24, diff --git a/src/pages/Changelog/utils.test.ts b/src/pages/Changelog/utils.test.ts index 230f567..dc11a1f 100644 --- a/src/pages/Changelog/utils.test.ts +++ b/src/pages/Changelog/utils.test.ts @@ -7,10 +7,12 @@ describe('parseContributors', () => { { name: 'caster-Q', avatar: 'https://github.com/caster-Q.png?size=48', + fallbackAvatar: 'https://api.dicebear.com/9.x/identicon/svg?seed=caster-Q&backgroundColor=b6e3f4', }, { name: '@octocat', avatar: 'https://github.com/octocat.png?size=48', + fallbackAvatar: 'https://api.dicebear.com/9.x/identicon/svg?seed=%40octocat&backgroundColor=ffdfbf', }, ]) }) diff --git a/src/pages/Changelog/utils.ts b/src/pages/Changelog/utils.ts index 4e2f351..174210e 100644 --- a/src/pages/Changelog/utils.ts +++ b/src/pages/Changelog/utils.ts @@ -183,16 +183,22 @@ export function getVersionSeverity(version: string, prevVersion?: string): Versi export interface Contributor { name: string avatar: string + fallbackAvatar: string } const CONTRIBUTORS_PATTERN = /^@contributors:\s*(.+)/i const GITHUB_AVATAR_SIZE = 48 +const CONTRIBUTOR_COLORS = ['b6e3f4', 'ffdfbf', 'c0aede', 'd1f4e0', 'ffd5dc', 'ffe4c4', 'c4e0ff', 'f4d1e0'] function githubAvatarUrl(name: string): string { const login = name.replace(/^@+/, '') return `https://github.com/${encodeURIComponent(login)}.png?size=${GITHUB_AVATAR_SIZE}` } +function fallbackAvatarUrl(name: string, index: number): string { + return `https://api.dicebear.com/9.x/identicon/svg?seed=${encodeURIComponent(name)}&backgroundColor=${CONTRIBUTOR_COLORS[index % CONTRIBUTOR_COLORS.length]}` +} + export function parseContributors(desc: string): Contributor[] { if (!desc) return [] @@ -204,9 +210,10 @@ export function parseContributors(desc: string): Contributor[] { .split(/[,,、]\s*/) .map((name) => name.trim()) .filter(Boolean) - .map((name) => ({ + .map((name, index) => ({ name, avatar: githubAvatarUrl(name), + fallbackAvatar: fallbackAvatarUrl(name, index), })) } }