const setupEl = document.getElementById("setup"); const statusEl = document.getElementById("status"); const backendUrlInput = document.getElementById("backendUrl"); const apiKeyInput = document.getElementById("apiKey"); const setupError = document.getElementById("setupError"); const statusLine = document.getElementById("statusLine"); const openBackend = document.getElementById("openBackend"); const blocklistEl = document.getElementById("blocklist"); const blockUserInput = document.getElementById("blockUserInput"); const blocklistStatus = document.getElementById("blocklistStatus"); function showSetup(settings) { setupEl.hidden = false; statusEl.hidden = true; backendUrlInput.value = settings.backendUrl || "http://127.0.0.1:8080"; apiKeyInput.value = settings.apiKey || ""; } function setBlocklistStatus(text, isError) { if (!text) { blocklistStatus.hidden = true; blocklistStatus.textContent = ""; return; } blocklistStatus.hidden = false; blocklistStatus.textContent = text; blocklistStatus.classList.toggle("error", Boolean(isError)); } function renderBlocklist(usernames) { blocklistEl.innerHTML = ""; if (!usernames.length) { const empty = document.createElement("li"); empty.className = "muted"; empty.textContent = "No blocked authors."; blocklistEl.appendChild(empty); return; } usernames.forEach((name) => { const li = document.createElement("li"); const label = document.createElement("span"); label.textContent = name; const remove = document.createElement("button"); remove.type = "button"; remove.className = "remove"; remove.textContent = "Remove"; remove.addEventListener("click", async () => { setBlocklistStatus("Syncing…"); try { const list = await rcsRemoveBlocked(name); renderBlocklist(list); setBlocklistStatus("Synced"); } catch (err) { setBlocklistStatus(String(err && err.message ? err.message : err), true); } }); li.appendChild(label); li.appendChild(remove); blocklistEl.appendChild(li); }); } async function syncBlocklistFromBackend() { setBlocklistStatus("Syncing…"); try { const list = await rcsPullBlocklist(); renderBlocklist(list); setBlocklistStatus(`Synced (${list.length})`); } catch (err) { const cached = await rcsGetCachedBlocklist(); renderBlocklist(cached); setBlocklistStatus("Sync failed — showing cache. " + (err && err.message ? err.message : err), true); } } function showStatus(settings, healthOk, healthHint) { setupEl.hidden = true; statusEl.hidden = false; if (healthOk) { statusLine.textContent = `Connected to ${settings.backendUrl}`; } else if (healthHint) { statusLine.textContent = healthHint; } else { statusLine.textContent = `Saved ${settings.backendUrl} (health check failed — is the backend running?)`; } openBackend.href = settings.backendUrl; if (healthOk) { syncBlocklistFromBackend(); } else { rcsGetCachedBlocklist().then(renderBlocklist); setBlocklistStatus("Connect to sync blocklist", true); } } async function load() { const settings = await chrome.storage.sync.get({ backendUrl: "", apiKey: "" }); if (!settings.backendUrl) { showSetup(settings); return; } try { const headers = { Accept: "application/json" }; if (settings.apiKey) headers["X-API-Key"] = settings.apiKey; const response = await fetch(`${settings.backendUrl.replace(/\/+$/, "")}/api/health`, { headers, credentials: "include", }); const text = await response.text(); let data = null; try { data = text ? JSON.parse(text) : null; } catch { data = { raw: text }; } const looksHtml = typeof text === "string" && /^\s* { setupError.hidden = true; const backendUrl = backendUrlInput.value.trim().replace(/\/+$/, ""); const apiKey = apiKeyInput.value.trim(); if (!backendUrl) { setupError.textContent = "Backend URL is required."; setupError.hidden = false; return; } try { new URL(backendUrl); } catch { setupError.textContent = "Invalid URL."; setupError.hidden = false; return; } const granted = await ensureHostPermission(backendUrl); if (!granted) { setupError.textContent = "Permission to reach the backend was denied."; setupError.hidden = false; return; } await chrome.storage.sync.set({ backendUrl, apiKey }); await load(); }); document.getElementById("edit").addEventListener("click", async () => { const settings = await chrome.storage.sync.get({ backendUrl: "", apiKey: "" }); showSetup(settings); }); document.getElementById("blockAdd").addEventListener("click", async () => { const username = blockUserInput.value.trim(); if (!username) return; setBlocklistStatus("Syncing…"); try { const list = await rcsAddBlocked(username); blockUserInput.value = ""; renderBlocklist(list); setBlocklistStatus("Synced"); } catch (err) { setBlocklistStatus(String(err && err.message ? err.message : err), true); } }); blockUserInput.addEventListener("keydown", (event) => { if (event.key === "Enter") { document.getElementById("blockAdd").click(); } }); load();