415 Commits

Author SHA1 Message Date
xfy
4e89412cde test(theme): 扩充主题模块测试覆盖
原仅 2 个 toggle 测试,补充后覆盖:
- toggle 的对合性(连续切换两次回到原值)
- Theme 的 PartialEq / Copy trait 行为
- 首屏预加载脚本的关键行为契约:读取 localStorage、
  回退 prefers-color-scheme、添加 dark class、
  包裹 try/catch 防止禁用 localStorage 时抛错

共 9 个测试,全部通过。
2026-06-15 10:57:51 +08:00
xfy
f7288cc390 style: 格式化测试代码以符合 clippy 宽度限制 2026-06-15 10:40:00 +08:00
xfy
0242534274 style(tags): 修复文档注释列表缩进以消除 clippy 警告
Some checks failed
CI / check (push) Failing after 4m52s
CI / build (push) Has been skipped
2026-06-12 19:48:10 +08:00
xfy
194611bb7e docs(bin): 补充中文注释 2026-06-12 19:45:59 +08:00
xfy
c43da3676f docs(components): 补充中文注释 2026-06-12 19:42:42 +08:00
xfy
c5d1eb117c docs(auth-pages, router, main): 补充中文注释 2026-06-12 19:31:21 +08:00
xfy
18500c9496 docs(pages-admin): 补充中文注释 2026-06-12 19:24:22 +08:00
xfy
abfab19839 docs(pages-frontend): 补充中文注释 2026-06-12 19:16:59 +08:00
xfy
1904907add docs(hooks, theme): 补充中文注释 2026-06-12 19:07:43 +08:00
xfy
671a9fea7a docs(infra): 补充中文注释 2026-06-12 19:02:37 +08:00
xfy
2db652137d docs(models, db, cache): 补充中文注释 2026-06-12 18:56:56 +08:00
xfy
a785683fc6 docs(posts): 补充中文注释 2026-06-12 18:50:17 +08:00
xfy
9921f8eebf docs(comments): 补充中文注释 2026-06-12 18:42:19 +08:00
xfy
26b012c40c docs(api, auth): 补充中文注释 2026-06-12 18:27:24 +08:00
xfy
4fe26f7eb3 test: improve unit test coverage and assertions
Some checks failed
CI / check (push) Failing after 15m51s
CI / build (push) Has been skipped
- Add tests for sanitizer, mime_to_ext, clean_tags, Theme::toggle
- Tighten assertions in highlight, markdown, post status classes
- Add boundary and XSS cases for comments, slug, rate_limit, webp
- Update Cargo.lock for serial_test dev-dependency
2026-06-12 18:13:51 +08:00
xfy
041cdf4102 test(cache): mark cache tests serial to fix parallel flakiness 2026-06-12 17:40:15 +08:00
xfy
942ac853fe refactor: tighten module-level allow attributes 2026-06-12 17:26:46 +08:00
xfy
294d60afab style: format rust code
Some checks failed
CI / build (push) Has been cancelled
CI / check (push) Has been cancelled
2026-06-12 17:14:31 +08:00
xfy
71ac08c373 feat(rate_limit): derive real client IP from X-Forwarded-For with TRUSTED_PROXY_COUNT 2026-06-12 17:13:17 +08:00
xfy
4ae7b38131 feat(auth): add Secure flag to session cookie via COOKIE_SECURE env 2026-06-12 17:02:22 +08:00
xfy
ee6aaf179c feat(posts): add batch limit and error handling to rebuild_content_html 2026-06-12 11:44:53 +08:00
xfy
835d71972c fix(admin): add missing dark mode background colors to skeleton components 2026-06-12 11:15:46 +08:00
xfy
a10bf8737c refactor(sanitizer): extract shared sanitizer module and migrate from ammonia to lol_html 2026-06-12 11:15:42 +08:00
xfy
f8fb35f8c2 fix(admin): use arbitrary value for tooltip dark text color 2026-06-12 10:55:32 +08:00
xfy
1c3f1aac34 fix(admin): flip tooltip to bottom to avoid navbar overlap
Changed from bottom-full/mb-2 to top-full/mt-2, added z-50.
2026-06-12 10:54:02 +08:00
xfy
8840faa830 fix(admin): use arbitrary dark mode values for tooltip bg
Matches project pattern of dark:text-[#dadadb] / dark:bg-[#dadadb]
for reliable Tailwind v4 class-based dark mode.
2026-06-12 10:52:05 +08:00
xfy
c62cf5a239 feat(admin): add tooltip to rebuild content button
Pure CSS tooltip appears on hover, inverted color scheme
(white-on-dark / dark-on-light) matching admin aesthetic.
2026-06-12 10:50:18 +08:00
xfy
67e23d672c feat(admin): add rebuild content button to posts management page
Outline-style button next to '写文章', calls rebuild_content_html(false)
to rebuild posts with NULL content_html. Shows result message below header.
2026-06-12 10:43:49 +08:00
xfy
f6589121da perf(markdown): eliminate duplicate clean_html call in generate_toc_html
clean_html() triggers expensive ammonia sanitization with aho_corasick.
Previously called twice for the same text (aria-label + display text).
Now calls once and reuses the result.
2026-06-12 10:36:06 +08:00
xfy
2e9d123396 feat(posts): add rebuild_content_html server function
New admin-only server function that re-renders content_html and
toc_html for posts from their content_md:
- rebuild_all=false: only processes posts where content_html IS NULL
- rebuild_all=true: processes all non-deleted posts
- Processes rows one at a time to avoid table locks
- Invalidates post list and stats caches after rebuild
2026-06-12 10:35:59 +08:00
xfy
a975e45cc9 feat(posts): store toc_html in DB on create and update
- create_post: include toc_html in INSERT alongside content_html
- update_post: include toc_html in UPDATE alongside content_html
- Both write toc_html as NULL when empty, Some(..) otherwise
2026-06-12 10:35:51 +08:00
xfy
acd85d18ce perf(posts): read pre-rendered content_html/toc_html from DB instead of re-rendering
Previously row_to_post_full() ignored the stored content_html and
re-rendered markdown with render_markdown_enhanced() on every read,
triggering expensive ammonia sanitization (aho_corasick accounted for
87% CPU in flame graph).

Now reads content_html and toc_html directly from the database row.
Falls back to render_markdown_enhanced() only for legacy posts where
content_html is NULL.
2026-06-12 10:35:39 +08:00
xfy
bd9e87128d perf(ssr): optimize request throughput by 32%
- Cache ammonia::Builder with LazyLock (was rebuilt per request)
- Enable tracing release_max_level_info to strip tracing overhead at compile time
- Remove TraceLayer and tower-http trace feature from production
- Increase DB pool size 10→20 (configurable via DB_POOL_SIZE)
- Increase SSR cache TTL 300s→3600s (configurable via SSR_CACHE_SECS)

Benchmark: 7,444 → 9,840 req/s, P99 latency 27.6ms → 11.1ms
2026-06-12 09:36:53 +08:00
xfy
8dbe564ca2 fix(write): 骨架屏与实际页面结构对齐 2026-06-11 18:12:35 +08:00
xfy
75e0659cb2 fix(admin): 后台管理页改为 CSR 避免闪烁
- dashboard: use_resource → use_signal + wasm32-only 加载
- posts: use_server_future → use_signal + wasm32-only 加载 + 乐观删除
- write: use_resource → use_signal + wasm32-only 加载
- 移除 use_server_future/use_resource 导致的骨架屏闪烁
- 操作按钮使用乐观更新,不调用 restart()
2026-06-11 18:04:07 +08:00
xfy
ea440cd61c fix(admin): 评论管理页改为 CSR 避免按钮点击闪烁 2026-06-11 17:34:39 +08:00
xfy
569eec5bf8 fix(admin): 评论管理页多项修复
- 修复默认头像无法显示:AdminComment 添加 avatar_url 字段
- 修复状态标签换行:移除 w-20 固定宽度,添加 whitespace-nowrap
- 操作按钮添加 cursor-pointer
- 已处于该状态的评论隐藏对应操作按钮
- 修复操作后页面不自动刷新:将 restart() 移到异步块内
2026-06-11 16:10:42 +08:00
xfy
b55409d421 fix(comments): remove admin action buttons from public comment item 2026-06-11 15:47:46 +08:00
xfy
3e95353cc5 fix(comments): nest pending replies under parent comments 2026-06-11 15:35:14 +08:00
xfy
44a738a940 fix(comments): migrate from use_server_future to use_resource 2026-06-11 15:19:37 +08:00
xfy
2b36a7c669 fix: resolve WASM compilation errors
- Remove tracing::warn! (tracing not available in WASM builds)
- Fix parameter names in comment_storage: _key → key, _value → value
- Add #[allow(unused_variables)] for non-WASM builds where params are unused
2026-06-11 14:55:10 +08:00
xfy
aa68dc4c55 fix(comments): address code quality issues in CommentForm
- Add mount guard (loaded signal) to use_effect to prevent re-firing
- Add in-flight guard at top of onclick handler to prevent double submits
- Prevent overwriting user input when clearing form fields
2026-06-11 14:49:48 +08:00
xfy
f855a9a6cd fix(comments): fix compilation errors in list.rs and pending_item.rs
- Fix rsx! macro syntax: can't use let inside for loop
- Revert post_id parameter name and use #[allow(unused_variables)] instead
- All components now compile successfully
2026-06-11 14:45:48 +08:00
xfy
792b06a2eb fix(comments): address code quality issues in list and pending_item
- Add key prop to CommentList for loop for Dioxus list diffing
- Rename post_id to _post_id in PendingCommentItem signature
- Remove unnecessary let _ = post_id suppression
2026-06-11 14:42:03 +08:00
xfy
8ae3299b3e feat(comments): add PendingCommentItem component
Renders pending (unapproved) comments with:
- opacity-70 for visual distinction
- amber '审核中' badge
- Client-side content_md rendering (HTML escape + newline→br)
- No reply button (server rejects replies to pending parents)
- Same depth/indent logic as approved comments
2026-06-11 14:36:05 +08:00
xfy
12a91e3b8e feat(comments): merge approved and pending comments in CommentList
- Accept both comments and pending props
- Merge into chronologically sorted list
- Route to CommentItem or PendingCommentItem per item type
2026-06-11 14:34:36 +08:00
xfy
9e658662cb fix(comments): add error logging for check_pending_status failure
Address code quality review: log warnings when the server call fails
instead of silently swallowing the error.
2026-06-11 14:33:13 +08:00
xfy
40cfd44d3a feat(comments): add pending_comments to CommentContext and sync on mount
- Extend CommentContext with pending_comments Signal
- Load pending comments from localStorage on provider init
- Run check_pending_status on mount to prune non-pending entries
- Pass both approved and pending comments to CommentList
- Include pending count in section heading
2026-06-11 14:30:49 +08:00
xfy
0f3d9fc25c fix(hooks): address code quality issues in comment_storage
- Fix is_expired: use js_sys::Date::now() on WASM, avoid format-parse roundtrip
- Make error fallback safe (expire on error)
- Restrict escape_html visibility to pub(crate)
- Only write storage in load_pending_comments when pruning actually occurs
2026-06-11 14:28:27 +08:00
xfy
fccd4c05ff feat(hooks): add comment_storage module for localStorage persistence
Provides save/load for author info (yggdrasil-comment-author) and
pending comments (yggdrasil-pending-comments) in localStorage.
- 7-day TTL with auto-pruning
- Per-post-id storage keyed by post_id string
- HTML escaping for pending content_md rendering
- All web_sys calls behind #[cfg(target_arch = "wasm32")]
2026-06-11 14:23:27 +08:00