import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Button, Input, Modal, Select, Space, Switch, Tabs, message } from 'antd'; import { BranchesOutlined, BuildOutlined, CloudSyncOutlined, DesktopOutlined, MobileOutlined, NotificationOutlined, ThunderboltOutlined, } from '@ant-design/icons'; import type { AllSetting } from '@/models/setting'; import { SettingListItem } from '@/components/ui'; import { buildHappPresetDeeplink, parseList, toBase64Utf8 } from './happPresets'; interface HappSettingsContentProps { allSetting: AllSetting; updateSetting: (patch: Partial) => void; isMobile: boolean; remoteSourceBadge: (val: string) => React.ReactNode; } export default function HappSettingsContent({ allSetting, updateSetting, isMobile, remoteSourceBadge, }: HappSettingsContentProps) { const { t } = useTranslation(); const [selectedPreset, setSelectedPreset] = useState('iran-bypass'); const [isModalOpen, setIsModalOpen] = useState(false); const [directDomains, setDirectDomains] = useState(''); const [proxyDomains, setProxyDomains] = useState(''); const [blockDomains, setBlockDomains] = useState(''); const [directIPs, setDirectIPs] = useState(''); const [proxyIPs, setProxyIPs] = useState(''); const [blockIPs, setBlockIPs] = useState(''); const applyPreset = () => { const payload = buildHappPresetDeeplink(selectedPreset); if (payload) { updateSetting({ subRoutingRules: payload }); message.success(t('pages.settings.subHappPresetApplied')); } }; const handleBuildDeeplink = () => { interface FieldRule { type: string; outboundTag: string; domain?: string[]; ip?: string[]; network?: string; } const rules: FieldRule[] = []; const bDom = parseList(blockDomains); const bIp = parseList(blockIPs); if (bDom.length > 0 || bIp.length > 0) { rules.push({ type: 'field', outboundTag: 'block', ...(bDom.length > 0 ? { domain: bDom } : {}), ...(bIp.length > 0 ? { ip: bIp } : {}), }); } const dDom = parseList(directDomains); const dIp = parseList(directIPs); if (dDom.length > 0 || dIp.length > 0) { rules.push({ type: 'field', outboundTag: 'direct', ...(dDom.length > 0 ? { domain: dDom } : {}), ...(dIp.length > 0 ? { ip: dIp } : {}), }); } const pDom = parseList(proxyDomains); const pIp = parseList(proxyIPs); if (pDom.length > 0 || pIp.length > 0) { rules.push({ type: 'field', outboundTag: 'proxy', ...(pDom.length > 0 ? { domain: pDom } : {}), ...(pIp.length > 0 ? { ip: pIp } : {}), }); } rules.push({ type: 'field', outboundTag: 'proxy', network: 'tcp,udp', }); const deeplink = 'happ://routing/onadd/' + toBase64Utf8(JSON.stringify({ rules })); updateSetting({ subRoutingRules: deeplink }); setIsModalOpen(false); message.success(t('pages.settings.subHappDeeplinkGenerated')); }; return ( <> {!isMobile && t('pages.settings.subHappGroupRouting')} ), children: ( <> updateSetting({ subEnableRouting: v })} /> updateSetting({ subHappSubInfoText: e.target.value })} /> updateSetting({ subHappSubInfoButtonText: e.target.value })} /> updateSetting({ subHappSubInfoButtonLink: e.target.value })} /> updateSetting({ subHappSubExpire: v })} /> updateSetting({ subHappSubExpireButtonLink: e.target.value })} /> updateSetting({ subHappNotificationExpire: v })} /> ), }, { key: 'network', label: ( {!isMobile && t('pages.settings.subHappGroupNetwork')} ), children: ( <> updateSetting({ subHappTunType: v })} options={[ { value: 'singbox', label: t('pages.settings.subHappTunTypeSingbox') }, { value: 'tun2proxy', label: t('pages.settings.subHappTunTypeTun2proxy') }, { value: 'default', label: t('pages.settings.subHappTunTypeDefault') }, { value: 'xray', label: t('pages.settings.subHappTunTypeXray') }, ]} /> updateSetting({ subHappExcludeRoutes: e.target.value })} /> updateSetting({ subHappExcludeApns: v })} /> updateSetting({ subHappAutoConnectType: v })} options={[ { value: 'lowestdelay', label: t('pages.settings.subHappAutoConnectLowestDelay'), }, { value: 'lastused', label: t('pages.settings.subHappAutoConnectLastUsed') }, { value: 'random', label: t('pages.settings.subHappAutoConnectRandom') }, ]} /> ), }, { key: 'themes', label: ( {!isMobile && t('pages.settings.subHappGroupThemes')} ), children: ( <> updateSetting({ subHappColorProfile: e.target.value })} /> ), }, { key: 'failover', label: ( {!isMobile && t('pages.settings.subHappGroupFailover')} ), children: ( <> updateSetting({ subHappAutoDetect: v })} /> updateSetting({ subHappProviderId: e.target.value })} /> updateSetting({ subHappNewUrl: e.target.value })} /> updateSetting({ subHappFallbackUrl: e.target.value })} /> updateSetting({ subHappAlwaysHwid: v })} /> ), }, { key: 'android', label: ( {!isMobile && t('pages.settings.subHappGroupAndroid')} ), children: ( <>