diff options
| author | MHSanaei <mc.sanaei@gmail.com> | 2023-02-09 22:18:06 +0300 |
|---|---|---|
| committer | MHSanaei <mc.sanaei@gmail.com> | 2023-02-09 22:18:06 +0300 |
| commit | b73e4173a3c1e69e02ad6b4e3b43e425e57a5be9 (patch) | |
| tree | d95d2f5e903d97082e11eb9f9023c165b1bde388 /web/html/common | |
3x-ui
Diffstat (limited to 'web/html/common')
| -rw-r--r-- | web/html/common/head.html | 17 | ||||
| -rw-r--r-- | web/html/common/js.html | 22 | ||||
| -rw-r--r-- | web/html/common/prompt_modal.html | 67 | ||||
| -rw-r--r-- | web/html/common/qrcode_modal.html | 120 | ||||
| -rw-r--r-- | web/html/common/text_modal.html | 58 |
5 files changed, 284 insertions, 0 deletions
diff --git a/web/html/common/head.html b/web/html/common/head.html new file mode 100644 index 00000000..f34ce62f --- /dev/null +++ b/web/html/common/head.html @@ -0,0 +1,17 @@ +{{define "head"}} +<head> + <meta charset="UTF-8"> + <meta name="renderer" content="webkit"> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link rel="stylesheet" href="{{ .base_path }}assets/ant-design-vue@1.7.2/antd.min.css"> + <link rel="stylesheet" href="{{ .base_path }}assets/element-ui@2.15.0/theme-chalk/display.css"> + <link rel="stylesheet" href="{{ .base_path }}assets/css/custom.css?{{ .cur_ver }}"> + <style> + [v-cloak] { + display: none; + } + </style> + <title>{{ i18n .title}}</title> +</head> +{{end}}
\ No newline at end of file diff --git a/web/html/common/js.html b/web/html/common/js.html new file mode 100644 index 00000000..d400196b --- /dev/null +++ b/web/html/common/js.html @@ -0,0 +1,22 @@ +{{define "js"}} +<script src="{{ .base_path }}assets/vue@2.6.12/vue.min.js"></script> +<script src="{{ .base_path }}assets/moment/moment.min.js"></script> +<script src="{{ .base_path }}assets/ant-design-vue@1.7.2/antd.min.js"></script> +<script src="{{ .base_path }}assets/base64/base64.min.js"></script> +<script src="{{ .base_path }}assets/axios/axios.min.js"></script> +<script src="{{ .base_path }}assets/qs/qs.min.js"></script> +<script src="{{ .base_path }}assets/qrcode/qrious.min.js"></script> +<script src="{{ .base_path }}assets/clipboard/clipboard.min.js"></script> +<script src="{{ .base_path }}assets/uri/URI.min.js"></script> +<script src="{{ .base_path }}assets/js/axios-init.js?{{ .cur_ver }}"></script> +<script src="{{ .base_path }}assets/js/util/common.js?{{ .cur_ver }}"></script> +<script src="{{ .base_path }}assets/js/util/date-util.js?{{ .cur_ver }}"></script> +<script src="{{ .base_path }}assets/js/util/utils.js?{{ .cur_ver }}"></script> +<script src="{{ .base_path }}assets/js/model/xray.js?{{ .cur_ver }}"></script> +<script src="{{ .base_path }}assets/js/model/models.js?{{ .cur_ver }}"></script> +<script src="{{ .base_path }}assets/js/langs.js"></script> +<script> + const basePath = '{{ .base_path }}'; + axios.defaults.baseURL = basePath; +</script> +{{end}}
\ No newline at end of file diff --git a/web/html/common/prompt_modal.html b/web/html/common/prompt_modal.html new file mode 100644 index 00000000..91c26615 --- /dev/null +++ b/web/html/common/prompt_modal.html @@ -0,0 +1,67 @@ +{{define "promptModal"}} +<a-modal id="prompt-modal" v-model="promptModal.visible" :title="promptModal.title" + :closable="true" @ok="promptModal.ok" :mask-closable="false" + :ok-text="promptModal.okText" cancel-text='{{ i18n "cancel" }}'> + <a-input id="prompt-modal-input" :type="promptModal.type" + v-model="promptModal.value" + :autosize="{minRows: 10, maxRows: 20}" + @keydown.enter.native="promptModal.keyEnter" + @keydown.ctrl.83="promptModal.ctrlS"></a-input> +</a-modal> + +<script> + + const promptModal = { + title: '', + type: '', + value: '', + okText: '{{ i18n "sure"}}', + visible: false, + keyEnter(e) { + if (this.type !== 'textarea') { + e.preventDefault(); + this.ok(); + } + }, + ctrlS(e) { + if (this.type === 'textarea') { + e.preventDefault(); + promptModal.confirm(promptModal.value); + } + }, + ok() { + promptModal.close(); + promptModal.confirm(promptModal.value); + }, + confirm() {}, + open({ + title='', + type='text', + value='', + okText='{{ i18n "sure"}}', + confirm=() => {}, + }) { + this.title = title; + this.type = type; + this.value = value; + this.okText = okText; + this.confirm = confirm; + this.visible = true; + promptModalApp.$nextTick(() => { + document.querySelector('#prompt-modal-input').focus(); + }); + }, + close() { + this.visible = false; + } + }; + + const promptModalApp = new Vue({ + el: '#prompt-modal', + data: { + promptModal: promptModal, + }, + }); + +</script> +{{end}}
\ No newline at end of file diff --git a/web/html/common/qrcode_modal.html b/web/html/common/qrcode_modal.html new file mode 100644 index 00000000..c80f8a0e --- /dev/null +++ b/web/html/common/qrcode_modal.html @@ -0,0 +1,120 @@ +{{define "qrcodeModal"}} +<a-modal id="qrcode-modal" v-model="qrModal.visible" :title="qrModal.title" + :closable="true" width="300px" :ok-text="qrModal.okText" + cancel-text='{{ i18n "close" }}' :ok-button-props="{attrs:{id:'qr-modal-ok-btn'}}"> + <a-tag color="green" style="margin-bottom: 10px;display: block;text-align: center;" >click on QR Code to Copy</a-tag> + <canvas v-if="qrModal.inbound.protocol != Protocols.VMESS && qrModal.inbound.protocol != Protocols.VLESS" id="qrCode" style="width: 100%; height: 100%;"></canvas> + + <template v-if="qrModal.inbound.protocol === Protocols.VMESS" v-for="(vmess, index) in qrModal.inbound.settings.vmesses"> + <a-tag color="red" style="margin-bottom: 10px;display: block;text-align: center;" v-text="vmess.email"></a-tag> + <canvas @click="copyTextToClipboard(`qrCode-vmess-${vmess.id}`,index)" :id="`qrCode-vmess-${vmess.id}`" style="width: 100%; height: 100%;"></canvas> + <a-divider style="height: 2px; background-color: #7e7e7e" /> + </template> + + <template v-if="qrModal.inbound.protocol === Protocols.VLESS" v-for="(vless, index) in qrModal.inbound.settings.vlesses"> + <a-tag color="red" style="margin-bottom: 10px;display: block;text-align: center;" v-text="vless.email"></a-tag> + <canvas @click="copyTextToClipboard(`qrCode-vless-${vless.id}`,index)" :id="`qrCode-vless-${vless.id}`" style="width: 100%; height: 100%;"></canvas> + <a-divider style="height: 2px; background-color: #7e7e7e" /> + </template> +</a-modal> + +<script> + + const qrModal = { + title: '', + content: '', + inbound: new Inbound(), + dbInbound: new DBInbound(), + okText: '', + copyText: '', + qrcode: null, + clipboard: null, + visible: false, + show: function (title='', content='', dbInbound=new DBInbound(),okText='{{ i18n "copy" }}', copyText='') { + this.title = title; + this.content = content; + this.dbInbound = dbInbound; + this.inbound = dbInbound.toInbound(); + this.okText = okText; + if (ObjectUtil.isEmpty(copyText)) { + this.copyText = content; + } else { + this.copyText = copyText; + } + this.visible = true; + qrModalApp.$nextTick(() => { + if (this.clipboard === null) { + this.clipboard = new ClipboardJS('#qr-modal-ok-btn', { + text: () => this.copyText, + }); + this.clipboard.on('success', () => 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 () { + this.visible = false; + }, + }; + + const qrModalApp = new Vue({ + el: '#qrcode-modal', + data: { + qrModal: qrModal, + }, + methods: { + setQrCode(elmentId,index) { + content = qrModal.inbound.genLink(qrModal.dbInbound.address,qrModal.dbInbound.remark,index) + + new QRious({ + element: document.querySelector('#'+elmentId), + size: 260, + value: content, + }); + }, + copyTextToClipboard(elmentId,index) { + link = qrModal.inbound.genLink(qrModal.dbInbound.address,qrModal.dbInbound.remark,index) + this.qrModal.copyText = link + + this.qrModal.clipboard = new ClipboardJS('#' + elmentId, { + text: () => link, + }); + this.qrModal.clipboard.on('success', () => { + app.$message.success('{{ i18n "copied" }}') + this.qrModal.clipboard.destroy(); + }); + + + } + }, + updated() { + switch (qrModal.inbound.protocol) { + case Protocols.VMESS: + vmesses = qrModal.inbound.settings.vmesses + for (const index in vmesses) { + this.setQrCode("qrCode-vmess-" + vmesses[index].id ,index) + } + break; + case Protocols.VLESS: + vlesses = qrModal.inbound.settings.vlesses + + for (const index in vlesses) { + this.setQrCode("qrCode-vless-" + vlesses[index].id ,index) + } + break; + default: return null; + } + + } + }); + +</script> +{{end}}
\ No newline at end of file diff --git a/web/html/common/text_modal.html b/web/html/common/text_modal.html new file mode 100644 index 00000000..0ae04a88 --- /dev/null +++ b/web/html/common/text_modal.html @@ -0,0 +1,58 @@ +{{define "textModal"}} +<a-modal id="text-modal" v-model="txtModal.visible" :title="txtModal.title" + :closable="true" ok-text='{{ i18n "copy" }}' cancel-text='{{ i18n "close" }}' + :ok-button-props="{attrs:{id:'txt-modal-ok-btn'}}"> + <a-button v-if="!ObjectUtil.isEmpty(txtModal.fileName)" type="primary" style="margin-bottom: 10px;" + @click="downloader.download(txtModal.fileName, txtModal.content)"> + {{ i18n "download" }} [[ txtModal.fileName ]] + </a-button> + <a-input type="textarea" v-model="txtModal.content" + :autosize="{ minRows: 10, maxRows: 20}"></a-input> +</a-modal> + +<script> + + const txtModal = { + title: '', + content: '', + fileName: '', + qrcode: null, + clipboard: null, + visible: false, + show: function (title='', content='', fileName='') { + this.title = title; + this.content = content; + this.fileName = fileName; + this.visible = true; + textModalApp.$nextTick(() => { + if (this.clipboard === null) { + this.clipboard = new ClipboardJS('#txt-modal-ok-btn', { + text: () => this.content, + }); + this.clipboard.on('success', () => 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 () { + this.visible = false; + }, + }; + + const textModalApp = new Vue({ + el: '#text-modal', + data: { + txtModal: txtModal, + }, + }); + +</script> +{{end}}
\ No newline at end of file |
