ViewOnYPMemoryHole

An add-on for ViewOnYP that adds support for Memory Hole.

  1. // ==UserScript==
  2. // @name ViewOnYPMemoryHole
  3. // @name:de ViewOnYPMemoryHole
  4. // @name:en ViewOnYPMemoryHole
  5. // @namespace sun/userscripts
  6. // @version 1.0.18
  7. // @description An add-on for ViewOnYP that adds support for Memory Hole.
  8. // @description:de Ein Add-on für ViewOnYP, das Unterstützung für Memory Hole hinzufügt.
  9. // @description:en An add-on for ViewOnYP that adds support for Memory Hole.
  10. // @compatible chrome
  11. // @compatible edge
  12. // @compatible firefox
  13. // @compatible opera
  14. // @compatible safari
  15. // @homepageURL https://forgejo.sny.sh/sun/userscripts
  16. // @supportURL https://forgejo.sny.sh/sun/userscripts/issues
  17. // @contributionURL https://liberapay.com/sun
  18. // @contributionAmount €1.00
  19. // @author Sunny <sunny@sny.sh>
  20. // @include *://www.patreon.com/*
  21. // @match *://www.patreon.com/*
  22. // @connect api.memoryhole.cc
  23. // @run-at document-end
  24. // @inject-into auto
  25. // @grant GM.deleteValue
  26. // @grant GM_deleteValue
  27. // @grant GM.getValue
  28. // @grant GM_getValue
  29. // @grant GM.registerMenuCommand
  30. // @grant GM_registerMenuCommand
  31. // @grant GM.setValue
  32. // @grant GM_setValue
  33. // @grant GM.xmlHttpRequest
  34. // @grant GM_xmlhttpRequest
  35. // @noframes
  36. // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
  37. // @icon https://forgejo.sny.sh/sun/userscripts/raw/branch/main/icons/ViewOnYPMemoryHole.png
  38. // @copyright 2022-present, Sunny (https://sny.sh/)
  39. // @license Hippocratic License; https://forgejo.sny.sh/sun/userscripts/src/branch/main/LICENSE.md
  40. // ==/UserScript==
  41.  
  42. (async () => {
  43. if (!(await GM.getValue("cache2"))) await GM.setValue("cache2", {});
  44. const cache = await GM.getValue("cache2");
  45.  
  46. GM.registerMenuCommand("Clear cache", () => {
  47. GM.deleteValue("cache2").then(alert("Cache cleared successfully."));
  48. });
  49.  
  50. window.addEventListener("load", () => {
  51. const campaign = unsafeWindow.patreon.bootstrap.campaign.data.id;
  52.  
  53. if (cache[campaign]) {
  54. show(cache[campaign]);
  55. } else {
  56. get(campaign);
  57. }
  58. });
  59.  
  60. function get(campaign) {
  61. GM.xmlHttpRequest({
  62. url: "https://api.memoryhole.cc/graphql",
  63. method: "POST",
  64. headers: {
  65. "Content-Type": "application/json",
  66. },
  67. data: JSON.stringify({
  68. query: `query { getPatreonByCampaignId (campaignId: ${campaign}) { creator { id } } }`,
  69. }),
  70. onload: (response) => {
  71. const id = JSON.parse(response.responseText).data
  72. ?.getPatreonByCampaignId?.creator?.id;
  73.  
  74. if (id) show(id);
  75. },
  76. });
  77. }
  78.  
  79. function show(id) {
  80. if (document.getElementById("voyp")) {
  81. insert(id);
  82. } else {
  83. const observer = new MutationObserver(() => {
  84. if (document.getElementById("voyp")) insert(id);
  85. });
  86. observer.observe(document.body, { childList: true });
  87. }
  88.  
  89. if (!cache[campaign]) cache[campaign] = id;
  90. GM.setValue("cache2", cache);
  91. }
  92.  
  93. function insert(id) {
  94. document.getElementById("voyp").getElementsByTagName("span")[0]?.remove();
  95.  
  96. document
  97. .getElementById("voyp")
  98. .insertAdjacentHTML(
  99. "beforeend",
  100. `<br><b>Memory Hole:</b> <a href="https://memoryhole.cc/creator/${id}">https://memoryhole.cc/creator/${id}</a>`,
  101. );
  102.  
  103. insert = () => {};
  104. }
  105. })();