Greasy Fork is available in English.
Get temporary shortened links for files uploaded to Send (formerly Firefox Send) instances.
// ==UserScript==
// @name Quick Send
// @namespace https://naeembolchhi.github.io/
// @version 0.5
// @description Get temporary shortened links for files uploaded to Send (formerly Firefox Send) instances.
// @author NaeemBolchhi
// @license GPL-3.0-or-later
// @icon data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 96 96"><path d="M96 51.43a25.5 25.5 0 0 1-6.61 17.14 22.297 22.297 0 0 1-15.84 6.86h-3.27V65.14h3.27c3.08-.06 6.02-1.3 8.2-3.47 2.55-2.81 3.95-6.46 3.96-10.25-.01-9.46-7.68-17.13-17.14-17.14-.57 0-3.47.37-5.23.59-.8.11-1.57-.38-1.83-1.14l-.7-2.04a21.146 21.146 0 0 0-17.57-14.45c-11.26-1.2-21.35 6.96-22.55 18.22-.25 2.32-.1 4.67.45 6.95l.73 3.13c.21.88-.31 1.77-1.17 2.03l-3.08.93a10.191 10.191 0 0 0-7.33 9.78c0 1.52.5 3 1.42 4.21a8.328 8.328 0 0 0 6.13 2.65h7.87v10.29h-7.87c-5.66.04-11.02-2.54-14.52-6.98A17.205 17.205 0 0 1 0 58.28a20.38 20.38 0 0 1 10.41-17.83c-.08-.92-.13-1.84-.13-2.75 0-17.03 13.8-30.85 30.83-30.86a30.86 30.86 0 0 1 27.65 17.14C83.83 24.1 95.97 36.34 96 51.41Zm-46.61-3.25c-.56-.77-1.63-.93-2.4-.38-.14.11-.27.23-.38.38L33.72 65.84c-.56.77-.39 1.84.38 2.4.29.21.65.33 1.01.33h7.75v18.86c0 .95.77 1.71 1.71 1.71h6.86c.95 0 1.71-.77 1.71-1.71V68.57h7.75a1.71 1.71 0 0 0 1.38-2.72L49.38 48.19h-.01Z" fill="%2345a1ff"/></svg>
// @match https://send.vis.ee/*
// @match https://send.mni.li/*
// @match https://send.monks.tools/*
// @match https://send.aurorabilisim.com/*
// @match https://send.artemislena.eu/*
// @match https://fileupload.ggc-project.de/*
// @match https://drop.chapril.org/*
// @match https://send.jeugdhulp.be/*
// @match https://send.cyberjake.xyz/*
// @match https://send.kokomo.cloud/*
// @match https://send.adminforge.de/*
// @match https://send.turingpoint.de/*
// @match https://send.aslaets.be/*
// @match https://send.codespace.cz/*
// @match https://upload.nolog.cz/*
// @match https://ch.skysend.ch/*
// @match https://send.canine.tools/*
// @match https://send.skylerszijjarto.com/*
// @match https://send.richy.sh/*
// @match https://send.majoenell.com/*
// @match https://send.nog.community/*
// @match https://send.hostnetwork.xyz/*
// @run-at document-body
// @grant GM_addStyle
// @grant GM_xmlhttpRequest
// @connect trimm.link
// ==/UserScript==
// Temporarily shortened link
async function slink(longurl) {
const baseUrl = "https://trimm.link/";
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: "POST",
url: baseUrl + "shorten",
headers: {
"Content-Type": "application/json"
},
data: JSON.stringify({ link: longurl.trim() }),
onload: function(response) {
try {
// responseText is the raw string; we need to parse it manually
const json = JSON.parse(response.responseText);
const shorturl = baseUrl + (json.word || "");
resolve(shorturl);
} catch (err) {
reject("Error parsing response: " + err);
}
},
onerror: function(error) {
reject("Request failed: " + error);
}
});
});
}
// Style Additions
const newCSS = `
.temp-link-shortener {
background-color: #f38416;
margin-bottom: 1rem;
}
.temp-link-shortener:hover, .temp-link-shortener:focus {
background-color: #a16908;
}
.temp-link-shortener.hide {
display: none;
}
.loader-circle-8 {
position: relative;
margin: 0 auto;
height: 18.4px;
stroke: white;
}
.loader-circle-8:before {
content: "";
display: block;
padding-top: 100%;
}
.circular {
animation: rotate 2s linear infinite;
height: 100%;
transform-origin: center center;
width: 100%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
.path {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
animation: dash 1.5s ease-in-out infinite, color 6s ease-in-out infinite;
stroke-linecap: round;
}
@keyframes rotate {
100% {
transform: rotate(360deg);
}
}
@keyframes dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -35px;
}
100% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -124px;
}
}
`;
GM_addStyle(newCSS);
// Add new button
function createShortenButton() {
if (document.querySelector('.temp-link-shortener')) {return;}
let sourcebtn = document.querySelectorAll('send-copy-dialog button[title*="opy link"], send-share-dialog button[title*="hare link"]')[0];
if (!sourcebtn) {return;}
let copybtn = sourcebtn.cloneNode(true);
copybtn.classList.add('temp-link-shortener');
copybtn.textContent = 'Shorten link';
copybtn.setAttribute('title', 'Shorten link');
sourcebtn.parentNode.insertBefore(copybtn, sourcebtn);
copybtn.addEventListener('click', clickShortenButton);
}
// Process shortening
function clickShortenButton() {
let shareURL = document.querySelector('#share-url');
let shortenbtn = document.querySelector('.temp-link-shortener');
shortenbtn.innerHTML = `
<div class="loader-circle-8">
<svg class="circular" viewbox="25 25 50 50">
<circle class="path" cx="50" cy="50" r="20" fill="none" stroke-width="5" stroke-miterlimit="10"/>
</svg>
</div>
`;
slink(shareURL.value).then(key => {
shareURL.value = key;
document.querySelector('.temp-link-shortener').classList.add('hide');
}).catch(() => {
console.log('error');
});
let sourcebtn = document.querySelectorAll('send-copy-dialog button[title*="opy link"], send-share-dialog button[title*="hare link"]')[0];
sourcebtn.outerHTML = sourcebtn.outerHTML;
sourcebtn = document.querySelectorAll('send-copy-dialog button[title*="opy link"], send-share-dialog button[title*="hare link"]')[0];
sourcebtn.addEventListener('click', clickCopyButton);
}
// Copy button new function
function clickCopyButton() {
let shareURL = document.querySelector('#share-url');
let sourcebtn = document.querySelectorAll('send-copy-dialog button[title*="opy link"]')[0];
let sharebtn = document.querySelectorAll('send-share-dialog button[title*="hare link"]')[0];
if (sourcebtn) {
navigator.clipboard.writeText(shareURL.value).then(() => {
// Success
sourcebtn.textContent = 'Copied!';
}).catch(err => {
// Failure
sourcebtn.textContent = 'Failure!';
});
window.location.reload();
} else if (sharebtn) {
navigator.share({url: shareURL.value});
}
}
// Mutation observer to track file uploads
let observer = new MutationObserver(function() {
createShortenButton();
});
observer.observe(document.documentElement, {childList: true, subtree: true});