Reddit Default Sort

Automatically sets Reddit's default sorting order for home and subreddits.

当前为 2025-02-11 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Reddit Default Sort
  3. // @version 1.1.1
  4. // @description Automatically sets Reddit's default sorting order for home and subreddits.
  5. // @author yodaluca23
  6. // @license MIT
  7. // @match *://*.reddit.com/*
  8. // @grant GM_getValue
  9. // @grant GM_setValue
  10. // @namespace https://greasyfork.org/users/1315976
  11. // ==/UserScript==
  12.  
  13. (function() {
  14.     'use strict';
  15.  
  16.     // Default values
  17.     const defaultHomePageSort = "new";
  18.     const defaultSubredditSort = "new";
  19. // This allows you to use the Reddit filters temporariliy, without it redirecting you to the default
  20. let lastUrl = "";
  21.  
  22.     // Function to get the stored sort option, or the default if none is stored.
  23.     function getSortOption(key, defaultValue) {
  24.         let value = GM_getValue(key);
  25.         return value === undefined ? defaultValue : value;
  26.     }
  27.  
  28.     // Get the stored sort options
  29.     let homePageSort = getSortOption("homePageSort", defaultHomePageSort);
  30.     let subredditSort = getSortOption("subredditSort", defaultSubredditSort);
  31.  
  32.     // Function to redirect if necessary
  33.     function redirectIfNeeded() {
  34.         const currentUrl = window.location.href;
  35.  
  36.         // Check for home page URLs
  37.         const homeUrls = [
  38.             "https://www.reddit.com/",
  39.             "https://www.reddit.com/?feed=home",
  40.             "https://www.reddit.com/best/?feed=home",
  41.             "https://www.reddit.com/hot/?feed=home",
  42.             "https://www.reddit.com/top/?feed=home",
  43.             "https://www.reddit.com/new/?feed=home",
  44.             "https://www.reddit.com/rising/?feed=home"
  45.         ];
  46.  
  47.         const homeTargetUrl = `https://www.reddit.com/${homePageSort}/?feed=home`;
  48.  
  49.         if (homeUrls.includes(currentUrl) && currentUrl !== homeTargetUrl && !homeUrls.includes(lastUrl)) {
  50. window.location.replace(homeTargetUrl);
  51. return;
  52.         }
  53.  
  54.         // Check for subreddit URLs
  55. const subredditPattern = /https:\/\/www\.reddit\.com\/r\/([^/]+)(\/(hot|new|top|best|rising))?(\/)?(\?.*)?$/;
  56.  
  57. if (subredditPattern.test(currentUrl)) {
  58. const match = currentUrl.match(subredditPattern);
  59. const subredditName = match[1];
  60.  
  61. // Check if were still on the same sub indicates the user only changed their sort we should not set it back
  62. if (subredditPattern.test(lastUrl)) {
  63. const matchLast = lastUrl.match(subredditPattern);
  64. if (subredditName == matchLast[1]) {
  65. return;
  66. }
  67. }
  68.  
  69. const targetUrl = `https://www.reddit.com/r/${subredditName}/${subredditSort}`;
  70. const altTargetUrl = `https://www.reddit.com/r/${subredditName}/${subredditSort}/`;
  71.  
  72. if (currentUrl !== targetUrl && currentUrl !== altTargetUrl) {
  73. window.location.replace(targetUrl);
  74. }
  75. }
  76.     }
  77.  
  78.     // Function to create the settings UI
  79. function createSettingsUI() {
  80. // Create the settings container
  81. const settingsContainer = document.createElement('div');
  82. settingsContainer.style.position = 'fixed';
  83. settingsContainer.style.top = '50%';
  84. settingsContainer.style.left = '50%';
  85. settingsContainer.style.transform = 'translate(-50%, -50%)';
  86. settingsContainer.style.padding = '20px';
  87. settingsContainer.style.borderRadius = '12px';
  88. settingsContainer.style.boxShadow = '0px 8px 20px rgba(0, 0, 0, 0.1)';
  89. settingsContainer.style.zIndex = '1000';
  90. settingsContainer.style.minWidth = '280px';
  91. settingsContainer.style.textAlign = 'center';
  92. settingsContainer.style.fontFamily = '"Arial", sans-serif';
  93.  
  94. // Dark/Light Mode detection based on system preference
  95. const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
  96. if (isDarkMode) {
  97. settingsContainer.style.backgroundColor = '#111111'; // AMOLED dark mode
  98. settingsContainer.style.color = '#fff';
  99. settingsContainer.style.border = '1px solid #444'; // Softer border for dark mode
  100. } else {
  101. settingsContainer.style.backgroundColor = '#f9f9f9';
  102. settingsContainer.style.color = '#000';
  103. settingsContainer.style.border = '1px solid #ccc'; // Softer border for light mode
  104. }
  105.  
  106. // Title
  107. const title = document.createElement('h2');
  108. title.textContent = 'Settings';
  109. title.style.marginBottom = '20px';
  110. settingsContainer.appendChild(title);
  111.  
  112. // Home page sort select
  113. const homePageLabel = document.createElement('label');
  114. homePageLabel.textContent = 'Home Page Sort:';
  115. homePageLabel.style.display = 'block';
  116. homePageLabel.style.marginBottom = '10px';
  117.  
  118. const homePageSelect = document.createElement('select');
  119. homePageSelect.id = 'homePageSortSelect';
  120. homePageSelect.style.width = '100%';
  121. homePageSelect.style.padding = '8px';
  122. homePageSelect.style.borderRadius = '5px';
  123. homePageSelect.style.backgroundColor = isDarkMode ? '#333' : '#fff'; // Darker dropdown in dark mode
  124. homePageSelect.style.color = isDarkMode ? '#fff' : '#000'; // Ensure text contrast is high
  125. homePageSelect.style.border = isDarkMode ? '1px solid #444' : '1px solid #ccc'; // Softer borders
  126.  
  127. ['best', 'hot', 'top', 'new', 'rising'].forEach(option => {
  128. const opt = document.createElement('option');
  129. opt.value = option;
  130. opt.textContent = option.charAt(0).toUpperCase() + option.slice(1);
  131. homePageSelect.appendChild(opt);
  132. });
  133. homePageSelect.value = homePageSort;
  134.  
  135. settingsContainer.appendChild(homePageLabel);
  136. settingsContainer.appendChild(homePageSelect);
  137.  
  138. // Subreddit sort select
  139. const subredditLabel = document.createElement('label');
  140. subredditLabel.textContent = 'Subreddit Sort:';
  141. subredditLabel.style.display = 'block';
  142. subredditLabel.style.marginBottom = '10px';
  143.  
  144. const subredditSelect = document.createElement('select');
  145. subredditSelect.id = 'subredditSortSelect';
  146. subredditSelect.style.width = '100%';
  147. subredditSelect.style.padding = '8px';
  148. subredditSelect.style.borderRadius = '5px';
  149. subredditSelect.style.backgroundColor = isDarkMode ? '#333' : '#fff'; // Darker dropdown in dark mode
  150. subredditSelect.style.color = isDarkMode ? '#fff' : '#000'; // Ensure text contrast is high
  151. subredditSelect.style.border = isDarkMode ? '1px solid #444' : '1px solid #ccc'; // Softer borders
  152.  
  153. ['best', 'hot', 'top', 'new', 'rising'].forEach(option => {
  154. const opt = document.createElement('option');
  155. opt.value = option;
  156. opt.textContent = option.charAt(0).toUpperCase() + option.slice(1);
  157. subredditSelect.appendChild(opt);
  158. });
  159. subredditSelect.value = subredditSort;
  160.  
  161. settingsContainer.appendChild(subredditLabel);
  162. settingsContainer.appendChild(subredditSelect);
  163.  
  164. // Buttons container
  165. const buttonsContainer = document.createElement('div');
  166. buttonsContainer.style.marginTop = '20px';
  167. buttonsContainer.style.display = 'flex';
  168. buttonsContainer.style.justifyContent = 'space-between';
  169.  
  170. // Save button
  171. const saveButton = document.createElement('button');
  172. saveButton.textContent = 'Save Settings';
  173. saveButton.style.padding = '10px 20px';
  174. saveButton.style.borderRadius = '5px';
  175. saveButton.style.backgroundColor = '#4CAF50';
  176. saveButton.style.color = 'white';
  177. saveButton.style.border = 'none';
  178. saveButton.style.cursor = 'pointer';
  179. saveButton.style.transition = 'background-color 0.3s ease';
  180. saveButton.style.textAlign = 'center'; // Center text
  181. saveButton.style.display = 'flex';
  182. saveButton.style.alignItems = 'center';
  183. saveButton.style.justifyContent = 'center'; // Ensure text is centered
  184. saveButton.addEventListener('click', () => {
  185. homePageSort = document.getElementById('homePageSortSelect').value;
  186. subredditSort = document.getElementById('subredditSortSelect').value;
  187.  
  188. GM_setValue("homePageSort", homePageSort);
  189. GM_setValue("subredditSort", subredditSort);
  190.  
  191. alert('Settings Saved!');
  192. settingsContainer.remove(); // Remove the settings UI after saving
  193. });
  194. saveButton.addEventListener('mouseover', () => {
  195. saveButton.style.backgroundColor = '#45a049'; // Darker green on hover
  196. });
  197. saveButton.addEventListener('mouseout', () => {
  198. saveButton.style.backgroundColor = '#4CAF50'; // Reset to original green
  199. });
  200.  
  201. // Close button
  202. const closeButton = document.createElement('button');
  203. closeButton.textContent = 'Close';
  204. closeButton.style.padding = '10px 20px';
  205. closeButton.style.borderRadius = '5px';
  206. closeButton.style.backgroundColor = '#f44336';
  207. closeButton.style.color = 'white';
  208. closeButton.style.border = 'none';
  209. closeButton.style.cursor = 'pointer';
  210. closeButton.style.transition = 'background-color 0.3s ease';
  211. closeButton.style.textAlign = 'center'; // Center text
  212. closeButton.style.display = 'flex';
  213. closeButton.style.alignItems = 'center';
  214. closeButton.style.justifyContent = 'center'; // Ensure text is centered
  215. closeButton.addEventListener('click', () => {
  216. settingsContainer.remove();
  217. });
  218. closeButton.addEventListener('mouseover', () => {
  219. closeButton.style.backgroundColor = '#e53935'; // Darker red on hover
  220. });
  221. closeButton.addEventListener('mouseout', () => {
  222. closeButton.style.backgroundColor = '#f44336'; // Reset to original red
  223. });
  224.  
  225. // Append buttons
  226. buttonsContainer.appendChild(saveButton);
  227. buttonsContainer.appendChild(closeButton);
  228. settingsContainer.appendChild(buttonsContainer);
  229.  
  230. // Append the settings container to the body
  231. document.body.appendChild(settingsContainer);
  232. }
  233.  
  234.     // Add a button to the page to open the settings
  235. function addSettingsButton() {
  236. const container = document.querySelector('.pl-lg.gap-xs.flex.items-center.justify-end');
  237.  
  238. if (!container) {
  239. console.warn("Sort Settings button: Target container not found.");
  240. return; // Exit if container is missing
  241. }
  242.  
  243. const settingsButton = document.createElement('button');
  244. settingsButton.textContent = 'Sort Settings';
  245. settingsButton.style.marginLeft = '10px'; // Add spacing
  246. settingsButton.className = 'btn btn-primary'; // Reddit-style button class
  247. settingsButton.addEventListener('click', createSettingsUI);
  248.  
  249. container.appendChild(settingsButton);
  250. }
  251.  
  252.  
  253.     // Initialize
  254.     addSettingsButton();
  255.     redirectIfNeeded();
  256.  
  257. // Function to monitor URL changes in single-page app
  258. function observeUrlChanges(callback) {
  259. lastUrl = location.href;
  260.  
  261. new MutationObserver(() => {
  262. if (location.href !== lastUrl) {
  263. lastUrl = location.href;
  264. callback();
  265. }
  266. }).observe(document, { subtree: true, childList: true });
  267.  
  268. // Also intercept history changes
  269. const pushState = history.pushState;
  270. const replaceState = history.replaceState;
  271.  
  272. history.pushState = function() {
  273. pushState.apply(this, arguments);
  274. callback();
  275. };
  276. history.replaceState = function() {
  277. replaceState.apply(this, arguments);
  278. callback();
  279. };
  280. }
  281.  
  282. // Run `redirectIfNeeded` whenever Reddit changes the page
  283. observeUrlChanges(redirectIfNeeded);
  284.  
  285. })();