mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-09-16 15:17:14 +00:00
feat(sub): refine Happ routing presets, serverDescription escaping, and auto-detect placement (#6488)
* feat(sub): refine Happ routing presets, serverDescription escaping, and auto-detect placement * fix(sub): address PR review findings on routing parity, agent regex, and i18n
This commit is contained in:
@@ -51,55 +51,19 @@ export default function HappSettingsContent({
|
||||
};
|
||||
|
||||
const handleBuildDeeplink = () => {
|
||||
interface FieldRule {
|
||||
type: string;
|
||||
outboundTag: string;
|
||||
domain?: string[];
|
||||
ip?: string[];
|
||||
network?: string;
|
||||
}
|
||||
const rules: FieldRule[] = [];
|
||||
const profile = {
|
||||
Name: 'Custom Rules',
|
||||
GlobalProxy: 'true',
|
||||
DirectSites: parseList(directDomains),
|
||||
DirectIp: parseList(directIPs),
|
||||
ProxySites: parseList(proxyDomains),
|
||||
ProxyIp: parseList(proxyIPs),
|
||||
BlockSites: parseList(blockDomains),
|
||||
BlockIp: parseList(blockIPs),
|
||||
DomainStrategy: 'IPIfNonMatch',
|
||||
};
|
||||
|
||||
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 }));
|
||||
const deeplink = 'happ://routing/onadd/' + toBase64Utf8(JSON.stringify(profile));
|
||||
updateSetting({ subRoutingRules: deeplink });
|
||||
setIsModalOpen(false);
|
||||
message.success(t('pages.settings.subHappDeeplinkGenerated'));
|
||||
@@ -107,6 +71,17 @@ export default function HappSettingsContent({
|
||||
|
||||
return (
|
||||
<>
|
||||
<SettingListItem
|
||||
paddings="small"
|
||||
title={t('pages.settings.subHappAutoDetect')}
|
||||
description={t('pages.settings.subHappAutoDetectDesc')}
|
||||
>
|
||||
<Switch
|
||||
checked={allSetting.subHappAutoDetect}
|
||||
onChange={(v) => updateSetting({ subHappAutoDetect: v })}
|
||||
/>
|
||||
</SettingListItem>
|
||||
|
||||
<Tabs
|
||||
type="card"
|
||||
size="small"
|
||||
@@ -454,11 +429,43 @@ export default function HappSettingsContent({
|
||||
title={t('pages.settings.subHappColorProfile')}
|
||||
description={t('pages.settings.subHappColorProfileDesc')}
|
||||
>
|
||||
<Input
|
||||
value={allSetting.subHappColorProfile}
|
||||
placeholder="default, violet, turquoise, cyberpunk, or custom JSON"
|
||||
onChange={(e) => updateSetting({ subHappColorProfile: e.target.value })}
|
||||
/>
|
||||
<Space orientation="vertical" style={{ width: '100%' }}>
|
||||
<Input
|
||||
value={allSetting.subHappColorProfile}
|
||||
placeholder='{"serverRowBackgroundColor":"#21003D67"} or resetcolors'
|
||||
onChange={(e) => updateSetting({ subHappColorProfile: e.target.value })}
|
||||
/>
|
||||
<Space wrap size="small">
|
||||
<Button
|
||||
size="small"
|
||||
onClick={() => updateSetting({ subHappColorProfile: 'resetcolors' })}
|
||||
>
|
||||
{t('reset')}
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
onClick={() =>
|
||||
updateSetting({
|
||||
subHappColorProfile:
|
||||
'{"serverRowBackgroundColor":"#21003D67","cardBackgroundColor":"#120023B3"}',
|
||||
})
|
||||
}
|
||||
>
|
||||
Violet
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
onClick={() =>
|
||||
updateSetting({
|
||||
subHappColorProfile:
|
||||
'{"serverRowBackgroundColor":"#002B3667","cardBackgroundColor":"#001F27B3"}',
|
||||
})
|
||||
}
|
||||
>
|
||||
Turquoise
|
||||
</Button>
|
||||
</Space>
|
||||
</Space>
|
||||
</SettingListItem>
|
||||
</>
|
||||
),
|
||||
@@ -472,17 +479,6 @@ export default function HappSettingsContent({
|
||||
),
|
||||
children: (
|
||||
<>
|
||||
<SettingListItem
|
||||
paddings="small"
|
||||
title={t('pages.settings.subHappAutoDetect')}
|
||||
description={t('pages.settings.subHappAutoDetectDesc')}
|
||||
>
|
||||
<Switch
|
||||
checked={allSetting.subHappAutoDetect}
|
||||
onChange={(v) => updateSetting({ subHappAutoDetect: v })}
|
||||
/>
|
||||
</SettingListItem>
|
||||
|
||||
<SettingListItem
|
||||
paddings="small"
|
||||
title={t('pages.settings.subHappProviderId')}
|
||||
|
||||
@@ -25,24 +25,15 @@ export function buildHappPresetDeeplink(preset: string): string {
|
||||
'happ://routing/onadd/' +
|
||||
toBase64Utf8(
|
||||
JSON.stringify({
|
||||
rules: [
|
||||
{
|
||||
type: 'field',
|
||||
outboundTag: 'direct',
|
||||
domain: ['domain:ir', 'regexp:.*\\.ir$'],
|
||||
ip: ['geoip:ir', 'geoip:private'],
|
||||
},
|
||||
{
|
||||
type: 'field',
|
||||
outboundTag: 'block',
|
||||
domain: ['geosite:category-ads-all'],
|
||||
},
|
||||
{
|
||||
type: 'field',
|
||||
outboundTag: 'proxy',
|
||||
network: 'tcp,udp',
|
||||
},
|
||||
],
|
||||
Name: 'Iran Bypass',
|
||||
GlobalProxy: 'true',
|
||||
DirectSites: ['domain:ir', 'regexp:.*\\.ir$'],
|
||||
DirectIp: ['geoip:ir', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'],
|
||||
BlockSites: ['geosite:category-ads-all'],
|
||||
BlockIp: [],
|
||||
ProxySites: [],
|
||||
ProxyIp: [],
|
||||
DomainStrategy: 'IPIfNonMatch',
|
||||
}),
|
||||
)
|
||||
);
|
||||
@@ -51,24 +42,15 @@ export function buildHappPresetDeeplink(preset: string): string {
|
||||
'happ://routing/onadd/' +
|
||||
toBase64Utf8(
|
||||
JSON.stringify({
|
||||
rules: [
|
||||
{
|
||||
type: 'field',
|
||||
outboundTag: 'direct',
|
||||
domain: ['domain:cn', 'geosite:cn'],
|
||||
ip: ['geoip:cn', 'geoip:private'],
|
||||
},
|
||||
{
|
||||
type: 'field',
|
||||
outboundTag: 'block',
|
||||
domain: ['geosite:category-ads-all'],
|
||||
},
|
||||
{
|
||||
type: 'field',
|
||||
outboundTag: 'proxy',
|
||||
network: 'tcp,udp',
|
||||
},
|
||||
],
|
||||
Name: 'China Direct',
|
||||
GlobalProxy: 'true',
|
||||
DirectSites: ['geosite:cn', 'geosite:geolocation-cn'],
|
||||
DirectIp: ['geoip:cn', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'],
|
||||
BlockSites: ['geosite:category-ads-all'],
|
||||
BlockIp: [],
|
||||
ProxySites: [],
|
||||
ProxyIp: [],
|
||||
DomainStrategy: 'IPIfNonMatch',
|
||||
}),
|
||||
)
|
||||
);
|
||||
@@ -77,23 +59,15 @@ export function buildHappPresetDeeplink(preset: string): string {
|
||||
'happ://routing/onadd/' +
|
||||
toBase64Utf8(
|
||||
JSON.stringify({
|
||||
rules: [
|
||||
{
|
||||
type: 'field',
|
||||
outboundTag: 'block',
|
||||
domain: ['geosite:category-ads-all'],
|
||||
},
|
||||
{
|
||||
type: 'field',
|
||||
outboundTag: 'direct',
|
||||
ip: ['geoip:private'],
|
||||
},
|
||||
{
|
||||
type: 'field',
|
||||
outboundTag: 'proxy',
|
||||
network: 'tcp,udp',
|
||||
},
|
||||
],
|
||||
Name: 'AdBlock',
|
||||
GlobalProxy: 'true',
|
||||
DirectSites: [],
|
||||
DirectIp: ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'],
|
||||
BlockSites: ['geosite:category-ads-all'],
|
||||
BlockIp: [],
|
||||
ProxySites: [],
|
||||
ProxyIp: [],
|
||||
DomainStrategy: 'IPIfNonMatch',
|
||||
}),
|
||||
)
|
||||
);
|
||||
@@ -102,13 +76,15 @@ export function buildHappPresetDeeplink(preset: string): string {
|
||||
'happ://routing/onadd/' +
|
||||
toBase64Utf8(
|
||||
JSON.stringify({
|
||||
rules: [
|
||||
{
|
||||
type: 'field',
|
||||
outboundTag: 'proxy',
|
||||
network: 'tcp,udp',
|
||||
},
|
||||
],
|
||||
Name: 'Global Proxy',
|
||||
GlobalProxy: 'true',
|
||||
DirectSites: [],
|
||||
DirectIp: [],
|
||||
BlockSites: [],
|
||||
BlockIp: [],
|
||||
ProxySites: [],
|
||||
ProxyIp: [],
|
||||
DomainStrategy: 'AsIs',
|
||||
}),
|
||||
)
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user