diff options
| author | AKILA INDUNIL <45641122+akilaid@users.noreply.github.com> | 2025-04-19 18:32:22 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-19 18:32:22 +0300 |
| commit | 96fd7d0e7cb7520661a9a0b672fbdcc8fa6f7872 (patch) | |
| tree | b49adfd7d294e4e13f7699474b49861564f62ca4 /web | |
| parent | cf02f02210b6501b8533a3cbbf96ed2077f71db5 (diff) | |
feat: add a toggle to use public IPv4 in QR/URI
Diffstat (limited to 'web')
| -rw-r--r-- | web/html/modals/qrcode_modal.html | 159 | ||||
| -rw-r--r-- | web/translation/translate.ar_EG.toml | 1 | ||||
| -rw-r--r-- | web/translation/translate.en_US.toml | 1 | ||||
| -rw-r--r-- | web/translation/translate.es_ES.toml | 1 | ||||
| -rw-r--r-- | web/translation/translate.fa_IR.toml | 1 | ||||
| -rw-r--r-- | web/translation/translate.id_ID.toml | 1 | ||||
| -rw-r--r-- | web/translation/translate.ja_JP.toml | 1 | ||||
| -rw-r--r-- | web/translation/translate.pt_BR.toml | 1 | ||||
| -rw-r--r-- | web/translation/translate.ru_RU.toml | 1 | ||||
| -rw-r--r-- | web/translation/translate.tr_TR.toml | 1 | ||||
| -rw-r--r-- | web/translation/translate.uk_UA.toml | 1 | ||||
| -rw-r--r-- | web/translation/translate.vi_VN.toml | 1 | ||||
| -rw-r--r-- | web/translation/translate.zh_CN.toml | 1 | ||||
| -rw-r--r-- | web/translation/translate.zh_TW.toml | 1 |
14 files changed, 161 insertions, 11 deletions
diff --git a/web/html/modals/qrcode_modal.html b/web/html/modals/qrcode_modal.html index 92d30e93..e5b27841 100644 --- a/web/html/modals/qrcode_modal.html +++ b/web/html/modals/qrcode_modal.html @@ -1,10 +1,9 @@ {{define "modals/qrcodeModal"}} <a-modal id="qrcode-modal" v-model="qrModal.visible" :title="qrModal.title" - :dialog-style="isMobile ? { top: '18px' } : {}" - :closable="true" - :class="themeSwitcher.currentTheme" - :footer="null" width="fit-content"> + :dialog-style="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> @@ -25,6 +24,18 @@ </template> <template v-for="(row, index) in qrModal.qrcodes"> <tr-qr-box class="qr-box"> + <div :style="{ display: 'flex', alignItems: 'center', marginBottom: '8px' }"> + <span>{{ i18n "useIPv4ForHost" }}: </span> + <button + type="button" + role="switch" + :aria-checked="row.useIPv4" + :class="['ant-switch', 'ant-switch-small', { 'ant-switch-checked': row.useIPv4 }]" + @click="toggleIPv4(index)" + :style="{ marginLeft: '8px' }"> + <span class="ant-switch-inner"></span> + </button> + </div> <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> @@ -34,6 +45,53 @@ </tr-qr-modal> </a-modal> +<style> + .ant-table:not(.ant-table-expanded-row .ant-table) { + outline: 1px solid #f0f0f0; + outline-offset: -1px; + border-radius: 1rem; + overflow-x: hidden; + } + + /* QR code transition effects */ + .qr-cv { + transition: all 0.3s ease-in-out; + } + + .qr-transition-enter-active, .qr-transition-leave-active { + transition: opacity 0.3s, transform 0.3s; + } + + .qr-transition-enter, .qr-transition-leave-to { + opacity: 0; + transform: scale(0.9); + } + + .qr-transition-enter-to, .qr-transition-leave { + opacity: 1; + transform: scale(1); + } + + .qr-flash { + animation: qr-flash-animation 0.6s; + } + + @keyframes qr-flash-animation { + 0% { + opacity: 1; + transform: scale(1); + } + 50% { + opacity: 0.5; + transform: scale(0.95); + } + 100% { + opacity: 1; + transform: scale(1); + } + } +</style> + <script> const qrModal = { title: '', @@ -42,31 +100,37 @@ qrcodes: [], visible: false, subId: '', - show: function(title = '', dbInbound, client) { + show: function (title = '', dbInbound, client) { this.title = title; this.dbInbound = dbInbound; this.inbound = dbInbound.toInbound(); this.client = client; this.subId = ''; this.qrcodes = []; + // Reset the status fetched flag when showing the modal + if (qrModalApp) qrModalApp.statusFetched = false; 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 + link: l, + useIPv4: false, + originalLink: l }); }); } else { this.inbound.genAllLinks(this.dbInbound.remark, app.remarkModel, client).forEach(l => { this.qrcodes.push({ remark: l.remark, - link: l.link + link: l.link, + useIPv4: false, + originalLink: l.link }); }); } this.visible = true; }, - close: function() { + close: function () { this.visible = false; }, }; @@ -76,8 +140,72 @@ mixins: [MediaQueryMixin], data: { qrModal: qrModal, + serverStatus: null, + statusFetched: false, }, methods: { + async getStatus() { + try { + const msg = await HttpUtil.post('/server/status'); + if (msg.success) { + this.serverStatus = msg.obj; + } + } catch (e) { + console.error("Failed to get status:", e); + } + }, + + toggleIPv4(index) { + const row = qrModal.qrcodes[index]; + row.useIPv4 = !row.useIPv4; + this.updateLink(index); + }, + updateLink(index) { + const row = qrModal.qrcodes[index]; + if (!this.serverStatus || !this.serverStatus.publicIP) { + return; + } + + if (row.useIPv4 && this.serverStatus.publicIP.ipv4) { + // Replace the hostname or IP in the link with the IPv4 address + const originalLink = row.originalLink; + const url = new URL(originalLink); + const ipv4 = this.serverStatus.publicIP.ipv4; + + if (qrModal.inbound.protocol == Protocols.WIREGUARD) { + // Special handling for WireGuard config + const endpointRegex = /Endpoint = ([^:]+):(\d+)/; + const match = originalLink.match(endpointRegex); + if (match) { + row.link = originalLink.replace( + `Endpoint = ${match[1]}:${match[2]}`, + `Endpoint = ${ipv4}:${match[2]}` + ); + } + } else { + // For other protocols using URL format + url.hostname = ipv4; + row.link = url.toString(); + } + } else { + // Restore original link + row.link = row.originalLink; + } + + // Update QR code with transition effect + const canvasElement = document.querySelector('#qrCode-' + index); + if (canvasElement) { + // Add flash animation class + canvasElement.classList.add('qr-flash'); + + // Remove the class after animation completes + setTimeout(() => { + canvasElement.classList.remove('qr-flash'); + }, 600); + } + + this.setQrCode("qrCode-" + index, row.link); + }, copy(content) { ClipboardManager .copyText(content) @@ -117,8 +245,14 @@ updated() { if (this.qrModal.visible) { fixOverflow(); + if (!this.statusFetched) { + this.getStatus(); + this.statusFetched = true; + } } else { this.revertOverflow(); + // Reset the flag when modal is closed so it will fetch again next time + this.statusFetched = false; } if (qrModal.client && qrModal.client.subId) { qrModal.subId = qrModal.client.subId; @@ -127,6 +261,10 @@ } qrModal.qrcodes.forEach((element, index) => { this.setQrCode("qrCode-" + index, element.link); + // Update links based on current toggle state + if (element.useIPv4 && this.serverStatus && this.serverStatus.publicIP) { + this.updateLink(index); + } }); } }); @@ -142,8 +280,7 @@ function wrapContentsInMarquee(element) { element.classList.add("tr-marquee"); - element.children[0].style.animation = `move-ltr ${ - (element.children[0].clientWidth / element.clientWidth) * 5 + 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) { @@ -159,4 +296,4 @@ }); } </script> -{{end}} +{{end}}
\ No newline at end of file diff --git a/web/translation/translate.ar_EG.toml b/web/translation/translate.ar_EG.toml index 8a50d648..229f1320 100644 --- a/web/translation/translate.ar_EG.toml +++ b/web/translation/translate.ar_EG.toml @@ -29,6 +29,7 @@ "copySuccess" = "اتنسخ بنجاح" "sure" = "متأكد؟" "encryption" = "تشفير" +"useIPv4ForHost" = "استخدم IPv4 للمضيف" "transmission" = "نقل" "host" = "المستضيف" "path" = "مسار" diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml index af06fb61..c691cbdd 100644 --- a/web/translation/translate.en_US.toml +++ b/web/translation/translate.en_US.toml @@ -29,6 +29,7 @@ "copySuccess" = "Copied Successful" "sure" = "Sure" "encryption" = "Encryption" +"useIPv4ForHost" = "Use IPv4 for host" "transmission" = "Transmission" "host" = "Host" "path" = "Path" diff --git a/web/translation/translate.es_ES.toml b/web/translation/translate.es_ES.toml index 1820565e..d989b3e9 100644 --- a/web/translation/translate.es_ES.toml +++ b/web/translation/translate.es_ES.toml @@ -29,6 +29,7 @@ "copySuccess" = "Copiado exitosamente"
"sure" = "Seguro"
"encryption" = "Encriptación"
+"useIPv4ForHost" = "Usar IPv4 para el host"
"transmission" = "Transmisión"
"host" = "Anfitrión"
"path" = "Ruta"
diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml index f6821b7a..96a39ca9 100644 --- a/web/translation/translate.fa_IR.toml +++ b/web/translation/translate.fa_IR.toml @@ -29,6 +29,7 @@ "copySuccess" = "باموفقیت کپیشد" "sure" = "مطمئن" "encryption" = "رمزگذاری" +"useIPv4ForHost" = "از IPv4 برای میزبان استفاده کنید" "transmission" = "راهاتصال" "host" = "آدرس" "path" = "مسیر" diff --git a/web/translation/translate.id_ID.toml b/web/translation/translate.id_ID.toml index 265770a7..f2277a27 100644 --- a/web/translation/translate.id_ID.toml +++ b/web/translation/translate.id_ID.toml @@ -29,6 +29,7 @@ "copySuccess" = "Berhasil Disalin" "sure" = "Yakin" "encryption" = "Enkripsi" +"useIPv4ForHost" = "Gunakan IPv4 untuk host" "transmission" = "Transmisi" "host" = "Host" "path" = "Jalur" diff --git a/web/translation/translate.ja_JP.toml b/web/translation/translate.ja_JP.toml index 7946a56e..2c8df756 100644 --- a/web/translation/translate.ja_JP.toml +++ b/web/translation/translate.ja_JP.toml @@ -29,6 +29,7 @@ "copySuccess" = "コピー成功" "sure" = "確定" "encryption" = "暗号化" +"useIPv4ForHost" = "ホストにIPv4を使用" "transmission" = "伝送" "host" = "ホスト" "path" = "パス" diff --git a/web/translation/translate.pt_BR.toml b/web/translation/translate.pt_BR.toml index 793d6799..87a44ca6 100644 --- a/web/translation/translate.pt_BR.toml +++ b/web/translation/translate.pt_BR.toml @@ -29,6 +29,7 @@ "copySuccess" = "Copiado com Sucesso" "sure" = "Certo" "encryption" = "Criptografia" +"useIPv4ForHost" = "Usar IPv4 para o host" "transmission" = "Transmissão" "host" = "Servidor" "path" = "Caminho" diff --git a/web/translation/translate.ru_RU.toml b/web/translation/translate.ru_RU.toml index b4b00366..47891227 100644 --- a/web/translation/translate.ru_RU.toml +++ b/web/translation/translate.ru_RU.toml @@ -29,6 +29,7 @@ "copySuccess" = "Скопировано" "sure" = "Да" "encryption" = "Шифрование" +"useIPv4ForHost" = "Использовать IPv4 для хоста" "transmission" = "Протокол" "host" = "Хост" "path" = "Путь" diff --git a/web/translation/translate.tr_TR.toml b/web/translation/translate.tr_TR.toml index 0dc4d05b..2b617ca5 100644 --- a/web/translation/translate.tr_TR.toml +++ b/web/translation/translate.tr_TR.toml @@ -29,6 +29,7 @@ "copySuccess" = "Başarıyla Kopyalandı" "sure" = "Emin misiniz" "encryption" = "Şifreleme" +"useIPv4ForHost" = "Ana bilgisayar için IPv4 kullan" "transmission" = "İletim" "host" = "Sunucu" "path" = "Yol" diff --git a/web/translation/translate.uk_UA.toml b/web/translation/translate.uk_UA.toml index 0b2efce4..ad3aea41 100644 --- a/web/translation/translate.uk_UA.toml +++ b/web/translation/translate.uk_UA.toml @@ -29,6 +29,7 @@ "copySuccess" = "Скопійовано успішно" "sure" = "Звичайно" "encryption" = "Шифрування" +"useIPv4ForHost" = "Використовувати IPv4 для хоста" "transmission" = "Протокол передачи" "host" = "Хост" "path" = "Шлях" diff --git a/web/translation/translate.vi_VN.toml b/web/translation/translate.vi_VN.toml index f5abc92b..3a825770 100644 --- a/web/translation/translate.vi_VN.toml +++ b/web/translation/translate.vi_VN.toml @@ -29,6 +29,7 @@ "copySuccess" = "Đã sao chép thành công"
"sure" = "Chắc chắn"
"encryption" = "Mã hóa"
+"useIPv4ForHost" = "Sử dụng IPv4 cho máy chủ"
"transmission" = "Truyền tải"
"host" = "Máy chủ"
"path" = "Đường dẫn"
diff --git a/web/translation/translate.zh_CN.toml b/web/translation/translate.zh_CN.toml index eae8a560..750db7e6 100644 --- a/web/translation/translate.zh_CN.toml +++ b/web/translation/translate.zh_CN.toml @@ -29,6 +29,7 @@ "copySuccess" = "复制成功" "sure" = "确定" "encryption" = "加密" +"useIPv4ForHost" = "使用 IPv4 连接主机" "transmission" = "传输" "host" = "主机" "path" = "路径" diff --git a/web/translation/translate.zh_TW.toml b/web/translation/translate.zh_TW.toml index f2c80d42..abc953f5 100644 --- a/web/translation/translate.zh_TW.toml +++ b/web/translation/translate.zh_TW.toml @@ -29,6 +29,7 @@ "copySuccess" = "複製成功" "sure" = "確定" "encryption" = "加密" +"useIPv4ForHost" = "使用 IPv4 連接主機" "transmission" = "傳輸" "host" = "主機" "path" = "路徑" |
