105 lines
3.3 KiB
JavaScript
105 lines
3.3 KiB
JavaScript
const timeout = 120000;
|
|
|
|
class Message {
|
|
constructor(object, onDestroy) {
|
|
this.target = object.target;
|
|
this.context = object.context;
|
|
this.message = object.message;
|
|
this.self = object.self;
|
|
}
|
|
|
|
createEl() {
|
|
this.element = document.createElement('li');
|
|
this.element.className = "item";
|
|
this.element.style.position = "relative";
|
|
|
|
let badges = document.createElement('span');
|
|
for (let key in this.context.badges) {
|
|
let badge = document.createElement('span');
|
|
badge.className = "badge";
|
|
badge.innerHTML = '<img src="/static/' + key + '.png">';
|
|
badges.appendChild(badge);
|
|
}
|
|
this.element.appendChild(badges);
|
|
|
|
let name = document.createElement('span');
|
|
name.className = "text name";
|
|
name.style.color = this.context.color;
|
|
name.innerHTML = escapeHtml(this.context["display-name"]);
|
|
this.element.appendChild(name);
|
|
|
|
let message = document.createElement('span');
|
|
let text = formatEmotes(this.message, this.context.emotes);
|
|
text = replaceAll(text, "DragonRck", '<img class="emoticon" src="/static/dragonrck.png">');
|
|
message.innerHTML = text;
|
|
message.className = "text message";
|
|
this.element.appendChild(message);
|
|
|
|
setTimeout(() => this.destroy(), timeout);
|
|
return this.element;
|
|
}
|
|
|
|
destroy() {
|
|
this.element.className += ' destroy';
|
|
}
|
|
}
|
|
|
|
function escapeHtml(unsafe) {
|
|
return unsafe
|
|
.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">")
|
|
.replace(/"/g, """)
|
|
.replace(/'/g, "'");
|
|
}
|
|
|
|
function formatEmotes(text, emotes) {
|
|
var splitText = text.split('');
|
|
for(var i in emotes) {
|
|
var e = emotes[i];
|
|
for(var j in e) {
|
|
var mote = e[j];
|
|
if(typeof mote == 'string') {
|
|
mote = mote.split('-');
|
|
mote = [parseInt(mote[0]), parseInt(mote[1])];
|
|
var length = mote[1] - mote[0],
|
|
empty = Array.apply(null, new Array(length + 1)).map(function() { return '' });
|
|
splitText = splitText.slice(0, mote[0]).concat(empty).concat(splitText.slice(mote[1] + 1, splitText.length));
|
|
splitText = splitText.map((x) => escapeHtml(x));
|
|
splitText.splice(mote[0], 1, '<img class="emoticon" src="http://static-cdn.jtvnw.net/emoticons/v1/' + i + '/3.0">');
|
|
}
|
|
}
|
|
}
|
|
return splitText.join('');
|
|
}
|
|
|
|
function replaceAll(input, from, to) {
|
|
const fromLen = from.length;
|
|
let output = "";
|
|
let pos = 0;
|
|
for (;;) {
|
|
let matchPos = input.indexOf(from, pos);
|
|
if (matchPos === -1) {
|
|
output += input.slice(pos);
|
|
break;
|
|
}
|
|
output += input.slice(pos, matchPos);
|
|
output += to;
|
|
pos = matchPos + fromLen;
|
|
}
|
|
return output;
|
|
}
|
|
|
|
function addMessage(object) {
|
|
messages .className = "";
|
|
let message = new Message(object);
|
|
messages.appendChild(message.createEl());
|
|
messages.style.bottom = '-' + message.element.offsetHeight + 'px';
|
|
messages.className = "slide";
|
|
};
|
|
|
|
let messages = document.getElementById('messages');
|
|
let socket = io();
|
|
socket.on('message', addMessage);
|
|
|