mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-02-04 14:41:14 +00:00
Merge branch 'main' of https://github.com/NapNeko/NapCatQQ
This commit is contained in:
commit
cf27b34242
@ -316,6 +316,11 @@ export class OB11PluginMangerAdapter extends IOB11NetworkAdapter<PluginConfig> i
|
||||
entry = newEntry;
|
||||
}
|
||||
|
||||
if (!entry.enable) {
|
||||
this.logger.log(`[PluginManager] Skipping loading disabled plugin: ${pluginId}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
return await this.loadPlugin(entry);
|
||||
}
|
||||
|
||||
|
||||
@ -123,8 +123,8 @@ export class PluginLoader {
|
||||
const entryFile = this.findEntryFile(pluginDir, packageJson);
|
||||
const entryPath = entryFile ? path.join(pluginDir, entryFile) : undefined;
|
||||
|
||||
// 获取启用状态(默认启用)
|
||||
const enable = statusConfig[pluginId] !== false;
|
||||
// 获取启用状态(默认禁用,内置插件除外)
|
||||
const enable = statusConfig[pluginId] ?? (pluginId === 'napcat-plugin-builtin');
|
||||
|
||||
// 创建插件条目
|
||||
const entry: PluginEntry = {
|
||||
@ -159,7 +159,7 @@ export class PluginLoader {
|
||||
id: dirname, // 使用目录名作为 ID
|
||||
fileId: dirname,
|
||||
pluginPath: path.join(this.pluginPath, dirname),
|
||||
enable: statusConfig[dirname] !== false,
|
||||
enable: statusConfig[dirname] ?? (dirname === 'napcat-plugin-builtin'),
|
||||
loaded: false,
|
||||
runtime: {
|
||||
status: 'error',
|
||||
|
||||
@ -285,6 +285,11 @@ export class OB11PluginManager extends IOB11NetworkAdapter<PluginConfig> impleme
|
||||
entry = newEntry;
|
||||
}
|
||||
|
||||
if (!entry.enable) {
|
||||
this.logger.log(`[PluginManager] Skipping loading disabled plugin: ${pluginId}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
return await this.loadPlugin(entry);
|
||||
}
|
||||
|
||||
|
||||
@ -340,7 +340,7 @@ export async function applyPendingUpdates (webUiPathWrapper: NapCatPathWrapper,
|
||||
const configPath = path.join(webUiPathWrapper.configPath, 'napcat-update.json');
|
||||
|
||||
if (!fs.existsSync(configPath)) {
|
||||
logger.log('[NapCat Update] No pending updates found');
|
||||
//logger.log('[NapCat Update] No pending updates found');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ const PluginStoreCard: React.FC<PluginStoreCardProps> = ({
|
||||
return {
|
||||
text: '更新',
|
||||
icon: <IoMdDownload size={16} />,
|
||||
color: 'success' as const,
|
||||
color: 'default' as const,
|
||||
};
|
||||
default:
|
||||
return {
|
||||
|
||||
@ -260,14 +260,14 @@ const NewVersionTip = (props: NewVersionTipProps) => {
|
||||
<div className="cursor-pointer flex items-center justify-center" onClick={updateStatus === 'updating' ? undefined : showUpdateDialog}>
|
||||
<Chip
|
||||
size="sm"
|
||||
color="danger"
|
||||
color="primary"
|
||||
variant="flat"
|
||||
classNames={{
|
||||
content: "font-bold text-[10px] px-1 flex items-center justify-center",
|
||||
base: "h-5 min-h-5 min-w-[42px]"
|
||||
}}
|
||||
>
|
||||
{updateStatus === 'updating' ? <Spinner size="sm" color="danger" classNames={{ wrapper: "w-3 h-3" }} /> : 'New'}
|
||||
{updateStatus === 'updating' ? <Spinner size="sm" color="primary" classNames={{ wrapper: "w-3 h-3" }} /> : 'New'}
|
||||
</Chip>
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
@ -2,9 +2,10 @@ import { Button } from '@heroui/button';
|
||||
import { useDisclosure } from '@heroui/modal';
|
||||
import { Tab, Tabs } from '@heroui/tabs';
|
||||
import clsx from 'clsx';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import { IoMdRefresh } from 'react-icons/io';
|
||||
import { FiDownload, FiUpload } from 'react-icons/fi';
|
||||
|
||||
import AddButton from '@/components/button/add_button';
|
||||
import HTTPClientDisplayCard from '@/components/display_card/http_client';
|
||||
@ -55,7 +56,9 @@ export default function NetworkPage () {
|
||||
deleteNetworkConfig,
|
||||
enableNetworkConfig,
|
||||
enableDebugNetworkConfig,
|
||||
updateSingleConfig,
|
||||
} = useConfig();
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const [activeField, setActiveField] =
|
||||
useState<keyof OneBotConfig['network']>('httpServers');
|
||||
const [activeName, setActiveName] = useState<string>('');
|
||||
@ -99,6 +102,45 @@ export default function NetworkPage () {
|
||||
onOpen();
|
||||
};
|
||||
|
||||
// 导出网络配置
|
||||
const handleExport = () => {
|
||||
const blob = new Blob([JSON.stringify(config.network, null, 2)], { type: 'application/json' });
|
||||
const link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = `network-config-${Date.now()}.json`;
|
||||
link.click();
|
||||
URL.revokeObjectURL(link.href);
|
||||
toast.success('导出成功');
|
||||
};
|
||||
|
||||
// 导入网络配置
|
||||
const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) return;
|
||||
e.target.value = '';
|
||||
|
||||
try {
|
||||
const data = JSON.parse(await file.text()) as OneBotConfig['network'];
|
||||
const keys: (keyof OneBotConfig['network'])[] = ['httpServers', 'httpClients', 'httpSseServers', 'websocketServers', 'websocketClients'];
|
||||
if (keys.some(k => !Array.isArray(data[k]))) throw new Error('配置格式错误');
|
||||
|
||||
dialog.confirm({
|
||||
title: '导入配置',
|
||||
content: '确定导入?这将覆盖现有网络配置。',
|
||||
onConfirm: async () => {
|
||||
try {
|
||||
await updateSingleConfig('network', data);
|
||||
toast.success('导入成功');
|
||||
} catch (err) {
|
||||
toast.error(`导入失败: ${(err as Error).message}`);
|
||||
}
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
toast.error(`解析失败: ${(err as Error).message}`);
|
||||
}
|
||||
};
|
||||
|
||||
const onDelete = async (
|
||||
field: keyof OneBotConfig['network'],
|
||||
name: string
|
||||
@ -373,6 +415,21 @@ export default function NetworkPage () {
|
||||
<PageLoading loading={loading} />
|
||||
<div className='flex mb-6 items-center gap-4'>
|
||||
<AddButton onOpen={handleClickCreate} />
|
||||
<Button
|
||||
className="bg-default-100/50 hover:bg-default-200/50 text-default-700 backdrop-blur-md"
|
||||
startContent={<FiUpload size={18} />}
|
||||
onPress={handleExport}
|
||||
>
|
||||
导出
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-default-100/50 hover:bg-default-200/50 text-default-700 backdrop-blur-md"
|
||||
startContent={<FiDownload size={18} />}
|
||||
onPress={() => fileInputRef.current?.click()}
|
||||
>
|
||||
导入
|
||||
</Button>
|
||||
<input ref={fileInputRef} type="file" accept=".json" className="hidden" onChange={handleFileChange} />
|
||||
<Button
|
||||
isIconOnly
|
||||
className="bg-default-100/50 hover:bg-default-200/50 text-default-700 backdrop-blur-md"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user