diff --git a/bundled-addons/aegis/addon.json b/bundled-addons/aegis/addon.json index 9cb2f7fc..f4caa1c7 100644 --- a/bundled-addons/aegis/addon.json +++ b/bundled-addons/aegis/addon.json @@ -1,7 +1,7 @@ { "id": "aegis", "name": "Aegis Wallet", - "version": "0.8.3", + "version": "0.8.4", "category": "plugin", "description": "Multi-chain wallet (BCH, BTC, TRX, ETH, SOL, SC, DGB) derived from your Theseus vault. Dapps get window.bitcoincash on .x sites; window.tronWeb / window.tronLink / window.ethereum / window.solana on any https page.", "author": "Silent Mode", diff --git a/bundled-addons/aegis/panel.html b/bundled-addons/aegis/panel.html index 8355579e..2671fcdc 100644 --- a/bundled-addons/aegis/panel.html +++ b/bundled-addons/aegis/panel.html @@ -81,7 +81,24 @@ #drop .brnet .hint { color: currentColor; opacity: .65; font-size: 11px; } .ttag { display: inline-block; font-size: 9.5px; letter-spacing: .06em; padding: 1px 5px; border-radius: 3px; background: rgba(224,179,65,.18); color: #e0b341; font-weight: 700; vertical-align: middle; margin-left: 2px; } - #hNet { color: var(--dim); font-size: 11px; margin-left: 4px; font-weight: 500; } + /* 0.8.4: hNet became a proper chip on its own row (.netrow) so the + network the wallet is on is easy to spot AND easy to switch. */ + .netrow { display: flex; margin-top: 6px; padding: 0 2px; } + .netchip { background: rgba(255,255,255,.05); border: 1px solid var(--line); + color: var(--mut); border-radius: 999px; padding: 3px 10px 3px 8px; + font: inherit; font-size: 11.5px; cursor: pointer; display: inline-flex; + align-items: center; gap: 6px; line-height: 1.2; } + .netchip:hover { border-color: var(--acid, #d6ff3d); color: var(--acid, #d6ff3d); } + .netchip::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .7; } + /* Currency-picker search + all-coins catalogue (0.8.4). */ + #drop .pickersearch { padding: 8px; border-bottom: 1px solid var(--line); } + #drop .pickersearch input { width: 100%; box-sizing: border-box; background: rgba(255,255,255,.04); + border: 1px solid var(--line); color: var(--ink); border-radius: 7px; + padding: 7px 10px; font: inherit; font-size: 12.5px; outline: none; } + #drop .pickersearch input:focus { border-color: rgb(from var(--acid, #d6ff3d) r g b / .55); } + #drop .catgroup { padding: 4px 6px 2px 10px; color: var(--dim); font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; } + #drop .row.unowned { opacity: .8; } + #drop .row.unowned .v { color: var(--acid, #d6ff3d); font-weight: 600; font-size: 11px; } .fiat { color: var(--dim); font-size: 12.5px; margin-left: 10px; font-weight: 500; letter-spacing: .2px; } .portfolio { margin-top: 6px; color: var(--mut); font-size: 11.5px; } .portfolio b { color: var(--ink); font-weight: 600; } @@ -500,7 +517,6 @@
Aegis Wallet - @@ -514,6 +530,12 @@
+ +
diff --git a/bundled-addons/aegis/panel.js b/bundled-addons/aegis/panel.js index f88cec7d..38b5b55e 100644 --- a/bundled-addons/aegis/panel.js +++ b/bundled-addons/aegis/panel.js @@ -378,6 +378,19 @@ $("pickerBtn").addEventListener("click", (e) => { d.hidden = false; fillPicker(); }); +// 0.8.4: separate netchip row. Click jumps straight to the browse:chain +// view for the current wallet's chain — the network-chip strip at the +// top of that view is what actually switches networks. +$("hNet").addEventListener("click", (e) => { + e.stopPropagation(); + const w = (state?.wallets || []).find((x) => x.id === state?.selectedWalletId); + if (!w) return; + pickerTab = "browse:" + w.chain; + const d = $("drop"); + positionDropBelowTabs(d); + d.hidden = false; + fillPicker(); +}); // + Add and ⋯ More chips moved from the wallet strip into the header // (0.6.31). Same handlers as before — fillPicker for the Add-only picker, // openMoreMenu for Import/Connect/About. Each stopsPropagation so the @@ -426,6 +439,11 @@ document.addEventListener("click", (e) => { // user who opens the picker → picks Import → cancels → reopens returns to // Wallets (the sane default). let pickerTab = "wallets"; +// 0.8.4: coin catalogue search query + one-shot preselected chain for the +// Add pane (set when the browse view routes into "add" for a specific +// unowned coin). +let browseQuery = ""; +let pickerAddChain = null; function fillPicker() { const d = $("drop"); @@ -508,42 +526,94 @@ function fillPicker() { walletsByChain.get(w.chain).push(w); } if (!focused) { - // COINS: one row per chain user has a wallet for. - const rows = []; - for (const [chain, ws] of walletsByChain) { - const first = ws[0]; - const nets = Array.from(new Set(ws.map((w) => w.network))); - let active = activeNetworkByChain.get(chain); - if (!active || !nets.includes(active)) active = nets.includes("mainnet") ? "mainnet" : nets[0]; - const netLbl = networkLabelFor(chain, active, active); - const totalUnits = sumGroupUnits(ws.filter((w) => w.network === active)); - const dec = first.decimals || 8; - const bal = fmtBig(totalUnits || 0, dec) + " " + esc(first.ticker || chain.toUpperCase()); - const usd = usdOf(chain, totalUnits || 0, dec); - const fiat = usd != null ? `
${esc(fmtFiat(usd))}
` : ""; - const activeMark = ws.some((w) => w.id === state?.selectedWalletId) ? "on" : ""; - rows.push(`
- ${logoSvg(first.logo, 22)} -
-
${esc(first.coinLabel || chain.toUpperCase())} · ${ws.length} wallet${ws.length === 1 ? "" : "s"}${nets.length > 1 ? ` · ${esc(netLbl)}` : ""}
-
${esc(chain)}
-
-
${bal}
${fiat}
-
`); + // 0.8.4: full catalogue with search. Every supported chain is + // listed, whether the user already has a wallet on it or not. + // Rows for owned coins jump to that coin's wallet list; rows for + // unowned coins jump straight into the Add-wallet flow for that + // coin, so the header picker doubles as a fast on-ramp. + const q = String(browseQuery || "").trim().toLowerCase(); + const matches = (c) => !q + || String(c.chain || "").toLowerCase().includes(q) + || String(c.label || "").toLowerCase().includes(q) + || String(c.ticker || "").toLowerCase().includes(q) + || String(c.short || "").toLowerCase().includes(q); + const ownedRows = []; + const otherRows = []; + for (const c of coins) { + if (!matches(c)) continue; + const ws = walletsByChain.get(c.chain) || []; + if (ws.length > 0) { + const first = ws[0]; + const nets = Array.from(new Set(ws.map((w) => w.network))); + let active = activeNetworkByChain.get(c.chain); + if (!active || !nets.includes(active)) active = nets.includes("mainnet") ? "mainnet" : nets[0]; + const netLbl = networkLabelFor(c.chain, active, active); + const totalUnits = sumGroupUnits(ws.filter((w) => w.network === active)); + const dec = first.decimals || c.decimals || 8; + const bal = fmtBig(totalUnits || 0, dec) + " " + esc(first.ticker || c.ticker || c.chain.toUpperCase()); + const usd = usdOf(c.chain, totalUnits || 0, dec); + const fiat = usd != null ? `
${esc(fmtFiat(usd))}
` : ""; + const activeMark = ws.some((w) => w.id === state?.selectedWalletId) ? "on" : ""; + ownedRows.push(`
+ ${logoSvg(c.logo, 22)} +
+
${esc(c.label)} · ${ws.length} wallet${ws.length === 1 ? "" : "s"}${nets.length > 1 ? ` · ${esc(netLbl)}` : ""}
+
${esc(c.ticker || c.chain)}
+
+
${bal}
${fiat}
+
`); + } else { + otherRows.push(`
+ ${logoSvg(c.logo, 22)} +
+
${esc(c.label)}
+
${esc(c.ticker || c.chain)}
+
+
+ Add
+
`); + } } d.innerHTML = `
Pick a coin
+
- ${rows.length ? rows.join("") : `
No wallets yet. Use + to create one.
`} + ${ownedRows.length ? `
Your wallets
${ownedRows.join("")}` : ""} + ${otherRows.length ? `
Add a new wallet
${otherRows.join("")}` : ""} + ${(!ownedRows.length && !otherRows.length) ? `
No coins match "${esc(q)}".
` : ""}
`; d.querySelectorAll("[data-browse-chain]").forEach((row) => row.addEventListener("click", (e) => { e.stopPropagation(); pickerTab = "browse:" + row.dataset.browseChain; fillPicker(); })); + d.querySelectorAll("[data-browse-add]").forEach((row) => row.addEventListener("click", (e) => { + e.stopPropagation(); + const chain = row.dataset.browseAdd; + // Jump straight into the create-wallet flow for that coin. The + // Add pane keys off `pickerTab = "add"` and reads the target + // chain from a scratch field the coin-picker fills. + pickerTab = "add"; + pickerAddChain = chain; + fillPicker(); + })); + const searchEl = d.querySelector("#pickerSearch"); + if (searchEl) { + searchEl.addEventListener("input", () => { + browseQuery = searchEl.value; + // Preserve caret across re-render. + const caret = searchEl.selectionStart; + fillPicker(); + const s2 = d.querySelector("#pickerSearch"); + if (s2) { s2.focus(); try { s2.setSelectionRange(caret, caret); } catch (_e) {} } + }); + // Autofocus on first render, but not on every re-render — the + // re-focus above handles that. Guard with a data flag. + if (!searchEl.dataset.autof) { searchEl.dataset.autof = "1"; searchEl.focus(); } + } const closeBtn = d.querySelector("#pickerClose"); if (closeBtn) closeBtn.addEventListener("click", (e) => { e.stopPropagation(); d.hidden = true; }); return; @@ -734,6 +804,21 @@ function fillPicker() { group.hidden = !group.hidden; r.querySelector(".caret").textContent = group.hidden ? "▸" : "▾"; })); + // 0.8.4: if the browse view routed here with a preselected chain (user + // clicked "+ Add" on an unowned coin), expand that coin's network + // group AND scroll it into view so the user sees which networks + // exist without a second click. + if (pickerTab === "add" && pickerAddChain) { + const target = pickerAddChain; + pickerAddChain = null; + const row = d.querySelector(`.coinrow[data-coin="${target.replace(/["\\]/g, "")}"]`); + const group = d.querySelector(`#netgroup-${target.replace(/["\\]/g, "")}`); + if (row && group) { + group.hidden = false; + const caret = row.querySelector(".caret"); if (caret) caret.textContent = "▾"; + row.scrollIntoView({ block: "nearest" }); + } + } d.querySelectorAll("[data-add]").forEach((r) => r.addEventListener("click", async () => { const [c, n] = r.dataset.add.split(":"); d.hidden = true; @@ -2586,9 +2671,16 @@ function render() { // $("hBadge").innerHTML = s?.meta?.logo ? logoSvg(s.meta.logo, 22) : logoSvg(null, 22); $("hLabel").textContent = s?.label || "Aegis Wallet"; - $("hNet").innerHTML = s?.meta - ? `${esc(s.meta.coinLabel)} · ${esc(s.meta.networkLabel)}${s.meta.testnet ? " " + testnetTag() : ""}` - : ""; + // 0.8.4: hNet is a chip on its own row. Show only the network name + // (coin name is already in hLabel above); hide the row when we don't + // have any wallet-context to describe yet. + if (s?.meta) { + $("hNet").innerHTML = `${esc(s.meta.networkLabel)}${s.meta.testnet ? " " + testnetTag() : ""}`; + $("hNetRow").hidden = false; + } else { + $("hNet").innerHTML = ""; + $("hNetRow").hidden = true; + } if (showLock) { renderLockScreen(phase); }