Custom Auto Refresh

Define custom auto-refresh intervals for different websites, and manage them through a settings menu with options to view, modify, or clear.

  1. // ==UserScript==
  2. // @name Custom Auto Refresh
  3. // @namespace YMHOMER
  4. // @version 2.0
  5. // @description Define custom auto-refresh intervals for different websites, and manage them through a settings menu with options to view, modify, or clear.
  6. // @match *://*/*
  7. // @grant GM_setValue
  8. // @grant GM_getValue
  9. // @grant GM_registerMenuCommand
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. 'use strict';
  14.  
  15. const currentUrl = window.location.href;
  16. const currentRoot = window.location.hostname;
  17. const defaultRefreshInterval = 0;
  18. let allRefreshSettings = GM_getValue('allRefreshSettings', {});
  19. let refreshInterval = allRefreshSettings[currentRoot] || defaultRefreshInterval;
  20. let refreshTimer;
  21. let manageSettingsDialogOpen = false;
  22.  
  23. const startAutoRefresh = () => {
  24. if (refreshInterval > 0 && !manageSettingsDialogOpen) {
  25. refreshTimer = setInterval(() => { location.reload(); }, refreshInterval * 1000);
  26. }
  27. };
  28.  
  29. const stopAutoRefresh = () => { clearInterval(refreshTimer); };
  30.  
  31. const showDialog = (title, content, onCloseCallback = null) => {
  32. const dialog = document.createElement('div');
  33. dialog.innerHTML = `
  34. <style>
  35. .custom-dialog {
  36. position: fixed;
  37. top: 50%;
  38. left: 50%;
  39. transform: translate(-50%, -50%);
  40. background: #fff;
  41. padding: 20px;
  42. border-radius: 8px;
  43. box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
  44. z-index: 10000;
  45. max-width: 400px;
  46. max-height: 500px;
  47. overflow-y: auto;
  48. }
  49. .custom-dialog input[type="checkbox"] { margin-right: 5px; }
  50. .custom-dialog button { margin-top: 10px; }
  51. .custom-overlay {
  52. position: fixed;
  53. top: 0;
  54. left: 0;
  55. width: 100%;
  56. height: 100%;
  57. background: rgba(0, 0, 0, 0.5);
  58. z-index: 9999;
  59. }
  60. .custom-dialog table {
  61. width: 100%;
  62. border-collapse: collapse;
  63. }
  64. .custom-dialog table, .custom-dialog th, .custom-dialog td {
  65. border: 1px solid #ccc;
  66. }
  67. .custom-dialog th, .custom-dialog td {
  68. padding: 8px;
  69. text-align: left;
  70. }
  71. </style>
  72. <div class="custom-dialog">
  73. <h2>${title}</h2>
  74. <div id="dialogContent">${content}</div>
  75. </div>
  76. <div class="custom-overlay"></div>
  77. `;
  78.  
  79. document.body.appendChild(dialog);
  80.  
  81. const overlay = dialog.querySelector('.custom-overlay');
  82. overlay.addEventListener('click', () => {
  83. document.body.removeChild(dialog);
  84. if (onCloseCallback) onCloseCallback();
  85. });
  86.  
  87. return dialog.querySelector('.custom-dialog');
  88. };
  89.  
  90. const refreshManageSettingsDialog = (dialog) => {
  91. const siteKeys = Object.keys(allRefreshSettings);
  92. let tableRows = siteKeys.map(site => `
  93. <tr>
  94. <td>${site}</td>
  95. <td>${allRefreshSettings[site]} seconds</td>
  96. <td><button class="modifyBtn" data-site="${site}">Modify</button></td>
  97. <td><button class="deleteBtn" data-site="${site}">Delete</button></td>
  98. </tr>
  99. `).join('');
  100.  
  101. const dialogContent = `
  102. <button id="addSettingBtn">Add New</button>
  103. <table>
  104. <thead>
  105. <tr>
  106. <th>Site</th>
  107. <th>Refresh Interval</th>
  108. <th>Modify</th>
  109. <th>Delete</th>
  110. </tr>
  111. </thead>
  112. <tbody>${tableRows}</tbody>
  113. </table>
  114. `;
  115.  
  116. dialog.querySelector('#dialogContent').innerHTML = dialogContent;
  117. bindManageSettingsEvents(dialog);
  118. };
  119.  
  120. const openSettingsDialog = (parentDialog = null) => {
  121. stopAutoRefresh();
  122.  
  123. const dialogContent = `
  124. <label>Enter refresh interval (Seconds):</label>
  125. <input type="number" id="intervalInput" value="${refreshInterval}" min="0" />
  126. <br/>
  127. <label><input type="checkbox" id="fullUrlCheckbox"> Apply to full URL</label>
  128. <button id="saveIntervalBtn">Save</button>
  129. `;
  130. const dialog = showDialog("Set Refresh Interval", dialogContent);
  131.  
  132. dialog.querySelector('#saveIntervalBtn').addEventListener('click', () => {
  133. const intervalInput = dialog.querySelector('#intervalInput').value;
  134. const applyToFullUrl = dialog.querySelector('#fullUrlCheckbox').checked;
  135. const targetUrl = applyToFullUrl ? currentUrl : currentRoot;
  136.  
  137. if (intervalInput !== null) {
  138. refreshInterval = parseInt(intervalInput, 10);
  139. allRefreshSettings[targetUrl] = refreshInterval;
  140. GM_setValue('allRefreshSettings', allRefreshSettings);
  141. document.body.removeChild(dialog.parentNode);
  142. startAutoRefresh();
  143.  
  144. // Refresh Manage Settings dialog if open
  145. if (parentDialog) {
  146. refreshManageSettingsDialog(parentDialog);
  147. }
  148. }
  149. });
  150. };
  151.  
  152. const manageAllSettingsDialog = () => {
  153. stopAutoRefresh();
  154. manageSettingsDialogOpen = true;
  155. const dialog = showDialog("Manage Settings", '', () => {
  156. manageSettingsDialogOpen = false;
  157. refreshInterval = allRefreshSettings[currentRoot] || defaultRefreshInterval;
  158. startAutoRefresh();
  159. });
  160. refreshManageSettingsDialog(dialog);
  161. };
  162.  
  163. const bindManageSettingsEvents = (dialog) => {
  164. dialog.querySelector('#addSettingBtn').addEventListener('click', () => openSettingsDialog(dialog));
  165.  
  166. dialog.querySelectorAll('.modifyBtn').forEach(button => {
  167. button.addEventListener('click', () => {
  168. const site = button.getAttribute('data-site');
  169. modifySettingDialog(dialog, site);
  170. });
  171. });
  172.  
  173. dialog.querySelectorAll('.deleteBtn').forEach(button => {
  174. button.addEventListener('click', () => {
  175. const site = button.getAttribute('data-site');
  176. deleteSetting(dialog, site);
  177. });
  178. });
  179. };
  180.  
  181. const modifySettingDialog = (parentDialog, site) => {
  182. const currentInterval = allRefreshSettings[site];
  183. const dialogContent = `
  184. <label>Enter new refresh interval (Seconds) for ${site}:</label>
  185. <input type="number" id="newIntervalInput" value="${currentInterval}" min="0" />
  186. <button id="saveModifyBtn">Save</button>
  187. `;
  188. const dialog = showDialog("Modify Refresh Interval", dialogContent);
  189.  
  190. dialog.querySelector('#saveModifyBtn').addEventListener('click', () => {
  191. const newInterval = dialog.querySelector('#newIntervalInput').value;
  192. if (newInterval !== null) {
  193. allRefreshSettings[site] = parseInt(newInterval, 10);
  194. GM_setValue('allRefreshSettings', allRefreshSettings);
  195. document.body.removeChild(dialog.parentNode);
  196. refreshManageSettingsDialog(parentDialog);
  197. }
  198. });
  199. };
  200.  
  201. const deleteSetting = (parentDialog, site) => {
  202. delete allRefreshSettings[site];
  203. GM_setValue('allRefreshSettings', allRefreshSettings);
  204. refreshManageSettingsDialog(parentDialog);
  205. };
  206.  
  207. startAutoRefresh();
  208. GM_registerMenuCommand("Manage Settings", manageAllSettingsDialog);
  209. })();