qrcode_modal.html 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. {{define "qrcodeModal"}}
  2. <a-modal id="qrcode-modal" v-model="qrModal.visible" :title="qrModal.title"
  3. :dialog-style="isMobileQr ? { top: '18px' } : {}"
  4. :closable="true"
  5. :class="themeSwitcher.currentTheme"
  6. :footer="null" width="fit-content">
  7. <tr-qr-modal class="qr-modal">
  8. <template v-if="app.subSettings.enable && qrModal.subId">
  9. <tr-qr-box class="qr-box">
  10. <a-tag color="purple" class="qr-tag"><span>{{ i18n "pages.settings.subSettings"}}</span></a-tag>
  11. <tr-qr-bg class="qr-bg-sub">
  12. <tr-qr-bg-inner class="qr-bg-sub-inner">
  13. <canvas @click="copyToClipboard('qrCode-sub',genSubLink(qrModal.client.subId))" id="qrCode-sub" class="qr-cv"></canvas>
  14. </tr-qr-bg-inner>
  15. </tr-qr-bg>
  16. </tr-qr-box>
  17. <tr-qr-box class="qr-box">
  18. <a-tag color="purple" class="qr-tag"><span>{{ i18n "pages.settings.subSettings"}} Json</span></a-tag>
  19. <tr-qr-bg class="qr-bg-sub">
  20. <tr-qr-bg-inner class="qr-bg-sub-inner">
  21. <canvas @click="copyToClipboard('qrCode-subJson',genSubJsonLink(qrModal.client.subId))" id="qrCode-subJson" class="qr-cv"></canvas>
  22. </tr-qr-bg-inner>
  23. </tr-qr-bg>
  24. </tr-qr-box>
  25. </template>
  26. <template v-if="!isJustSub">
  27. <template v-for="(row, index) in qrModal.qrcodes">
  28. <tr-qr-box class="qr-box">
  29. <a-tag color="green" class="qr-tag"><span>[[ row.remark ]]</span></a-tag>
  30. <tr-qr-bg class="qr-bg">
  31. <canvas @click="copyToClipboard('qrCode-'+index, row.link)" :id="'qrCode-'+index" class="qr-cv"></canvas>
  32. </tr-qr-bg>
  33. </tr-qr-box>
  34. </template>
  35. </template>
  36. </tr-qr-modal>
  37. </a-modal>
  38. <script>
  39. const isMobileQr = window.innerWidth <= 768;
  40. const qrModal = {
  41. title: '',
  42. dbInbound: new DBInbound(),
  43. client: null,
  44. qrcodes: [],
  45. clipboard: null,
  46. visible: false,
  47. isJustSub: false,
  48. subId: '',
  49. show: function(title = '', dbInbound, client, isJustSub = false) {
  50. this.title = title;
  51. this.dbInbound = dbInbound;
  52. this.inbound = dbInbound.toInbound();
  53. this.client = client;
  54. this.isJustSub = isJustSub;
  55. this.subId = '';
  56. this.qrcodes = [];
  57. if (this.inbound.protocol == Protocols.WIREGUARD) {
  58. this.inbound.genInboundLinks(dbInbound.remark).split('\r\n').forEach((l, index) => {
  59. this.qrcodes.push({
  60. remark: "Peer " + (index + 1),
  61. link: l
  62. });
  63. });
  64. } else {
  65. this.inbound.genAllLinks(this.dbInbound.remark, app.remarkModel, client).forEach(l => {
  66. this.qrcodes.push({
  67. remark: l.remark,
  68. link: l.link
  69. });
  70. });
  71. }
  72. this.visible = true;
  73. },
  74. close: function() {
  75. this.visible = false;
  76. },
  77. };
  78. const qrModalApp = new Vue({
  79. delimiters: ['[[', ']]'],
  80. el: '#qrcode-modal',
  81. data: {
  82. qrModal: qrModal,get isJustSub(){
  83. return qrModal.isJustSub
  84. }
  85. },
  86. methods: {
  87. copyToClipboard(elementId, content) {
  88. this.qrModal.clipboard = new ClipboardJS('#' + elementId, {
  89. text: () => content,
  90. });
  91. this.qrModal.clipboard.on('success', () => {
  92. app.$message.success('{{ i18n "copied" }}')
  93. this.qrModal.clipboard.destroy();
  94. });
  95. },
  96. setQrCode(elementId, content) {
  97. new QRious({
  98. element: document.querySelector('#' + elementId),
  99. size: 400,
  100. value: content,
  101. background: 'white',
  102. backgroundAlpha: 0,
  103. foreground: 'black',
  104. padding: 2,
  105. level: 'L'
  106. });
  107. },
  108. genSubLink(subID) {
  109. return app.subSettings.subURI + subID;
  110. },
  111. genSubJsonLink(subID) {
  112. return app.subSettings.subJsonURI + subID;
  113. },
  114. revertOverflow() {
  115. const elements = document.querySelectorAll(".qr-tag");
  116. elements.forEach((element) => {
  117. element.classList.remove("tr-marquee");
  118. element.children[0].style.animation = '';
  119. while (element.children.length > 1) {
  120. element.removeChild(element.lastChild);
  121. }
  122. });
  123. }
  124. },
  125. updated() {
  126. if (this.qrModal.visible) {
  127. fixOverflow();
  128. } else {
  129. this.revertOverflow();
  130. }
  131. if (qrModal.client && qrModal.client.subId) {
  132. qrModal.subId = qrModal.client.subId;
  133. this.setQrCode("qrCode-sub", this.genSubLink(qrModal.subId));
  134. this.setQrCode("qrCode-subJson", this.genSubJsonLink(qrModal.subId));
  135. }
  136. qrModal.qrcodes.forEach((element, index) => {
  137. this.setQrCode("qrCode-" + index, element.link);
  138. });
  139. }
  140. });
  141. function fixOverflow() {
  142. const elements = document.querySelectorAll(".qr-tag");
  143. elements.forEach((element) => {
  144. function isElementOverflowing(element) {
  145. const overflowX = element.offsetWidth < element.scrollWidth,
  146. overflowY = element.offsetHeight < element.scrollHeight;
  147. return overflowX || overflowY;
  148. }
  149. function wrapContentsInMarquee(element) {
  150. element.classList.add("tr-marquee");
  151. element.children[0].style.animation = `move-ltr ${
  152. (element.children[0].clientWidth / element.clientWidth) * 5
  153. }s ease-in-out infinite`;
  154. const marqueeText = element.children[0];
  155. if (element.children.length < 2) {
  156. for (let i = 0; i < 1; i++) {
  157. const marqueeText = element.children[0].cloneNode(true);
  158. element.children[0].after(marqueeText);
  159. }
  160. }
  161. }
  162. if (isElementOverflowing(element)) {
  163. wrapContentsInMarquee(element);
  164. }
  165. });
  166. }
  167. </script>
  168. {{end}}