Last active
January 8, 2020 21:29
-
-
Save csvoss/b144ebd67fb3dc8f519722763d6a2cd8 to your computer and use it in GitHub Desktop.
csvoss's GitHub Homepage++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name GitHub Homepage ++ | |
// @namespace | |
// @version 0.1 | |
// @description Inject any PRs with reviews requested from me & any PRs waiting on me into the GitHub main page | |
// @author Chelsea Voss | |
// @match https://github.com/ | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
// Edit this variable! | |
const REPOS_YOU_CARE_ABOUT = [ | |
"/YourOrg/yourrepo", | |
]; | |
const username = document.getElementsByClassName("header-nav-current-user").item(0).getElementsByTagName("strong").item(0).innerHTML; | |
const dash = document.getElementById("dashboard"); | |
const parser = new DOMParser(); | |
function getDOMFromPath(path) { | |
const xmlhttp=new XMLHttpRequest(); | |
xmlhttp.open("GET", path, false); | |
xmlhttp.send(); | |
return parser.parseFromString(xmlhttp.responseText, "text/html"); | |
} | |
function prependSpace(place) { | |
place.prepend(parser.parseFromString("<br/>", "text/html").firstChild); | |
} | |
function prependHeader(place, headerString, headerType) { | |
place.prepend(parser.parseFromString("<" + headerType + ">" + headerString + "</" + headerType + ">", "text/html").firstChild); | |
} | |
function prependSlot(place, id) { | |
place.prepend(parser.parseFromString("<div id=\"" + id + "\"></div>", "text/html").firstChild); | |
return document.getElementById(id); | |
} | |
function addGenericSearch(id, header, path) { | |
prependSpace(dash); | |
const slot = prependSlot(dash, id); | |
new Promise(function(resolve, reject) { | |
const searchPage = getDOMFromPath(path); | |
resolve(searchPage.getElementById("issue_search_results")); | |
}).then(function(searchResults) { | |
if (searchResults) { | |
slot.prepend(searchResults); | |
prependHeader(slot, header, "h3"); | |
} else { | |
slot.prepend(header + ": none!"); | |
} | |
}); | |
} | |
function addPullRequestSearch(id, header, path, showStatus, showButton) { | |
prependSpace(dash); | |
const slot = prependSlot(dash, id); | |
function fetchList() { | |
const searchPage = getDOMFromPath(path); | |
return searchPage.getElementById("issue_search_results"); | |
} | |
async function fillSlot() { | |
const searchResults = await fetchList(); | |
if (searchResults) { | |
const pullRequests = searchResults.getElementsByClassName("issue-list-item"); | |
for (let i=0; i<pullRequests.length; i+=0) { | |
const oldLength = pullRequests.length; | |
const searchResult = pullRequests.item(i); | |
if (showStatus || showButton) { | |
const subSlot = prependSlot(slot, id + i); | |
new Promise(function(resolve, reject) { | |
const pullRequestPath = searchResult.getElementsByTagName("h3").item(0).getElementsByTagName("a").item(0).getAttribute("href"); | |
resolve(getDOMFromPath(pullRequestPath)); | |
}).then(function(pullRequestPage) { | |
const changesSinceLastViewed = pullRequestPage.getElementsByClassName("discussion-item-changes-marker").item(0); | |
if (showButton) { | |
const reviewRequestButton = pullRequestPage.getElementsByClassName("issues-listing").item(0).getElementsByClassName("flash-warn").item(0); | |
subSlot.prepend(reviewRequestButton); | |
} | |
if (showStatus) { | |
const pullRequestStatus = pullRequestPage.getElementsByClassName("branch-action-body").item(0).getElementsByClassName("branch-action-item").item(0); | |
subSlot.prepend(pullRequestStatus); | |
} | |
if (changesSinceLastViewed !== null) { | |
subSlot.prepend(changesSinceLastViewed.getElementsByClassName("discussion-item-header").item(0)); | |
} | |
}); | |
} | |
slot.prepend(searchResult); | |
// i+=0 in the loop because weirdly, newLength goes down. I'm not sure why. | |
// Hedge against both of the possible behaviors while not infinite looping. | |
const newLength = pullRequests.length; | |
if (newLength === oldLength) { | |
i += 1; | |
} | |
} | |
prependHeader(slot, header, "h3"); | |
} else { | |
slot.prepend(header + ": none!"); | |
} | |
} | |
fillSlot(); | |
} | |
function addRecentlyPushedBranches(id, header) { | |
prependSpace(dash); | |
let prependedHeader = false; | |
REPOS_YOU_CARE_ABOUT.forEach(function(path) { | |
const slot = prependSlot(dash, id + path); | |
const headerSlot = prependSlot(dash, id + "header"); | |
function fetchList() { | |
const repositoryPage = getDOMFromPath(path + "/show_partial?partial=tree%2Frecently_touched_branches_list"); | |
return repositoryPage.getElementsByClassName("RecentBranches").item(0); | |
} | |
async function fillSlot() { | |
const newBranchAlert = await fetchList(); | |
if (newBranchAlert) { | |
slot.prepend(newBranchAlert); | |
if (!prependedHeader) { | |
prependSpace(slot); | |
prependHeader(headerSlot, header, "h3"); | |
prependedHeader = true; | |
} | |
} | |
} | |
fillSlot(); | |
}); | |
} | |
prependSpace(dash); | |
prependSpace(dash); | |
addPullRequestSearch( | |
"prsopenednotreviewed", | |
"PRs you opened that aren't yet reviewed", | |
"/search?utf8=%E2%9C%93&q=is%3Aopen+is%3Apr+author%3A" + username + "+review%3Anone", | |
true, false | |
); | |
prependHeader(dash, "Waiting", "h1"); | |
addGenericSearch( | |
"issuesassignedto", | |
"Issues you are assigned to", | |
"/search?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue+assignee%3A" + username + "+" | |
); | |
addPullRequestSearch( | |
"prswaitingonchanges", | |
"PRs waiting on your changes", | |
"/search?utf8=✓&q=is%3Aopen+is%3Apr+review%3Achanges-requested+author%3A" + username + "+", | |
true, false | |
); | |
addPullRequestSearch( | |
"prswaitingonship", | |
"PRs waiting for you to ship them", | |
"/search?utf8=✓&q=is%3Aopen+is%3Apr+review%3Aapproved+author%3A" + username + "+", | |
true, false | |
); | |
addPullRequestSearch( | |
"prswaitingonreview", | |
"PRs waiting on your review", | |
"/search?utf8=✓&q=is%3Aopen+is%3Apr+review-requested%3A" + username + "+", | |
false, true | |
); | |
addRecentlyPushedBranches( | |
"recentlypushedbranches", | |
"Your recently pushed branches" | |
); | |
prependHeader(dash, "Ready", "h1"); | |
window.scrollTo(0, 0); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment