IdlePixel - Zlef's Chat Addons

Functions focused around chat on idle pixel. V1 Emoji button, font size up and down buttons

// ==UserScript==
// @name         IdlePixel - Zlef's Chat Addons
// @namespace    com.zlef.idlepixel
// @version      1.0.4
// @description  Functions focused around chat on idle pixel. V1 Emoji button, font size up and down buttons
// @author       Zlef
// @license      MIT
// @match        https://idle-pixel.com/login/play/
// @grant        none
// ==/UserScript==


(function() {
    'use strict';

    const shouldCloseOnSelect = false;
    const emoji_list = ['128512', '128513', '128514', '128515', '128516', '128517', '128518', '128519', '128520', '128521', '128522', '128523', '128524', '128525', '128526', '128527', '128528', '128529', '128530', '128531', '128532', '128533', '128534', '128535', '128536', '128537', '128538', '128539', '128540', '128541', '128542', '128543', '128544', '128545', '128546', '128547', '128548', '128549', '128550', '128551', '128552', '128553', '128554', '128555', '128556', '128557', '128558', '128559', '128560', '128561', '128562', '128563', '128564', '128565', '128566', '128567', '128577', '128578', '128579', '128580', '129296', '129297', '129298', '129299', '129300', '129301', '129303', '129312', '129314', '129315', '129316', '129317', '129319', '129320', '129321', '129322', '129323', '129325', '129326', '129327', '129392', '129393', '129395', '129396', '129397', '129398', '129402', '129488', '128568', '128569', '128570', '128571', '128572', '128573', '128574', '128575', '128576', '128584', '128585', '128586', '128127', '128128', '129324']
    const emojisPerRow = 6;
    const emojisPerCol = 5;
    const emojiSize = '24px';
    let currentPage = 0; // Start at the first page

    function updatePopupContent(popup) {
        popup.empty();

        const navDiv = $('<div id="emoji-nav"></div>');
        const emojiDiv = $('<div id="emoji-container"></div>').css({
            "display": "grid",
            "grid-template-columns": `repeat(${emojisPerRow}, auto)`
        });
        const prevButton = $('<span id="emoji-prev-button"><</span>');
        const nextButton = $('<span id="emoji-next-button">></span>');
        prevButton.css({
            "padding": "10px 20px",
            "font-size": "1.5em",
            "line-height": "0.5em",  // Adjust the line height
            "height": "1.5em", // Add the height property
            "color": currentPage > 0 ? "black" : "grey",
            "cursor": "pointer"
        });

        nextButton.css({
            "padding": "10px 20px",
            "font-size": "1.5em",
            "line-height": "0.5em", // Adjust the line height
            "height": "1.5em", // Add the height property
            "color": currentPage < Math.ceil(emoji_list.length / (emojisPerRow * emojisPerCol)) - 1 ? "black" : "grey",
            "cursor": "pointer"
        });

        const separator = $('<hr style="border: 1px solid lightgrey; margin-top: 10px; margin-bottom: 10px;">');

        navDiv.append(prevButton, nextButton);
        navDiv.css({
            "display": "flex",
            "justify-content": "space-between",
            "padding": "5px",
            "font-size": emojiSize,
            "cursor": "pointer",
            "color": "black"
        });

        popup.append(navDiv);
        popup.append(separator);
        popup.append(emojiDiv);

        prevButton.css("color", currentPage > 0 ? "black" : "grey");
        nextButton.css("color", currentPage < Math.ceil(emoji_list.length / (emojisPerRow * emojisPerCol)) - 1 ? "black" : "grey");

        const start = currentPage * emojisPerRow * emojisPerCol;
        const end = start + emojisPerRow * emojisPerCol;
        const page_emoji_list = emoji_list.slice(start, end);

        // Existing code for adding emojis from page_emoji_list
        page_emoji_list.forEach(function(emojiCode) {
            const emojiChar = String.fromCodePoint(parseInt(emojiCode));
            const item = $('<div class="emoji-item"></div>').text(emojiChar);
            item.css({
                "padding": "10px",
                "text-align": "center",
                "cursor": "pointer",
                "font-size": emojiSize,
                "min-width": "1em"
            });
            emojiDiv.append(item);
        });

        // New code for filling up remaining emojis to make it divisible by 30
        const remainingEmojis = (emojisPerRow * emojisPerCol) - page_emoji_list.length;
        for (let i = 0; i < remainingEmojis; i++) {
            const hiddenEmojiChar = String.fromCodePoint(128064);
            const hiddenItem = $('<div class="emoji-item"></div>').text(hiddenEmojiChar);
            hiddenItem.css({
                "padding": "10px",
                "text-align": "center",
                "cursor": "pointer",
                "font-size": emojiSize,
                "min-width": "1em",
                "visibility": "hidden" // Make the extra emoji invisible
            });
            emojiDiv.append(hiddenItem);
        }
    }

    function createPopup() {
        const popup = $('<div id="emoji-popup"></div>');
        popup.css({
            "position": "absolute",
            "background-color": "#fff",
            "border": "1px solid #ccc",
            "display": "flex",
            "flex-direction": "column",
            "overflow": "auto",
            "z-index": "9999"
        });

        updatePopupContent(popup);

        $('body').append(popup);
        return popup;
    }


    function increaseFontSize() {
        let currentSize = parseInt($("#chat-area").css('font-size'));
        if (isNaN(currentSize)) {
            currentSize = 16;
        }
        $("#chat-area").css('font-size', (currentSize + 1) + "px");
    }

    function decreaseFontSize() {
        let currentSize = parseInt($("#chat-area").css('font-size'));
        if (isNaN(currentSize)) {
            currentSize = 16;
        }
        if (currentSize > 10) {
            $("#chat-area").css('font-size', (currentSize - 1) + "px");
        }
    }

    $("#chat-area-input").before('<button id="chat-emojis-button" style="color: blue;margin-left: 2px;margin-right: 2px;">&#128512;</button>');

    $(".btn-chat-configure:last").after(`
    <button id="chat-font-down-button" style="color: blue;margin-left: 2px;margin-right: 2px;">FONT DOWN</button>
    <button id="chat-font-up-button" style="color: blue;margin-left: 2px;margin-right: 2px;">FONT UP</button>`);

    $("#chat-font-down-button").on("click", function() {
        decreaseFontSize();
    });

    $("#chat-font-up-button").on("click", function() {
        increaseFontSize();
    });

    const emojiPopup = createPopup();
    emojiPopup.hide();

    $("#chat-emojis-button").on("click", function() {
        const buttonHeight = $(this).outerHeight();
        const popupHeight = emojiPopup.outerHeight();
        const offset = $(this).offset();

        // Position the popup's bottom edge right above the button's top edge
        emojiPopup.css({
            top: offset.top - popupHeight,
            left: offset.left
        });

        // If popup is already showing, toggle will hide it.
        if(!emojiPopup.is(":visible")) {
            // If popup is hidden, this will make it visible.
            emojiPopup.show();

            const newPopupHeight = emojiPopup.outerHeight();
            if (newPopupHeight !== popupHeight) {
                emojiPopup.css({
                    top: offset.top - newPopupHeight,
                });
            }
        } else {
            // If popup is showing, this will hide it.
            emojiPopup.hide();
        }
    });

    // Navigation button click handlers
    $(document).on('click', '#emoji-prev-button, #emoji-next-button', function(event) {
        event.stopPropagation(); // Stop the event from propagating to close the popup

        if ($(this).is("#emoji-prev-button") && currentPage > 0) {
            currentPage--;
            updatePopupContent(emojiPopup);
        }
        if ($(this).is("#emoji-next-button") && currentPage < Math.ceil(emoji_list.length / (emojisPerRow * emojisPerCol)) - 1) {
            currentPage++;
            updatePopupContent(emojiPopup);
        }
    });

    $(document).on('keydown', function(event) {
        if (emojiPopup.is(":visible")) {
            if (event.key === "ArrowLeft" && currentPage > 0) {
                currentPage--;
                updatePopupContent(emojiPopup);
            } else if (event.key === "ArrowRight" && currentPage < Math.ceil(emoji_list.length / (emojisPerRow * emojisPerCol)) - 1) {
                currentPage++;
                updatePopupContent(emojiPopup);
            } else if (event.key === "Enter") {
                $("button[onclick='Chat.send()']").click();

                // Close the emoji popup
                emojiPopup.hide();
            }
        }
    });


    $(document).on('click', function(event) {
        if (!$(event.target).closest("#emoji-popup, #chat-emojis-button").length) {
            emojiPopup.hide();
        }
    });

    $(document).on('click', '.emoji-item', function() {
        const selectedEmoji = $(this).text();
        const chatInput = $("#chat-area-input");
        chatInput.val(chatInput.val() + selectedEmoji);

        if (shouldCloseOnSelect) {
            emojiPopup.hide();
        }
    });
})();