TradingView: hide disconnected session popup (PC Version)

Hides "Session disconnected" popup. Reconnect is triggered by a mouse move

当前为 2024-08-11 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name TradingView: hide disconnected session popup (PC Version)
  3. // @description Hides "Session disconnected" popup. Reconnect is triggered by a mouse move
  4. // @author Konf
  5. // @namespace https://greasyfork.org/users/424058
  6. // @icon https://www.google.com/s2/favicons?sz=64&domain=tradingview.com
  7. // @version 1.1.0
  8. // @match https://www.tradingview.com/*
  9. // @require https://cdnjs.cloudflare.com/ajax/libs/arrive/2.4.1/arrive.min.js#sha512-wkU3qYWjenbM+t2cmvw2ADRRh4opbOYBjkhrPGHV7M6dcE/TR0oKpoDkWXfUs3HrulI2JFuTQyqPLRih1V54EQ==
  10. // @run-at document-body
  11. // @grant none
  12. // @noframes
  13. // ==/UserScript==
  14.  
  15. /* jshint esversion: 8 */
  16.  
  17. (function() {
  18. 'use strict';
  19.  
  20. const IS_DEBUG_MODE = true; // true or false
  21. const MOUSEMOVE_AMOUNT_NEEDED = 100;
  22. const MOUSEMOVE_RESET_INTERVAL_MS = 4000;
  23. const USE_ADAPTIVE_FAVICON = false;
  24.  
  25. const originalFavicon = document.querySelector("link[rel='icon']");
  26. const disconnectedFavicon = (() => {
  27. const link = document.createElement('link');
  28.  
  29. link.rel = 'icon';
  30. link.type = 'image/png';
  31. link.sizes = '16x16';
  32. link.href = [
  33. 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMAAAADACAYAAABS3GwHA',
  34. 'AAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDoAABSCAAB',
  35. 'FVgAADqXAAAXb9daH5AAAAo6SURBVHja7N1bjFVXHcfx39owTkxkLoJcAocO44u2kMY',
  36. 'xGQQeio2QFqMhDAq1SQVSSl9UQlsfjLGixoc2INUn28ZMHzRgGGzTlGnA1GkTxkLjYF',
  37. 'Pavlg4zEAYBHLOTHk5wOzlwzANDnM71335f39J3+Awe+312f//2rO6jvOSVwwz7AJ1N',
  38. 'C/S6bp6kVQm66S8l8tL/n0vnQtHgvdzV//TU8sfwsUVAAgsx/XIq3MkGHk7N5jNmgUA',
  39. 'AiK5HoXqvHrlk1dMAgABGWuZvFdnGISvVLIqJAIACMh4CNf+e3avKQAgIONybsSFO3K',
  40. 'D2R4zAEBA7prA0u9uFcJf5fLZvAkAICCTVIMHS1kbBEm82gYfqit3SV+7WeDWE0laNs',
  41. 'sHffPmt2w0AQAEZII0ywVH5i5o3W0CAAjIRC29k/bPnd/6bKrXAKwJyDTxXtpz7fLZA',
  42. 'yYAgIBMhOD2wrjHBAAQkAmSG3Fh21Rvh4I0XS1rAjJ+YTzLB281N7U0mQAAAjJBls2u',
  43. 'D35hogWiHSLFrgdSCwAEZFzOjRTCtvFbJoI0XzHtELmzFQo+F+w2VQGoBGRcciOFsPX',
  44. 'OKhBYuGoqAbmd5vFVwEQFoBKQyapAYOnKqQREUlNQH2wz1QKBgNzZ9Tj575psgWiHyO',
  45. '34kUL4xVw+mw+sjgCVwHbG2qDA8iCAgDbIbAtEO2Q+uZFC2BowDlQCo2lSnVoAAAK76',
  46. '4AgWAsAEBheB+geAIDAcHwLi2AWxpZzjgpAJbDdB1EBqASWeyAqAJXAdAAAAgAQEACA',
  47. 'gAAABATGAAw7DIDAMIDNzYsEAhCYBdBXVy8QgMD0GgAEIDC/CAYBCEwDAAEIzAMAAQj',
  48. 'MAwABCMwDAAEIzAMAAQjMAwABCMwDAAEIzAMAAQjMAwABCMwDAAEIzAMAAQjMAwABCM',
  49. 'wDAAEIzAMAAQiSHjd3QWtFDsZqu1nQ4dwlNfiQUS0ykx2+1dAwR99+eJ1Wr16lFfd9R',
  50. 'ZmlS9TY0CBJGhoe1kD/BX3w4cc60XtSR7uPaXj4UwazuPiKAQBB+Qg2Ny9SX129MpnF',
  51. '2rVzux7Z2vHZhJ9J/nKwS8/ve0EDAxer9nOuWH6v/vH312M1dh+c+Ujf/NZ3SgJQ0b6',
  52. 'FdqjMdig/qJd2PKrT772jJ5/YXtTkl6QfbO3Q6ffe0W9+/XM1NsypfLvgnJ7YuS1ej3',
  53. 'Dv9ceXOqNvgcZXgmMj16WhIWZ2sWlslI4dk9rby/qY8/0D2tjxaEWrwdKlS9R36u1YD',
  54. 'df5/gv6evsDJfupyqO6r65+9CY2NjKhi83QkLR+vXTqVFkfc8/SjF7t+rOW3/fViv1o',
  55. 'a1Z/I3bD1dv7bjwWweNzdfCT0Zu4fj2VIAWVwDmnf53q0dLMkli1P23tazUwcCFeFeC',
  56. 'ztLdTCWJSCcpdE2x4aF2sJr8kHe0+Xs7kl1SLoxFBEAsETz/9k9Qtfl98ubPsz6nN6x',
  57. 'oQRI7gyZ3blMksLunvZjKLtWb1ylgNS//ARZ3oPZkQACCIHIFzTrse317S33vmqR/H7',
  58. 'un//L7fV+SzavvCHgSRIti6ZVNJa4G4Pf0lVeTpX3sAIIgUQWNjgzY8vK5INB2xW/we',
  59. 'PNRV9uI3OgAgiAyBc06rVq0s6s/vevyHsWt/yvnNbzwAgCAyBCuW31tU67O8iD9fq9b',
  60. 'nzIcfpwAACCJBkFkyszdBzjlt+f6m2D39D/71SEU/M/pdayCoKYLGxpltsMtkFuuRLR',
  61. '2xutz+gYs6eKgrZQBAEOnCePL2J337fuILAAQ1QzA0NDyj9ueZp34Uu/bnuX1/SDEAE',
  62. 'NQEwcCF6TfFpf3VZ3wBgKDqCM6c+Wjap/9WA4vf+AIAQdUQeO914p+npl38pnXfT3IA',
  63. 'gKBqCLq7j03T+6d330+yAICg4ggOHurS0DQnR6R530/yAICgYghm8hbF0uI3OQBAUBE',
  64. 'Ef/vZs1NOJEuvPpMHAARlI1j33G/VNsUJdGtWr4zd0/9E78mqPv2TBQAEZWVOOKLDuU',
  65. 'sTIrCy72fCylfVUyGqFU6bKDl3nkA3lhSe9zNjZ8k8wo1KUHIafHhXJdjw0LrY/Zzdb',
  66. 'x6vyb+T3DMMQVARBGk87tAGABBUBMFPH1hl7tVnegCAoGwEe954teJbqZOw+E0PABCU',
  67. 'lVnXr1fl/ycoNdXc9zNRZlfrg+ct/HLNB69t1hd02H3K9xMUm7HfGFfgLNJyn/7V3Pe',
  68. 'T3gpwO2PfT0AlKANBhJVgaGi4pk//1AEYQ0A7lEwE3W8er9niN7UAWBMkE0Et9v3YAQ',
  69. 'CCxCGoxb4fWwBAkBgEtX71aQcACBKBoBrn/QAABIlBcPDQkcguz873mYIglghG258uA',
  70. 'IDAJoJa7vsBAAhihSDKxa9dACCIDYJa7/sBAAhigyCKfT8AAEFsEPQPXJzykC4AgCDV',
  71. 'CHp73532kC4AgCCVCKLa9wMAEMQCQVT7fgAAgsgRxOHVJwBAEBmCKPf9AAAEkSLwXnr',
  72. 'x5c5Y/bgAAEENEXgd7T4OABDYRBD1vh8AgCAyBHFb/AIABDVFcPn1NyLf9wMAEESGoP',
  73. 'F7m6f8fgIAgCDV+fyNwqTfTwAAEJjIREezAwAEIAAACEAAABCAAAAgAAEAQAACAIAAB',
  74. 'ABIJIJhx7AmBQF3qgoINjcvAkFCEHCXqpCxb6oBQfwRcIdAYBoBdwcEphFwZ0BgGgF3',
  75. 'BQSmEXBHQGAaAXcDBKYRcCdAYBoBdwEEphFwB0BgGgGjDwLTCFI58t77SP8DQXIQuLk',
  76. 'LWj1DGX3abo6emtDgQwajyAy7QJubF6mvrr7oZyWPHdoh05WA0QaBaQSMNAhMI2CUQW',
  77. 'AaASMMAtMIGF0QmEbAyILANAJGFQSmETCiIDCNgNEEgWkEjCQITCNgFEFgGgEjCALTC',
  78. 'NgNmvCwi7T0DLuACkAlsF0JGDUQmA4jBgIAEBAYBuCzDAMIqAAEBCYBePdvhgEEZgF4',
  79. 'p/MMAwgst0CsAUBgF0AYhj0MAwjsVoCbynqvPEMBApMAcvls3jnPQhgEZtcA8nKvMRQ',
  80. 'gMAsgLISdDAUIzALI5bN5ybMYBoFNALRBIDAPICyEnbwNAoFZALl8Nh9ILzAlQGASgC',
  81. 'TduhEeoAqAwCwAqgAIrCG460pv3QgPePlzTAcQmASQy2fzgfM7mAogsIBgwiu8Mpjtk',
  82. 'XSAqQCCtCOY9OpGCuFeWiEQpB3BpFeWy2fzofMPeq8cUwEEaUUw5VXlBrPZIAg3SeL0',
  83. 'OBCkEsG0V3RlMNvjpT1MAxCkEcGMruba5bMHnNNeKgEI0obAFTOj5y5o3e2k/ZIc08F',
  84. 'u0nQgryv2kT5vfstGr+BPzqmZqQCCpCNwpfQ0zQtbWgLv3nJyy5gKIEgygpKaudxgNh',
  85. 'sWfJtGf1nGuoA1ga0KcFdL5Nx+qgGVIImVwFXq8f2lha2/DL1/DAggMAlgbG0wW8G22',
  86. 'xBaxNsiEFgC8H+t0cKWbfLuMcmtHfu3mCIgMAPgzqowS1o7DgMgQGADwN1rhZa1oQ/u',
  87. 'd1KL5O+XV5OcmjTaMpF0IXBxR/C/AQCN9dVskCYggwAAAABJRU5ErkJggg==',
  88. ].join('');
  89.  
  90. return link;
  91. })();
  92.  
  93. let isConnected = true;
  94. let popupContainer = null;
  95. let reconnectBtn = null;
  96.  
  97. document.addEventListener('mousemove', (() => {
  98. let lastResetTime = Date.now();
  99. let mouseMoveCount = 0;
  100.  
  101. return () => {
  102. if (isConnected) return;
  103.  
  104. if (IS_DEBUG_MODE) reconnectBtn.innerText = mouseMoveCount;
  105.  
  106. const now = Date.now();
  107.  
  108. if (now - lastResetTime >= MOUSEMOVE_RESET_INTERVAL_MS) {
  109. lastResetTime = now;
  110. mouseMoveCount = 0;
  111.  
  112. if (IS_DEBUG_MODE) reconnectBtn.innerText = 0;
  113.  
  114. return;
  115. }
  116.  
  117. mouseMoveCount++;
  118.  
  119. if (mouseMoveCount >= MOUSEMOVE_AMOUNT_NEEDED) {
  120. isConnected = true;
  121. popupContainer.style.display = '';
  122.  
  123. if (USE_ADAPTIVE_FAVICON) {
  124. disconnectedFavicon.remove();
  125. document.head.appendChild(originalFavicon);
  126. }
  127.  
  128. reconnectBtn.click();
  129. }
  130. };
  131. })());
  132.  
  133. document.arrive(
  134. 'div[data-dialog-name="gopro"]', {
  135. existing: true,
  136. },
  137. (popup) => {
  138. // skip a container with exact same selector.
  139. // the popup has two of them, no need to run twice for the same one
  140. if (popup.querySelector('div[data-dialog-name="gopro"]')) return;
  141.  
  142. popupContainer = document.querySelector('div#overlap-manager-root');
  143.  
  144. if (popupContainer.contains(popup) === false) return;
  145.  
  146. for (const div of popup.querySelectorAll('div')) {
  147. if (
  148. div.childElementCount === 0 &&
  149. div.innerText === 'Session disconnected' &&
  150. /(center|title).+(center|title).+/.test(div.className) === true
  151. ) {
  152. isConnected = false;
  153. reconnectBtn = popup.querySelector(
  154. 'button[data-overflow-tooltip-text*="Connect"]'
  155. );
  156.  
  157. if (USE_ADAPTIVE_FAVICON) {
  158. originalFavicon.remove();
  159. document.head.appendChild(disconnectedFavicon);
  160. }
  161.  
  162. if (!IS_DEBUG_MODE) popupContainer.style.display = 'none';
  163.  
  164. break;
  165. }
  166. }
  167. }
  168. );
  169. })();