fix: token selector related issues#867
Conversation
kushagrasarathe
commented
May 16, 2025
- contributes to TASK-11332
- also fixes TASK-11255
- do no default to peanut wallet token/chain on first load
- check if token is supported by squid
- add fallback for logos
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
## Walkthrough
This change refactors several components in the Token Selector feature to improve image error handling and token support indication. It introduces state variables to track image load failures, adds conditional rendering for fallback avatars, and updates default token data initialization to use an empty object instead of a specific token. The token selection and display logic is streamlined for clarity.
## Changes
| Files | Change Summary |
|--------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| src/components/Global/TokenSelector/Components/NetworkButton.tsx,<br>src/components/Global/TokenSelector/Components/NetworkListItem.tsx | Refactored both components to introduce state variables for tracking image load errors. Updated rendering logic to display fallback avatars if network icon images fail to load, using `useState` and `onError` handlers. |
| src/components/Global/TokenSelector/Components/TokenListItem.tsx | Enhanced the component to accept a new `isSquidSupported` prop (defaulting to true) that controls interactivity and styling. Added state for tracking token and chain image load errors, with improved fallback rendering using avatars. Chevron icon rendering is now conditional based on token support or popularity. |
| src/components/Global/TokenSelector/TokenSelector.tsx | Added state variables for image error tracking in token and chain logos. Simplified logic for token selection when changing chains, defaulting to clearing selection. Updated rendering to pass Squid support status to token list items and improved image fallback handling. Removed unused imports and streamlined control flow for token and chain display. |
| src/context/tokenSelector.context.tsx | Replaced the use of `peanutDefaultTokenData` with an `emptyTokenData` object for default token data initialization and context reset, ensuring no default token is selected when not using Peanut Wallet and no last used token exists. |
## Possibly related PRs
- [peanutprotocol/peanut-ui#756](https://github.com/peanutprotocol/peanut-ui/pull/756): Both PRs change the initial token data setup in `tokenSelector.context.tsx`, focusing on default token selection logic.
- [peanutprotocol/peanut-ui#395](https://github.com/peanutprotocol/peanut-ui/pull/395): Both PRs modify `TokenSelector.tsx` to improve token selection logic and state management, but address different aspects of token selection and image handling.
- [peanutprotocol/peanut-ui#825](https://github.com/peanutprotocol/peanut-ui/pull/825): Both PRs refactor the `NetworkButton` component with similar image error handling and rendering improvements.
## Suggested labels
`Being worked on`
## Suggested reviewers
- Hugo0📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (1)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
src/components/Global/TokenSelector/TokenSelector.tsx (4)
187-194: Duplicate clearing logic – simplifyhandleChainSelectFromListBoth branches assign
setSelectedTokenAddress(''); theif/elsedistinction is no longer needed.if (isExternalWalletConnected) { - setSelectedTokenAddress('') // clear token when chain changes with external wallet -} else { - setSelectedTokenAddress('') // clear selected token when changing network in popular view + // clear selected token whenever the chain changes + setSelectedTokenAddress('') }Removing the redundant path makes the intent clearer and avoids future divergence.
458-470: Costly per-render look-ups in large token lists
find+someare executed for every balance rendered. When the list is large this becomes O(n²).
Caching theSetof supported addresses for each chain outside the map (e.g., inuseMemo) avoids repeated scans.Example optimisation (sketch):
const squidSupportedByChain = useMemo(() => { const map = new Map<string, Set<string>>() Object.entries(supportedSquidChainsAndTokens).forEach(([chainId, data]) => map.set(chainId, new Set(data.tokens.map(t => t.address.toLowerCase()))), ) return map }, [supportedSquidChainsAndTokens])Then inside the map:
const isTokenSupportedBySquid = squidSupportedByChain.get(String(balance.chainId))?.has(balance.address.toLowerCase()) ?? false
518-526: Button logo fallback misses chain badge & alt text context
- When the token image fails, the chain badge is dropped completely. Consider rendering the badge even when the main image is replaced by the generic currency icon or avatar.
- The generic
currencyicon lacks descriptivealttext, affecting accessibility.
599-627:AvatarWithBadgereuse: consider componentising the fallbackThe default-token block repeats the same “image with badge or fallback avatar/icon” logic already seen elsewhere. Extracting this into a small
<TokenLogo>component (with internalonErrorhandling and optional badge) would:
- Eliminate duplication
- Automatically reset error flags when the
srcprop changes (state lives inside the component)- Keep this parent component leaner
Let me know if you’d like a quick proof-of-concept diff.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/components/Global/TokenSelector/Components/NetworkButton.tsx(2 hunks)src/components/Global/TokenSelector/Components/NetworkListItem.tsx(3 hunks)src/components/Global/TokenSelector/Components/TokenListItem.tsx(5 hunks)src/components/Global/TokenSelector/TokenSelector.tsx(8 hunks)src/context/tokenSelector.context.tsx(3 hunks)
🧰 Additional context used
🧠 Learnings (2)
src/context/tokenSelector.context.tsx (2)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#413
File: src/context/tokenSelector.context.tsx:118-123
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In the `TokenContextProvider` component within `src/context/tokenSelector.context.tsx`, in the TypeScript React application, when data changes and before calling `fetchAndSetTokenPrice`, it is necessary to reset `selectedTokenData`, `selectedTokenPrice`, `selectedTokenDecimals`, and `inputDenomination` to discard stale data.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#631
File: src/components/Create/Create.tsx:108-112
Timestamp: 2025-01-16T13:14:40.363Z
Learning: In the Peanut UI codebase, the `resetTokenContextProvider` function from `tokenSelectorContext` is a stable function reference that doesn't change, so it doesn't need to be included in useEffect dependencies.
src/components/Global/TokenSelector/TokenSelector.tsx (1)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#551
File: src/components/Request/Create/Views/Initial.view.tsx:151-156
Timestamp: 2024-12-02T17:19:18.532Z
Learning: In the `InitialView` component at `src/components/Request/Create/Views/Initial.view.tsx`, when setting the default chain and token in the `useEffect` triggered by `isPeanutWallet`, it's acceptable to omit the setters from the dependency array and not include additional error handling for invalid defaults.
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Deploy-Preview
🔇 Additional comments (13)
src/context/tokenSelector.context.tsx (3)
64-68: Good addition ofemptyTokenDatafor better token state initialization.The new
emptyTokenDataobject provides a proper empty state for tokens, which aligns with the PR objective of removing default token selection on first load.
81-82: Improved token initialization logic.Replacing the default Peanut wallet token with an empty token state when no wallet is connected and no last used token exists creates a cleaner user experience. Users will now need to explicitly select a token rather than having one pre-selected.
113-113: Consistent application of empty token data in the reset function.This change ensures that the same empty token data logic is applied when resetting the token context, maintaining consistency with the initialization logic.
src/components/Global/TokenSelector/Components/NetworkListItem.tsx (2)
2-2: Added state for image error handling.Good addition of the React
useStatehook and theiconErrorstate variable to track image loading failures.Also applies to: 28-28
54-65: Implemented fallback for network icons.The conditional rendering now properly handles image loading failures by displaying an
AvatarWithBadgecomponent when the network icon fails to load, which prevents broken images from appearing in the UI.src/components/Global/TokenSelector/Components/NetworkButton.tsx (2)
4-4: Added state for chain image error handling.Good implementation of the React
useStatehook and thechainImageErrorstate variable to track chain icon loading failures.Also applies to: 22-24
25-57: Implemented fallback for chain icons.The component now properly handles chain icon loading failures by displaying an
AvatarWithBadgecomponent when the icon fails to load. This improves the user experience by providing a consistent visual representation even when network or CDN issues occur.src/components/Global/TokenSelector/Components/TokenListItem.tsx (6)
18-18: Added support for flagging Squid-unsupported tokens.The new
isSquidSupportedprop allows the component to visually indicate and disable tokens that aren't supported by Squid, addressing the PR objective of implementing Squid support verification.Also applies to: 28-28
32-33: Added state variables for token and chain image error handling.Good addition of separate state variables to track loading failures for both token and chain images.
51-58: Improved styling and interaction for unsupported tokens.The component now visually indicates unsupported tokens with reduced opacity and a "not-allowed" cursor, and prevents interaction by conditionally applying the click handler based on the
isSquidSupportedprop.
71-85: Enhanced token image error handling.The rendering logic for the token icon now includes proper error handling, falling back to the
AvatarWithBadgecomponent when the image fails to load.
86-100: Improved chain logo error handling.The chain logo is now only rendered if it exists and hasn't encountered loading errors, with proper error state tracking.
126-129: Conditionally rendering chevron icon based on token support.The chevron icon is now only displayed for tokens that are either supported by Squid or marked as popular, providing a visual indication of which tokens can be selected.