Untitled

 avatar
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