// ==UserScript== // @name vidbee-quick-download // @namespace vidbee // @version 0.0.1 // @icon https://vidbee.org/favicon.svg // @match https://www.youtube.com/* // @match https://youtube.com/* // @match https://music.youtube.com/* // @match https://www.bilibili.com/* // @match https://bilibili.com/* // @match https://www.tiktok.com/* // @match https://tiktok.com/* // @match https://vimeo.com/* // @match https://www.vimeo.com/* // @match https://www.dailymotion.com/* // @match https://dailymotion.com/* // @match https://www.twitch.tv/* // @match https://twitch.tv/* // @match https://twitter.com/* // @match https://www.twitter.com/* // @match https://x.com/* // @match https://www.x.com/* // @match https://www.instagram.com/* // @match https://instagram.com/* // @match https://www.facebook.com/* // @match https://facebook.com/* // @match https://fb.com/* // @match https://www.fb.com/* // @match https://www.reddit.com/* // @match https://reddit.com/* // @match https://soundcloud.com/* // @match https://www.soundcloud.com/* // @match https://www.nicovideo.jp/* // @match https://nicovideo.jp/* // @match https://kick.com/* // @match https://www.kick.com/* // @match https://bandcamp.com/* // @match https://*.bandcamp.com/* // @match https://www.mixcloud.com/* // @match https://mixcloud.com/* // @grant GM_addStyle // ==/UserScript== (function () { 'use strict'; const d=new Set;const importCSS = async e=>{d.has(e)||(d.add(e),(t=>{typeof GM_addStyle=="function"?GM_addStyle(t):(document.head||document.documentElement).appendChild(document.createElement("style")).append(t);})(e));}; const styleCss = '.vidbee-download-container{position:fixed;bottom:16px;right:16px;z-index:9999;transition:all .2s ease;overflow:visible}.vidbee-download-container.vidbee-hidden{opacity:0;pointer-events:none;transform:scale(0)}.vidbee-download-button{position:relative;display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;background:#00000080;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);color:#fffc;border:1px solid rgba(255,255,255,.1);border-radius:50%;box-shadow:0 2px 8px #0003;cursor:pointer;font-size:0;transition:all .2s ease;opacity:.6;overflow:visible}.vidbee-download-button:hover{opacity:1;background:#000000b3;border-color:#fff3;box-shadow:0 4px 12px #0000004d;transform:scale(1.1)}.vidbee-download-button:active{transform:scale(.95)}.vidbee-download-button svg{flex-shrink:0;stroke:currentColor;width:16px;height:16px}.vidbee-tooltip{position:absolute;right:calc(100% + 8px);top:50%;padding:6px 10px;background:#000000e6;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);color:#fff;font-size:12px;font-weight:500;white-space:nowrap;border-radius:4px;box-shadow:0 2px 8px #0000004d;opacity:0;pointer-events:none;transition:opacity .2s ease,transform .2s ease;transform:translateY(-50%) translate(4px);z-index:10000;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;line-height:1}.vidbee-tooltip:after{content:"";position:absolute;left:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-left-color:#000000e6}.vidbee-download-button:hover .vidbee-tooltip{opacity:1;transform:translateY(-50%) translate(0)}.vidbee-close-button{position:absolute;top:-6px;right:-6px;display:flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;background:#ff4d4de6;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);color:#fff;border:1px solid rgba(255,255,255,.2);border-radius:50%;box-shadow:0 2px 4px #0000004d;cursor:pointer;font-size:0;transition:all .2s ease;z-index:1;opacity:0;pointer-events:none;overflow:visible}.vidbee-download-container:hover .vidbee-close-button{opacity:1;pointer-events:auto}.vidbee-close-button:hover{background:#ff4d4d;transform:scale(1.15);box-shadow:0 3px 6px #0006}.vidbee-close-button:active{transform:scale(.9)}.vidbee-close-button svg{flex-shrink:0;stroke:currentColor;width:10px;height:10px}.vidbee-close-button .vidbee-tooltip{right:calc(100% + 6px);top:50%;left:auto;transform:translateY(-50%) translate(4px)}.vidbee-close-button .vidbee-tooltip:after{left:100%;top:50%;right:auto;transform:translateY(-50%);border-left-color:#000000e6;border-top-color:transparent}.vidbee-download-container:hover .vidbee-close-button:hover .vidbee-tooltip{opacity:1;transform:translateY(-50%) translate(0)}'; importCSS(styleCss); function getVideoUrl() { return window.location.href; } function hideButtonTemporarily() { const container = document.getElementById("vidbee-download-btn"); if (container) { container.classList.add("vidbee-hidden"); setTimeout(() => { if (container) { container.classList.remove("vidbee-hidden"); } }, 5e3); } } function createVidBeeButton() { if (document.getElementById("vidbee-download-btn")) { return; } const videoUrl = getVideoUrl(); if (!videoUrl) { return; } const container = document.createElement("div"); container.id = "vidbee-download-btn"; container.className = "vidbee-download-container"; const button = document.createElement("button"); button.className = "vidbee-download-button"; button.setAttribute("aria-label", "Download with VidBee"); button.innerHTML = ` Download with VidBee `; const closeButton = document.createElement("button"); closeButton.className = "vidbee-close-button"; closeButton.setAttribute("aria-label", "Hide button"); closeButton.innerHTML = ` Hide `; closeButton.addEventListener("click", (e) => { e.stopPropagation(); hideButtonTemporarily(); }); let clickTimer = null; let clickCount = 0; button.addEventListener("click", () => { clickCount++; if (clickCount === 1) { clickTimer = window.setTimeout(() => { const vidbeeUrl = `vidbee://download?url=${encodeURIComponent(videoUrl)}`; window.location.href = vidbeeUrl; clickCount = 0; }, 300); } else if (clickCount === 2) { if (clickTimer !== null) { clearTimeout(clickTimer); } clickCount = 0; hideButtonTemporarily(); } }); container.appendChild(button); container.appendChild(closeButton); document.body.appendChild(container); } function init() { if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", createVidBeeButton); } else { createVidBeeButton(); } let lastUrl = location.href; let urlCheckTimer = null; const checkUrlChange = () => { const currentUrl = location.href; if (currentUrl !== lastUrl) { lastUrl = currentUrl; const oldButton = document.getElementById("vidbee-download-btn"); if (oldButton) { oldButton.remove(); } const hostname = window.location.hostname; const delay = hostname.includes("bilibili.com") ? 800 : 500; setTimeout(createVidBeeButton, delay); } }; new MutationObserver(() => { if (urlCheckTimer !== null) { clearTimeout(urlCheckTimer); } urlCheckTimer = window.setTimeout(checkUrlChange, 100); }).observe(document.body, { childList: true, subtree: true }); window.addEventListener("popstate", () => { setTimeout(checkUrlChange, 300); }); } init(); })();