Firefly 魔改:GitHub 贡献热力图侧边栏

Firefly 魔改:GitHub 贡献热力图侧边栏

在侧边栏展示近 100 天的 GitHub 贡献数据,无需 Token 即可拉取。
AI 迁移提示

本文由 AI 协助从旧站迁移,尚未完成逐篇人工审校;内容如有疏漏,将在复核后修订。

> 本文部分内容由 AI 辅助整理,已结合实际操作进行校验,请根据自身环境谨慎使用。

GitHub 贡献热力图是很多开发者主页的标配,在博客侧边栏放一个,既能展示你的活跃度,也让访客更直观地了解你的开源参与情况。

GitHub 热力图效果

一、组件文件

组件源码位于 src/components/widget/GitHubHeatmap.astro,是一个 Astro 服务端渲染组件 + 客户端交互脚本。

使用 jogruber 公开 API 拉取数据,无需 Token:

typescript
const url = `https://github-contributions-api.jogruber.de/v4/${username}?y=last`;
const response = await fetch(url, { signal: AbortSignal.timeout(8000) });

服务端 8 秒超时兜底,失败时返回空数据,前端显示降级提示。数据结构:

typescript
type ContributionDay = {
  date: string;
  count: number;
  level: number;     // 0-4 贡献等级
  tooltip: string;
};

type CalendarData = {
  days: ContributionDay[];
  totalContributions: number;
  activeDays: number;
};

按 7 天一列排列网格,每格根据 level 设置透明度,颜色取自 var(--primary) 跟随主题。

完整组件代码

二、注册组件

新增组件需要在两处注册。

SideBar.astro 导入

src/components/layout/SideBar.astro 的 frontmatter 导入区,按字母顺序与其他 widget 一起引入:

js
import Advertisement from "@/components/widget/Advertisement.astro";
import Announcement from "@/components/widget/Announcement.astro";
import Calendar from "@/components/widget/Calendar.astro";
import Categories from "@/components/widget/Categories.astro";
import Dynamic from "@/components/widget/Dynamic.astro";
import GitHubHeatmap from "@/components/widget/GitHubHeatmap.astro";
import Music from "@/components/widget/Music.astro";
import Profile from "@/components/widget/Profile.astro";
import QuoteOfTheDay from "@/components/widget/QuoteOfTheDay.astro";
import Schedule from "@/components/widget/Schedule.astro";

SideBar.astro 组件映射表

SideBar.astro 通过 componentMap 动态渲染已注册的组件,而 SideBar 本身在 src/layouts/MainGridLayout.astro 中导入并使用:

js
import Live2DWidget from "@components/features/Live2DWidget.astro";
import SpineModel from "@components/features/SpineModel.astro";
import Footer from "@components/layout/Footer.astro";
import Navbar from "@components/layout/Navbar.astro";
import SideBar from "@components/layout/SideBar.astro";
import type { MarkdownHeading } from "astro";
import { Icon } from "astro-icon/components";

组件渲染链:MainGridLayout.astroSideBar.astro(componentMap) → GitHubHeatmap.astro

js
const componentMap = {
    profile: Profile,
    announcement: Announcement,
    categories: Categories,
    tags: Tags,
    // ...
    githubHeatmap: GitHubHeatmap,
    timeGreeting: TimeGreeting,
    dynamic: Dynamic,
    schedule: Schedule,
    quoteOfTheDay: QuoteOfTheDay,
};

src/components/widget/GitHubHeatmap.astro — 标题栏颜色适配深浅模式:

astro
    <div class="flex items-center justify-between mb-2 text-xs">
    <div class="flex items-center justify-between mb-2 text-xs text-neutral-600 dark:text-neutral-400">

三、注册类型

src/types/sidebarConfig.ts 的类型联合中添加组件名:

typescript
export type WidgetComponentType =
    | "calendar"
    | "music"
    | "siteInfo"
    | "githubHeatmap"
    | "timeGreeting";

四、配置启用

src/config/sidebarConfig.ts 的组件配置数组中添加:

typescript
{
    // 组件类型:GitHub 活跃度热力图
    type: "githubHeatmap",
    // 是否启用该组件
    enable: true,
    // 组件位置
    position: "top",
    // 是否在文章详情页显示
    showOnPostPage: false,
},
用户名自动提取

组件会自动从 profileConfig.links 中匹配 GitHub 链接提取用户名,无需单独填写。

五、相关文件

组件:/src/components/widget/GitHubHeatmap.astro

侧边栏:/src/components/layout/SideBar.astro

配置:/src/config/sidebarConfig.ts

相关源码:olinll/firefly-blog

🔗 最后

这个组件的实现参考了 Wine-Red 的思路,数据层使用开源 API,前端渲染与主题色保持统一。

Firefly 魔改:IP 定位欢迎弹窗组件
Firefly 魔改:时段问候实时时钟组件

评论区

评论加载中...