docs: replace static star history with live links

This commit is contained in:
haixin.yang
2026-07-13 16:14:02 +08:00
parent 0e9fef6df9
commit fe799d322f
5 changed files with 6 additions and 189 deletions
-38
View File
@@ -1,38 +0,0 @@
name: Update Star History
on:
schedule:
- cron: '17 2 * * *'
workflow_dispatch:
permissions:
contents: write
concurrency:
group: update-star-history
cancel-in-progress: true
jobs:
update:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Generate chart from GitHub stargazer data
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node scripts/update-star-history.mjs
- name: Commit updated chart
run: |
if git diff --quiet -- docs/star-history.svg; then
echo "Star history is already current."
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add docs/star-history.svg
git commit -m "docs: update star history [skip ci]"
git push
+3 -3
View File
@@ -216,8 +216,8 @@ npx netlify-cli deploy --prod --dir=dist
Released under the [MIT License](LICENSE). You may use, modify, and distribute this project with attribution.
## Star History
## Community
If Timeline Studio is useful to you, starring the repository helps more people discover it.
The current star count is updated live in the GitHub Stars badge at the top of this README.
[![Timeline Studio GitHub Star History](docs/star-history.svg)](https://github.com/MartinDelophy/ai-video-editor/stargazers)
[View current stargazers](https://github.com/MartinDelophy/ai-video-editor/stargazers) · [Star Timeline Studio](https://github.com/MartinDelophy/ai-video-editor)
+3 -3
View File
@@ -201,8 +201,8 @@ npx netlify-cli deploy --prod --dir=dist
本项目采用 [MIT License](LICENSE)。在保留版权声明的前提下,可以自由使用、修改和分发。
## Star 趋势
## 社区
如果 Timeline Studio 对你有帮助,欢迎点一个 Star,这会帮助更多人发现这个项目
README 顶部的 GitHub Stars 徽章会实时显示当前 Star 数量
[![Timeline Studio GitHub Star 趋势](docs/star-history.svg)](https://github.com/MartinDelophy/ai-video-editor/stargazers)
[查看当前 Stargazers](https://github.com/MartinDelophy/ai-video-editor/stargazers) · [Timeline Studio Star](https://github.com/MartinDelophy/ai-video-editor)
-21
View File
@@ -1,21 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="320" viewBox="0 0 900 320" role="img" aria-labelledby="title desc">
<title id="title">Timeline Studio GitHub Star History</title>
<desc id="desc">A chart generated from GitHub's live stargazer history. The repository currently has 15 stars.</desc>
<style>
.card{fill:#fff;stroke:#d0d7de}.grid{stroke:#d8dee4}.axis,.label{fill:#57606a}.title{fill:#1f2328}.area{fill:url(#area-light)}.line{stroke:#2f81f7}.point{fill:#2f81f7;stroke:#fff}
@media(prefers-color-scheme:dark){.card{fill:#0d1117;stroke:#30363d}.grid{stroke:#21262d}.axis,.label{fill:#8b949e}.title{fill:#f0f6fc}.area{fill:url(#area-dark)}.line{stroke:#58a6ff}.point{fill:#58a6ff;stroke:#0d1117}}
</style>
<defs>
<linearGradient id="area-light" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#2f81f7" stop-opacity=".28"/><stop offset="1" stop-color="#2f81f7" stop-opacity=".02"/></linearGradient>
<linearGradient id="area-dark" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#58a6ff" stop-opacity=".32"/><stop offset="1" stop-color="#58a6ff" stop-opacity=".03"/></linearGradient>
</defs>
<rect class="card" x="1" y="1" width="898" height="318" rx="12"/>
<text class="title" x="70" y="42" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif" font-size="20" font-weight="600">GitHub Stars over time</text>
<text class="label" x="830" y="34" text-anchor="end" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif" font-size="14">15 stars</text>
<text class="label" x="830" y="51" text-anchor="end" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif" font-size="10">Updated Jul 13, 2026</text>
<g stroke-width="1"><line class="grid" x1="70" y1="260" x2="830" y2="260"/><line class="grid" x1="70" y1="210" x2="830" y2="210"/><line class="grid" x1="70" y1="160" x2="830" y2="160"/><line class="grid" x1="70" y1="110" x2="830" y2="110"/><line class="grid" x1="70" y1="60" x2="830" y2="60"/></g>
<g class="axis" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif" font-size="12"><text x="55" y="264" text-anchor="end">0</text><text x="55" y="214" text-anchor="end">4</text><text x="55" y="164" text-anchor="end">8</text><text x="55" y="114" text-anchor="end">12</text><text x="55" y="64" text-anchor="end">16</text><text x="70" y="290" text-anchor="start">Jul 9</text><text x="260" y="290" text-anchor="middle">Jul 10</text><text x="450" y="290" text-anchor="middle">Jul 11</text><text x="640" y="290" text-anchor="middle">Jul 12</text><text x="830" y="290" text-anchor="end">Jul 13</text></g>
<path class="area" d="M70 260 L83.3 247.5 L85.3 235 L88.2 222.5 L89.6 210 L100.4 197.5 L238.6 185 L463.3 172.5 L472.4 160 L553.5 147.5 L805.2 135 L805.2 122.5 L805.5 110 L826 97.5 L827.6 85 L829.6 72.5 L830 72.5 L830 260 L70 260 Z"/>
<path class="line" d="M70 260 L83.3 247.5 L85.3 235 L88.2 222.5 L89.6 210 L100.4 197.5 L238.6 185 L463.3 172.5 L472.4 160 L553.5 147.5 L805.2 135 L805.2 122.5 L805.5 110 L826 97.5 L827.6 85 L829.6 72.5 L830 72.5" fill="none" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
<circle class="point" cx="830" cy="72.5" r="5" stroke-width="2"/>
</svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

-124
View File
@@ -1,124 +0,0 @@
import { mkdir, writeFile } from 'node:fs/promises'
import path from 'node:path'
const token = process.env.GITHUB_TOKEN
const repository = process.env.GITHUB_REPOSITORY || 'MartinDelophy/ai-video-editor'
const outputPath = process.env.STAR_HISTORY_OUTPUT || 'docs/star-history.svg'
if (!token) {
throw new Error('GITHUB_TOKEN is required to read timestamped stargazer data.')
}
const headers = {
Accept: 'application/vnd.github.star+json',
Authorization: `Bearer ${token}`,
'User-Agent': 'timeline-studio-star-history',
'X-GitHub-Api-Version': '2022-11-28',
}
async function requestJson(url) {
const response = await fetch(url, { headers })
if (!response.ok) {
throw new Error(`GitHub API ${response.status}: ${await response.text()}`)
}
return response.json()
}
async function getStargazers() {
const stars = []
for (let page = 1; ; page += 1) {
const batch = await requestJson(
`https://api.github.com/repos/${repository}/stargazers?per_page=100&page=${page}`,
)
stars.push(...batch)
if (batch.length < 100) return stars
}
}
const repositoryInfo = await requestJson(`https://api.github.com/repos/${repository}`)
const stargazers = await getStargazers()
const starDates = stargazers
.map(({ starred_at: starredAt }) => new Date(starredAt))
.filter((date) => !Number.isNaN(date.getTime()))
.sort((a, b) => a - b)
const now = new Date()
const createdAt = new Date(repositoryInfo.created_at)
const firstEvent = starDates[0] || createdAt
const start = new Date(Math.min(createdAt.getTime(), firstEvent.getTime()))
const end = new Date(Math.max(now.getTime(), start.getTime() + 86_400_000))
const maxStars = Math.max(4, Math.ceil(starDates.length / 4) * 4)
const chart = { left: 70, right: 830, top: 60, bottom: 260 }
const x = (date) =>
chart.left +
((date.getTime() - start.getTime()) / (end.getTime() - start.getTime())) *
(chart.right - chart.left)
const y = (count) =>
chart.bottom - (count / maxStars) * (chart.bottom - chart.top)
const number = (value) => Number(value.toFixed(1))
const points = [{ date: start, count: 0 }]
starDates.forEach((date, index) => points.push({ date, count: index + 1 }))
points.push({ date: end, count: starDates.length })
const linePath = points
.map(({ date, count }, index) => `${index ? 'L' : 'M'}${number(x(date))} ${number(y(count))}`)
.join(' ')
const areaPath = `${linePath} L${chart.right} ${chart.bottom} L${chart.left} ${chart.bottom} Z`
const dateFormatter = new Intl.DateTimeFormat('en', {
month: 'short',
day: 'numeric',
timeZone: 'UTC',
})
const tickDates = Array.from({ length: 5 }, (_, index) =>
new Date(start.getTime() + ((end.getTime() - start.getTime()) * index) / 4),
)
const yTicks = Array.from({ length: 5 }, (_, index) => (maxStars * index) / 4)
const updatedAt = new Intl.DateTimeFormat('en', {
year: 'numeric',
month: 'short',
day: 'numeric',
timeZone: 'UTC',
}).format(now)
const grid = yTicks
.map((tick) => `<line class="grid" x1="70" y1="${number(y(tick))}" x2="830" y2="${number(y(tick))}"/>`)
.join('')
const yLabels = yTicks
.map((tick) => `<text x="55" y="${number(y(tick) + 4)}" text-anchor="end">${tick}</text>`)
.join('')
const xLabels = tickDates
.map((date, index) => {
const anchor = index === 0 ? 'start' : index === 4 ? 'end' : 'middle'
return `<text x="${number(x(date))}" y="290" text-anchor="${anchor}">${dateFormatter.format(date)}</text>`
})
.join('')
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="900" height="320" viewBox="0 0 900 320" role="img" aria-labelledby="title desc">
<title id="title">Timeline Studio GitHub Star History</title>
<desc id="desc">A chart generated from GitHub's live stargazer history. The repository currently has ${starDates.length} stars.</desc>
<style>
.card{fill:#fff;stroke:#d0d7de}.grid{stroke:#d8dee4}.axis,.label{fill:#57606a}.title{fill:#1f2328}.area{fill:url(#area-light)}.line{stroke:#2f81f7}.point{fill:#2f81f7;stroke:#fff}
@media(prefers-color-scheme:dark){.card{fill:#0d1117;stroke:#30363d}.grid{stroke:#21262d}.axis,.label{fill:#8b949e}.title{fill:#f0f6fc}.area{fill:url(#area-dark)}.line{stroke:#58a6ff}.point{fill:#58a6ff;stroke:#0d1117}}
</style>
<defs>
<linearGradient id="area-light" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#2f81f7" stop-opacity=".28"/><stop offset="1" stop-color="#2f81f7" stop-opacity=".02"/></linearGradient>
<linearGradient id="area-dark" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#58a6ff" stop-opacity=".32"/><stop offset="1" stop-color="#58a6ff" stop-opacity=".03"/></linearGradient>
</defs>
<rect class="card" x="1" y="1" width="898" height="318" rx="12"/>
<text class="title" x="70" y="42" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif" font-size="20" font-weight="600">GitHub Stars over time</text>
<text class="label" x="830" y="34" text-anchor="end" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif" font-size="14">${starDates.length} stars</text>
<text class="label" x="830" y="51" text-anchor="end" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif" font-size="10">Updated ${updatedAt}</text>
<g stroke-width="1">${grid}</g>
<g class="axis" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif" font-size="12">${yLabels}${xLabels}</g>
<path class="area" d="${areaPath}"/>
<path class="line" d="${linePath}" fill="none" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
<circle class="point" cx="${number(x(end))}" cy="${number(y(starDates.length))}" r="5" stroke-width="2"/>
</svg>
`
await mkdir(path.dirname(outputPath), { recursive: true })
await writeFile(outputPath, svg)
console.log(`Updated ${outputPath} with ${starDates.length} stars.`)