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:
Diffstat (limited to 'web/html/xui')
-rw-r--r--web/html/xui/inbounds.html14
-rw-r--r--web/html/xui/modals/client_bulk_modal.html (renamed from web/html/xui/client_bulk_modal.html)2
-rw-r--r--web/html/xui/modals/client_modal.html (renamed from web/html/xui/client_modal.html)2
-rw-r--r--web/html/xui/modals/dns_modal.html (renamed from web/html/xui/dns_modal.html)2
-rw-r--r--web/html/xui/modals/fakedns_modal.html (renamed from web/html/xui/fakedns_modal.html)2
-rw-r--r--web/html/xui/modals/inbound_info_modal.html (renamed from web/html/xui/inbound_info_modal.html)2
-rw-r--r--web/html/xui/modals/inbound_modal.html (renamed from web/html/xui/inbound_modal.html)2
-rw-r--r--web/html/xui/modals/prompt_modal.html71
-rw-r--r--web/html/xui/modals/qrcode_modal.html161
-rw-r--r--web/html/xui/modals/text_modal.html52
-rw-r--r--web/html/xui/modals/warp_modal.html (renamed from web/html/xui/warp_modal.html)2
-rw-r--r--web/html/xui/modals/xray_balancer_modal.html (renamed from web/html/xui/xray_balancer_modal.html)2
-rw-r--r--web/html/xui/modals/xray_outbound_modal.html (renamed from web/html/xui/xray_outbound_modal.html)2
-rw-r--r--web/html/xui/modals/xray_reverse_modal.html (renamed from web/html/xui/xray_reverse_modal.html)2
-rw-r--r--web/html/xui/modals/xray_rule_modal.html (renamed from web/html/xui/xray_rule_modal.html)2
-rw-r--r--web/html/xui/xray.html14
16 files changed, 309 insertions, 25 deletions
diff --git a/web/html/xui/inbounds.html b/web/html/xui/inbounds.html
index 94333429..fd6ebe8d 100644
--- a/web/html/xui/inbounds.html
+++ b/web/html/xui/inbounds.html
@@ -1524,12 +1524,12 @@
});
</script>
-{{template "inboundModal"}}
-{{template "promptModal"}}
-{{template "qrcodeModal"}}
-{{template "textModal"}}
-{{template "inboundInfoModal"}}
-{{template "clientsModal"}}
-{{template "clientsBulkModal"}}
+{{template "modals/inboundModal"}}
+{{template "modals/promptModal"}}
+{{template "modals/qrcodeModal"}}
+{{template "modals/textModal"}}
+{{template "modals/inboundInfoModal"}}
+{{template "modals/clientsModal"}}
+{{template "modals/clientsBulkModal"}}
</body>
</html>
diff --git a/web/html/xui/client_bulk_modal.html b/web/html/xui/modals/client_bulk_modal.html
index 82e68c74..88e8e645 100644
--- a/web/html/xui/client_bulk_modal.html
+++ b/web/html/xui/modals/client_bulk_modal.html
@@ -1,4 +1,4 @@
-{{define "clientsBulkModal"}}
+{{define "modals/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"
:ok-text="clientsBulkModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
diff --git a/web/html/xui/client_modal.html b/web/html/xui/modals/client_modal.html
index aa62e02a..b6d2a554 100644
--- a/web/html/xui/client_modal.html
+++ b/web/html/xui/modals/client_modal.html
@@ -1,4 +1,4 @@
-{{define "clientsModal"}}
+{{define "modals/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.currentTheme"
diff --git a/web/html/xui/dns_modal.html b/web/html/xui/modals/dns_modal.html
index f61cd8b2..a1ebaa9f 100644
--- a/web/html/xui/dns_modal.html
+++ b/web/html/xui/modals/dns_modal.html
@@ -1,4 +1,4 @@
-{{define "dnsModal"}}
+{{define "modals/dnsModal"}}
<a-modal id="dns-modal" v-model="dnsModal.visible" :title="dnsModal.title" @ok="dnsModal.ok" :closable="true"
:mask-closable="false" :ok-text="dnsModal.okText" cancel-text='{{ i18n "close" }}'
:class="themeSwitcher.currentTheme">
diff --git a/web/html/xui/fakedns_modal.html b/web/html/xui/modals/fakedns_modal.html
index 1b4dbe77..8e554ac0 100644
--- a/web/html/xui/fakedns_modal.html
+++ b/web/html/xui/modals/fakedns_modal.html
@@ -1,4 +1,4 @@
-{{define "fakednsModal"}}
+{{define "modals/fakednsModal"}}
<a-modal id="fakedns-modal" v-model="fakednsModal.visible" :title="fakednsModal.title" @ok="fakednsModal.ok"
:closable="true" :mask-closable="false"
:ok-text="fakednsModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
diff --git a/web/html/xui/inbound_info_modal.html b/web/html/xui/modals/inbound_info_modal.html
index 5ac5e9ab..50a52190 100644
--- a/web/html/xui/inbound_info_modal.html
+++ b/web/html/xui/modals/inbound_info_modal.html
@@ -1,4 +1,4 @@
-{{define "inboundInfoModal"}}
+{{define "modals/inboundInfoModal"}}
<a-modal id="inbound-info-modal" v-model="infoModal.visible" title='{{ i18n "pages.inbounds.details"}}' :closable="true" :mask-closable="true" :footer="null" width="600px" :class="themeSwitcher.currentTheme">
<a-row>
<a-col :xs="24" :md="12">
diff --git a/web/html/xui/inbound_modal.html b/web/html/xui/modals/inbound_modal.html
index 4de3518c..99d182b9 100644
--- a/web/html/xui/inbound_modal.html
+++ b/web/html/xui/modals/inbound_modal.html
@@ -1,4 +1,4 @@
-{{define "inboundModal"}}
+{{define "modals/inboundModal"}}
<a-modal id="inbound-modal" v-model="inModal.visible" :title="inModal.title"
:dialog-style="{ top: '20px' }" @ok="inModal.ok"
:confirm-loading="inModal.confirmLoading" :closable="true" :mask-closable="false"
diff --git a/web/html/xui/modals/prompt_modal.html b/web/html/xui/modals/prompt_modal.html
new file mode 100644
index 00000000..5073650f
--- /dev/null
+++ b/web/html/xui/modals/prompt_modal.html
@@ -0,0 +1,71 @@
+{{define "modals/promptModal"}}
+<a-modal id="prompt-modal" v-model="promptModal.visible" :title="promptModal.title"
+ :closable="true" @ok="promptModal.ok" :mask-closable="false"
+ :confirm-loading="promptModal.confirmLoading"
+ :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}"
+ @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,
+ confirmLoading: 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.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;
+ },
+ loading(loading=true) {
+ this.confirmLoading = loading;
+ },
+ };
+
+ const promptModalApp = new Vue({
+ el: '#prompt-modal',
+ data: {
+ promptModal: promptModal,
+ },
+ });
+
+</script>
+{{end}} \ No newline at end of file
diff --git a/web/html/xui/modals/qrcode_modal.html b/web/html/xui/modals/qrcode_modal.html
new file mode 100644
index 00000000..7046ca9b
--- /dev/null
+++ b/web/html/xui/modals/qrcode_modal.html
@@ -0,0 +1,161 @@
+{{define "modals/qrcodeModal"}}
+<a-modal id="qrcode-modal" v-model="qrModal.visible" :title="qrModal.title"
+ :dialog-style="DeviceUtils.isMobile() ? { top: '18px' } : {}"
+ :closable="true"
+ :class="themeSwitcher.currentTheme"
+ :footer="null" width="fit-content">
+ <tr-qr-modal class="qr-modal">
+ <template v-if="app.subSettings.enable && qrModal.subId">
+ <tr-qr-box class="qr-box">
+ <a-tag color="purple" class="qr-tag"><span>{{ i18n "pages.settings.subSettings"}}</span></a-tag>
+ <tr-qr-bg class="qr-bg-sub">
+ <tr-qr-bg-inner class="qr-bg-sub-inner">
+ <canvas @click="copy(genSubLink(qrModal.client.subId))" id="qrCode-sub" class="qr-cv"></canvas>
+ </tr-qr-bg-inner>
+ </tr-qr-bg>
+ </tr-qr-box>
+ <tr-qr-box class="qr-box">
+ <a-tag color="purple" class="qr-tag"><span>{{ i18n "pages.settings.subSettings"}} Json</span></a-tag>
+ <tr-qr-bg class="qr-bg-sub">
+ <tr-qr-bg-inner class="qr-bg-sub-inner">
+ <canvas @click="copy(genSubJsonLink(qrModal.client.subId))" id="qrCode-subJson" class="qr-cv"></canvas>
+ </tr-qr-bg-inner>
+ </tr-qr-bg>
+ </tr-qr-box>
+ </template>
+ <template v-for="(row, index) in qrModal.qrcodes">
+ <tr-qr-box class="qr-box">
+ <a-tag color="green" class="qr-tag"><span>[[ row.remark ]]</span></a-tag>
+ <tr-qr-bg class="qr-bg">
+ <canvas @click="copy(row.link)" :id="'qrCode-'+index" class="qr-cv"></canvas>
+ </tr-qr-bg>
+ </tr-qr-box>
+ </template>
+ </tr-qr-modal>
+</a-modal>
+
+<script>
+ const qrModal = {
+ title: '',
+ dbInbound: new DBInbound(),
+ client: null,
+ qrcodes: [],
+ visible: false,
+ subId: '',
+ show: function(title = '', dbInbound, client) {
+ this.title = title;
+ this.dbInbound = dbInbound;
+ this.inbound = dbInbound.toInbound();
+ this.client = client;
+ this.subId = '';
+ this.qrcodes = [];
+ if (this.inbound.protocol == Protocols.WIREGUARD) {
+ this.inbound.genInboundLinks(dbInbound.remark).split('\r\n').forEach((l, index) => {
+ this.qrcodes.push({
+ remark: "Peer " + (index + 1),
+ link: l
+ });
+ });
+ } else {
+ this.inbound.genAllLinks(this.dbInbound.remark, app.remarkModel, client).forEach(l => {
+ this.qrcodes.push({
+ remark: l.remark,
+ link: l.link
+ });
+ });
+ }
+ this.visible = true;
+ },
+ close: function() {
+ this.visible = false;
+ },
+ };
+ const qrModalApp = new Vue({
+ delimiters: ['[[', ']]'],
+ el: '#qrcode-modal',
+ data: {
+ qrModal: qrModal,
+ },
+ methods: {
+ copy(content) {
+ ClipboardManager
+ .copyText(content)
+ .then(() => {
+ app.$message.success('{{ i18n "copied" }}')
+ })
+ },
+ setQrCode(elementId, content) {
+ new QRious({
+ element: document.querySelector('#' + elementId),
+ size: 400,
+ value: content,
+ background: 'white',
+ backgroundAlpha: 0,
+ foreground: 'black',
+ padding: 2,
+ level: 'L'
+ });
+ },
+ genSubLink(subID) {
+ return app.subSettings.subURI + subID;
+ },
+ genSubJsonLink(subID) {
+ return app.subSettings.subJsonURI + subID;
+ },
+ revertOverflow() {
+ const elements = document.querySelectorAll(".qr-tag");
+ elements.forEach((element) => {
+ element.classList.remove("tr-marquee");
+ element.children[0].style.animation = '';
+ while (element.children.length > 1) {
+ element.removeChild(element.lastChild);
+ }
+ });
+ }
+ },
+ updated() {
+ if (this.qrModal.visible) {
+ fixOverflow();
+ } else {
+ this.revertOverflow();
+ }
+ if (qrModal.client && qrModal.client.subId) {
+ qrModal.subId = qrModal.client.subId;
+ this.setQrCode("qrCode-sub", this.genSubLink(qrModal.subId));
+ this.setQrCode("qrCode-subJson", this.genSubJsonLink(qrModal.subId));
+ }
+ qrModal.qrcodes.forEach((element, index) => {
+ this.setQrCode("qrCode-" + index, element.link);
+ });
+ }
+ });
+
+ function fixOverflow() {
+ const elements = document.querySelectorAll(".qr-tag");
+ elements.forEach((element) => {
+ function isElementOverflowing(element) {
+ const overflowX = element.offsetWidth < element.scrollWidth,
+ overflowY = element.offsetHeight < element.scrollHeight;
+ return overflowX || overflowY;
+ }
+
+ function wrapContentsInMarquee(element) {
+ element.classList.add("tr-marquee");
+ element.children[0].style.animation = `move-ltr ${
+ (element.children[0].clientWidth / element.clientWidth) * 5
+ }s ease-in-out infinite`;
+ const marqueeText = element.children[0];
+ if (element.children.length < 2) {
+ for (let i = 0; i < 1; i++) {
+ const marqueeText = element.children[0].cloneNode(true);
+ element.children[0].after(marqueeText);
+ }
+ }
+ }
+ if (isElementOverflowing(element)) {
+ wrapContentsInMarquee(element);
+ }
+ });
+ }
+</script>
+{{end}}
diff --git a/web/html/xui/modals/text_modal.html b/web/html/xui/modals/text_modal.html
new file mode 100644
index 00000000..77cb719e
--- /dev/null
+++ b/web/html/xui/modals/text_modal.html
@@ -0,0 +1,52 @@
+{{define "modals/textModal"}}
+<a-modal id="text-modal" v-model="txtModal.visible" :title="txtModal.title"
+ :closable="true"
+ :class="themeSwitcher.currentTheme">
+ <template slot="footer">
+ <a-button v-if="!ObjectUtil.isEmpty(txtModal.fileName)" icon="download"
+ :href="'data:application/text;charset=utf-8,' + encodeURIComponent(txtModal.content)"
+ :download="txtModal.fileName">[[ txtModal.fileName ]]
+ </a-button>
+ <a-button type="primary" @click="txtModal.copy(txtModal.content)">{{ i18n "copy" }}</a-button>
+ </template>
+ <a-input style="overflow-y: auto;" type="textarea" v-model="txtModal.content"
+ :autosize="{ minRows: 10, maxRows: 20}"></a-input>
+</a-modal>
+
+<script>
+
+ const txtModal = {
+ title: '',
+ content: '',
+ fileName: '',
+ qrcode: null,
+ visible: false,
+ show: function (title = '', content = '', fileName = '') {
+ this.title = title;
+ this.content = content;
+ this.fileName = fileName;
+ this.visible = true;
+ },
+ copy: function (content = '') {
+ ClipboardManager
+ .copyText(content)
+ .then(() => {
+ app.$message.success('{{ i18n "copied" }}')
+ this.close();
+ })
+ },
+ close: function () {
+ this.visible = false;
+ },
+ };
+
+ const textModalApp = new Vue({
+ delimiters: ['[[', ']]'],
+ el: '#text-modal',
+ data: {
+ txtModal: txtModal,
+ },
+ });
+
+</script>
+{{end}}
diff --git a/web/html/xui/warp_modal.html b/web/html/xui/modals/warp_modal.html
index 20ce8139..7fb55847 100644
--- a/web/html/xui/warp_modal.html
+++ b/web/html/xui/modals/warp_modal.html
@@ -1,4 +1,4 @@
-{{define "warpModal"}}
+{{define "modals/warpModal"}}
<a-modal id="warp-modal" v-model="warpModal.visible" title="Cloudflare WARP"
:confirm-loading="warpModal.confirmLoading" :closable="true" :mask-closable="true"
:footer="null" :class="themeSwitcher.currentTheme">
diff --git a/web/html/xui/xray_balancer_modal.html b/web/html/xui/modals/xray_balancer_modal.html
index de2a0acb..fea4019a 100644
--- a/web/html/xui/xray_balancer_modal.html
+++ b/web/html/xui/modals/xray_balancer_modal.html
@@ -1,4 +1,4 @@
-{{define "balancerModal"}}
+{{define "modals/balancerModal"}}
<a-modal
id="balancer-modal"
v-model="balancerModal.visible"
diff --git a/web/html/xui/xray_outbound_modal.html b/web/html/xui/modals/xray_outbound_modal.html
index fd9cf99c..b3c5d6b1 100644
--- a/web/html/xui/xray_outbound_modal.html
+++ b/web/html/xui/modals/xray_outbound_modal.html
@@ -1,4 +1,4 @@
-{{define "outModal"}}
+{{define "modals/outModal"}}
<a-modal id="out-modal" v-model="outModal.visible" :title="outModal.title" @ok="outModal.ok"
:confirm-loading="outModal.confirmLoading" :closable="true" :mask-closable="false"
:ok-button-props="{ props: { disabled: !outModal.isValid } }" style="overflow: hidden;"
diff --git a/web/html/xui/xray_reverse_modal.html b/web/html/xui/modals/xray_reverse_modal.html
index bb1e4bdf..22f04317 100644
--- a/web/html/xui/xray_reverse_modal.html
+++ b/web/html/xui/modals/xray_reverse_modal.html
@@ -1,4 +1,4 @@
-{{define "reverseModal"}}
+{{define "modals/reverseModal"}}
<a-modal id="reverse-modal" v-model="reverseModal.visible" :title="reverseModal.title" @ok="reverseModal.ok"
:confirm-loading="reverseModal.confirmLoading" :closable="true" :mask-closable="false"
:ok-text="reverseModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
diff --git a/web/html/xui/xray_rule_modal.html b/web/html/xui/modals/xray_rule_modal.html
index aba5ba9e..4be74a8f 100644
--- a/web/html/xui/xray_rule_modal.html
+++ b/web/html/xui/modals/xray_rule_modal.html
@@ -1,4 +1,4 @@
-{{define "ruleModal"}}
+{{define "modals/ruleModal"}}
<a-modal id="rule-modal" v-model="ruleModal.visible" :title="ruleModal.title" @ok="ruleModal.ok" :confirm-loading="ruleModal.confirmLoading" :closable="true" :mask-closable="false" :ok-text="ruleModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
<a-form-item label='Domain Matcher'>
diff --git a/web/html/xui/xray.html b/web/html/xui/xray.html
index 07737509..8eb8239a 100644
--- a/web/html/xui/xray.html
+++ b/web/html/xui/xray.html
@@ -133,13 +133,13 @@
{{template "component/aThemeSwitch" .}}
{{template "component/aTableSortable" .}}
{{template "component/aSettingListItem" .}}
-{{template "ruleModal"}}
-{{template "outModal"}}
-{{template "reverseModal"}}
-{{template "balancerModal"}}
-{{template "dnsModal"}}
-{{template "fakednsModal"}}
-{{template "warpModal"}}
+{{template "modals/ruleModal"}}
+{{template "modals/outModal"}}
+{{template "modals/reverseModal"}}
+{{template "modals/balancerModal"}}
+{{template "modals/dnsModal"}}
+{{template "modals/fakednsModal"}}
+{{template "modals/warpModal"}}
<script>
const rulesColumns = [
{ title: "#", align: 'center', width: 15, scopedSlots: { customRender: 'action' } },