Hides the channel list at the press of a button
// ==UserScript==
// @name Discord Hide Channel List Button
// @namespace http://tampermonkey.net/
// @version 0.9
// @description Hides the channel list at the press of a button
// @author 20kdc
// @match https://discordapp.com/*
// @match https://discord.com/*
// @grant none
// ==/UserScript==
// I release this user-script into the public domain.
// Enables the new button location.
var buttonLocation0p6 = true;
var buttonProperWrap = buttonLocation0p6;
// Since iterating through the entire DOM would be performance suicide,
// let's try to detect classes in ANY OTHER WAY.
var dragonequus;
dragonequus = {
version: 5.3,
getAllClassesLen: 0,
getAllClassesCache: [],
getAllClasses: function () {
var sheets = document.styleSheets;
if (sheets.length == dragonequus.getAllClassesLen) {
return dragonequus.getAllClassesCache;
}
var workspace = [];
var seen = {};
for (var k = 0; k < sheets.length; k++) {
var sheet = sheets[k];
for (var k2 = 0; k2 < sheet.cssRules.length; k2++) {
var rule = sheet.cssRules[k2];
if (rule.type == CSSRule.STYLE_RULE) {
// .A:I .B:I, .A .B
var majors = rule.selectorText.split(",");
for (var k3 = 0; k3 < majors.length; k3++) {
var minors = majors[k3].split(" ");
for (var k4 = 0; k4 < minors.length; k4++) {
// Minor starts off as say .A:B
var minor = minors[k4];
// Must be class
if (!minor.startsWith("."))
continue;
// Cut off any : and remove .
var selectorBreak = minor.indexOf(":");
if (selectorBreak != -1) {
minor = minor.substring(1, selectorBreak);
} else {
minor = minor.substring(1);
}
if (seen[minor])
continue;
seen[minor] = true;
workspace.push(minor);
}
}
}
}
}
dragonequus.getAllClassesLen = sheets.length;
dragonequus.getAllClassesCache = workspace;
return workspace;
},
isValidDC: function (obfuscated, real) {
if (!(obfuscated.startsWith(real + "-") || obfuscated.startsWith(real + "_")))
return false;
if (obfuscated.length != real.length + 7)
return false;
return true;
},
findAllByDiscordClass: function (name) {
var q = [];
var q2 = document.querySelectorAll("." + name);
for (var k2 = 0; k2 < q2.length; k2++)
q.push(q2[k2]);
var classes = dragonequus.getAllClasses();
for (var k in classes) {
var n = classes[k];
if (dragonequus.isValidDC(n, name)) {
q2 = document.querySelectorAll("." + n);
for (var k2 = 0; k2 < q2.length; k2++)
q.push(q2[k2]);
}
}
return q;
},
findByDiscordClass: function (name) {
var all = dragonequus.findAllByDiscordClass(name);
if (all.length > 0)
return all[0];
return null;
},
toDiscordClasses: function (name) {
var classes = dragonequus.getAllClasses();
var all = [];
for (var k in classes) {
var n = classes[k];
if (dragonequus.isValidDC(n, name))
all.push(n);
}
all.push(name);
return all;
},
toDiscordClass: function (name) {
return dragonequus.toDiscordClasses(name)[0];
},
injectCSSRulesNow: function (rules) {
var styleElm = document.createElement('style');
console.log("dragonequus CSS:", rules);
document.body.appendChild(styleElm);
for (var i = 0; i < rules.length; i++)
styleElm.sheet.insertRule(rules[i], 0);
},
injectCSSRules: function (getRules) {
setTimeout(function () {
dragonequus.injectCSSRulesNow(getRules());
}, 5000);
},
injectCSSForClassScript: function (clazz, css) {
dragonequus.injectCSSRules(function () {
var classes = dragonequus.toDiscordClasses(clazz);
var total = [];
for (var i = 0; i < classes.length; i++) {
// This is stupid.
// This is really, really stupid.
total.push(".visual-refresh ." + classes[i] + " { " + css + " }");
total.push("." + classes[i] + " { " + css + " }");
}
return total;
});
},
};
var findParent, performAppend;
if (buttonLocation0p6) {
// New behavior as per given feedback.
findParent = function () {
const vChat = dragonequus.findByDiscordClass("guildSeparator");
if (!vChat)
return null;
return vChat.parentNode;
};
performAppend = function (a, b) {
a.insertBefore(b, a.childNodes[1]);
};
} else {
// Older behavior that may be better for some people.
findParent = function () {
const vChat = dragonequus.findByDiscordClass("chat");
if (!vChat)
return null;
return vChat.firstChild.firstChild.lastChild;
};
performAppend = function (a, b) {
a.appendChild(b);
};
}
var mainFunc;
var lastTryParent;
mainFunc = function() {
'use strict';
// Toolbar instance tends to change
setTimeout(mainFunc, 5000);
const bParent = findParent();
if (!bParent)
return;
if (lastTryParent == bParent)
return;
lastTryParent = bParent;
// Create & append button
const d = document.createElement("img");
d.draggable = false;
d.src = "/assets/a860a4e9c04e5cc2c8c48ebf51f7ed46.svg";
// Unscalable, but Discord does it too
d.width = 24;
d.height = 24;
var button = d;
if (buttonProperWrap) {
button = document.createElement("div");
button.type = "div";
// Make it a div, listItem & clickable, which makes it similar to other Discord buttons
button.className = dragonequus.toDiscordClass("listItem") + " " + dragonequus.toDiscordClass("clickable");
button.appendChild(d);
}
performAppend(bParent, button);
var toggleState = true;
button.addEventListener("click", () => {
const v2 = dragonequus.findByDiscordClass("sidebarList");
if (!v2)
return;
toggleState = !toggleState;
if (toggleState) {
v2.style.display = "inherit";
} else {
v2.style.display = "none";
}
});
};
mainFunc();