TimeCrackbot
|
93362376f8
|
fix: 消除文章页 dev 下的 "Invalid hook call" 告警
现象
dev 下每次打开文章页,终端都会打印 2 次 React 的 "Invalid hook call"。
生产构建没有;首页、/thoughts/、/friends/ 也没有。
根因(用临时 Vite 插件抓的调用栈定位)
不是 React 多副本,也不是 hooks 写法有问题,而是 Astro 的渲染器探测:
1. TableOfContents 首屏 headings 为空 → `return null`(数据在 useEffect 里填,
SSR 期不执行)
2. @astrojs/react 的 check 会试渲染一次,拿到 null 就认不出这是 React 组件 → false
3. Astro 转向下一个渲染器 @astrojs/mdx
4. MDX 的 check 把组件**当普通函数裸调** `await Component({...})`,不在 React
渲染树里 → useState 找不到 dispatcher → 报 Invalid hook call → 抛错被 catch
5. 两个渲染器都说不是自己的,Astro 最终仍用 React 正确渲染了组件
所以页面和组件一直是对的,只有日志是错的。生产构建没有是因为 React 生产版
剥掉了这段 dev-only 警告(栈里是 react.development.js)。
Hero 之类的组件不报,是因为它们探测时返回真实 JSX,第 2 步就被 React 认出来了。
修法
去掉 `if (headings.length === 0) return null`,改为始终返回 <nav>,无标题时用
`hidden` 收起,视觉结果不变。这样第 2 步就能认出是 React 组件,根本不会走到
MDX 的探测。代价是文章页 SSR 多出 2 个 display:none 的空 <nav>(两个 TOC 实例各一个),
以及 island 上多了 Astro 的 await-children 标记。
另一条路(未采用):项目里 0 个 .mdx,直接删掉 @astrojs/mdx 也能消除告警,
且零 DOM 变化。选择保留 MDX 是为了不因一个纯噪音的警告砍掉一个能力。
验证
dev 下逐个请求 5 类页面(含之前必现的 2 个文章页)告警数全为 0;
生产构建与基线的差异只剩本次有意的隐藏 nav、资源哈希和 island uid;
pnpm build 41 页 + pagefind 通过;astro check 仍是 1 error/0 warnings(原有报错)。
|
2026-09-17 18:16:43 +08:00 |
|
TimeCrackbot
|
f4a49ef94c
|
feat: 支持 Obsidian 风格 callout,并把脚注文案中文化
Callout
- 接入 satteri-callouts(HAST 插件),用 Obsidian 语法:
> [!tip] 标题
> 内容
> [!warning]- 默认折叠
类型名大小写不敏感,支持嵌套、可折叠、标题内联 Markdown。
- 样式没有用它自带的主题 CSS(Obsidian 原版是高饱和蓝/青/紫,还靠
mix-blend-mode 叠底色,在暖纸底上会发脏),改为新建 src/styles/callouts.css,
复用主题已有的 --admonitions-color-* token,与 .admonition(免责声明块)
统一成「3px 左边框 + 彩色标题、无底色」。
- 类型映射:tip/hint→tip,note/info/todo/abstract/summary/tldr→note,
important/example→important,warning/attention/question/help/faq→warning,
caution→caution,success/check/done→(新增的)success,
danger/error/failure/fail/missing/bug→destructive,quote/cite→muted-foreground。
- global.css 补一个 --admonitions-color-success(浅色 oklch(0.62 0.16 150) /
深色 oklch(0.7 0.18 150)),与 tip(180)/note(250)/important(310) 同明度彩度。
脚注中文化
features.gfm.footnotes 设 label「脚注」、backLabel「返回第 {reference} 条」、
backContent「↑」,替换默认的 Footnotes / Back to reference。
正文
- 周末愉快.md:`::: tip 下周计划`(冒号后有空格,从来不是合法指令,
一直渲染成普通段落)改成 `> [!tip] 下周计划`,任务列表一并加 `>` 前缀。
- 关于价值感和归属感的思考.md 的 `> [!tip] Tip` 本来就合法,一行未改,
现在自动变成真 callout。
顺带修
autolink-headings 不再给脚注区那个 sr-only 的「脚注」标题加 # 锚点。
验证
- 两处 callout 均正确渲染;callout 内的图片仍带 data-lightbox-src
(说明 imageLightbox 与 satteriCallouts 的执行顺序没问题)。
- 临时加了一篇带脚注和折叠 callout 的文章验证:脚注文案、返回链接、
折叠态 <details>/<summary> 结构都正确,验证后已删除。
- 整页对比基线:37/41 一致,4 处差异中 2 处是本次有意的 callout 生效,
另 2 处是已知的智能标点引号方向(Sätteri 的结果更正确)。
- pnpm build 41 页 + pagefind 通过。
|
2026-09-17 18:01:44 +08:00 |
|
TimeCrackbot
|
5e808a9cd4
|
feat: 接入 KaTeX 渲染,完成 Sätteri 迁移(Phase 3)
方案:用现成的 satteri-katex(MDAST 插件,40 行,是 rehype-katex 的移植),
而不是自己写。它跑在 MDAST 阶段,天然绕开下面这个坑。
为什么不能用 HAST 阶段做
Sätteri 把块级公式输出成 <pre><code class="language-math math-display">,
而 expressive-code 过滤所有 <pre>,会把它当成未知语言渲染成带行号的
plaintext 代码块 —— 实测 10 个块级公式全部被吃掉(math-display: 0)。
unified 时期没这问题,是因为 rehype-katex 排在 rehypePlugins 第一位,
先把 <pre><code> 换掉了。satteri-katex 的源码注释里记录的是同一个坑。
插件顺序
satteriKatex() 放在 mdastPlugins 最后:它把 math 节点换成 KaTeX 的 html
节点,若排在 reading-time / excerpt 之前,字数统计会把 KaTeX 标记也算进去。
顺带修掉一个之前漏掉的回归
reading-time / excerpt 原本用 ctx.textContent(),但它只拼接纯 text 节点,
会漏掉代码块、行内代码、公式、图片 alt。实测 LaTeX 那篇字数 830 → 488。
改用 mdast-util-to-string 的 toString()(与迁移前的实现一致),字数完全复原。
之前没发现是因为我的对比脚本只截取了 <article> 区域,而字数在它外面的 header 里。
现改为整页对比。
清理依赖(10 个,已确认无引用)
remark-math / rehype-katex / remark-directive /
remark-github-admonitions-to-directives / remark-sectionize / rehype-slug /
rehype-components / rehype-autolink-headings / @astrojs/markdown-remark /
hastscript / unist-util-visit
验证(与 unified() 基线整页对比,41 页)
- 39 页语义完全一致;2 页只剩智能标点在中文/emoji 旁的引号方向差异
(Sätteri 的结果更正确:把开引号排成 “ 而不是 ”)。
- LaTeX 页:class="katex" 76、katex-display 10,与基线完全一致;
块级公式不再被 expressive-code 吞掉。
- 字数/阅读时长与基线逐篇一致(830/4、1042/5、416/2)。
- pnpm build 41 页 + pagefind 通过;astro check 仍是 1 error/0 warnings
(原有 footer.astro 报错,与本次无关)。
|
2026-09-17 17:52:56 +08:00 |
|
TimeCrackbot
|
26e873b9f6
|
refactor: Markdown 管线迁移到 Sätteri(Phase 1 + Phase 2)
把 markdown.processor 从 unified() 换成 Astro 7 的默认管线 satteri(),
并把原来 12 个 remark/rehype 插件逐一移植到 Sätteri 的 MDAST/HAST 插件模型。
内置能力直接替代(零代码)
- remark-math → features.math
- remark-directive → 未启用(见下)
- rehype-slug → satteriHeadingIdsPlugin()
新增 src/plugins/satteri/(6 个插件,约 200 行)
- reading-time.mjs after 钩子写 ctx.data.astro.frontmatter.minutes/words
- excerpt.mjs 取第一段写 frontmatter.excerpt
- shift-headings.mjs 工厂按 fileURL 判断,只对 posts 下的文章生效
- sectionize.mjs remark-sectionize 的等价实现(递归分组 + data.hName)
- autolink-headings.mjs 标题锚点,输出与 rehype-autolink-headings 逐字一致
- image-lightbox.mjs 上一版 rehype 图片灯箱的 HAST 版
删除(已迁移或本就无效)
- remark-reading-time / remark-excerpt / remark-shift-headings /
remark-directive-rehype / rehype-component-admonition /
rehype-image-lightbox —— 共 6 个旧插件文件
- 未启用 features.directive:内容里的 `::: tip`(冒号后有空格)和
`> [!tip] Tip` 在迁移前后都渲染成普通段落/引用,属于死语法;
保持现状以免升级顺手把它激活。
行为对齐
- smartPunctuation: { dashes: false } —— Astro 的 unified 管线会把直引号
排成弯引号但不转换 ---,Sätteri 默认会转,显式关掉 dashes 才能逐字一致。
验证(与 unified() 构建逐页对比,41 页)
- 正文 HTML 完全一致 35 页;把 HTML 实体和表格对齐写法归一化后,
只剩 3 页有差异:1 页是 KaTeX 尚未迁移(见下),2 页是中文/emoji 旁的
引号方向(Sätteri 的结果更正确)。
- meta description 仍由 excerpt 正确生成;阅读时长与基线一致。
- astro check:1 error / 0 warnings,与迁移前完全相同(原有 footer.astro 报错)。
- pnpm build 41 页通过;dev server 正常。
尚未迁移
- KaTeX:Sätteri 的 math 只负责解析,不渲染。数学公式目前落成
<code class="language-math">,是可见的回归,Phase 3 处理。
- package.json 里 remark-*/rehype-* 依赖暂未清理,等 Phase 3 确定后再收。
|
2026-09-17 17:38:37 +08:00 |
|
TimeCrackbot
|
c1643ae95d
|
feat: 文章正文图片支持灯箱;删除未使用的 GitHub Card 插件
灯箱
- 相册页原本已有一套无依赖灯箱(事件委托 + ClientRouter 友好),
但它写在 gallery/[album].astro 里,只有相册页能用。
现抽成 src/components/ImageLightbox.astro,挂到 BaseLayout,全站可用。
- 新增 src/plugins/rehype-image-lightbox.mjs:给正文里的 <img> 注入
data-lightbox-src。跳过链接内的图片(点击应跳转)和显式标记
data-lightbox-ignore 的图片。
- 顺带让灯箱大图继承原图的 alt 文本(原先固定为空)。
- 正文图片加 cursor: zoom-in 提示。
清理
- 删除 src/plugins/rehype-component-github-card.mjs(165 行)及其在
rehypeComponents 里的 github 映射:内容里从未使用过 ::github 指令。
验证:构建 41 页通过;文章页正文图片 4/4 带上 data-lightbox-src,
相册页 5 个触发元素不受影响;灯箱脚本按页内联(2.8KB 压缩后);
正文渲染文本与线上基线一致,无回归。
|
2026-09-17 17:29:23 +08:00 |
|
TimeCrackbot
|
738fe3175e
|
chore: 升级 Astro 5.16.5 → 7.3.3
依赖
- astro 5 → 7.3.3,@astrojs/{mdx,react,rss,sitemap,check}、astro-expressive-code
与 @swup/astro 同步升到最新
- 新增 @astrojs/markdown-remark(Astro 7 默认改用 Sätteri 处理器,
本项目依赖大量 remark/rehype 插件,故显式固定回 unified 管线)
内容集合迁移到 Content Layer API(Astro 6 已移除旧 API)
- src/content/config.ts → src/content.config.ts,三个集合改用 glob() loader
- z 改从 astro/zod 导入
- 所有 entry.slug → entry.id;entry.render() → render(entry)
Astro 7 兼容
- 修复 bookshelf-content.astro 里多行 {/* */} 注释导致的 Rust 编译器
"Unterminated regular expression"
- 删除该文件里一处多余的 </div>(旧 Go 编译器会静默纠正,新编译器不会)
- global.css: @import "tailwindcss" → "tailwindcss/index.css"
(Vite 8 不再解析裸包名的 style 条件)
- astro.config.mjs 显式设置 compressHTML: true,保持 v6 的空白处理行为
验证:构建 41 页通过;与线上(Astro 5 构建)对比 39 个 URL 无一丢失,
仅新增新文章 DIY-computer 的 2 个 URL;逐页渲染文本与线上一致;
pnpm build 与 dev server 均正常。
|
2026-09-17 17:14:08 +08:00 |
|
TimeCrackbot
|
fe9adb246f
|
文章更新
|
2026-09-17 16:58:41 +08:00 |
|
TimeCrackbot
|
426c21b93c
|
文章更新:为小站更新内容<1. 我的台式机组装好了;2.偶得1篇>
|
2026-09-17 16:47:03 +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 |
|
TimeCrackbot
|
c597427b9a
|
chore: 优化文章结构,把一些之前用AI生成的文章都删除掉了
|
2026-09-15 19:53:43 +08:00 |
|
dsh
|
23484a0433
|
new-post / new-thought:漏参数时先说清原因,不再像脚本崩了
无参数调用时脚本会打印用法并 exit 1(语义是对的:缺必填参数),
但 pnpm 会再补一句 "[ELIFECYCLE] Command failed with exit code 1",
看起来像脚本崩了而不是用法提示。
改成在用法前面先输出一行:
缺少正文内容,没有创建任何文件。
正确写法:pnpm new-thought "今天把树莓派的散热换掉了。"
exit 码不变(无参数 1、--help 0),只是把原因说清楚。
|
2026-09-15 19:49:40 +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 |
|
dsh
|
9a822e7105
|
关于页移除技术栈标签
- 删掉「关于本站」里那排 emoji 标签(🐧 Linux / 🐳 Docker / 🚀 Astro …)
- 一并删掉只为它存在的 skills 数组(删掉渲染后就没引用了)
- 顺手修复:手动删除时把上一节的 </section> 也一起带走了,JSX 变成
4 个 <section> 对 3 个 </section>,构建直接报
`Unexpected closing "div" tag does not match opening "section" tag`(:165)
- 清掉删除后残留的一行游离空格
验证:pnpm build 退出码 0;dist/about/index.html 里 🐧🐳🚀📋 / VS Code
均消失,章节只剩 关于我 / 关于本站 / 博客旅程 / 评论
|
2026-09-15 17:51:54 +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
|
056b5faf98
|
去重「我的介绍」:页脚改放站点信息卡片,关于页入口只留在侧栏
「我的介绍」重复
- 页脚原来那栏和侧栏作者卡片是同一份内容(同头像、同站名、同一句签名),
手机端首页从头刷到尾会看到两次
- 页脚那栏整栏删除,只保留侧栏作者卡片
- 空出来的左侧位置给站点信息卡片
站点信息改成卡片
- 从原来横跨全宽的裸信息带,改成和侧栏作者卡片/分类卡片同一套语言:
bg-card + border-border/50 + rounded-xl + p-5,标题带那道红色短竖线
- 内部 2 列 × 3 行:建站时间 / 已运行 / 文章 / 偶得 / 总字数 / 最近更新
- 桌面页脚高 529 -> 476px;手机 822 -> 760px(相比最初的 957px 共省 197px)
关于页入口
- 只留在侧栏作者卡片:站名和签名两行包在同一个 <a href="/about/"> 里
- 按要求去掉所有 hover 装饰(原来有头像描边转主色、站名转主色、箭头位移),
也不再放「关于我 →」提示,两行就是安静的文字链接
- 头像不参与:下面社交图标本身是 <a>,<a> 不能嵌套 <a>
验证(headless Chrome 131,禁用缓存)
- 页脚站点信息卡片计算样式:bg oklch(0.98 0.011 84)、border 1px …/0.5、
radius 12px、padding 20px,与侧栏卡片一致
- 页脚内已无「时之刃的小站 / 只是将博客作为新的爱好的普通人」字样
- 侧栏 <a> href=/about/,链接文本为「时之刃只是将博客作为新的爱好的普通人!」,
className 为空(无 hover 类);点名字跳转 /about/ 正常
- a a 嵌套数 0,无横向溢出;桌面/手机截图正常
|
2026-09-15 10:05:55 +08:00 |
|
dsh
|
0cfcbd060e
|
页脚改版:删掉重复的导航栏,桌面补站点信息;我的介绍可点去关于页
页脚「导航」栏
- 它是顶部导航的逐项复制(9 条名字和目标完全一样),手机上白占 312px
- 已整栏删除;桌面端改用「最新文章」(最近 4 篇,按发布时间倒序,
不把置顶提前),把重复变成发现
- 手机端「最新文章」隐藏(上面就是文章列表,再列一遍没意义)
- 不影响 SEO:顶部导航 hidden md:flex 和移动端菜单里的同一批链接
在每页 HTML 里都还在,爬虫照样抓得到
站点信息(新增)
- 新增 src/lib/site-stats.ts:文章数/偶得数/分类数/标签数/总字数
在构建期算;「已运行 N 天」「最近更新」由页脚内联脚本按真实时间刷新,
避免站点久不重建时数字停在构建那天;服务端先渲染构建时兜底值,关 JS 不空
- 页脚加一条站点信息带:建站时间 / 已运行 / 文章 / 偶得 / 总字数 / 最近更新
桌面 6 列一行,手机 3 列两行
- 实测数值:2026-07-17 建站、已运行 60 天、30 篇文章、8 条偶得、
2.9 万字、最近更新 59 天前
「我的介绍」跳关于页
- 页脚 BRAND 栏整块包 <a href="/about/">,加 hover 反馈(头像描边转主色、
站名转主色、右上箭头位移)和常显的「关于我 →」提示(手机没有 hover,
不能只在 hover 才出现)
- 侧栏作者卡片同样处理。注意这里**只包到签名那一段** —— 下面的社交图标
本身是 <a>,<a> 不能嵌套 <a>;页脚 BRAND 栏没有嵌套链接,所以可以整块包
- 两处都给 aria-label,避免读屏把「头像 alt + 站名 + 签名」念成链接名
工程改动
- footer.tsx -> footer.astro:React 组件不能在构建期 await 统计数据,
换成 Astro 组件后可以直接取;12 处引用同步改成默认导入
- README 补「页脚」一节,并修正组件路径
验证(headless Chrome 131,禁用缓存)
- 桌面 1280:页脚 529px,三栏(我的介绍/最新文章/联系)+ 站点信息 + 底栏,
页脚内 nav 链接数 0,无横向溢出
- 手机 390:页脚 822px(原 957),最新文章 display:none,三栏只剩两栏
- 点页脚「我的介绍」-> /about/;点侧栏作者卡片 -> /about/,均正常
- 页面内 `a a` 嵌套数量:页脚 0、侧栏 0
|
2026-09-15 09:55:26 +08:00 |
|
dsh
|
5532c35064
|
浅色改为暖纸底 + 纸纹底 + 移动端分类胶囊条
浅色配色(global.css,暗色未动)
- 纯白底在屏幕上偏刺眼、大面积纯色没有视觉落点,整套浅色 token
压到 L*≈96 并给暖黄彩度(oklch hue 84),墨色换成暖褐而非纯黑
- background #f8f3e9 / surface-subtle #f4eee3 / card #fcf8f0(比页面底亮,
靠明度差拉层次)/ foreground #221d18 / border #dfd9ce
- 对比度仍留足:正文 15:1、content-secondary 7.5:1、muted-foreground 5.3:1、
主色链接 4.9:1(AA 要求 4.5:1)
- secondary / sidebar / popover 等原来偏中性的 token 一并转暖,避免冷暖打架
纸纹底
- --paper-noise 用内联 SVG feTurbulence 分形噪声,无需图片文件;
feColorMatrix saturate=0 去饱和得到带随机 alpha 的灰颗粒,
因此不需要 mix-blend-mode 就能亮暗通用
- body::before 铺成 position:fixed 整屏颗粒,z-index:1(压在正文上、
页眉 z-50 / 菜单 z-60 之下),pointer-events:none
- 颗粒浓度:亮色 0.2 / 暗色 0.22。实测亮度标准差 0.05→0.7、0.2→1.9、
0.3→2.9(0=完全平整),选 2 左右这个「看得出是纸但不觉得脏」的档位
- 顺带让 backdrop-filter 有细节可模糊,此前纯色底上磨砂等于不存在
移动端分类胶囊条(article-list.tsx + sidebar.tsx)
- 移动端侧栏被排在文章列表下面(实测首篇 y=999、侧栏 y=3212),
分类筛选基本摸不到;现在列表顶部多一条吸附胶囊条
- 复用同一份 categories / activeCategory / handleCategoryChange,不写第二套;
末尾胶囊在「分类 / 标签」间切换;两端渐隐提示可横向滑;滚动条藏掉
- 把当前项自动滚到中间,只操作这条横向容器,不动页面纵向位置
- sidebar.tsx 的分类/标签块加 hidden lg:block,避免同页出现两份
其他
- 新增 --header-h: 69px(页眉实测高度),移动端菜单面板和吸附胶囊条
都改用它定位,不再各处硬编码 69/76
- README 补「浅色配色」「纸纹底」「移动端分类胶囊条」三节
验证(headless Chrome 131)
- 390px:胶囊条可见、侧栏两块 display:none;点「思考」→ ?category=思考、
列表 10→4 条、当前项高亮;切到标签模式列出 35 个标签;无横向溢出
- 1280px:胶囊条隐藏、侧栏分类恢复显示(display:block)
- 亮/暗两套截图正常,书架、文章页均无异常
|
2026-09-15 09:37:14 +08:00 |
|
dsh
|
9d9f87a013
|
移动端美化:悬浮磨砂导航菜单 + 保守档字号
菜单(site-header.astro)
- 全屏遮罩居中大链接 -> 仿 Firefly float-panel 的悬浮磨砂卡片:
fixed top-[76px] 左右各留 12px,rounded-2xl,浅阴影,max-h 兜底防横屏溢出
- 菜单项 30px -> 18px,行高 44px,圆角 hover 底色;外链右侧加 ↗
- 当前页在构建期用 Astro.url.pathname 判定,高亮为主色文字 + 淡主色底
+ 正文标题那道红色短竖线(滑入/当前项显示)
- 入场动画改为「面板落下 + 逐项上浮」,节奏从 420ms 收到 300ms
- 遮罩从纯色全屏改为 background/45% + 极轻模糊,点它关闭
- JS 未改:data-open / ESC / body 滚动锁 / astro:before-swap 复位 / aria 全部沿用
- 补 :focus-visible 自定义焦点环(替掉浏览器默认那圈)、prefers-reduced-motion、
prefers-reduced-transparency、@supports 回退
磨砂
- global.css 新增 --glass-bg / --glass-border / --glass-blur / --glass-saturate,
由 --card 派生所以亮暗自动跟随
- 移动端页眉仍保持关闭常驻磨砂(原来就是有意为之),只有点开的菜单面板用
字号(只动 <768px,保守档)
- 正文/引用/列表 16.5px/1.85 -> 15.5px/1.78,行高密度约省 10%
- 文章 h1 30 -> 27px;正文 h2 30 -> 25;h3 24 -> 21;h4 20 -> 18
- 列表区标题 24 -> 21px
- 桌面端用 md: 前缀原样恢复
验证(headless Chrome 131,390x844 + 1280/800/700)
- 390px:正文 15.5/27.59、h1 27、菜单项 18;面板 445px 高、底边 511 < 844
- 1280/800px:正文 16.5/30.525、h1 48px,与改动前一致
- 亮/暗两套截图正常,无横向溢出
|
2026-09-15 09:03:24 +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
|
4810c87d30
|
修复评论区不渲染:id 全局变量遮蔽导致脚本未加载
容器是 <div id="twikoo">,浏览器会把带 id 的元素暴露成 window 上的同名
全局变量,所以脚本加载前 window.twikoo 已指向那个 DOM 元素。原守卫
if (window.twikoo) 因此误判「已加载」而直接返回,真正的 twikoo 库从未被加载,
表现为只显示「评论」标题、容器为空。
改为检查真正的 API:typeof window.twikoo?.init === "function"。
验证(jsdom 对线上页面实测):init 为函数,容器渲染 23040 字节,
提交框/昵称/textarea 齐全,历史评论 |´・ω・)ノ 正常显示,无报错。
另:deploy.sh 的 PI_SITE_PATH 改为 /home/pi/www/Astro_firefly/(覆盖部署)
|
2026-09-14 21:08:46 +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
|
686b1caa7d
|
新增 new-post 脚本与操作指南文档
- scripts/new-post.mjs + pnpm new-post:按标题建文章,支持 --category/--tags/
--description/--image/--file/--pinned/--draft,标题里的冒号引号会正确转义
- docs/操作指南.md:写文章、发偶得、加相册、预览、检查、部署的完整流程
- 修复 astro check 报出的 2 个类型错误(gallery 索引页 querySelector 未指定
HTMLElement,导致 dataset 不可用)。现在 pnpm check 为 0 error
|
2026-09-14 20:50:22 +08:00 |
|
dsh
|
e029c69899
|
删除 9 个孤儿配图:8.72 MB
这些文件只出现在 vitepress-blog-guide.md 的代码块示例里,从未被真实渲染。
删除后 public/assets 从 9.1 MB 降到 280 KB。
|
2026-09-14 20:47:52 +08:00 |
|
dsh
|
8ecc08cfce
|
压缩文章配图:9 张转 WebP,1.99 MB -> 0.25 MB
- 限宽 1920px、质量 82;有真实透明通道的两张(ubuntu-2604-desktop、
墨菲定律图1)保留 alpha,其余去 alpha 转 RGB
- 同步更新 8 个 markdown 文件中的 9 处引用(含 Caddy 那篇的 frontmatter)
- Caddy.png 1368 KB -> 22.8 KB(原为截图存成 PNG)
- 已核对:全项目 0 处缺失引用
|
2026-09-14 20:47:00 +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 |
|