diff --git a/README.md b/README.md index b68469e..1f7df1f 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ A collection of BetterDiscord plugins to tweak and improve my user experience. +Looking for support or to discuss changes to one of my plugins? Feel free to join my [Discord server](https://discord.gg/6eTbbrXes8)! + ## Installation To install a plugin, you must first ensure [BetterDiscord](#) is installed on your system. @@ -24,4 +26,4 @@ white. These changes are mostly to improve readability, and I think they look go > Please be aware, there are still a few outstanding issues with this plugin. > You might need to reload the plugin if you create a new folder. -![Demo gif](/assets/better-folders.gif) \ No newline at end of file +![Demo gif](https://github.com/webcrawls/discord/blob/master/assets/better-folders.gif?raw=true) \ No newline at end of file diff --git a/pretty-folders.plugin.js b/pretty-folders.plugin.js index 627562b..d57341e 100644 --- a/pretty-folders.plugin.js +++ b/pretty-folders.plugin.js @@ -1,73 +1,120 @@ /** * @name PrettyFolders * @author webcrawls - * @authorLink https://github.com/webcrawls + * @version 1.2.3 * @description Applies a folder's icon colour to its background when expanded. - * @version 1.2.2 * @source https://github.com/webcrawls/discord + * @invite 6eTbbrXes8 + * @authorId 1057917670781095977 + * @authorLink https://github.com/webcrawls + * @website https://github.com/webcrawls/discord * @updateUrl https://raw.githubusercontent.com/webcrawls/discord/master/pretty-folders.plugin.js */ module.exports = class MyPlugin { - start = () => Array.from(document.getElementsByClassName(FOLDER_WRAPPER)).forEach(attachFolder) - stop = () => Array.from(document.getElementsByClassName(FOLDER_WRAPPER)).forEach(detachFolder) + start = () => Array.from(document.querySelectorAll(FOLDER_WRAPPER)).forEach(attachFolder) + stop = () => Array.from(document.querySelectorAll(FOLDER_WRAPPER)).forEach(detachFolder) }; // Discord HTML classname constants -const FOLDER_WRAPPER = "wrapper__832f2" -const FOLDER_COLLAPSED = "collapsed__98ad5" -const FOLDER_ICON_WRAPPER = "expandedFolderIconWrapper__324c1" -const EXPANDED_FOLDER_BACKGROUND = "expandedFolderBackground_b1385f" +const FOLDER_WRAPPER = "div[aria-label='Servers'] > div[class^='wrapper__']" +const FOLDER_COLLAPSED = "span[class^='expandedFolderBackground'][class^='collapsed__']" +const FOLDER_ICON_WRAPPER = "div[class^='expandedFolderIconWrapper']" +const EXPANDED_FOLDER_BACKGROUND = "span[class^='expandedFolderBackground']" + +/** + * Returns the folder icon element, if any, within the provided element. + * + * @param el an HTMLElement + * @returns an HTMLElement or null + */ +const folderIcon = (el) => "querySelector" in el ? el.querySelector(FOLDER_ICON_WRAPPER) : null -// Utility methods to get key elements -// Not exactly happy with how these, but hey, they're one-liners :D -const folderIcon = (el) => "getElementsByClassName" in el ? el.getElementsByClassName(FOLDER_ICON_WRAPPER)[0] : undefined -const folderBackground = (el) => "getElementsByClassName" in el ? el.getElementsByClassName(EXPANDED_FOLDER_BACKGROUND)[0] : undefined +/** + * Returns the folder background element, if any, within the provided element. + * + * @param el an HTMLElement + * @returns an HTMLElement or null + */ +const folderBackground = (el) => "querySelector" in el ? el.querySelector(EXPANDED_FOLDER_BACKGROUND) : null -// State. MutationObservers are thrown in here +/** + * State that maps a root folder HTML element to it's MutationObserver. + * + * @type {Object.} + */ const observers = {} -// A bit of a hack. "#updateFolder" reads this string when updating a folder. -// If the icon's SVG color is one of these, i.e. "white", which it will be after we make it look better, -// the function will not make any modifications. +/** + * Used for a dumb hack. + * + * If a folder icon's SVG is a colour in this array, the colour won't be changed by the plugin. + * Currently, we change the folder icon's colour to 'white'. So we're telling the plugin to skip any changes that + * we've already made. + * + * @type {string[]} + */ const ignoredColors = [ "white" ] +/** + * Creates a MutationObserver that listens for changes to a folder wrapper. + * + * @param folderElement the folder wrapper element + */ const attachFolder = (folderElement) => { const observer = new MutationObserver(() => setTimeout(updateFolder.bind(this, folderElement), 1)) observer.observe(folderElement, {childList: true, attributes: true}) observers[folderElement] = observer updateFolder(folderElement) + + console.info("[PrettyFolders] attached observer to ", folderElement) } +/** + * Removes a MutationObserver for a folder wrapper. + * + * @param folderElement the folder wrapper element + */ const detachFolder = (folderElement) => { observers[folderElement]?.disconnect() observers[folderElement] = null + console.info("[PrettyFolders] removed observer from ", folderElement) } /** * Updates a folder's background color with the icon color. + * * @param folder the folder wrapper element */ const updateFolder = (folder) => { const background = folderBackground(folder) if (!background) { - console.warn("could not find background element for", {folder}) + console.warn("[PrettyFolders] could not find background element for", {folder}) return } const icon = folderIcon(folder) + if (!icon) { + console.warn("[PrettyFolders] could not find icon element for", {folder}) + return + } + const svg = icon?.querySelector("svg") const folderColor = svg?.style?.color; - if (!folderColor) return; + if (!folderColor) { + console.info("[PrettyFolders] skipping style changes (no custom colour found), ", folder) + } - if (!background.classList.contains(FOLDER_COLLAPSED) && ignoredColors.indexOf(folderColor) === -1) { + if (!background.matches(FOLDER_COLLAPSED) && ignoredColors.indexOf(folderColor) === -1) { background.style.backgroundColor = folderColor; icon.style.backgroundColor = folderColor svg.style.color = "white" svg.style.opacity = 0.7; background.style.opacity = 0.3; + } else { + console.info("[PrettyFolders] skipping style changes (collapsed or ignored colour), ", folder) } folder.addEventListener("click", () => updateFolder(this)) @@ -77,6 +124,11 @@ const updateFolder = (folder) => { observers[folder] = observer } +/** + * Resets any changes to a folder wrapper. + * + * @param folder the folder wrapper element + */ const resetFolder = (folder) => { const background = folderBackground(folder) background.style.removeProperty("background-color");