说说评论系统全面升级:每条说说独立评论区
说说评论系统全面升级:每条说说独立评论区
为说说页面的每条动态适配独立评论区,实现自定义聊天室 UI、邮件通知导航到详情页等功能。
前言
博客的说说功能上线一段时间了,但之前只有留言板有评论区,说说页面的评论功能一直没有完善。这次花了点时间,给每条说说都加上了独立的评论区,并且重新设计了评论 UI,让整体体验更接近现代聊天应用。
功能概览
1. 每条说说独立评论区
点击说说卡片右下角的评论按钮,会弹出一个评论弹窗。每条说说的评论是独立的,通过 Waline 的 path 参数区分。

2. 自定义聊天室 UI
评论弹窗采用了留言板的聊天室风格:
- 气泡样式:深色背景白色文字的聊天气泡
- 站长标识:站长的消息显示在右侧,白色背景,并带有「站长」徽章
- 回复引用:支持回复其他评论,引用内容以边框样式展示
- 日期居中:每条评论的日期在消息上方居中显示

3. 赛车加载动画
评论弹窗打开时会显示一个赛车加载动画,最低展示 2 秒后才显示评论内容。

4. 邮件通知导航到详情页
当有人回复你的评论时,Waline 会发送邮件通知。邮件中的链接会直接跳转到对应的说说详情页(如 /moments/2026-07-25/),而不是动态列表页。

技术实现
评论弹窗组件
评论弹窗使用 Svelte 5 实现,核心是 CommentModal.svelte 组件:
<script lang="ts"> import { onMount } from "svelte"; import CommentSidebarDesktop from "./CommentSidebarDesktop.svelte"; import CommentSidebarMobile from "./CommentSidebarMobile.svelte";
interface Props { serverURL: string; adminNicknames?: string[]; }
let { serverURL, adminNicknames = ["团子和蛋糕"] }: Props = $props();
// 评论数据 let comments: Comment[] = $state([]); let flatComments = $derived.by(() => { // 展平嵌套评论并按时间排序 });
// 弹窗状态 let visible = $state(false); let phase = $state<"loader" | "comments">("loader");
export function open(momentId: string, commentPath: string) { // 打开弹窗并加载评论 }</script>Waline API 集成
评论数据通过 Waline REST API 获取,而不是使用 Waline 的内置 UI:
// 获取评论const res = await fetch(`${serverURL}/api/comment?path=${encodeURIComponent(path)}&pageSize=100`);const data = await res.json();comments = data.data?.data || [];
// 发送评论const body = { comment: `<p>${text.replace(/\n/g, "</p><p>")}</p>`, nick: nickText, mail: mailText, link: linkText, url: commentPath, ua: navigator.userAgent,};await fetch(`${serverURL}/api/comment`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body),});说说详情页
为了支持邮件通知中的链接跳转,创建了说说详情页 src/pages/moments/[slug].astro:
---export async function getStaticPaths() { const moments = await getCollection("moments"); return moments.map((moment) => ({ params: { slug: moment.id }, props: { moment }, }));}---
<MomentCard moment={moment} detail={true} />
桌面端与移动端适配
评论弹窗在桌面端和移动端有不同的布局:
- 桌面端:右侧固定显示评论成员列表
- 移动端:成员列表默认隐藏,点击按钮后从右侧滑入
通过 CSS Grid 和媒体查询实现响应式布局:
/* 桌面端:两列布局 */.chat-workspace { display: grid; grid-template-columns: 1fr 11rem;}
/* 移动端:单列布局 */@media (max-width: 640px) { .chat-workspace { grid-template-columns: 1fr; } .sidebar-desktop { display: none; } .sidebar-mobile { display: block; }}
UI 设计细节
气泡样式
评论气泡参考了留言板的设计,使用 CSS 自定义属性适配深色/浅色主题:
.msg-bubble { background: var(--guestbook-bubble); color: var(--guestbook-bubble-text); border-radius: var(--radius-medium); padding: var(--space-3) var(--space-4);}
/* 站长消息 */.msg.is-admin .msg-bubble { background: var(--guestbook-admin-bubble); color: var(--guestbook-admin-text);}回复引用
回复其他评论时,引用内容以边框样式显示在气泡内部:
.msg-quote { border-left: 3px solid currentColor; padding: var(--space-2); opacity: 0.78; border-radius: var(--radius-small);}
加载动画
使用了一个赛车动画作为加载指示器,动画颜色跟随主题:
.loader > span { background: var(--deep-text);}
.base span { border-right: 100px solid var(--deep-text);}总结
这次升级让说说页面的评论体验更加完整:
- ✅ 每条说说都有独立评论区
- ✅ 评论 UI 采用聊天室风格
- ✅ 邮件通知可直接跳转到对应说说
- ✅ 桌面端和移动端都有良好的体验
后续还计划添加评论点赞、表情包等功能,让互动更加丰富。
评论区
[ 标签 ]
[ 分类 ]
[ 公告 ]
如果你喜欢,那么欢迎来到我的世界!
了解更多[ 音乐 ]
找不到相关结果。
[ contents ]
[ 全部文章 ]















