import { useEffect, useRef, useState } from 'react'; let loader; function widgetReady() { return new Promise((resolve, reject) => { const timer = setTimeout(() => reject(new Error('widget unavailable')), 10000); customElements.whenDefined('altcha-widget').then(() => { clearTimeout(timer); resolve(); }); }); } function loadCap() { if (window.capCaptcha) return widgetReady(); if (!loader) loader = new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = 'https://cap.bug.im/v1.js'; script.onload = () => { if (!window.capCaptcha) { reject(new Error('cap unavailable')); return; } widgetReady().then(resolve, reject); }; script.onerror = () => { script.remove(); loader = undefined; reject(new Error('cap unavailable')); }; document.head.append(script); }); return loader; } export default function CapForm({ sitekey }) { const host = useRef(null); const [status, setStatus] = useState('正在加载验证控件…'); useEffect(() => { let cancelled = false; const node = host.current; const container = document.createElement('div'); container.className = 'cap-captcha'; container.dataset.sitekey = sitekey; const onState = event => { const state = event.detail?.state; setStatus(state === 'verified' ? '验证完成,可以提交。' : state === 'error' ? '验证失败,请重试。' : '请完成验证。'); }; let widget; node.append(container); loadCap().then(() => { if (!cancelled) { window.capCaptcha.mount(); widget = container.querySelector('altcha-widget'); widget?.addEventListener('statechange', onState); setStatus('请完成验证。'); } }).catch(() => { if (!cancelled) setStatus('控件加载失败,请刷新后重试。'); }); return () => { cancelled = true; widget?.removeEventListener('statechange', onState); container.remove(); }; }, [sitekey]); return
; }