function setStatus(message) { document.getElementById("status").textContent = message; } async function getActiveTab() { const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); if (!tab?.id) { throw new Error("No readable active tab found."); } return tab; } async function captureFromActiveTab(tabId) { const [result] = await chrome.scripting.executeScript({ target: { tabId }, func: deerExtractCurrentPage, }); if (!result?.result?.content) { throw new Error("The current page has no readable text to send."); } return result.result; } async function submitToZncm(page, settings, prompt) { const apiBaseUrl = deerNormalizeBaseUrl(settings.apiBaseUrl || DEER_CLIPPER_DEFAULTS.apiBaseUrl); const response = await fetch(`${apiBaseUrl}/api/browser-context/capture`, { method: "POST", headers: { "Content-Type": "application/json", ...deerAuthHeaders(settings), }, body: JSON.stringify({ title: page.title, url: page.url, content: page.content, content_type: page.contentType, prompt, }), }); const data = await response.json().catch(() => ({})); if (!response.ok) { const detail = typeof data.detail === "string" ? data.detail : JSON.stringify(data.detail || data); throw new Error(detail || `HTTP ${response.status}`); } return data; } async function sendCurrentPage() { const sendButton = document.getElementById("send"); sendButton.disabled = true; setStatus("正在读取当前页面..."); try { await syncToken({ silent: true }); const settings = await chrome.storage.sync.get(DEER_CLIPPER_DEFAULTS); const prompt = document.getElementById("prompt").value.trim() || settings.defaultPrompt || DEER_CLIPPER_DEFAULT_PROMPT; const tab = await getActiveTab(); const page = await captureFromActiveTab(tab.id); setStatus("正在发送到 zncm..."); const result = await submitToZncm(page, settings, prompt); const webBaseUrl = deerNormalizeBaseUrl(settings.webBaseUrl || DEER_CLIPPER_DEFAULTS.webBaseUrl); await chrome.tabs.create({ url: `${webBaseUrl}/${result.chat_url}`.replace(/\/#/g, "/#") }); setStatus("已发送,zncm 聊天页面已打开。"); } catch (error) { setStatus(error instanceof Error ? error.message : "发送失败。"); } finally { sendButton.disabled = false; } } function sendSyncTokenMessage() { return new Promise((resolve, reject) => { chrome.runtime.sendMessage({ type: "zncm-sync-token" }, (response) => { const error = chrome.runtime.lastError; if (error) { reject(new Error(error.message)); return; } resolve(response || { ok: false, message: "Token 同步没有返回结果。" }); }); }); } function sendPollNowMessage() { return new Promise((resolve, reject) => { chrome.runtime.sendMessage({ type: "zncm-poll-now" }, (response) => { const error = chrome.runtime.lastError; if (error) { reject(new Error(error.message)); return; } resolve(response || { ok: true, message: "Poll requested." }); }); }); } async function syncToken(options = {}) { const button = document.getElementById("syncToken"); button.disabled = true; if (!options.silent) { setStatus("正在同步 zncm token..."); } try { const response = await sendSyncTokenMessage(); if (!options.silent) { setStatus(response.message || "Token sync finished."); } return response; } catch (error) { if (!options.silent) { setStatus(error instanceof Error ? error.message : "Token 同步失败。"); } return { ok: false, message: error instanceof Error ? error.message : "Token 同步失败。" }; } finally { button.disabled = false; } } async function pollNow() { const button = document.getElementById("pollNow"); button.disabled = true; setStatus("正在检查 zncm 浏览器任务..."); try { await syncToken({ silent: true }); const response = await sendPollNowMessage(); setStatus(response.message || "任务检查完成。"); } catch (error) { setStatus(error instanceof Error ? error.message : "任务检查失败。"); } finally { button.disabled = false; } } async function togglePageAssistant() { const enabled = document.getElementById("pageAssistantEnabled").checked; await chrome.storage.sync.set({ pageAssistantEnabled: enabled }); setStatus(enabled ? "页面问答框已开启。" : "页面问答框已关闭。"); } async function init() { const settings = await chrome.storage.sync.get(DEER_CLIPPER_DEFAULTS); document.getElementById("prompt").value = settings.defaultPrompt || DEER_CLIPPER_DEFAULT_PROMPT; document.getElementById("pageAssistantEnabled").checked = Boolean(settings.pageAssistantEnabled); document.getElementById("send").addEventListener("click", sendCurrentPage); document.getElementById("syncToken").addEventListener("click", () => syncToken()); document.getElementById("pollNow").addEventListener("click", pollNow); document.getElementById("pageAssistantEnabled").addEventListener("change", togglePageAssistant); document.getElementById("options").addEventListener("click", () => chrome.runtime.openOptionsPage()); } void init();