Files
NapCatQQ/packages/napcat-webui-frontend/src/components/network_edit/modal.tsx
T
TanTan f954252a34
Build NapCat Artifacts / Type Check & Test (push) Waiting to run
Release Tag / validate-version (push) Waiting to run
NapCatQQ source snapshot
2026-11-13 09:01:47 +08:00

159 lines
4.4 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 { Modal, ModalContent, ModalHeader } from '@heroui/modal';
import toast from 'react-hot-toast';
import useConfig from '@/hooks/use-config';
import useDialog from '@/hooks/use-dialog';
import HTTPClientForm from './http_client';
import HTTPServerForm from './http_server';
import HTTPServerSSEForm from './http_sse';
import WebsocketClientForm from './ws_client';
import WebsocketServerForm from './ws_server';
const modalTitle = {
httpServers: 'HTTP Server',
httpClients: 'HTTP Client',
httpSseServers: 'HTTP SSE Server',
websocketServers: 'Websocket Server',
websocketClients: 'Websocket Client',
};
export interface NetworkFormModalProps<
T extends keyof OneBotConfig['network']
> {
isOpen: boolean;
field: T;
data?: OneBotConfig['network'][T][0];
onOpenChange: (isOpen: boolean) => void;
}
const NetworkFormModal = <T extends keyof OneBotConfig['network']> (
props: NetworkFormModalProps<T>
) => {
const { isOpen, onOpenChange, field, data } = props;
const { createNetworkConfig, updateNetworkConfig } = useConfig();
const dialog = useDialog();
const isCreate = !data;
const onSubmit = async (data: OneBotConfig['network'][typeof field][0]) => {
const saveData = async (dataToSave: OneBotConfig['network'][typeof field][0]) => {
try {
if (isCreate) {
await createNetworkConfig(field, dataToSave);
} else {
await updateNetworkConfig(field, dataToSave);
}
toast.success('保存配置成功');
} catch (error) {
const msg = (error as Error).message;
toast.error(`保存配置失败: ${msg}`);
throw error;
}
};
if (['httpServers', 'httpSseServers', 'websocketServers'].includes(field)) {
const serverData = data as any;
if (!serverData.token && serverData.host !== '127.0.0.1') {
await new Promise<void>((resolve, reject) => {
dialog.confirm({
title: '安全警告',
content: (
<div>
<p>检测到未配置Token,这可能导致安全风险。确认要继续吗?</p>
<p className='text-sm text-gray-500 mt-2'>(未配置Token时,Host将被强制限制为 127.0.0.1)</p>
</div>
),
onConfirm: async () => {
serverData.host = '127.0.0.1';
try {
await saveData(serverData);
resolve();
} catch (e) {
reject(e);
}
},
onCancel: () => {
reject(new Error('Cancelled'));
},
});
});
return;
}
}
await saveData(data);
};
const renderFormComponent = (onClose: () => void) => {
switch (field) {
case 'httpServers':
return (
<HTTPServerForm
data={data as OneBotConfig['network']['httpServers'][0]}
onClose={onClose}
onSubmit={onSubmit}
/>
);
case 'httpClients':
return (
<HTTPClientForm
data={data as OneBotConfig['network']['httpClients'][0]}
onClose={onClose}
onSubmit={onSubmit}
/>
);
case 'websocketServers':
return (
<WebsocketServerForm
data={data as OneBotConfig['network']['websocketServers'][0]}
onClose={onClose}
onSubmit={onSubmit}
/>
);
case 'websocketClients':
return (
<WebsocketClientForm
data={data as OneBotConfig['network']['websocketClients'][0]}
onClose={onClose}
onSubmit={onSubmit}
/>
);
case 'httpSseServers':
return (
<HTTPServerSSEForm
data={data as OneBotConfig['network']['httpSseServers'][0]}
onClose={onClose}
onSubmit={onSubmit}
/>
);
default:
return null;
}
};
return (
<Modal
backdrop='blur'
isDismissable={false}
isOpen={isOpen}
size='lg'
scrollBehavior='outside'
onOpenChange={onOpenChange}
>
<ModalContent>
{(onClose) => (
<>
<ModalHeader className='flex flex-col gap-1'>
{modalTitle[field]}
</ModalHeader>
{renderFormComponent(onClose)}
</>
)}
</ModalContent>
</Modal>
);
};
export default NetworkFormModal;