您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Makes the channel list a panel you can toggle
// ==UserScript== // @name QOAL/discord/channelPanel // @namespace QOAL/discord/channelPanel // @description Makes the channel list a panel you can toggle // @author QOAL // @version 1.10 // @grant GM.setValue // @grant GM.getValue // @match https://discord.com/* // @run-at document-end // @license GPLv3 // ==/UserScript== /* Adds a # button to the toolbar (Top right), click it will toggle the visibility of the Channel list pane. Based on my QOAL/discord/dontPingReplies script */ (function(){ 'use strict'; const toolbarSelector = '.toolbar__88c63'; const channelsSideBarSelector = '.sidebar_ded4b5'; const channelIconSVGSelector = '.icon__4cb88'; const selectedIconClass = 'selected_be2668'; const iconWrapper = "iconWrapper_af9215"; const clickable = "clickable_d23a1a"; const clickEvent = document.createEvent('Events'); clickEvent.initEvent('click', true, false); // Discord has an connecting screen should you or it have network issues // The url and page title doesn't change during this // I think it's a good idea to listen for browser events, and start mutation observers const networkStatusChange = (e) => { findUI(); } window.addEventListener('online', networkStatusChange); //window.addEventListener('offline', networkStatusChange); let lastLocation = window.location; const pageChange = () => { if (document.querySelector(toolbarSelector)) { // Recheck if we have a server UI, if not start the mutation handler for it findUI(); } } new MutationObserver(pageChange).observe( document.head.querySelector('title'), { subtree: true, characterData: true, childList: true } ); let toolbarEle; let channelsPane; let channelsIcon; let toolbarButton; let initiallyActive = true; let findUIObserver; let findUITimer; const findUI = () => { stopUIObserver(); const tmpCont = document.querySelector(toolbarSelector); if (tmpCont) { toolbarEle = tmpCont; doUIStuff(); return; } findUIObserver = new MutationObserver(checkForUI); findUIObserver.observe( document.body/*getElementById("app-mount")*/, { subtree: true, childList: true } ); findUITimer = setTimeout(function() { // Give up waiting findUIObserver.disconnect(); }, 10 * 1000); } const stopUIObserver = () => { if (findUIObserver) { findUIObserver.disconnect(); findUIObserver = null; } } const checkForUI = () => { const tmpCont = document.querySelector(toolbarSelector); if (!tmpCont) { return; } toolbarEle = tmpCont; stopUIObserver(); doUIStuff(); } const doUIStuff = async () => { // What do we do here? // Get the current channel pane visibility and set the visibility of it. // Add, if needed, the button to the toolbar channelsPane = document.querySelector(channelsSideBarSelector); if (!channelsIcon) { // Try and find a text channel icon, if we can't find one use the first icon we can. channelsIcon = document.querySelector(channelIconSVGSelector).cloneNode(true) } if (!initiallyActive) { channelsPane.style.width = '0'; } if (!toolbarButton) { const hideMembersBtn = document.querySelector(toolbarSelector + ` [aria-label="Hide Member List"]`); if (hideMembersBtn) { toolbarButton = hideMembersBtn.cloneNode(); toolbarButton.replaceChildren(channelsIcon.cloneNode(true)); toolbarButton.setAttribute('aria-label', 'Toggle Server Channels'); } else { toolbarButton = document.createElement('div'); toolbarButton.append(channelsIcon.cloneNode(true)); toolbarButton.setAttribute('class', `${iconWrapper} ${clickable}` + (initiallyActive ? ' ' + selectedIconClass : '')); toolbarButton.setAttribute('role', 'button'); toolbarButton.setAttribute('aria-label', 'Toggle Server Channels'); toolbarButton.setAttribute('tabindex', '0'); } toolbarEle.prepend(toolbarButton) toolbarButton.addEventListener('click', toggleChannelPane) } else if (toolbarButton.parentNode !== toolbarEle) { toolbarEle.prepend(toolbarButton) } } const toggleChannelPane = () => { const isActive = toolbarButton.classList.contains(selectedIconClass); toolbarButton.classList.toggle(selectedIconClass); channelsPane.style.width = isActive ? '0' : ''; GM.setValue("showChannelPane", !isActive); } GM.getValue("showChannelPane", true).then(rVal => { initiallyActive = rVal; }) findUI(); })()