Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--web/assets/js/model/models.js13
-rw-r--r--web/assets/js/util/common.js48
-rw-r--r--web/html/common/prompt_modal.html2
-rw-r--r--web/html/common/qrcode_modal.html4
-rw-r--r--web/html/common/text_modal.html2
-rw-r--r--web/html/xui/client_bulk_modal.html8
-rw-r--r--web/html/xui/client_modal.html7
-rw-r--r--web/html/xui/common_sider.html10
-rw-r--r--web/html/xui/component/password.html4
-rw-r--r--web/html/xui/component/themeSwitch.html26
-rw-r--r--web/html/xui/form/client.html29
-rw-r--r--web/html/xui/form/inbound.html4
-rw-r--r--web/html/xui/form/protocol/dokodemo.html2
-rw-r--r--web/html/xui/form/protocol/shadowsocks.html93
-rw-r--r--web/html/xui/form/protocol/trojan.html99
-rw-r--r--web/html/xui/form/protocol/vless.html104
-rw-r--r--web/html/xui/form/protocol/vmess.html90
-rw-r--r--web/html/xui/form/stream/stream_kcp.html2
-rw-r--r--web/html/xui/form/stream/stream_quic.html4
-rw-r--r--web/html/xui/form/stream/stream_settings.html2
-rw-r--r--web/html/xui/form/stream/stream_sockopt.html2
-rw-r--r--web/html/xui/form/tls_settings.html29
-rw-r--r--web/html/xui/inbound_client_table.html246
-rw-r--r--web/html/xui/inbound_info_modal.html4
-rw-r--r--web/html/xui/inbound_modal.html2
-rw-r--r--web/html/xui/inbounds.html474
-rw-r--r--web/html/xui/index.html73
-rw-r--r--web/html/xui/settings.html825
-rw-r--r--web/html/xui/xray.html911
29 files changed, 1697 insertions, 1422 deletions
diff --git a/web/assets/js/model/models.js b/web/assets/js/model/models.js
index 122145fb..dd602c46 100644
--- a/web/assets/js/model/models.js
+++ b/web/assets/js/model/models.js
@@ -141,6 +141,19 @@ class DBInbound {
return Inbound.fromJson(config);
}
+ isMultiUser() {
+ switch (this.protocol) {
+ case Protocols.VMESS:
+ case Protocols.VLESS:
+ case Protocols.TROJAN:
+ return true;
+ case Protocols.SHADOWSOCKS:
+ return this.toInbound().isSSMultiUser;
+ default:
+ return false;
+ }
+ }
+
hasLink() {
switch (this.protocol) {
case Protocols.VMESS:
diff --git a/web/assets/js/util/common.js b/web/assets/js/util/common.js
index 8e30bce7..b2f15fb2 100644
--- a/web/assets/js/util/common.js
+++ b/web/assets/js/util/common.js
@@ -52,13 +52,15 @@ function safeBase64(str) {
function formatSecond(second) {
if (second < 60) {
- return second.toFixed(0) + ' s';
+ return second.toFixed(0) + 's';
} else if (second < 3600) {
- return (second / 60).toFixed(0) + ' m';
+ return (second / 60).toFixed(0) + 'm';
} else if (second < 3600 * 24) {
- return (second / 3600).toFixed(0) + ' h';
+ return (second / 3600).toFixed(0) + 'h';
} else {
- return (second / 3600 / 24).toFixed(0) + ' d';
+ day = Math.floor(second / 3600 / 24);
+ remain = ((second/3600) - (day*24)).toFixed(0);
+ return day + 'd' + (remain > 0 ? ' ' + remain + 'h' : '');
}
}
@@ -72,7 +74,7 @@ function addZero(num) {
function toFixed(num, n) {
n = Math.pow(10, n);
- return Math.round(num * n) / n;
+ return Math.floor(num * n) / n;
}
function debounce(fn, delay) {
@@ -115,15 +117,39 @@ function setCookie(cname, cvalue, exdays) {
function usageColor(data, threshold, total) {
switch (true) {
case data === null:
- return 'blue';
- case total <= 0:
- return 'blue';
+ return "green";
+ case total < 0:
+ return "blue";
+ case total == 0:
+ return "purple";
case data < total - threshold:
- return 'cyan';
+ return "blue";
case data < total:
- return 'orange';
+ return "orange";
default:
- return 'red';
+ return "red";
+ }
+}
+
+function userExpiryColor(threshold, client, isDark = false) {
+ if (!client.enable) {
+ return isDark ? '#2c3950' : '#bcbcbc';
+ }
+ now = new Date().getTime(),
+ expiry = client.expiryTime;
+ switch (true) {
+ case expiry === null:
+ return "#389e0d";
+ case expiry < 0:
+ return "#0e49b5";
+ case expiry == 0:
+ return "#7a316f";
+ case now < expiry - threshold:
+ return "#0e49b5";
+ case now < expiry:
+ return "#ffa031";
+ default:
+ return "#e04141";
}
}
diff --git a/web/html/common/prompt_modal.html b/web/html/common/prompt_modal.html
index 17a65ec1..a61b4454 100644
--- a/web/html/common/prompt_modal.html
+++ b/web/html/common/prompt_modal.html
@@ -2,7 +2,7 @@
<a-modal id="prompt-modal" v-model="promptModal.visible" :title="promptModal.title"
:closable="true" @ok="promptModal.ok" :mask-closable="false"
:class="themeSwitcher.darkCardClass"
- :ok-text="promptModal.okText" cancel-text='{{ i18n "cancel" }}'>
+ :ok-text="promptModal.okText" cancel-text='{{ i18n "cancel" }}' :class="themeSwitcher.currentTheme">
<a-input id="prompt-modal-input" :type="promptModal.type"
v-model="promptModal.value"
:autosize="{minRows: 10, maxRows: 20}"
diff --git a/web/html/common/qrcode_modal.html b/web/html/common/qrcode_modal.html
index 51dc38cb..2db1948b 100644
--- a/web/html/common/qrcode_modal.html
+++ b/web/html/common/qrcode_modal.html
@@ -1,7 +1,7 @@
{{define "qrcodeModal"}}
<a-modal id="qrcode-modal" v-model="qrModal.visible" :title="qrModal.title"
:closable="true"
- :class="themeSwitcher.darkCardClass"
+ :class="themeSwitcher.currentTheme"
:footer="null"
width="300px">
<a-tag color="green" style="margin-bottom: 10px;display: block;text-align: center;">
@@ -13,7 +13,7 @@
</template>
<a-divider>{{ i18n "pages.inbounds.client" }}</a-divider>
<template v-for="(row, index) in qrModal.qrcodes">
- <a-tag color="orange" style="margin-top: 10px;display: block;text-align: center;">[[ row.remark ]]</a-tag>
+ <a-tag color="green" style="margin: 10px 0; display: block; text-align: center;">[[ row.remark ]]</a-tag>
<canvas @click="copyToClipboard('qrCode-'+index, row.link)" :id="'qrCode-'+index" style="width: 100%; height: 100%;"></canvas>
</template>
</a-modal>
diff --git a/web/html/common/text_modal.html b/web/html/common/text_modal.html
index 1514051b..2b455ae4 100644
--- a/web/html/common/text_modal.html
+++ b/web/html/common/text_modal.html
@@ -1,7 +1,7 @@
{{define "textModal"}}
<a-modal id="text-modal" v-model="txtModal.visible" :title="txtModal.title"
:closable="true" ok-text='{{ i18n "copy" }}' cancel-text='{{ i18n "close" }}'
- :class="themeSwitcher.darkCardClass"
+ :class="themeSwitcher.currentTheme"
:ok-button-props="{attrs:{id:'txt-modal-ok-btn'}}">
<a-button v-if="!ObjectUtil.isEmpty(txtModal.fileName)" type="primary" style="margin-bottom: 10px;"
:href="'data:application/text;charset=utf-8,' + encodeURIComponent(txtModal.content)"
diff --git a/web/html/xui/client_bulk_modal.html b/web/html/xui/client_bulk_modal.html
index d5c60b76..f758f627 100644
--- a/web/html/xui/client_bulk_modal.html
+++ b/web/html/xui/client_bulk_modal.html
@@ -1,11 +1,11 @@
{{define "clientsBulkModal"}}
<a-modal id="client-bulk-modal" v-model="clientsBulkModal.visible" :title="clientsBulkModal.title" @ok="clientsBulkModal.ok"
:confirm-loading="clientsBulkModal.confirmLoading" :closable="true" :mask-closable="false"
- :class="themeSwitcher.darkCardClass"
+ :class="themeSwitcher.currentTheme"
:ok-text="clientsBulkModal.okText" cancel-text='{{ i18n "close" }}'>
<a-form layout="inline">
<a-form-item label='{{ i18n "pages.client.method" }}'>
- <a-select v-model="clientsBulkModal.emailMethod" buttonStyle="solid" style="width: 350px" :dropdown-class-name="themeSwitcher.darkCardClass">
+ <a-select v-model="clientsBulkModal.emailMethod" buttonStyle="solid" style="width: 350px" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option :value="0">Random</a-select-option>
<a-select-option :value="1">Random+Prefix</a-select-option>
<a-select-option :value="2">Random+Prefix+Num</a-select-option>
@@ -72,13 +72,13 @@
</a-form-item>
<br>
<a-form-item v-if="clientsBulkModal.inbound.xtls" label="Flow">
- <a-select v-model="clientsBulkModal.flow" style="width: 200px" :dropdown-class-name="themeSwitcher.darkCardClass">
+ <a-select v-model="clientsBulkModal.flow" style="width: 200px" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option value="">{{ i18n "none" }}</a-select-option>
<a-select-option v-for="key in XTLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
</a-select>
</a-form-item>
<a-form-item v-if="clientsBulkModal.inbound.canEnableTlsFlow()" label="Flow" layout="inline">
- <a-select v-model="clientsBulkModal.flow" style="width: 200px" :dropdown-class-name="themeSwitcher.darkCardClass">
+ <a-select v-model="clientsBulkModal.flow" style="width: 200px" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
<a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
</a-select>
diff --git a/web/html/xui/client_modal.html b/web/html/xui/client_modal.html
index e7c23098..b2c03129 100644
--- a/web/html/xui/client_modal.html
+++ b/web/html/xui/client_modal.html
@@ -1,8 +1,11 @@
{{define "clientsModal"}}
<a-modal id="client-modal" v-model="clientModal.visible" :title="clientModal.title" @ok="clientModal.ok"
:confirm-loading="clientModal.confirmLoading" :closable="true" :mask-closable="false"
- :class="themeSwitcher.darkCardClass"
+ :class="themeSwitcher.currentTheme"
:ok-text="clientModal.okText" cancel-text='{{ i18n "close" }}'>
+ <template v-if="isEdit">
+ <a-tag v-if="isExpiry || isTrafficExhausted" color="red" style="margin-bottom: 10px;display: block;text-align: center;">Account is (Expired|Traffic Ended) And Disabled</a-tag>
+ </template>
{{template "form/client"}}
</a-modal>
<script>
@@ -151,7 +154,7 @@
this.$confirm({
title: '{{ i18n "pages.inbounds.resetTraffic"}}',
content: '{{ i18n "pages.inbounds.resetTrafficContent"}}',
- class: themeSwitcher.darkCardClass,
+ class: themeSwitcher.currentTheme,
okText: '{{ i18n "reset"}}',
cancelText: '{{ i18n "cancel"}}',
onOk: async () => {
diff --git a/web/html/xui/common_sider.html b/web/html/xui/common_sider.html
index 58072f82..12a8ed41 100644
--- a/web/html/xui/common_sider.html
+++ b/web/html/xui/common_sider.html
@@ -11,6 +11,10 @@
<a-icon type="setting"></a-icon>
<span>{{ i18n "menu.settings"}}</span>
</a-menu-item>
+<a-menu-item key="{{ .base_path }}xui/xray">
+ <a-icon type="tool"></a-icon>
+ <span>{{ i18n "menu.xray"}}</span>
+</a-menu-item>
<!--<a-menu-item key="{{ .base_path }}panel/clients">-->
<!-- <a-icon type="laptop"></a-icon>-->
<!-- <span>Client</span>-->
@@ -26,7 +30,7 @@
<a-layout-sider :theme="themeSwitcher.currentTheme" id="sider" collapsible breakpoint="md" collapsed-width="0">
<a-menu :theme="themeSwitcher.currentTheme" mode="inline" selected-keys="">
<a-menu-item mode="inline">
- <a-icon type="bg-colors"></a-icon>
+ <a-icon type="bulb" :theme="themeSwitcher.isDarkTheme ? 'filled' : 'outlined'"></a-icon>
<theme-switch />
</a-menu-item>
</a-menu>
@@ -38,14 +42,14 @@
<a-drawer id="sider-drawer" placement="left" :closable="false"
@close="siderDrawer.close()"
:visible="siderDrawer.visible"
- :wrap-class-name="themeSwitcher.darkDrawerClass"
+ :wrap-class-name="themeSwitcher.currentTheme"
:wrap-style="{ padding: 0 }">
<div class="drawer-handle" @click="siderDrawer.change()" slot="handle">
<a-icon :type="siderDrawer.visible ? 'close' : 'menu-fold'"></a-icon>
</div>
<a-menu :theme="themeSwitcher.currentTheme" mode="inline" selected-keys="">
<a-menu-item mode="inline">
- <a-icon type="bg-colors"></a-icon>
+ <a-icon type="bulb" :theme="themeSwitcher.isDarkTheme ? 'filled' : 'outlined'"></a-icon>
<theme-switch />
</a-menu-item>
</a-menu>
diff --git a/web/html/xui/component/password.html b/web/html/xui/component/password.html
index ebea3be6..13dbfb51 100644
--- a/web/html/xui/component/password.html
+++ b/web/html/xui/component/password.html
@@ -4,12 +4,12 @@
:placeholder="placeholder"
@input="$emit('input', $event.target.value)">
<template v-if="icon" #prefix>
- <a-icon :type="icon" :style="'font-size: 16px;' + themeSwitcher.textStyle" />
+ <a-icon :type="icon" style="font-size: 16px;" />
</template>
<template #addonAfter>
<a-icon :type="showPassword ? 'eye-invisible' : 'eye'"
@click="toggleShowPassword"
- :style="'font-size: 16px;' + themeSwitcher.textStyle" />
+ style="font-size: 16px;" />
</template>
</a-input>
</template>
diff --git a/web/html/xui/component/themeSwitch.html b/web/html/xui/component/themeSwitch.html
index 7cbedecf..4d5412e2 100644
--- a/web/html/xui/component/themeSwitch.html
+++ b/web/html/xui/component/themeSwitch.html
@@ -1,8 +1,6 @@
{{define "component/themeSwitchTemplate"}}
<template>
- <a-switch :default-checked="themeSwitcher.isDarkTheme"
- checked-children="☀"
- un-checked-children="🌙"
+ <a-switch size="small" :default-checked="themeSwitcher.isDarkTheme"
@change="themeSwitcher.toggleTheme()">
</a-switch>
</template>
@@ -10,39 +8,17 @@
{{define "component/themeSwitcher"}}
<script>
- const colors = {
- dark: {
- bg: "#242c3a",
- text: "hsla(0,0%,100%,.65)"
- },
- light: {
- bg: '#f0f2f5',
- text: "rgba(0, 0, 0, 0.7)",
- }
- }
-
function createThemeSwitcher() {
const isDarkTheme = localStorage.getItem('dark-mode') === 'true';
const theme = isDarkTheme ? 'dark' : 'light';
return {
isDarkTheme,
- bgStyle: `background: ${colors[theme].bg};`,
- textStyle: `color: ${colors[theme].text};`,
- darkClass: isDarkTheme ? 'ant-dark' : '',
- darkCardClass: isDarkTheme ? 'ant-card-dark' : '',
- darkDrawerClass: isDarkTheme ? 'ant-drawer-dark' : '',
get currentTheme() {
return this.isDarkTheme ? 'dark' : 'light';
},
toggleTheme() {
this.isDarkTheme = !this.isDarkTheme;
- this.theme = this.isDarkTheme ? 'dark' : 'light';
localStorage.setItem('dark-mode', this.isDarkTheme);
- this.bgStyle = `background: ${colors[this.theme].bg};`;
- this.textStyle = `color: ${colors[this.theme].text};`;
- this.darkClass = this.isDarkTheme ? 'ant-dark' : '';
- this.darkCardClass = this.isDarkTheme ? 'ant-card-dark' : '';
- this.darkDrawerClass = this.isDarkTheme ? 'ant-drawer-dark' : '';
},
};
}
diff --git a/web/html/xui/form/client.html b/web/html/xui/form/client.html
index 4fd5b8e3..63080ab7 100644
--- a/web/html/xui/form/client.html
+++ b/web/html/xui/form/client.html
@@ -1,10 +1,5 @@
{{define "form/client"}}
<a-form layout="inline" v-if="client">
- <template v-if="isEdit">
- <a-tag v-if="isExpiry || isTrafficExhausted" color="red" style="margin-bottom: 10px;display: block;text-align: center;">
- Account is (Expired|Traffic Ended) And Disabled
- </a-tag>
- </template>
<a-form-item label='{{ i18n "pages.inbounds.enable" }}'>
<a-switch v-model="client.enable"></a-switch>
</a-form-item>
@@ -97,13 +92,13 @@
</a-form-item>
<br>
<a-form-item v-if="inbound.xtls" label="Flow">
- <a-select v-model="client.flow" style="width: 200px" :dropdown-class-name="themeSwitcher.darkCardClass">
+ <a-select v-model="client.flow" style="width: 200px" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option value="">{{ i18n "none" }}</a-select-option>
<a-select-option v-for="key in XTLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
</a-select>
</a-form-item>
<a-form-item v-else-if="inbound.canEnableTlsFlow()" label="Flow">
- <a-select v-model="client.flow" style="width: 200px" :dropdown-class-name="themeSwitcher.darkCardClass">
+ <a-select v-model="client.flow" style="width: 200px" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
<a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
</a-select>
@@ -136,10 +131,10 @@
</a-form-item>
<br>
<a-form-item label='{{ i18n "pages.client.delayedStart" }}'>
- <a-switch v-model="clientModal.delayedStart" @click="client._expiryTime=0"></a-switch>
+ <a-switch v-model="delayedStart" @click="client._expiryTime=0"></a-switch>
</a-form-item>
<br>
- <a-form-item label='{{ i18n "pages.client.expireDays" }}' v-if="clientModal.delayedStart">
+ <a-form-item label='{{ i18n "pages.client.expireDays" }}' v-if="delayedStart">
<a-input-number v-model="delayedExpireDays" :min="0"></a-input-number>
</a-form-item>
<a-form-item v-else>
@@ -153,9 +148,21 @@
</a-tooltip>
</span>
<a-date-picker :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss"
- :dropdown-class-name="themeSwitcher.darkCardClass"
+ :dropdown-class-name="themeSwitcher.currentTheme"
v-model="client._expiryTime" style="width: 170px;"></a-date-picker>
- <a-tag color="red" v-if="isExpiry">Expired</a-tag>
+ <a-tag color="red" v-if="isEdit && isExpiry">Expired</a-tag>
+ </a-form-item>
+ <a-form-item v-if="client.expiryTime != 0">
+ <span slot="label">
+ <span>{{ i18n "pages.client.renew" }}</span>
+ <a-tooltip>
+ <template slot="title">
+ <span>{{ i18n "pages.client.renewDesc" }}</span>
+ </template>
+ <a-icon type="question-circle" theme="filled"></a-icon>
+ </a-tooltip>
+ </span>
+ <a-input-number v-model.number="client.reset" :min="0"></a-input-number>
</a-form-item>
</a-form>
{{end}} \ No newline at end of file
diff --git a/web/html/xui/form/inbound.html b/web/html/xui/form/inbound.html
index e5b3bfc3..40a96d1e 100644
--- a/web/html/xui/form/inbound.html
+++ b/web/html/xui/form/inbound.html
@@ -9,7 +9,7 @@
<a-input v-model.trim="dbInbound.remark"></a-input>
</a-form-item>
<a-form-item label='{{ i18n "protocol" }}'>
- <a-select v-model="inbound.protocol" style="width: 160px;" :disabled="isEdit" :dropdown-class-name="themeSwitcher.darkCardClass">
+ <a-select v-model="inbound.protocol" style="width: 160px;" :disabled="isEdit" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="p in Protocols" :key="p" :value="p">[[ p ]]</a-select-option>
</a-select>
</a-form-item>
@@ -53,7 +53,7 @@
</a-tooltip>
</span>
<a-date-picker :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss"
- :dropdown-class-name="themeSwitcher.darkCardClass"
+ :dropdown-class-name="themeSwitcher.currentTheme"
v-model="dbInbound._expiryTime" style="width: 250px;"></a-date-picker>
</a-form-item>
</a-form>
diff --git a/web/html/xui/form/protocol/dokodemo.html b/web/html/xui/form/protocol/dokodemo.html
index 0eed31d4..6a37f346 100644
--- a/web/html/xui/form/protocol/dokodemo.html
+++ b/web/html/xui/form/protocol/dokodemo.html
@@ -8,7 +8,7 @@
</a-form-item>
<br>
<a-form-item label='{{ i18n "pages.inbounds.network"}}'>
- <a-select v-model="inbound.settings.network" style="width: 100px;" :dropdown-class-name="themeSwitcher.darkCardClass">
+ <a-select v-model="inbound.settings.network" style="width: 100px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option value="tcp,udp">TCP+UDP</a-select-option>
<a-select-option value="tcp">TCP</a-select-option>
<a-select-option value="udp">UDP</a-select-option>
diff --git a/web/html/xui/form/protocol/shadowsocks.html b/web/html/xui/form/protocol/shadowsocks.html
index 486b372f..001a7006 100644
--- a/web/html/xui/form/protocol/shadowsocks.html
+++ b/web/html/xui/form/protocol/shadowsocks.html
@@ -3,94 +3,7 @@
<template v-if="inbound.isSSMultiUser">
<a-collapse activeKey="0" v-for="(client, index) in inbound.settings.shadowsockses.slice(0,1)" v-if="!isEdit">
<a-collapse-panel header='{{ i18n "pages.inbounds.client" }}'>
- <a-form-item>
- <span slot="label">
- <span>{{ i18n "pages.inbounds.email" }}</span>
- <a-tooltip>
- <template slot="title">
- <span>{{ i18n "pages.inbounds.emailDesc" }}</span>
- </template>
- </a-tooltip>
- </span>
- <a-icon @click="client.email = RandomUtil.randomLowerAndNum(8)" type="sync"> </a-icon>
- <a-input v-model.trim="client.email" style="width: 200px;"></a-input>
- </a-form-item>
- <a-form-item label="Password">
- <a-icon @click="client.password = RandomUtil.randomShadowsocksPassword()" type="sync"> </a-icon>
- <a-input v-model.trim="client.password" style="width: 250px;"></a-input>
- </a-form-item>
- <a-form-item v-if="client.email && app.subSettings.enable">
- <span slot="label">
- Subscription
- <a-tooltip>
- <template slot="title">
- <span>{{ i18n "pages.inbounds.subscriptionDesc" }}</span>
- </template>
- <a-icon type="question-circle" theme="filled"></a-icon>
- </a-tooltip>
- </span>
- <a-icon @click="client.subId = RandomUtil.randomLowerAndNum(16)" type="sync"> </a-icon>
- <a-input v-model.trim="client.subId" style="width: 150px;"></a-input>
- </a-form-item>
- <a-form-item v-if="client.email && app.tgBotEnable">
- <span slot="label">
- Telegram ID
- <a-tooltip>
- <template slot="title">
- <span>{{ i18n "pages.inbounds.telegramDesc" }}</span>
- </template>
- <a-icon type="question-circle" theme="filled"></a-icon>
- </a-tooltip>
- </span>
- <a-input v-model.trim="client.tgId"></a-input>
- </a-form-item>
- <a-form-item>
- <span slot="label">
- <span>{{ i18n "pages.inbounds.IPLimit" }}</span>
- <a-tooltip>
- <template slot="title">
- <span>{{ i18n "pages.inbounds.IPLimitDesc" }}</span>
- </template>
- <a-icon type="question-circle" theme="filled"></a-icon>
- </a-tooltip>
- </span>
- <a-input-number v-model="client.limitIp" min="0"></a-input-number>
- </a-form-item>
- <br>
- <a-form-item>
- <span slot="label">
- <span>{{ i18n "pages.inbounds.totalFlow" }}</span> (GB)
- <a-tooltip>
- <template slot="title">
- 0 <span>{{ i18n "pages.inbounds.meansNoLimit" }}</span>
- </template>
- <a-icon type="question-circle" theme="filled"></a-icon>
- </a-tooltip>
- </span>
- <a-input-number v-model="client._totalGB" :min="0"></a-input-number>
- </a-form-item>
- <br>
- <a-form-item label='{{ i18n "pages.client.delayedStart" }}'>
- <a-switch v-model="delayedStart" @click="client._expiryTime=0"></a-switch>
- </a-form-item>
- <br>
- <a-form-item v-if="delayedStart" label='{{ i18n "pages.client.expireDays" }}'>
- <a-input-number v-model.number="delayedExpireDays" :min="0"></a-input-number>
- </a-form-item>
- <a-form-item v-else>
- <span slot="label">
- <span>{{ i18n "pages.inbounds.expireDate" }}</span>
- <a-tooltip>
- <template slot="title">
- <span>{{ i18n "pages.inbounds.leaveBlankToNeverExpire" }}</span>
- </template>
- <a-icon type="question-circle" theme="filled"></a-icon>
- </a-tooltip>
- </span>
- <a-date-picker :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss"
- :dropdown-class-name="themeSwitcher.darkCardClass"
- v-model="client._expiryTime" style="width: 170px;"></a-date-picker>
- </a-form-item>
+ {{template "form/client"}}
</a-collapse-panel>
</a-collapse>
<a-collapse v-else>
@@ -111,7 +24,7 @@
</a-form>
<a-form layout="inline">
<a-form-item label='{{ i18n "encryption" }}'>
- <a-select v-model="inbound.settings.method" style="width: 250px;" :dropdown-class-name="themeSwitcher.darkCardClass" @change="SSMethodChange">
+ <a-select v-model="inbound.settings.method" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme" @change="SSMethodChange">
<a-select-option v-for="method in SSMethods" :value="method">[[ method ]]</a-select-option>
</a-select>
</a-form-item>
@@ -120,7 +33,7 @@
<a-input v-model.trim="inbound.settings.password" style="width: 250px;"></a-input>
</a-form-item>
<a-form-item label='{{ i18n "pages.inbounds.network" }}'>
- <a-select v-model="inbound.settings.network" style="width: 100px;" :dropdown-class-name="themeSwitcher.darkCardClass">
+ <a-select v-model="inbound.settings.network" style="width: 100px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option value="tcp,udp">TCP+UDP</a-select-option>
<a-select-option value="tcp">TCP</a-select-option>
<a-select-option value="udp">UDP</a-select-option>
diff --git a/web/html/xui/form/protocol/trojan.html b/web/html/xui/form/protocol/trojan.html
index 46ae5e32..b2ac3dba 100644
--- a/web/html/xui/form/protocol/trojan.html
+++ b/web/html/xui/form/protocol/trojan.html
@@ -2,100 +2,7 @@
<a-form layout="inline" style="padding: 10px 0px;">
<a-collapse activeKey="0" v-for="(client, index) in inbound.settings.trojans.slice(0,1)" v-if="!isEdit">
<a-collapse-panel header='{{ i18n "pages.inbounds.client" }}'>
- <a-form-item>
- <span slot="label">
- <span>{{ i18n "pages.inbounds.email" }}</span>
- <a-tooltip>
- <template slot="title">
- <span>{{ i18n "pages.inbounds.emailDesc" }}</span>
- </template>
- </a-tooltip>
- </span>
- <a-icon @click="client.email = RandomUtil.randomLowerAndNum(8)" type="sync"> </a-icon>
- <a-input v-model.trim="client.email" style="width: 200px;"></a-input>
- </a-form-item>
- <a-form-item label="Password">
- <a-icon @click="client.password = RandomUtil.randomSeq(10)" type="sync"> </a-icon>
- <a-input v-model.trim="client.password" style="width: 150px;"></a-input>
- </a-form-item>
- <a-form-item v-if="client.email && app.subSettings.enable">
- <span slot="label">
- Subscription
- <a-tooltip>
- <template slot="title">
- <span>{{ i18n "pages.inbounds.subscriptionDesc" }}</span>
- </template>
- <a-icon type="question-circle" theme="filled"></a-icon>
- </a-tooltip>
- </span>
- <a-icon @click="client.subId = RandomUtil.randomLowerAndNum(16)" type="sync"> </a-icon>
- <a-input v-model.trim="client.subId" style="width: 150px;"></a-input>
- </a-form-item>
- <a-form-item v-if="client.email && app.tgBotEnable">
- <span slot="label">
- Telegram ID
- <a-tooltip>
- <template slot="title">
- <span>{{ i18n "pages.inbounds.telegramDesc" }}</span>
- </template>
- <a-icon type="question-circle" theme="filled"></a-icon>
- </a-tooltip>
- </span>
- <a-input v-model.trim="client.tgId"></a-input>
- </a-form-item>
- <a-form-item>
- <span slot="label">
- <span>{{ i18n "pages.inbounds.IPLimit" }}</span>
- <a-tooltip>
- <template slot="title">