1006 Commits

Author SHA1 Message Date
xfy
b309f2dbc1 chore: release v0.3.0
Some checks failed
CI / check (push) Failing after 4m42s
CI / build (push) Has been skipped
Comment system, post trash, View Transitions theme animation, Tiptap image
upload coordinator, blur-up progressive images, lightbox & yggdrasil-core
subprojects, session/CSRF hardening, image Cache-Control/ETag, Dockerfile,
Gitea Actions CI, plus numerous performance and security improvements.
v0.3.0
2026-06-29 16:12:18 +08:00
xfy
74992d272f docs(deployment): uncomment XFF in nginx example
Keep X-Forwarded-For as an active default so the snippet is
copy-paste safe; TRUSTED_PROXY_COUNT=1 relies on the proxy
rewriting XFF, and a commented-out line is easy to miss.
2026-06-29 15:59:54 +08:00
xfy
5e4f32f2ab docs(main): fix misleading APP_BASE_URL comment
warn_if_app_base_url_unset() is unconditional—localhost dev also
emits a WARN (per csrf.rs doc). The main.rs side note claimed
localhost stays silent, contradicting the implementation.
2026-06-29 15:59:54 +08:00
xfy
62fe87961f chore(build): add clippy and fix targets to Makefile
Some checks failed
CI / check (push) Failing after 5m19s
CI / build (push) Has been skipped
2026-06-29 15:55:51 +08:00
xfy
431e6e1db4 fix(lint): resolve clippy warnings in comment_storage tests and trash.rs
- comment_storage.rs: group digits consistently (3600_000 → 3_600_000)
- trash.rs: remove unused `use super::*` in test module
2026-06-29 15:54:49 +08:00
xfy
48a328f553 feat(admin): add decorative image to tiptap editor with focus-within fade effect 2026-06-29 15:45:24 +08:00
xfy
962bef2276 fix(ssr-cache): log generation bump and effective SSR_CACHE_SECS
Dioxus 0.7 的增量渲染器把 IncrementalRenderer 封装在 FullstackState 内部
(pub(crate)),应用侧无法拿到句柄调用 invalidate(),世代号机制只是"未来就绪"
状态。实际失效仍依赖 SSR_CACHE_SECS 兜底 TTL,但此前写入路径完全静默,部署者
无法从日志判断"文章已写入、只是 SSR 缓存未失效",易误判成 DB/发布问题。

- bump_global_generation() 增加 info 日志(带 new_generation),诚实说明 Dioxus
  0.7 不读取此值、需等 TTL 过期。
- main.rs 启动时打印生效的 SSR_CACHE_SECS(滞后上界),提示可调小缩短滞后。
2026-06-29 15:42:40 +08:00
xfy
45811df96e fix(comments): add md-content class to comment item to fix syntax highlighting and blank line issues 2026-06-29 15:42:08 +08:00
xfy
408b29dd9d feat(assets): add xiantiaoxiaogou decorative image 2026-06-29 15:34:47 +08:00
xfy
8855cdd49d fix(styles): add @source to input.css to ensure tailwind scans rust files 2026-06-29 15:31:37 +08:00
xfy
656e35c79f fix(comments): move decorative image properly inside textarea background layer 2026-06-29 15:20:48 +08:00
xfy
0b53e968c1 feat(comments): add decorative image to comment input with focus fade effect 2026-06-29 14:42:03 +08:00
xfy
fbd706b198 style: format files and update about page content
- Update about page content

- Format code in admin pages, tags, and theme modules
2026-06-29 14:31:04 +08:00
xfy
d1b5b8ee4e fix(ui): suppress unused variable warning for active param in server build 2026-06-29 14:29:45 +08:00
xfy
369b4838a3 style: add brightness filter to images in dark mode
Some checks failed
CI / check (push) Failing after 5m7s
CI / build (push) Has been skipped
2026-06-29 14:16:44 +08:00
xfy
ae770cae3a feat(ui): use EmptyState component for search no results 2026-06-29 14:14:03 +08:00
xfy
23f0cc6222 fix(ui): adjust search placeholder size and position 2026-06-29 14:10:21 +08:00
xfy
b366c00e74 fix(ui): enlarge and better center search placeholder image 2026-06-29 14:07:35 +08:00
xfy
b666472193 fix(ui): add margin between post count and list in tag detail page 2026-06-29 14:05:47 +08:00
xfy
3ade2569df chore(assets): add new empty state image for search page 2026-06-29 14:03:10 +08:00
xfy
40114b603c fix(css): remove redundant .dark .blur-img causing grey background on loaded images 2026-06-29 14:00:08 +08:00
xfy
3f7d112898 feat(pages): add empty placeholder image to search page 2026-06-29 13:55:08 +08:00
xfy
528a79fb83 feat(pages): add empty state to tags and tag detail pages 2026-06-29 13:50:05 +08:00
xfy
373498870a style: apply cargo fmt to workspace
Some checks failed
CI / check (push) Failing after 5m35s
CI / build (push) Has been skipped
2026-06-29 13:47:40 +08:00
xfy
5e1becf116 fix(admin): explicitly set pointer-events auto for trash settings panel to resolve click bug 2026-06-29 13:46:05 +08:00
xfy
ef8af77a08 style(admin): format trash.rs 2026-06-29 13:42:29 +08:00
xfy
fdaefae027 test: fix test_auto_purge_settings_has_transition_class false positive 2026-06-29 13:37:59 +08:00
xfy
768dbc9510 feat(admin): add smooth slide-down animation to trash auto-purge settings panel 2026-06-29 13:34:43 +08:00
xfy
a47a5a6ac9 feat(admin): update empty state for trash page 2026-06-29 13:26:45 +08:00
xfy
c69a632e75 fix(ui): trigger FilterTabs indicator animation on click 2026-06-29 13:24:52 +08:00
xfy
3daa09efc2 fix(ui): fix WASM compilation error in FilterTabs indicator animation 2026-06-29 13:22:22 +08:00
xfy
ec5f933191 feat(ui): add smooth sliding animation to FilterTabs active indicator 2026-06-29 13:20:39 +08:00
xfy
d91a56f8b2 refactor(admin): extract comments filter tabs into FilterTabs component 2026-06-29 13:15:50 +08:00
xfy
79af7d345e fix(admin): 修复重建内容后标题行纵向错位
点击「重建内容 / 重建全部」后,结果消息撑高了 RebuildCacheBar,外层
header 的 items-center 据此重新居中,把「文章管理」标题与「+ 写文章」按钮
整体下移,而重建按钮停在容器顶部,造成三者不再同处一行。

根因:c024de1 抽取 RebuildCacheBar 时把结果消息纳入子组件的 flex-col 文档流
(重构前消息是页面级兄弟节点,不参与 header 居中计算)。

修复:根容器改 relative,结果消息用 absolute 悬挂于按钮行下方、脱离文档流,
组件盒高恒等于按钮行高度,无论消息是否出现都不影响 header 的垂直居中。

验证:dx check + cargo clippy 全绿。
2026-06-29 11:49:28 +08:00
xfy
a1aef5bda9 fix(admin): add cursor-pointer to comment status filter buttons 2026-06-29 11:41:52 +08:00
xfy
dbe95f1173 feat(admin): use global EmptyState component in comments management page 2026-06-29 11:39:32 +08:00
xfy
72d21c6670 feat(admin): use global EmptyState component in posts management page 2026-06-29 11:38:50 +08:00
xfy
46e9a29f1e fix(theme): 消除 ThemeToggle 在 wasm/server 构建的 unused_mut 警告
Some checks failed
CI / check (push) Failing after 6m25s
CI / build (push) Has been skipped
dx build 的 wasm target 报两条 unused_mut:

- theme (160行): wasm 端的 theme.set 被非 wasm cfg 分支剥离,写操作转移
  到副本 theme_clone,theme 本身在 wasm 下只被读取/Copy。加
  #[cfg_attr(target_arch = "wasm32", allow(unused_mut))]——仅 wasm 端压住,
  server 端仍需 mut(theme.set(next) 实际存在)。
- gen_clone (191行): 闭包内只读 gen_clone(),从未 set,两端都不需 mut,
  直接删除。

顺带把原来无条件挂在 click_gen 上的 #[allow(unused_mut)] 改成
#[cfg_attr(not(target_arch = "wasm32"), ...)]——click_gen 只在 wasm 分支被
set(189行),server 端该分支被剥离。改为按 cfg 方向标注,与 theme 对称,
语义更精确(不再无差别压住 wasm 端的检查)。

匹配项目既定模式(post_cover.rs:20 的 cfg_attr allow)。零行为变更,
dx check / cargo check(双 target) / clippy / theme 测试均通过。
2026-06-29 11:31:57 +08:00
xfy
b923851284 docs(main): 注明 CompressionLayer 默认跳过 image/*
Some checks failed
CI / check (push) Failing after 5m37s
CI / build (push) Has been skipped
避免后续误以为压缩层会对 WebP/PNG/JPEG 等已是压缩格式的图片再次
压缩而浪费 CPU。tower-http 的 DefaultPredicate 开箱即跳过 image/*
(例外 image/svg+xml)、gRPC、SSE 及 <32 字节响应,无需额外配置。

纯文档性注释,无行为变更。
2026-06-29 11:16:30 +08:00
xfy
74f8c212f6 feat(csrf): warn at startup when APP_BASE_URL is unset
APP_BASE_URL 未设置时 trusted_origin 回退到请求 Host 头推导本站 origin,
反向代理后若 Host 头可被客户端影响存在 CSRF 绕过风险。.env.example 虽然
警告了,但默认值就是空——'cp .env.example .env 后忘改' 是最常见的部署失误。

加启动时一次性 WARN(与 image.rs 的启动告警同范式):
- warn_if_app_base_url_unset() 在 main.rs 启动序列调用,与 validate_database_url
  等配置告警归在一处
- 抽出纯函数 app_base_url_is_set() 承载判断逻辑,便于测试,打日志副作用与之解耦
- 5 个单测覆盖 unset/empty/whitespace/set/trim 边界

每请求路径的 trusted_origin 保持纯函数不变,不引入 dedup 状态或刷屏风险。
2026-06-29 11:02:58 +08:00
xfy
c237007111 docs: add production deployment guide
服务端的安全逻辑(会话 Cookie Secure 标志、限流按真实客户端 IP 聚合、
CSRF origin 校验)都默认前置反向代理并终结 TLS,但缺少一份成体系的部署
文档说明这一点。不知情的部署者直接把 3000 端口暴露到公网 HTTP 会同时踩中
cookie 无 Secure、限流退化/可伪造、CSRF Host 回退可绕过三个坑。

新增 docs/DEPLOYMENT.md:
- 醒目的前置警告,禁止裸暴露 3000 端口到公网 HTTP
- nginx + Caddy 最小配置示例(含 XFF 覆写、body 上限对齐应用侧 10 MiB、
  代理超时对齐应用侧 300s)
- 生产环境必设变量三件套及 TRUSTED_PROXY_COUNT 设错的两种后果
- Docker 部署示例(绑定回环地址,反代作为唯一公网入口)
- 部署后验证清单

README 加「生产部署」节链接到该文档。代码无需修改——三个环境变量的保守
默认值与 .env.example 的警告注释设计上是正确的,缺口纯粹是文档。
2026-06-29 10:55:24 +08:00
xfy
8ec4ecd310 chore: migrate JS subprojects from npm to pnpm
Some checks failed
CI / check (push) Failing after 4m41s
CI / build (push) Has been skipped
Switch tiptap-editor, lightbox, and yggdrasil-core from npm to pnpm.
Replace package-lock.json with pnpm-lock.yaml and update Makefile accordingly.
2026-06-29 10:35:04 +08:00
xfy
cb73a9b979 chore: fix cargo clippy warnings (unused import and false positive unused_mut) 2026-06-29 10:14:27 +08:00
xfy
178870427c feat(ui): refactor EmptyState to accept dynamic string props and add empty state to archives page 2026-06-29 10:11:00 +08:00
xfy
824ad5a3d3 chore(Makefile): remove build hints and start target
Build instructions have been moved to AGENTS.md.
The verbose echo messages and the standalone start target
are no longer needed.
2026-06-29 09:59:14 +08:00
xfy
7615def3d1 fix: add required [web.resource.dev] for dioxus 0.7.9
dioxus-cli 0.7.9 requires a `dev` sub-table under [web.resource].
Added [web.resource.dev] with the same style/script arrays as the
production [web.resource] section.
2026-06-29 09:56:07 +08:00
xfy
18db852f30 fix(build): correct asset path resolution for local release build and remove duplicated resources 2026-06-26 18:35:48 +08:00
xfy
225c477f8c chore(theme): remove debug prints 2026-06-26 18:27:27 +08:00
xfy
82a8c511fc fix(theme): remove dark class from AppRouter div 2026-06-26 18:24:00 +08:00
xfy
230ec60f24 fix(theme): remove transition from body to fix VT snapshots
The CSS transition on the body's background-color (0.3s ease) was
causing the browser's View Transitions to capture a stale snapshot
during the Dark -> Light change. Even though the .dark class was
removed synchronously and we tried to disable transitions via an
!important override class, the interaction between Tailwind classes
and the raw CSS transition on body still caused the root VT snapshot
to render as Dark when it should have been Light.

By removing the transition from body entirely (which is redundant
anyway since we're using View Transitions for theme changes), the
body jumps to its target color instantly, guaranteeing the NEW
snapshot accurately reflects the final Light theme, eliminating
the 'ghost circle' or 'circle outline' bug.
2026-06-26 18:21:13 +08:00