diff options
| author | Adam Soltys <[email protected]> | 2026-08-29 07:38:47 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-29 07:38:47 -0700 |
| commit | 5f636a75b1230202993d6f794c18bf2017971478 (patch) | |
| tree | 892bd2de7e7d75b3491ebae31b32f5e3d987afe7 /src/features | |
| parent | 351aa2248dc1719da1caf845aa8a552461585b23 (diff) | |
| download | coinosv3-5f636a75b1230202993d6f794c18bf2017971478.tar.gz coinosv3-5f636a75b1230202993d6f794c18bf2017971478.zip | |
The exit-cost line stops arriving late: the last computed answer is remembered per wallet and painted on the very first render, then the live figure replaces it in place — no more layout lurch while ark connects
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019WboeoetMF3MTmgT7Ew8yi
Diffstat (limited to 'src/features')
| -rw-r--r-- | src/features/ark.js | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/src/features/ark.js b/src/features/ark.js index b40fc1f..1e6782b 100644 --- a/src/features/ark.js +++ b/src/features/ark.js @@ -1531,24 +1531,36 @@ export function arkFeature(ctx) { // Most users never need to think about this — the card only appears once // coins run deep enough for the difference to matter. const EXIT_DEPTH_ADVISORY = 4; + const depthNoticeEl = (exitFee) => + h('div', { class: 'small muted', style: 'margin:10px 0 0;text-align:center' }, + t('arkDepthNotice', { fee: fmtAmount(exitFee) }), + ' ', + h('button', { class: 'linklike small', onClick: () => { ui.arkCoinsPage = true; render(); } }, + t('arkDepthBtn'))); function exitDepthNotice() { - if (!arkAvailable() || wallet.watchOnly || !ark || !ark.state) return null; + if (!arkAvailable() || wallet.watchOnly) return null; + // Ark connects lazily after the wallet paints, so the first renders have + // no state to price an exit from — the line popping in seconds later + // shoved the whole layout down. Paint the last computed answer at once; + // the live numbers replace it in place. + const cached = wallet.loadFeatureState('arkDepth', null); + if (!ark || !ark.state) return cached && cached.show ? depthNoticeEl(cached.exitFee) : null; + const remember = (show, exitFee = 0) => { + if (!cached || cached.show !== show || cached.exitFee !== exitFee) + wallet.saveFeatureState('arkDepth', { show, exitFee }); + }; const spend = (ark.state.vtxos || []).filter((v) => v.state === 'spendable'); - if (!spend.length) return null; let depth = 0; for (const v of spend) { try { depth = Math.max(depth, ark._decoded(v).genesis.length); } catch {} } - if (depth < EXIT_DEPTH_ADVISORY) return null; + if (!spend.length || depth < EXIT_DEPTH_ADVISORY) { remember(false); return null; } let exitFee = 0; try { exitFee = estimateExitFeeSat(ark); } catch {} // after a renewal everything is ONE coin, ONE hop: parent + its fee // child + the claim, ~530 vB all in at today's rate const feeRate = Math.max(1, (wallet.feeRates && wallet.feeRates.halfHourFee) || 2); const afterFee = Math.ceil(530 * feeRate); - if (afterFee >= exitFee) return null; // renewing wouldn't help — stay quiet - return h('div', { class: 'small muted', style: 'margin:10px 0 0;text-align:center' }, - t('arkDepthNotice', { fee: fmtAmount(exitFee) }), - ' ', - h('button', { class: 'linklike small', onClick: () => { ui.arkCoinsPage = true; render(); } }, - t('arkDepthBtn'))); + if (afterFee >= exitFee) { remember(false); return null; } // renewing wouldn't help — stay quiet + remember(true, exitFee); + return depthNoticeEl(exitFee); } // The screen behind that notice's Manage link: every spendable coin with |
