Untitled
unknown
javascript
a year ago
10 kB
10
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