feat(faucet): add an Order toggle (Default / A→Z / Market cap)
New "Order" control in the header reorders both the chain cards/tabs and the EVM network dropdown: - Default — the curated order (embeddable-first). - A→Z — alphabetical by chain name. - Market cap — approximate native-coin rank (BTC > ETH > BNB > SOL > TRX > AVAX > POL > ARB > BASE > OP > BCH); the EVM group sorts by its top member (ETH). Choice persists (faucet.order); applied on load. Ordering re-renders cards/tabs and re-applies collapse / active-tab / auto-refresh state. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
a9b11e81cb
commit
a5183cf1a1
1 changed files with 48 additions and 3 deletions
|
|
@ -208,6 +208,13 @@
|
|||
<button data-mode="multi" class="active">▤ Multiple open</button>
|
||||
<button data-mode="accordion">▬ One open</button>
|
||||
</div>
|
||||
<label class="auto" id="order-wrap">Order
|
||||
<select id="order-sel">
|
||||
<option value="default">Default</option>
|
||||
<option value="alpha">A → Z</option>
|
||||
<option value="mcap">Market cap</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
|
@ -421,6 +428,12 @@ window.startFaucetApp = (function(){
|
|||
let evmActive = ls.get(EVMKEY);
|
||||
if(!EVM_CHAINS.includes(evmActive)) evmActive = EVM_CHAINS[0];
|
||||
|
||||
// chain ordering: default (curated) · alpha · market cap (approx native-coin rank)
|
||||
const ORDERKEY = 'faucet.order';
|
||||
let orderMode = ls.get(ORDERKEY) || 'default';
|
||||
const MCAP_RANK = { btc:1, eth:2, bsc:3, sol:4, tron:5, avax:6, polygon:7, arbitrum:8, base:9, optimism:10, bch:11 };
|
||||
const rankOf = id => MCAP_RANK[id] ?? 99;
|
||||
|
||||
// discovered tokens persist globally (contract defs are chain-wide, not per-profile)
|
||||
const TOKENS_KEY = 'faucet.tokens.v1';
|
||||
const discoveredTokens = parseObj(TOKENS_KEY);
|
||||
|
|
@ -761,6 +774,21 @@ window.startFaucetApp = (function(){
|
|||
|
||||
// the chain a render unit currently shows (group → the active EVM network)
|
||||
const unitChain = u => u.group ? CHAIN_BY_ID[evmActive] : u.chain;
|
||||
// ordering (default / alpha / market cap) applied to both cards and the EVM dropdown
|
||||
const unitName = u => u.group ? 'EVM Networks' : u.chain.name;
|
||||
const unitRank = u => u.group ? Math.min(...u.chains.map(c => rankOf(c.id))) : rankOf(u.chain.id);
|
||||
function orderedUnits(){
|
||||
const arr = RENDER_UNITS.slice();
|
||||
if(orderMode === 'alpha') arr.sort((a,b) => unitName(a).localeCompare(unitName(b)));
|
||||
else if(orderMode === 'mcap') arr.sort((a,b) => unitRank(a) - unitRank(b));
|
||||
return arr;
|
||||
}
|
||||
function sortedChains(chains){
|
||||
const arr = chains.slice();
|
||||
if(orderMode === 'alpha') arr.sort((a,b) => a.name.localeCompare(b.name));
|
||||
else if(orderMode === 'mcap') arr.sort((a,b) => rankOf(a.id) - rankOf(b.id));
|
||||
return arr;
|
||||
}
|
||||
const autoCtlHTML = unit => `<div class="head-ctls">
|
||||
<label class="auto-lbl">Auto-refresh
|
||||
<select class="chain-auto" data-unit="${unit}" title="Auto-refresh this card's balances">
|
||||
|
|
@ -770,7 +798,7 @@ window.startFaucetApp = (function(){
|
|||
function cardHTML(u){
|
||||
const c = unitChain(u);
|
||||
const titleEl = u.group
|
||||
? `<select class="evm-net" title="Choose EVM network">${u.chains.map(x => `<option value="${x.id}"${x.id===evmActive?' selected':''}>${esc(x.name)}</option>`).join('')}</select>`
|
||||
? `<select class="evm-net" title="Choose EVM network">${sortedChains(u.chains).map(x => `<option value="${x.id}"${x.id===evmActive?' selected':''}>${esc(x.name)}</option>`).join('')}</select>`
|
||||
: `<h2>${esc(c.name)}</h2>`;
|
||||
return `<div class="card" data-chain="${c.id}" data-unit="${u.unit}">
|
||||
<div class="card-head">
|
||||
|
|
@ -794,8 +822,9 @@ window.startFaucetApp = (function(){
|
|||
return `<div class="tab${active?' active':''}" data-unit="${u.unit}" data-chain="${c.id}"><span class="cicon sm" style="color:${c.color}">${ICONS[c.id]||''}</span>${esc(short)}</div>`;
|
||||
}
|
||||
function buildPanels(){
|
||||
panels.innerHTML = RENDER_UNITS.map(cardHTML).join('');
|
||||
tabbar.innerHTML = RENDER_UNITS.map((u,i) => tabHTML(u, i===0)).join('');
|
||||
const units = orderedUnits();
|
||||
panels.innerHTML = units.map(cardHTML).join('');
|
||||
tabbar.innerHTML = units.map((u,i) => tabHTML(u, i===0)).join('');
|
||||
wireEmbeds();
|
||||
}
|
||||
// rebuild a single unit's card + tab (used when the EVM network dropdown changes)
|
||||
|
|
@ -1033,6 +1062,21 @@ window.startFaucetApp = (function(){
|
|||
}
|
||||
viewSeg.addEventListener('click', e => { const b = e.target.closest('button'); if(b) setView(b.dataset.view); });
|
||||
|
||||
/* ---- chain order (default / alpha / market cap) ---- */
|
||||
const orderSel = document.getElementById('order-sel');
|
||||
function applyOrder(mode){
|
||||
orderMode = mode; ls.set(ORDERKEY, mode); orderSel.value = mode;
|
||||
buildPanels(); // re-render cards + tabs in new order
|
||||
applyCollapsed();
|
||||
setActiveTab(ls.get(TKEY) || RENDER_UNITS[0].unit);
|
||||
RENDER_UNITS.forEach(u => { // restore auto-refresh select display
|
||||
const s = panels.querySelector(`.card[data-unit="${u.unit}"] .chain-auto`);
|
||||
if(s){ const v = autoByChain[u.unit] || 0; s.value = String(v); s.classList.toggle('live', v > 0); }
|
||||
});
|
||||
reloadSet(document.querySelectorAll('.bal[data-addr]'));
|
||||
}
|
||||
orderSel.addEventListener('change', () => applyOrder(orderSel.value));
|
||||
|
||||
const UNIT_IDS = new Set(RENDER_UNITS.map(u => u.unit));
|
||||
function setActiveTab(unit){
|
||||
if(!UNIT_IDS.has(unit)) unit = RENDER_UNITS[0].unit;
|
||||
|
|
@ -1128,6 +1172,7 @@ window.startFaucetApp = (function(){
|
|||
document.getElementById('profile-del').addEventListener('click', deleteProfile);
|
||||
|
||||
/* ===================== init ===================== */
|
||||
orderSel.value = orderMode;
|
||||
buildPanels();
|
||||
updateProfileUI();
|
||||
setPanelMode(panelMode);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue