Discord Hide Channel List Button

Hides the channel list at the press of a button

// ==UserScript==
// @name         Discord Hide Channel List Button
// @namespace    http://tampermonkey.net/
// @version      0.8.3
// @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.1,
    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());
        }, 1000);
    },
    injectCSSForClassScript: function (clazz, css) {
        dragonequus.injectCSSRules(function () {
            var classes = dragonequus.toDiscordClasses(clazz);
            var total = [];
            for (var i = 0; i < classes.length; i++)
                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 v2a = dragonequus.findByDiscordClass("chat");
        if (!v2a)
            return;
        const v2 = v2a.parentNode.firstChild;
        toggleState = !toggleState;
        if (toggleState) {
            v2.style.display = "inherit";
        } else {
            v2.style.display = "none";
        }
    });
};
mainFunc();