Discord Catbox Uploader

Adds a button to upload files to catbox.moe in Discord

目前為 2024-09-30 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        Discord Catbox Uploader
// @namespace   https://tampermonkey.net/
// @version     1.3
// @description Adds a button to upload files to catbox.moe in Discord
// @author      OasisVee
// @match       https://*.discord.com/*
// @grant       GM_xmlhttpRequest
// @grant       GM_setClipboard
// @grant       GM_addStyle
// @connect     catbox.moe
// @icon        https://www.google.com/s2/favicons?sz=64&domain=catbox.moe
// @license     MIT
// ==/UserScript==

(function() {
    'use strict';

    const STYLES = `
        .catbox-tooltip {
            position: absolute;
            background-color: #202225;
            color: #dcddde;
            padding: 8px 12px;
            border-radius: 5px;
            font-size: 14px;
            font-weight: 500;
            pointer-events: none;
            opacity: 0;
            transition: opacity 0.1s ease-in-out;
            z-index: 9999;
            top: -30px;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
            white-space: nowrap;
            border: 1px solid #36393F;
        }
        .catbox-tooltip::before {
            content: '';
            position: absolute;
            width: 0;
            height: 0;
            border: 8px solid transparent;
            border-top-color: #202225;
            bottom: -16px;
            left: 50%;
            transform: translateX(-50%);
        }
    `;

    const CAT_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor"><path d="M12,8L10.67,8.09C9.81,7.07 7.4,4.5 5,4.5C5,4.5 3.03,7.46 4.96,11.41C4.41,12.24 4.07,12.67 4,13.66L2.07,18.37L2.06,18.39C1.61,19.31 2.08,20.68 3,21.13L3.09,21.17C3.42,21.31 3.77,21.35 4.09,21.3C4.39,21.33 4.7,21.27 4.95,21.13L5.36,20.94C6.35,20.44 6.69,20.18 7.12,20.03C7.88,19.83 8.88,19.9 10.01,19.9H14C15.15,19.9 16.15,19.83 16.91,20.03C17.34,20.18 17.66,20.44 18.65,20.94L19.06,21.13C19.3,21.27 19.61,21.33 19.91,21.3C20.23,21.35 20.58,21.31 20.91,21.17L21,21.13C21.92,20.68 22.39,19.31 21.94,18.39L21.93,18.37L20,13.66C19.93,12.67 19.59,12.24 19.04,11.41C20.97,7.46 19,4.5 19,4.5C16.6,4.5 14.19,7.07 13.33,8.09L12,8M9,11A1,1 0 0,1 10,12A1,1 0 0,1 9,13A1,1 0 0,1 8,12A1,1 0 0,1 9,11M15,11A1,1 0 0,1 16,12A1,1 0 0,1 15,13A1,1 0 0,1 14,12A1,1 0 0,1 15,11M11,14H13L12.3,15.39C12.5,16.03 13.06,16.5 13.75,16.5A1.5,1.5 0 0,0 15.25,15H15.75A2,2 0 0,1 13.75,17C13,17 12.35,16.59 12,16V16H12C11.65,16.59 11,17 10.25,17A2,2 0 0,1 8.25,15H8.75A1.5,1.5 0 0,0 10.25,16.5C10.94,16.5 11.5,16.03 11.7,15.39L11,14Z"/></svg>`;

    const catboxButtonTemplate = document.createElement('button');
    catboxButtonTemplate.id = 'catbox-upload-btn';
    catboxButtonTemplate.innerHTML = CAT_SVG;
    catboxButtonTemplate.setAttribute('data-tooltip', 'Upload to Catbox');

    const fileInput = document.createElement('input');
    fileInput.type = 'file';

    const tooltipElement = document.createElement('div');
    tooltipElement.className = 'catbox-tooltip';

    const notificationElement = document.createElement('div');
    notificationElement.style.cssText = `
        position: fixed;
        top: 10px;
        right: 10px;
        padding: 10px 20px;
        border-radius: 5px;
        color: white;
        font-weight: bold;
        z-index: 9999;
        opacity: 0;
        transition: opacity 0.3s ease-in-out;
    `;

    function addCatboxButton() {
        const uploadButton = document.querySelector('button.attachButton_f298d4.attachButton_d0696b');
        if (uploadButton && !document.getElementById('catbox-upload-btn')) {
            const catboxButton = catboxButtonTemplate.cloneNode(true);
            catboxButton.className = uploadButton.className;
            catboxButton.style.cssText = `
                vertical-align: top;
                padding: 0px 8px;
                height: 0px;
                line-height: 0px;
                top: -20px;
                margin-left: 23px;
                position: relative;
                transform: translateX(0px);
                color: white;
                opacity: 80%;
                display: flex;
                align-items: center;
                justify-content: center;
            `;
            catboxButton.addEventListener('click', handleCatboxUpload);
            catboxButton.addEventListener('mouseenter', showTooltip);
            catboxButton.addEventListener('mouseleave', hideTooltip);
            uploadButton.parentNode.insertBefore(catboxButton, uploadButton.nextSibling);
            return true;
        }
        return false;
    }

    function showTooltip(event) {
        const button = event.currentTarget;
        tooltipElement.textContent = button.getAttribute('data-tooltip');
        document.body.appendChild(tooltipElement);
        const buttonRect = button.getBoundingClientRect();
        const tooltipRect = tooltipElement.getBoundingClientRect();
        tooltipElement.style.left = `${buttonRect.left + (buttonRect.width / 2) - (tooltipRect.width / 2)}px`;
        tooltipElement.style.top = `${buttonRect.top - tooltipRect.height - 15}px`;
        requestAnimationFrame(() => tooltipElement.style.opacity = '1');
    }

    function hideTooltip() {
        tooltipElement.style.opacity = '0';
        setTimeout(() => {
            if (tooltipElement.parentNode) {
                tooltipElement.parentNode.removeChild(tooltipElement);
            }
        }, 100);
    }

    function handleCatboxUpload(event) {
        event.preventDefault();
        event.stopPropagation();
        fileInput.click();
    }

    function uploadFile(file) {
        const formData = new FormData();
        formData.append('reqtype', 'fileupload');
        formData.append('fileToUpload', file);

        GM_xmlhttpRequest({
            method: 'POST',
            url: 'https://catbox.moe/user/api.php',
            data: formData,
            onload: handleUploadResponse,
            onerror: () => showNotification('Error uploading to Catbox.moe. Please try again.', 'error')
        });
    }

    function handleUploadResponse(response) {
        if (response.status === 200) {
            GM_setClipboard(response.responseText);
            showNotification('File uploaded and link copied to clipboard!', 'success');
        } else {
            showNotification('Error uploading to Catbox.moe. Please try again.', 'error');
        }
    }

    function showNotification(message, type) {
        notificationElement.textContent = message;
        notificationElement.style.backgroundColor = type === 'error' ? '#ff4444' : '#00C851';
        document.body.appendChild(notificationElement);
        requestAnimationFrame(() => {
            notificationElement.style.opacity = '1';
            setTimeout(() => {
                notificationElement.style.opacity = '0';
                setTimeout(() => document.body.removeChild(notificationElement), 300);
            }, 3000);
        });
    }

    function init() {
        GM_addStyle(STYLES);
        const observer = new MutationObserver((mutations) => {
            if (mutations.some(mutation => mutation.addedNodes.length > 0)) {
                addCatboxButton();
            }
        });
        observer.observe(document.body, { childList: true, subtree: true });
        fileInput.addEventListener('change', event => {
            const file = event.target.files[0];
            if (file) uploadFile(file);
        });
        addCatboxButton();
    }

    init();
})();