mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-03-01 01:20:49 +03:00

* UI Improvements Better Table Update QR Code Modal Better Info Modal Compression HTML files Better Dropdown Menu Better Calendar and more .. Remove files Minor Fixes
166 lines
5.4 KiB
HTML
166 lines
5.4 KiB
HTML
{{define "qrcodeModal"}}
|
|
<a-modal id="qrcode-modal" v-model="qrModal.visible" :title="qrModal.title"
|
|
:dialog-style="isMobileQr ? { 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="copyToClipboard('qrCode-sub',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="copyToClipboard('qrCode-subJson',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="copyToClipboard('qrCode-'+index, row.link)" :id="'qrCode-'+index" class="qr-cv"></canvas>
|
|
</tr-qr-bg>
|
|
</tr-qr-box>
|
|
</template>
|
|
</tr-qr-modal>
|
|
</a-modal>
|
|
|
|
<script>
|
|
const isMobileQr = window.innerWidth <= 768;
|
|
const qrModal = {
|
|
title: '',
|
|
dbInbound: new DBInbound(),
|
|
client: null,
|
|
qrcodes: [],
|
|
clipboard: null,
|
|
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: {
|
|
copyToClipboard(elmentId, content) {
|
|
this.qrModal.clipboard = new ClipboardJS('#' + elmentId, {
|
|
text: () => content,
|
|
});
|
|
this.qrModal.clipboard.on('success', () => {
|
|
app.$message.success('{{ i18n "copied" }}')
|
|
this.qrModal.clipboard.destroy();
|
|
});
|
|
},
|
|
setQrCode(elmentId, content) {
|
|
new QRious({
|
|
element: document.querySelector('#' + elmentId),
|
|
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}}
|