From bc56e637376142c370c31b17558fc3778a863bd2 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Fri, 17 Mar 2023 01:31:14 +0330 Subject: pack1 --- web/html/common/prompt_modal.html | 1 + web/html/common/qrcode_modal.html | 1 + web/html/common/text_modal.html | 14 +-- web/html/xui/common_sider.html | 44 +++++++- web/html/xui/component/inbound_info.html | 94 ----------------- web/html/xui/form/protocol/trojan.html | 88 ++++++++-------- web/html/xui/form/protocol/vless.html | 89 ++++++++-------- web/html/xui/form/protocol/vmess.html | 20 ++-- web/html/xui/form/stream/stream_settings.html | 2 +- web/html/xui/form/tls_settings.html | 42 +++++--- web/html/xui/inbound_info_modal.html | 1 + web/html/xui/inbound_modal.html | 56 +++++----- web/html/xui/inbounds.html | 144 ++++++++++++++------------ web/html/xui/index.html | 42 ++++++-- web/html/xui/setting.html | 20 ++-- 15 files changed, 317 insertions(+), 341 deletions(-) delete mode 100644 web/html/xui/component/inbound_info.html (limited to 'web/html') diff --git a/web/html/common/prompt_modal.html b/web/html/common/prompt_modal.html index 91c26615..3ef764c5 100644 --- a/web/html/common/prompt_modal.html +++ b/web/html/common/prompt_modal.html @@ -1,6 +1,7 @@ {{define "promptModal"}} diff --git a/web/html/common/text_modal.html b/web/html/common/text_modal.html index 0ae04a88..a0352c88 100644 --- a/web/html/common/text_modal.html +++ b/web/html/common/text_modal.html @@ -1,9 +1,10 @@ {{define "textModal"}} + :href="'data:application/text;charset=utf-8,' + encodeURIComponent(txtModal.content)" :download="txtModal.fileName"> {{ i18n "download" }} [[ txtModal.fileName ]] app.$message.success('{{ i18n "copied" }}')); } - if (this.qrcode === null) { - this.qrcode = new QRious({ - element: document.querySelector('#qrCode'), - size: 260, - value: content, - }); - } else { - this.qrcode.value = content; - } + }); }, close: function () { @@ -48,6 +41,7 @@ }; const textModalApp = new Vue({ + delimiters: ['[[', ']]'], el: '#text-modal', data: { txtModal: txtModal, diff --git a/web/html/xui/common_sider.html b/web/html/xui/common_sider.html index 38a55265..9de00175 100644 --- a/web/html/xui/common_sider.html +++ b/web/html/xui/common_sider.html @@ -24,7 +24,7 @@ Github - + Telegram @@ -37,27 +37,51 @@ {{define "commonSider"}} - - + + + + + + + {{template "menuItems" .}} + :visible="siderDrawer.visible" + :wrap-style="{ padding: 0 }">
- + + + + + + {{template "menuItems" .}}
-{{end}} \ No newline at end of file diff --git a/web/html/xui/form/protocol/trojan.html b/web/html/xui/form/protocol/trojan.html index 4bf57d7a..3127e4c5 100644 --- a/web/html/xui/form/protocol/trojan.html +++ b/web/html/xui/form/protocol/trojan.html @@ -1,6 +1,6 @@ {{define "form/trojan"}} - + @@ -20,8 +20,11 @@ xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="anticon anticon-question-circle" viewBox="0 0 16 16"> - + + + + IP Count Limit @@ -32,7 +35,7 @@ - + @@ -53,15 +56,12 @@ - + - - - - + {{ i18n "none" }} [[ key ]] @@ -90,7 +90,7 @@ + v-model="trojan._expiryTime" style="width: 170px;"> @@ -123,39 +123,41 @@ - - - - - + - - - - + {{end}} \ No newline at end of file diff --git a/web/html/xui/form/protocol/vless.html b/web/html/xui/form/protocol/vless.html index 6d895f19..67337aba 100644 --- a/web/html/xui/form/protocol/vless.html +++ b/web/html/xui/form/protocol/vless.html @@ -1,6 +1,6 @@ {{define "form/vless"}} - + @@ -21,8 +21,11 @@ xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="anticon anticon-question-circle" viewBox="0 0 16 16"> - + + + + IP Count Limit @@ -33,7 +36,7 @@ - + @@ -55,15 +58,12 @@ - + - - - - + {{ i18n "none" }} [[ key ]] @@ -75,11 +75,6 @@ [[ key ]] - - - [[ key ]] - - {{ i18n "pages.inbounds.totalFlow" }}(GB) @@ -137,39 +132,41 @@ - - - - - + - - - - + {{end}} \ No newline at end of file diff --git a/web/html/xui/form/protocol/vmess.html b/web/html/xui/form/protocol/vmess.html index bab0cb8b..d7561633 100644 --- a/web/html/xui/form/protocol/vmess.html +++ b/web/html/xui/form/protocol/vmess.html @@ -1,6 +1,6 @@ {{define "form/vmess"}} - + @@ -20,8 +20,14 @@ xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="anticon anticon-question-circle" viewBox="0 0 16 16"> - + + + + + + + IP Count Limit @@ -32,7 +38,7 @@ - + @@ -52,16 +58,10 @@ - + - - - - - - {{ i18n "pages.inbounds.totalFlow" }}(GB) diff --git a/web/html/xui/form/stream/stream_settings.html b/web/html/xui/form/stream/stream_settings.html index e3b8308a..d5c7e425 100644 --- a/web/html/xui/form/stream/stream_settings.html +++ b/web/html/xui/form/stream/stream_settings.html @@ -8,7 +8,7 @@ WS HTTP QUIC - GRPC + gRPC diff --git a/web/html/xui/form/tls_settings.html b/web/html/xui/form/tls_settings.html index ea3216e7..532850c7 100644 --- a/web/html/xui/form/tls_settings.html +++ b/web/html/xui/form/tls_settings.html @@ -5,13 +5,22 @@ - - + + - + + + + + + + auto + [[ key ]] + + [[ key ]] @@ -22,17 +31,20 @@ [[ key ]] - - - auto - [[ key ]] - - + + + None + [[ key ]] + + - - + + + auto + [[ key ]] + @@ -42,18 +54,18 @@ diff --git a/web/html/xui/inbound_info_modal.html b/web/html/xui/inbound_info_modal.html index 2ffebe85..737665d5 100644 --- a/web/html/xui/inbound_info_modal.html +++ b/web/html/xui/inbound_info_modal.html @@ -3,6 +3,7 @@ v-model="infoModal.visible" title='{{ i18n "pages.inbounds.details"}}' :closable="true" :mask-closable="true" + :class="siderDrawer.isDarkTheme ? darkClass : ''" :footer="null" width="600px" > diff --git a/web/html/xui/inbound_modal.html b/web/html/xui/inbound_modal.html index 54a64bf9..7b7450b6 100644 --- a/web/html/xui/inbound_modal.html +++ b/web/html/xui/inbound_modal.html @@ -1,6 +1,7 @@ {{define "inboundModal"}} {{template "form/inbound"}} @@ -88,22 +89,18 @@ removeClient(index, clients) { clients.splice(index, 1); }, - 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 getDBClientIps(email, event) { + const msg = await HttpUtil.post('/xui/inbound/clientIps/' + email); + if (!msg.success) { + return; + } + try { + let ips = JSON.parse(msg.obj); + ips = ips.join(","); + event.target.value = ips; + } catch (error) { + event.target.value = msg.obj; + } }, async clearDBClientIps(email,event) { const msg = await HttpUtil.post('/xui/inbound/clearClientIps/'+ email); @@ -112,20 +109,19 @@ } event.target.value = "" }, - async resetClientTraffic(client,event) { - const msg = await HttpUtil.post('/xui/inbound/resetClientTraffic/'+ client.email); - if (!msg.success) { - return; - } - clientStats = this.inbound.clientStats - if(clientStats.length > 0) - { - for (const key in clientStats) { - if (Object.hasOwnProperty.call(clientStats, key)) { - if(clientStats[key]['email'] == client.email){ - clientStats[key]['up'] = 0 - clientStats[key]['down'] = 0 - } + async resetClientTraffic(client, event) { + const msg = await HttpUtil.post(`/xui/inbound/resetClientTraffic/${client.email}`); + if (!msg.success) { + return; + } + const clientStats = this.inbound.clientStats; + if (clientStats.length > 0) { + for (let i = 0; i < clientStats.length; i++) { + if (clientStats[i].email === client.email) { + clientStats[i].up = 0; + clientStats[i].down = 0; + break; // Stop looping once we've found the matching client. + } } } diff --git a/web/html/xui/inbounds.html b/web/html/xui/inbounds.html index 1f324846..cc759394 100644 --- a/web/html/xui/inbounds.html +++ b/web/html/xui/inbounds.html @@ -11,11 +11,15 @@ .ant-col-sm-24 { margin-top: 10px; } + + .ant-table-row-expand-icon { + color: rgba(0,0,0,.65); + } {{ template "commonSider" . }} - + @@ -24,7 +28,7 @@ - + {{ i18n "pages.inbounds.totalDownUp" }}: @@ -38,11 +42,17 @@ {{ i18n "pages.inbounds.inboundCount" }}: [[ dbInbounds.length ]] + + {{ i18n "clients" }}: + [[ total.clients ]] + {{ i18n "enabled" }} [[ total.active ]] + {{ i18n "disabled" }} [[ total.deactive ]] + - +
Add Inbound Export Links @@ -67,6 +77,12 @@ {{ i18n "edit" }} + {{ i18n "pages.inbounds.resetTraffic" }} @@ -202,7 +218,7 @@ { title: '{{ i18n "pages.inbounds.client" }}', width: 60, scopedSlots: { customRender: 'client' } }, { title: '{{ i18n "pages.inbounds.traffic" }}↑|↓', width: 100, scopedSlots: { customRender: 'traffic' } }, { title: '{{ i18n "pages.inbounds.expireDate" }}', width: 70, scopedSlots: { customRender: 'expiryTime' } }, - { title: 'UID', width: 120, dataIndex: "id" }, + { title: 'UID', width: 150, dataIndex: "id" }, ]; @@ -281,6 +297,9 @@ case "qrcode": this.showQrcode(dbInbound); break; + case "export": + this.inboundLinks(dbInbound.id); + break; case "edit": this.openEditInbound(dbInbound.id); break; @@ -372,18 +391,6 @@ }, }); }, - exportAllLinks() { - let copyText = ''; - for (const dbInbound of this.dbInbounds) { - copyText += dbInbound.genInboundLinks - } - const clipboard = new ClipboardJS('.copy-btn', { - text: function () { - return copyText; - } - }); - clipboard.on('success', () => { this.$message.success('Export Links succeed'); }); - }, delInbound(dbInbound) { this.$confirm({ title: '{{ i18n "pages.inbounds.deleteInbound"}}', @@ -393,7 +400,15 @@ onOk: () => this.submit('/xui/inbound/del/' + dbInbound.id), }); }, - showQrcode(dbInbound, clientIndex) { + 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; + } + }, + showQrcode(dbInbound, clientIndex) { const link = dbInbound.genLink(clientIndex); qrModal.show('{{ i18n "qrCode"}}', link, dbInbound); }, @@ -451,60 +466,34 @@ return dbInbound.toInbound().isExpiry(index) }, getUpStats(dbInbound, email) { - clientStats = dbInbound.clientStats - if(clientStats.length > 0) - { - for (const key in clientStats) { - if (Object.hasOwnProperty.call(clientStats, key)) { - if(clientStats[key]['email'] == email) - return clientStats[key]['up'] - - } - } - } - + if(email.length == 0) return 0 + clientStats = dbInbound.clientStats.find(stats => stats.email === email) + return clientStats ? clientStats.up : 0 }, getDownStats(dbInbound, email) { - clientStats = dbInbound.clientStats - if(clientStats.length > 0) - { - for (const key in clientStats) { - if (Object.hasOwnProperty.call(clientStats, key)) { - if(clientStats[key]['email'] == email) - return clientStats[key]['down'] - - } - } - } + if(email.length == 0) return 0 + clientStats = dbInbound.clientStats.find(stats => stats.email === email) + return clientStats ? clientStats.down : 0 }, isTrafficExhausted(dbInbound, email) { - clientStats = dbInbound.clientStats - if(clientStats.length > 0) - { - for (const key in clientStats) { - if (Object.hasOwnProperty.call(clientStats, key)) { - if(clientStats[key]['email'] == email) - return clientStats[key]['down']+clientStats[key]['up'] > clientStats[key]['total'] - - } - } + if(email.length == 0) return false + clientStats = dbInbound.clientStats.find(stats => stats.email === email) + return clientStats ? clientStats.down + clientStats.up > clientStats.total : false + }, + inboundLinks(dbInboundId) { + dbInbound = this.dbInbounds.find(row => row.id === dbInboundId); + txtModal.show('{{ i18n "pages.inbounds.export"}}',dbInbound.genInboundLinks,dbInbound.remark); + }, + exportAllLinks() { + let copyText = ''; + for (const dbInbound of this.dbInbounds) { + copyText += dbInbound.genInboundLinks } + txtModal.show('{{ i18n "pages.inbounds.export"}}',copyText,'All-Inbounds'); }, isClientEnabled(dbInbound, email) { - clientStats = dbInbound.clientStats - if(clientStats.length > 0) - { - for (const key in clientStats) { - if (Object.hasOwnProperty.call(clientStats, key)) { - if(clientStats[key]['email'] == email) - return clientStats[key]['enable'] - - } - } - } - else{ - return true - } + clientStats = dbInbound.clientStats ? dbInbound.clientStats.find(stats => stats.email === email) : null + return clientStats ? clientStats['enable'] : true }, }, watch: { @@ -518,13 +507,32 @@ computed: { total() { let down = 0, up = 0; - for (let i = 0; i < this.dbInbounds.length; ++i) { - down += this.dbInbounds[i].down; - up += this.dbInbounds[i].up; - } + let clients = 0, active = 0, deactive = 0; + this.dbInbounds.forEach(dbInbound => { + down += dbInbound.down; + up += dbInbound.up; + inbound = dbInbound.toInbound(); + clients = this.getClients(dbInbound.protocol, inbound.settings); + if(clients){ + if(dbInbound.enable){ + isClientEnable = false; + clients.forEach(client => { + isClientEnable = client.email == "" ? true: this.isClientEnabled(dbInbound,client.email); + isClientEnable ? active++ : deactive++; + }); + } else { + deactive += clients.length; + } + } else { + dbInbound.enable ? active++ : deactive++; + } + }); return { down: down, up: up, + clients: active + deactive, + active: active, + deactive: deactive, }; } }, diff --git a/web/html/xui/index.html b/web/html/xui/index.html index 141174dc..604c6621 100644 --- a/web/html/xui/index.html +++ b/web/html/xui/index.html @@ -15,24 +15,26 @@ {{ template "commonSider" . }} - + - +
CPU
{{ i18n "pages.index.memory"}}: [[ sizeFormat(status.mem.current) ]] / [[ sizeFormat(status.mem.total) ]] @@ -45,6 +47,7 @@
Swap: [[ sizeFormat(status.swap.current) ]] / [[ sizeFormat(status.swap.total) ]] @@ -53,6 +56,7 @@
{{ i18n "pages.index.hard"}}: [[ sizeFormat(status.disk.current) ]] / [[ sizeFormat(status.disk.total) ]] @@ -67,7 +71,7 @@ - + {{ i18n "pages.index.xrayStatus" }}: [[ status.xray.state ]] @@ -77,11 +81,13 @@ [[ status.xray.version ]] - {{ i18n "pages.index.xraySwitch"}} + {{ i18n "pages.index.stopXray" }} + {{ i18n "pages.index.restartXray" }} + {{ i18n "pages.index.xraySwitch" }} - + {{ i18n "pages.index.operationHours" }}: [[ formatSecond(status.uptime) ]] @@ -93,12 +99,12 @@ - + {{ i18n "pages.index.systemLoad" }}: [[ status.loads[0] ]] | [[ status.loads[1] ]] | [[ status.loads[2] ]] - + TCP / UDP {{ i18n "pages.index.connectionCount" }}: [[ status.tcpCount ]] / [[ status.udpCount ]]