Files
im_webapp/web/src/features/settings/GeneralSettingsPage.tsx
T
Your NameandClaude Sonnet 5 37d08e8989 feat(web): 用符合系统风格的组件替换全部 window.alert/confirm
全项目搜出15处 window.confirm、9处 window.alert(其中3处是各文件
各自复制的 notImplemented() 辅助函数,文案还都一样)用在退出登录、
删除消息/收藏/好友、清空聊天记录、解散群聊、转让群主、危险链接
二次确认等场景——全是浏览器原生弹窗,样式和整个应用的设计语言完全
脱节。

新增两个全局UI基础设施(Zustand store + 挂载在App.tsx根节点的
渲染组件,参照stores/calls.ts/messageJump.ts已有的"任何组件都能调用"
惯例,不是每个弹窗各自管理一份本地状态):

- stores/confirmDialog.ts + app/ConfirmDialogRoot.tsx:替换
  window.confirm。requestConfirm()返回Promise<boolean>,和
  window.confirm的返回值语义一致,所以原来"if (!window.confirm(...))
  return"这一行改成"if (!(await requestConfirm({message:...})))
  return",外层函数标成async,不用大改周围逻辑。危险/不可恢复操作
  (删除、解散群聊、注销账号等)传danger:true,确认按钮变红色,
  弹窗视觉沿用转发弹窗已有的"描边取消+实心确认"按钮搭配。
- stores/globalToast.ts + app/GlobalToastRoot.tsx:替换window.alert,
  复用应用里本来就有、每个页面各自本地状态管理的Toast组件。顺手把
  3个文件里各自重复定义、文案完全一样的notImplemented()合并成
  一个共享导出。

实机验证了非危险确认(清空缓存,蓝色确认按钮)、危险确认(删除
消息,红色确认按钮)、取消按钮、Escape键取消、全局提示(点"投诉
举报")——均正常工作,且原有页面各自的Toast错误提示不受影响。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 00:08:15 +08:00

46 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from 'react';
import { Toast } from '@/app/Toast';
import { requestConfirm } from '@/stores/confirmDialog';
/**
* README §8.7 mentions a "清空缓存「126 MB」" row -- confirmed no server endpoint touches cache at
* all (docs/IM-后端问题清单.md-adjacent research: "No backend endpoint clears cache/history -- both
* are pure client-side operations"). Computing a real, honest "just this app's cache" byte count is
* not reliably possible (`navigator.storage.estimate()` reports the WHOLE origin, not a
* per-feature breakdown) -- rather than show a fabricated-looking number, this omits the size and
* just performs and confirms the real clear (this app's own Cache Storage buckets, per the SW-
* caching behavior already relied on elsewhere in this app).
*/
export function GeneralSettingsPage() {
const [status, setStatus] = useState<'idle' | 'clearing' | 'done'>('idle');
const [error, setError] = useState('');
const clearCache = async () => {
if (!(await requestConfirm({ message: '确定清除本地缓存吗?不会影响你的账号数据。' }))) return;
setStatus('clearing');
try {
if (typeof caches === 'undefined') throw new Error('此浏览器不支持缓存清除');
const keys = await caches.keys();
await Promise.all(keys.map((k) => caches.delete(k)));
setStatus('done');
} catch (err) {
setStatus('idle');
setError(err instanceof Error ? err.message : '清除缓存失败,请重试');
}
};
return (
<div className="mx-auto w-full max-w-[720px] px-5 py-8 md:px-10">
<h2 className="mb-4 text-xl font-semibold text-text-heading">通用</h2>
<div className="rounded-xl bg-white text-sm">
<button type="button" onClick={clearCache} disabled={status === 'clearing'} className="flex w-full items-center justify-between px-7 py-4 text-left">
<span className="text-text-body">清空缓存</span>
<span className="text-text-tertiary-2">{status === 'clearing' ? '清除中…' : status === 'done' ? '已清除 ›' : '›'}</span>
</button>
</div>
<Toast message={error} variant="error" onDone={() => setError('')} />
</div>
);
}