Files
wompchat/src/content/ChatWatcher.js
wompmacho cf52afc0ba moving welcome banner change to index
remove extra lines
moved welcome banner to index
moved set defaults inside main of index
2020-11-01 23:35:22 -05:00

228 lines
6.4 KiB
JavaScript

import Emotes from './Emotes';
import Message from './Message';
import PersistentSyncStorage from 'src/helpers/PersistentSyncStorage';
class ChatWatcher {
constructor() {
this.watchChat = this.watchChat.bind(this);
this._chatContainer = null;
this._observer = null;
this.messages = new Map();
}
init() {
return new Promise((res, rej) => {
this.getChatContainer().then(Emotes.init).then(() => {
this.addEmotePopup();
this.watchChat();
this.parsePreloadedMessages();
});
});
}
getChatContainer() {
// Parent of actual chat (children are messages)
const checkForContainer = (res, rej) => {
this._chatContainer = document.querySelector('#items.style-scope.yt-live-chat-item-list-renderer');
if(this._chatContainer !== null) {
res();
} else {
setTimeout(checkForContainer.bind(this, res, rej), 250);
}
};
return new Promise(checkForContainer);
}
parsePreloadedMessages() {
const messages = this._chatContainer.children;
for(let i = messages.length-1; i >= 0; i--) {
const node = messages[i];
if(this.isMessageNode(node)) {
const message = new Message(node);
}
}
}
watchChat() {
console.log('Chat observer started');
this._observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
const { addedNodes, removedNodes } = mutation;
// Added nodes
if(typeof addedNodes !== 'undefined' && addedNodes.length > 0) {
for(let i = 0, length = addedNodes.length-1; i <= length; i++) {
const node = addedNodes[i];
if(this.isMessageNode(node)) {
this.onNewMessage(node);
}
}
}
// Removed nodes
if(typeof removedNodes !== 'undefined' && removedNodes.length > 0) {
for(let i = 0, length = removedNodes.length-1; i <= length; i++) {
const node = removedNodes[i];
if(this.isMessageNode(node) && this.isObservedMessage(node)) {
this.onObservedMessageRemoved(node);
}
}
}
});
});
this._observer.observe(this._chatContainer, {
childList: true,
attributes: false,
characterData: false,
subtree: false
});
}
onNewMessage(node) {
const message = new Message(node);
// Don't store message if has 0 emotes
if(message.hasEmotes) {
this.messages.set(message.id, message);
}
}
onObservedMessageRemoved(node) {
const messageId = node.getAttribute('message-id');
const message = this.messages.get(messageId);
if(message != undefined){
message.destroy();
}
this.messages.delete(messageId);
}
isMessageNode(node) {
return node.tagName === 'YT-LIVE-CHAT-TEXT-MESSAGE-RENDERER';
}
isObservedMessage(node) {
return node.getAttribute('message-id') !== null;
}
///////////////////////////////////////////////////////////////////
addEmotePopup(){
// create emote button
const emoteButton = document.createElement('button');
emoteButton.classList.add('emoteButton');
emoteButton.textContent = '';
// append button to action-buttons list
const chatButtonSelectionList = document.getElementById('action-buttons');
chatButtonSelectionList.parentNode.insertBefore(emoteButton, chatButtonSelectionList);
// create popupDiv
const popUpDiv = document.createElement('div');
popUpDiv.classList.add('popup');
popUpDiv.classList.add('hideElement');
function emoteAppend(keysITer){
// create divider
var hr = document.createElement('hr');
hr.classList.add('emoteDivider');
for (let index = 0; index < keysITer.length; index++) {
const element = keysITer[index];
var emote_div = document.createElement('emote_div');
emote_div.innerHTML = (Emotes.get(element).html);
popUpDiv.appendChild(emote_div);
}
popUpDiv.appendChild(hr);
}
// create text
var bttv_text = document.createElement('h2');
bttv_text.textContent = "BTTV";
bttv_text.classList.add('emotePopUpText');
var franker_text = document.createElement('h2');
franker_text.textContent = "FrankerFacez";
franker_text.classList.add('emotePopUpText');
var twitch_text = document.createElement('h2');
twitch_text.textContent = "Twitch";
twitch_text.classList.add('emotePopUpText');
// need ittr to search each dict and append to dom
let keysITer = null;
keysITer = Array.from(Emotes.specialEmotesDictionary.keys());
emoteAppend(keysITer);
if(PersistentSyncStorage.data.options.enableBTTVEmotes){
popUpDiv.appendChild(bttv_text);
keysITer = Array.from(Emotes.bttv_Dictionary.keys());
emoteAppend(keysITer);
}
if(PersistentSyncStorage.data.options.enableFrankerEmotes){
popUpDiv.appendChild(franker_text);
keysITer = Array.from(Emotes.franker_Dictionary.keys());
emoteAppend(keysITer);
}
if(PersistentSyncStorage.data.options.enableTwitchEmotes){
popUpDiv.appendChild(twitch_text);
keysITer = Array.from(Emotes.twitch_Dictionary.keys());
emoteAppend(keysITer);
}
// add div to doc
chatButtonSelectionList.appendChild(popUpDiv);
// listen for popup button
emoteButton.addEventListener('click', function(){
popUpDiv.classList.toggle('hideElement');
console.log('emote popup button clicked');
});
// get input area
var inputArea = document.querySelector('#input.yt-live-chat-text-input-field-renderer');
var inputAreaLabel = document.querySelector('#label.yt-live-chat-text-input-field-renderer');
// add alt tag to chat
function emoteToTextArea(){
inputArea.textContent += this.alt + " ";
inputArea.focus();
inputAreaLabel.textContent = "";
popUpDiv.classList.toggle('hideElement');
console.log(this.alt + " emote button selected");
}
// listener button for emotes
var EMOTICONS = document.getElementsByTagName('img');
for (let index = 0; index < EMOTICONS.length; index++) {
const element = EMOTICONS[index];
element.addEventListener('click', emoteToTextArea, false);
}
console.log((keysITer.length+1) + " Emotes Added");
}// end addEmotePopup
///////////////////////////////////////////////////////////////////
}// end chat watcher
export default ChatWatcher;