Persistent Auto Page Refresher

Refreshes the current page with a customizable timer that persists across refreshes

  1. // ==UserScript==
  2. // @name Persistent Auto Page Refresher
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description Refreshes the current page with a customizable timer that persists across refreshes
  6. // @author You
  7. // @match *://*/*
  8. // @grant GM_setValue
  9. // @grant GM_getValue
  10. // @grant GM_deleteValue
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. // Get saved state from previous page load (if any)
  18. const savedInterval = GM_getValue('refreshInterval', 5);
  19. const wasRefreshing = GM_getValue('isRefreshing', false);
  20. const lastRefreshTime = GM_getValue('lastRefreshTime', 0);
  21.  
  22. // Default refresh interval
  23. let refreshInterval = savedInterval * 1000;
  24. let isRefreshing = wasRefreshing;
  25. let countdownTimer;
  26. let refreshTimer;
  27.  
  28. // Create control panel
  29. const panel = document.createElement('div');
  30. panel.style.position = 'fixed';
  31. panel.style.bottom = '10px';
  32. panel.style.right = '10px';
  33. panel.style.backgroundColor = 'rgba(40,40,40,0.8)';
  34. panel.style.color = 'white';
  35. panel.style.padding = '10px';
  36. panel.style.borderRadius = '8px';
  37. panel.style.zIndex = '9999';
  38. panel.style.fontSize = '14px';
  39. panel.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)';
  40. panel.style.display = 'flex';
  41. panel.style.flexDirection = 'column';
  42. panel.style.gap = '10px';
  43.  
  44. // Create input for seconds
  45. const inputContainer = document.createElement('div');
  46. inputContainer.style.display = 'flex';
  47. inputContainer.style.alignItems = 'center';
  48. inputContainer.style.gap = '8px';
  49.  
  50. const inputLabel = document.createElement('label');
  51. inputLabel.textContent = 'Refresh every:';
  52. inputLabel.style.marginRight = '5px';
  53.  
  54. const input = document.createElement('input');
  55. input.type = 'number';
  56. input.min = '1';
  57. input.value = savedInterval;
  58. input.style.width = '60px';
  59. input.style.padding = '5px';
  60. input.style.borderRadius = '4px';
  61. input.style.border = '1px solid #ccc';
  62.  
  63. const secondsLabel = document.createElement('span');
  64. secondsLabel.textContent = 'seconds';
  65.  
  66. inputContainer.appendChild(inputLabel);
  67. inputContainer.appendChild(input);
  68. inputContainer.appendChild(secondsLabel);
  69.  
  70. // Create status display
  71. const status = document.createElement('div');
  72. status.textContent = isRefreshing ? 'Auto-refresh: On' : 'Auto-refresh: Off';
  73. status.style.textAlign = 'center';
  74. status.style.fontWeight = 'bold';
  75.  
  76. // Create button container
  77. const buttonContainer = document.createElement('div');
  78. buttonContainer.style.display = 'flex';
  79. buttonContainer.style.gap = '5px';
  80.  
  81. // Create toggle button
  82. const toggleButton = document.createElement('button');
  83. toggleButton.textContent = isRefreshing ? 'Stop' : 'Start';
  84. toggleButton.style.padding = '5px 10px';
  85. toggleButton.style.borderRadius = '4px';
  86. toggleButton.style.border = 'none';
  87. toggleButton.style.backgroundColor = isRefreshing ? '#f44336' : '#4CAF50';
  88. toggleButton.style.color = 'white';
  89. toggleButton.style.cursor = 'pointer';
  90. toggleButton.style.flexGrow = '1';
  91.  
  92. // Create close button
  93. const closeButton = document.createElement('button');
  94. closeButton.textContent = '×';
  95. closeButton.style.padding = '5px 10px';
  96. closeButton.style.borderRadius = '4px';
  97. closeButton.style.border = 'none';
  98. closeButton.style.backgroundColor = '#f44336';
  99. closeButton.style.color = 'white';
  100. closeButton.style.cursor = 'pointer';
  101.  
  102. buttonContainer.appendChild(toggleButton);
  103. buttonContainer.appendChild(closeButton);
  104.  
  105. // Add everything to panel
  106. panel.appendChild(inputContainer);
  107. panel.appendChild(status);
  108. panel.appendChild(buttonContainer);
  109.  
  110. // Function to start/stop refresh
  111. function toggleRefresh() {
  112. if (isRefreshing) {
  113. // Stop refreshing
  114. clearInterval(countdownTimer);
  115. clearTimeout(refreshTimer);
  116. isRefreshing = false;
  117. status.textContent = 'Auto-refresh: Off';
  118. toggleButton.textContent = 'Start';
  119. toggleButton.style.backgroundColor = '#4CAF50';
  120.  
  121. // Save state
  122. GM_setValue('isRefreshing', false);
  123. } else {
  124. // Get user input
  125. refreshInterval = Math.max(1, parseInt(input.value, 10)) * 1000;
  126.  
  127. // Save state
  128. GM_setValue('refreshInterval', refreshInterval / 1000);
  129. GM_setValue('isRefreshing', true);
  130. GM_setValue('lastRefreshTime', Date.now());
  131.  
  132. // Start refreshing
  133. startRefreshTimer();
  134.  
  135. isRefreshing = true;
  136. toggleButton.textContent = 'Stop';
  137. toggleButton.style.backgroundColor = '#f44336';
  138. }
  139. }
  140.  
  141. function startRefreshTimer() {
  142. const now = Date.now();
  143. let timeLeft = Math.ceil(refreshInterval / 1000);
  144.  
  145. if (wasRefreshing && lastRefreshTime) {
  146. // Calculate time elapsed since the last save
  147. const elapsedMs = now - lastRefreshTime;
  148. const remainingMs = refreshInterval - (elapsedMs % refreshInterval);
  149. timeLeft = Math.ceil(remainingMs / 1000);
  150. }
  151.  
  152. status.textContent = `Refreshing in: ${timeLeft} seconds`;
  153.  
  154. // Update the countdown every second
  155. countdownTimer = setInterval(function() {
  156. timeLeft -= 1;
  157. if (timeLeft <= 0) {
  158. timeLeft = refreshInterval / 1000;
  159. }
  160. status.textContent = `Refreshing in: ${timeLeft} seconds`;
  161. }, 1000);
  162.  
  163. // Set the page refresh
  164. const refreshDelay = wasRefreshing ? (timeLeft * 1000) : refreshInterval;
  165. refreshTimer = setTimeout(function() {
  166. GM_setValue('lastRefreshTime', Date.now());
  167. location.reload();
  168. }, refreshDelay);
  169. }
  170.  
  171. // Event listeners
  172. toggleButton.addEventListener('click', toggleRefresh);
  173.  
  174. closeButton.addEventListener('click', function() {
  175. // Stop any refreshing before removing
  176. if (isRefreshing) {
  177. clearInterval(countdownTimer);
  178. clearTimeout(refreshTimer);
  179. }
  180. // Clear saved values
  181. GM_deleteValue('refreshInterval');
  182. GM_deleteValue('isRefreshing');
  183. GM_deleteValue('lastRefreshTime');
  184. panel.remove();
  185. });
  186.  
  187. input.addEventListener('change', function() {
  188. const newInterval = Math.max(1, parseInt(input.value, 10));
  189. GM_setValue('refreshInterval', newInterval);
  190.  
  191. if (isRefreshing) {
  192. toggleRefresh(); // Stop current timer
  193. toggleRefresh(); // Restart with new value
  194. }
  195. });
  196.  
  197. // Make panel draggable
  198. let isDragging = false;
  199. let dragOffsetX, dragOffsetY;
  200.  
  201. panel.style.cursor = 'move';
  202.  
  203. panel.addEventListener('mousedown', function(e) {
  204. if (e.target === panel || e.target === status) {
  205. isDragging = true;
  206. dragOffsetX = e.clientX - panel.getBoundingClientRect().left;
  207. dragOffsetY = e.clientY - panel.getBoundingClientRect().top;
  208. }
  209. });
  210.  
  211. document.addEventListener('mousemove', function(e) {
  212. if (isDragging) {
  213. panel.style.left = (e.clientX - dragOffsetX) + 'px';
  214. panel.style.top = (e.clientY - dragOffsetY) + 'px';
  215. panel.style.right = 'auto';
  216. panel.style.bottom = 'auto';
  217. }
  218. });
  219.  
  220. document.addEventListener('mouseup', function() {
  221. isDragging = false;
  222. });
  223.  
  224. // Start refreshing if it was active before page reload
  225. if (isRefreshing) {
  226. startRefreshTimer();
  227. }
  228.  
  229. // Add to document
  230. document.body.appendChild(panel);
  231. })();