Get Random Github Issue

Adds a button to get random github issues from the repo you're on, respects your filter options

  1. // ==UserScript==
  2. // @name Get Random Github Issue
  3. // @namespace https://github.com/veryCrunchy/random-issue-user-script
  4. // @version 1.0.0
  5. // @description Adds a button to get random github issues from the repo you're on, respects your filter options
  6. // @author veryCrunchy
  7. // @contributors joerkig
  8. // @match https://github.com/*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=github.com
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. "use strict";
  15. (() => {
  16. const oldPushState = history.pushState;
  17. history.pushState = function pushState() {
  18. const ret = oldPushState.apply(this, arguments);
  19. window.dispatchEvent(new Event("pushstate"));
  20. window.dispatchEvent(new Event("locationchange"));
  21. return ret;
  22. };
  23.  
  24. const oldReplaceState = history.replaceState;
  25. history.replaceState = function replaceState() {
  26. const ret = oldReplaceState.apply(this, arguments);
  27. window.dispatchEvent(new Event("replacestate"));
  28. window.dispatchEvent(new Event("locationchange"));
  29. return ret;
  30. };
  31.  
  32. window.addEventListener("popstate", () => {
  33. window.dispatchEvent(new Event("locationchange"));
  34. });
  35. })();
  36.  
  37. window.addEventListener("locationchange", function () {
  38. const { pathname, hash } = document.location;
  39. const searchParams = new URLSearchParams(window.location.search);
  40. function getRandomNumber(max) {
  41. return Math.floor(Math.random() * Number(max));
  42. }
  43.  
  44. if (hash === "#randomPage") {
  45. randomPage();
  46. }
  47. if (hash.startsWith("#randomIssue")) {
  48. randomIssue();
  49. }
  50.  
  51. function randomIssue() {
  52. const randomIssue = getRandomNumber(
  53. document.querySelectorAll("div[id^='issue_']").length
  54. );
  55. window.location.href =
  56. document
  57. .querySelectorAll("div[id^='issue_']")
  58. [randomIssue].querySelector("div > a").href +
  59. "?" +
  60. searchParams;
  61. }
  62. function randomPage() {
  63. console.log(
  64. document.querySelector(".next_page")?.previousSibling?.previousSibling
  65. ?.text
  66. );
  67. const randomNumber = getRandomNumber(
  68. document.querySelector(".next_page")?.previousSibling?.previousSibling
  69. ?.text || 1
  70. );
  71. searchParams.set("page", randomNumber + 1);
  72. window.location.href = pathname + "?" + searchParams + "#randomIssue";
  73. }
  74. const newButton = document.createElement("button");
  75. const defaultButton = document.querySelector(".Button--primary");
  76. newButton.textContent = "Random issue";
  77. newButton.id = "randomIssueButton";
  78. newButton.classList.add(
  79. "Button--secondary",
  80. "Button--medium",
  81. "subnav-item"
  82. );
  83. if (!document.querySelector("#randomIssueButton")) {
  84. if (pathname.match(/\/issues\/?$/)) {
  85. newButton.onclick = function () {
  86. randomPage();
  87. };
  88. document
  89. .querySelector(".Button--primary")
  90. .parentElement?.prepend(newButton);
  91. document.querySelector(".Button--primary").classList.remove("Button");
  92. document.querySelector(".Button--primary").classList.add("subnav-item");
  93. } else if (pathname.match(/\/issues\/(\d+)/)) {
  94. newButton.onclick = function () {
  95. window.location.href =
  96. pathname.replace(/\/issues\/(\d+)/, "/issues") +
  97. "?" +
  98. searchParams +
  99. "#randomPage";
  100. };
  101. defaultButton.parentElement.classList.remove("gap-1");
  102. defaultButton.parentElement?.prepend(newButton);
  103. defaultButton.classList.remove("Button", "Button--small");
  104. defaultButton.classList.add("Button--medium", "subnav-item");
  105. defaultButton.nextElementSibling.remove();
  106. }
  107. }
  108. });
  109. })();