import { useMemo } from 'react'; import { Divider, Input, InputNumber, Select, Space, Switch, Tabs } from 'antd'; import { ClockCircleOutlined, InfoCircleOutlined, SafetyCertificateOutlined, SettingOutlined } from '@ant-design/icons'; import { useTranslation } from 'react-i18next'; import type { AllSetting } from '@/models/setting'; import { SettingListItem } from '@/components/ui'; import { useMediaQuery } from '@/hooks/useMediaQuery'; import { catTabLabel } from './catTabLabel'; import { sanitizePath, normalizePath } from './uriPath'; const REMARK_MODELS: Record = { i: 'Inbound', e: 'Email', o: 'Other' }; const REMARK_SAMPLES: Record = { i: 'Germany', e: 'john', o: 'Relay' }; const REMARK_SEPARATORS = [' ', '-', '_', '@', ':', '~', '|', ',', '.', '/']; interface SubscriptionGeneralTabProps { allSetting: AllSetting; updateSetting: (patch: Partial) => void; } export default function SubscriptionGeneralTab({ allSetting, updateSetting }: SubscriptionGeneralTabProps) { const { t } = useTranslation(); const { isMobile } = useMediaQuery(); const remarkModel = useMemo(() => { const rm = allSetting.remarkModel || ''; return rm.length > 1 ? rm.substring(1).split('') : []; }, [allSetting.remarkModel]); const remarkSeparator = useMemo(() => { const rm = allSetting.remarkModel || '-'; return rm.length > 1 ? rm.charAt(0) : '-'; }, [allSetting.remarkModel]); const remarkSample = useMemo(() => { const parts = remarkModel.map((k) => REMARK_SAMPLES[k]); return parts.length === 0 ? '' : parts.join(remarkSeparator); }, [remarkModel, remarkSeparator]); function setRemarkModel(parts: string[]) { updateSetting({ remarkModel: remarkSeparator + parts.join('') }); } function setRemarkSeparator(sep: string) { const tail = (allSetting.remarkModel || '-').substring(1); updateSetting({ remarkModel: sep + tail }); } return ( , t('pages.settings.panelSettings'), isMobile), children: ( <> updateSetting({ subEnable: v })} /> updateSetting({ subJsonEnable: v })} /> updateSetting({ subClashEnable: v })} /> updateSetting({ subListen: e.target.value })} /> updateSetting({ subDomain: e.target.value })} /> updateSetting({ subPort: Number(v) || 0 })} /> updateSetting({ subPath: sanitizePath(e.target.value) })} onBlur={() => updateSetting({ subPath: normalizePath(allSetting.subPath) })} /> updateSetting({ subURI: e.target.value })} /> ), }, { key: '2', label: catTabLabel(, t('pages.settings.information'), isMobile), children: ( <> updateSetting({ subEncrypt: v })} /> updateSetting({ subShowInfo: v })} /> updateSetting({ subEmailInRemark: v })} /> {t('pages.settings.sampleRemark')}:{' '} {remarkSample ? `#${remarkSample}` : '—'} } > ({ value: s, label: s === ' ' ? '␣' : s }))} /> {t('pages.settings.subTitle')} updateSetting({ subTitle: e.target.value })} /> updateSetting({ subSupportUrl: e.target.value })} /> updateSetting({ subProfileUrl: e.target.value })} /> updateSetting({ subAnnounce: e.target.value })} /> Happ updateSetting({ subEnableRouting: v })} /> updateSetting({ subRoutingRules: e.target.value })} /> Clash / Mihomo updateSetting({ subClashEnableRouting: v })} /> updateSetting({ subClashRules: e.target.value })} /> ), }, { key: '3', label: catTabLabel(, t('pages.settings.certs'), isMobile), children: ( <> updateSetting({ subCertFile: e.target.value })} /> updateSetting({ subKeyFile: e.target.value })} /> ), }, { key: '4', label: catTabLabel(, t('pages.settings.intervals'), isMobile), children: ( <> updateSetting({ subUpdates: Number(v) || 0 })} /> ), }, ]} /> ); }