feat(theseus/settings): Aegis update card + DevTools open in tab sidebar
Two additions: 1) Aegis (bchwallet) update card lands in Settings > General beside the Ariadne one. Same look, different substance: Aegis is a bundled add-on, not a system service, so no Install/Uninstall buttons — the checkboxes there are 'Check for updates' and (only when an update is staged) 'Restart to apply update'. Reuses the existing signed OTA endpoint (addons-check-updates IPC) and addons-list-staged for the pending-update surface, so new wallet versions ship without a Theseus release. New app-restart IPC (app.relaunch + app.quit) does the promotion handoff — addons-host promotes staged updates on next boot. 2) DevTools (F12 / Ctrl+Shift+I) opens docked to the right of the tab view (mode: 'right') instead of popping a detached window. A user debugging a page gets the tools alongside it, matching stock Chrome; anyone who prefers detached can still drag it out via the DevTools own toolbar.
This commit is contained in:
parent
ce53db3063
commit
b5f1cf468b
3 changed files with 67 additions and 4 deletions
11
main.js
11
main.js
|
|
@ -2978,6 +2978,9 @@ ipcMain.handle("find-stop", () => {
|
||||||
// Just the app version — no network. Used by Settings > General so the
|
// Just the app version — no network. Used by Settings > General so the
|
||||||
// user can see which Theseus they're on without clicking "Check for updates".
|
// user can see which Theseus they're on without clicking "Check for updates".
|
||||||
ipcMain.handle("app-version", () => app.getVersion());
|
ipcMain.handle("app-version", () => app.getVersion());
|
||||||
|
// Clean relaunch — used by the Aegis card to apply a staged add-on update
|
||||||
|
// (promotion happens on next boot; this is just how the user gets there).
|
||||||
|
ipcMain.handle("app-restart", () => { try { app.relaunch(); } catch {} app.quit(); });
|
||||||
ipcMain.handle("recheck-update", async () => {
|
ipcMain.handle("recheck-update", async () => {
|
||||||
// Manual "Check for updates" also un-dismisses any chip the user closed
|
// Manual "Check for updates" also un-dismisses any chip the user closed
|
||||||
// in this session — they're actively asking to see the status, so honour
|
// in this session — they're actively asking to see the status, so honour
|
||||||
|
|
@ -4056,9 +4059,9 @@ app.on("web-contents-created", (_event, wc) => {
|
||||||
return e.preventDefault();
|
return e.preventDefault();
|
||||||
}
|
}
|
||||||
// DevTools: F12 or Ctrl+Shift+I toggles Chromium DevTools on the active
|
// DevTools: F12 or Ctrl+Shift+I toggles Chromium DevTools on the active
|
||||||
// TAB (not the chrome/overlay that received the keystroke — a user
|
// TAB. Docked to the right of the tab view (mode: "right") so the tools
|
||||||
// debugging a page wants the page's inspector, always). Detach into
|
// ride alongside the page instead of popping a separate Theseus window.
|
||||||
// its own window so we don't shove tools into the tab strip.
|
// Users who prefer detached can still drag out via the DevTools UI.
|
||||||
const isI = input.key === "I" || input.key === "i";
|
const isI = input.key === "I" || input.key === "i";
|
||||||
if (input.key === "F12" || (input.control && input.shift && isI)) {
|
if (input.key === "F12" || (input.control && input.shift && isI)) {
|
||||||
const t = activeTab();
|
const t = activeTab();
|
||||||
|
|
@ -4066,7 +4069,7 @@ app.on("web-contents-created", (_event, wc) => {
|
||||||
try {
|
try {
|
||||||
const twc = t.view.webContents;
|
const twc = t.view.webContents;
|
||||||
if (twc.isDevToolsOpened()) twc.closeDevTools();
|
if (twc.isDevToolsOpened()) twc.closeDevTools();
|
||||||
else twc.openDevTools({ mode: "detach" });
|
else twc.openDevTools({ mode: "right" });
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
return e.preventDefault();
|
return e.preventDefault();
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ contextBridge.exposeInMainWorld("cfg", {
|
||||||
// fetches the release manifest. Returns { updateAvailable, currentVersion }.
|
// fetches the release manifest. Returns { updateAvailable, currentVersion }.
|
||||||
recheckUpdate: () => ipcRenderer.invoke("recheck-update"),
|
recheckUpdate: () => ipcRenderer.invoke("recheck-update"),
|
||||||
appVersion: () => ipcRenderer.invoke("app-version"),
|
appVersion: () => ipcRenderer.invoke("app-version"),
|
||||||
|
restartApp: () => ipcRenderer.invoke("app-restart"),
|
||||||
// Add-ons management (Settings > Add-ons tab).
|
// Add-ons management (Settings > Add-ons tab).
|
||||||
listAddons: () => ipcRenderer.invoke("addons-list"),
|
listAddons: () => ipcRenderer.invoke("addons-list"),
|
||||||
setAddonEnabled: (id, enabled) => ipcRenderer.invoke("addons-set-enabled", id, !!enabled),
|
setAddonEnabled: (id, enabled) => ipcRenderer.invoke("addons-set-enabled", id, !!enabled),
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,22 @@
|
||||||
<a href="https://silentmode.st/tools/">silentmode.st/tools</a>.
|
<a href="https://silentmode.st/tools/">silentmode.st/tools</a>.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row" style="flex-direction:column;align-items:stretch;gap:8px">
|
||||||
|
<div class="txt">
|
||||||
|
<div class="t">Built-in wallet — Aegis</div>
|
||||||
|
<div class="d">
|
||||||
|
Multi-chain wallet (BCH, BTC, TRX, ETH, SOL, SC, DGB) that ships in the box.
|
||||||
|
Bundled with Theseus, but updates are delivered <b>over-the-air</b>: new signed
|
||||||
|
versions land without a Theseus release. Runs entirely inside this browser —
|
||||||
|
never system-wide.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="aegisStatus" class="pmuted" style="font-size:12.5px">Loading…</div>
|
||||||
|
<div style="display:flex;gap:8px;flex-wrap:wrap">
|
||||||
|
<button id="aegisCheck" class="btn">Check for updates</button>
|
||||||
|
<button id="aegisApply" class="btn" hidden>Restart to apply update</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<!-- SEARCH -->
|
<!-- SEARCH -->
|
||||||
<section id="search" hidden>
|
<section id="search" hidden>
|
||||||
|
|
@ -982,6 +998,49 @@
|
||||||
arRefresh.onclick = refreshAriadne;
|
arRefresh.onclick = refreshAriadne;
|
||||||
refreshAriadne();
|
refreshAriadne();
|
||||||
|
|
||||||
|
// ---- Aegis (bchwallet) update card --------------------------------------
|
||||||
|
// Aegis is a bundled add-on but its updates are shipped OTA via the signed
|
||||||
|
// add-on update endpoint, so users can get new wallet versions without
|
||||||
|
// updating Theseus. The same addons-check-updates IPC the Extensions page
|
||||||
|
// uses is filtered for the bchwallet id so this card only speaks for Aegis.
|
||||||
|
const aegisStatus = document.getElementById("aegisStatus");
|
||||||
|
const aegisCheck = document.getElementById("aegisCheck");
|
||||||
|
const aegisApply = document.getElementById("aegisApply");
|
||||||
|
async function refreshAegis() {
|
||||||
|
aegisApply.hidden = true;
|
||||||
|
try {
|
||||||
|
const [installed, staged] = await Promise.all([
|
||||||
|
C.listAddons ? C.listAddons() : Promise.resolve([]),
|
||||||
|
C.listStagedAddonUpdates ? C.listStagedAddonUpdates() : Promise.resolve([]),
|
||||||
|
]);
|
||||||
|
const cur = (installed || []).find((a) => a.id === "bchwallet");
|
||||||
|
const upd = (staged || []).find((a) => a.id === "bchwallet");
|
||||||
|
if (!cur) { aegisStatus.textContent = "Aegis isn't installed. Reinstall Theseus to add it back, or open Settings > Extensions to load it manually."; return; }
|
||||||
|
const curVer = cur.version || "?";
|
||||||
|
if (upd && upd.version) {
|
||||||
|
aegisStatus.innerHTML = `<b style="color:var(--acid-text)">v${upd.version}</b> staged — restart Theseus to switch to it. You're on v${curVer}.`;
|
||||||
|
aegisApply.hidden = false;
|
||||||
|
} else {
|
||||||
|
aegisStatus.textContent = `You're on v${curVer}. Updates arrive over-the-air; the next check runs at boot and every 6h.`;
|
||||||
|
}
|
||||||
|
} catch (e) { aegisStatus.textContent = "Status check failed: " + (e?.message || e); }
|
||||||
|
}
|
||||||
|
aegisCheck.onclick = async () => {
|
||||||
|
const orig = aegisCheck.textContent;
|
||||||
|
aegisCheck.disabled = true; aegisCheck.textContent = "Checking…";
|
||||||
|
aegisStatus.textContent = "Checking…";
|
||||||
|
try {
|
||||||
|
const staged = await (C.checkAddonUpdates ? C.checkAddonUpdates() : Promise.resolve([]));
|
||||||
|
const upd = (staged || []).find((a) => a.id === "bchwallet");
|
||||||
|
if (!upd) { aegisStatus.textContent = "You're on the latest Aegis."; }
|
||||||
|
// refresh will populate everything else + toggle the Apply button
|
||||||
|
refreshAegis();
|
||||||
|
} catch (e) { aegisStatus.textContent = "Check failed: " + (e?.message || e); }
|
||||||
|
finally { aegisCheck.disabled = false; aegisCheck.textContent = orig; }
|
||||||
|
};
|
||||||
|
aegisApply.onclick = () => { if (C && C.restartApp) C.restartApp(); };
|
||||||
|
refreshAegis();
|
||||||
|
|
||||||
// ---- Manual "Check for updates" -----------------------------------------
|
// ---- Manual "Check for updates" -----------------------------------------
|
||||||
// Fires an IPC that un-dismisses any lingering session chip and hits the
|
// Fires an IPC that un-dismisses any lingering session chip and hits the
|
||||||
// release manifest. Renders either "you're on the latest (vN.M.O)" or
|
// release manifest. Renders either "you're on the latest (vN.M.O)" or
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue