From f3094f5f886e0164e0bd450405abf2a855432d15 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Wed, 25 Mar 2026 17:32:02 -0700 Subject: [PATCH] fix(rwallet): chain filter now updates all displayed data + chain proportion bar - Stats, balance table, and DeFi positions all filter by selected chain - Added proportional color bar showing each chain's share of total value - Chain buttons show USD value + percentage on hover - Bumped JS cache version to v=21 Co-Authored-By: Claude Opus 4.6 --- .../rwallet/components/folk-wallet-viewer.ts | 36 ++++++++++++++++--- modules/rwallet/mod.ts | 2 +- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/modules/rwallet/components/folk-wallet-viewer.ts b/modules/rwallet/components/folk-wallet-viewer.ts index 5b2ef34..db70e51 100644 --- a/modules/rwallet/components/folk-wallet-viewer.ts +++ b/modules/rwallet/components/folk-wallet-viewer.ts @@ -1650,7 +1650,9 @@ class FolkWalletViewer extends HTMLElement { .example-type.eoa { background: rgba(20,184,166,0.1); color: var(--rs-accent); } /* ── Dashboard: chains ── */ - .chains { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; } + .chains { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; } + .chain-bar { display: flex; height: 6px; border-radius: 3px; overflow: hidden; margin-bottom: 16px; } + .chain-bar-seg { transition: width 0.3s ease; min-width: 3px; } .chain-btn { padding: 6px 14px; border-radius: 8px; border: 2px solid var(--rs-border); background: var(--rs-bg-surface); color: var(--rs-text-secondary); cursor: pointer; font-size: 13px; @@ -3120,9 +3122,15 @@ class FolkWalletViewer extends HTMLElement { } if (this.defiPositions.length === 0) return ""; + // Filter by selected chain + const filtered = this.chainFilter + ? this.defiPositions.filter(p => p.chainId === this.chainFilter) + : this.defiPositions; + if (filtered.length === 0) return ""; + // Group by protocol const byProtocol = new Map>(); - for (const p of this.defiPositions) { + for (const p of filtered) { const existing = byProtocol.get(p.protocol) || []; existing.push(p); byProtocol.set(p.protocol, existing); @@ -3166,7 +3174,7 @@ class FolkWalletViewer extends HTMLElement {

DeFi Positions

- ${this.formatUSD(String(this.defiTotalUSD))} + ${this.formatUSD(String(filtered.reduce((s, p) => s + p.totalValueUSD, 0)))}
${cards}
`; @@ -3296,12 +3304,24 @@ class FolkWalletViewer extends HTMLElement { return false; }).length; + // Compute per-chain USD totals for proportional bar + const allBalancesForBar = this.getUnifiedBalances(true); + const chainTotals = new Map(); + for (const b of allBalancesForBar) { + const cid = b.chainId; + chainTotals.set(cid, (chainTotals.get(cid) || 0) + parseFloat(b.fiatBalance || "0")); + } + const grandTotal = Array.from(chainTotals.values()).reduce((s, v) => s + v, 0) || 1; + // Build chain buttons with "All" filter const chainButtons = this.detectedChains.map((ch) => { const isActive = this.chainFilter === ch.chainId; + const chainUSD = chainTotals.get(ch.chainId) || 0; + const pct = grandTotal > 0 ? ((chainUSD / grandTotal) * 100).toFixed(1) : "0"; return `
+ data-chain="${ch.chainId}" style="--chain-color: ${ch.color}" + title="${ch.name}: ${this.formatUSD(String(chainUSD))} (${pct}%)">
${ch.name}
`; @@ -3315,6 +3335,13 @@ class FolkWalletViewer extends HTMLElement { Local ` : ""; + // Proportional chain bar + const barSegments = this.detectedChains.map((ch) => { + const pct = ((chainTotals.get(ch.chainId) || 0) / grandTotal) * 100; + if (pct < 0.5) return ""; + return `
`; + }).join(""); + const isVizView = this.activeView !== "balances"; return ` @@ -3326,6 +3353,7 @@ class FolkWalletViewer extends HTMLElement { ${chainButtons} ${localBtn} + ${barSegments ? `
${barSegments}
` : ""} ${!isVizView ? `
diff --git a/modules/rwallet/mod.ts b/modules/rwallet/mod.ts index d73e651..e1a3c18 100644 --- a/modules/rwallet/mod.ts +++ b/modules/rwallet/mod.ts @@ -1274,7 +1274,7 @@ function renderWallet(spaceSlug: string, initialView?: string) { modules: getModuleInfoList(), theme: "dark", body: ``, - scripts: ``, + scripts: ``, styles: ``, }); }