- // ==UserScript==
- // @name Enhanced Catbox File Uploader with Auto-Close Drop Zone and Duration Option
- // @namespace https://catbox.moe/
- // @version 1.1
- // @description Upload files to Catbox with URL history, customizable duration, minimize support, middle-click to open in new tab, auto-close drop zone if no file is dropped within 3 seconds.
- // @match *://litterbox.catbox.moe/*
- // @match *://catbox.moe/*
- // @match *://*/*
- // @grant GM_addStyle
- // @grant GM_setValue
- // @grant GM_getValue
- // ==/UserScript==
- (function() {
- 'use strict';
-
- // Create necessary DOM elements
- const uploadButton = document.createElement('div');
- uploadButton.id = 'uploadButton';
- uploadButton.innerHTML = '⬆';
- document.body.appendChild(uploadButton);
-
- const fileInput = document.createElement('input');
- fileInput.type = 'file';
- fileInput.style.display = 'none';
- document.body.appendChild(fileInput);
-
- const urlTextBox = document.createElement('input');
- urlTextBox.type = 'text';
- urlTextBox.id = 'fileUrl';
- urlTextBox.placeholder = 'URL will appear here';
- urlTextBox.readOnly = true;
- urlTextBox.style.display = 'none';
- document.body.appendChild(urlTextBox);
-
- const copyButton = document.createElement('div');
- copyButton.id = 'copyButton';
- copyButton.innerHTML = '📋';
- copyButton.style.display = 'none';
- document.body.appendChild(copyButton);
-
- const dropZone = document.createElement('div');
- dropZone.id = 'dropZone';
- dropZone.innerText = 'Drag & Drop File Here';
- dropZone.style.display = 'none';
- document.body.appendChild(dropZone);
-
- const minimizeButton = document.createElement('div');
- minimizeButton.id = 'minimizeButton';
- minimizeButton.innerHTML = '—';
- minimizeButton.style.display = 'none';
- document.body.appendChild(minimizeButton);
-
- const historyButton = document.createElement('div');
- historyButton.id = 'historyButton';
- historyButton.innerHTML = '📜';
- historyButton.style.display = 'none';
- document.body.appendChild(historyButton);
-
- const clearHistoryButton = document.createElement('div');
- clearHistoryButton.id = 'clearHistoryButton';
- clearHistoryButton.innerHTML = '🗑️';
- clearHistoryButton.style.display = 'none';
- document.body.appendChild(clearHistoryButton);
-
- const historyList = document.createElement('div');
- historyList.id = 'historyList';
- historyList.style.display = 'none';
- document.body.appendChild(historyList);
-
- const durationButton = document.createElement('div');
- durationButton.id = 'durationButton';
- durationButton.innerHTML = GM_getValue('uploadDuration', '1h'); // Display initial duration
- durationButton.style.display = 'none';
- document.body.appendChild(durationButton);
-
- const durationMenu = document.createElement('div');
- durationMenu.id = 'durationMenu';
- durationMenu.style.display = 'none';
- durationMenu.innerHTML = `
- <div data-duration="1h">1 hour</div>
- <div data-duration="12h">12 hours</div>
- <div data-duration="24h">24 hours</div>
- <div data-duration="72h">72 hours</div>
- `;
- document.body.appendChild(durationMenu);
-
- GM_addStyle(`
- #uploadButton, #historyButton, #clearHistoryButton, #minimizeButton, #durationButton {
- position: fixed;
- bottom: 20px;
- width: 50px;
- height: 50px;
- background-color: #333;
- color: white;
- border: none;
- border-radius: 50%;
- cursor: pointer;
- font-family: Arial, sans-serif;
- font-size: 24px;
- text-align: center;
- line-height: 50px;
- box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2);
- z-index: 10000;
- }
- #uploadButton { left: 20px; }
- #uploadButton.minimized {
- bottom: 0;
- width: 50px;
- height: 10px;
- border-radius: 50px 50px 0 0;
- font-size: 10px;
- line-height: 10px;
- }
- #minimizeButton, #historyButton, #clearHistoryButton, #durationButton {
- width: 40px;
- height: 40px;
- font-size: 20px;
- line-height: 40px;
- }
- #minimizeButton { left: 80px; }
- #historyButton { left: 140px; }
- #clearHistoryButton { left: 200px; }
- #durationButton { left: 260px; }
-
- #fileUrl, #historyList, #durationMenu {
- position: fixed;
- bottom: 80px;
- left: 20px;
- width: 270px;
- background-color: #333;
- color: white;
- padding: 10px;
- border: none;
- border-radius: 5px;
- font-size: 14px;
- box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2);
- z-index: 10000;
- overflow-y: auto;
- }
- #fileUrl { display: block; }
- #historyList {
- height: 200px;
- display: none;
- }
- #historyList div {
- margin-bottom: 10px;
- }
- #historyList div span.timestamp {
- display: block;
- color: #aaa;
- font-size: 12px;
- margin-top: 4px;
- border-top: 1px solid #555;
- padding-top: 2px;
- }
- #historyList a {
- color: #66ccff;
- text-decoration: none;
- }
- #copyButton {
- position: fixed;
- bottom: 80px;
- left: 300px;
- width: 30px;
- height: 30px;
- background-color: #333;
- color: white;
- border: none;
- border-radius: 5px;
- cursor: pointer;
- font-family: Arial, sans-serif;
- font-size: 16px;
- text-align: center;
- line-height: 30px;
- box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2);
- z-index: 10000;
- }
- #dropZone {
- position: fixed;
- bottom: 150px;
- left: 20px;
- width: 300px;
- height: 150px;
- border: 2px dashed #aaa;
- background-color: #444;
- color: white;
- text-align: center;
- line-height: 150px;
- font-family: Arial, sans-serif;
- font-size: 14px;
- border-radius: 5px;
- z-index: 10000;
- }
- #dropZone.dragover {
- border-color: #fff;
- background-color: #555;
- }
- #durationMenu div:hover {
- background-color: #555;
- }
- `);
-
- let isMinimized = true;
- let uploadDuration = GM_getValue('uploadDuration', '1h');
- uploadButton.classList.add('minimized');
-
- uploadButton.addEventListener('click', () => {
- if (isMinimized) {
- uploadButton.classList.remove('minimized');
- isMinimized = false;
- minimizeButton.style.display = 'block';
- historyButton.style.display = 'block';
- clearHistoryButton.style.display = 'block';
- durationButton.style.display = 'block';
- } else {
- fileInput.click();
- }
- });
-
- minimizeButton.addEventListener('click', () => {
- uploadButton.classList.add('minimized');
- isMinimized = true;
- minimizeButton.style.display = 'none';
- urlTextBox.style.display = 'none';
- copyButton.style.display = 'none';
- historyList.style.display = 'none';
- historyButton.style.display = 'none';
- clearHistoryButton.style.display = 'none';
- durationButton.style.display = 'none';
- dropZone.style.display = 'none';
- durationMenu.style.display = 'none';
- });
-
- durationButton.addEventListener('click', () => {
- durationMenu.style.display = durationMenu.style.display === 'none' ? 'block' : 'none';
- });
-
- durationMenu.addEventListener('click', (e) => {
- if (e.target.dataset.duration) {
- uploadDuration = e.target.dataset.duration;
- GM_setValue('uploadDuration', uploadDuration);
- durationButton.innerHTML = uploadDuration;
- durationMenu.style.display = 'none';
- }
- });
-
- fileInput.addEventListener('change', () => {
- const file = fileInput.files[0];
- if (file) uploadFile(file);
- });
-
- const uploadedUrlsKey = 'globalUploadedUrls';
- const urlLimit = 10;
-
- let savedUrls = GM_getValue(uploadedUrlsKey, []);
-
- function updateHistoryList() {
- historyList.innerHTML = savedUrls.map(item => `<div><a href="${item.url}" target="_blank">${item.url}</a><span class="timestamp">${item.timestamp}</span></div>`).join('');
- }
-
- historyButton.addEventListener('click', () => {
- historyList.style.display = historyList.style.display === 'none' ? 'block' : 'none';
- updateHistoryList();
- });
-
- clearHistoryButton.addEventListener('click', () => {
- if (confirm("Are you sure you want to clear the URL history? This action cannot be undone.")) {
- savedUrls = [];
- GM_setValue(uploadedUrlsKey, savedUrls);
- updateHistoryList();
- }
- });
-
- function handleFileDrop(e) {
- e.preventDefault();
- dropZone.classList.remove('dragover');
- const file = e.dataTransfer.files[0];
- if (file) uploadFile(file);
- }
-
- document.addEventListener('dragover', e => {
- e.preventDefault();
- dropZone.style.display = 'block';
- dropZone.classList.add('dragover');
- });
-
- document.addEventListener('dragleave', () => dropZone.style.display = 'none');
- dropZone.addEventListener('drop', handleFileDrop);
-
- async function uploadFile(file) {
- const timestamp = new Date().toLocaleString('en-GB');
- try {
- const formData = new FormData();
- formData.append('reqtype', 'fileupload');
- formData.append('fileToUpload', file);
-
- const response = await fetch('https://litterbox.catbox.moe/resources/internals/api.php', {
- method: 'POST',
- body: formData
- });
-
- const url = await response.text();
- const newEntry = { url, timestamp };
- savedUrls.push(newEntry);
- if (savedUrls.length > urlLimit) savedUrls.shift();
- GM_setValue(uploadedUrlsKey, savedUrls);
-
- urlTextBox.value = url;
- urlTextBox.style.display = 'block';
- copyButton.style.display = 'block';
-
- updateHistoryList();
- } catch (error) {
- console.error("Upload failed:", error);
- }
- }
-
- copyButton.addEventListener('click', () => {
- navigator.clipboard.writeText(urlTextBox.value).then(() => alert('Copied to clipboard!'));
- });
-
- })();