fix: the address screen shows a token just added at its fetched balance, not 0.0000 (closes #516)
A balance refresh that returns now draws the balances on AddressDetail or AddressToken again when that screen is up, not only the wallet list; their transaction lists are left alone. Every add path on AddToken and SettingsAddToken tracks a token through one step, trackToken(), which also lists it in the new stored field tokensNotFetched: its line reads `quantity unknown` instead of 0.0000 until a refresh that started with it tracked has fetched every address's token balances, even if the popup closes first. To tell an address whose token balances the explorer did not return, the refresh takes them off its copy of the wallets before fetching. Model: opus-5-5
This commit is contained in:
@@ -82,12 +82,26 @@ let refreshTimer = null;
|
||||
// (https://git.eeqj.de/sneak/AutistMask/issues/577). A dropped refresh is not
|
||||
// recorded as done. Results are copied by address, so an address added or
|
||||
// removed meanwhile is left as it is.
|
||||
//
|
||||
// Once the save is done, the wallet list is drawn again, and so are the
|
||||
// balances on AddressDetail or AddressToken when that is the screen up. No
|
||||
// other screen is drawn again, DeleteAddress and its balance lines included.
|
||||
async function doRefreshAndRender() {
|
||||
if (refreshInFlight) return;
|
||||
refreshInFlight = true;
|
||||
try {
|
||||
const networkId = state.networkId;
|
||||
// The tracked tokens this refresh asks the explorer about. A token
|
||||
// added on AddToken after this point is not among them, so this
|
||||
// refresh does not count as having fetched it.
|
||||
const tokens = state.trackedTokens.map((t) => t.address.toLowerCase());
|
||||
const wallets = structuredClone(state.wallets);
|
||||
// Taken off the copy, so that an address whose token balances the
|
||||
// explorer did not return comes back without any and keeps its
|
||||
// stored ones.
|
||||
for (const wallet of wallets) {
|
||||
for (const addr of wallet.addresses) delete addr.tokenBalances;
|
||||
}
|
||||
await Promise.all([
|
||||
refreshPrices(),
|
||||
refreshBalances(
|
||||
@@ -100,9 +114,13 @@ async function doRefreshAndRender() {
|
||||
),
|
||||
]);
|
||||
const refreshed = new Map();
|
||||
let allTokenBalancesFetched = true;
|
||||
for (const wallet of wallets) {
|
||||
for (const addr of wallet.addresses) {
|
||||
refreshed.set(addr.address, addr);
|
||||
if (addr.tokenBalances === undefined) {
|
||||
allTokenBalancesFetched = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
await saveState((stored) => {
|
||||
@@ -117,10 +135,19 @@ async function doRefreshAndRender() {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Each token this refresh asked about is now fetched for every
|
||||
// address.
|
||||
if (allTokenBalancesFetched) {
|
||||
state.tokensNotFetched = state.tokensNotFetched.filter(
|
||||
(token) => !tokens.includes(token),
|
||||
);
|
||||
}
|
||||
state.lastBalanceRefresh = Date.now();
|
||||
return true;
|
||||
});
|
||||
renderWalletList();
|
||||
if (state.currentView === "address") addressDetail.renderBalances();
|
||||
if (state.currentView === "address-token") addressToken.renderBalance();
|
||||
} catch (e) {
|
||||
// Every call site fires this and walks away — the boot below, the ten
|
||||
// second interval, and eight views through ctx — so it must never
|
||||
|
||||
Reference in New Issue
Block a user