-
Notifications
You must be signed in to change notification settings - Fork 5
/
chat.js
123 lines (105 loc) · 3.75 KB
/
chat.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Setting the default value of the maximum variable to 250.
let cap = 250;
let ban = "";
let cmd = true;
let ccd = true;
let sts = false;
let clr = "#fff";
window.addEventListener("onWidgetLoad", function (obj) {
const fieldData = obj.detail.fieldData;
cap = fieldData.CharLimit;
ban = fieldData.HiddenAccounts;
cmd = fieldData.HideCommands;
ccd = fieldData.ColorCommands;
sts = fieldData.StaticColor;
clr = fieldData.FontColor;
});
window.addEventListener("onEventReceived", function (obj) {
// If the event is not a chat message, return.
if (obj?.detail?.listener?.toUpperCase() !== "MESSAGE") return;
// Get ID, message, user color, username, and emotes from the event.
const mid = obj.detail.event.data.msgId;
const bod = obj.detail.event.data.text;
const col = obj.detail.event.data.displayColor;
const usr = obj.detail.event.data.displayName;
const emo = obj.detail.event.data.emotes;
// seperate unallowed users by comma
let banList = ban.split(", ");
// If the user exists in the list of unallowed users, return.
if (banList.includes(usr)) return;
// If message starts with a command prefix, return.
if (cmd && bod.startsWith("!")) return;
// grab the chat element
const container = document.getElementById("main-container");
// create the message element
div = document.createElement("div");
div.className = "message";
div.setAttribute("data-id", mid);
// Apply static color if enabled, otherwise apply user chat color.
sts ? (div.style.color = clr) : (div.style.color = col);
// if the message has a color prefix and custom colors are enabled, apply the color.
if (ccd && getColorCommand(bod)) div.style.color = getColorCommand(bod).color;
if (ccd && getColorCommand(bod))
div.innerHTML = attachEmote(getColorCommand(bod).message, emo);
// if not, don't apply any colours.
else div.innerHTML = attachEmote(bod, emo);
container.append(div);
const el = document.querySelector(`[data-id="${mid}"]`);
bod.length > cap ? el.remove() : null;
// Speed calculation.
let speed = 25 - ((bod.length - 10) / 290) * 10 + "s";
// Random Height.
margin = Math.floor(
Math.random() * (window.innerHeight - el.offsetHeight / 1.3 - 0)
);
// Apply animation.
el.style.animation = `LRMove ${speed} linear, RLMove ${speed} linear ${speed} forwards`;
el.style.width = window.innerWidth;
el.style.bottom = `${margin}px`;
});
/**
* Takes a message and an array of emotes, and replaces the emote strings with the images of
* the emotes.
* @param message - The message that you want to attach the emote to.
* @param emotes - An array of emotes.
* @returns The html with the message and emotes attached.
*/
function attachEmote(message, emotes) {
message = escapeHtml(message);
for (let emote of emotes) {
message = message.replace(
emote["name"],
`<img class="emote" src="${emote["urls"]["4"]}" />`
);
}
return message;
}
/**
* Takes a string, checks if it starts with a command prefix, and if it does, it returns an object with the
* color and the message seperated.
* @param body - The message body
* @returns An object with two properties: color and message.
*/
function getColorCommand(body) {
if (body.startsWith("#")) {
return {
color: body.split(" ")[0].substring(1),
message: body.substring(body.split(" ")[0].length + 1),
};
} else {
return false;
}
}
/**
* Replaces the characters &, <, >, ", and ' with their HTML entity equivalents to prevent XSS attacks.
* @param unsafe - The string to be escaped.
* @returns the string with the HTML characters escaped.
*/
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}