import { useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Alert, Button, Collapse, Modal, Radio, Spin, Tag, Tooltip } from 'antd'; import { ReloadOutlined } from '@ant-design/icons'; import { HttpUtil } from '@/utils'; import type { Status } from '@/models/status'; import CustomGeoSection from './CustomGeoSection'; import './VersionModal.css'; interface BusyEvent { busy: boolean; tip?: string; } interface VersionModalProps { open: boolean; status: Status; onClose: () => void; onBusy: (e: BusyEvent) => void; } const GEOFILES = [ 'geosite.dat', 'geoip.dat', 'geosite_IR.dat', 'geoip_IR.dat', 'geosite_RU.dat', 'geoip_RU.dat', ]; export default function VersionModal({ open, status, onClose, onBusy }: VersionModalProps) { const { t } = useTranslation(); const [modal, modalContextHolder] = Modal.useModal(); const [activeKey, setActiveKey] = useState('1'); const [versions, setVersions] = useState([]); const [loading, setLoading] = useState(false); const fetchVersions = useCallback(async () => { setLoading(true); try { const msg = await HttpUtil.get('/panel/api/server/getXrayVersion'); if (msg?.success) setVersions(msg.obj || []); } finally { setLoading(false); } }, []); useEffect(() => { if (open) fetchVersions(); }, [open, fetchVersions]); function switchXrayVersion(version: string) { modal.confirm({ title: t('pages.index.xraySwitchVersionDialog'), content: t('pages.index.xraySwitchVersionDialogDesc').replace('#version#', version), okText: t('confirm'), cancelText: t('cancel'), onOk: async () => { onClose(); onBusy({ busy: true, tip: t('pages.index.dontRefresh') }); try { await HttpUtil.post(`/panel/api/server/installXray/${version}`); } finally { onBusy({ busy: false }); } }, }); } function updateGeofile(fileName: string) { const isSingle = !!fileName; modal.confirm({ title: t('pages.index.geofileUpdateDialog'), content: isSingle ? t('pages.index.geofileUpdateDialogDesc').replace('#filename#', fileName) : t('pages.index.geofilesUpdateDialogDesc'), okText: t('confirm'), cancelText: t('cancel'), onOk: async () => { onClose(); onBusy({ busy: true, tip: t('pages.index.dontRefresh') }); const url = isSingle ? `/panel/api/server/updateGeofile/${fileName}` : '/panel/api/server/updateGeofile'; try { await HttpUtil.post(url); } finally { onBusy({ busy: false }); } }, }); } const activeKeyStr = Array.isArray(activeKey) ? activeKey[0] : activeKey; return ( {modalContextHolder}
{versions.map((version, index) => (
{version} switchXrayVersion(version)} />
))}
), }, { key: '2', label: 'Geofiles', children: ( <>
{GEOFILES.map((file, index) => (
{file} updateGeofile(file)} />
))}
), }, { key: '3', label: t('pages.index.customGeoTitle'), children: , }, ]} />
); }