diff --git a/extensions/index.html b/extensions/index.html index aaf1113..85d8cfc 100644 --- a/extensions/index.html +++ b/extensions/index.html @@ -104,6 +104,16 @@ .ext .install.alt{background:rgba(214,255,61,.12);color:var(--acid)} .ext .act .st{font-size:13px;color:var(--mut)} .ext .act .st.ok{color:var(--acid)} .ext .act .st.err{color:#f6768a} + .ext .act .how{flex-basis:100%;font-size:13px;color:var(--mut);background:#0e131b;border:1px solid var(--line);border-radius:8px;padding:8px 12px} + .ext .how b{color:var(--ink)} + .search{max-width:560px;margin:1.4rem auto 0;position:relative} + .search input{width:100%;background:var(--panel);border:1px solid var(--line);border-radius:12px;color:var(--ink); + font:inherit;font-size:15px;padding:11px 14px 11px 40px;outline:none} + .search input:focus{border-color:rgba(214,255,61,.5)} + .search svg{position:absolute;left:13px;top:50%;transform:translateY(-50%);width:17px;height:17px;color:var(--dim)} + .search .n{position:absolute;right:13px;top:50%;transform:translateY(-50%);font-size:12px;color:var(--dim)} + .ext.hide, .nomatch{display:none} + .nomatch.show{display:block} .note{background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--acid); border-radius:10px;padding:14px 18px;color:var(--mut);font-size:14px;margin:1.4rem 0} .note b{color:var(--ink)} @@ -151,6 +161,11 @@ publish. Every package is signed (by the Silent Mode operator, or by the publisher's own BCDN name) and verified on your device before install. No cert authority, no app-store gatekeeper. First-party plug-ins (Aegis, Ariadne's Thread) have their own page.

+
@@ -180,6 +195,13 @@
Settings › Extensions · no update channel yet — ships with each Theseus release.
+
+

🌐 Translate bundled 0.1.0

+
Select text on any page and right-click Translate — the sidebar panel shows the translation, + with LibreTranslate or Google as the backend (your choice in the panel). Nothing is sent until you ask.
+
Settings › Extensions · no update channel yet — ships with each Theseus release.
+
+

PDF Editor current 0.1.0

Open a PDF in a full tab — read, highlight, mark up, reorder or rotate or drop pages, @@ -194,6 +216,8 @@
sha256—
+ +
No bundled extension matches that search.
@@ -203,6 +227,7 @@ package itself and re-checks every signature against the name's current owner in its own chain index — the relay cannot substitute code under a trusted name.

Loading the catalog…
+
No community extension matches that search.
Trust, stated plainly. A community extension runs with the same access as any add-on — treat one like an unsigned executable from that publisher. The signature proves who published it, not that it is safe.
@@ -268,11 +293,10 @@ // fetches the package, confirms in a native dialog and verifies the signature. const inTheseus = !!window.bcnr; const canInstall = inTheseus && typeof window.bcnr.installExtension === "function"; - const installUi = (id) => canInstall - ? `` - : inTheseus - ? `Update Theseus to install from hereuntil then: Settings › Extensions › Community › Install` - : `Get Theseus to installone click from this page inside Theseus`; + const mode = canInstall ? "bridge" : inTheseus ? "old" : "none"; + const installUi = (id) => mode === "none" + ? `Get Theseus to installone click from this page inside Theseus` + : ``; try { const r = await fetch("./community/catalog.json", { cache: "no-store" }); const cat = r.ok ? await r.json() : { extensions: [] }; @@ -299,6 +323,16 @@ `).join(""); box.querySelectorAll("button[data-install]").forEach((btn) => btn.addEventListener("click", async () => { const id = btn.dataset.install, st = box.querySelector(`[data-st="${CSS.escape(id)}"]`); + if (btn.dataset.mode === "old") { + // This Theseus predates the page bridge: point at the path it does have. + const name = [...btn.closest(".ext").querySelector("h3").childNodes].find((x) => x.nodeType === 3 && x.textContent.trim())?.textContent.trim() || id; + let how = btn.parentElement.querySelector(".how"); + if (!how) { how = document.createElement("div"); how.className = "how"; btn.parentElement.appendChild(how); } + how.innerHTML = `Your Theseus is older than this button. Open Settings › Extensions, scroll to Community and press + Install next to ${esc(name)} — same signed package, same checks. Newer builds install from here in one click: + update Theseus.`; + return; + } btn.disabled = true; st.className = "st"; st.textContent = "Confirm in the Theseus dialog…"; let r; try { r = await window.bcnr.installExtension(id); } catch (err) { r = { ok: false, error: err?.message || String(err) }; } if (r && r.ok) { st.className = "st ok"; st.textContent = `Installed v${r.version} — signed by ${r.publisher}`; btn.textContent = "Installed"; } @@ -306,6 +340,25 @@ })); } catch (e) { box.innerHTML = '
Catalog unavailable right now.
'; } })(); +// Search: filters the bundled and community cards by name, description, publisher, capabilities. +(() => { + const q = document.getElementById("extSearch"), n = document.getElementById("extSearchN"); + const apply = () => { + const s = q.value.trim().toLowerCase(); + let shown = 0; + for (const sec of ["bundled", "community"]) { + const cards = [...document.querySelectorAll(`#${sec} .ext`)].filter((c) => c.querySelector("h3")); + let hit = 0; + for (const c of cards) { const ok = !s || c.textContent.toLowerCase().includes(s); c.classList.toggle("hide", !ok); if (ok) hit++; } + document.getElementById(sec === "bundled" ? "nomatchBundled" : "nomatchCommunity").classList.toggle("show", !!s && cards.length > 0 && hit === 0); + shown += hit; + } + n.textContent = s ? `${shown} match${shown === 1 ? "" : "es"}` : ""; + }; + q.addEventListener("input", apply); + new MutationObserver(() => { if (q.value.trim()) apply(); }).observe(document.getElementById("communityList"), { childList: true }); + if (location.hash === "#search") q.focus(); +})();