Commit Graph
23 Commits
Author SHA1 Message Date
TimeCrackbot fe9adb246f 文章更新 2026-09-17 16:58:41 +08:00
TimeCrackbot fcedd32d02 更新微信读书阅读进度 2026-09-16 18:29:16 +08:00
dsh 2c876f8776 彩蛋调整:文案改回原句,去掉悬停变色/下划线,那句话改回纯文本
按站主要求三处调整:

1) 文案改回原文
   他还需要一个诗意的世界。 → 他还应该拥有诗意的世界。
   (仍是 12 字,和最长那句 15 字的关系不变,固定字号不受影响)

2) 去掉悬停的变色与下划线
   现在那句话悬停时完全不变化,保持纯排版。
   删掉 .hero-quote-link 的两条规则,以及 reduced-motion 里对它的引用。

3) 那句话不再可点
   去掉 h1 里的 <a>,文字恢复成纯文本。豆瓣链接只剩卡片里那一处。
   交互全部落在署名上:悬停/聚焦淡入署名 → 点署名展开卡片 → 卡片里去豆瓣。
   这样读的时候不会误触跳走。

署名按钮补了 aria-label(「查看这句话的出处:王小波《万寿寺》」),
因为现在它是唯一的交互元素,读屏用户需要知道它是干嘛的。

验证:pnpm build 退出码 0
- 新文案在 hero.*.js 里,旧文案无残留
- dist/index.html 里豆瓣链接只剩 1 处、h1 内为纯 <span>、无 hero-quote-link
- 产物 CSS 从 16 条 hero-quote 规则减到 14 条,
  仍保留署名淡入、展开态常显、@media(hover:none) 手机常显
2026-09-16 18:24:49 +08:00
dsh 0f74467933 首屏彩蛋:那句话出自王小波《万寿寺》,可跳豆瓣
交互(默认完全看不出可点,保持留白):
- 悬停/聚焦:整句话由墨黑转朱红 + 朱红细下划线,署名随之淡入
- 点那句话   → 直接去豆瓣人物页
- 点署名     → 展开一张极简作者卡片,卡片里也能去豆瓣

结构上的几个考量:
- 用 <h1><a> 而不是把 h1 变成链接:保住标题语义,点击热区只包住文字
  而不是整行 1024px(点旁边空白也跳走会很怪)
- 光标 ::after 挂在 h1 上(链接外面),点那个闪烁的竖线不会触发跳转
- 署名占一行固定高度(2.25rem)平时透明,hover 才淡入 —— 空间一直留着,
  所以展开卡片时下面的按钮不会往上跳
- 卡片是手风琴式展开(max-height 过渡),留在文档流里,不盖住下面的按钮
- @media (hover: none) 下署名常显 —— 否则手机上这个彩蛋永远看不到
- aria-expanded / aria-controls / aria-label + focus-within 可见焦点,
  键盘和读屏用户都能用
- prefers-reduced-motion 下关掉所有过渡

出处核实:多个豆瓣《万寿寺》原文摘录页都收录这句,确认为王小波《万寿寺》。
豆瓣链接在 curl 下会跳 sec.douban.com(反爬),真实浏览器可正常打开。

验证:pnpm build 退出码 0;dist/index.html 里豆瓣链接出现 2 次、
h1 内为 <a>、署名与卡片均在、卡片默认 data-open="false";
产物 CSS 含 16 条 hero-quote 规则(含 @media(hover:none))
2026-09-16 18:03:32 +08:00
dsh ee5ec50602 首屏打字机改为固定字号 + CSS 光标,并修掉首屏白屏
按 Firefly banner 的做法重做,三件事:

1) 字号固定,不随句子长度变
   - 文案从 4 句(14/11/4/4 字,差 3.5 倍)压成 2 句长度接近的王小波
   - 字号用 text-[clamp(1.125rem,5.6vw,4rem)],只跟视口缩放
     · 手机 390px → 21.8px(15 个字一行刚好放得下)
     · 桌面 1280px → 64px(比 Firefly 的 3rem 更大更醒目)
   - 容器 max-w-4xl(896px) → max-w-5xl(1024px):15 字 × 64px = 954px,4xl 装不下
   - 实测 320/360/390/430/640/768/1024/1280/1920 全部放得下,无溢出

2) 光标改成 CSS ::after
   - 删掉整套运行时测量:measureRef / designRef / fontSize state /
     fitFontSize / ResizeObserver / CURSOR_EM / CURSOR_GAP_PX / 两个隐藏量具
   - hero.tsx 298 → 208 行,两个文件净减 52 行
   - 顺带消除测量误差,光标跟着字号自动缩放

3) 去掉和打字机重复的 Flannery O'Connor 引语

另外修掉两个自己发现的问题:

- 【真 bug】首屏在 JS 加载前是隐形的
  SSR 出来的包裹层带 opacity-0,要等 React hydrate 才变可见,
  慢网络下第一屏是白屏、LCP 被拖后。改成 CSS 入场动画(.hero-enter),
  SSR 即可见;顺带删掉只为它存在的 mounted state

- 【算错】第一版 clamp 封顶写了 4.25rem(68px),但容器 896px 装不下
  1013px,≥1280px 会溢出。一起修掉了

验证:pnpm build 退出码 0;dist 里已无 hero-cursor span、无隐藏量具、
无 Flannery 引语,h1 class 为 hero-typewriter + clamp 字号
2026-09-16 17:47:20 +08:00
dsh 71026ee291 文档:记录两个部署目标的服务方式,并开启线上压缩
排查「树莓派预览打不开」时发现两件事,都不是这次部署造成的,但都修了/记了:

1) 树莓派上根本没有 web 服务
   - nginx 未安装(Unit nginx.service could not be found),80 端口无人监听
   - deploy.sh 一直把文件 rsync 到 /home/pi/www/Astro_firefly(这次也确实到了,
     index.html 17:54、59 个 KaTeX 字体都在),但没有服务对外提供
   - 补了 Caddy 容器 blog-caddy(--restart unless-stopped,配置 /home/pi/caddy/Caddyfile,
     站点根挂到 /srv:ro),http://192.168.1.87 现在正常,各页面 200

2) 云服务器的 Caddy 一条 encode 都没有,全站裸传
   - twikoo.min.js 506 KB、主 CSS 231 KB、首页 HTML 134 KB
   - 站点块加 encode zstd gzip(改前按已有习惯备份成
     Caddyfile.bak.gzip.20260915_175943,validate 通过后 reload)
   - 实测 twikoo.min.js 506108 -> 160547 B(省 68%),CSS 230615 -> 40822 B(省 82%)
   - Caddy 按 Accept-Encoding 协商 zstd / gzip,所有页面仍 200

README 与操作指南补了「两个目标各自怎么服务的」和 Pi Caddy 的重建命令,
并注明 1Panel 管的 Caddyfile 手改后要注意什么、reload 为什么是安全的。
2026-09-15 18:00:33 +08:00
TimeCrackbot d0e504d1c3 刷新微信读书数据快照(仅 updatedAt 变化) 2026-09-15 17:53:30 +08:00
TimeCrackbot 61625c3740 更新站点文案:tagline / description / keywords
- tagline:抵抗遗忘 -> 记录时间
- description:改为「只是分享自己的看法。」
- keywords:收敛为 技术 / Linux / Obsidian

(这几处是站主本人改的,随本次推送一起备份。
  reading.json 只变了 updatedAt 时间戳。)
2026-09-15 17:21:23 +08:00
dsh 61c39557df 首屏打字文案改成长句也不溢出:按实际字宽自适应字号
问题
- h1 是 whitespace-nowrap + 固定字号 text-[min(10.5vw,3rem)] sm:text-6xl
  md:text-7xl lg:text-8xl。其实旧文案就已经临界:旧句「折腾 Linux 的乐趣」
  约 9.5 字宽,390px 屏上设计字号 40.9px 需要 389px,而 px-6 之后只有 342px。
  换成王小波那句(14 字)后溢出更明显。桌面端同理:lg 的 96px × 14 字
  = 1344px,而容器 max-w-4xl 只有 896px。

做法
- 不再拍固定字号,改成按「这一句完整文本」的实际渲染宽度算
- 关键点:只会**缩小**,不会放大。上限取当前断点的设计字号 ——
  短句(记录思考/总结生活)保持原来的视觉分量,只有放不下的长句让步
- 量的是完整句子不是当前已打出的部分,所以打字机逐字出现时不会重排
- 字号只在句子切换的那一刻变一次,那时 h1 是空的,看不出跳动;
  另加了 300ms 的 font-size 过渡
- 光标从固定像素改成 em 单位(w-[0.08em] h-[0.9em]),跟着字号缩放
- 算字号时扣掉光标自身的占宽(ml-2 的 8px + 0.08em),否则右边会顶出去

实现细节
- 设计字号不写死在 JS 里:用一个带同样响应式类的隐藏探针读计算值,
  断点逻辑仍然只在 class 里有一处
- 两个隐藏量具放在 h-0 + overflow-hidden 的绝对定位容器里,不参与布局、
  不会撑出横向滚动条
- ResizeObserver 跟随容器变化;document.fonts.ready 后再量一次
  (网络字体加载完字宽会变)

预期效果(含光标占位,实测可用宽度)
  390px  设计 40.9px:14字 24.3px / 11字 30.9px / 4字 40.9px(保持)
  430px  设计 45.1px:14字 27.2px / 11字 34.6px / 4字 45.1px(保持)
  768px  设计 72.0px:14字 51.9px / 11字 65.9px / 4字 72.0px(保持)
  1280px 设计 96.0px:14字 64.7px / 11字 82.2px / 4字 96.0px(保持)
长句刚好占满可用宽度,短句维持原设计大小,无一溢出。

注:hero.tsx 里同时带入了你自己改的那四句文案(王小波那句 + 记录思考 /
总结生活)。src/data/site.ts 里你的 tagline/description/keywords 改动我没有提交。
2026-09-15 12:50:09 +08:00
dsh a994839b5a 修复 KaTeX 字体全部 404:60 条构建警告,dist 里一个字体都没输出
问题
- 构建时刷 60 条 `fonts/KaTeX_*.woff2 referenced in ... didn't resolve`
- 更要紧的是这不是纯警告:dist 里 0 个字体文件,而 CSS 里写的是相对路径
  url(fonts/KaTeX_AMS-Regular.woff2),CSS 输出在 /_astro/ 下,
  浏览器会去找 /_astro/fonts/… —— 那个目录不存在,数学公式全部退化成系统字体

根因
- global.css 顶部写的是 @import "katex/dist/katex.min.css"
- postcss 只挂了 @tailwindcss/postcss,Tailwind v4 会自己解析并**内联** @import,
  内联之后 KaTeX 的 url() 被算成相对 src/styles/ 去找,自然找不到

(确认过不是我引入的:把 package.json 的 type:module 去掉重跑,一样 60 条;
 这条 @import 从初始提交就在)

修法
- global.css 里删掉那行 @import
- 改成在 BaseLayout.astro 的 frontmatter 里 `import "katex/dist/katex.min.css"`
- 走 Vite 的 CSS 模块管线,url() 按 node_modules/katex/dist/ 解析,
  字体带哈希输出到 _astro/,CSS 里替换成绝对路径

验证
- 构建:KaTeX 警告 60 -> 0;dist 字体 0 -> 59 个、共 1.2MB
- CSS:20 条 @font-face,59 处 url(/_astro/KaTeX_*.woff2) 全部绝对化
- LaTeX 那篇文章含 17 处 class="katex" 标记,引用的就是这份 CSS
- dev server:ERROR 0,KaTeX 警告 0,首页 200
- 全量构建日志现在只剩 1 条预期内的 [WARN] glob-loader(studies 集合为空)
2026-09-15 12:45:24 +08:00
dsh 9c0851fd12 修复 pnpm dev 启动刷红:Sketch.astro 脚本误识别 + .pnpm-store 撑爆 inotify
两个独立问题叠在一起,用户看到的只是第一个(扫描失败会中止启动,
第二个来不及暴露)。

1) Sketch.astro 的 frontmatter 里出现字面量的 script 开标签
   Astro 编译器靠扫描源码文本收集内联脚本,分不清真标签和字符串/注释。
   原代码用模板字符串拼 iframe 里的 resize 脚本,那个字面量开标签被当成
   组件脚本抽出来交给 Vite,里面的 ${JSON.stringify(...)} 直接报
   `Expected "}" but found "{"`,dev 依赖扫描失败、整个 /src 刷红。
   -> 改成 "\x3Cscript>" / "\x3C/script>" 拼接。
   注意闭标签原本写作 <\/script> 所以没被误判,只有开标签要处理。
   修完第一版又把解释写进注释、注释里带了字面量开标签,于是换了条错误
   (`Unexpected "。"`)继续报;这次注释也改成不带字面量的写法。

2) .pnpm-store 被 Vite 的 watcher 一起监听
   项目根目录下的 .pnpm-store 是 pnpm 内容寻址仓库(54269 个文件 / 672MB,
   已被 .gitignore 忽略),Vite 默认 watch 项目根,直接撑爆 inotify
   (max_user_watches = 65536),启动后无限刷
   `ENOSPC: System limit for number of file watchers reached`。
   -> astro.config.mjs 加 vite.server.watch.ignored: ["**/.pnpm-store/**"]。

顺带:package.json 加 "type": "module",消掉 Node 对
src/plugins/*.js 的 MODULE_TYPELESS_PACKAGE_JSON 警告(两个文件本来就是 ESM)。

验证
- 删掉 node_modules/.vite 强制重新做依赖扫描后启动 pnpm dev:
  ERROR 0 / Failed to scan 0 / ENOSPC 0,ready in 496ms
  /、/bookshelf/、/bookshelf/books/ 均 200
- pnpm build 退出码 0,MODULE_TYPELESS 警告 0
- 仅剩 [WARN] glob-loader 提示 src/content/studies 为空,属预期
- 操作指南补了这条 FAQ,说明两个原因和"注释里也不能写"这个坑
2026-09-15 12:22:44 +08:00
dsh 30c958c2f0 代码块阴槽调浅一档:#ece6da -> #f2ece1
上一版 0.925 偏重,用户反馈太深。改成 0.945(顶栏 0.893 -> 0.915),
色相和彩度不变,仍然是暖色槽而不是冷白补丁。

明度差对比(页面底 0.964 = #f8f3e9):
  0.958 #f6f1e6  差 1.018:1   ← 再浅一档,几乎看不出边界
  0.945 #f2ece1  差 1.058:1   ← 本次采用
  0.925 #ece6da  差 1.124:1   ← 上一版
  0.905 #e5dfd3  差 1.19:1

正文对比度 12.4:1,暗色模式未动。三档都写进 README 和 global.css 注释,
以后想调只改一个数字。
2026-09-15 12:07:25 +08:00
dsh cd0da2a19d 页脚三栏统一成卡片;代码块改暖色阴槽;导航字号/移动端菜单位置调整
页脚
- 「最新文章」和「联系」也套上 bg-card + border/50 + rounded-xl + p-5,
  标题用和「站点信息」同一套红竖线样式,三栏现在是一个语言
- 栏间距 gap-12 -> gap-5,卡片自己撑开视觉分隔
- 去掉 md:justify-self-center / md:justify-self-end,卡片改为填满各自栅格

代码块(浅色)
- --codeblock-bg  oklch(0.97 0.003 85) -> oklch(0.925 0.017 84)  #f6f5f3 -> #ece6da
- --codeblock-topbar-bg 0.94/0.003 -> 0.893/0.018
- 原来那个值是中性灰白(彩度 0.003),而页面底是暖纸 #f8f3e9,
  在暖底上就是一块冷白补丁;现在比页面底更深且色相一致
- 正文对比度仍有 11.7:1,暗色模式未动

桌面导航
- 链接 text-sm -> text-sm lg:text-[15px]
- 间距 gap-8 -> gap-6 lg:gap-7
- 只在 lg 以上放大:768-1023 这段页眉本来就挤(导航 9 项 + 搜索框 + 主题按钮
  加起来超过可用宽度),再放大只会更难看,这段维持原样不做回归

移动端菜单
- 从 left-3 right-3 横向铺满,改成 right-3 w-60(240px)+ max-w 兜底
- 展开原点 top center -> top right
- 竖向空间占用不变(max-h 仍在),横向不再占满一屏

验证(dist)
- 页脚 3 个 bg-card 容器 / 3 个红竖线标题,三个标题都在卡片内
- 构建出的 CSS: codeblock-bg:oklch(92.5% .017 84),暗色分支未变
- 页眉 class 确认为 text-sm lg:text-[15px] + gap-6 lg:gap-7
- 移动端面板 class 确认为 right-3 w-60 ...,transform-origin: top right
2026-09-15 12:04:50 +08:00
dsh 0719d8ba5d 书架首页改成「在读」,书籍挪到 /bookshelf/books/
原来 /bookshelf/ 是书籍页,点顶部导航「书架」直接进书籍,
和「先看在读」的预期相反。

- /bookshelf/       -> 在读页(view="reading")
- /bookshelf/books/ -> 书籍页(view="books")
- 顶部导航「书架」保持指向 /bookshelf/,现在落在在读页,不用改导航
- 侧栏「馆藏」:在读 -> /bookshelf/,书籍 -> /bookshelf/books/
- /bookshelf/reading/ 这个临时 URL 撤掉(还没上线,没有外链负担)

因为导航的 isCurrent 用的是 startsWith,在 /bookshelf/books/ 下
顶部「书架」仍然是高亮状态,符合预期。

验证
- /bookshelf/       : title「在读 20 本」、id=reading、20 张卡、20 条进度条、
                      无书籍区块;侧栏「在读」带 aria-current
- /bookshelf/books/ : title「书籍」、id=books、已读完分组 6 张、无进度条;
                      侧栏「书籍」带 aria-current
- 顶部导航「书架」href = /bookshelf/
2026-09-15 11:11:32 +08:00
dsh a88bb536ab 书籍页:手工书单为空时隐藏统计行和搜索/筛选条
books.json 是空的,所以「书籍」页顶上挂着一排
「0 本已读 / 0 本推荐 / 0 个领域」加搜索框、领域和评价筛选 ——
没数据可显示也没东西可筛,纯占地方。

改成 hasManualBooks = allBooks.length > 0 控制:
- 为空时整块(统计行 + 搜索框 + 领域筛选 + 评价筛选)不渲染
- 往 books.json 加了书自动回来,不用改代码
- 顺带补一个兜底空态:手工书单和微信读书都已读完都为空时,
  显示「书架还是空的」并提示两条填充路径

验证(双向都测了)
- books.json 为空时构建:本已读 / data-bookshelf-search /
  data-filter-books-category / data-filter-books-status 在产物里均 0 次;
  已读完分组和 6 张卡片不受影响
- 临时往 books.json 注入 1 本假书再构建:统计行、搜索框、领域筛选、
  评价筛选、手工书卡全部出现(测完已 git checkout 还原)
- 在读页未受影响:20 张卡 / 20 条进度条
2026-09-15 11:05:39 +08:00
dsh 95e5111fd8 书架拆成「在读」和「书籍」两个独立页面
问题:两块内容挤在 /bookshelf/ 一页里,往下滚就从「在读」滑进「书籍」,
不像两个分类该有的样子。

拆法
- src/pages/bookshelf.astro -> src/pages/bookshelf/index.astro(书籍页)
- 新增 src/pages/bookshelf/reading.astro(在读页)
- 两页共用 bookshelf-content.astro,只多收一个 view: "reading" | "books",
  决定渲染哪一块;外壳(页眉/侧栏/页脚/样式)完全同一份,样式不会跑偏
- 在读页标题带真实本数:「在读 20 本 | 时之刃的小站」

侧栏「馆藏」改成真导航
- 在读 -> /bookshelf/reading/,数量 = 未读完本数(20)
- 书籍 -> /bookshelf/,数量 = 手工书单 + 微信读书已读完(0 + 6 = 6)
  原来这里只算 books.json 的 total,所以显示 0,正是截图里的问题
- 当前页用 aria-current="page" + 主色底高亮

页面互相不串
- /bookshelf/        : id=books、搜索框、已读完分组 6 张、无在读区块、0 条进度条
- /bookshelf/reading/: id=reading、在读卡片 20 张、20 条进度条、无书籍区块、
                       无搜索框、无已读完分组、0 张 data-weread-card

顺带更正 README 首段还写着的「读书/论文/漫画书架」。
2026-09-15 10:58:27 +08:00
dsh 8a867132de 已读完的书卡改成和「在读」同一套样式,补开始/读完时间
可行性(先说结论)
- 「开始阅读时间」在官方文档里没列,但 /book/getprogress 的原始回包里有
  book.startReadingTime,6 本已读完的全都有
- 顺带纠正我上一轮的错误结论:真正常为 0 的是 recordReadingTime,
  book.readingTime 是有值的(西线无战事 6190 秒 = 103 分),
  已存进 JSON 的 readingSeconds,卡片暂未展示

抽公共组件
- 新增 src/components/reading-card.astro,在读和已读完共用,样式强制统一:
  横版卡片、封面在左、信息在右
- 两处只在底部两行不同:
    在读   进度条 + 百分比 / 最近阅读 X
    已读完 开始 X / 读完 Y(无进度条)

数据层
- fetch-reading.mjs 每个条目新增 startedAt / finishedAt / readingSeconds
- src/lib/reading.ts 的 ReadingBook 类型同步补上(都可选,老数据不会炸)
- startReadingTime / finishTime 缺失时卡片自动少一行,不会渲染出「开始 —」

时间显示走 Asia/Shanghai。所以西线无战事的 startReadingTime
1786207913(UTC 08-08T15:31Z)在页面上是「开始 2026-08-09」,
这才是本地日期。

静态验证(dist/bookshelf/index.html)
- 在读区 20 张卡 / 20 条进度条 / 20 个「最近阅读」
- 已读完区 6 张卡 / 0 条进度条 / 6 个「开始 X」/ 6 个「读完 X」
- 抽一张:西线无战事(译文经典) 雷马克 · 文学-外国文学
  开始 2026-08-09 读完 2026-09-06,确认不含进度条
- 搜索/领域筛选的 data-weread-card 仍挂在新卡片上,筛选不受影响
2026-09-15 10:51:50 +08:00
dsh 4df235ea21 已读完的书挪进「书籍」,抓取上限去掉(8 -> 整架 26 本)
抓取范围
- TOP_N 默认从 8 改成 0=不限制。原来那个 8 是我拍的「最近动过的前 8 本」,
  不是接口限制;整架 26 本也就 1+26 个请求,完全够用
- --top N 仍可用,想只抓最近几本时加

分组调整
- 「最近在读」只留 progress < 100 的(20 本),进度条不再出现 100%
- 新增「书籍」区底部的「微信读书 · 已读完」分组(6 本),卡片结构与手工
  书单一致,左上角带「已读完」徽标;因为微信读书的数据没有书评/简介,
  这一组点击直接跳 weread.qq.com,不弹窗
- 这一组带 data-weread-card + data-category="微信读书",所以搜索框和
  「领域」筛选同样作用得到;领域筛选里会多出一个「微信读书」选项
- 筛选逻辑把 [data-book-card] 的选择器扩成 [data-book-card],
  [data-weread-card],分组计数也一并算上

实测数据分布(整架 26 本)
- 已读完 6 / 在读中 16(1%-97%)/ 没开始 4(0%)

静态验证(dist/bookshelf/index.html)
- 在读区 20 张卡片,进度条 30/0/77/28/13/97/0/5/16/3/10/1/4/13/4/0/1/10/6/0,
  区内无「已读完」字样
- 已读完分组 6 张卡片,6 个徽标、6 个微信读书跳转链接,均带 data-weread-card
- 手工书单 3 张卡片未受影响;领域筛选新增「微信读书」按钮
2026-09-15 10:45:29 +08:00
dsh 95dd0d9552 书架页新增「最近在读」:构建时抓微信读书,顺带移除漫画/论文
数据链路
- scripts/fetch-reading.mjs:调腾讯官方 Agent Gateway
  (POST https://i.weread.qq.com/api/agent/gateway,Bearer wrk-...),
  /shelf/sync 拿书架,再对前 N 本调 /book/getprogress 拿进度,
  写出 src/data/reading.json
- src/lib/reading.ts:读 JSON + 按 YYYY-MM-DD 格式化(官方硬性要求),
  文件缺失返回 null 让页面走空态而不是构建报错
- src/components/bookshelf-content.astro:只渲染,页面本身不发请求

接口实测得到的几个结论(都写进脚本注释和 README 了)
- skill_version 必填,业务参数平铺顶层
- /shelf/sync 一次给全封面/书名/作者/分类/最近阅读时间/deepLink,
  只有进度要额外请求,所以请求数 = 1 + N
- progress 是 0-100 整数,只有 100 算读完
- recordReadingTime 恒为 0,所以卡片不做「累计时长」
- deepLink 实测是普通 https,浏览器能直接打开

失败兜底(这次最关键的一条)
- pnpm reading:失败 exit 1,明确报错
- pnpm build:串的是 `fetch-reading.mjs --soft`,Key 失效/断网/接口挂了
  都保留上一次的 reading.json 并 exit 0,不会阻塞部署
- 实测:错误 Key 时 pnpm reading exit 1;pnpm build 完整跑通 exit 0 且
  reading.json 未被改动;不设 Key 也 exit 0
- process.loadEnvFile 不覆盖已存在的环境变量,所以 CI 设的 Key 优先于 .env

Key 安全
- 只写进 .env(gitignore,权限 600),已确认 git status 里没有它
- deploy.sh 是本地构建再 rsync,凭据不会上传服务器
- .env.example 补了占位和申请地址

书架页改版
- 移除漫画/论文两个分类:删掉 tab 切换、两个视图、对应筛选和 JS,
  956 行 -> 620 行;sidebar 的 tab 按钮改成 #reading / #books 页内锚点
- 新增「最近在读」区块置顶(Collection · 01),书籍顺延为 02
- 卡片:封面(hot-link 腾讯 CDN,referrerpolicy=no-referrer)+ 书名 +
  作者 · 分类 + 进度条 + 最近阅读日期,整卡跳 weread.qq.com
- 读完标「已读完」,0% 标「还没开始」
- 过滤私密阅读(secret=1)和从没打开过的书;有声书不处理

静态验证(dist/bookshelf/index.html)
- 8 张在读卡片,链接均指向 weread.qq.com/book-detail
- 8 条进度条宽度 30/0/77/100/28/13/97/0,与脚本输出一致
- 8 张封面全部 hot-link,无本地副本
- 漫画/论文/comics/papers/data-type-btn/switchType 均已从产物消失
- 其他页面(首页/时间线/关于/文章页)不含该区块,未受影响
2026-09-15 10:40:11 +08:00
dsh 121a03dd85 作者卡片的状态小字挪到 profile.ts,文案可配置
「正在空降:超级地球」原来硬编码在 sidebar.tsx 里,找起来费劲 ——
个人可见的文案应该和其它个人资料放一起。

- src/data/profile.ts 新增 status 字段,默认值就是原来那句
- sidebar.tsx 改成读 profile.status;值为空字符串时整行(含分隔线)不渲染
- README 里三处 profile.ts 的说明补上「状态小字」

验证:构建产物中该文案仍渲染 1 处。
2026-09-15 10:13:45 +08:00
dsh c841fa2047 修复评论区切页后排版崩坏:twikoo 基础样式改为静态引入
Astro 的 ClientRouter 切页时会清掉 head 里它不认识的 <style>,而 twikoo
的 CSS 正是 twikoo.min.js 运行时 appendChild 到 head 的;脚本本身又只执行
一次(window.twikoo 已存在就跳过),样式不会重新注入。

表现:从一篇带评论的文章点链接进另一篇后,评论区样式整段丢失 ——
markdown 图标被 .twikoo svg{width:100%;height:100%} 撑成 768x1240px、
文件输入框 .tk-input-image 从 display:none 变回可见、.OwO-items 从 flex
塌成 block 竖排成一列;整页刷新后恢复。

修复:把官方 twikoo.css 放进 public/assets/css/(与现有 twikoo.min.js 同为
1.7.20,已核对两个文件都来自同一个 npm 包、md5 一致),在 Comments.astro
里用静态 <link> 引入,排在 twikoo-custom.css 之前。静态 link 在 <body> 里,
切页时会随新页面一起换进来,不再依赖运行时注入。

没有换用官方 twikoo.nocss.js:它是 all 完整版去掉 CSS(997 KB),比
twikoo.min.js(506 KB,CSS 打包在内)大近一倍,而本站服务器没开 gzip,
换过去等于访客多下 491 KB。

验证(headless Chrome 131,禁用缓存,对本地 dist 实测):
- 直接打开文章页:icon 18.75px / fileInput none / .tk-submit 179px
- 文章 -> 文章切页:修复前 768px / inline-block / 2919px;
  修复后与直接打开逐像素一致(diff bbox = None,差异像素 0.0000%)
- 连续切页 3 次、切页后展开 OwO 表情面板,均正常
2026-09-15 08:39:41 +08:00
dsh 0b99eabfbe 评论区改为自托管 twikoo 前端,并适配主题
- 前端脚本从 jsDelivr 改为自托管 public/assets/js/twikoo.min.js,
  版本与后端对齐(1.7.20)。国内访问 jsDelivr 实测 3 秒以上且常被墙,
  是评论区空白的根因
- 新增 public/assets/css/twikoo-custom.css 主题适配层:选择器加 #twikoo
  前缀以覆盖运行时注入的样式,颜色引用主题变量,自动跟随亮/暗色
- 修复首屏重复初始化:astro:page-load 在首屏也会触发,用 dataset.mounted 去重
- 评论配置移除已无用的 version 字段;README 与操作指南同步更新
2026-09-14 20:58:37 +08:00
dsh 6f4cc13a20 初始提交:时之刃的小站
基于 VermilionVoid(朱墨留白)主题的个人博客。
- 站点配置集中在 src/data/site.ts 与 src/data/profile.ts
- 30 篇文章、8 条偶得、相册
- 评论使用自托管 twikoo
- 部署走 deploy.sh(rsync 到树莓派 + 云服务器)
2026-09-14 20:44:12 +08:00