feat: 添加 ContributorsGrid 组件以显示 GitHub 贡献者#16
Conversation
Reviewer's Guide添加了一个可复用的 ContributorsGrid Vue 组件,用于获取并展示 GitHub 仓库贡献者,将其接入 VitePress 主题,并在所有语言的贡献者页面中,用它替换之前基于图片的贡献者徽章。 ContributorsGrid 获取并渲染贡献者的时序图sequenceDiagram
actor User
participant Browser
participant ContributorsGrid
participant GitHubAPI
User->>Browser: Navigate to contributor_page
Browser->>ContributorsGrid: Instantiate_with_props(repo, perPage, max)
Browser->>ContributorsGrid: onMounted()
activate ContributorsGrid
ContributorsGrid->>ContributorsGrid: set loading = true
ContributorsGrid->>ContributorsGrid: clear error
ContributorsGrid->>GitHubAPI: GET /repos/{repo}/contributors?per_page={perPage}
alt Response_OK
GitHubAPI-->>ContributorsGrid: contributors_json_array
ContributorsGrid->>ContributorsGrid: slice(0, max) into contributors
ContributorsGrid->>ContributorsGrid: set loading = false
ContributorsGrid-->>Browser: Render grid_of_contributors
else Response_error_or_invalid
GitHubAPI-->>ContributorsGrid: error_status_or_invalid_body
ContributorsGrid->>ContributorsGrid: set error_message
ContributorsGrid->>ContributorsGrid: set loading = false
ContributorsGrid-->>Browser: Render error_message
end
deactivate ContributorsGrid
新的 ContributorsGrid Vue 组件的类图classDiagram
class ContributorsGrid {
+repo: string
+perPage: number
+max: number
+loading: boolean
+error: string
+contributors: Array
+fetchContributors(): Promise
}
文件级变更
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
Original review guide in EnglishReviewer's GuideAdds a reusable ContributorsGrid Vue component that fetches and displays GitHub repository contributors, wires it into the VitePress theme, and replaces the previous image-based contributors badge on contributor pages in all locales. Sequence diagram for ContributorsGrid fetching and rendering contributorssequenceDiagram
actor User
participant Browser
participant ContributorsGrid
participant GitHubAPI
User->>Browser: Navigate to contributor_page
Browser->>ContributorsGrid: Instantiate_with_props(repo, perPage, max)
Browser->>ContributorsGrid: onMounted()
activate ContributorsGrid
ContributorsGrid->>ContributorsGrid: set loading = true
ContributorsGrid->>ContributorsGrid: clear error
ContributorsGrid->>GitHubAPI: GET /repos/{repo}/contributors?per_page={perPage}
alt Response_OK
GitHubAPI-->>ContributorsGrid: contributors_json_array
ContributorsGrid->>ContributorsGrid: slice(0, max) into contributors
ContributorsGrid->>ContributorsGrid: set loading = false
ContributorsGrid-->>Browser: Render grid_of_contributors
else Response_error_or_invalid
GitHubAPI-->>ContributorsGrid: error_status_or_invalid_body
ContributorsGrid->>ContributorsGrid: set error_message
ContributorsGrid->>ContributorsGrid: set loading = false
ContributorsGrid-->>Browser: Render error_message
end
deactivate ContributorsGrid
Class diagram for the new ContributorsGrid Vue componentclassDiagram
class ContributorsGrid {
+repo: string
+perPage: number
+max: number
+loading: boolean
+error: string
+contributors: Array
+fetchContributors(): Promise
}
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - 我发现了两个问题,并提供了一些整体性的反馈:
- 建议将
contributors: ref<any[]>([])替换为针对 GitHub 贡献者响应的带类型接口,以便让后续使用更安全、并具备自我文档化的效果。 perPage和max这两个 prop 之间可能存在冲突(例如,当max > perPage时,max将无法被完全利用);你可以考虑从max推导出perPage,或者对这两个值进行校验/归一化处理,以确保行为是可预期的。- 组件内部硬编码的英文加载/错误信息会破坏 zh/zh-tw 页面本地化;可以考虑通过插槽或 props 接受文案,以便在每个页面按需进行翻译。
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider replacing `contributors: ref<any[]>([])` with a typed interface for the GitHub contributor response to make downstream usage safer and self-documented.
- The `perPage` and `max` props can conflict (e.g., `max > perPage` will never be fully used); you might want to derive `perPage` from `max` or validate/normalize these values so the behavior is predictable.
- The hardcoded English loading/error messages inside the component break localization for the zh/zh-tw pages; consider accepting message slots or props so they can be translated per page.
## Individual Comments
### Comment 1
<location path=".vitepress/theme/components/ContributorsGrid.vue" line_range="15" />
<code_context>
+
+const loading = ref(true)
+const error = ref('')
+const contributors = ref<any[]>([])
+
+async function fetchContributors() {
</code_context>
<issue_to_address>
**suggestion:** Avoid `any[]` for contributors and use a typed structure instead.
`any[]` removes type safety for fields like `c.login` and `c.avatar_url`. Define a minimal `Contributor` interface with the properties you use (e.g. `id`, `login`, `avatar_url`, `html_url`, `contributions`) and type this as `ref<Contributor[]>([])` to keep the component safe and maintainable.
Suggested implementation:
```
interface Contributor {
id: number
login: string
avatar_url: string
html_url: string
contributions: number
}
const loading = ref(true)
const error = ref('')
const contributors = ref<Contributor[]>([])
```
```
const res = await fetch(url, { headers: { Accept: 'application/vnd.github.v3+json' } })
if (!res.ok) throw new Error(`HTTP ${res.status}`)
const data = await res.json() as Contributor[]
```
Review all usages of `contributors` in this component/template to ensure they only access properties defined on `Contributor` (`id`, `login`, `avatar_url`, `html_url`, `contributions`). If additional fields are used (e.g. `type`, `site_admin`), add them to the `Contributor` interface with appropriate types so that the template type-checks correctly.
</issue_to_address>
### Comment 2
<location path=".vitepress/theme/components/ContributorsGrid.vue" line_range="17-32" />
<code_context>
+ try {
+ const url = `https://api.github.com/repos/${props.repo}/contributors?per_page=${props.perPage}`
+ const res = await fetch(url, { headers: { Accept: 'application/vnd.github.v3+json' } })
+ if (!res.ok) throw new Error(`HTTP ${res.status}`)
+ const data = await res.json()
+ if (!Array.isArray(data)) throw new Error('Invalid response')
+ contributors.value = data.slice(0, props.max)
+ } catch (e: any) {
+ error.value = e.message || String(e)
+ } finally {
+ loading.value = false
</code_context>
<issue_to_address>
**suggestion:** User-facing error messages are quite low-level; consider mapping to friendlier text.
The UI will currently surface raw messages like `HTTP 403`, which isn’t very helpful for docs users. Consider mapping common statuses (e.g., 403/404/429) to clearer, user-friendly messages and logging the detailed error to the console for debugging instead of showing it directly.
```suggestion
async function fetchContributors() {
loading.value = true
error.value = ''
try {
const url = `https://api.github.com/repos/${props.repo}/contributors?per_page=${props.perPage}`
const res = await fetch(url, { headers: { Accept: 'application/vnd.github.v3+json' } })
if (!res.ok) {
const status = res.status
const statusText = res.statusText || ''
// Log detailed technical information for debugging
console.error('[ContributorsGrid] Failed to fetch contributors', {
url,
status,
statusText,
})
let friendlyMessage = 'Failed to load contributors. Please try again later.'
if (status === 403) {
friendlyMessage = 'GitHub rate limit reached. Please try again in a few minutes.'
} else if (status === 404) {
friendlyMessage = 'Contributors could not be found for this repository.'
} else if (status === 429) {
friendlyMessage = 'Too many requests to GitHub. Please wait a moment and try again.'
}
throw new Error(friendlyMessage)
}
const data = await res.json()
if (!Array.isArray(data)) {
console.error('[ContributorsGrid] Unexpected contributors response shape', data)
throw new Error('Failed to load contributors.')
}
contributors.value = data.slice(0, props.max)
} catch (e: any) {
console.error('[ContributorsGrid] Error while loading contributors', e)
error.value = e?.message || 'Failed to load contributors.'
} finally {
loading.value = false
}
}
```
</issue_to_address>帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的 review。
Original comment in English
Hey - I've found 2 issues, and left some high level feedback:
- Consider replacing
contributors: ref<any[]>([])with a typed interface for the GitHub contributor response to make downstream usage safer and self-documented. - The
perPageandmaxprops can conflict (e.g.,max > perPagewill never be fully used); you might want to deriveperPagefrommaxor validate/normalize these values so the behavior is predictable. - The hardcoded English loading/error messages inside the component break localization for the zh/zh-tw pages; consider accepting message slots or props so they can be translated per page.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider replacing `contributors: ref<any[]>([])` with a typed interface for the GitHub contributor response to make downstream usage safer and self-documented.
- The `perPage` and `max` props can conflict (e.g., `max > perPage` will never be fully used); you might want to derive `perPage` from `max` or validate/normalize these values so the behavior is predictable.
- The hardcoded English loading/error messages inside the component break localization for the zh/zh-tw pages; consider accepting message slots or props so they can be translated per page.
## Individual Comments
### Comment 1
<location path=".vitepress/theme/components/ContributorsGrid.vue" line_range="15" />
<code_context>
+
+const loading = ref(true)
+const error = ref('')
+const contributors = ref<any[]>([])
+
+async function fetchContributors() {
</code_context>
<issue_to_address>
**suggestion:** Avoid `any[]` for contributors and use a typed structure instead.
`any[]` removes type safety for fields like `c.login` and `c.avatar_url`. Define a minimal `Contributor` interface with the properties you use (e.g. `id`, `login`, `avatar_url`, `html_url`, `contributions`) and type this as `ref<Contributor[]>([])` to keep the component safe and maintainable.
Suggested implementation:
```
interface Contributor {
id: number
login: string
avatar_url: string
html_url: string
contributions: number
}
const loading = ref(true)
const error = ref('')
const contributors = ref<Contributor[]>([])
```
```
const res = await fetch(url, { headers: { Accept: 'application/vnd.github.v3+json' } })
if (!res.ok) throw new Error(`HTTP ${res.status}`)
const data = await res.json() as Contributor[]
```
Review all usages of `contributors` in this component/template to ensure they only access properties defined on `Contributor` (`id`, `login`, `avatar_url`, `html_url`, `contributions`). If additional fields are used (e.g. `type`, `site_admin`), add them to the `Contributor` interface with appropriate types so that the template type-checks correctly.
</issue_to_address>
### Comment 2
<location path=".vitepress/theme/components/ContributorsGrid.vue" line_range="17-32" />
<code_context>
+ try {
+ const url = `https://api.github.com/repos/${props.repo}/contributors?per_page=${props.perPage}`
+ const res = await fetch(url, { headers: { Accept: 'application/vnd.github.v3+json' } })
+ if (!res.ok) throw new Error(`HTTP ${res.status}`)
+ const data = await res.json()
+ if (!Array.isArray(data)) throw new Error('Invalid response')
+ contributors.value = data.slice(0, props.max)
+ } catch (e: any) {
+ error.value = e.message || String(e)
+ } finally {
+ loading.value = false
</code_context>
<issue_to_address>
**suggestion:** User-facing error messages are quite low-level; consider mapping to friendlier text.
The UI will currently surface raw messages like `HTTP 403`, which isn’t very helpful for docs users. Consider mapping common statuses (e.g., 403/404/429) to clearer, user-friendly messages and logging the detailed error to the console for debugging instead of showing it directly.
```suggestion
async function fetchContributors() {
loading.value = true
error.value = ''
try {
const url = `https://api.github.com/repos/${props.repo}/contributors?per_page=${props.perPage}`
const res = await fetch(url, { headers: { Accept: 'application/vnd.github.v3+json' } })
if (!res.ok) {
const status = res.status
const statusText = res.statusText || ''
// Log detailed technical information for debugging
console.error('[ContributorsGrid] Failed to fetch contributors', {
url,
status,
statusText,
})
let friendlyMessage = 'Failed to load contributors. Please try again later.'
if (status === 403) {
friendlyMessage = 'GitHub rate limit reached. Please try again in a few minutes.'
} else if (status === 404) {
friendlyMessage = 'Contributors could not be found for this repository.'
} else if (status === 429) {
friendlyMessage = 'Too many requests to GitHub. Please wait a moment and try again.'
}
throw new Error(friendlyMessage)
}
const data = await res.json()
if (!Array.isArray(data)) {
console.error('[ContributorsGrid] Unexpected contributors response shape', data)
throw new Error('Failed to load contributors.')
}
contributors.value = data.slice(0, props.max)
} catch (e: any) {
console.error('[ContributorsGrid] Error while loading contributors', e)
error.value = e?.message || 'Failed to load contributors.'
} finally {
loading.value = false
}
}
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
|
请提供截图,包括明暗模式的 |
There was a problem hiding this comment.
Pull request overview
This PR adds a reusable VitePress theme component to render a contributors grid by fetching GitHub repo contributor data, and replaces the old external contributors image embed across localized contributor pages.
Changes:
- Add
ContributorsGridVue component that fetches and displays GitHub contributors in a responsive grid. - Register
ContributorsGridglobally in the VitePress theme. - Update contributor pages (en / zh / zh-tw) to use the new component and adjust the GitHub link text.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
en/contributor.md |
Replaces external contributors image with <ContributorsGrid /> and clarifies link to full GitHub graph. |
zh/contributor.md |
Replaces external contributors image with <ContributorsGrid />. |
zh-tw/contributor.md |
Replaces external contributors image with <ContributorsGrid />. |
.vitepress/theme/index.ts |
Registers ContributorsGrid as a global theme component. |
.vitepress/theme/components/ContributorsGrid.vue |
Implements client-side GitHub contributors fetching + grid UI. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| })) | ||
|
|
||
| contributors.value = mapped.slice(0, props.max) |
There was a problem hiding this comment.
contributors.value = mapped.slice(0, props.max) behaves unexpectedly if max is negative (slice will drop items from the end). Also, since only one page is fetched, max > perPage can never be fulfilled. Clamp max/perPage to positive integers (and to GitHub’s per_page max) and/or implement pagination when max > perPage.
| onMounted(fetchContributors) | ||
| </script> |
There was a problem hiding this comment.
The component only loads once in onMounted. If repo, perPage, or max props change, the grid won’t refetch and will show stale data. Consider watching the relevant props (with { immediate: true }) and calling fetchContributors on change.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>




看原本的贡献者卡片没了,就vibe了一个,有错误请指正。
原本想用 contrib.rocks 的但是太糊了
由 Sourcery 提供的摘要
向 VitePress 主题中新增一个可复用的贡献者网格组件,并将其集成到贡献者页面中。
新功能:
ContributorsGridVue 组件,用于获取并在自适应网格中展示 GitHub 仓库的贡献者。文档:
ContributorsGrid组件替换外部贡献者图片嵌入,并对指向完整 GitHub 贡献者图的链接进行说明和澄清。Original summary in English
Summary by Sourcery
Add a reusable contributors grid component to the VitePress theme and integrate it into the contributor pages.
New Features:
Documentation: