Skip to content

Commit b9acff5

Browse files
Add files via upload
1 parent bd97719 commit b9acff5

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

ColorIndicator.plugin.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/**
2+
* @name ColorIndicator
3+
* @author QuantumSoul
4+
* @description Highlights color codes in discord chats
5+
* @version 0.0.1
6+
*/
7+
8+
const CLASS_SCROLLER_INNER = BdApi.Webpack.getByKeys("navigationDescription", "scrollerInner")["scrollerInner"];
9+
const CLASS_MESSAGE_LIST_ITEM = BdApi.Webpack.getByKeys("messageListItem")["messageListItem"];
10+
const CLASS_MESSAGE_CONTENT = BdApi.Webpack.getByKeys("messageEditorCompact", "messageContent")["messageContent"];
11+
12+
module.exports = class Plugin {
13+
observer = null;
14+
15+
start() {
16+
this.onSwitch();
17+
}
18+
19+
stop() {
20+
if (this.observer) this.observer.disconnect();
21+
}
22+
23+
onSwitch() {
24+
if (this.observer) this.observer.disconnect();
25+
this.observer = new MutationObserver(this.handleMutations);
26+
27+
//format existing messages and listen to new ones
28+
const channels = document.querySelector("." + CLASS_SCROLLER_INNER);
29+
if (channels) {
30+
//existing one
31+
channels.querySelectorAll("." + CLASS_MESSAGE_CONTENT).forEach(this.parseMessage);
32+
33+
//new ones
34+
this.observer.observe(channels, {
35+
childList: true,
36+
subtree: true,
37+
characterData: true,
38+
});
39+
}
40+
}
41+
42+
handleMutations = (mutationsList) => {
43+
let timeoutId = null; //prevents formatting before edition
44+
45+
for (const mutation of mutationsList) {
46+
if (mutation.type === "childList") {
47+
for (const node of mutation.addedNodes) {
48+
if (node.classList && node.classList.contains(CLASS_MESSAGE_CONTENT)) {
49+
timeoutId = setTimeout(() => {
50+
//unedited message
51+
this.parseMessage(node);
52+
timeoutId = null;
53+
}, 500);
54+
} else if (node.classList && node.classList.contains(CLASS_MESSAGE_LIST_ITEM)) {
55+
//new message
56+
this.parseMessage(node.querySelector("." + CLASS_MESSAGE_CONTENT));
57+
}
58+
}
59+
} else if (mutation.type === "characterData") {
60+
const messageContent = mutation.target.parentNode.closest("." + CLASS_MESSAGE_CONTENT);
61+
if (messageContent) {
62+
//edited message
63+
if (timeoutId !== null) {
64+
clearTimeout(timeoutId);
65+
timeoutId = null;
66+
}
67+
this.parseMessage(messageContent);
68+
}
69+
}
70+
}
71+
};
72+
73+
parseMessage = (messageContent) => {
74+
const colorCodeRegex = /#(?:[0-9a-fA-F]{3,6})\b/g;
75+
76+
messageContent.querySelectorAll('span').forEach((span) => {
77+
if (span.classList.contains('changed-indicator')) {
78+
const textNode = document.createTextNode(span.textContent);
79+
try {
80+
span.parentNode.replaceChild(textNode, span);
81+
} catch (error) {}
82+
}
83+
});
84+
85+
messageContent.innerHTML = messageContent.innerHTML.replace(colorCodeRegex, (match) => {
86+
const textColor = this.isColorTooDark(match) ? 'white' : 'black';
87+
return `<span class="changed-indicator inline" style="background-color:${match}; color:${textColor};">${match}</span>`;
88+
});
89+
};
90+
91+
isColorTooDark = (hexColor) => {
92+
const bigint = parseInt(hexColor.slice(1), 16);
93+
const rgb = { r: (bigint >> 16) & 255, g: (bigint >> 8) & 255, b: bigint & 255 };
94+
return 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b < 128;
95+
};
96+
};

bm-colors.png

23.5 KB
Loading

0 commit comments

Comments
 (0)