Quick Send

Get temporary shortened links for files uploaded to Send (formerly Firefox Send) instances.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Для установки этого скрипта вам необходимо установить расширение, такое как Tampermonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==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});