feat(theseus/chrome): per-extension toolbar dock + Aegis placeholder
Replaces the single sidebarbtn with a dock that renders one button per registered addon sidebar-panel. Each button shows the panel's icon (the emoji from its manifest) and opens the sidebar on that panel. Clicking the currently-active button collapses the sidebar; clicking a different one swaps the visible panel. Notepad (📝) and Silent Mode Relay (🌐) appear automatically because they already register panels. Also lands a static Aegis Wallet placeholder button (₿) next to the live ones, styled as .soon so it reads as coming-soon. It'll come out once the addon registers a real panel. Preload adds openSidebar(panelId) and closeSidebar() wrappers around the existing sidebar-open / sidebar-close IPC handlers.
This commit is contained in:
parent
40391798e0
commit
f5a500c796
2 changed files with 58 additions and 13 deletions
64
chrome.html
64
chrome.html
|
|
@ -102,6 +102,20 @@
|
||||||
.ic.active { background: rgba(214,255,61,.12); color: var(--acid); }
|
.ic.active { background: rgba(214,255,61,.12); color: var(--acid); }
|
||||||
.ic:active { background: var(--line); }
|
.ic:active { background: var(--line); }
|
||||||
.ic:disabled { opacity: .28; cursor: default; background: transparent; }
|
.ic:disabled { opacity: .28; cursor: default; background: transparent; }
|
||||||
|
/* One toolbar button per registered addon sidebar-panel, plus a static
|
||||||
|
placeholder for the built-in wallet before it lands. Each button
|
||||||
|
shows the panel's icon (usually a single emoji from the manifest);
|
||||||
|
click toggles the sidebar open on that panel, or collapses if it
|
||||||
|
was already the active panel. */
|
||||||
|
.extdock { display: flex; gap: 2px; align-items: center; padding-left: 4px; margin-left: 2px;
|
||||||
|
border-left: 1px solid var(--line); }
|
||||||
|
.extbtn { width: 30px; height: 30px; display: grid; place-items: center; border-radius: 7px;
|
||||||
|
cursor: pointer; border: none; background: transparent; padding: 0;
|
||||||
|
font-size: 15px; line-height: 1; color: var(--mut); }
|
||||||
|
.extbtn:hover { background: var(--line2); color: var(--ink); }
|
||||||
|
.extbtn.active { background: rgba(214,255,61,.12); color: var(--acid); box-shadow: inset 0 -2px 0 var(--acid); }
|
||||||
|
.extbtn.soon { opacity: .45; cursor: help; }
|
||||||
|
.extbtn.soon:hover { opacity: .7; background: var(--line2); }
|
||||||
/* downloads button — a small badge sits over the icon when there's activity */
|
/* downloads button — a small badge sits over the icon when there's activity */
|
||||||
.dlbtn { position: relative; }
|
.dlbtn { position: relative; }
|
||||||
.dlbtn.spin::before { content: ""; position: absolute; inset: 4px; border-radius: 999px;
|
.dlbtn.spin::before { content: ""; position: absolute; inset: 4px; border-radius: 999px;
|
||||||
|
|
@ -278,9 +292,10 @@
|
||||||
<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M8 2 V10 M4.5 6.5 L8 10 L11.5 6.5"/><path d="M3 12.5 L3 13.5 L13 13.5 L13 12.5"/></svg>
|
<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M8 2 V10 M4.5 6.5 L8 10 L11.5 6.5"/><path d="M3 12.5 L3 13.5 L13 13.5 L13 12.5"/></svg>
|
||||||
<span class="dlbadge" id="dlbadge" hidden>0</span>
|
<span class="dlbadge" id="dlbadge" hidden>0</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="ic" id="sidebarbtn" title="Toggle extension sidebar" hidden>
|
<span class="extdock" id="extdock" hidden>
|
||||||
<svg viewBox="0 0 16 16" aria-hidden="true"><rect x="2" y="3" width="12" height="10" rx="1.5"/><path d="M10 3 L10 13"/></svg>
|
<span id="extbuttons"></span>
|
||||||
</button>
|
<button class="extbtn soon" id="aegisSoon" title="Aegis Wallet — built-in BCH wallet, coming soon" aria-disabled="true">₿</button>
|
||||||
|
</span>
|
||||||
<span class="upchip" id="upchip" hidden><button class="upcore" id="upDownload" title=""></button><button class="updismiss" id="upDismiss" title="Not now">✕</button></span>
|
<span class="upchip" id="upchip" hidden><button class="upcore" id="upDownload" title=""></button><button class="updismiss" id="upDismiss" title="Not now">✕</button></span>
|
||||||
<button class="tor" id="tor" title="Route traffic through Tor">🧅 Tor: Off</button>
|
<button class="tor" id="tor" title="Route traffic through Tor">🧅 Tor: Off</button>
|
||||||
<button class="logo" id="logo" title="Settings"><span>⛓ Theseus</span><span class="gear">⚙</span></button>
|
<button class="logo" id="logo" title="Settings"><span>⛓ Theseus</span><span class="gear">⚙</span></button>
|
||||||
|
|
@ -408,18 +423,43 @@
|
||||||
T.getDownloads && T.getDownloads().then(renderDownloads);
|
T.getDownloads && T.getDownloads().then(renderDownloads);
|
||||||
T.onDownloads && T.onDownloads(renderDownloads);
|
T.onDownloads && T.onDownloads(renderDownloads);
|
||||||
|
|
||||||
// ---- add-on sidebar toggle ----
|
// ---- extension dock ----
|
||||||
// Only surfaces the button when at least one add-on has registered a
|
// One toolbar button per registered addon sidebar-panel, plus a static
|
||||||
// sidebar panel; a fresh install with no add-ons keeps the toolbar clean.
|
// "coming soon" placeholder for Aegis (the built-in BCH wallet, in
|
||||||
const sideBtn = $("sidebarbtn");
|
// progress). Click a live button → open the sidebar on that panel; if
|
||||||
|
// the sidebar was already open on that panel, collapse it.
|
||||||
|
const extDock = $("extdock");
|
||||||
|
const extButtons = $("extbuttons");
|
||||||
|
let lastPanels = [], sidebarOpen = false, activePanelId = null;
|
||||||
function renderSidebarState(d) {
|
function renderSidebarState(d) {
|
||||||
if (!d) return;
|
if (!d) return;
|
||||||
const has = Array.isArray(d.panels) && d.panels.length > 0;
|
lastPanels = Array.isArray(d.panels) ? d.panels : [];
|
||||||
sideBtn.hidden = !has;
|
sidebarOpen = !!d.visible;
|
||||||
sideBtn.classList.toggle("active", !!d.visible);
|
activePanelId = d.active || null;
|
||||||
if (has && d.panels[0]) sideBtn.title = "Toggle " + d.panels[0].title;
|
// Dock is always visible when either at least one addon panel exists
|
||||||
|
// OR the Aegis placeholder is meant to show. Aegis is always shown
|
||||||
|
// for now, so the dock is always visible.
|
||||||
|
extDock.hidden = false;
|
||||||
|
extButtons.innerHTML = lastPanels.map((p) => {
|
||||||
|
const isActive = sidebarOpen && p.panelId === activePanelId;
|
||||||
|
const icon = String(p.icon || "•");
|
||||||
|
return `<button class="extbtn${isActive ? " active" : ""}" data-panel="${p.panelId.replace(/"/g,""")}" title="${(p.title || "Extension").replace(/"/g,""")}">${icon.replace(/</g,"<")}</button>`;
|
||||||
|
}).join("");
|
||||||
|
extButtons.querySelectorAll(".extbtn").forEach((btn) => {
|
||||||
|
btn.onclick = () => {
|
||||||
|
const pid = btn.dataset.panel;
|
||||||
|
if (sidebarOpen && pid === activePanelId) { T.closeSidebar && T.closeSidebar(); }
|
||||||
|
else { T.openSidebar && T.openSidebar(pid); }
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
sideBtn.onclick = () => T.toggleSidebar && T.toggleSidebar();
|
$("aegisSoon").onclick = () => {
|
||||||
|
// Non-blocking hint — the user asked for the placeholder to appear now
|
||||||
|
// even though the wallet ships in a later release. Once the addon is
|
||||||
|
// registered it renders as a live extbtn and this static button can
|
||||||
|
// come out.
|
||||||
|
$("aegisSoon").title = "Aegis Wallet — built-in BCH wallet, coming soon";
|
||||||
|
};
|
||||||
T.sidebarState && T.sidebarState().then(renderSidebarState);
|
T.sidebarState && T.sidebarState().then(renderSidebarState);
|
||||||
T.onSidebarState && T.onSidebarState(renderSidebarState);
|
T.onSidebarState && T.onSidebarState(renderSidebarState);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,13 @@ contextBridge.exposeInMainWorld("theseus", {
|
||||||
getDownloads: () => ipcRenderer.invoke("downloads-get"),
|
getDownloads: () => ipcRenderer.invoke("downloads-get"),
|
||||||
toggleDownloads: (rect) => ipcRenderer.invoke("toggle-downloads", rect),
|
toggleDownloads: (rect) => ipcRenderer.invoke("toggle-downloads", rect),
|
||||||
onDownloads: (cb) => ipcRenderer.on("downloads", (_e, d) => cb(d)),
|
onDownloads: (cb) => ipcRenderer.on("downloads", (_e, d) => cb(d)),
|
||||||
// Add-on sidebar toggle in the toolbar.
|
// Add-on sidebar: toggle, open on a specific panel, close, or subscribe
|
||||||
|
// to state (visibility + which panel is active + the panel list). The
|
||||||
|
// extension dock in chrome.html renders one button per panel and calls
|
||||||
|
// openSidebar / closeSidebar accordingly.
|
||||||
toggleSidebar: () => ipcRenderer.invoke("sidebar-toggle"),
|
toggleSidebar: () => ipcRenderer.invoke("sidebar-toggle"),
|
||||||
|
openSidebar: (panelId) => ipcRenderer.invoke("sidebar-open", panelId),
|
||||||
|
closeSidebar: () => ipcRenderer.invoke("sidebar-close"),
|
||||||
sidebarState: () => ipcRenderer.invoke("sidebar-state"),
|
sidebarState: () => ipcRenderer.invoke("sidebar-state"),
|
||||||
onSidebarState: (cb) => ipcRenderer.on("sidebar-state", (_e, d) => cb(d)),
|
onSidebarState: (cb) => ipcRenderer.on("sidebar-state", (_e, d) => cb(d)),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue