diff --git a/monkey/.gitignore b/monkey/.gitignore index a547bf3..251ce6d 100644 --- a/monkey/.gitignore +++ b/monkey/.gitignore @@ -8,7 +8,6 @@ pnpm-debug.log* lerna-debug.log* node_modules -dist dist-ssr *.local diff --git a/monkey/dist/vidbee-quick-download.user.js b/monkey/dist/vidbee-quick-download.user.js new file mode 100644 index 0000000..d794fc9 --- /dev/null +++ b/monkey/dist/vidbee-quick-download.user.js @@ -0,0 +1,156 @@ +// ==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(); + +})(); \ No newline at end of file