diff options
| author | MHSanaei <ho3ein.sanaei@gmail.com> | 2023-03-17 19:07:49 +0300 |
|---|---|---|
| committer | MHSanaei <ho3ein.sanaei@gmail.com> | 2023-03-17 19:07:49 +0300 |
| commit | 96786c94189f3d2f3f04c1915529c786228bdf42 (patch) | |
| tree | 879085e09a3cd485f3246f46be907fe77eb84a1a /web/html | |
| parent | bc56e637376142c370c31b17558fc3778a863bd2 (diff) | |
alireza
Diffstat (limited to 'web/html')
24 files changed, 999 insertions, 419 deletions
diff --git a/web/html/common/prompt_modal.html b/web/html/common/prompt_modal.html index 3ef764c5..4b8a13d0 100644 --- a/web/html/common/prompt_modal.html +++ b/web/html/common/prompt_modal.html @@ -1,7 +1,7 @@ {{define "promptModal"}} <a-modal id="prompt-modal" v-model="promptModal.visible" :title="promptModal.title" :closable="true" @ok="promptModal.ok" :mask-closable="false" - :class="siderDrawer.isDarkTheme ? darkClass : ''" + :class="siderDrawer.isDarkTheme ? darkClass : ''" :ok-text="promptModal.okText" cancel-text='{{ i18n "cancel" }}'> <a-input id="prompt-modal-input" :type="promptModal.type" v-model="promptModal.value" diff --git a/web/html/common/qrcode_modal.html b/web/html/common/qrcode_modal.html index e6a6d476..6c9afbb3 100644 --- a/web/html/common/qrcode_modal.html +++ b/web/html/common/qrcode_modal.html @@ -1,9 +1,10 @@ {{define "qrcodeModal"}} <a-modal id="qrcode-modal" v-model="qrModal.visible" :title="qrModal.title" :closable="true" width="300px" :ok-text="qrModal.okText" - :class="siderDrawer.isDarkTheme ? darkClass : ''" + :class="siderDrawer.isDarkTheme ? darkClass : ''" cancel-text='{{ i18n "close" }}' :ok-button-props="{attrs:{id:'qr-modal-ok-btn'}}"> - <canvas id="qrCode" style="width: 100%; height: 100%;"></canvas> + <a-tag color="green" style="margin-bottom: 10px;display: block;text-align: center;" >{{ i18n "pages.inbounds.clickOnQRcode" }}</a-tag> + <canvas @click="copyToClipboard()" id="qrCode" style="width: 100%; height: 100%;"></canvas> </a-modal> <script> @@ -35,7 +36,10 @@ this.clipboard = new ClipboardJS('#qr-modal-ok-btn', { text: () => this.copyText, }); - this.clipboard.on('success', () => app.$message.success('{{ i18n "copied" }}')); + this.clipboard.on('success', () => { + app.$message.success('{{ i18n "copied" }}') + this.clipboard.destroy(); + }); } if (this.qrcode === null) { this.qrcode = new QRious({ @@ -58,6 +62,17 @@ data: { qrModal: qrModal, }, + methods: { + copyToClipboard() { + this.qrModal.clipboard = new ClipboardJS('#qrCode', { + text: () => this.qrModal.copyText, + }); + this.qrModal.clipboard.on('success', () => { + app.$message.success('{{ i18n "copied" }}') + this.qrModal.clipboard.destroy(); + }); + } + }, }); </script> diff --git a/web/html/common/text_modal.html b/web/html/common/text_modal.html index a0352c88..b2da6160 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="siderDrawer.isDarkTheme ? darkClass : ''" + :class="siderDrawer.isDarkTheme ? darkClass : ''" :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)" :download="txtModal.fileName"> @@ -32,7 +32,6 @@ }); this.clipboard.on('success', () => app.$message.success('{{ i18n "copied" }}')); } - }); }, close: function () { @@ -41,7 +40,7 @@ }; const textModalApp = new Vue({ - delimiters: ['[[', ']]'], + delimiters: ['[[', ']]'], el: '#text-modal', data: { txtModal: txtModal, diff --git a/web/html/login.html b/web/html/login.html index f2c2116c..5138f15e 100644 --- a/web/html/login.html +++ b/web/html/login.html @@ -39,7 +39,7 @@ <a-layout-content> <a-row type="flex" justify="center"> <a-col :xs="22" :sm="20" :md="16" :lg="12" :xl="8"> - <h1>3x-ui {{ i18n "pages.login.title" }}</h1> + <h1>{{ i18n "pages.login.title" }}</h1> </a-col> </a-row> <a-row type="flex" justify="center"> diff --git a/web/html/xui/client_bulk_modal.html b/web/html/xui/client_bulk_modal.html new file mode 100644 index 00000000..19fd4b18 --- /dev/null +++ b/web/html/xui/client_bulk_modal.html @@ -0,0 +1,160 @@ +{{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="siderDrawer.isDarkTheme ? darkClass : ''" + :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="siderDrawer.isDarkTheme ? 'ant-card-dark' : ''"> + <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> + <a-select-option :value="3">Random_Prefix+Num+Postfix</a-select-option> + <a-select-option :value="4">Random_Prefix+Num@Telegram Username</a-select-option> + </a-select> + </a-form-item><br /> + <a-form-item v-if="clientsBulkModal.emailMethod>1"> + <span slot="label">{{ i18n "pages.client.first" }}</span> + <a-input-number v-model="clientsBulkModal.firstNum" :min="1"></a-input-number> + </a-form-item> + <a-form-item v-if="clientsBulkModal.emailMethod>1"> + <span slot="label">{{ i18n "pages.client.last" }}</span> + <a-input-number v-model="clientsBulkModal.lastNum" :min="clientsBulkModal.firstNum"></a-input-number> + </a-form-item> + <a-form-item v-if="clientsBulkModal.emailMethod>0"> + <span slot="label">{{ i18n "pages.client.prefix" }}</span> + <a-input v-model="clientsBulkModal.emailPrefix" style="width: 120px"></a-input> + </a-form-item> + <a-form-item v-if="clientsBulkModal.emailMethod>2"> + <span slot="label" v-if="clientsBulkModal.emailMethod == 4">tg_uname</span> + <span slot="label" v-else>{{ i18n "pages.client.postfix" }}</span> + <a-input v-model="clientsBulkModal.emailPostfix" style="width: 120px"></a-input> + </a-form-item> + + <a-form-item v-if="clientsBulkModal.emailMethod < 2"> + <span slot="label">{{ i18n "pages.client.clientCount" }}</span> + <a-input-number v-model="clientsBulkModal.quantity" :min="1" :max="100"></a-input-number> + </a-form-item> + <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="clientsBulkModal.totalGB" :min="0"></a-input-number> + </a-form-item> + <a-form-item> + <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' }" format="YYYY-MM-DD HH:mm" + :dropdown-class-name="siderDrawer.isDarkTheme ? 'ant-card-dark' : ''" + v-model="clientsBulkModal.expiryTime" style="width: 300px;"></a-date-picker> + </a-form-item> + </a-form> +</a-modal> +<script> + + const clientsBulkModal = { + visible: false, + confirmLoading: false, + title: '', + okText: '', + confirm: null, + dbInbound: new DBInbound(), + inbound: new Inbound(), + clients: [], + quantity: 1, + totalGB: 0, + expiryTime: '', + emailMethod: 0, + firstNum: 1, + lastNum: 1, + emailPrefix: "", + emailPostfix: "", + ok() { + method=clientsBulkModal.emailMethod; + if(method>1){ + start=clientsBulkModal.firstNum; + end=clientsBulkModal.lastNum + 1; + } else { + start=0; + end=clientsBulkModal.quantity; + } + prefix = (method>0 && clientsBulkModal.emailPrefix.length>0) ? "_" + clientsBulkModal.emailPrefix : ""; + useNum=(method>1); + postfix = (method>2 && clientsBulkModal.emailPostfix.length>0) ? (method == 4 ? "@" : "") + clientsBulkModal.emailPostfix : ""; + for (let i = start; i < end; i++) { + newClient = clientsBulkModal.newClient(clientsBulkModal.dbInbound.protocol); + newClient.email += useNum ? prefix + i.toString() + postfix : prefix + postfix; + newClient._totalGB = clientsBulkModal.totalGB; + newClient._expiryTime = clientsBulkModal.expiryTime; + clientsBulkModal.clients.push(newClient); + } + ObjectUtil.execute(clientsBulkModal.confirm, clientsBulkModal.inbound, clientsBulkModal.dbInbound); + }, + show({ title='', okText='{{ i18n "sure" }}', dbInbound=null, confirm=(inbound, dbInbound)=>{} }) { + this.visible = true; + this.title = title; + this.okText = okText; + this.confirm = confirm; + this.quantity = 1; + this.totalGB = 0; + this.expiryTime = ''; + this.emailMethod= 0; + this.firstNum= 1; + this.lastNum= 1; + this.emailPrefix= ""; + this.emailPostfix= ""; + + this.dbInbound = new DBInbound(dbInbound); + this.inbound = dbInbound.toInbound(); + this.clients = this.getClients(this.inbound.protocol, this.inbound.settings); + }, + getClients(protocol, clientSettings) { + switch(protocol){ + case Protocols.VMESS: return clientSettings.vmesses; + case Protocols.VLESS: return clientSettings.vlesses; + case Protocols.TROJAN: return clientSettings.trojans; + default: return null; + } + }, + newClient(protocol) { + switch (protocol) { + case Protocols.VMESS: return new Inbound.VmessSettings.Vmess(); + case Protocols.VLESS: return new Inbound.VLESSSettings.VLESS(); + case Protocols.TROJAN: return new Inbound.TrojanSettings.Trojan(); + default: return null; + } + }, + close() { + clientsBulkModal.visible = false; + clientsBulkModal.loading(false); + }, + loading(loading) { + clientsBulkModal.confirmLoading = loading; + }, + }; + + const clientsBulkModalApp = new Vue({ + delimiters: ['[[', ']]'], + el: '#client-bulk-modal', + data: { + clientsBulkModal, + get inbound() { + return this.clientsBulkModal.inbound; + }, + }, + }); +</script> +{{end}}
\ No newline at end of file diff --git a/web/html/xui/client_modal.html b/web/html/xui/client_modal.html new file mode 100644 index 00000000..17381a88 --- /dev/null +++ b/web/html/xui/client_modal.html @@ -0,0 +1,133 @@ +{{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="siderDrawer.isDarkTheme ? darkClass : ''" + :ok-text="clientModal.okText" cancel-text='{{ i18n "close" }}'> + {{template "form/client"}} +</a-modal> +<script> + + const clientModal = { + visible: false, + confirmLoading: false, + title: '', + okText: '', + dbInbound: new DBInbound(), + inbound: new Inbound(), + clients: [], + clientStats: [], + index: null, + clientIps: null, + isExpired: false, + ok() { + ObjectUtil.execute(clientModal.confirm, clientModal.inbound, clientModal.dbInbound, clientModal.index); + }, + show({ title='', okText='{{ i18n "sure" }}', index=null, dbInbound=null, confirm=(index, dbInbound)=>{}, isEdit=false }) { + this.visible = true; + this.title = title; + this.okText = okText; + this.isEdit = isEdit; + this.dbInbound = new DBInbound(dbInbound); + this.inbound = dbInbound.toInbound(); + this.clients = this.getClients(this.inbound.protocol, this.inbound.settings); + this.index = index === null ? this.clients.length : index; + this.isExpired = isEdit ? this.inbound.isExpiry(this.index) : false; + if (!isEdit){ + this.addClient(this.inbound.protocol, this.clients); + } + this.clientStats = this.dbInbound.clientStats.find(row => row.email === this.clients[this.index].email); + this.confirm = confirm; + }, + getClients(protocol, clientSettings) { + switch(protocol){ + case Protocols.VMESS: return clientSettings.vmesses; + case Protocols.VLESS: return clientSettings.vlesses; + case Protocols.TROJAN: return clientSettings.trojans; + default: return null; + } + }, + addClient(protocol, clients) { + switch (protocol) { + case Protocols.VMESS: return clients.push(new Inbound.VmessSettings.Vmess()); + case Protocols.VLESS: return clients.push(new Inbound.VLESSSettings.VLESS()); + case Protocols.TROJAN: return clients.push(new Inbound.TrojanSettings.Trojan()); + default: return null; + } + }, + close() { + clientModal.visible = false; + clientModal.loading(false); + }, + loading(loading) { + clientModal.confirmLoading = loading; + }, + }; + + const clientModalApp = new Vue({ + delimiters: ['[[', ']]'], + el: '#client-modal', + data: { + clientModal, + get inbound() { + return this.clientModal.inbound; + }, + get client() { + return this.clientModal.clients[this.clientModal.index]; + }, + get clientStats() { + return this.clientModal.clientStats; + }, + get isEdit() { + return this.clientModal.isEdit; + }, + get isTrafficExhausted() { + if(!clientStats) return false + if(clientStats.total == 0) return false + if(clientStats.up + clientStats.down < clientStats.total) return false + return true + }, + get isExpiry() { + return this.clientModal.isExpired + }, + get statsColor() { + if(!clientStats) return 'blue' + if(clientStats.total === 0) return 'blue' + else if(clientStats.total > 0 && (clientStats.down+clientStats.up) < clientStats.total) return 'cyan' + else return 'red' + } + }, + methods: { + getNewEmail(client) { + var chars = 'abcdefghijklmnopqrstuvwxyz1234567890'; + var string = ''; + var len = 6 + Math.floor(Math.random() * 5); + for(var ii=0; ii<len; ii++){ + string += chars[Math.floor(Math.random() * chars.length)]; + } + client.email = string; + }, + async getDBClientIps(email,event) { + const msg = await HttpUtil.post('/xui/inbound/clientIps/'+ email); + if (!msg.success) { + return; + } + try { + ips = JSON.parse(msg.obj) + ips = ips.join(",") + event.target.value = ips + } catch (error) { + // text + event.target.value = msg.obj + } + }, + async clearDBClientIps(email,event) { + const msg = await HttpUtil.post('/xui/inbound/clearClientIps/'+ email); + if (!msg.success) { + return; + } + event.target.value = "" + }, + }, + }); +</script> +{{end}} diff --git a/web/html/xui/common_sider.html b/web/html/xui/common_sider.html index 9de00175..13c24c34 100644 --- a/web/html/xui/common_sider.html +++ b/web/html/xui/common_sider.html @@ -13,14 +13,14 @@ </a-menu-item> <!--<a-menu-item key="{{ .base_path }}xui/clients">--> <!-- <a-icon type="laptop"></a-icon>--> -<!-- <span>client</span>--> +<!-- <span>Client</span>--> <!--</a-menu-item>--> <a-sub-menu> <template slot="title"> <a-icon type="link"></a-icon> <span>{{ i18n "menu.link"}}</span> </template> - <a-menu-item key="https://github.com/mhsanaei/3x-ui/"> + <a-menu-item key="https://github.com/mhsanaei/3x-ui/"> <a-icon type="github"></a-icon> <span>Github</span> </a-menu-item> @@ -55,11 +55,12 @@ <a-drawer id="sider-drawer" placement="left" :closable="false" @close="siderDrawer.close()" :visible="siderDrawer.visible" + :wrap-class-name="siderDrawer.isDarkTheme ? 'ant-drawer-dark' : ''" :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 mode="inline" selected-keys=""> + <a-menu :theme="siderDrawer.theme" mode="inline" selected-keys=""> <a-menu-item mode="inline"> <a-icon type="bg-colors"></a-icon> <a-switch :default-checked="siderDrawer.isDarkTheme" @@ -68,19 +69,17 @@ @change="siderDrawer.changeTheme()"></a-switch> </a-menu-item> </a-menu> - <a-menu mode="inline" :selected-keys="['{{ .request_uri }}']" + <a-menu :theme="siderDrawer.theme" mode="inline" :selected-keys="['{{ .request_uri }}']" @click="({key}) => key.startsWith('http') ? window.open(key) : location.href = key"> {{template "menuItems" .}} </a-menu> </a-drawer> <script> - - const darkClass = "ant-card-dark"; const bgDarkStyle = "background-color: #242c3a"; const siderDrawer = { visible: false, - collapsed: false, + collapsed: false, isDarkTheme: localStorage.getItem("dark-mode") === 'true' ? true : false, show() { this.visible = true; @@ -90,7 +89,7 @@ }, change() { this.visible = !this.visible; - }, + }, toggleCollapsed() { this.collapsed = !this.collapsed; }, diff --git a/web/html/xui/form/client.html b/web/html/xui/form/client.html new file mode 100644 index 00000000..586f4fd4 --- /dev/null +++ b/web/html/xui/form/client.html @@ -0,0 +1,110 @@ +{{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> + <span slot="label"> + Email + <a-tooltip> + <template slot="title"> + The Email Must Be Completely Unique + </template> + <a-icon type="sync" @click="getNewEmail(client)"></a-icon> + </a-tooltip> + </span> + <a-input v-model.trim="client.email" style="width: 150px;" ></a-input> + </a-form-item> + <a-form-item label="Password" v-if="inbound.protocol === Protocols.TROJAN"> + <a-input v-model.trim="client.password" style="width: 150px;" ></a-input> + </a-form-item> + <a-form-item label="ID" v-if="inbound.protocol === Protocols.VMESS || inbound.protocol === Protocols.VLESS"> + <a-input v-model.trim="client.id" style="width: 300px;"></a-input> + </a-form-item> + <a-form-item label='{{ i18n "additional" }} ID' v-if="inbound.protocol === Protocols.VMESS"> + <a-input type="number" v-model.number="client.alterId" style="width: 70px;"></a-input> + </a-form-item> + <a-form-item> + <span slot="label"> + IP Count Limit + <a-tooltip> + <template slot="title"> + Disable inbound if more than entered count (0 for disable limit ip) + </template> + <a-icon type="question-circle" theme="filled"></a-icon> + </a-tooltip> + </span> + <a-input type="number" v-model.number="client.limitIp" min="0" style="width: 70px;" ></a-input> + </a-form-item> + <a-form-item v-if="client.email && client.limitIp > 0 && isEdit"> + <span slot="label"> + IP Log + <a-tooltip> + <template slot="title"> + IPs history Log (before enabling inbound after it has been disabled by IP limit, you should clear the log) + </template> + <a-icon type="question-circle" theme="filled"></a-icon> + </a-tooltip> + <a-tooltip> + <template slot="title"> + Clear The Log + </template> + <span style="color: #FF4D4F"> + <a-icon type="delete" @click="clearDBClientIps(client.email,$event)"></a-icon> + </span> + </a-tooltip> + </span> + <a-form layout="block"> + <a-textarea readonly @click="getDBClientIps(client.email,$event)" placeholder="Click To Get IPs" :auto-size="{ minRows: 2, maxRows: 10 }"> + </a-textarea> + </a-form> + </a-form-item> + <a-form-item v-if="inbound.XTLS" label="Flow"> + <a-select v-model="client.flow" style="width: 150px"> + <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" layout="inline"> + <a-select v-model="client.flow" style="width: 150px"> + <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> + </a-form-item> + <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" style="width: 70px;"></a-input-number> + <template v-if="isEdit && clientStats"> + {{ i18n "usage" }}: + <a-tag :color="statsColor"> + [[ sizeFormat(clientStats.up) ]] / + [[ sizeFormat(clientStats.down) ]] + ([[ sizeFormat(clientStats.up + clientStats.down) ]]) + </a-tag> + </template> + </a-form-item> + <a-form-item> + <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' }" format="YYYY-MM-DD HH:mm" + :dropdown-class-name="siderDrawer.isDarkTheme ? 'ant-card-dark' : ''" + v-model="client._expiryTime" style="width: 170px;"></a-date-picker> + <a-tag color="red" v-if="isExpiry">Expired</a-tag> + </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 1a2e7ca1..74fe1384 100644 --- a/web/html/xui/form/inbound.html +++ b/web/html/xui/form/inbound.html @@ -8,7 +8,7 @@ <a-switch v-model="dbInbound.enable"></a-switch> </a-form-item> <a-form-item label='{{ i18n "protocol" }}'> - <a-select v-model="inbound.protocol" style="width: 160px;"> + <a-select v-model="inbound.protocol" style="width: 160px;" :disabled="isEdit" :dropdown-class-name="siderDrawer.isDarkTheme ? 'ant-card-dark' : ''"> <a-select-option v-for="p in Protocols" :key="p" :value="p">[[ p ]]</a-select-option> </a-select> </a-form-item> @@ -50,6 +50,7 @@ </a-tooltip> </span> <a-date-picker :show-time="{ format: 'HH:mm' }" format="YYYY-MM-DD HH:mm" + :dropdown-class-name="siderDrawer.isDarkTheme ? 'ant-card-dark' : ''" v-model="dbInbound._expiryTime" style="width: 300px;"></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 a4dde06d..dbba6b5b 100644 --- a/web/html/xui/form/protocol/dokodemo.html +++ b/web/html/xui/form/protocol/dokodemo.html @@ -7,11 +7,14 @@ <a-input type="number" v-model.number="inbound.settings.port"></a-input> </a-form-item> <a-form-item label='{{ i18n "pages.inbounds.network"}}'> - <a-select v-model="inbound.settings.network" style="width: 100px;"> + <a-select v-model="inbound.settings.network" style="width: 100px;" :dropdown-class-name="siderDrawer.isDarkTheme ? 'ant-card-dark' : ''"> <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> </a-select> </a-form-item> + <a-form-item label="FollowRedirect"> + <a-switch v-model="inbound.settings.followRedirect"></a-switch> + </a-form-item> </a-form> {{end}}
\ No newline at end of file diff --git a/web/html/xui/form/protocol/shadowsocks.html b/web/html/xui/form/protocol/shadowsocks.html index 18bcf727..21d614ae 100644 --- a/web/html/xui/form/protocol/shadowsocks.html +++ b/web/html/xui/form/protocol/shadowsocks.html @@ -1,7 +1,7 @@ {{define "form/shadowsocks"}} <a-form layout="inline"> <a-form-item label='{{ i18n "encryption" }}'> - <a-select v-model="inbound.settings.method" style="width: 165px;"> + <a-select v-model="inbound.settings.method" style="width: 165px;" :dropdown-class-name="siderDrawer.isDarkTheme ? 'ant-card-dark' : ''"> <a-select-option v-for="method in SSMethods" :value="method">[[ method ]]</a-select-option> </a-select> </a-form-item> @@ -9,7 +9,7 @@ <a-input v-model.trim="inbound.settings.password"></a-input> </a-form-item> <a-form-item label='{{ i18n "pages.inbounds.network" }}'> - <a-select v-model="inbound.settings.network" style="width: 100px;"> + <a-select v-model="inbound.settings.network" style="width: 100px;" :dropdown-class-name="siderDrawer.isDarkTheme ? 'ant-card-dark' : ''"> <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/socks.html b/web/html/xui/form/protocol/socks.html index 35c1c0b5..5857d413 100644 --- a/web/html/xui/form/protocol/socks.html +++ b/ |
