Quick Send

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

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

Advertisement:

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

Advertisement:

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