Untitled
unknown
javascript
5 months ago
10 kB
6
Indexable
// Define the users to track and notify with popup and audio const usersToTrack = [ { name: 'Даниэль', gender: 'male', pronunciation: 'Даниэль' }, // ------------ 01 { name: 'Пьяный_Качок', gender: 'male', pronunciation: 'Пьяный-Качок' }, // -- 02 { name: 'Баристарх', gender: 'male', pronunciation: 'Баристарх' }, // -------- 03 { name: 'madinko', gender: 'female', pronunciation: 'Мадинко' }, // ---------- 04 { name: 'Переборыч', gender: 'male', pronunciation: 'Переборыч' }, // -------- 05 { name: 'Advisor', gender: 'male', pronunciation: 'Адвайзер' }, // ----------- 06 { name: 'Хеопс', gender: 'male', pronunciation: 'Хеопс' }, // ---------------- 07 { name: 'Рустамко', gender: 'male', pronunciation: 'Рустамко' }, // ---------- 08 { name: 'ExpLo1t', gender: 'female', pronunciation: 'Эксплоит' }, // --------- 09 { name: 'инфо-пчелы', gender: 'male', pronunciation: 'Инфо-Пчёлы' }, // ------ 10 { name: 'Razmontana', gender: 'male', pronunciation: 'Размонтана' }, // ------ 11 { name: 'un4given', gender: 'male', pronunciation: 'Унч' }, // --------------- 12 { name: 'oonch', gender: 'male', pronunciation: 'Клонец унча' }, // ---------- 13 { name: 'iChessKnock', gender: 'male', pronunciation: 'Чеснок' }, // --------- 14 { name: 'Anatolysov', gender: 'male', pronunciation: 'Анатолий' }, // -------- 15 { name: 'Солнцеликий', gender: 'male', pronunciation: 'Солнцеликий' }, // ---- 16 { name: 'elasez_uyefot_2', gender: 'male', pronunciation: 'Чупачупс' } // ---- 17 ]; // Function to replace username mentions with their respective pronunciations function replaceWithPronunciation(text) { if (text === null) { return text; } const replaceUsername = (username) => { // Clean digits from the username for comparison const cleanedUsername = username.replace(/\d/g, ''); // Find the user by cleaned username const user = usersToTrack.find(user => user.name.replace(/\d/g, '').toLowerCase() === cleanedUsername.toLowerCase()); return user ? user.pronunciation : username; }; // Create a pattern to match usernames, allowing for digits in the names const pattern = new RegExp(usersToTrack.map(user => user.name.replace(/\d/g, '\\d*')).join('|'), 'gi'); // Replace all matching usernames with their corresponding pronunciations return text.replace(pattern, replaceUsername); } // Function to get the cleaned text content of the latest message with username prefix function getLatestMessageTextContent() { const messageElement = document.querySelector('.messages-content div p:last-child'); if (!messageElement) { return null; } const isTextNode = (node) => node.nodeType === Node.TEXT_NODE && node.textContent.trim() !== ''; const textNodes = [...messageElement.childNodes].filter(isTextNode); const messageText = textNodes.map(node => node.textContent).join('').trim(); const username = messageElement.querySelector('.username'); let usernameText = username ? username.textContent : null; // Check if usernameText is not null before replacing "<", ">" symbols, and digits if (usernameText !== null) { // Remove the "<", ">", and digits from the username usernameText = usernameText.replace(/<|>/g, '').replace(/\d/g, ''); } let usernamePrefix = ''; // If the current username is an alias what is about you, use a "is addressing" prefix if (isMentionForMe(messageText)) { isMention = true; usernamePrefix = `${replaceWithPronunciation(usernameText)} обращается: `; highlightMentionWords(); } // If the current username is the same as the last username seen, use a "is writing" prefix else if (usernameText !== lastUsername) { isMention = false; usernamePrefix = `${replaceWithPronunciation(usernameText)} пишет: `; } lastUsername = usernameText; const messageWithPronunciation = `${usernamePrefix}${replaceWithPronunciation(messageText)}`; return { messageText: messageWithPronunciation, usernameText: usernameText }; } // Skip reading the messages on page load to read them normally when the user is present and the page is stable let isInitialized = false; // create a mutation observer to watch for new messages being added const newMessagesObserver = new MutationObserver(mutations => { // If isInitialized is false return without doing anything if (!isInitialized) { isInitialized = true; return; } for (let mutation of mutations) { if (mutation.type === 'childList') { for (let node of mutation.addedNodes) { if (node.nodeType === Node.ELEMENT_NODE && node.tagName === 'P') { // read the text content of the new message and speak it const latestMessageTextContent = localStorage.getItem('latestMessageTextContent'); // Get the latest message text content const latestMessageTextContentResult = getLatestMessageTextContent(); const newMessageTextContent = latestMessageTextContentResult.messageText; // Get the username of the user who sent the latest message let latestMessageUsername = null; if (latestMessageTextContentResult && latestMessageTextContentResult.usernameText) { latestMessageUsername = latestMessageTextContentResult.usernameText; } // Sanitize the username for comparison const sanitizedLatestMessageUsername = latestMessageUsername ? latestMessageUsername.replace(/\d/g, '') : null; const sanitizedMyNickname = myNickname.replace(/\d/g, ''); // Get the sound switcher element and check which option is selected const soundSwitcher = document.querySelector('#voice, #beep, #silence'); const isVoice = soundSwitcher && soundSwitcher.id === 'voice'; const isBeep = soundSwitcher && soundSwitcher.id === 'beep'; // Get the message mode element and check which option is selected const messageMode = document.querySelector('#every-message, #mention-message'); const isEveryMessage = messageMode && messageMode.id === 'every-message'; const isMentionMessage = messageMode && messageMode.id === 'mention-message'; // If mode is voice, speak the new message and update the latest message content in local storage if (isVoice && isInitialized && newMessageTextContent && newMessageTextContent !== latestMessageTextContent) { // Update localStorage key "latestMessageTextContent" localStorage.setItem('latestMessageTextContent', newMessageTextContent); // Speak the new message only if it's not addressed to your nickname if (sanitizedLatestMessageUsername && !sanitizedLatestMessageUsername.includes(sanitizedMyNickname)) { if (isEveryMessage) { // Add the new message to the Set addNewMessage(newMessageTextContent); } else if (isMentionMessage) { // Make sure if the user is tracked before adding new message in a queue for reading const isTrackedUser = usersToTrack.some((trackedUser) => newMessageTextContent.includes(trackedUser.pronunciation)); if (isTrackedUser) { // Add the new message to the Set addNewMessage(newMessageTextContent); } } } } // If mode is beep, play the beep sound for the new message if (isBeep && isInitialized && newMessageTextContent && newMessageTextContent !== latestMessageTextContent) { // Update localStorage key "latestMessageTextContent" localStorage.setItem('latestMessageTextContent', newMessageTextContent); // Play the beep sound only if the message is not addressed to your nickname if (sanitizedLatestMessageUsername && !sanitizedLatestMessageUsername.includes(sanitizedMyNickname)) { // Play mention frequencies if the message is addressed to you if (isMention) { playBeep(mentionMessageFrequencies, beepVolume); // Return value as default to continue make a beep sound as a usual message isMention = false; } // Play usual frequencies if the message is addressed to other users or not addressed to anybody else { if (isEveryMessage) { playBeep(usualMessageFrequencies, beepVolume); } } } } if (isInitialized) { // Attach contextmenu event listener for messages deletion attachEventsToMessages(); // Convert image links to visible image containers convertImageLinkToImage(); // Convert YouTube links to visible iframe containers convertYoutubeLinkToIframe(); // Call the function to apply the chat message grouping applyChatMessageGrouping(); // Calls the removeSpamMessages function to filter and hide similar chat messages based on Jaro-Winkler distance. // removeSpamMessages(); // Call the function to scroll to the bottom of the chat scrollMessages(); // Call the banSpammer function to track and handle potential spam messages banSpammer(); // Call the function to show the latest popup message showPopupMessage(); } } } } } }); // observe changes to the messages container element const messagesContainer = document.querySelector('.messages-content div'); newMessagesObserver.observe(messagesContainer, { childList: true, subtree: true });
Editor is loading...
Leave a Comment