Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f800202356 |
@@ -1573,8 +1573,8 @@ The popup refreshes balances every ten seconds while it is open
|
||||
(`doRefreshAndRender()` in `src/popup/index.js`). Each refresh that returns
|
||||
draws the wallet list again and, when AddressDetail or AddressToken is up, that
|
||||
screen's USD total and balance lines; its transaction list is left alone. No
|
||||
other screen is drawn again by a refresh, since the rest show no balances or
|
||||
hold what the user typed.
|
||||
other screen is drawn again by a refresh, DeleteAddress and its balance lines
|
||||
included.
|
||||
|
||||
A network switch leaves every screen on the page showing the previous network.
|
||||
The user makes it in Settings, or approves a site's request and the background
|
||||
@@ -2090,10 +2090,11 @@ view would leave a wallet one click from deletion.
|
||||
**AddressDetail**. The token's balance is not known until a balance
|
||||
refresh that started with it tracked has fetched every address's token
|
||||
balances; until then its balance line reads `quantity unknown`, never
|
||||
`0.0000`, unless the explorer had already listed a holding of it. A
|
||||
refresh that returns draws AddressDetail's balances again (see
|
||||
Navigation), so the fetched balance shows without the screen being
|
||||
reopened
|
||||
`0.0000`, unless the explorer had already listed a holding of it. That
|
||||
holds after the popup is closed and opened again, as the tokens still
|
||||
waiting for a fetch are stored with the profile. A refresh that returns
|
||||
draws AddressDetail's balances again (see Navigation), so the fetched
|
||||
balance shows without the screen being reopened
|
||||
- "Add" with a token already tracked, a scam-listed address, or a failed
|
||||
contract lookup → flash message, no screen change
|
||||
- "Add", then a network switch in Settings before the contract lookup
|
||||
|
||||
+4
-4
@@ -21,7 +21,6 @@ const {
|
||||
showSaveFailureBanner,
|
||||
pushCurrentView,
|
||||
goBack,
|
||||
tokensNotFetched,
|
||||
} = require("./views/helpers");
|
||||
const { applyTheme } = require("./theme");
|
||||
const {
|
||||
@@ -86,8 +85,7 @@ let refreshTimer = null;
|
||||
//
|
||||
// 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, since the rest show no balances or hold what the
|
||||
// user typed.
|
||||
// other screen is drawn again, DeleteAddress and its balance lines included.
|
||||
async function doRefreshAndRender() {
|
||||
if (refreshInFlight) return;
|
||||
refreshInFlight = true;
|
||||
@@ -140,7 +138,9 @@ async function doRefreshAndRender() {
|
||||
// Each token this refresh asked about is now fetched for every
|
||||
// address.
|
||||
if (allTokenBalancesFetched) {
|
||||
for (const token of tokens) tokensNotFetched.delete(token);
|
||||
state.tokensNotFetched = state.tokensNotFetched.filter(
|
||||
(token) => !tokens.includes(token),
|
||||
);
|
||||
}
|
||||
state.lastBalanceRefresh = Date.now();
|
||||
return true;
|
||||
|
||||
@@ -13,7 +13,6 @@ const {
|
||||
nativeCurrency,
|
||||
balanceLine,
|
||||
unknownableAmount,
|
||||
tokensNotFetched,
|
||||
renderAddressHtml,
|
||||
attachCopyHandlers,
|
||||
goBack,
|
||||
@@ -165,7 +164,7 @@ function renderBalance() {
|
||||
// token just added: no quantity to show, and none to price.
|
||||
// balanceLine() states that rather than printing 0.0000.
|
||||
if (tb) amount = unknownableAmount(tb.balance);
|
||||
else amount = tokensNotFetched.has(id) ? null : 0;
|
||||
else amount = state.tokensNotFetched.includes(id) ? null : 0;
|
||||
price = getPrice(currentSymbol);
|
||||
}
|
||||
|
||||
|
||||
@@ -380,20 +380,16 @@ function balanceLine(symbol, amount, price, tokenId) {
|
||||
);
|
||||
}
|
||||
|
||||
// Contract addresses, lowercased, of the tokens the user added that no balance
|
||||
// refresh has fetched yet. An address with no balance row for one of them has
|
||||
// no known balance of it, so its line says the quantity is unknown rather than
|
||||
// 0.0000. trackToken() adds a token here, and doRefreshAndRender() in
|
||||
// src/popup/index.js takes it off once a refresh that started with it tracked
|
||||
// has fetched every address's token balances
|
||||
// (https://git.eeqj.de/sneak/AutistMask/issues/516).
|
||||
const tokensNotFetched = new Set();
|
||||
|
||||
// Tracks `token` on the active network, as every add path on AddToken and
|
||||
// SettingsAddToken does. No refresh has fetched its balance yet.
|
||||
// SettingsAddToken does, and lists it in `state.tokensNotFetched`: no refresh
|
||||
// has fetched its balance yet. An address with no balance row for it has no
|
||||
// known balance of it, so its line says the quantity is unknown rather than
|
||||
// 0.0000. doRefreshAndRender() in src/popup/index.js takes it off once a
|
||||
// refresh that started with it tracked has fetched every address's token
|
||||
// balances (https://git.eeqj.de/sneak/AutistMask/issues/516).
|
||||
function trackToken(token) {
|
||||
state.trackedTokens.push(token);
|
||||
tokensNotFetched.add(token.address.toLowerCase());
|
||||
state.tokensNotFetched.push(token.address.toLowerCase());
|
||||
}
|
||||
|
||||
function balanceLinesForAddress(addr, trackedTokens, showZero) {
|
||||
@@ -429,7 +425,7 @@ function balanceLinesForAddress(addr, trackedTokens, showZero) {
|
||||
if (seen.has(id)) continue;
|
||||
html += balanceLine(
|
||||
t.symbol,
|
||||
tokensNotFetched.has(id) ? null : 0,
|
||||
state.tokensNotFetched.includes(id) ? null : 0,
|
||||
getPrice(t.symbol),
|
||||
id,
|
||||
);
|
||||
@@ -803,7 +799,6 @@ module.exports = {
|
||||
flashCopyFeedback,
|
||||
balanceLine,
|
||||
balanceLinesForAddress,
|
||||
tokensNotFetched,
|
||||
trackToken,
|
||||
addressHoldsFunds,
|
||||
keyMaterialName,
|
||||
|
||||
@@ -28,6 +28,13 @@ const DEFAULT_STATE = {
|
||||
// others are restored from when the active network changes. See
|
||||
// applyChainSwitchFields().
|
||||
networkTrackedTokens: {},
|
||||
// Contract addresses, lowercased, of the tokens the user added that no
|
||||
// balance refresh has fetched yet. trackToken() in
|
||||
// src/popup/views/helpers.js adds one, and doRefreshAndRender() in
|
||||
// src/popup/index.js takes it off. Stored, so a token added just before
|
||||
// the popup closed still reads `quantity unknown` when it opens again
|
||||
// (https://git.eeqj.de/sneak/AutistMask/issues/516).
|
||||
tokensNotFetched: [],
|
||||
networkId: "mainnet",
|
||||
rpcUrl: DEFAULT_RPC_URL,
|
||||
blockscoutUrl: DEFAULT_BLOCKSCOUT_URL,
|
||||
@@ -412,6 +419,8 @@ function normalizePersisted(saved) {
|
||||
// so a stored string walks through the `|| []` and a stored number walks
|
||||
// through an Array.isArray().
|
||||
out.fraudContracts = textList(saved.fraudContracts);
|
||||
// Contract addresses too, read with `includes()` and `filter()`.
|
||||
out.tokensNotFetched = textList(saved.tokensNotFetched);
|
||||
out.tokenHolderCache = structuredClone(saved.tokenHolderCache || {});
|
||||
out.theme = saved.theme || "system";
|
||||
out.debugMode = saved.debugMode !== undefined ? saved.debugMode : false;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// After "Add" on AddToken, AddressDetail lists the new token, and its line reads
|
||||
// `quantity unknown`, not 0.0000, until a balance refresh that asked the
|
||||
// explorer about the token has returned for every address; so does a token
|
||||
// added on SettingsAddToken, wherever it is listed. A refresh that
|
||||
// returns draws the balances on AddressDetail or AddressToken again, so the
|
||||
// fetched balance shows without the screen being reopened
|
||||
// explorer about the token has returned for every address, the popup closing
|
||||
// and opening again meanwhile included; so does a token added on
|
||||
// SettingsAddToken, wherever it is listed. A refresh that returns draws the
|
||||
// balances on AddressDetail or AddressToken again, so the fetched balance shows
|
||||
// without the screen being reopened
|
||||
// (https://git.eeqj.de/sneak/AutistMask/issues/516). Driven through the real
|
||||
// popup over a stored profile on Ethereum Mainnet, with "Show tracked tokens
|
||||
// with zero balance" on, as it is by default.
|
||||
@@ -163,6 +164,29 @@ test("a refresh already running when the token is added does not count as fetchi
|
||||
expect(newTokenRow(page)).toContain("0.0000");
|
||||
});
|
||||
|
||||
test("closed and opened again before any refresh has fetched it, the new token's line still reads quantity unknown", async () => {
|
||||
const closed = await bootOnAddress();
|
||||
holdNextRefresh(closed);
|
||||
await addNewToken(closed);
|
||||
cleanupPopup();
|
||||
|
||||
// The refresh this boot starts gets no token balances back: the boot's
|
||||
// stub of refreshBalances() writes none.
|
||||
const page = await bootPopup(undefined, { storage: closed.storage });
|
||||
expect(page.visibleViews()).toEqual(["address"]);
|
||||
const row = newTokenRow(page);
|
||||
expect(row).toContain("quantity unknown");
|
||||
expect(row).not.toContain("0.0000");
|
||||
|
||||
const finish = holdNextRefresh(page);
|
||||
const ticking = page.tick();
|
||||
await page.settle();
|
||||
await finish([MILLION]);
|
||||
await ticking;
|
||||
|
||||
expect(newTokenRow(page)).toContain("1000000.0000");
|
||||
});
|
||||
|
||||
test("a refresh in which the explorer did not answer leaves the new token's line quantity unknown", async () => {
|
||||
const page = await bootOnAddress();
|
||||
const finish = holdNextRefresh(page);
|
||||
|
||||
@@ -248,6 +248,13 @@ const CONTRACT = [
|
||||
floorOnly: [[42], [null], [{}], [[TOKEN_ADDRESS]]],
|
||||
holds: (v) => everyEntry(v, isText),
|
||||
},
|
||||
{
|
||||
field: "tokensNotFetched",
|
||||
kind: KIND.ENTRIES,
|
||||
hostile: [42, "notalist", { a: 1 }],
|
||||
floorOnly: [[42], [null], [{}], [[TOKEN_ADDRESS]]],
|
||||
holds: (v) => everyEntry(v, isText),
|
||||
},
|
||||
{
|
||||
field: "viewStack",
|
||||
kind: KIND.ENTRIES,
|
||||
|
||||
Reference in New Issue
Block a user