diff options
| author | Tara Rostami <132676256+TaraRostami@users.noreply.github.com> | 2024-04-20 21:45:36 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-20 21:45:36 +0300 |
| commit | db24d216210e0038f92e634de1ab8a46fbce4632 (patch) | |
| tree | 3648326a1e359543febd865747822bc6f8f72781 /web/html/common | |
| parent | 3d5c06bf08f0ede7206e0ef39966d6be2106a225 (diff) | |
UI Improvements (#2228)
* 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
Diffstat (limited to 'web/html/common')
| -rw-r--r-- | web/html/common/head.html | 54 | ||||
| -rw-r--r-- | web/html/common/qrcode_modal.html | 249 |
2 files changed, 179 insertions, 124 deletions
diff --git a/web/html/common/head.html b/web/html/common/head.html index b2533098..6c195db5 100644 --- a/web/html/common/head.html +++ b/web/html/common/head.html @@ -1,32 +1,32 @@ {{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.8/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; - } - /* vazirmatn-regular - arabic_latin_latin-ext */ - @font-face { - font-display: swap; - font-family: 'Vazirmatn'; - font-style: normal; - font-weight: 400; - src: url('{{ .base_path }}assets/Vazirmatn-UI-NL-Regular.woff2') format('woff2'); - unicode-range: U+0600-06FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE80-FEFC, U+0030-0039; - } - body { - font-family: -apple-system, BlinkMacSystemFont, 'Vazirmatn', 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', - 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif, 'Apple Color Emoji', - 'Segoe UI Emoji', 'Segoe UI Symbol'; - } - </style> - <title>{{ .host }}-{{ i18n .title}}</title> + <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.8/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.min.css?{{ .cur_ver }}"> + <style> + [v-cloak] { + display: none; + } + /* vazirmatn-regular - arabic_latin_latin-ext */ + @font-face { + font-display: swap; + font-family: 'Vazirmatn'; + font-style: normal; + font-weight: 400; + src: url('{{ .base_path }}assets/Vazirmatn-UI-NL-Regular.woff2') format('woff2'); + unicode-range: U+0600-06FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE80-FEFC, U+0030-0039; + } + body { + font-family: -apple-system, BlinkMacSystemFont, 'Vazirmatn', 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', + 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif, 'Apple Color Emoji', + 'Segoe UI Emoji', 'Segoe UI Symbol'; + } + </style> + <title>{{ .host }}-{{ i18n .title}}</title> </head> <div id="message"></div> {{end}}
\ No newline at end of file diff --git a/web/html/common/qrcode_modal.html b/web/html/common/qrcode_modal.html index 524335cf..fd5a17b7 100644 --- a/web/html/common/qrcode_modal.html +++ b/web/html/common/qrcode_modal.html @@ -1,110 +1,165 @@ {{define "qrcodeModal"}} <a-modal id="qrcode-modal" v-model="qrModal.visible" :title="qrModal.title" - :dialog-style="{ top: '20px' }" + :dialog-style="isMobileQr ? { top: '18px' } : {}" :closable="true" :class="themeSwitcher.currentTheme" - :footer="null" width="300px"> - <a-tag color="green" style="margin-bottom: 10px;display: block;text-align: center;"> - {{ i18n "pages.inbounds.clickOnQRcode" }} - </a-tag> - <template v-if="app.subSettings.enable && qrModal.subId"> - <a-divider>{{ i18n "pages.settings.subSettings"}}</a-divider> - <div class="qr-bg"><canvas @click="copyToClipboard('qrCode-sub',genSubLink(qrModal.client.subId))" id="qrCode-sub" class="qr-cv"></canvas></div> - <a-divider>{{ i18n "pages.settings.subSettings"}} Json</a-divider> - <div class="qr-bg"><canvas @click="copyToClipboard('qrCode-subJson',genSubJsonLink(qrModal.client.subId))" id="qrCode-subJson" class="qr-cv"></canvas></div> - </template> - <a-divider>{{ i18n "pages.inbounds.client" }}</a-divider> - <template v-for="(row, index) in qrModal.qrcodes"> - <a-tag color="green" style="margin: 10px 0; display: block; text-align: center;">[[ row.remark ]]</a-tag> - <div class="qr-bg"><canvas @click="copyToClipboard('qrCode-'+index, row.link)" :id="'qrCode-'+index" class="qr-cv"></canvas></div> - </template> + :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); + }); + } + }); - 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; - }, - }; + 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; + } - 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; - } - }, - updated() { - 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 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}} |
