// ==UserScript== // @name 剪贴板图片上传lsky图床 // @namespace http://tampermonkey.net/ // @version 1.7.5 // @description 自动处理 token 和剪贴板图片上传到 lsky 图床 // @author You // @match *://*.nodeseek.com/* // @match *://linux.do/* // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @grant GM_addStyle // @connect * // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/529474/%E5%89%AA%E8%B4%B4%E6%9D%BF%E5%9B%BE%E7%89%87%E4%B8%8A%E4%BC%A0lsky%E5%9B%BE%E5%BA%8A.user.js // @updateURL https://update.greasyfork.icu/scripts/529474/%E5%89%AA%E8%B4%B4%E6%9D%BF%E5%9B%BE%E7%89%87%E4%B8%8A%E4%BC%A0lsky%E5%9B%BE%E5%BA%8A.meta.js // ==/UserScript== (function () { "use strict"; const config = loadConfig(); function loadConfig() { return { baseUrl: GM_getValue("baseUrl", "http://"), token: GM_getValue("token", ""), email: GM_getValue("email", ""), password: GM_getValue("password", ""), strategyId: GM_getValue("strategyId", 1), }; } function saveConfig(newConfig) { for (const key in newConfig) { GM_setValue(key, newConfig[key]); config[key] = newConfig[key]; } } function addGlobalStyle(css) { const style = document.createElement("style"); style.textContent = css; document.head.appendChild(style); } function createSettingsPanel() { if (document.getElementById("gm-settings-panel")) return; let panel = document.createElement("div"); panel.id = "gm-settings-panel"; panel.innerHTML = `

lsky 图床 配置

`; document.body.appendChild(panel); document .getElementById("gm-save-settings") .addEventListener("click", () => { let baseUrl = document.getElementById("gm-baseUrl").value; if (!baseUrl.startsWith("http://") && !baseUrl.startsWith("https://")) { baseUrl = "http://" + baseUrl; } saveConfig({ baseUrl, email: document.getElementById("gm-email").value, password: document.getElementById("gm-password").value, strategyId: Number(document.getElementById("gm-strategyId").value), }); panel.remove(); showSuccessMessage("配置已保存!"); }); document .getElementById("gm-close-settings") .addEventListener("click", () => panel.remove()); addGlobalStyle(` #gm-settings-panel { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); z-index: 10000; width: 300px; } .gm-panel h2 { margin-bottom: 10px; font-size: 18px; } .gm-panel label { display: block; margin-bottom: 10px; } .gm-panel input { width: 100%; padding: 5px; margin-top: 5px; border: 1px solid #ccc; border-radius: 4px; } .gm-panel button { margin-right: 10px; padding: 6px 12px; cursor: pointer; } `); } function addFloatingButton() { const btn = document.createElement("div"); btn.id = "gm-floating-button"; btn.innerText = "⚙️ 设置"; document.body.appendChild(btn); let isDragging = false; let offsetX = 0; let offsetY = 0; btn.addEventListener("mousedown", function (e) { isDragging = false; offsetX = e.clientX - btn.getBoundingClientRect().left; offsetY = e.clientY - btn.getBoundingClientRect().top; function onMouseMove(e) { isDragging = true; btn.style.left = `${e.clientX - offsetX}px`; btn.style.top = `${e.clientY - offsetY}px`; } function onMouseUp(e) { document.removeEventListener("mousemove", onMouseMove); document.removeEventListener("mouseup", onMouseUp); if (!isDragging) { createSettingsPanel(); } } document.addEventListener("mousemove", onMouseMove); document.addEventListener("mouseup", onMouseUp); }); addGlobalStyle(` #gm-floating-button { position: fixed; bottom: 20px; left: 20px; width: 60px; height: 20px; background: #3498db; color: white; padding: 10px; border-radius: 70px; cursor: move; font-size: 14px; z-index: 9999; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); user-select: none; display: flex; align-items: center; justify-content: center; text-align: center; line-height: normal; transition: background 0.2s; } #gm-floating-button:hover { background: #2980b9; } `); } async function getToken() { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "POST", url: `${config.baseUrl}/api/v1/tokens`, headers: { Accept: "application/json", "Content-Type": "application/json", }, data: JSON.stringify({ email: config.email, password: config.password, }), onload: function (response) { try { let res = JSON.parse(response.responseText); if (res.status && res.data?.token) { GM_setValue("token", res.data.token); config.token = res.data.token; resolve(res.data.token); } else { reject(res.message || "获取 Token 失败"); } } catch (e) { reject("无效响应:" + response.responseText); } }, onerror: () => reject("网络错误"), }); }); } function showUploadModal() { if (document.getElementById("upload-modal")) return; const modal = document.createElement("div"); modal.id = "upload-modal"; modal.innerHTML = ` `; document.body.appendChild(modal); addGlobalStyle(` #upload-modal { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: rgba(0, 0, 0, 0.5); padding: 20px; border-radius: 8px; z-index: 9999; display: flex; justify-content: center; align-items: center; } .modal-content { background-color: white; padding: 20px; border-radius: 8px; text-align: center; } .loader { border: 4px solid #f3f3f3; border-top: 4px solid #3498db; border-radius: 50%; width: 50px; height: 50px; animation: spin 1s linear infinite; margin: auto; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } `); } function hideUploadModal() { let modal = document.getElementById("upload-modal"); if (modal) modal.remove(); } function showSuccessMessage(msg) { let div = document.createElement("div"); div.innerHTML = `

${msg}

`; div.id = "success-modal"; document.body.appendChild(div); addGlobalStyle(` #success-modal { position: fixed; top: 20px; left: 50%; transform: translateX(-50%); background-color: rgba(0, 128, 0, 0.8); padding: 10px 20px; border-radius: 8px; color: white; z-index: 10000; font-size: 16px; } `); setTimeout(() => div.remove(), 3000); } function showFailureMessage(msg) { let div = document.createElement("div"); div.innerHTML = `

${msg}

`; div.id = "failure-modal"; document.body.appendChild(div); addGlobalStyle(` #failure-modal { position: fixed; top: 20px; left: 50%; transform: translateX(-50%); background-color: rgba(255, 0, 0, 0.8); padding: 10px 20px; border-radius: 8px; color: white; z-index: 10000; font-size: 16px; } `); setTimeout(() => div.remove(), 3000); } async function uploadImage(file) { return new Promise((resolve, reject) => { const formData = new FormData(); formData.append("file", file); GM_xmlhttpRequest({ method: "POST", url: `${config.baseUrl}/api/v1/upload`, headers: { Authorization: `Bearer ${config.token}`, }, data: formData, onload: function (response) { try { if (response.status === 401 || response.status === 403) { reject("unauthorized"); return; } const res = JSON.parse(response.responseText); if (res.status && res.data?.links?.markdown) { resolve(res.data.links.markdown); } else { reject(res.message || "上传失败"); } } catch (e) { reject("无效响应:" + response.responseText); } }, onerror: () => reject("网络错误"), }); }); } async function ensureTokenValid() { if (!config.token) { await getToken(); } } function insertText(text) { const el = document.activeElement; if (el && (el.tagName === "TEXTAREA" || el.tagName === "INPUT")) { const start = el.selectionStart; const end = el.selectionEnd; el.value = el.value.slice(0, start) + text + el.value.slice(end); el.selectionStart = el.selectionEnd = start + text.length; } else if (el?.isContentEditable) { document.execCommand("insertText", false, text); } } document.addEventListener("paste", async (event) => { try { const clipboard = event.clipboardData || event.originalEvent?.clipboardData; if (!clipboard) return; const items = clipboard.items; const images = []; for (let item of items) { if (item.type.indexOf("image") !== -1) { images.push(item.getAsFile()); } } if (images.length === 0) return; showUploadModal(); await ensureTokenValid(); for (const file of images) { try { const url = await uploadImage(file).catch(async (err) => { if (err === "unauthorized") { await getToken(); return await uploadImage(file); } throw err; }); await navigator.clipboard.writeText(url); showSuccessMessage("上传成功,链接已复制到剪贴板!"); } catch (err) { console.error(err); showFailureMessage("上传失败"); } } } catch (err) { console.error("粘贴处理异常:", err); } finally { hideUploadModal(); } }); // 初始化 addFloatingButton(); })();