server_list.htm 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <%#
  2. Copyright 2018-2019 Lienol <[email protected]>
  3. Licensed to the public under the Apache License 2.0.
  4. -%>
  5. <%
  6. local dsp = require "luci.dispatcher"
  7. -%>
  8. <script type="text/javascript">
  9. //<![CDATA[
  10. const doms = document.getElementsByClassName('pingtime');
  11. const ports = document.getElementsByClassName("socket-connected")
  12. const xhr = (index) => {
  13. return new Promise((res) => {
  14. const dom = doms[index];
  15. const port = ports[index];
  16. if (!dom) res()
  17. port.innerHTML = '<font color="#0072c3">connect</font>';
  18. XHR.get('<%=dsp.build_url("admin/services/shadowsocksr/ping")%>', {
  19. index,
  20. domain: dom.getAttribute("hint"),
  21. port: port.getAttribute("hint")
  22. },
  23. (x, result) => {
  24. let col = '#ff0000';
  25. if (result.ping) {
  26. if (result.ping < 300) col = '#ff3300';
  27. if (result.ping < 200) col = '#ff7700';
  28. if (result.ping < 100) col = '#249400';
  29. }
  30. dom.innerHTML = `<font color="${col}">${(result.ping ? result.ping : "--") + " ms"}</font>`
  31. if (result.socket) {
  32. port.innerHTML = '<font color="#249400">ok</font>';
  33. } else {
  34. port.innerHTML = '<font color="#ff0000">fail</font>';
  35. }
  36. res();
  37. });
  38. })
  39. }
  40. let task = -1;
  41. const thread = () => {
  42. task = task + 1
  43. if (doms[task]) {
  44. xhr(task).then(thread);
  45. }
  46. }
  47. for (let i = 0; i < 20; i++) {
  48. thread()
  49. }
  50. function cbi_row_drop(fromId, toId, store, isToBottom) {
  51. var fromNode = document.getElementById(fromId);
  52. var toNode = document.getElementById(toId);
  53. if (!fromNode || !toNode) return false;
  54. var table = fromNode.parentNode;
  55. while (table && table.nodeName.toLowerCase() != "table")
  56. table = table.parentNode;
  57. if (!table) return false;
  58. var ids = [];
  59. if (isToBottom) {
  60. toNode.parentNode.appendChild(fromNode);
  61. } else {
  62. fromNode.parentNode.insertBefore(fromNode, toNode);
  63. }
  64. for (var idx = 2; idx < table.rows.length; idx++) {
  65. table.rows[idx].className = table.rows[idx].className.replace(
  66. /cbi-rowstyle-[12]/,
  67. "cbi-rowstyle-" + (1 + (idx % 2))
  68. );
  69. if (table.rows[idx].id && table.rows[idx].id.match(/-([^\-]+)$/))
  70. ids.push(RegExp.$1);
  71. }
  72. var input = document.getElementById(store);
  73. if (input) input.value = ids.join(" ");
  74. return false;
  75. }
  76. // set tr draggable
  77. function enableDragForTable(table_selecter, store) {
  78. var trs = document.querySelectorAll(table_selecter + " tr");
  79. if (!trs || trs.length.length < 3) {
  80. return;
  81. }
  82. function ondragstart(ev) {
  83. ev.dataTransfer.setData("Text", ev.target.id);
  84. }
  85. function ondrop(ev) {
  86. var from = ev.dataTransfer.getData("Text");
  87. cbi_row_drop(from, this.id, store);
  88. }
  89. function ondragover(ev) {
  90. ev.preventDefault();
  91. ev.dataTransfer.dropEffect = "move";
  92. }
  93. function moveToTop(id) {
  94. var top = document.querySelectorAll(table_selecter + " tr")[2];
  95. cbi_row_drop(id, top.id, store);
  96. }
  97. function moveToBottom(id) {
  98. console.log('moveToBottom:', id);
  99. var trList = document.querySelectorAll(table_selecter + " tr");
  100. var bottom = trList[trList.length - 1];
  101. cbi_row_drop(id, bottom.id, store, true);
  102. }
  103. for (let index = 2; index < trs.length; index++) {
  104. const el = trs[index];
  105. el.setAttribute("draggable", true);
  106. el.ondragstart = ondragstart;
  107. el.ondrop = ondrop;
  108. el.ondragover = ondragover;
  109. // reset the behaviors of the btns
  110. var upBtns = el.querySelectorAll(".cbi-button.cbi-button-up");
  111. if (upBtns && upBtns.length > 0) {
  112. upBtns.forEach(function (_el) {
  113. _el.onclick = function () {
  114. moveToTop(el.id);
  115. };
  116. });
  117. }
  118. var downBtns = el.querySelectorAll(".cbi-button.cbi-button-down");
  119. if (downBtns && downBtns.length > 0) {
  120. downBtns.forEach(function (_el) {
  121. _el.onclick = function () {
  122. moveToBottom(el.id);
  123. };
  124. });
  125. }
  126. }
  127. }
  128. // enable
  129. enableDragForTable(
  130. "#cbi-shadowsocksr-servers table",
  131. "cbi.sts.shadowsocksr.servers"
  132. );
  133. </script>