/fluttershy/ Upload images from URL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | // ==UserScript==
// @name Fluttershy Uploader from URL
// @namespace Fluttershy-uploader
// @version 1.0
// @description Upload image from URL, integrated into 8kun with Fluttershy style UI
// @match https://8kun.top/*
// @grant GM_xmlhttpRequest
// @connect *
// ==/UserScript==
(function () {
'use strict';
function waitForElement(selector, timeout = 10000) {
return new Promise((resolve, reject) => {
const start = Date.now();
const interval = setInterval(() => {
const el = document.querySelector(selector);
if (el) {
clearInterval(interval);
resolve(el);
} else if (Date.now() - start > timeout) {
clearInterval(interval);
reject("Container not found in time.");
}
}, 500);
});
}
function createUploader(container) {
if (container.querySelector('.url-upload-wrapper')) return;
const wrapper = document.createElement("div");
wrapper.className = "url-upload-wrapper";
wrapper.style.marginTop = "10px";
wrapper.style.padding = "10px";
wrapper.style.border = "1px dashed #fdd835";
wrapper.style.borderRadius = "8px";
wrapper.style.background = "#fff0f5";
wrapper.style.fontSize = "0.8em";
const toggleBtn = document.createElement("button");
toggleBtn.textContent = "Upload image from URL";
toggleBtn.type = "button";
toggleBtn.className = "url-upload-toggle";
toggleBtn.style.marginBottom = "6px";
toggleBtn.style.background = "#fce4ec";
toggleBtn.style.color = "#d6336c";
toggleBtn.style.border = "1px solid #fdd835";
toggleBtn.style.borderRadius = "6px";
toggleBtn.style.padding = "6px 10px";
toggleBtn.style.cursor = "pointer";
toggleBtn.style.fontSize = "0.8em";
const inputWrap = document.createElement("div");
inputWrap.className = "url-upload-box";
inputWrap.style.display = "none";
const urlInput = document.createElement("input");
urlInput.type = "text";
urlInput.className = "url-input";
urlInput.placeholder = "Paste a direct image URL";
urlInput.style.width = "100%";
urlInput.style.marginTop = "6px";
urlInput.style.border = "1px solid #fdd835";
urlInput.style.borderRadius = "4px";
urlInput.style.padding = "6px";
urlInput.style.background = "#fffafc";
urlInput.style.color = "#c2185b";
urlInput.style.fontSize = "0.8em";
const uploadBtn = document.createElement("button");
uploadBtn.textContent = "Upload";
uploadBtn.type = "button";
uploadBtn.className = "url-upload-btn";
uploadBtn.style.marginTop = "6px";
uploadBtn.style.background = "#f8bbd0";
uploadBtn.style.color = "#880e4f";
uploadBtn.style.border = "1px solid #fdd835";
uploadBtn.style.borderRadius = "6px";
uploadBtn.style.padding = "6px 10px";
uploadBtn.style.cursor = "pointer";
uploadBtn.style.fontSize = "0.8em";
inputWrap.appendChild(urlInput);
inputWrap.appendChild(uploadBtn);
wrapper.appendChild(toggleBtn);
wrapper.appendChild(inputWrap);
container.appendChild(wrapper);
}
document.addEventListener('click', function (e) {
if (e.target.matches('.url-upload-toggle')) {
const box = e.target.nextElementSibling;
if (box) {
box.style.display = box.style.display === 'none' ? 'block' : 'none';
}
}
if (e.target.matches('.url-upload-btn')) {
const box = e.target.closest('.url-upload-box');
const input = box.querySelector('.url-input');
const imageUrl = input.value.trim();
if (!imageUrl) return alert("Please enter a URL first.");
const form = e.target.closest("form");
const dropzone = form.querySelector(".dropzone");
if (!dropzone) return alert("Dropzone not found in this form.");
GM_xmlhttpRequest({
method: "GET",
url: imageUrl,
responseType: "blob",
onload: function (response) {
if (response.status !== 200) {
alert("Could not download the image. Is the URL valid?");
return;
}
const blob = response.response;
const filename = imageUrl.split('/').pop() || "image.png";
const file = new File([blob], filename, { type: blob.type });
const dt = new DataTransfer();
dt.items.add(file);
const dropEvent = new DragEvent("drop", {
dataTransfer: dt,
bubbles: true,
cancelable: true
});
dropzone.dispatchEvent(dropEvent);
},
onerror: function () {
alert("Error while downloading the image.");
}
});
}
});
async function init() {
try {
const mainForm = await waitForElement("form[name='post']");
createUploader(mainForm);
} catch (err) {
console.error("Main form not detected:", err);
}
const observer = new MutationObserver(() => {
const qr = document.querySelector('#quick-reply');
if (qr && qr.style.display !== 'none') {
const qrForm = qr.querySelector("form");
if (qrForm) createUploader(qrForm);
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
window.addEventListener('load', init);
})();
|
F.A.Q.
What is this script for?
One of the most important and hardest-to-live-without features of 4chanX is the ability to upload images directly from a URL. This script enables that functionality, letting you copy an image URL from a booru (like Danbooru) and upload it here, no need to download the image first, re-upload it, or dig through your hard drive. Hope you flutterbros like it! The theme is inspired by her.
How to use it
- Once the script is installed, a new button labeled "Upload image from URL" will appear.
- Click it to open a simple upload menu. Paste the URL in the designated field and click Upload.
- Your image will appear automatically in the Attachments section. Now publish your post as usual.
How do I install it?"
Install Guide:
- How to Install Scripts in Firefox/Chrome (Tampermonkey, etc.):
-Get a Userscript Manager:
-Firefox/Chrome: Install Tampermonkey (Chrome Web Store / Firefox Add-ons).
-Alternatives: Violentmonkey or Greasemonkey (same steps). - Import the Script into Tampermonkey:
-Open Tampermonkey’s dashboard (click its icon → "Dashboard").
-Go to the "Utilities" tab. - Paste the ##User Script code into the box.
-Under "Install from clipboard", click "Import" → paste the code from above → "Install". - Click "Install" or "Confirm".