Skip to content

fix(home): make hide balance work, and add an eye to peek - #203

Merged
theanmolsharma merged 8 commits into
masterfrom
theanmolsharma/hide-balance-feature-fix
Oct 14, 2026
Merged

theanmolsharma merged 8 commits into
masterfrom
theanmolsharma/hide-balance-feature-fix

Conversation

@theanmolsharma

@theanmolsharma theanmolsharma commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Hide balance on home now hides amounts, and an eye on home overrides it until the app goes to the background, without turning the setting off.

The bug

The Security toggle wrote hideBalance onto the wallet, but the home screen never read it. Its reader in the wallet header went with the WalletTransactions screen (fc3049f), and only the drawer card shown on large screens still checked it, so on a phone the switch did nothing.

Hide balance on home

  • The setting is now an app-wide preference in SettingsProvider (HideBalance, next to PinLayoutScrambled) instead of a field on the wallet. It holds on every network and can be changed without a wallet.
    • hideBalance is dropped from AbstractWallet. Values saved by the old toggle aren't carried over, since they never had an effect on a phone: if you'd turned it on, turn it on again.
  • While it's on, home shows •••• for the balance, the fiat line and each transaction amount. The large-screen drawer card hides its balance too.
  • The two dot groups share a centre line. A clear copy of the unit sits left of the dots to balance the visible one, and the fiat line drops its ≈ while hidden. The unit stays so tapping it still visibly switches BTC/sats.
  • A transaction row's long-press menu stops offering Copy Amount.
  • Screen readers hear "Balance hidden" and "Amount hidden" instead of a run of bullets.
  • Still shown: Transaction Details (opened on purpose) and the send flow.

The eye

  • An eye sits in the home header next to ⋮. On iOS 26 both share one glass capsule; elsewhere each gets a circle, which HeaderBarButton now draws by default (Contacts' "+" keeps its own square).
  • It sets a single override; isBalanceHidden is derived from that override and the setting, and the context exposes toggleBalanceHidden(). The eye never changes the setting, and changing the setting clears the override.
  • Going to the background clears the override, with the setting on or off, so every visit starts from the setting.
    • iOS inactive doesn't clear it. Control Center, Face ID and permission prompts would otherwise undo the eye mid-use.
    • The trade-off: the app switcher's snapshot can show amounts the eye revealed, since home has no capture protection.
  • Why the header rather than beside the balance:
    • the eye also covers the transaction amounts;
    • the header stays on screen while the list scrolls;
    • on large screens the balance lives in the drawer;
    • tapping the balance already switches between BTC and sats.
  • The glyph shows the current state: EyeIcon gains a slashed prop, with the gap around the slash worked out from the stroke width.
  • The Security row gains a subtitle that points to the eye.
  • New strings: settings.security_hide_balance_subtitle, wallets.show_balance, wallets.hide_balance, wallets.balance_hidden, transactions.amount_hidden.

Testing

  • Static checks: tsc is clean on each commit. Lint has no errors and adds no warnings.
  • Unit tests: 51 suites, 495 tests pass. New tests cover:
    • the setting persisting, and the eye leaving it on so the next launch starts hidden;
    • a change to the setting taking over from the eye;
    • going to the background clearing the eye's choice with the setting on and off, while inactive doesn't. Each test captures its own AppState listeners;
    • a transaction row masking its amount and dropping Copy Amount.
  • Detox on an Android release build (Pixel 10 Pro emulator at CI's 320×640dp):
    • 06-settings 3/3, including the new hide-balance test, which now turns the setting back off at the end.
    • CI's first run on this PR passed every spec on the first attempt.
    • Locally the two existing tests in the spec often failed at a tap straight after a scroll (About, Theme). That's the Android overscroll flake from 07-contacts, and the steps are untouched here. With a one-second settle added locally (not committed) all 3 passed.
  • iOS 26.5 simulator (iPhone 17 Pro), with real taps:
    • turning the setting on hides everything, the eye shows amounts again, and the Security toggle is still on afterwards;
    • a peek survives moving between screens;
    • backgrounding clears the eye's choice in both directions, and a cold relaunch starts from the setting;
    • the long-press menu has no Copy Amount while hidden;
    • dark and light mode;
    • the dot groups are centred within 1pt of each other, in BTC and in sats;
    • the unslashed eye on Receive's address card is unchanged.
  • Android emulator, by hand: the eye toggles, the header circles match the previous look, and the dot groups are centred.

Not verified

  • VoiceOver and TalkBack reading the new labels.
  • The large-screen drawer card (iPad, iPhone landscape). Only its source of the hidden state changed.
  • The rest of the e2e suite locally (CI runs it).

🤖 Generated with Claude Code

theanmolsharma and others added 8 commits October 14, 2026 14:18
… is on

The Security toggle wrote hideBalance onto the wallet, but the home
screen never read it. Its reader in the wallet header went with the
WalletTransactions screen, and only the drawer card shown on large
screens still checked it, so on a phone the switch did nothing.

The setting is now an app-wide preference kept with the other settings
instead of on the wallet, so it holds on every network and can be
changed without a wallet. Values saved by the old toggle aren't carried
over, since they never had an effect on a phone.

While it's on, home shows dots for the balance, the fiat line and each
transaction amount, as does the large-screen drawer card. The dots on
the two balance lines share a centre line: a clear copy of the unit
balances the visible one, and the fiat line drops its ≈. A row's
long-press menu stops offering Copy Amount, and screen readers hear
"Balance hidden" and "Amount hidden" instead of a run of bullets.
Transaction details still show the amount, since that screen is opened
on purpose.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The home header gets an eye next to the settings button. It hides or
shows the balance and transaction amounts for the current session
without touching the Hide balance on home setting, so a quick look
doesn't turn the setting off. Every launch starts from the setting, and
while the setting is on, leaving the app hides the amounts again, for
whoever opens it next and in the app switcher's snapshot.

The eye sits in the header rather than beside the balance: it also
covers the transaction amounts, the header stays on screen while the
list scrolls, and on large screens the balance is in the drawer. Tapping
the balance already switches between BTC and sats. The glyph shows the
current state, struck through while amounts are hidden. On iOS 26 it
shares the settings button's glass capsule; elsewhere it gets a circle
of its own.

The setting's row gains a subtitle that points to the eye.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Turns the setting on in Security and checks that home shows the balance
as dots, that the eye shows it, and that after a relaunch it starts
hidden again, so the peek left the setting on.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e background

isBalanceHidden was a second piece of state, mirrored from the setting by
hand on load, on change and on leaving the app. It also behaved
differently depending on the setting: with it on, leaving the app hid a
peek again, but with it off, a hide from the eye outlived leaving.

Now the eye sets a single override and isBalanceHidden is derived from
it and the setting. The override clears when the setting changes and
when the app goes to the background, so the eye works the same either
way and every visit starts from the setting. The context exposes
toggleBalanceHidden rather than a raw setter.

Only 'background' clears it. iOS also goes 'inactive' for Control
Center, Face ID and permission prompts, which would undo the eye
mid-use. The cost is that the app switcher's snapshot can show amounts
the eye revealed, since home has no capture protection.

The tests now capture each test's own AppState listeners instead of
picking the last one from a mock shared across tests, and cover both
directions of the override.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The settings button and the eye each drew the same 52pt circle where
there's no glass behind them. HeaderBarButton already decides between
glass and its own background, so the circle is now its default and both
callers drop their copy. Contacts' "+" still passes its own square.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
EyeOffIcon repeated EyeIcon's path and circle, and its clip polygons
hardcoded numbers that only held for one stroke width. EyeIcon takes a
`slashed` prop instead, and the gap cut around the slash is worked out
from the stroke width and the view box.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The fiat line drops its ≈ while hidden, but the balance keeps its unit,
balanced by a clear copy, so tapping it still visibly switches BTC/sats.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The test left the setting on, so a test added after it in the spec would
have started with the amounts hidden. Getting to the switch and back
moves into a helper that both steps use.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@theanmolsharma
theanmolsharma merged commit c44b16a into master Oct 14, 2026
4 of 5 checks passed
@theanmolsharma
theanmolsharma deleted the theanmolsharma/hide-balance-feature-fix branch October 14, 2026 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant