├── LICENSE ├── README.md └── old-feed.user.js /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Gerrit Birkeland 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # old-github-feed 2 | 3 | Brings back GitHub's old feed. To use this, install a user script manager (like https://www.tampermonkey.net/), then go to https://github.com/Gerrit0/old-github-feed/raw/main/old-feed.user.js and it will prompt you to install. 4 | 5 | If you can't install user scripts, you can use https://github.com/dashboard-feed to view the old feed (with slightly broken styling) manually. 6 | 7 | ## Features 8 | 9 | 1. Caches following feed to localStorage to improve page load speed 10 | 2. Automatically reloads the following feed every minute like GitHub did 11 | 3. Allows quickly switching between the Following/For you feeds, and remembers which one was last active 12 | 13 | ## Change Log 14 | 15 | ### v0.17 (2024-12-07) 16 | 17 | - Also detect/remove copilot from dashboard (@cotes2020) 18 | 19 | ### v0.16 (2024-10-08) 20 | 21 | - Update favicon to use GitHub instead of Google (@xPaw) 22 | 23 | ### v0.15 (2024-10-06) 24 | 25 | - Update to handle GitHub style/layout change (@KMohZaid) 26 | 27 | ### v0.14 (2024-04-27) 28 | 29 | - Add box around non-boxed feed items for consistency (@AlexV525) 30 | 31 | ### v0.13 (2023-10-15) 32 | 33 | - Updated Following/For You styles for consistency with GitHub's UI (@Teraskull) 34 | 35 | ### v0.12 (2023-10-07) 36 | 37 | - Adjusted page insert to fix display on very narrow (mobile) screens (@Gerrit0) 38 | 39 | ### v0.11 (2023-09-22) 40 | 41 | - Update styling of feed entries to more closely match GitHub's colors (@AlexV525) 42 | 43 | ### v0.10 (2023-09-18) 44 | 45 | - Improve selectors for padding adjustment to work in more cases (@AlexV525) 46 | 47 | ### v0.9 (2023-09-17) 48 | 49 | - Reduce overly large padding between feed entries (@AlexV525) 50 | 51 | ### v0.8 (2023-09-16) 52 | 53 | - Implement toggle for old/new feed (@Gerrit0) 54 | - Fix crash when overwriting the feed due to infinite loop (@Gerrit0) 55 | 56 | ### v0.7 (2023-09-12) 57 | 58 | - SSO link is no longer removed from the page when overwriting the new feed (@Gerrit0) 59 | 60 | ### v0.6 (2023-09-07) 61 | 62 | - Feed is now full-width like it used to be, rather than oddly centered like GitHub's new design (@Gerrit0) 63 | 64 | ### v0.5 (2023-09-06) 65 | 66 | - Update feed target selectors to handle GitHub's new feed structure (@jevinskie) 67 | 68 | ### v0.4 (2022-10-29) 69 | 70 | - Fixed jitter caused by conflict with Refined GitHub addon (@Gerrit0) 71 | 72 | ### v0.3 (2022-10-29) 73 | 74 | - Fixed "Load More" button at end of feed (@Gerrit0) 75 | 76 | ### v0.2 (2022-10-29) 77 | 78 | - Improved styling on mobile/small screens (@Gerrit0) 79 | 80 | ### v0.1 (2022-10-28) 81 | 82 | - Initial release 83 | -------------------------------------------------------------------------------- /old-feed.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Old Feed 3 | // @namespace https://gerritbirkeland.com/ 4 | // @version 0.17 5 | // @updateURL https://raw.githubusercontent.com/Gerrit0/old-github-feed/main/old-feed.user.js 6 | // @downloadURL https://raw.githubusercontent.com/Gerrit0/old-github-feed/main/old-feed.user.js 7 | // @description Restores the Following/For You buttons to let you pick your feed 8 | // @author Gerrit Birkeland 9 | // @match https://github.com/ 10 | // @match https://github.com/dashboard 11 | // @icon https://github.com/favicon.ico 12 | // @grant none 13 | // ==/UserScript== 14 | 15 | (function () { 16 | "use strict"; 17 | 18 | const feedContainer = document.querySelector("#dashboard feed-container"); 19 | // Apparently if this isn't true, then an SSO popup is being shown, so don't do anything. 20 | if (!feedContainer) return; 21 | 22 | // Remove Copilot 23 | const copilot = document.querySelector(".copilotPreview__container"); 24 | if (copilot) copilot.remove(); 25 | 26 | const columnContainer = document.querySelector(".feed-content"); 27 | columnContainer.classList.remove("flex-justify-center"); 28 | columnContainer.style.maxWidth = "100vw"; 29 | const feedColumn = columnContainer.querySelector(".feed-main"); 30 | feedColumn.style.maxWidth = "100vw"; 31 | 32 | if (feedColumn.children.length != 2) { 33 | console.warn("[Old Feed] Page does not have expected structure, please report an issue"); 34 | return; 35 | } 36 | 37 | const news = document.querySelector("#dashboard .news"); 38 | 39 | const followingFeedWrapper = document.createElement("div"); 40 | followingFeedWrapper.innerHTML = localStorage.getItem("dashboardCache") || ""; 41 | news.appendChild(followingFeedWrapper); 42 | 43 | const picker = document.createElement("div"); 44 | news.insertBefore(picker, feedContainer); 45 | picker.innerHTML = ` 46 |
47 | 66 |
67 | `; 68 | 69 | const loadingIndicator = picker.querySelector(".loader"); 70 | 71 | const tabs = { following: followingFeedWrapper, forYou: feedContainer }; 72 | picker.addEventListener("click", event => { 73 | const isChildSpanClicked = event.target.tagName === "SPAN" && event.target.parentNode.classList.contains("feed-button") && event.target.parentNode.tagName === "A" 74 | let target = isChildSpanClicked ? event.target.parentNode : event.target; 75 | 76 | if (target.tagName !== "A") return; 77 | 78 | Object.entries(tabs).forEach(([name, el]) => { 79 | el.style.display = name === target.dataset.show ? "block" : "none"; 80 | }); 81 | 82 | picker.querySelectorAll(".feed-button").forEach(button => { 83 | button.classList.remove("selected"); 84 | }); 85 | target.classList.add("selected"); 86 | 87 | localStorage.setItem("dashboardActiveButton", target.dataset.show); 88 | }); 89 | picker.querySelector(`[data-show=${localStorage.getItem("dashboardActiveButton") || "following"}]`).click(); 90 | 91 | let userHasLoadedMore = false; 92 | fetchDashboard(); 93 | 94 | // GitHub updates the feed every minute unless the user has loaded more, so we'll do the same. 95 | setInterval(() => { 96 | if (userHasLoadedMore === false) { 97 | fetchDashboard(); 98 | } 99 | }, 60000); 100 | 101 | function fetchDashboard() { 102 | fetch(`https://github.com/dashboard-feed?page=1`, { headers: { "X-Requested-With": "XMLHttpRequest" } }) 103 | .then(r => r.text()) 104 | .then(html => { 105 | loadingIndicator.textContent = ""; 106 | followingFeedWrapper.innerHTML = html; 107 | followingFeedWrapper.querySelector(".ajax-pagination-btn").addEventListener("click", () => { 108 | userHasLoadedMore = true; 109 | }); 110 | // Apply pretty paddings for feeds. 111 | followingFeedWrapper.querySelector(".body .py-4").style.setProperty("padding-top", "var(--base-size-4, 4px)", "important"); 112 | followingFeedWrapper.querySelectorAll(".body .py-4").forEach((e) => { 113 | e.classList.remove("py-4"); 114 | e.classList.add("py-3"); 115 | }); 116 | // Apply the same foreground color for texts. 117 | followingFeedWrapper.querySelectorAll(".body > div > div > div.color-fg-muted").forEach((e) => { 118 | if (!e.nextElementSibling) { 119 | e.querySelector("div").classList.add("color-fg-default"); 120 | } 121 | }); 122 | // Apply box for non-boxed items. 123 | followingFeedWrapper.querySelectorAll(".body > .d-flex > .d-flex > div > div[class=color-fg-default]").forEach((e) => { 124 | e.classList.add("Box"); 125 | e.classList.add("p-3"); 126 | e.classList.add("mt-2"); 127 | }); 128 | // Apply the same colors for feeds. 129 | followingFeedWrapper.querySelectorAll("div.Box.color-bg-overlay").forEach((e) => { 130 | e.classList.remove("color-bg-overlay"); 131 | e.classList.remove("color-shadow-medium"); 132 | e.classList.add("feed-item-content"); 133 | e.classList.add("border"); 134 | e.classList.add("color-border-default"); 135 | e.classList.add("color-shadow-small"); 136 | e.classList.add("rounded-2"); 137 | const markdownBody = e.querySelector("div.color-fg-muted.comment-body.markdown-body"); 138 | if (markdownBody) { 139 | markdownBody.classList.remove("color-fg-muted"); 140 | } 141 | }); 142 | // Saving the edited content for the cache. 143 | localStorage.setItem("dashboardCache", followingFeedWrapper.innerHTML); 144 | }); 145 | } 146 | })(); 147 | --------------------------------------------------------------------------------