fix: 空评论列表 500,并完善撤回审计与角色说明
空切片 JSON 统一为数组;撤回保留正文供站长阅读,成员侧居中提示与重新编辑;头像支持拖放;角色弹窗补全职责说明并汇入封禁。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
31
frontend/lib/visibilityReconcile.ts
Normal file
31
frontend/lib/visibilityReconcile.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 回前台 HTTP 对账限频。
|
||||
*
|
||||
* 多组件(Header / 通知铃 / 聊天侧栏 / ThemeSync / 管理后台)都会在
|
||||
* visibilitychange 时拉一次状态;短时间切标签会叠加请求。
|
||||
* 本工具保证「同一订阅在 minGapMs 内最多执行一次」。
|
||||
*/
|
||||
|
||||
/** 与 ThemeSync 对齐:10s 内不重复对账 */
|
||||
export const VISIBLE_RECONCILE_GAP_MS = 10_000;
|
||||
|
||||
/**
|
||||
* 监听 document 重新可见;限频后调用 run。
|
||||
* 返回取消订阅函数。
|
||||
*/
|
||||
export function onDocumentVisible(
|
||||
run: () => void,
|
||||
minGapMs: number = VISIBLE_RECONCILE_GAP_MS
|
||||
): () => void {
|
||||
if (typeof document === "undefined") return () => {};
|
||||
let lastAt = 0;
|
||||
const onVisible = () => {
|
||||
if (document.visibilityState !== "visible") return;
|
||||
const now = Date.now();
|
||||
if (now - lastAt < minGapMs) return;
|
||||
lastAt = now;
|
||||
run();
|
||||
};
|
||||
document.addEventListener("visibilitychange", onVisible);
|
||||
return () => document.removeEventListener("visibilitychange", onVisible);
|
||||
}
|
||||
Reference in New Issue
Block a user