diff --git a/manifest.json b/manifest.json index 22f371e..24ccff6 100644 --- a/manifest.json +++ b/manifest.json @@ -7,6 +7,10 @@ "default_title": "Archive.org Link Grabber", "default_popup": "src/popup/index.html" }, + "options_ui": { + "page": "src/options/index.html", + "open_in_tab": true + }, "permissions": [ "storage", "clipboardWrite", @@ -28,4 +32,3 @@ } ] } - diff --git a/src/lib/aria2.js b/src/lib/aria2.js index 7509b4d..179881d 100644 --- a/src/lib/aria2.js +++ b/src/lib/aria2.js @@ -34,3 +34,21 @@ export async function addUrisBatch({ endpoint, secret, uris, options = {} }) { return results; } +export async function getVersion({ endpoint, secret }) { + const body = { + jsonrpc: "2.0", + id: "archive-org-link-grabber:getVersion:" + Date.now(), + method: "aria2.getVersion", + params: [secret ? `token:${secret}` : undefined].filter(Boolean) + }; + const res = await fetch(endpoint, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body) + }); + if (!res.ok) { + const text = await res.text().catch(() => String(res.status)); + throw new Error(`aria2 RPC error ${res.status}: ${text}`); + } + return res.json(); +} diff --git a/src/options/index.html b/src/options/index.html new file mode 100644 index 0000000..3b01b46 --- /dev/null +++ b/src/options/index.html @@ -0,0 +1,34 @@ + + + + + Archive.org Link Grabber — Options + + + +
+

Options

+
+
+
+

aria2 RPC

+
+ +
+
+ +
+
+ + + +
+
+ +
+
+
+ + + + diff --git a/src/options/index.js b/src/options/index.js new file mode 100644 index 0000000..c39d152 --- /dev/null +++ b/src/options/index.js @@ -0,0 +1,52 @@ +import { getVersion } from "../lib/aria2.js"; + +const els = { + endpoint: document.getElementById('rpc-endpoint'), + secret: document.getElementById('rpc-secret'), + btnSave: document.getElementById('btn-save'), + btnReset: document.getElementById('btn-reset'), + btnTest: document.getElementById('btn-test'), + status: document.getElementById('status'), +}; + +async function restore() { + const { aria2 } = await browser.storage.local.get('aria2'); + els.endpoint.value = aria2?.endpoint || 'http://localhost:6800/jsonrpc'; + els.secret.value = aria2?.secret || ''; +} + +async function save() { + const endpoint = els.endpoint.value.trim(); + const secret = els.secret.value.trim(); + await browser.storage.local.set({ aria2: { endpoint, secret } }); + els.status.textContent = 'Saved.'; +} + +async function reset() { + await browser.storage.local.remove('aria2'); + await restore(); + els.status.textContent = 'Reset to defaults.'; +} + +async function testConnection() { + els.status.textContent = 'Testing…'; + try { + const res = await getVersion({ endpoint: els.endpoint.value.trim(), secret: els.secret.value.trim() }); + const version = res?.result?.version || JSON.stringify(res?.result || res); + els.status.textContent = `OK: aria2 version ${version}`; + } catch (e) { + els.status.textContent = `Error: ${e?.message || e}`; + } +} + +function wire() { + els.btnSave.addEventListener('click', save); + els.btnReset.addEventListener('click', reset); + els.btnTest.addEventListener('click', testConnection); +} + +document.addEventListener('DOMContentLoaded', async () => { + wire(); + await restore(); +}); + diff --git a/src/options/styles.css b/src/options/styles.css new file mode 100644 index 0000000..722729e --- /dev/null +++ b/src/options/styles.css @@ -0,0 +1,9 @@ +body { font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif; margin: 16px; } +header h1 { margin: 0 0 12px; font-size: 18px; } +section { margin: 12px 0; } +.row { display: flex; align-items: center; gap: 8px; margin: 8px 0; flex-wrap: wrap; } +label { font-size: 14px; } +label input { margin-left: 6px; min-width: 360px; } +button { font-size: 13px; padding: 6px 12px; } +#status { font-size: 13px; white-space: pre-wrap; } +