Discord Hide Channel List Button

Hides the channel list at the press of a button

  1. // ==UserScript==
  2. // @name Discord Hide Channel List Button
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.9
  5. // @description Hides the channel list at the press of a button
  6. // @author 20kdc
  7. // @match https://discordapp.com/*
  8. // @match https://discord.com/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. // I release this user-script into the public domain.
  13.  
  14. // Enables the new button location.
  15. var buttonLocation0p6 = true;
  16. var buttonProperWrap = buttonLocation0p6;
  17.  
  18. // Since iterating through the entire DOM would be performance suicide,
  19. // let's try to detect classes in ANY OTHER WAY.
  20. var dragonequus;
  21. dragonequus = {
  22. version: 5.3,
  23. getAllClassesLen: 0,
  24. getAllClassesCache: [],
  25. getAllClasses: function () {
  26. var sheets = document.styleSheets;
  27. if (sheets.length == dragonequus.getAllClassesLen) {
  28. return dragonequus.getAllClassesCache;
  29. }
  30. var workspace = [];
  31. var seen = {};
  32. for (var k = 0; k < sheets.length; k++) {
  33. var sheet = sheets[k];
  34. for (var k2 = 0; k2 < sheet.cssRules.length; k2++) {
  35. var rule = sheet.cssRules[k2];
  36. if (rule.type == CSSRule.STYLE_RULE) {
  37. // .A:I .B:I, .A .B
  38. var majors = rule.selectorText.split(",");
  39. for (var k3 = 0; k3 < majors.length; k3++) {
  40. var minors = majors[k3].split(" ");
  41. for (var k4 = 0; k4 < minors.length; k4++) {
  42. // Minor starts off as say .A:B
  43. var minor = minors[k4];
  44. // Must be class
  45. if (!minor.startsWith("."))
  46. continue;
  47. // Cut off any : and remove .
  48. var selectorBreak = minor.indexOf(":");
  49. if (selectorBreak != -1) {
  50. minor = minor.substring(1, selectorBreak);
  51. } else {
  52. minor = minor.substring(1);
  53. }
  54. if (seen[minor])
  55. continue;
  56. seen[minor] = true;
  57. workspace.push(minor);
  58. }
  59. }
  60. }
  61. }
  62. }
  63. dragonequus.getAllClassesLen = sheets.length;
  64. dragonequus.getAllClassesCache = workspace;
  65. return workspace;
  66. },
  67. isValidDC: function (obfuscated, real) {
  68. if (!(obfuscated.startsWith(real + "-") || obfuscated.startsWith(real + "_")))
  69. return false;
  70. if (obfuscated.length != real.length + 7)
  71. return false;
  72. return true;
  73. },
  74. findAllByDiscordClass: function (name) {
  75. var q = [];
  76. var q2 = document.querySelectorAll("." + name);
  77. for (var k2 = 0; k2 < q2.length; k2++)
  78. q.push(q2[k2]);
  79. var classes = dragonequus.getAllClasses();
  80. for (var k in classes) {
  81. var n = classes[k];
  82. if (dragonequus.isValidDC(n, name)) {
  83. q2 = document.querySelectorAll("." + n);
  84. for (var k2 = 0; k2 < q2.length; k2++)
  85. q.push(q2[k2]);
  86. }
  87. }
  88. return q;
  89. },
  90. findByDiscordClass: function (name) {
  91. var all = dragonequus.findAllByDiscordClass(name);
  92. if (all.length > 0)
  93. return all[0];
  94. return null;
  95. },
  96. toDiscordClasses: function (name) {
  97. var classes = dragonequus.getAllClasses();
  98. var all = [];
  99. for (var k in classes) {
  100. var n = classes[k];
  101. if (dragonequus.isValidDC(n, name))
  102. all.push(n);
  103. }
  104. all.push(name);
  105. return all;
  106. },
  107. toDiscordClass: function (name) {
  108. return dragonequus.toDiscordClasses(name)[0];
  109. },
  110. injectCSSRulesNow: function (rules) {
  111. var styleElm = document.createElement('style');
  112. console.log("dragonequus CSS:", rules);
  113. document.body.appendChild(styleElm);
  114. for (var i = 0; i < rules.length; i++)
  115. styleElm.sheet.insertRule(rules[i], 0);
  116. },
  117. injectCSSRules: function (getRules) {
  118. setTimeout(function () {
  119. dragonequus.injectCSSRulesNow(getRules());
  120. }, 5000);
  121. },
  122. injectCSSForClassScript: function (clazz, css) {
  123. dragonequus.injectCSSRules(function () {
  124. var classes = dragonequus.toDiscordClasses(clazz);
  125. var total = [];
  126. for (var i = 0; i < classes.length; i++) {
  127. // This is stupid.
  128. // This is really, really stupid.
  129. total.push(".visual-refresh ." + classes[i] + " { " + css + " }");
  130. total.push("." + classes[i] + " { " + css + " }");
  131. }
  132. return total;
  133. });
  134. },
  135. };
  136.  
  137. var findParent, performAppend;
  138. if (buttonLocation0p6) {
  139. // New behavior as per given feedback.
  140. findParent = function () {
  141. const vChat = dragonequus.findByDiscordClass("guildSeparator");
  142. if (!vChat)
  143. return null;
  144. return vChat.parentNode;
  145. };
  146. performAppend = function (a, b) {
  147.  
  148. a.insertBefore(b, a.childNodes[1]);
  149. };
  150. } else {
  151. // Older behavior that may be better for some people.
  152. findParent = function () {
  153. const vChat = dragonequus.findByDiscordClass("chat");
  154. if (!vChat)
  155. return null;
  156. return vChat.firstChild.firstChild.lastChild;
  157. };
  158. performAppend = function (a, b) {
  159. a.appendChild(b);
  160. };
  161. }
  162.  
  163. var mainFunc;
  164. var lastTryParent;
  165. mainFunc = function() {
  166. 'use strict';
  167. // Toolbar instance tends to change
  168. setTimeout(mainFunc, 5000);
  169. const bParent = findParent();
  170. if (!bParent)
  171. return;
  172. if (lastTryParent == bParent)
  173. return;
  174. lastTryParent = bParent;
  175. // Create & append button
  176. const d = document.createElement("img");
  177. d.draggable = false;
  178. d.src = "/assets/a860a4e9c04e5cc2c8c48ebf51f7ed46.svg";
  179. // Unscalable, but Discord does it too
  180. d.width = 24;
  181. d.height = 24;
  182.  
  183. var button = d;
  184. if (buttonProperWrap) {
  185. button = document.createElement("div");
  186. button.type = "div";
  187. // Make it a div, listItem & clickable, which makes it similar to other Discord buttons
  188. button.className = dragonequus.toDiscordClass("listItem") + " " + dragonequus.toDiscordClass("clickable");
  189. button.appendChild(d);
  190. }
  191.  
  192. performAppend(bParent, button);
  193.  
  194. var toggleState = true;
  195. button.addEventListener("click", () => {
  196. const v2 = dragonequus.findByDiscordClass("sidebarList");
  197. if (!v2)
  198. return;
  199. toggleState = !toggleState;
  200. if (toggleState) {
  201. v2.style.display = "inherit";
  202. } else {
  203. v2.style.display = "none";
  204. }
  205. });
  206. };
  207. mainFunc();