Files
blog/src/lib/heartbeat.ts
T
wait4xandGLM-5.3 363cc616f7 feat(motion): 动效层三件——背景辉光/入场/心跳,页脚撤双入口
- 背景鼠标辉光:ink 色 4% 径向渐变跟随(pointer:fine×非
  reduced-motion 才有 JS,raf 节流 document 级监听 VT 存活)——
  丙灰阶语言的"活背景",触屏/减动效自动隐藏
- 正文入场 rise-in 12px/0.4s(VT 换页自然重放)+ 列表行悬停
  1px 微浮;全量 prefers-reduced-motion 豁免
- 首页"最近心跳":构建期拉 blog 仓最新 commit(gitea API 8s 超时
  静默降级),脉冲点+相对时长——本站自己的脉搏
- 页脚撤「装备/制作」入口(页面保留,用户决策:只删入口)
- E2E 加固:g-chords 修好后 location.href 与 goto 竞态(en 页弦
  导航迟到提交打断 goto)——中断重试模式
- 过程教训:str.replace 静默无操作再犯(锚点瞄错组件文件)——
  脚本未进产物却报"全落地",replace 必须 assert 配对 grep 产物

验证: --mx 鼠标双跳 15.6% 实测跟随;E2E 31/31 PASS(竞态重试后
      确定性);构建 34 页 exit 0

Spec: none (动效层+页脚撤口+测试加固,车道级交付)

Co-authored-by: GLM-5.3
2026-10-25 22:09:41 +08:00

39 lines
1.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 首页"最近心跳":构建期拉 blog 仓最新 commit——本站自己的脉搏。
* 失败静默(返回 null,首页渲染"很久以前"兜底文案),绝不阻塞构建。
*/
export interface Heartbeat {
/** commit 首行(截 40 字符) */
msg: string;
/** commit 时间(ISO) */
when: string;
}
const API = 'https://git.wait4x.online/api/v1/repos/wait4x/blog/commits?limit=1';
export async function fetchHeartbeat(): Promise<Heartbeat | null> {
try {
const res = await fetch(API, {
headers: { Accept: 'application/json', 'User-Agent': 'wait4x-blog-build' },
signal: AbortSignal.timeout(8_000),
});
if (!res.ok) return null;
const [c] = (await res.json()) as Array<{ commit?: { message?: string; author?: { date?: string } } }>;
const msg = c?.commit?.message?.split('\n')[0]?.slice(0, 40);
const when = c?.commit?.author?.date;
return msg && when ? { msg, when } : null;
} catch {
return null;
}
}
/** 相对时长(中文短句;en 页由调用方换词条) */
export function agoZh(iso: string, now = Date.now()): string {
const h = Math.floor((now - new Date(iso).getTime()) / 3_600_000);
if (h < 1) return '刚刚';
if (h < 24) return `${h} 小时前`;
const d = Math.floor(h / 24);
if (d < 30) return `${d} 天前`;
return `${Math.floor(d / 30)} 个月前`;
}