feat(comments): 匿名评论升级为「悄悄话」——只藏内容不藏身份;fix: PJAX 瞬断自动重试

- 悄悄话:头像/昵称/头衔/等级/IP归属照常显示,仅内容对非管理员请求剥空
  (F12/网络面板拿不到原文),博主后台/登录态/邮件看全文
- 开关挪进底栏 .atk-bottom-left、表情/预览按钮右边,移动端不挤;
  回复悄悄话勾不勾随自己(去掉自动勾选)
- 前端识别:服务端剥空后 .atk-content 为空即悄悄话(空评论会被后端拒绝、
  纯表情评论有 img 不误判),无需解析 API
- 邮件页面标题书名号《》保留(按用户要求)
- PJAX 偶发「连不上服务器」:GET /api/v2 网络错误或 5xx 静默重试 2 次
  (700ms/1800ms 退避),POST 不重试,被 abort 的请求不续命
This commit is contained in:
zqlit committed 2026-10-05 10:05:21 +08:00
1 parent 215929a67f
commit 4fa592c11c
7 files changed
+183 -60

No files matched your search

+29 -1
View File
@@ -112,6 +112,30 @@
// ── 1) 记录 API 失败原因。只读不改:包装层原样返回上游响应,
// 失败时顺带 clone 一份读 body(clone 不影响 Artalk 自己读)。
// ── 1.5) 瞬断自动重试:PJAX 进文章偶尔「连不上服务器」,手动刷新就好
// —— 跨境链路抖一下(Failed to fetch / 5xx)列表就整块报错。GET/HEAD
// 幂等,网络错误或 5xx 时静默重试两次(700ms / 1800ms 退避);POST
// 绝不重试(重复提交风险);请求已被 PJAX abort 的也不再续命。
var RETRYABLE_STATUS = { 502: 1, 503: 1, 504: 1, 520: 1, 521: 1, 522: 1, 523: 1, 524: 1, 525: 1, 527: 1, 530: 1 };
function retryWait(ms) {
return new Promise(function (resolve) { setTimeout(resolve, ms); });
}
function fetchRetry(doFetch) {
var delays = [700, 1800];
function run(i) {
return doFetch().then(function (res) {
if (res && RETRYABLE_STATUS[res.status] && i < delays.length) {
try { if (res.body && res.body.cancel) res.body.cancel(); } catch (e) {}
return retryWait(delays[i]).then(function () { return run(i + 1); });
}
return res;
}, function (err) {
if (i >= delays.length) throw err;
return retryWait(delays[i]).then(function () { return run(i + 1); });
});
}
return run(0);
}
var origFetch = window.fetch;
if (typeof origFetch === 'function') {
window.fetch = function (input, init) {
@@ -141,7 +165,11 @@
fargs = [input, sansContentType(init || {})];
}
var p = origFetch.apply(this, fargs);
var self = this;
function doFetch() { return origFetch.apply(self, fargs); }
var canRetry = (method === 'GET' || method === 'HEAD') &&
!(init && init.signal && init.signal.aborted);
var p = canRetry ? fetchRetry(doFetch) : doFetch();
return p.then(function (res) {
if (res && res.ok === false) {
try {