From 5a164cea494a7a9e6944f8b2e2e19e13e53ec5bc Mon Sep 17 00:00:00 2001 From: Florent Tapponnier Date: Sun, 26 Jul 2026 15:15:54 +0200 Subject: [PATCH 1/3] fix: hide chain row when venue restricts to single chain (all+1 = redundant) --- src/components/benchmark-body.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/benchmark-body.tsx b/src/components/benchmark-body.tsx index a271a816..56fc1c3e 100644 --- a/src/components/benchmark-body.tsx +++ b/src/components/benchmark-body.tsx @@ -698,7 +698,7 @@ export function BenchmarkBody({ )} /> )} - {filteredChainOptions.length > 0 && ( + {filteredChainOptions.length > 2 && ( Date: Sun, 26 Jul 2026 15:21:20 +0200 Subject: [PATCH 2/3] fix: strip All Chains from chain row when venue is specific --- src/components/benchmark-body.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/benchmark-body.tsx b/src/components/benchmark-body.tsx index 56fc1c3e..9582f55c 100644 --- a/src/components/benchmark-body.tsx +++ b/src/components/benchmark-body.tsx @@ -309,7 +309,9 @@ export function BenchmarkBody({ const valid = chainsForVenue[effectiveVenue]; if (!valid || valid.length === 0) return chainOptions; const validSet = new Set(valid); - return chainOptions.filter((c) => c.value === "all" || validSet.has(c.value)); + // Strip the "all" aggregate option when a specific venue is selected: mixing + // chains is unfair (a Solana-only provider scores 0% on Base tokens). + return chainOptions.filter((c) => c.value !== "all" && validSet.has(c.value)); }, [chainOptions, chainsForVenue, effectiveVenue]); // The page ships ONLY the aggregate view (embedding every variant made @@ -698,7 +700,7 @@ export function BenchmarkBody({ )} /> )} - {filteredChainOptions.length > 2 && ( + {filteredChainOptions.length > 1 && ( Date: Sun, 26 Jul 2026 15:28:27 +0200 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20venue=20tabs=20never=20filtered=20by?= =?UTF-8?q?=20chain=20=E2=80=94=20asymmetric=20filtering=20only?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/benchmark-body.tsx | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/components/benchmark-body.tsx b/src/components/benchmark-body.tsx index 9582f55c..c82505f6 100644 --- a/src/components/benchmark-body.tsx +++ b/src/components/benchmark-body.tsx @@ -287,13 +287,10 @@ export function BenchmarkBody({ // Cross-dimension filtering: hide venue tabs with no data for the active // chain, and hide chain tabs with no data for the active venue. - const filteredVenueOptions = useMemo(() => { - if (!venuesForChain || !effectiveChain || effectiveChain === "all") return venueOptions; - const valid = venuesForChain[effectiveChain]; - if (!valid || valid.length === 0) return venueOptions; - const validSet = new Set(valid); - return venueOptions.filter((v) => v.value === "all" || validSet.has(v.value)); - }, [venueOptions, venuesForChain, effectiveChain]); + // Venue tabs are never filtered by chain: the user picks a launchpad first, + // then drills into a chain. The reverse (chain → hides venues) is confusing + // because launchpad tabs disappear unexpectedly. + const filteredVenueOptions = venueOptions; const chainsForVenue = useMemo(() => { if (!venuesForChain) return undefined; @@ -705,13 +702,7 @@ export function BenchmarkBody({ label="Chain" options={filteredChainOptions} selected={chain ?? fallbackChain} - onSelect={(v) => { - setChain(v); - if (v !== "all" && effectiveVenue && effectiveVenue !== "all" && venuesForChain) { - const validVenues = venuesForChain[v]; - if (validVenues && !validVenues.includes(effectiveVenue)) setVenue(null); - } - }} + onSelect={setChain} metaByValue={Object.fromEntries( filteredChainOptions .map((o) => [