Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PrettyFolders v1.2.3 #13

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)
![Demo gif](https://github.com/webcrawls/discord/blob/master/assets/better-folders.gif?raw=true)
90 changes: 71 additions & 19 deletions pretty-folders.plugin.js
Original file line number Diff line number Diff line change
@@ -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.<HTMLElement, MutationObserver>}
*/
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))
Expand All @@ -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");
Expand Down