Skip to content

Commit afa3ba1

Browse files
committed
chore: adds chain icon
1 parent c5532e5 commit afa3ba1

3 files changed

Lines changed: 96 additions & 6 deletions

File tree

app/components/Views/SocialLeaderboard/TraderProfileView/components/PositionRow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const PositionRow: React.FC<PositionRowProps> = ({ position, onPress }) => {
5555
gap={4}
5656
twClassName="flex-1 min-w-0 mr-3"
5757
>
58-
<PositionTokenAvatar position={position} />
58+
<PositionTokenAvatar position={position} showChainBadge />
5959

6060
<Box twClassName="flex-1 min-w-0">
6161
<Text

app/components/Views/SocialLeaderboard/components/PositionTokenAvatar.test.tsx

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import {
77
import renderWithProvider from '../../../../util/test/renderWithProvider';
88
import PositionTokenAvatar from './PositionTokenAvatar';
99
import type { Position } from '@metamask/social-controllers';
10+
import BadgeWrapper from '../../../../component-library/components/Badges/BadgeWrapper';
11+
import BadgeNetwork from '../../../../component-library/components/Badges/Badge/variants/BadgeNetwork';
1012

1113
jest.mock('@metamask/design-system-react-native', () => ({
1214
...jest.requireActual('@metamask/design-system-react-native'),
@@ -26,7 +28,30 @@ jest.mock('../utils/chainMapping', () => ({
2628
),
2729
}));
2830

31+
jest.mock(
32+
'../../../../component-library/components/Badges/BadgeWrapper',
33+
() => ({
34+
__esModule: true,
35+
default: jest.fn(() => null),
36+
BadgePosition: { BottomRight: 'bottom-right' },
37+
}),
38+
);
39+
40+
jest.mock(
41+
'../../../../component-library/components/Badges/Badge/variants/BadgeNetwork',
42+
() => ({
43+
__esModule: true,
44+
default: jest.fn(() => null),
45+
}),
46+
);
47+
48+
jest.mock('../../../../util/networks', () => ({
49+
getNetworkImageSource: jest.fn(() => ({ uri: 'network.png' })),
50+
}));
51+
2952
const MockAvatarToken = AvatarToken as jest.Mock;
53+
const MockBadgeWrapper = BadgeWrapper as jest.Mock;
54+
const MockBadgeNetwork = BadgeNetwork as jest.Mock;
3055

3156
const lastAvatarTokenProps = () =>
3257
MockAvatarToken.mock.calls[MockAvatarToken.mock.calls.length - 1][0] as {
@@ -214,4 +239,40 @@ describe('PositionTokenAvatar', () => {
214239
uri: 'https://static.cx.metamask.io/eip155:8453.png',
215240
});
216241
});
242+
243+
describe('showChainBadge', () => {
244+
it('wraps the avatar in BadgeWrapper when showChainBadge is true and the chain resolves', () => {
245+
renderWithProvider(
246+
<PositionTokenAvatar position={basePosition} showChainBadge />,
247+
);
248+
249+
expect(MockBadgeWrapper).toHaveBeenCalled();
250+
});
251+
252+
it('passes a BadgeNetwork as the badgeElement when showChainBadge is true', () => {
253+
renderWithProvider(
254+
<PositionTokenAvatar position={basePosition} showChainBadge />,
255+
);
256+
257+
const badgeElement = MockBadgeWrapper.mock.calls[0][0]
258+
.badgeElement as React.ReactElement;
259+
expect(badgeElement.type).toBe(MockBadgeNetwork);
260+
});
261+
262+
it('does not wrap the avatar in BadgeWrapper when showChainBadge is false by default', () => {
263+
renderWithProvider(<PositionTokenAvatar position={basePosition} />);
264+
265+
expect(MockBadgeWrapper).not.toHaveBeenCalled();
266+
});
267+
268+
it('does not wrap the avatar in BadgeWrapper when the chain is unsupported', () => {
269+
const position = { ...basePosition, chain: 'unsupported' };
270+
271+
renderWithProvider(
272+
<PositionTokenAvatar position={position} showChainBadge />,
273+
);
274+
275+
expect(MockBadgeWrapper).not.toHaveBeenCalled();
276+
});
277+
});
217278
});

app/components/Views/SocialLeaderboard/components/PositionTokenAvatar.tsx

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@ import {
66
import type { Position } from '@metamask/social-controllers';
77
import { getAssetImageUrl } from '../../../UI/Bridge/hooks/useAssetMetadata/utils';
88
import { chainNameToId } from '../utils/chainMapping';
9+
import BadgeWrapper, {
10+
BadgePosition,
11+
} from '../../../../component-library/components/Badges/BadgeWrapper';
12+
import BadgeNetwork from '../../../../component-library/components/Badges/Badge/variants/BadgeNetwork';
13+
import { getNetworkImageSource } from '../../../../util/networks';
914

1015
export interface PositionTokenAvatarProps {
1116
position: Position;
1217
size?: AvatarTokenSize;
18+
showChainBadge?: boolean;
1319
}
1420

1521
type ImageSource = 'clicker' | 'metamask' | 'none';
@@ -23,12 +29,17 @@ type ImageSource = 'clicker' | 'metamask' | 'none';
2329
const PositionTokenAvatar: React.FC<PositionTokenAvatarProps> = ({
2430
position,
2531
size = AvatarTokenSize.Lg,
32+
showChainBadge = false,
2633
}) => {
34+
const caipChainId = useMemo(
35+
() => chainNameToId(position.chain),
36+
[position.chain],
37+
);
38+
2739
const metamaskUrl = useMemo(() => {
28-
const chainId = chainNameToId(position.chain);
29-
if (!chainId) return undefined;
30-
return getAssetImageUrl(position.tokenAddress, chainId);
31-
}, [position.chain, position.tokenAddress]);
40+
if (!caipChainId) return undefined;
41+
return getAssetImageUrl(position.tokenAddress, caipChainId);
42+
}, [caipChainId, position.tokenAddress]);
3243

3344
const initialSource = useMemo((): ImageSource => {
3445
if (position.tokenImageUrl) return 'clicker';
@@ -64,7 +75,7 @@ const PositionTokenAvatar: React.FC<PositionTokenAvatarProps> = ({
6475
});
6576
};
6677

67-
return (
78+
const avatar = (
6879
<AvatarToken
6980
name={position.tokenSymbol}
7081
src={src}
@@ -75,6 +86,24 @@ const PositionTokenAvatar: React.FC<PositionTokenAvatarProps> = ({
7586
}}
7687
/>
7788
);
89+
90+
if (showChainBadge && caipChainId) {
91+
return (
92+
<BadgeWrapper
93+
badgePosition={BadgePosition.BottomRight}
94+
badgeElement={
95+
<BadgeNetwork
96+
name={position.chain}
97+
imageSource={getNetworkImageSource({ chainId: caipChainId })}
98+
/>
99+
}
100+
>
101+
{avatar}
102+
</BadgeWrapper>
103+
);
104+
}
105+
106+
return avatar;
78107
};
79108

80109
export default PositionTokenAvatar;

0 commit comments

Comments
 (0)