TalkingPanda / Kick Emote Auto Complete

// ==UserScript==
// @name         Kick Emote Auto Complete
// @namespace    https://tampermonkey.net/
// @version      0.1
// @description  adds a emote auto complete feature to kick
// @author       TalkingPanda
// @match        https://kick.com/*
// @exclude      https://kick.com/dashboard/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net
// @require      https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js
// @require      https://gist.githubusercontent.com/raw/2625891/waitForKeyElements.js
// @require   https://cdn.jsdelivr.net/npm/fuse.js/dist/fuse.js
// @license GPL-3.0-only
// ==/UserScript==
//

var selectedEmote = 0;
var fuse;

const fuseoptions = {
  keys: ['name']
};

(function () {
  'use strict';

  loadEmotes();
  waitForKeyElements("#chatroom-footer", actionFunction);
  document.onkeydown = (e) => {
    switch (e.keyCode) {
      // Key up
      case 38:
        selectedEmote = selectedEmote == 0 ? 0 : selectedEmote - 1;
        break;
        // Key down
      case 40:
        selectedEmote = selectedEmote == 4 ? 0 : selectedEmote + 1;
        break;
        // Tab
      case 9:
        sendEmote($(`#emote-${selectedEmote}`).text());
        break;
        // Escape
      case 27:
        $('#emotePopup').css('display', 'none');
        break;
      default:
        return;
        break;
    }
    e.preventDefault();
    e.stopPropagation();
    for (var i = 0; i < 5; i++) {
      $(`#emote-${i}`).css('color', 'white');
    }
    $(`#emote-${selectedEmote}`).css('color', '#53fc18');

  }

})();
// Puts the emote in the input
function sendEmote(emote) {
  $('#emotePopup').css('display', 'none');
  var words = $('.chat-input').text().trim().split(' ');
  var lastword = words[words.length - 1];
  for (var i = 0; i < lastword.length; i++)
    document.execCommand("delete");
  $('.chat-input').focus();
  document.execCommand("insertText", false, emote);
}

async function loadEmotes() {
  var emotelist = await fetch(`https://kick.com/emotes/${document.URL.split('/')[3]}`);
  var emotesJson = await emotelist.json();
  var emotes = [];
  emotesJson.forEach((emoteGroup) => {
    emoteGroup.emotes.forEach((emote) => {
      emotes.push(emote);
    });
  });

  fuse = new Fuse(emotes, fuseoptions);
}

function actionFunction(chatroom) {
  chatroom.prepend('<ul id="emotePopup" style="display: none;"></ul>');

  $('.chat-input').on('propertychange input', (e) => {
    var words = e.target.textContent.trim().split(' ');
    var lastword = words[words.length - 1];
    if (lastword.startsWith(':')) {
      $('#emotePopup').empty();
      $('#emotePopup').css('display', 'block');
      fuse.search(lastword).slice(0, 5).forEach((e, i, a) => {
        $('#emotePopup').append(`<li><button class="emoteButton" id="emote-${i}" style="display: block ruby"><img width=25 height=25 src=https://files.kick.com/emotes/${e.item.id}/fullsize /> ${e.item.name} </button></li>`);
      });
      selectedEmote = 0;
      $(`#emote-${selectedEmote}`).css('color', '#53fc18');

      $('.emoteButton').on('click', (event) => {
        sendEmote(event.target.innerText.trim());
      });

    }
    else {
      $('#emotePopup').css('display', 'none');
    }
  })
}