ebeec2a295
fix(comments): resolve reactivity dependency tracking in CommentSection hooks
2026-07-08 15:42:44 +08:00
a72a167a5f
fix(comment): resolve potential SSR hydration mismatch in CommentSection
2026-07-08 15:38:29 +08:00
74a74e77a8
feat(comment): render form and header persistently to eliminate layout shift
2026-07-08 15:32:24 +08:00
61c64841f9
refactor(skeletons): 统一骨架屏延迟机制,200ms 内加载不显示
...
- DelayedSkeleton 从「延迟 pulse 动画」改为「延迟渲染」:
前 200ms 完全不渲染,超时后才显示并带 pulse 动画
- admin_layout 从 use_delayed_loading hook 改为 DelayedSkeleton 包裹
- CommentListSkeleton 的两处裸用(section.rs / post_detail.rs)
补上 DelayedSkeleton 包裹
- 移除不再使用的 use_delayed_loading hook 模块
2026-07-08 14:18:08 +08:00
45f4e9cde0
refactor(ui): 去除 Rust 中硬编码颜色,统一语义色阶
...
跟随 Catppuccin 配色迁移,清理 src/ 中绕过 paper-* 语义 token 的
硬编码 dark:[#hex] 任意值,改用 Tailwind 默认灰阶(gray-700/800),
它们随主题切换自然适配。
- post.rs 状态徽章:dark:bg-[#333 ]/dark:text-[#9b9c9d] → gray-800/gray-400/500
(同步更新测试断言)
- comments/* 与 skeletons/* 的 dark:[#2a2a2a]/[#2e2e33]/[#333 ]/[#5a5a62]
→ 对应 gray-600/700/800
- trash.rs 状态灯发光圈 rgba 由旧鼠尾草绿(92,122,94) 改 Latte green(64,160,43)
- ui.rs BTN_SECONDARY 注释更新为新 Teal 强调色值
注:src/pages/admin/posts.rs 的 clippy redundant_closure 报错为既有问题,
与本次配色迁移无关,不在范围内。
2026-07-03 14:25:40 +08:00
759bbab7ee
refactor(utils): comment_storage 从 hooks/ 迁至 utils/
...
该文件全是普通函数(save_author / load_pending_comments 等),没有任何
use_ 开头的 Hook,放在 hooks/ 下名不副实。内部只剩结构体与 localStorage
读写(时间/HTML 工具已在上一 commit 拆出),迁到 utils/ 后文件名与内容
自洽,hooks/ 目录回归只放真正的渲染期 Hook。
机械替换 4 个组件文件的 use 路径(hooks::comment_storage → utils::comment_storage)。
2026-07-02 16:18:52 +08:00
dcdd72a8c2
refactor(utils): 拆分 comment_storage 的时间/HTML 工具函数
...
消除 server 端对 hooks 模块的跨层引用:
- escape_html(+ 两份重复实现:comment_storage 用 '、helpers 用 ')
统一到 utils/html.rs,单引号采用 HTML5 标准 '。
- now_millis / relative_label_from_millis / format_relative_time_iso 及其
单元测试迁到 utils/time.rs,与既有 sleep_ms 同构(wasm32/非 wasm 双版本)。
调用方迁移:
- api/comments/helpers.rs:删掉本地 escape_html,format_relative_time 改引
utils::time;其 escape_html 测试随之删除(utils/html.rs 已覆盖)。
- api/comments/create.rs:两处 helpers::escape_html 改 utils::html。
- api/markdown.rs:escape_heading_text 改 utils::html。
- components/comments/pending_item.rs:format_relative_time_iso 改从
utils::time 引入;render_pending_content 留在 comment_storage(语义紧贴
待审核评论)。
- hooks/comment_storage.rs:is_expired 的 now_millis 改引 utils::time。
comment_storage.rs 现在只剩结构体与 localStorage 读写,文件名即将自洽。
2026-07-02 16:15:23 +08:00
48a21564c4
refactor(assets): 背景图固定 opacity-10,移除动态透明度逻辑
...
动态判断不生效,统一固定为 10% 透明度,移除聚焦/有内容的条件类。
2026-07-02 11:17:41 +08:00
5fd883d7a1
feat(comments): 评论区有内容时自动调淡背景图透明度
...
与 tiptap 编辑器保持一致:无内容时 60%,有内容或聚焦时淡出到
10%。content_md 由 oninput 实时维护,输入即触发重渲染。
2026-07-02 11:14:58 +08:00
48107d8e18
refactor(assets): 评论区与后台编辑器背景图换用 xiantiaoxiaogou_input_bg
2026-07-02 10:58:52 +08:00
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
656e35c79f
fix(comments): move decorative image properly inside textarea background layer
2026-06-29 15:20:48 +08:00
0b53e968c1
feat(comments): add decorative image to comment input with focus fade effect
2026-06-29 14:42:03 +08:00
373498870a
style: apply cargo fmt to workspace
CI / check (push) Failing after 5m35s
CI / build (push) Has been skipped
2026-06-29 13:47:40 +08:00
0398cc6c66
perf(render): 列表加显式 key + release 启用 panic=abort
...
依据 Dioxus 0.7 optimizing 指南做两项改进:
- 为数据驱动列表渲染补全显式 key(13 处,9 个文件):
home/archives/tags/search 文章与标签列表、post_card/post_footer
标签、header 桌面/移动导航、admin dashboard/posts/write 列表。
使用各类型稳定唯一字段(post.id / tag / tag.name / item.label /
err.id / year_group.year / month_group.month_en)作为 key,
让 Dioxus diff 正确识别元素身份。骨架屏 for _ in 0..N 静态占位
循环与已带 key 的评论树/admin 行不动。
- [profile.release] 加 panic = "abort":WASM 去掉 unwind 元数据减小
体积;server 端错误处理走 Result+?(见 error.rs),不依赖 panic
unwind,无副作用。
其余文件为本机格式化(单行折叠/多行展开),一并提交。
验证:dx check 通过、cargo test 405 passed。
2026-06-25 18:07:22 +08:00
3df677e181
feat(comment): show real relative time on pending comments
...
待审核评论显示真实相对时间,而非永久"刚刚"
pending_item.rs 改用 format_relative_time_iso 基于创建时间动态计算
相对文本(承接上一个 relative time 重构 commit),并加 title 悬浮提示
显示原始 ISO 时间。修复待审核评论一直显示"刚刚"的问题。
2026-06-22 14:19:05 +08:00
10ef52bede
fix(comment): harden comment form with server honeypot, a11y labels, and reply layout
...
CI / check (push) Failing after 5m20s
CI / build (push) Has been skipped
四项评论区输入框修复:
1. 蜜罐服务端二次校验
- helpers.rs 新增 validate_comment_honeypot 校验器 + 单元测试
- create_comment 加 honeypot 参数,在限流后做服务端校验
- 即便机器人禁用 JS 绕过前端拦截,服务端仍返回 spam_detected 错误
- 与 rate limit 共同构成纵深防御
2. label/input 关联 (可访问性)
- 四个字段补 id + r#for 属性,用 id_suffix(顶层 root/回复用 parent_id)保证页面唯一
- textarea 原本无 label,补上"内容 *"label
3. 提交按钮右对齐 + 宽度自适应
- 新常量 COMMENT_SUBMIT_CLASS 去掉 w-full、px-4 改为 px-6
- 外层包 flex justify-end,按钮跟随文字宽度
- login/register 的全宽按钮保持不变(模态卡片场景)
4. 深层回复表单回到内容区左边缘
- CommentForm 新增 parent_indent prop,回复时用负 margin 抵消父评论缩进
- 避免 depth 越深表单被越挤越右
验证: cargo test (376 passed) / cargo clippy --all-targets (无警告) / dx check (无问题)
2026-06-22 13:45:28 +08:00
c43da3676f
docs(components): 补充中文注释
2026-06-12 19:42:42 +08:00
294d60afab
style: format rust code
CI / build (push) Has been cancelled
CI / check (push) Has been cancelled
2026-06-12 17:14:31 +08:00
b55409d421
fix(comments): remove admin action buttons from public comment item
2026-06-11 15:47:46 +08:00
3e95353cc5
fix(comments): nest pending replies under parent comments
2026-06-11 15:35:14 +08:00
44a738a940
fix(comments): migrate from use_server_future to use_resource
2026-06-11 15:19:37 +08:00
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
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
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
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
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
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
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
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
880c53d2a4
fix(comments): show name/email/url fields in reply form
2026-06-11 13:30:54 +08:00
59d5b9222a
refactor(comments): remove privacy consent checkbox and consented param
2026-06-11 13:22:57 +08:00
04737300e6
feat(comments): add complete comment system with guest commenting, moderation, and admin UI
...
Implements a fully self-built comment system for the blog:
Data layer:
- comments table with BIGSERIAL PK, parent_id self-reference (ON DELETE SET NULL),
depth tracking (max 20), status workflow (pending/approved/spam/trash),
content hashing for dedup, GDPR consent tracking, IP/UA storage with auto-purge
- 5 partial indexes optimized for read patterns
- updated_at auto-trigger
API (9 Dioxus server functions):
- Public: get_comments, get_comment_count, create_comment
- Admin: get_pending_comments, get_pending_count, get_all_comments,
approve_comment (with ancestor auto-approval), spam_comment, trash_comment,
batch_update_comment_status
Security:
- Function-level rate limiting (1/sec, burst 5) via FullstackContext IP extraction
- Input validation (name, email, URL scheme, content length, consent)
- Parent chain validation (must be approved, same post)
- Strict comment Markdown renderer (headings→strong, no img/id/data URIs, nofollow links)
- Honeypot anti-spam field
- 5-minute dedup window via SHA-256 content hash
Frontend:
- CommentSection with SuspenseBoundary isolation
- Flat-list rendering with depth-based CSS indentation (responsive)
- Gravatar via cravatar.cn (server-computed, email never exposed)
- Inline reply forms (one-at-a-time via Signal)
- Admin action buttons (approve/spam/delete) visible per-comment
- CommentForm with privacy consent, Markdown hint, loading states
Admin:
- /admin/comments page with status tabs, batch operations, pagination
- Pending count badge on admin dashboard
Infrastructure:
- Shared get_current_admin_user moved from posts/helpers to auth module
- COMMENT_LIMITER rate limiter tier
- Moka caches (60s TTL for comments, 10s for pending count)
- IP/UA purge background task (daily, 90-day retention)
2026-06-11 12:34:26 +08:00