/** * 解锁对话框。 * * 它只是**入口**,不是闸门:真正拦住改绑的是后端的 `require_unlocked`。所以这里即使 * 被人绕过、甚至被改成永远返回成功,配置也改不动。 * * # 它是"校验"而不是"弹窗" * * 这一层出现时,背后的一切都停了:整屏压暗、面板上扫过一条校验线、左下角挂着 `LOCKED`。 * 现场有人要改绑定,多半是在出问题的时候;那时候界面必须明确地说"现在这一步是在验证身份", * 而不是给出一个和别处一样的灰色小框。 */ import { useEffect, useRef, useState } from "react"; import { api } from "../lib/ipc"; interface Props { /** 为什么需要密码:显示在标题下。 */ reason: string; onUnlocked: () => void; onCancel: () => void; } export function UnlockDialog({ reason, onUnlocked, onCancel }: Props) { const [password, setPassword] = useState(""); const [error, setError] = useState(null); const [busy, setBusy] = useState(false); const input = useRef(null); useEffect(() => { input.current?.focus(); }, []); const submit = async () => { if (busy) return; setBusy(true); setError(null); try { const ok = await api.unlock(password); if (ok) { onUnlocked(); } else { setError("密码错误"); setPassword(""); input.current?.focus(); } } catch (err) { setError(err instanceof Error ? err.message : String(err)); } finally { setBusy(false); } }; return (
); }