Skip to content

Commit 24712bd

Browse files
fix: graceful fallback for assets missing images cp-7.77.0 (#30096)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** - replace the confirmation token avatar fallback with `AssetLogo` in `token.tsx` so send/perps flows use the same asset image pipeline + fallback as home/swap. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: fix: ensure missing assets try a fallback image url path. ## **Related issues** Fixes: #29946 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <div><a href="https://cursor.com/agents/bc-ac7fc83c-c5ae-4a0e-bf24-babcd2652926"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/background-agent?bcId=bc-ac7fc83c-c5ae-4a0e-bf24-babcd2652926"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI change that only alters how token logos are rendered; main risk is minor layout/styling differences or unexpected image URL fallback behavior in a few flows. > > **Overview** > Uses the shared `AssetLogo` component (with its fallback image URL logic) anywhere non-native token avatars were previously rendered directly via `AvatarToken`, including the asset overview balance header and the confirmations token selector. > > Updates the confirmations `Token` tests to mock `AssetLogo` to keep them focused on text/interaction behavior. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5d62794. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
1 parent 3595344 commit 24712bd

3 files changed

Lines changed: 9 additions & 15 deletions

File tree

app/components/UI/AssetOverview/Balance/Balance.tsx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ import BadgeWrapper, {
2323
} from '../../../../component-library/components/Badges/BadgeWrapper';
2424
import { BadgeVariant } from '../../../../component-library/components/Badges/Badge/Badge.types';
2525
import Badge from '../../../../component-library/components/Badges/Badge/Badge';
26-
import AvatarToken from '../../../../component-library/components/Avatars/Avatar/variants/AvatarToken';
27-
import { AvatarSize } from '../../../../component-library/components/Avatars/Avatar';
2826
import NetworkAssetLogo from '../../NetworkAssetLogo';
2927
import Text, {
3028
TextColor,
@@ -53,6 +51,7 @@ import { ACCOUNT_TYPE_LABELS } from '../../../../constants/account-type-labels';
5351
import { useRWAToken } from '../../Bridge/hooks/useRWAToken';
5452
import { BridgeToken } from '../../Bridge/types';
5553
import StockBadge from '../../shared/StockBadge';
54+
import AssetLogo from '../../Assets/components/AssetLogo/AssetLogo';
5655

5756
export const ACCOUNT_TYPE_LABEL_TEST_ID = 'account-type-label';
5857

@@ -186,13 +185,7 @@ const Balance = ({
186185
);
187186
}
188187

189-
return (
190-
<AvatarToken
191-
name={asset.symbol}
192-
imageSource={{ uri: asset.image }}
193-
size={AvatarSize.Lg}
194-
/>
195-
);
188+
return <AssetLogo asset={asset} />;
196189
}, [asset, styles.ethLogo]);
197190

198191
const isDisabled = useMemo(

app/components/Views/confirmations/components/UI/token/token.test.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import { AssetType } from '../../../types/token';
66
import { Token } from './token';
77
import { act, fireEvent } from '@testing-library/react-native';
88

9+
jest.mock(
10+
'../../../../../UI/Assets/components/AssetLogo/AssetLogo',
11+
() => () => null,
12+
);
13+
914
describe('Token', () => {
1015
const createMockToken = (overrides: Partial<AssetType> = {}): AssetType => ({
1116
address: '0x1234567890123456789012345678901234567890',

app/components/Views/confirmations/components/UI/token/token.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
Box,
55
Text,
66
TextVariant,
7-
AvatarToken,
87
FontWeight,
98
TextColor,
109
} from '@metamask/design-system-react-native';
@@ -23,6 +22,7 @@ import { AccountTypeLabel } from '../account-type-label';
2322
import { AssetType } from '../../../types/token';
2423
import { formatAmount } from '../../../../../../components/UI/SimulationDetails/formatAmount';
2524
import { ACCOUNT_TYPE_LABELS } from '../../../../../../constants/account-type-labels';
25+
import AssetLogo from '../../../../../UI/Assets/components/AssetLogo/AssetLogo';
2626

2727
interface TokenProps {
2828
asset: AssetType;
@@ -75,11 +75,7 @@ export function Token({ asset, onPress }: TokenProps) {
7575
ticker={asset.symbol as string}
7676
/>
7777
) : (
78-
<AvatarToken
79-
name={asset.symbol || asset.name || 'Token'}
80-
src={asset.image ? { uri: asset.image } : undefined}
81-
style={tw.style('w-10 h-10')}
82-
/>
78+
<AssetLogo asset={asset} />
8379
)}
8480
</BadgeWrapper>
8581
</Box>

0 commit comments

Comments
 (0)