import { Button } from '@heroui/button'; import { useLocalStorage } from '@uidotdev/usehooks'; import { useEffect, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; import toast from 'react-hot-toast'; import key from '@/const/key'; import SaveButtons from '@/components/button/save_buttons'; import ImageInput from '@/components/input/image_input'; import { siteConfig } from '@/config/site'; import WebUIManager from '@/controllers/webui_manager'; // Base64URL to Uint8Array converter function base64UrlToUint8Array (base64Url: string): Uint8Array { const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); const rawData = window.atob(base64); const outputArray = new Uint8Array(rawData.length); for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); } return outputArray; } // Uint8Array to Base64URL converter function uint8ArrayToBase64Url (uint8Array: Uint8Array): string { const base64 = window.btoa(String.fromCharCode(...uint8Array)); return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); } const WebUIConfigCard = () => { const { control, handleSubmit: handleWebuiSubmit, formState: { isSubmitting }, setValue: setWebuiValue, } = useForm({ defaultValues: { background: '', customIcons: {} as Record, }, }); const [b64img, setB64img] = useLocalStorage(key.backgroundImage, ''); const [customIcons, setCustomIcons] = useLocalStorage>( key.customIcons, {} ); const [registrationOptions, setRegistrationOptions] = useState(null); const [isLoadingOptions, setIsLoadingOptions] = useState(false); // 预先获取注册选项(可以在任何时候调用) const preloadRegistrationOptions = async () => { setIsLoadingOptions(true); try { console.log('预先获取注册选项...'); const options = await WebUIManager.generatePasskeyRegistrationOptions(); setRegistrationOptions(options); console.log('✅ 注册选项已获取并存储'); toast.success('注册选项已准备就绪,请点击注册按钮'); } catch (error) { console.error('❌ 获取注册选项失败:', error); toast.error('获取注册选项失败,请重试'); } finally { setIsLoadingOptions(false); } }; const reset = () => { setWebuiValue('customIcons', customIcons); setWebuiValue('background', b64img); }; const onSubmit = handleWebuiSubmit((data) => { try { setCustomIcons(data.customIcons); setB64img(data.background); toast.success('保存成功'); } catch (error) { const msg = (error as Error).message; toast.error(`保存失败: ${msg}`); } }); useEffect(() => { reset(); }, [customIcons, b64img]); return ( <> WebUI配置 - NapCat WebUI
背景图
( )} />
自定义图标
{siteConfig.navItems.map((item) => ( ( )} /> ))}
Passkey认证
注册Passkey后,您可以更便捷地登录WebUI,无需每次输入token
{registrationOptions && (
✅ 注册选项已准备就绪,可以开始注册
)}
); }; export default WebUIConfigCard;