feat(comments): 匿名评论 + 表情最近使用;fix: 自动填充聚焦提示 & 邮件模板回退原版 & 返回顶部改 CSS 动画

- 匿名评论:comments.is_anonymous 列;对外昵称/头像/网址/徽标/等级/IP归属全部脱敏,
  真实身份留 users 表(回复通知照发、autofill 不受污染);邮件昵称也用「匿名」防泄露
- 表情包最近使用:面板顶部「最近」栏,localStorage 记录 8 个,零侵入复用 Artalk 插入逻辑
- 匿名开关插在 textarea 与底栏之间独立一行,不挤移动端底栏
- 自动填充:提示改 focusin 触发(原 input+sessionStorage 一次性门导致永不触发);
  已填昵称/网址时不覆盖并弹提示
- 邮件模板 UI 回退原版深色气泡设计,保留表情内联尺寸/主题文案等逻辑修复
- 返回顶部:rAF 自绘改 CSS scroll-behavior(滚动期临时挂类),修移动端掉帧
This commit is contained in:
zqlit committed 2026-10-05 09:02:23 +08:00
1 parent fb6b987132
commit 8521c3f385
11 files changed
+587 -207

No files matched your search

+11 -3
View File
@@ -428,6 +428,11 @@ export async function createComment(ctx: Ctx): Promise<Response> {
return fail(403, 'Admin access required', { need_login: true });
}
// 匿名评论:真实身份只留在 users 表(回复通知照发、自动填充不受污染),
// 对外一律显示「匿名」。管理员身份本来就不是匿名的,忽略标志。
const anonymous =
!admin && (body.anonymous === true || body.anonymous === 1 || body.anonymous === '1' || body.anonymous === 'true');
// 匿名用户:按 name+email 找或建
let author = user;
let isVerified = true;
@@ -455,8 +460,8 @@ export async function createComment(ctx: Ctx): Promise<Response> {
const t = now();
const res = await env.DB.prepare(
`INSERT INTO comments
(content, page_key, site_name, user_id, rid, root_id, is_pending, is_verified, ua, ip, ip_region, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
(content, page_key, site_name, user_id, rid, root_id, is_pending, is_verified, is_anonymous, ua, ip, ip_region, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
)
.bind(
content,
@@ -467,6 +472,7 @@ export async function createComment(ctx: Ctx): Promise<Response> {
rootId,
pending ? 1 : 0,
isVerified ? 1 : 0,
anonymous ? 1 : 0,
ua,
ip,
ipRegion,
@@ -504,7 +510,9 @@ export async function createComment(ctx: Ctx): Promise<Response> {
const siteUrl = await siteFirstUrl(env, siteName);
await notifyByEmail(env, {
newComment: row,
author,
// 匿名评论:邮件里的昵称也用「匿名」——收件人可能是任何第三方,
// 真实昵称不能从邮件漏出去(邮箱本来就是只进不出)
author: anonymous ? { ...author, name: '匿名' } : author,
parent,
parentAuthor,
siteName,