feat(content): 置顶契约与计数徽标组件(5h T1 契约部分)
置顶(T1):
- src/lib/post-order.ts 新增 sortPosts:置顶优先 → pubDate 倒序 → id 兜底,
把首页双轨/归档/书架四处排序口径收敛到一处
- postsSchema 增 pinned;PostList 三处渲染路径加灰阶 pin 小徽标;后台置顶开关
- 语义边界:只影响列表顺序,不改 pubDate/URL/RSS 时间语义
计数徽标(T4 契约组件):
- src/components/geek/ViewMeta.astro:眼睛 = 浏览数、气泡 = 评论数,
本地 SVG + tokens 着色,不引第三方图片
- 数据只用 Artalk 匿名端点:GET comments?limit=1 一次拿到 count 与 page.pv;
page 模式先 POST pages/pv 计一次浏览,readonly 模式零写入
- SSR 占位「–」:无 JS/接口失败不显示 0 误导读者
验证: pnpm astro build 48 页 exit 0;config-check 208 字段/65 hint 全过;
sortPosts 四调用点替换后构建通过
Spec: 2026-11-02_blog-5h-content-social (T1 契约)
Co-authored-by: GLM-5.3
This commit is contained in:
1 parent
ed473e996a
commit
6538311387
12 files changed
+388
-9
No files matched your search
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 文章列表排序契约(置顶功能,Phase 5h T1)
|
||||
*
|
||||
* 为什么集中在这里:首页双轨 / 归档折叠 / 书架 / en 归档四处列表各自写
|
||||
* `sort((a,b)=>b.pubDate-a.pubDate)`,加置顶必须四处同步,否则同一篇文章
|
||||
* 在不同页面位置不一致。排序键固定为「置顶优先 → 时间倒序」,时间相等时
|
||||
* 用 id 兜底保证构建确定(同一份内容两次构建产出一致,便于快照比对)。
|
||||
*
|
||||
* 置顶语义:`pinned: true` 只影响列表展示顺序,不改 pubDate、不改 URL、
|
||||
* 不影响 RSS/订阅源的时间语义。
|
||||
*/
|
||||
import type { CollectionEntry } from 'astro:content';
|
||||
|
||||
type SortablePost = { id: string; data: { pubDate: Date; pinned?: boolean } };
|
||||
|
||||
/**
|
||||
* 置顶优先、其次按发布日期倒序。
|
||||
*
|
||||
* @param posts 任意文章条目数组(不修改入参,返回新数组)
|
||||
* @returns 新数组;`pinned` 为真者在前,其内部与其余条目均按 pubDate 倒序,
|
||||
* 同日按 id 升序保证确定性
|
||||
*/
|
||||
export function sortPosts<T extends SortablePost>(posts: T[]): T[] {
|
||||
return [...posts].sort((a, b) => {
|
||||
const pin = Number(b.data.pinned === true) - Number(a.data.pinned === true);
|
||||
if (pin !== 0) return pin;
|
||||
const dt = b.data.pubDate.getTime() - a.data.pubDate.getTime();
|
||||
if (dt !== 0) return dt;
|
||||
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user