Untitled

mail@pastecode.io avatar
unknown
javascript
a year ago
15 kB
2
Indexable
Never
// ==UserScript==
// @name         KG_Full_Emoticons
// @namespace    http://klavogonki.ru/
// @version      0.1
// @description  Show all the emoticons
// @author       Patcher
// @match        *://klavogonki.ru/g*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=klavogonki.ru
// @grant        none
// ==/UserScript==

const categories = {
  "Boys": [
    ":heart:", ":facepalm:", ":friends:", ":shok:", ":megashok:", ":dash:", ":music:", ":acute:",
    ":victory:", ":scare:", ":clapping:", ":whistle:", ":popcorn:", ":hello:", ":rose:", ":good:",
    ":silence:", ":bad:", ":tea:", ":sick:", ":confuse:", ":rofl2:", ":nervous:", ":chaingun:",
    ":diablo:", ":cult:", ":russian:", ":birthday:", ":champ2:", ":champ:", ":confetti:", ":formula1:"
  ],
  "Girls": [
    ":girlnotebook:", ":girlkiss:", ":curtsey:", ":girlblum:", ":girlcrazy:", ":girlcry:",
    ":girlwink:", ":girlwacko:", ":umbrage:", ":girlinlove:", ":girldevil:", ":girlimpossible:",
    ":girlwitch:", ":hysteric:", ":tender:", ":spruceup:", ":girlsad:", ":girlscare:", ":girltea:",
    ":girlsick:", ":grose:", ":cheerful:", ":cheerleader:", ":girlconfuse:", ":spruceup1:",
    ":angrygirl:", ":clapgirl:", ":goody:", ":hiya:", ":girlsilence:", ":girlstop:", ":girlnervous:",
    ":girlwonder:", ":girlwonder:", ":kgrace:", ":kgagainstaz:", ":girlkissboy:", ":girlmusic:"
  ],
  "Christmas": [
    ":cheers:", ":christmasevil:", ":heyfrombag:", ":merrychristmas:", ":moose:", ":santa:",
    ":santa2:", ":santa3:", ":santasnegurka:", ":snegurka:", ":snegurochka:", ":snowball:",
    ":snowgirlwave:", ":snowhand:", ":snowhit:", ":snowman:", ":spruce:"
  ],
  "Inlove": [
    ":adultery:", ":airkiss:", ":cave:", ":flowers:", ":flowers2:", ":frog:", ":girlfrog:",
    ":girlheart2:", ":girllove:", ":grose:", ":heart2:", ":heartcake:", ":hug:", ":inlove:",
    ":nolove:", ":smell:", ":wecheers:", ":wedance:", ":wedding:", ":wine:"
  ],
  "Army": [
    ":ak47:", ":armyfriends:", ":armyscare:", ":armystar:", ":armytongue:", ":barret:",
    ":bayanist:", ":budenov:", ":captain:", ":comandos:", ":fly:", ":foolrifle:", ":girlpogran:",
    ":girlranker:", ":girlrogatka:", ":girlvdv:", ":kirpich:", ":partizan:", ":pogran:",
    ":pogranflowers:", ":pogranmail:", ":pogranmama:", ":pogranminigun:", ":pogranrose:",
    ":pograntort:", ":prival:", ":radistka:", ":ranker:", ":rogatka:", ":soldier:", ":tank:",
    ":uzi:", ":vdv:", ":vpered:", ":vtik:"
  ],
  "8 March": [
    ":boystroking:", ":cheerleader:", ":confetti:", ":enjoygift:", ":firework:", ":girlicecream:",
    ":girlmad:", ":girlobserve:", ":girlrevolve:", ":girlshighfive:", ":girlstroking:", ":girlsuper:",
    ":grats:", ":hairdryer:", ":leisure:", ":primp:", ":respect:", ":serenade:", ":spruceup:"
  ],
  "Halloween": [
    ":alien:", ":batman:", ":bebebe:", ":bite:", ":carpet:", ":clown:", ":corsair:", ":cowboy:",
    ":cyborg:", ":dandy:", ":death:", ":dwarf:", ":gangster:", ":ghost:", ":girlpirate:", ":holmes:",
    ":indigenous:", ":jester:", ":mafia:", ":musketeer:", ":paladin:", ":pioneer:", ":pirate:",
    ":pirates:", ":robot:", ":rocker:", ":spider:", ":supergirl:", ":terminator:", ":turtle:",
    ":vampire:", ":witch:", ":wizard:"
  ]
};

let roomField = null;
let isEventListenersInitialized = false;
let isPopupCreated = false;
let activeCategory = 'Boys';

// Function to determine which chat room we are in
function determineChatRoom() {
  if (!roomField) {
    if (window.location.href.startsWith("https://klavogonki.ru/gamelist")) {
      roomField = document.querySelector('#chat-general input.text');
      console.log("Chat Field (General):", roomField);
    } else if (window.location.href.startsWith("https://klavogonki.ru/g/?gmid=")) {
      roomField = document.querySelector('div[id*="chat-game"] input.text');
      console.log("Chat Field (Game):", roomField);
    }
  }
  return roomField;
}

// Function to remove the emoticons popup
function removeEmoticonsPopup() {
  const popupBox = document.querySelector('.emoticons-popup');
  if (popupBox) {
    document.body.removeChild(popupBox);
    isPopupCreated = false; // Reset the flag when the popup is removed
  }
}

// Function to calculate the maximum image width and height for a given category
function calculateMaxImageDimensions(category) {
  const maxImageWidth = 34;
  const maxImageHeight = 34;

  const maxImageWidthCalculated = category.reduce((maxWidth, emoticon) => {
    const emoticonName = emoticon.substring(1, emoticon.length - 1);
    const imgSrc = `/img/smilies/${emoticonName}.gif`;
    const img = new Image();
    img.src = imgSrc;
    const imageWidth = img.width;
    return Math.max(maxWidth, imageWidth);
  }, maxImageWidth);

  return { maxImageWidth: maxImageWidthCalculated, maxImageHeight };
}

// Function to toggle the emoticons popup on double click
function toggleEmoticonsPopup() {
  if (isPopupCreated) {
    removeEmoticonsPopup();
  } else {
    createEmoticonsPopup(activeCategory);
  }
}

// Function to initialize event listeners
function initializeEventListeners() {
  if (!isEventListenersInitialized) {
    document.addEventListener('keydown', function (event) {
      if (event.ctrlKey && event.code === 'Semicolon') {
        event.preventDefault();
        createEmoticonsPopup(activeCategory);
      } else if (event.key === 'Escape') {
        removeEmoticonsPopup();
      }
    });

    // Attempt to find the chat input field
    roomField = determineChatRoom();

    // Check if the chat input field was found
    if (roomField) {
      // Attach a double-click event listener to the chat field
      roomField.addEventListener('dblclick', toggleEmoticonsPopup);
    }

    isEventListenersInitialized = true;
  }
}

// Function to create the emoticons popup for a given category
function createEmoticonsPopup(category) {
  if (!isPopupCreated) {
    const popupBox = document.createElement('div');
    popupBox.style.position = 'fixed';
    popupBox.style.display = 'grid';

    // Calculate the maximum image width and height for a given category
    let { maxImageWidth, maxImageHeight } = calculateMaxImageDimensions(categories[category]);

    // Define the grid properties for the popup
    popupBox.style.gridTemplateRows = "50px auto";
    popupBox.style.gridGap = '10px';

    // Calculate background color for the popup
    const bodyBackgroundColor = window.getComputedStyle(document.body).backgroundColor;
    const bodyLightness = getLightness(bodyBackgroundColor);
    const popupLightness = bodyLightness < 50 ? bodyLightness + 10 : bodyLightness - 10;
    const adjustedPopupLightness = Math.min(100, Math.max(0, popupLightness));
    const popupBackgroundColor = `hsl(0, 0%, ${adjustedPopupLightness}%)`;

    popupBox.style.backgroundColor = popupBackgroundColor;
    popupBox.style.border = 'none';
    popupBox.style.padding = '10px';
    popupBox.style.zIndex = '9999';
    popupBox.style.top = '50%';
    popupBox.style.left = '50%';
    popupBox.style.transform = 'translate(-50%, -50%)';
    popupBox.style.maxWidth = '50vw';
    popupBox.style.width = '50vw';
    popupBox.style.maxHeight = '50vh';
    popupBox.style.overflow = 'auto';

    // Create category buttons inside the popup
    const buttonContainer = document.createElement('div');
    buttonContainer.classList.add('category-buttons');
    buttonContainer.style.display = 'flex';
    buttonContainer.style.justifyContent = 'center';

    for (const categoryKey in categories) {
      if (categories.hasOwnProperty(categoryKey)) {
        const button = document.createElement('button');
        button.textContent = categoryKey;
        button.addEventListener('click', () => {
          changeActiveCategory(categoryKey);
        });

        // Apply button styles
        const buttonLightness = bodyLightness < 50 ? bodyLightness + 15 : bodyLightness - 15;
        const adjustedButtonLightness = Math.min(100, Math.max(0, buttonLightness));
        const buttonBackgroundColor = `hsl(0, 0%, ${adjustedButtonLightness}%)`;

        button.style.backgroundColor = buttonBackgroundColor;
        button.style.border = 'none';
        button.style.outline = 'none';
        button.style.marginRight = '5px';
        button.style.cursor = 'pointer';

        button.addEventListener('mouseover', () => {
          const currentButtonLightness = getLightness(button.style.backgroundColor);
          const hoverLightness = bodyLightness < 50
            ? currentButtonLightness + 10
            : currentButtonLightness - 10;

          const adjustedHoverLightness = Math.min(100, Math.max(0, hoverLightness));
          const hoverBackgroundColor = `hsl(0, 0%, ${adjustedHoverLightness}%)`;

          button.style.backgroundColor = hoverBackgroundColor;
        });

        button.addEventListener('mouseout', () => {
          button.style.backgroundColor = buttonBackgroundColor;
        });

        buttonContainer.appendChild(button);
      }
    }

    popupBox.appendChild(buttonContainer);

    const emoticonButtonsContainer = document.createElement('div');
    emoticonButtonsContainer.classList.add('emoticon-buttons');
    emoticonButtonsContainer.style.display = 'none'; // Initially hide the container
    emoticonButtonsContainer.style.gridGap = '10px';

    const imageLoadPromises = [];

    categories[category].forEach(emoticon => {
      const button = document.createElement('button');
      const emoticonName = emoticon.substring(1, emoticon.length - 1);
      const imgSrc = `/img/smilies/${emoticonName}.gif`;
      const imgAlt = emoticonName;
      const buttonTitle = emoticonName;

      const buttonLightness = bodyLightness < 50 ? bodyLightness + 15 : bodyLightness - 15;
      const adjustedButtonLightness = Math.min(100, Math.max(0, buttonLightness));
      const buttonBackgroundColor = `hsl(0, 0%, ${adjustedButtonLightness}%)`;

      button.style.backgroundColor = buttonBackgroundColor;
      button.innerHTML = `<img src="${imgSrc}" alt="${imgAlt}">`;
      button.title = buttonTitle;
      button.style.border = 'none';
      button.style.outline = 'none';

      const imageLoadPromise = new Promise(resolve => {
        const img = new Image();
        img.onload = () => {
          resolve();
        };
        img.src = imgSrc;
      });

      imageLoadPromises.push(imageLoadPromise);

      button.addEventListener('click', function (event) {
        if (!event.ctrlKey) {
          insertEmoticonCode(emoticon);
          removeEmoticonsPopup();
        } else {
          // If Ctrl key is pressed, just insert the emoticon code
          insertEmoticonCode(emoticon);
        }
      });

      button.addEventListener('mouseover', () => {
        const currentButtonLightness = getLightness(button.style.backgroundColor);
        const hoverLightness = bodyLightness < 50
          ? currentButtonLightness + 10
          : currentButtonLightness - 10;

        const adjustedHoverLightness = Math.min(100, Math.max(0, hoverLightness));
        const hoverBackgroundColor = `hsl(0, 0%, ${adjustedHoverLightness}%)`;

        button.style.backgroundColor = hoverBackgroundColor;
      });

      button.addEventListener('mouseout', () => {
        button.style.backgroundColor = buttonBackgroundColor;
      });

      emoticonButtonsContainer.appendChild(button);
    });

    // Wait for all images to load before updating grid properties and making it visible
    Promise.all(imageLoadPromises).then(() => {
      // Calculate the maximum image width and height again after all images are loaded
      const { maxImageWidth: newMaxImageWidth, maxImageHeight: newMaxImageHeight } = calculateMaxImageDimensions(categories[category]);

      // Update grid properties with new values
      emoticonButtonsContainer.style.gridTemplateColumns = `repeat(auto-fit, minmax(${newMaxImageWidth}px, 1fr))`;
      emoticonButtonsContainer.style.gridAutoRows = `minmax(${newMaxImageHeight}px, auto)`;

      // Make it visible after all images are loaded
      emoticonButtonsContainer.style.display = 'grid';
    });

    popupBox.appendChild(emoticonButtonsContainer);

    popupBox.classList.add('emoticons-popup');
    document.body.appendChild(popupBox);
    isPopupCreated = true;
  }
}

// Function to insert emoticon code into the input field
function insertEmoticonCode(emoticon) {
  const roomField = determineChatRoom();
  if (roomField) {
    const cursorPosition = roomField.selectionStart;
    const emoticonCode = `${emoticon} `;

    // Get the current value of the input field
    const currentValue = roomField.value;

    // Insert the emoticon code at the cursor position
    const newValue =
      currentValue.substring(0, cursorPosition) +
      emoticonCode +
      currentValue.substring(cursorPosition);

    // Update the input field value with the new value
    roomField.value = newValue;

    // Set the cursor position after the inserted emoticon
    roomField.setSelectionRange(cursorPosition + emoticonCode.length, cursorPosition + emoticonCode.length);

    // Focus on the input field
    roomField.focus();
  }
}

// Function to get lightness from an RGB color string
function getLightness(color) {
  const match = color.match(/\d+/g);
  if (match && match.length === 3) {
    const r = parseInt(match[0]);
    const g = parseInt(match[1]);
    const b = parseInt(match[2]);
    const max = Math.max(r, g, b) / 255;
    const min = Math.min(r, g, b) / 255;
    const lightness = ((max + min) / 2) * 100;
    return lightness;
  }
  return 0;
}

// Function to change the active category
function changeActiveCategory(newCategory) {
  // Save the new active category to localStorage
  localStorage.setItem('activeCategory', newCategory);

  // Update the activeCategory variable
  activeCategory = newCategory;

  // Remove the existing emoticons popup (if any)
  removeEmoticonsPopup();

  // Create a new emoticons popup with the updated category
  createEmoticonsPopup(activeCategory);
}

// Initialize event listeners and create the emoticons popup with the default category
initializeEventListeners();

// Retrieve the active category from localStorage or use the default category if not found
activeCategory = localStorage.getItem('activeCategory') || 'Boys';