Discord Catbox Uploader

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

当前为 2024-09-30 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Discord Catbox Uploader
  3. // @namespace https://tampermonkey.net/
  4. // @version 1.2
  5. // @description Adds a button to upload files to catbox.moe in Discord
  6. // @author OasisVee
  7. // @match https://*.discord.com/*
  8. // @grant GM_xmlhttpRequest
  9. // @grant GM_setClipboard
  10. // @grant GM_addStyle
  11. // @connect catbox.moe
  12. // @icon https://www.google.com/s2/favicons?sz=64&domain=catbox.moe
  13. // @license MIT
  14. // ==/UserScript==
  15.  
  16. (function() {
  17. 'use strict';
  18.  
  19. // Add custom CSS for the tooltip
  20. GM_addStyle(`
  21. .catbox-tooltip {
  22. position: absolute;
  23. background-color: #202225;
  24. color: #dcddde;
  25. padding: 8px 12px;
  26. border-radius: 5px;
  27. font-size: 14px;
  28. font-weight: 500;
  29. pointer-events: none;
  30. opacity: 0;
  31. transition: opacity 0.1s ease-in-out;
  32. z-index: 9999;
  33. top: -30px;
  34. box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* Adjust shadow for a more subtle appearance */
  35. white-space: nowrap;
  36. border: 1px solid #36393F;
  37. }
  38. .catbox-tooltip::before {
  39. content: '';
  40. position: absolute;
  41. width: 0;
  42. height: 0;
  43. border-left: 8px solid transparent;
  44. border-right: 8px solid transparent;
  45. border-bottom:
  46. 8px solid #202225;
  47. bottom: -8px;
  48. left: 50%;
  49. transform: translateX(-50%) rotate(180deg);
  50. }
  51. `);
  52.  
  53. function addCatboxButton() {
  54. const uploadButton = document.querySelector('button.attachButton_f298d4.attachButton_d0696b');
  55. if (uploadButton && !document.getElementById('catbox-upload-btn')) {
  56. const catboxButton = document.createElement('button');
  57. catboxButton.id = 'catbox-upload-btn';
  58. catboxButton.className = uploadButton.className;
  59. catboxButton.style.cssText = `
  60. vertical-align: top;
  61. padding: 0px 8px;
  62. height: 0px;
  63. line-height: 0px;
  64. top: -20px;
  65. margin-left: 23px;
  66. position: relative;
  67. transform: translateX(0px);
  68. color: white;
  69. opacity: 80%;
  70. display: flex;
  71. align-items: center;
  72. justify-content: center;
  73. `;
  74.  
  75. // creates the cat svg
  76. const svgIcon = `
  77. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
  78. <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"/>
  79. </svg>
  80. `;
  81.  
  82. catboxButton.innerHTML = svgIcon;
  83. catboxButton.setAttribute('data-tooltip', 'Upload to Catbox');
  84. catboxButton.addEventListener('click', handleCatboxUpload);
  85. catboxButton.addEventListener('mouseenter', showTooltip);
  86. catboxButton.addEventListener('mouseleave', hideTooltip);
  87. uploadButton.parentNode.insertBefore(catboxButton, uploadButton.nextSibling);
  88. return true;
  89. }
  90. return false;
  91. }
  92.  
  93. function showTooltip(event) {
  94. const button = event.target.closest('button');
  95. const tooltipText = button.getAttribute('data-tooltip');
  96.  
  97. const tooltip = document.createElement('div');
  98. tooltip.className = 'catbox-tooltip';
  99. tooltip.textContent = tooltipText;
  100. document.body.appendChild(tooltip);
  101.  
  102. const buttonRect = button.getBoundingClientRect();
  103. const tooltipRect = tooltip.getBoundingClientRect();
  104.  
  105. tooltip.style.left = `${buttonRect.left + (buttonRect.width / 2) - (tooltipRect.width / 2)}px`;
  106. tooltip.style.top = `${buttonRect.top - tooltipRect.height - 15}px`;
  107.  
  108. setTimeout(() => {
  109. tooltip.style.opacity = '1';
  110. }, 10);
  111.  
  112. button.tooltip = tooltip;
  113. }
  114.  
  115. function hideTooltip(event) {
  116. const button = event.target.closest('button');
  117. if (button.tooltip) {
  118. button.tooltip.style.opacity = '0';
  119. setTimeout(() => {
  120. if (button.tooltip.parentNode) {
  121. button.tooltip.parentNode.removeChild(button.tooltip);
  122. }
  123. button.tooltip = null;
  124. }, 100);
  125. }
  126. }
  127.  
  128. function handleCatboxUpload(event) {
  129. event.preventDefault();
  130. event.stopPropagation();
  131.  
  132. const fileInput = document.createElement('input');
  133. fileInput.type = 'file';
  134. fileInput.click();
  135.  
  136. fileInput.addEventListener('change', async (event) => {
  137. const file = event.target.files[0];
  138. if (!file) return;
  139.  
  140. const formData = new FormData();
  141. formData.append('reqtype', 'fileupload');
  142. formData.append('fileToUpload', file);
  143.  
  144. try {
  145. GM_xmlhttpRequest({
  146. method: 'POST',
  147. url: 'https://catbox.moe/user/api.php',
  148. data: formData,
  149. onload: function(response) {
  150. if (response.status === 200) {
  151. const link = response.responseText;
  152. copyToClipboardAndNotify(link);
  153. } else {
  154. console.error('Error uploading to Catbox.moe:', response.responseText);
  155. showNotification('Error uploading to Catbox.moe. Please try again.', 'error');
  156. }
  157. },
  158. onerror: function(error) {
  159. console.error('Error uploading to Catbox.moe:', error);
  160. showNotification('Error uploading to Catbox.moe. Please try again.', 'error');
  161. }
  162. });
  163. } catch (error) {
  164. console.error('Error uploading to Catbox.moe:', error);
  165. showNotification('Error uploading to Catbox.moe. Please try again.', 'error');
  166. }
  167. });
  168. }
  169.  
  170. function copyToClipboardAndNotify(link) {
  171. GM_setClipboard(link);
  172. showNotification('File uploaded and link copied to clipboard!', 'success');
  173. }
  174.  
  175. function showNotification(message, type = 'info') {
  176. const notification = document.createElement('div');
  177. notification.textContent = message;
  178. notification.style.cssText = `
  179. position: fixed;
  180. top: 10px;
  181. right: 10px;
  182. padding: 10px 20px;
  183. border-radius: 5px;
  184. color: white;
  185. font-weight: bold;
  186. z-index: 9999;
  187. opacity: 0;
  188. transition: opacity 0.3s ease-in-out;
  189. `;
  190.  
  191. if (type === 'error') {
  192. notification.style.backgroundColor = '#ff4444';
  193. } else if (type === 'success') {
  194. notification.style.backgroundColor = '#00C851';
  195. } else {
  196. notification.style.backgroundColor = '#33b5e5';
  197. }
  198.  
  199. document.body.appendChild(notification);
  200.  
  201. // Fade in
  202. setTimeout(() => {
  203. notification.style.opacity = '1';
  204. }, 10);
  205.  
  206. // Fade out and remove
  207. setTimeout(() => {
  208. notification.style.opacity = '0';
  209. setTimeout(() => {
  210. document.body.removeChild(notification);
  211. }, 300);
  212. }, 3000);
  213. }
  214.  
  215. function waitForUploadButton() {
  216. const intervalId = setInterval(() => {
  217. if (addCatboxButton()) {
  218. clearInterval(intervalId);
  219. }
  220. }, 1000);
  221. }
  222.  
  223. // watches for upload press
  224. waitForUploadButton();
  225.  
  226. // MutationObserver to watch for changes
  227. const observer = new MutationObserver((mutations) => {
  228. for (let mutation of mutations) {
  229. if (mutation.type === 'childList') {
  230. addCatboxButton();
  231. }
  232. }
  233. });
  234.  
  235. // Start observing the document body for changes
  236. observer.observe(document.body, { childList: true, subtree: true });
  237. })();