import { obfuscator } from './obfuscator' import { NameConfigInstance, nameImages } from './options' import { ChatMessage, innermostElement, usernameImageTemplateSuffix, usernameTemplateSuffix, } from './util' export function loadChatMessage(chatboxMessage: Element) { // only chat messages const chatboxMessageInner = chatboxMessage.querySelector( '.chat-line__message' ) if (!chatboxMessageInner) { return } // get chatbox details const chatboxBadgeContainer = chatboxMessage.querySelector( '.chat-line__message--badges' ) if (!chatboxBadgeContainer) { console.error("found message, couldn't find badges") return } const chatboxUser = chatboxMessage.querySelector( '.chat-line__username' ) if (!chatboxUser) { console.error("found message, couldn't find user") return } const chatboxUserInner = chatboxUser.querySelector( '.chat-author__display-name' ) if (!chatboxUserInner) { console.error("found message, couldn't find userInner") return } // got the data, so we're loaded chatboxMessage.classList.add('obf-loaded') // hide 7tv extra colors if (chatboxUser.classList.contains('seventv-paint')) { chatboxUser.classList.remove('seventv-paint') } // check if mod let isMod = false for (const badge of chatboxBadgeContainer.children) { if ( badge.hasAttribute('data-badge') && (badge.getAttribute('data-badge') === 'moderator' || badge.getAttribute('data-badge') === 'broadcaster') ) { isMod = true chatboxMessage.classList.add('ismod') } } // combine details into object const chatMessage: ChatMessage = { username: chatboxUserInner.textContent, isMod, } // run main script (process chatMessage), return new ChatMessage const newChatMessage = obfuscator(chatMessage) if (newChatMessage !== null) { setUsernameDetails(newChatMessage, chatboxUserInner, chatboxUser) } loadReplyLine(chatboxMessage) loadMessageMentions(chatboxMessage) } function loadReplyLine(chatboxMessage: Element) { const replyline = chatboxMessage.querySelector('.ffz--fix-reply-line') const replyUsername = replyline?.querySelector( 'p > span:nth-child(1)' ) if (!replyUsername) { return } const chatMessage: ChatMessage = { username: replyUsername.textContent.replace(/^@/, ''), isMod: false, } // run main script (process chatMessage), return new ChatMessage const newChatMessage = obfuscator(chatMessage) if (newChatMessage !== null) { setUsernameDetails(newChatMessage, replyUsername, undefined, '@') } } function loadMessageMentions(chatboxMessage: Element) { function eachMention(messageMention: HTMLElement) { const chatMessage: ChatMessage = { username: messageMention.textContent.replace(/^@/, ''), isMod: false, } // run main script (process chatMessage), return new ChatMessage const newChatMessage = obfuscator(chatMessage) if (newChatMessage !== null) { setUsernameDetails(newChatMessage, messageMention, undefined, '@') } } const messageMentions = chatboxMessage.querySelectorAll( '.chat-line__message-mention' ) for (const messageMention of messageMentions) { eachMention(messageMention) } } export function loadAdditionalUserNames(chatboxMessage: Element) { // look for additional chat member names const chatterNames = chatboxMessage.querySelectorAll('.chatter-name') for (const chatterName of chatterNames) { chatboxMessage.classList.add('obf-loaded') const chatterNameBox = innermostElement(chatterName) const username = chatterNameBox.textContent if (!username) { continue } // combine details into object const chatMessage: ChatMessage = { username, isMod: false, } // run main script (process chatMessage), return new ChatMessage const newChatMessage = obfuscator(chatMessage) if (newChatMessage !== null) { setUsernameDetails(newChatMessage, chatterNameBox) } } } function setUsernameDetails( newChatMessage: NameConfigInstance, textbox: HTMLElement, colorbox?: HTMLElement, prefixStr: string = '' ) { const username = `${newChatMessage.username}${usernameTemplateSuffix(newChatMessage)}` const imageName = newChatMessage.image if (imageName) { // image name const image = nameImages[imageName] const img = document.createElement('img') img.classList.add('obf-image', 'ffz--pointer-events', 'ffz-tooltip') img.setAttribute('data-tooltip-type', 'html') img.setAttribute('data-title', username) img.setAttribute('alt', username) img.setAttribute('src', image) const prefix = document.createElement('span') prefix.textContent = prefixStr const suffix = document.createElement('span') suffix.textContent = usernameImageTemplateSuffix(newChatMessage) textbox.replaceChildren(prefix, img, suffix) } else { // text name only textbox.textContent = `${prefixStr}${username}` } if (colorbox) { colorbox.style.color = newChatMessage.color } }