UNIT3D chatbox - enhanced ULCX

Chat functionalities: Reply, Message and Gift buttons. BBCode buttons. Toggle menu. Emojis.

// ==UserScript==
// @name         UNIT3D chatbox - enhanced ULCX
// @version      1.2
// @description  Chat functionalities: Reply, Message and Gift buttons. BBCode buttons. Toggle menu. Emojis. 
// @match        https://upload.cx/
// @grant        none
// @namespace https://greasyfork.org/users/1344404
// ==/UserScript==

(function() {
    'use strict';
    //Please do not alter this, It is for contributors to the project only.
            const USER_COLORS = {
    'ace': '#ef008c',
    'TheoneandonlyPook': '#ef008c',
    'Demonic': '#ffac6b',
    }

    // Function to extract the CSRF token
    function extractToken() {
        const tokenElement = document.querySelector('meta[name="csrf-token"]');
        return tokenElement ? tokenElement.content : 'Token not found';
    }

    // Function to extract the user from the URL
    function extractUser() {
        const userLink = document.querySelector('a.top-nav__username--highresolution');
        if (userLink) {
            const url = new URL(userLink.href);
            return url.pathname.split('/').pop();
        }
        return 'User not found';
    }

    // Function to remove the dialog from the page
    function removeDialog() {
        const existingDialog = document.querySelector('dialog');
        if (existingDialog) {
            existingDialog.remove();
        }
    }

    const chatboxID = '#chatbox__messages-create';
    const chatMessagesClassName = '.chatroom__messages';
    const onlineUserListSelector = '.blocks__online .panel__body ul';
    const additionalUserListSelector = '.chatroom-users__list';
    const bbCodesPanelID = 'bbCodesPanel';
    const settingsButtonID = 'settingsButton';
    const settingsPanelID = 'settingsPanel';
    const BBCODES_PANEL_HTML = `
<div id="${bbCodesPanelID}" style="position: relative; display: flex; flex-wrap: wrap; z-index: 9998;">
    <span id="imgButton" style="cursor: pointer; margin-right: 4px;" data-bbcode="[img][/img]">IMG</span>
    <span id="urlButton" style="cursor: pointer; margin-right: 4px;" data-bbcode="[url][/url]">URL</span>
    <span id="colorButton" style="cursor: pointer; margin-right: 4px;">Color</span>
    <input type="color" id="colorPicker" style="cursor: pointer; margin-left: 10px; display: none;" title="Select Color">
    <span style="cursor: pointer; margin: 4px;" id="emojiButton">😊</span>
    <div id="emojiMenu" style="display: none; position: absolute; left: 10px; top: 30px; background: #000000; border: 1px solid #ccc; z-index: 10000;">
        <span class="emoji" data-emoji="😊">😊</span>
        <span class="emoji" data-emoji="😂">😂</span>
        <span class="emoji" data-emoji="😍">😍</span>
        <span class="emoji" data-emoji="😇">😇</span>
        <span class="emoji" data-emoji="🤨">🤨</span>
        <span class="emoji" data-emoji="🥳">🥳</span>
        <span class="emoji" data-emoji="😏">😏</span>
        <span class="emoji" data-emoji="😞">😞</span>
        <span class="emoji" data-emoji="😤">😤</span>
        <span class="emoji" data-emoji="🤬">🤬</span>
        <span class="emoji" data-emoji="🤯">🤯</span>
        <span class="emoji" data-emoji="🥵">🥵</span>
        <span class="emoji" data-emoji="🥶">🥶</span>
        <span class="emoji" data-emoji="🤫">🤫</span>
        <span class="emoji" data-emoji="🤥">🤥</span>
        <span class="emoji" data-emoji="😴">😴</span>
        <span class="emoji" data-emoji="🤮">🤮</span>
        <span class="emoji" data-emoji="🤡">🤡</span>
        <span class="emoji" data-emoji="💩">💩</span>
        <span class="emoji" data-emoji="👻">👻</span>
        <span class="emoji" data-emoji="💀">💀</span>
        <span class="emoji" data-emoji="👽">👽</span>
        <span class="emoji" data-emoji="🎃">🎃</span>
        <span class="emoji" data-emoji="🤝">🤝</span>
        <span class="emoji" data-emoji="👍">👍</span>
        <span class="emoji" data-emoji="👎">👎</span>
        <span class="emoji" data-emoji="✌️">✌️</span>
        <span class="emoji" data-emoji="🖕">🖕</span>
        <span class="emoji" data-emoji="👮">👮</span>
        <span class="emoji" data-emoji="🕸️">🕸️</span>
        <span class="emoji" data-emoji="🐢">🐢</span>
        <span class="emoji" data-emoji="🐋">🐋</span>
        <span class="emoji" data-emoji="🐐">🐐</span>
        <span class="emoji" data-emoji="🐦‍🔥">🐦‍🔥</span>
        <span class="emoji" data-emoji="🌵">🌵</span>
        <span class="emoji" data-emoji="🎄">🎄</span>
        <span class="emoji" data-emoji="🔥">🔥</span>
        <span class="emoji" data-emoji="🌪️">🌪️</span>
        <span class="emoji" data-emoji="🌈">🌈</span>
        <span class="emoji" data-emoji="☀️">☀️</span>
        <span class="emoji" data-emoji="🌧️">🌧️</span>
        <span class="emoji" data-emoji="❄️">❄️</span>
        <span class="emoji" data-emoji="🍺">🍺</span>
        <span class="emoji" data-emoji="🩷">🩷</span>
        <span class="emoji" data-emoji="💔">💔</span>
        <span class="emoji" data-emoji="🛑">🛑</span>
        <span class="emoji" data-emoji="🏴‍☠️">🏴‍☠️</span>
        <!-- Add more emojis as needed -->
    </div>
    <div style="position: relative;">
        <span style="cursor: pointer;" id="bbCodeDropdown">➪</span>
        <div id="bbCodeDropdownMenu" style="display: none; position: absolute; left: 20px; top: -2px; flex-direction: row; z-index: 10000;">
            <span style="cursor: pointer; margin: 2px;" data-bbcode="[b][/b]">[B]</span>
            <span style="cursor: pointer; margin: 2px;" data-bbcode="[i][/i]">[I]</span>
            <span style="cursor: pointer; margin: 2px;" data-bbcode="[u][/u]">[U]</span>
        </div>
    </div>
</div>`;

    const SETTINGS_PANEL_HTML = `<div id="${settingsPanelID}" style="display: none; position: absolute; top: 20px; right: 0; background: rgba(0,0,0,0.9); border-radius: 8px; padding: 10px; color: white; z-index: 10001;">
            <label><input type="checkbox" id="toggleBBCodes" checked> Show BB Codes</label><br>
            <label><input type="checkbox" id="toggleMessageGift" checked> Show Message/Gift Buttons</label><br>
            <label><input type="checkbox" id="toggleReply" checked> Show Reply Button</label>
        </div>`;
    const TOGGLE_BUTTON_HTML = `<div id="${settingsButtonID}" style="cursor: pointer; color: #fff; display: inline-block; margin-left: 4px; font-size: 16px;">⚙️</div>`;
      // Create and add the style block
    const style = document.createElement('style');
    style.type = 'text/css';
    style.innerHTML = `
        .emoji {
            cursor: pointer;
        }
        .reply-icon, .message-icon, .gift-icon { cursor: pointer; margin-left: 5px; }
        .mention-dropdown { position: absolute; background: #333; border: 1px solid #ccc; max-height: 150px; overflow-y: auto; display: none; z-index: 10000; color: #ccc; }
        .mention-dropdown span { display: block; padding: 5px; cursor: pointer; color: #ccc; }
        .mention-dropdown span:hover { background: #555; }
        .panel__actions { position: relative; }
    `;
    document.head.appendChild(style);
    function saveSetting(key, value) {
        localStorage.setItem(key, value);
    }
    function loadSetting(key) {
        return localStorage.getItem(key);
    }
    function applySettings() {
        const toggleBBCodes = loadSetting('toggleBBCodes') === 'true';
        const toggleMessageGift = loadSetting('toggleMessageGift') === 'true';
        const toggleReply = loadSetting('toggleReply') === 'true';
        document.getElementById('toggleBBCodes').checked = toggleBBCodes;
        document.getElementById(bbCodesPanelID).style.display = toggleBBCodes ? 'flex' : 'none';
        document.getElementById('toggleMessageGift').checked = toggleMessageGift;
        const iconsMessageGift = document.querySelectorAll('.message-icon, .gift-icon');
        iconsMessageGift.forEach(icon => icon.style.display = toggleMessageGift ? 'inline' : 'none');
        document.getElementById('toggleReply').checked = toggleReply;
        const iconsReply = document.querySelectorAll('.reply-icon');
        iconsReply.forEach(icon => icon.style.display = toggleReply ? 'inline' : 'none');
    }
    function setupSettingsListeners() {
        document.getElementById('toggleBBCodes').addEventListener('change', (event) => {
            saveSetting('toggleBBCodes', event.target.checked);
            document.getElementById(bbCodesPanelID).style.display = event.target.checked ? 'flex' : 'none';
        });
        document.getElementById('toggleMessageGift').addEventListener('change', (event) => {
            saveSetting('toggleMessageGift', event.target.checked);
            const icons = document.querySelectorAll('.message-icon, .gift-icon');
            icons.forEach(icon => icon.style.display = event.target.checked ? 'inline' : 'none');
        });
        document.getElementById('toggleReply').addEventListener('change', (event) => {
            saveSetting('toggleReply', event.target.checked);
            const icons = document.querySelectorAll('.reply-icon');
            icons.forEach(icon => icon.style.display = event.target.checked ? 'inline' : 'none');
        });
    }
    function getOnlineUsernames() {
        const userElements = document.querySelectorAll(`${onlineUserListSelector} .user-tag__link`);
        const additionalUserElements = document.querySelectorAll(`${additionalUserListSelector} .user-tag__link`);
        const userSet = new Set([...Array.from(userElements), ...Array.from(additionalUserElements)].map(el => el.textContent.trim()));
        return Array.from(userSet);
    }
    function setupMentionFeature(chatbox) {
        const mentionDropdown = document.createElement('div');
        mentionDropdown.classList.add('mention-dropdown');
        document.body.appendChild(mentionDropdown);
        chatbox.addEventListener('input', function(event) {
            const cursorPosition = chatbox.selectionStart;
            const text = chatbox.value.substring(0, cursorPosition);
            const mentionMatch = text.match(/@(\w*)$/);
            if (mentionMatch) {
                const usernamePrefix = mentionMatch[1].toLowerCase();
                const users = getOnlineUsernames().filter(user => user.toLowerCase().startsWith(usernamePrefix));
                mentionDropdown.innerHTML = '';
                users.forEach(user => {
                    const userElement = document.createElement('span');
                    userElement.textContent = user;
                    userElement.addEventListener('click', () => {
                        chatbox.value = chatbox.value.substring(0, cursorPosition - usernamePrefix.length - 1) + '@' + user + ' ' + chatbox.value.substring(cursorPosition);
                        chatbox.focus();
                        mentionDropdown.style.display = 'none';
                    });
                    mentionDropdown.appendChild(userElement);
                });
                const rect = chatbox.getBoundingClientRect();
                mentionDropdown.style.left = `${rect.left}px`;
                mentionDropdown.style.top = `${rect.bottom}px`;
                mentionDropdown.style.display = 'block';
            } else {
                mentionDropdown.style.display = 'none';
            }
        });
        chatbox.addEventListener('keydown', (e) => {
            if (mentionDropdown.style.display === 'block' && e.key === 'Tab') {
                e.preventDefault();
                const firstUser = mentionDropdown.querySelector('span');
                if (firstUser) firstUser.click();
            }
        });
        document.addEventListener('click', function(event) {
            if (!mentionDropdown.contains(event.target)) mentionDropdown.style.display = 'none';
        });
    }

    // Function to add the dialog element to the page
    function addDialog(token, user, username) {
        // Check if a dialog already exists and remove it
        removeDialog();

        // Create dialog HTML
        const dialogHTML = `
        <dialog class="dialog" x-bind="dialogElement">
            <h3 class="dialog__heading">Gift BON to: ${username}</h3>
            <form class="dialog__form" method="POST" action="https://upload.cx/users/${user}/gifts" x-bind="dialogForm">
                <input type="hidden" name="_token" value="${token}" autocomplete="off">
                <input type="hidden" name="recipient_username" value="${username}">
                <p class="form__group">
                    <input id="bon" class="form__text" name="bon" type="text" pattern="[0-9]*" inputmode="numeric" placeholder=" ">
                    <label class="form__label form__label--floating" for="bon">Amount</label>
                </p>
                <p class="form__group">
                    <textarea id="message" class="form__textarea" name="message" placeholder=" "></textarea>
                    <label class="form__label form__label--floating" for="message">Message</label>
                </p>
                <p class="form__group">
                    <button type="submit" class="form__button form__button--filled">Gift</button>
                    <button type="button" class="form__button form__button--outlined">Cancel</button>
                </p>
            </form>
        </dialog>`;

        // Create a container <div> if one does not exist
        let container = document.querySelector('#dialog-container');
        if (!container) {
            container = document.createElement('div');
            container.id = 'dialog-container';
            document.body.appendChild(container);
        }

        // Add dialog HTML to the container
        container.innerHTML = dialogHTML;

        // Add styling for the backdrop
        const style = document.createElement('style');
        style.innerHTML = `
        dialog::backdrop {
            background-color: rgba(0, 0, 0, 0.8);
        }`;
        document.head.appendChild(style);

        // Get the dialog element and show it
        const dialog = container.querySelector('dialog');
        dialog.showModal();

        // Add event listener to the "Cancel" button to remove the dialog
        const cancelButton = dialog.querySelector('button[type="button"]');
        if (cancelButton) {
            cancelButton.addEventListener('click', removeDialog);
        }
    }

    function setupReplyFeatures(chatMessages) {
        //Please do not alter this, It is for contributors to the project only.
        const USER_COLORS = {
    'ace': '#ef008c',
    'TheoneandonlyPook': '#ef008c',
    'Demonic': '#ffac6b'

    // Add more users and colors as needed
};

        const newMessageTextArea = document.querySelector(chatboxID);

function rgbToHex(rgb) {
    // Convert RGB to HEX format
    const rgbArray = rgb.match(/\d+/g).map(Number);
    if (rgbArray.length === 3) {
        return `#${rgbArray.map(value => {
            const hex = value.toString(16).padStart(2, '0');
            return hex;
        }).join('')}`;
    }
    return rgb; // Return original if not in expected format
}

function quoteMessage(username, message) {
    const chatbox = document.querySelector(chatboxID);
    if (!chatbox) {
        console.error(`Chatbox not found: ${chatboxID}`);
        return;
    }

    // Default color if user is not found in USER_COLORS
    let userColor = '#ecc846'; // Default color

    // Check USER_COLORS first
    if (USER_COLORS.hasOwnProperty(username)) {
        userColor = USER_COLORS[username];
    } else {

        // If not in USER_COLORS, extract the color from the chat messages
        const messages = document.querySelectorAll('.chatbox-message, .message');
        for (const msg of messages) {
            const msgUsername = msg.querySelector(".chatbox-message__address.user-tag span, .message-username span");
            if (msgUsername && msgUsername.textContent.trim() === username) {
                const style = window.getComputedStyle(msgUsername);
                userColor = rgbToHex(style.color);
                break; // Stop searching once the user is found
            }
        }
    }

    // Debugging
    console.log(`Username: ${username}, Color used: ${userColor}`);

    // Create the quoted message
    const quoteText = `[color=${userColor}][b]${username}[/b][/color]: [color=#ffff80][i]"${message}"[/i][/color]`;

    // Append the quoted message to the chat input
    chatbox.value += `${quoteText}\n\n`;
    chatbox.focus();
    chatbox.setSelectionRange(chatbox.value.length, chatbox.value.length);
}

        function addReplyIconToMessage(message) {
            const content = message.querySelector(".chatbox-message__content")?.innerText || message.querySelector(".message-content")?.innerText;
            const username = message.querySelector(".chatbox-message__address.user-tag span")?.innerText || message.querySelector(".message-username span")?.innerText;
            const header = message.querySelector(".chatbox-message__header") || message.querySelector(".message-header");
            if (!content || !username || !header) return;
            const replyIcon = document.createElement("i");
            replyIcon.classList.add("fa", "solid", "fa-reply", "reply-icon");
            replyIcon.style.color = "#d82c20";
            replyIcon.addEventListener("click", () => quoteMessage(username, content));
            const messageIcon = document.createElement("i");
            messageIcon.classList.add("fa", "solid", "fa-envelope", "message-icon");
            messageIcon.style.color = "#118DFF";
            const giftIcon = document.createElement("i");
            giftIcon.classList.add("fa", "solid", "fa-gift", "gift-icon");
            giftIcon.style.color = "#f3c911";
            messageIcon.addEventListener("click", () => {
                newMessageTextArea.value += `/msg ${username} `;
                newMessageTextArea.focus();
            });
            giftIcon.addEventListener("click", () => {
                const token = extractToken();
                const user = extractUser();
                addDialog(token, user, username);
            });
            header.appendChild(replyIcon);
            header.appendChild(messageIcon);
            header.appendChild(giftIcon);
            applySettings();
        }
        document.querySelectorAll(".chatbox-message, .message").forEach(addReplyIconToMessage);
        const observer = new MutationObserver(function(mutationsList, observer) {
            document.querySelectorAll(".reply-icon, .message-icon, .gift-icon").forEach((icon) => icon.remove());
            document.querySelectorAll(".chatbox-message, .message").forEach(addReplyIconToMessage);
        });
        observer.observe(chatMessages, { childList: true });
    }
    function setupChatFeatures(chatbox) {
    const container = document.createElement('div');
    container.style.position = 'relative';
    container.style.display = 'inline-flex';
    chatbox.parentNode.insertBefore(container, chatbox.nextSibling);
    const bbCodesPanel = document.createElement('div');
    bbCodesPanel.innerHTML = BBCODES_PANEL_HTML;
    container.appendChild(bbCodesPanel);
    bbCodesPanel.style.background = 'transparent';
    bbCodesPanel.style.border = 'none';

    // BBCode Dropdown
    const bbCodeDropdown = document.getElementById('bbCodeDropdown');
    const bbCodeDropdownMenu = document.getElementById('bbCodeDropdownMenu');
    bbCodeDropdown.addEventListener('click', function() {
        bbCodeDropdownMenu.style.display = bbCodeDropdownMenu.style.display === 'flex' ? 'none' : 'flex';
    });

    // Emoji Button
    const emojiButton = document.getElementById('emojiButton');
    const emojiMenu = document.getElementById('emojiMenu');
    emojiButton.addEventListener('click', function() {
        emojiMenu.style.display = emojiMenu.style.display === 'block' ? 'none' : 'block';
    });

    // Emoji Menu
    emojiMenu.addEventListener('click', function(event) {
        if (event.target.classList.contains('emoji')) {
            const emoji = event.target.getAttribute('data-emoji');
            insertEmoji(emoji, chatbox);
            emojiMenu.style.display = 'none'; // Hide menu after selection
        }
    });

    // BBCode Buttons
    bbCodesPanel.querySelectorAll('span').forEach(function(span) {
        span.addEventListener('click', function() {
            const bbCode = span.getAttribute('data-bbcode');
            if (bbCode === "[img][/img]") {
                insertImgBBCodeWithClipboard(bbCode, chatbox);
            } else if (bbCode === "[url][/url]") {
                insertBBCodeWithClipboard(bbCode, chatbox);
            } else if (span.id === 'colorButton') {
                document.getElementById('colorPicker').style.display = 'block'; // Show color picker
            } else {
                insertBBCode(chatbox, bbCode);
            }
        });
    });

    // Color Picker
    document.getElementById('colorPicker').addEventListener('input', function(event) {
        const color = event.target.value;
        const colorBBCode = `[color=${color}][/color]`;
        chatbox.value += colorBBCode + " ";
        const pos = chatbox.value.length;
        chatbox.setSelectionRange(pos, pos);
        chatbox.focus();
        document.getElementById('colorPicker').style.display = 'none'; // Hide color picker after selection
    });

    setupMentionFeature(chatbox);
}

function insertEmoji(emoji, chatbox) {
    const pos = chatbox.selectionStart;
    chatbox.value = chatbox.value.substring(0, pos) + emoji + chatbox.value.substring(pos);
    chatbox.setSelectionRange(pos + emoji.length, pos + emoji.length);
    chatbox.focus();
}

    function insertBBCodeWithClipboard(tag, chatbox) {
        navigator.clipboard.readText().then(clipText => {
            const newContent = clipText.trim().length > 0
                ? tag.replace(/(\[.*?\])(.*?)(\[\/.*?\])/, `$1${clipText}$3`)
                : tag.replace(/(\[.*?\])(.*?)(\[\/.*?\])/, `$1$2$3`);
            chatbox.value += newContent + " ";
            const pos = chatbox.value.length;
            chatbox.setSelectionRange(pos, pos);
            chatbox.focus();
        }).catch((err) => {
            console.error('Failed to read clipboard contents:', err);
            chatbox.value += tag.replace(/(\[.*?\])(.*?)(\[\/.*?\])/, `$1$2$3`) + " ";
            const pos = chatbox.value.length;
            chatbox.setSelectionRange(pos, pos);
            chatbox.focus();
        });
    }
    function insertImgBBCodeWithClipboard(tag, chatbox) {
        navigator.clipboard.readText().then(clipText => {
            const newContent = clipText.trim().length > 0
                ? tag.replace(/(\[.*?\])(.*?)(\[\/.*?\])/, `$1${clipText}$3`)
                : tag.replace(/(\[.*?\])(.*?)(\[\/.*?\])/, `$1$2$3`);
            chatbox.value += newContent + "\n";
            const pos = chatbox.value.length;
            chatbox.setSelectionRange(pos, pos);
            chatbox.focus();
        }).catch((err) => {
            console.error('Failed to read clipboard contents:', err);
            chatbox.value += tag.replace(/(\[.*?\])(.*?)(\[\/.*?\])/, `$1$2$3`) + "\n";
            const pos = chatbox.value.length;
            chatbox.setSelectionRange(pos, pos);
            chatbox.focus();
        });
    }
    function insertBBCode(chatbox, bbCode) {
        const textSelected = chatbox.value.substring(chatbox.selectionStart, chatbox.selectionEnd);
        const startTag = bbCode.substring(0, bbCode.indexOf(']') + 1);
        const endTag = bbCode.substring(bbCode.lastIndexOf('['));
        if (textSelected.length > 0) {
            const newText = startTag + textSelected + endTag;
            chatbox.value = chatbox.value.substring(0, chatbox.selectionStart) + newText + " " + chatbox.value.substring(chatbox.selectionEnd);
            const newPos = chatbox.value.lastIndexOf(' ') + 1;
            chatbox.setSelectionRange(newPos, newPos);
        } else {
            const pos = chatbox.selectionStart + startTag.length;
            chatbox.value += startTag + endTag + " ";
            chatbox.setSelectionRange(pos, pos);
        }
        chatbox.focus();
    }
function setupSettingsPanel() {
    const chatboxHeaderActions = document.querySelector('#chatbox_header .panel__actions');
    if (chatboxHeaderActions) {
        chatboxHeaderActions.insertAdjacentHTML('beforeend', TOGGLE_BUTTON_HTML);
        const settingsPanel = document.createElement('div');
        settingsPanel.innerHTML = `
            <div id="${settingsPanelID}" style="display: none; position: absolute; top: 30px; right: 0; background: rgba(0,0,0,0.9); border-radius: 8px; padding: 10px; color: white; z-index: 10001;">
                <label><input type="checkbox" id="toggleBBCodes" checked> Show BB Codes</label><br>
                <label><input type="checkbox" id="toggleMessageGift" checked> Show Message/Gift Buttons</label><br>
                <label><input type="checkbox" id="toggleReply" checked> Show Reply Button</label>
            </div>`;
        chatboxHeaderActions.appendChild(settingsPanel);
        const toggleSettingsButton = document.getElementById(settingsButtonID);
        const settingsPanelElement = document.getElementById(settingsPanelID);
        toggleSettingsButton.addEventListener('click', (event) => {
            event.stopPropagation(); // Prevent event from bubbling up
            const isPanelVisible = settingsPanelElement.style.display === 'block';
            settingsPanelElement.style.display = isPanelVisible ? 'none' : 'block';
        });
        document.addEventListener('click', (event) => {
            if (!settingsPanelElement.contains(event.target) && !toggleSettingsButton.contains(event.target)) {
                settingsPanelElement.style.display = 'none'; // Hide when clicking outside
            }
        });
        applySettings();
        setupSettingsListeners();
    } else {
        console.error("Failed to attach the settings button: '#chatbox_header .panel__actions' not found.");
    }
}
    function checkAndSetup() {
        const chatbox = document.querySelector(chatboxID);
        const chatMessages = document.querySelector(chatMessagesClassName);
        if (chatbox) {
            setupChatFeatures(chatbox);
            setupSettingsPanel();
        } else {
            console.error('Chatbox not found: Ensure the chatbox ID is correct.');
        }
        if (chatMessages) {
            setupReplyFeatures(chatMessages);
        } else {
            console.error('Chat messages not found: Ensure the chatMessages class is correct.');
        }
        if (!chatbox || !chatMessages) {
            setTimeout(checkAndSetup, 1000);
        }

    }

    checkAndSetup();

})();