mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-11 15:16:07 +00:00
feat(xray): add connIdle and bufferSize policy controls
Expose level-0 connection policies in the panel's Basics tab: idle timeout (connIdle) and per-connection buffer size (bufferSize). Empty fields delete the key so Xray falls back to its own defaults. Adds en-US/fa-IR strings and types policy.levels in the Zod schema.
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Alert, Button, Input, Modal, Select, Space, Switch, Tabs } from 'antd';
|
||||
import { Alert, Button, Input, InputNumber, Modal, Select, Space, Switch, Tabs } from 'antd';
|
||||
import {
|
||||
BarChartOutlined,
|
||||
ClockCircleOutlined,
|
||||
FileTextOutlined,
|
||||
ReloadOutlined,
|
||||
SettingOutlined,
|
||||
@@ -54,6 +55,20 @@ export default function BasicsTab({
|
||||
[setTemplateSettings],
|
||||
);
|
||||
|
||||
const setLevel0 = useCallback(
|
||||
(field: string, value: number | null) => mutate((tt) => {
|
||||
if (!tt.policy) tt.policy = {};
|
||||
if (!tt.policy.levels) tt.policy.levels = {};
|
||||
if (!tt.policy.levels['0']) tt.policy.levels['0'] = {};
|
||||
if (value === null || value === undefined) {
|
||||
delete tt.policy.levels['0'][field];
|
||||
} else {
|
||||
tt.policy.levels['0'][field] = value;
|
||||
}
|
||||
}),
|
||||
[mutate],
|
||||
);
|
||||
|
||||
function confirmResetDefault() {
|
||||
modal.confirm({
|
||||
title: t('pages.settings.resetDefaultConfig'),
|
||||
@@ -72,6 +87,7 @@ export default function BasicsTab({
|
||||
const routingStrategy = templateSettings?.routing?.domainStrategy ?? 'AsIs';
|
||||
const log = (templateSettings?.log || {}) as Record<string, unknown>;
|
||||
const policy = (templateSettings?.policy?.system || {}) as Record<string, boolean>;
|
||||
const level0 = (templateSettings?.policy?.levels?.['0'] || {}) as Record<string, unknown>;
|
||||
|
||||
const items = [
|
||||
{
|
||||
@@ -168,6 +184,50 @@ export default function BasicsTab({
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'connection',
|
||||
label: catTabLabel(<ClockCircleOutlined />, t('pages.xray.connectionLimits'), isMobile),
|
||||
children: (
|
||||
<>
|
||||
<Alert
|
||||
type="warning"
|
||||
showIcon
|
||||
className="mb-12 hint-alert"
|
||||
title={t('pages.xray.connectionLimitsDesc')}
|
||||
/>
|
||||
<SettingListItem
|
||||
title={t('pages.xray.connIdle')}
|
||||
description={t('pages.xray.connIdleDesc')}
|
||||
paddings="small"
|
||||
control={
|
||||
<InputNumber
|
||||
value={typeof level0.connIdle === 'number' ? level0.connIdle : undefined}
|
||||
min={0}
|
||||
style={{ width: '100%' }}
|
||||
placeholder="300"
|
||||
addonAfter={t('pages.xray.seconds')}
|
||||
onChange={(v) => setLevel0('connIdle', v as number | null)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingListItem
|
||||
title={t('pages.xray.bufferSize')}
|
||||
description={t('pages.xray.bufferSizeDesc')}
|
||||
paddings="small"
|
||||
control={
|
||||
<InputNumber
|
||||
value={typeof level0.bufferSize === 'number' ? level0.bufferSize : undefined}
|
||||
min={0}
|
||||
style={{ width: '100%' }}
|
||||
placeholder={t('pages.xray.bufferSizePlaceholder')}
|
||||
addonAfter="KB"
|
||||
onChange={(v) => setLevel0('bufferSize', v as number | null)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
label: catTabLabel(<FileTextOutlined />, t('pages.xray.logConfigs'), isMobile),
|
||||
|
||||
@@ -28,6 +28,7 @@ export const XraySettingsValueSchema = z.object({
|
||||
log: z.record(z.string(), z.unknown()).optional(),
|
||||
policy: z.object({
|
||||
system: z.record(z.string(), z.boolean()).optional(),
|
||||
levels: z.record(z.string(), z.record(z.string(), z.unknown())).optional(),
|
||||
}).loose().optional(),
|
||||
observatory: z.unknown().optional(),
|
||||
burstObservatory: z.unknown().optional(),
|
||||
|
||||
Reference in New Issue
Block a user