Skip to content

[Home refresh] Relocate Tokens/Collectibles settings actions#948

Open
CassioMG wants to merge 23 commits into
mainfrom
worktree-tokens-collectibles-actions
Open

[Home refresh] Relocate Tokens/Collectibles settings actions#948
CassioMG wants to merge 23 commits into
mainfrom
worktree-tokens-collectibles-actions

Conversation

@CassioMG

@CassioMG CassioMG commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Part of the Home refresh design work.

What this does

Removes the Sliders01 settings button from the Home Tokens/Collectibles tabs and relocates its four actions to more discoverable places, so managing tokens and collectibles no longer hides behind a single overflow menu.

Home → Tokens tab

  • A floating "+ Add token" pill pinned near the bottom of the list opens the Add Token flow.

Home → Collectibles tab

  • A floating "+ Add collectible" pill (same style) opens the Add Collectible screen — replacing the old "Add manually" menu item.

Token Details

  • Adds a "⋯" header menu with Copy address and Remove. Removing a token is now done from the token's own screen instead of a separate list. The Remove flow reuses the existing confirmation / "can't remove" bottom sheets (native XLM and tokens with a balance can't be removed), and returns to Home on success.
  • This replaces the old Manage tokens screen, which is removed.

Add Collectible

  • Adds a left-aligned purple "Show hidden" link that opens the Hidden Collectibles screen — replacing the old "Hidden collectibles" menu item.

🎨 Figma: + Add token · + Add collectible · Token Details ⋯ menu

📹 Demo videos

iOS

tokens-collectibles-actions-ios.mov

Android

tokens-collectibles-actions-android.mov
🔧 Technical details (for reviewers / agents)

New components / assets

  • src/components/FloatingTabActionButton.tsx — presentational dark, rounded-full pill (leading plus icon + label). Grey foreground.primary icon, text.primary semibold label, 4px icon↔label gap, background-tertiary fill + border-primary. An optional disabled prop dims the pill (opacity-50) and blocks presses. Uses Icon.PlusDouble for a heavier "+".
  • src/assets/icons/plus-double.svg (registered as Icon.PlusDouble) — a bolder plus. The base plus.svg stroke (2 in a 24 viewBox) renders ~1.5px at the pill's 18px size; this duplicate uses a thicker stroke so it reads ~2px.
  • src/components/screens/TokenDetailsScreen/components/RemoveTokenSheetContent.tsx — the token removability guard (native XLM → can't remove; positive balance or LP shares → can't remove; otherwise the removable confirmation), extracted verbatim from the now-deleted SimpleBalancesList so Token Details owns a single source of truth.

Home floating buttons

  • HomeScreen renders the pill as an absolute sibling of the ScrollView (not inside TokensCollectiblesTabs), anchored bottom: pxValue(DEFAULT_PADDING) — the screen's content already ends at the tab bar, so no useBottomTabBarHeight offset is needed. pointerEvents="box-none" so the container doesn't block scroll, and the ScrollView contentContainerStyle reserves paddingBottom: pxValue(88) so the pill never obscures the last list row.
  • The active tab is tracked via TokensCollectiblesTabs's existing onTabChange; the pill swaps label / handler / testID (home-add-token-buttonhome-add-collectible-button). Tokens → MANAGE_TOKENS_STACK / ADD_TOKEN_SCREEN; Collectibles → ADD_COLLECTIBLE_SCREEN. The collectibles pill is disabled while the collectibles store isLoading (restores the old isCollectiblesLoading guard so the Add flow isn't entered before the list has loaded).
  • TokensCollectiblesTabs (Home's only consumer — not used in the Send flow) had its Sliders01 ContextMenuButton, both menu-action arrays, and the showTokensSettings / showCollectiblesSettings props removed.

Token Details "⋯" menu

  • TokenDetailsScreen adds useRightHeaderMenu({ icon: Icon.DotsHorizontal, actions: [Copy address, Remove(destructive)] }) alongside the existing headerTitle effect (both merge into setOptions).
  • The selected balance is read from the existing useBalancesList call (balanceItems.find(id === tokenId)); Remove presents a BottomSheet with RemoveTokenSheetContent, wired to useManageToken({ …, onSuccess: () => navigation.goBack() }). Copy uses useTokenActions().copyTokenAddress; cancel fires trackRemoveTokenRejected.

Manage Tokens removal

  • Deleted ManageTokensScreen + SimpleBalancesList (its only consumer). Removed the MANAGE_TOKENS_SCREEN entry from MANAGE_TOKENS_ROUTES and its ManageTokensStackParamList line.
  • Kept MANAGE_TOKENS_STACK hosting AddTokenScreen as its sole screen — route string values unchanged for analytics stability (only the MANAGE_TOKENS_SCREEN entry was removed). ManageTokenRightContent, RemoveTokenBottomSheet, CannotRemoveTokenBottomSheet stay (still used by AddTokenScreen).

Add Collectible

  • The purple "Show hidden" link uses the SDS TextButton (variant="tertiary" = lilac) → HIDDEN_COLLECTIBLES_SCREEN. TextButton is w-full/centered, so it's wrapped in a self-start container to hug its content and left-align, with mb-3 above and below and py-1 for a compact height. Inputs / description / bottom button untouched.
  • TextButton gained an optional hitSlop prop; the link passes { top: 6, bottom: 6 } so the tap target reaches ~44pt without changing the visible layout.

Shared-hook fixes (from device testing / review)

  • useManageTokensonSuccess now fires only on a confirmed success (moved out of the finally block for both addToken and removeToken). Previously a failed add/remove still ran the caller's onSuccess — e.g. navigating away from a token that wasn't removed. This also fixes the same latent issue in AddTokenScreen.
  • useManageToken.removeToken — falls back to a canonical code:issuer identifier when the token has no id (search results carry no id), fixing "No token ID or token record provided" when removing from the Add Token list. Token Details (which passes an id) is unaffected.

i18n

  • Added balancesList.addTokenButton, collectiblesGrid.addCollectibleButton, addCollectibleScreen.showHidden (en + pt).
  • Removed four now-orphaned keys that only fed the deleted Sliders menu: balancesList.menuAddToken, balancesList.menuManageTokens, collectiblesGrid.menuAddManually, collectiblesGrid.menuHidenCollectibles.

Tests

  • New: FloatingTabActionButton (label/press + disabled), TokensCollectiblesTabs, RemoveTokenSheetContent (native / has-balance / zero-balance LP-share / removable), AddCollectibleScreen (navigate-on-press).
  • Updated: HomeScreen (per-tab pill), TokenDetailsScreen (header menu actions), useManageTokens (asserts onSuccess does not fire on failure), useManageToken (derives tokenId from code:issuer when id is absent).
  • Deleted: SimpleBalancesList test.
  • tsc + eslint clean; full jest suite green.

🤖 Generated with Claude Code

CassioMG and others added 9 commits July 23, 2026 15:57
…lesTabs

The menu's actions were relocated to floating tab-action pills on Home
(Tasks 2-3). Strips the ContextMenuButton block, tokensMenuActions/
collectiblesMenuActions memos, showSettingsMenu memo, the
showTokensSettings/showCollectiblesSettings props, and the now-unused
navigation/collectibles-loading wiring and imports.

The brief's target test file (TokensCollectiblesInline.test.tsx) covers an
unrelated SendScreen component with no menu assertions to remove, so adds a
dedicated TokensCollectiblesTabs.test.tsx instead, asserting the tab headers
render with no settings menu trigger.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rences

Delete four unused i18n keys left over from the removed Sliders settings
menu (balancesList.menuAddToken/menuManageTokens,
collectiblesGrid.menuAddManually/menuHidenCollectibles) from both en and
pt locales, fix a stale JSDoc comment on TokensCollectiblesTabs that still
referenced the removed TransactionTokenScreen usage, and drop a vacuously
true test assertion for a testID that never existed on the component.
@CassioMG CassioMG changed the title [WIP] Relocate Tokens/Collectibles settings actions (floating add buttons, token-details remove, show hidden) [WIP] Relocate Tokens/Collectibles settings actions Jul 23, 2026
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

iOS Simulator preview build is ready: https://github.com/stellar/freighter-mobile/releases/tag/untagged-63485e01f38ad6dd28ca (SDF collaborators only — install instructions in the release description)

CassioMG and others added 2 commits July 23, 2026 19:37
… semibold label)

- Anchor the pill exactly 24px above the tab bar (drop pxValue scaling that
  inflated the gap on shorter/wider devices)
- Plus icon uses foreground.primary (grey) per Foreground/Primary, not the
  near-white text.primary
- Label uses semiBold (600) per Text/MD/600; tighten icon/label gap to 4px

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop useBottomTabBarHeight — HomeScreen's content already ends at the tab
bar, so adding the tab-bar height double-counted and pushed the pill too
high. Bottom margin is now just pxValue(DEFAULT_PADDING).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@CassioMG CassioMG changed the title [WIP] Relocate Tokens/Collectibles settings actions [Home refresh] Relocate Tokens/Collectibles settings actions Jul 23, 2026
@CassioMG
CassioMG marked this pull request as ready for review July 24, 2026 00:05
Copilot AI review requested due to automatic review settings July 24, 2026 00:05
@CassioMG CassioMG self-assigned this Jul 24, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Relocates token and collectible management actions to Home, Token Details, and Add Collectible screens.

Changes:

  • Adds floating Home actions and a reusable pill button.
  • Moves token removal/copy actions into Token Details.
  • Removes the Manage Tokens screen and adds “Show hidden” to Add Collectible.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/navigators/ManageTokensNavigator.tsx Removes Manage Tokens route.
src/config/routes.ts Removes obsolete route types.
src/i18n/locales/en/translations.json Updates English action labels.
src/i18n/locales/pt/translations.json Updates Portuguese action labels.
src/components/TokensCollectiblesTabs.tsx Removes tab settings menus.
src/components/SimpleBalancesList.tsx Deletes obsolete management list.
src/components/screens/ManageTokensScreen.tsx Deletes obsolete screen.
src/components/FloatingTabActionButton.tsx Adds floating pill component.
src/components/screens/HomeScreen/HomeScreen.tsx Adds tab-specific floating actions.
src/components/screens/AddCollectibleScreen/AddCollectibleScreen.tsx Adds hidden-collectibles link.
src/components/screens/TokenDetailsScreen/TokenDetailsScreen.tsx Adds copy and removal menu.
src/components/screens/TokenDetailsScreen/components/RemoveTokenSheetContent.tsx Adds removal guards and confirmation content.
__tests__/components/TokensCollectiblesTabs.test.tsx Tests tab headers.
__tests__/components/SimpleBalancesList.test.tsx Removes obsolete tests.
__tests__/components/FloatingTabActionButton.test.tsx Tests floating button interaction.
__tests__/components/screens/HomeScreen.test.tsx Tests per-tab floating actions.
__tests__/components/screens/AddCollectibleScreen.test.tsx Tests hidden-screen navigation.
__tests__/components/screens/TokenDetailsScreen/TokenDetailsScreen.test.tsx Tests header menu configuration.
__tests__/components/screens/TokenDetailsScreen/RemoveTokenSheetContent.test.tsx Tests removal guard variants.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/components/screens/TokenDetailsScreen/TokenDetailsScreen.tsx Outdated
Comment thread src/components/screens/HomeScreen/HomeScreen.tsx
Comment thread src/components/screens/AddCollectibleScreen/AddCollectibleScreen.tsx Outdated
@CassioMG CassioMG added the don't review yet Work in Progress / Draft PR / Code Review adjustments being worked on label Jul 24, 2026
CassioMG and others added 10 commits July 23, 2026 21:25
The Token Details header context menu built its Copy address and Remove
actions without a systemIcon, so both rendered without a leading icon.
Match the existing convention (ManageTokenRightContent) and set the same
platform icons; widen useRightHeaderMenu's action type to accept systemIcon.

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

Add a DEFAULT_PADDING top margin to the View / Send footer so the buttons
have breathing room from the scrollable content above.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- useManageTokens: fire onSuccess only on confirmed success (was in finally,
  so a failed add/remove still ran the caller's onSuccess — e.g. navigating
  Home away from a token that wasn't removed). Guards added to error tests.
- HomeScreen: reserve bottom scroll padding so the floating pill can't obscure
  the last list row.
- AddCollectibleScreen: replace the hand-rolled 'Show hidden' touchable with
  the SDS TextButton (tertiary/lilac), left-aligned with a 44pt tap target.
- RemoveTokenSheetContent: add a zero-balance LP-share test case (LP shares
  stay non-removable independent of balance).
- FloatingTabActionButton: add a disabled state; disable the 'Add collectible'
  pill while the collectibles store is loading (restores the dropped
  isCollectiblesLoading guard so the Add flow isn't entered mid-fetch).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Removing a token from the Add Token list threw 'No token ID or token record
provided': search results (FormattedSearchTokenRecord) have no `id`, and
useManageToken forwarded only tokenId. Fall back to the canonical
`code:issuer` identifier when id is absent. Token Details (which passes an
id) is unaffected. Pre-existing bug surfaced via the new + Add token entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
TextButton is w-full with centered content, so className='items-start' didn't
override it. Wrap in a self-start container so it hugs content and sits at the
left, and reduce py-3 -> py-1 (and mb-6 -> mb-4) so it's no longer oversized.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The base plus.svg stroke (2 in a 24 viewBox) renders ~1.5px at the pill's
18px size, looking thin next to the semibold label. Add a plus-double.svg
with a heavier stroke and use it in FloatingTabActionButton.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…r even spacing

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The compact 'Show hidden' link (py-1) is ~32px tall — under the 44pt a11y
target. Add an optional hitSlop to TextButton and apply { top: 6, bottom: 6 }
so the tappable area reaches ~44pt without changing the visible layout.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts:
#	src/i18n/locales/en/translations.json
#	src/i18n/locales/pt/translations.json
…keys

Both belonged to the deleted Manage Tokens screen and are now unreferenced
(en + pt). moreInfo.*, cantRemove*, and removeToken* stay — still used by
AddTokenScreen / CannotRemoveTokenBottomSheet / useManageTokens.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 31 out of 33 changed files in this pull request and generated 1 comment.

Comment thread src/components/screens/TokenDetailsScreen/TokenDetailsScreen.tsx Outdated
@CassioMG

Copy link
Copy Markdown
Contributor Author

Code review

Found 1 issue:

  1. Removing a token from Token Details no longer refreshes balances, so the removed token stays visible on Home until the next poll. onSuccess only calls navigation.goBack(), while the deleted SimpleBalancesList passed onSuccess: handleRefresh (old code). useBalancesList exposes handleRefresh but it is not destructured at line 105, the local handleRefresh at line 172 only refetches token history, removeToken in useManageTokens.ts does not refetch balances, and HomeScreen has no focus-triggered refresh (only pull-to-refresh). This matches the still-unaddressed Copilot comment on this PR.

account,
bottomSheetRefRemove: removeTokenBottomSheetModalRef,
onSuccess: () => navigation.goBack(),
});

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

CassioMG and others added 2 commits July 25, 2026 17:38
Removal only navigated back, so Home kept showing the removed token (from
pricedBalances) until the next focused poll — up to ~30s, and custom-token
storage had already stopped future fetches. Call the balances-list
handleRefresh before goBack so the removal is reflected immediately.

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

- Remove collectiblesGrid.menuAddManually / menuHidenCollectibles (en + pt),
  re-introduced by a merge; unreferenced now that the Sliders menu is gone.
- Extract HomeScreen's pxValue(88) pill clearance into
  FLOATING_ADD_BUTTON_CLEARANCE.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@CassioMG CassioMG removed the don't review yet Work in Progress / Draft PR / Code Review adjustments being worked on label Jul 25, 2026
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.

2 participants