Torn.com Enhanced Chat Buttons V2

Add customizable buttons to Torn.com chat

当前为 2024-05-24 提交的版本,查看 最新版本

// ==UserScript==
// @name         Torn.com Enhanced Chat Buttons V2
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Add customizable buttons to Torn.com chat
// @author       Created by Callz [2188704], updated by Weav3r [1853324]
// @match        https://www.torn.com/*
// @grant        GM_setClipboard
// ==/UserScript==

(function() {
    'use strict';

    const buttonCSS = `
        .custom-chat-button {
            background-color: #007BFF;
            color: white;
            padding: 2px 7px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 14px;
            margin: 4px 6px;
            cursor: pointer;
            border-radius: 5px;
            border: none;
            transition: background-color 0.3s ease;
            min-width: 80px;
            overflow: hidden;
            white-space: nowrap;
        }

        .custom-chat-button:hover {
            background-color: #0056b3;
        }

        .custom-chat-button.recent {
            border: 2px solid #FFD700;
            box-shadow: 0 0 5px rgba(255, 215, 0, 0.8);
        }

        .custom-ui-panel label {
            font-size: 20px;
            margin-bottom: 20px;
        }

        .custom-ui-panel {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: #f5f5f5;
            padding: 20px;
            color: black;
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
            z-index: 9999999999;
            max-width: 70%;
        }

        .custom-ui-panel h3 {
            font-size: 20px;
            margin-bottom: 20px;
        }

        .custom-ui-panel input[type="text"],
        .custom-ui-panel select,
        .custom-ui-panel textarea {
            width: 90%;
            padding: 10px;
            margin-top:10px;
            margin-bottom: 15px;
            border: 1px solid #ccc;
            border-radius: 5px;
            font-size: 16px;
        }

        .custom-ui-panel input[type="color"] {
            padding: 0;
        }

        .custom-ui-panel button {
            background-color: #007BFF;
            color: white;
            border: none;
            padding: 10px 16px;
            border-radius: 5px;
            cursor: pointer;
            margin: 10px 5px;
            font-size: 16px;
            transition: background-color 0.3s ease;
        }

        .custom-ui-panel button#close-ui {
            background-color: #ccc;
            margin-right: 10px;
        }

        .custom-ui-panel button#close-ui:hover {
            background-color: #999;
        }

        .custom-ui-panel textarea {
            height: 100px;
            resize: vertical;
        }
        .custom-ui-panel hr {
            margin: 20px 0;
            border: 0;
            border-top: 1px solid #ccc;
        }
        #chat-config-button {
           color:green;
       }
       #button-configs {
        max-height: 200px;
        overflow-y: scroll;
       }
    `;

    const conditions = {
        TradeChat: chatBox => chatBox.querySelector('.chat-box-header__name___jIjjM').textContent === 'Trade',
        HospitalChat: chatBox => chatBox.querySelector('.chat-box-header__name___jIjjM').textContent === 'Hospital',
        FactionChat: chatBox => chatBox.querySelector('.chat-box-header__name___jIjjM').textContent === 'Faction',
        CompanyChat: chatBox => chatBox.querySelector('.chat-box-header__name___jIjjM').textContent === 'Company',
        GlobalChat: chatBox => chatBox.querySelector('.chat-box-header__name___jIjjM').textContent === 'Global',
        UserChat: chatBox => chatBox.querySelector('.chat-box-header__options___nTsMU'),
    };

    function addCSS(cssString) {
        const style = document.createElement('style');
        style.textContent = cssString;
        document.head.append(style);
    }

    function getButtonConfigurations() {
        return JSON.parse(localStorage.getItem('chatButtonConfig')) || { buttons: [] };
    }

    function saveButtonConfigurations(config) {
        localStorage.setItem('chatButtonConfig', JSON.stringify(config));
    }

    function createUIPanel() {
        const panel = document.createElement('div');
        panel.className = 'custom-ui-panel';
        panel.innerHTML = `
            <h3>Chat Button Configuration</h3>
            <div id="button-configs"></div>
            <hr>
            <div>
                <input type="text" id="button-text" placeholder="Button Text">
                <label for="button-color">Background Color:</label>
                <input type="color" id="button-color">
                <select id="button-condition">
                    <option value="TradeChat">Trade Chat</option>
                    <option value="HospitalChat">Hospital Chat</option>
                    <option value="FactionChat">Faction Chat</option>
                    <option value="CompanyChat">Company Chat</option>
                    <option value="GlobalChat">Global Chat</option>
                    <option value="UserChat">User Chat</option>
                </select>
                <textarea id="button-text-content" placeholder="Add the text here that should be pasted in chat. You can use {name} to get the name of the active chat"></textarea>
                <button id="add-button">Add Button</button>
                <button id="edit-button" style="display: none;">Edit Button</button>
            </div>
            <button id="close-ui">Close</button>
        `;
        document.body.appendChild(panel);

        document.getElementById('add-button').addEventListener('click', addNewButtonConfig);
        document.getElementById('edit-button').addEventListener('click', editButtonConfig);
        document.getElementById('close-ui').addEventListener('click', closeUI);
        populateButtonConfigs();
    }

    function populateButtonConfigs() {
        const configsContainer = document.getElementById('button-configs');
        configsContainer.innerHTML = '';
        const configs = getButtonConfigurations();

        configs.buttons.forEach((buttonConfig, index) => {
            const configDiv = document.createElement('div');
            configDiv.innerHTML = `
                <div>Text: ${buttonConfig.buttonText}</div>
                <div>Color: ${buttonConfig.backgroundColor}</div>
                <div>Condition: ${buttonConfig.condition}</div>
                <div>Message: ${buttonConfig.text}</div>
            `;

            const editButton = document.createElement('button');
            editButton.textContent = 'Edit';
            editButton.addEventListener('click', () => selectForEdit(index));
            configDiv.appendChild(editButton);

            const deleteButton = document.createElement('button');
            deleteButton.textContent = 'Delete';
            deleteButton.addEventListener('click', () => deleteButtonConfig(index));
            configDiv.appendChild(deleteButton);

            configsContainer.appendChild(configDiv);
        });
    }

    function selectForEdit(index) {
        const config = getButtonConfigurations().buttons[index];
        document.getElementById('button-text').value = config.buttonText;
        document.getElementById('button-color').value = config.backgroundColor;
        document.getElementById('button-condition').value = config.condition;
        document.getElementById('button-text-content').value = config.text;

        document.getElementById('edit-button').style.display = 'block';
        document.getElementById('edit-button').setAttribute('data-edit-index', index);
    }

    function deleteButtonConfig(index) {
        const config = getButtonConfigurations();
        config.buttons.splice(index, 1);
        saveButtonConfigurations(config);
        populateButtonConfigs();
    }

    function addNewButtonConfig() {
        const buttonText = document.getElementById('button-text').value;
        const backgroundColor = document.getElementById('button-color').value;
        const condition = document.getElementById('button-condition').value;
        const text = document.getElementById('button-text-content').value;

        const config = getButtonConfigurations();
        config.buttons.push({ buttonText, backgroundColor, condition, text });
        saveButtonConfigurations(config);
        populateButtonConfigs();
    }

    function editButtonConfig() {
        const index = parseInt(document.getElementById('edit-button').getAttribute('data-edit-index'), 10);
        const buttonText = document.getElementById('button-text').value;
        const backgroundColor = document.getElementById('button-color').value;
        const condition = document.getElementById('button-condition').value;
        const text = document.getElementById('button-text-content').value;

        const config = getButtonConfigurations();
        config.buttons[index] = { buttonText, backgroundColor, condition, text };
        saveButtonConfigurations(config);
        populateButtonConfigs();
    }

    function closeUI() {
        document.querySelector('.custom-ui-panel').remove();
    }

    function createConfigButton() {
        const settingsPanel = document.querySelector('.settings-panel___IZSDs');
        if (settingsPanel && !document.querySelector('#chat-config-button')) {
            const configButton = document.createElement('button');
            configButton.id = 'chat-config-button';
            configButton.textContent = 'Edit Chat Buttons';
            configButton.addEventListener('click', createUIPanel);
            settingsPanel.appendChild(configButton);
        }
    }

    function applyButtonConfigurations() {
        const configs = getButtonConfigurations();
        document.querySelectorAll('.chat-box___mHm01').forEach(chatBox => {
            configs.buttons.forEach(buttonConfig => {
                const conditionFunc = conditions[buttonConfig.condition];
                if (conditionFunc && conditionFunc(chatBox) && !chatBox.querySelector(`[data-button-text="${buttonConfig.buttonText}"]`)) {
                    const button = document.createElement('button');
                    button.className = 'custom-chat-button';
                    button.innerText = buttonConfig.buttonText;
                    button.style.backgroundColor = buttonConfig.backgroundColor;
                    button.setAttribute('data-button-text', buttonConfig.buttonText);
                    button.addEventListener('click', (event) => addCustomText(chatBox, buttonConfig.text, event));

                    const filterContainer = chatBox.querySelector('.tt-chat-filter');
                    filterContainer.insertBefore(button, filterContainer.firstChild);
                }
            });
        });
    }

    function addCustomText(chatBox, messageTemplate, event) {
        const nameElement = chatBox.querySelector('.typography___Dc5WV');
        const name = nameElement ? nameElement.textContent.trim() : 'Trader';
        const message = messageTemplate.replace('{name}', name);

        navigator.clipboard.writeText(message).then(() => {
            const textArea = chatBox.querySelector('textarea');
            textArea.focus();
            const startPos = textArea.selectionStart;
            const endPos = textArea.selectionEnd;
            textArea.setRangeText(message, startPos, endPos, 'end');
            textArea.dispatchEvent(new Event('input', { bubbles: true }));
            textArea.focus();
            textArea.selectionStart = textArea.selectionEnd = startPos + message.length;
            chatBox.querySelectorAll('.custom-chat-button').forEach(btn => {
                btn.classList.remove('recent');
            });
            event.target.classList.add('recent');
        });
    }

    addCSS(buttonCSS);

    const chatContainerObserver = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            createConfigButton();
            applyButtonConfigurations();
        });
    });

    const chatContainer = document.querySelector('#chatRoot');
    if (chatContainer) {
        chatContainerObserver.observe(chatContainer, { childList: true, subtree: true });
    }

    applyButtonConfigurations();
})();