Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trending Tokens UI implementation phase 1 #6276

Closed
Closed
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@ module.exports = {
],
'jest/expect-expect': 'off',
'jest/no-disabled-tests': 'off',
'no-nested-ternary': 'off',
greg-schrammel marked this conversation as resolved.
Show resolved Hide resolved
},
};
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { IS_ANDROID, IS_DEV } from '@/env';
import { prefetchDefaultFavorites } from '@/resources/favorites';
import Routes from '@/navigation/Routes';
import { BackendNetworks } from '@/components/BackendNetworks';
import { AbsolutePortalRoot } from './components/AbsolutePortal';

if (IS_DEV) {
reactNativeDisableYellowBox && LogBox.ignoreAllLogs();
Expand Down Expand Up @@ -73,6 +74,7 @@ function App({ walletReady }: AppProps) {
<InitialRouteContext.Provider value={initialRoute}>
<Routes ref={handleNavigatorRef} />
<PortalConsumer />
<AbsolutePortalRoot />
</InitialRouteContext.Provider>
)}
<OfflineToast />
Expand Down
90 changes: 25 additions & 65 deletions src/__swaps__/screens/Swap/components/AnimatedSwapCoinIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,37 +14,19 @@ import { IS_ANDROID, IS_IOS } from '@/env';
import { PIXEL_RATIO } from '@/utils/deviceUtils';
import { useSwapContext } from '../providers/swap-provider';

const fallbackIconStyle = {
...borders.buildCircleAsObject(32),
position: 'absolute' as ViewStyle['position'],
};

const largeFallbackIconStyle = {
...borders.buildCircleAsObject(36),
position: 'absolute' as ViewStyle['position'],
};

const smallFallbackIconStyle = {
...borders.buildCircleAsObject(16),
position: 'absolute' as ViewStyle['position'],
};

export const AnimatedSwapCoinIcon = memo(function AnimatedSwapCoinIcon({
assetType,
large = true,
small,
size = 32,
showBadge = true,
}: {
assetType: 'input' | 'output';
large?: boolean;
small?: boolean;
size?: number;
showBadge?: boolean;
}) {
const { isDarkMode, colors } = useTheme();
const { internalSelectedInputAsset, internalSelectedOutputAsset } = useSwapContext();

const asset = assetType === 'input' ? internalSelectedInputAsset : internalSelectedOutputAsset;
const size = small ? 16 : large ? 36 : 32;

const didErrorForUniqueId = useSharedValue<string | undefined>(undefined);

Expand Down Expand Up @@ -91,15 +73,8 @@ export const AnimatedSwapCoinIcon = memo(function AnimatedSwapCoinIcon({
}));

return (
<View style={small ? sx.containerSmall : large ? sx.containerLarge : sx.container}>
<Animated.View
style={[
sx.reactCoinIconContainer,
small ? sx.coinIconFallbackSmall : large ? sx.coinIconFallbackLarge : sx.coinIconFallback,
sx.withShadow,
animatedCoinIconWrapperStyles,
]}
>
<View style={containerStyle(size)}>
<Animated.View style={[sx.reactCoinIconContainer, coinIconFallbackStyle(size), sx.withShadow, animatedCoinIconWrapperStyles]}>
<Animated.View style={animatedCoinIconStyles}>
{/* ⚠️ TODO: This works but we should figure out how to type this correctly to avoid this error */}
{/* @ts-expect-error: Doesn't pick up that it's getting a source prop via animatedProps */}
Expand All @@ -122,29 +97,14 @@ export const AnimatedSwapCoinIcon = memo(function AnimatedSwapCoinIcon({
/>
</Animated.View>

<Animated.View
style={[animatedFallbackStyles, small ? sx.coinIconFallbackSmall : large ? sx.coinIconFallbackLarge : sx.coinIconFallback]}
>
<SwapCoinIconTextFallback
asset={asset}
height={size}
width={size}
style={small ? smallFallbackIconStyle : large ? largeFallbackIconStyle : fallbackIconStyle}
/>
<Animated.View style={[animatedFallbackStyles, coinIconFallbackStyle(size)]}>
<SwapCoinIconTextFallback asset={asset} height={size} width={size} style={fallbackIconStyle(size)} />
</Animated.View>

<Box
as={Animated.View}
background={isDarkMode ? 'fillQuaternary' : 'fillTertiary'}
style={[
animatedEmptyStateStyles,
small ? sx.coinIconFallbackSmall : large ? sx.coinIconFallbackLarge : sx.coinIconFallback,
{
borderRadius: size / 2,
height: size,
width: size,
},
]}
style={[animatedEmptyStateStyles, coinIconFallbackStyle(size)]}
/>
</Animated.View>

Expand All @@ -153,28 +113,28 @@ export const AnimatedSwapCoinIcon = memo(function AnimatedSwapCoinIcon({
);
});

const fallbackIconStyle = (size: number) => ({
...borders.buildCircleAsObject(size),
position: 'absolute' as ViewStyle['position'],
});

const coinIconFallbackStyle = (size: number) => ({
borderRadius: size / 2,
height: size,
width: size,
overflow: 'visible' as const,
});

const containerStyle = (size: number) => ({
elevation: 6,
height: size,
overflow: 'visible' as const,
});

const sx = StyleSheet.create({
coinIcon: {
overflow: 'hidden',
},
coinIconFallback: {
borderRadius: 16,
height: 32,
overflow: 'visible',
width: 32,
},
coinIconFallbackLarge: {
borderRadius: 18,
height: 36,
overflow: 'visible',
width: 36,
},
coinIconFallbackSmall: {
borderRadius: 8,
height: 16,
overflow: 'visible',
width: 16,
},
container: {
elevation: 6,
height: 32,
Expand Down
2 changes: 1 addition & 1 deletion src/__swaps__/screens/Swap/components/CoinRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export function CoinRow({ isFavorite, onPress, output, uniqueId, testID, ...asse
iconUrl={icon_url}
address={address}
mainnetAddress={mainnetAddress}
large
size={36}
chainId={chainId}
symbol={symbol || ''}
color={colors?.primary}
Expand Down
103 changes: 30 additions & 73 deletions src/__swaps__/screens/Swap/components/SwapCoinIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,10 @@ const fallbackTextStyles = {
textAlign: 'center',
};

const fallbackIconStyle = {
...borders.buildCircleAsObject(32),
const fallbackIconStyle = (size: number) => ({
...borders.buildCircleAsObject(size),
position: 'absolute',
};

const largeFallbackIconStyle = {
...borders.buildCircleAsObject(36),
position: 'absolute',
};

const smallFallbackIconStyle = {
...borders.buildCircleAsObject(16),
position: 'absolute',
};
});

/**
* If mainnet asset is available, get the token under /ethereum/ (token) url.
Expand All @@ -63,22 +53,22 @@ export const SwapCoinIcon = React.memo(function FeedCoinIcon({
iconUrl,
disableShadow = true,
forceDarkMode,
large,
mainnetAddress,
chainId,
small,
symbol,
size = 32,
chainSize,
}: {
address: string;
color?: string;
iconUrl?: string;
disableShadow?: boolean;
forceDarkMode?: boolean;
large?: boolean;
mainnetAddress?: string;
chainId: ChainId;
small?: boolean;
symbol: string;
size?: number;
chainSize?: number;
}) {
const theme = useTheme();

Expand All @@ -92,52 +82,52 @@ export const SwapCoinIcon = React.memo(function FeedCoinIcon({
const eth = isETH(resolvedAddress);

return (
<View style={small ? sx.containerSmall : large ? sx.containerLarge : sx.container}>
<View style={[styles.container(size), { height: size }]}>
{eth ? (
<Animated.View
key={`${resolvedAddress}-${eth}`}
style={[
sx.reactCoinIconContainer,
small ? sx.coinIconFallbackSmall : large ? sx.coinIconFallbackLarge : sx.coinIconFallback,
small || disableShadow ? {} : sx.withShadow,
{ shadowColor },
]}
style={[sx.reactCoinIconContainer, styles.coinIcon(size), !disableShadow && sx.withShadow, { shadowColor }]}
>
<FastImage
source={EthIcon as Source}
style={small ? sx.coinIconFallbackSmall : large ? sx.coinIconFallbackLarge : sx.coinIconFallback}
/>
<FastImage source={EthIcon as Source} style={styles.coinIcon(size)} />
</Animated.View>
) : (
<FastFallbackCoinIconImage
size={small ? 16 : large ? 36 : 32}
icon={iconUrl}
shadowColor={shadowColor}
symbol={symbol}
theme={theme}
>
<FastFallbackCoinIconImage size={size} icon={iconUrl} shadowColor={shadowColor} symbol={symbol} theme={theme}>
{() => (
<CoinIconTextFallback
color={color}
height={small ? 16 : large ? 36 : 32}
style={small ? smallFallbackIconStyle : large ? largeFallbackIconStyle : fallbackIconStyle}
height={size}
style={fallbackIconStyle(size)}
symbol={symbol}
textStyles={fallbackTextStyles}
width={small ? 16 : large ? 36 : 32}
width={size}
/>
)}
</FastFallbackCoinIconImage>
)}

{chainId && chainId !== ChainId.mainnet && !small && (
{chainId && chainId !== ChainId.mainnet && size > 16 && (
<View style={sx.badge}>
<ChainImage chainId={chainId} size={16} />
<ChainImage chainId={chainId} size={chainSize ?? 16} />
</View>
)}
</View>
);
});

const styles = {
container: (size: number) => ({
elevation: 6,
height: size,
overflow: 'visible' as const,
}),
coinIcon: (size: number) => ({
borderRadius: size / 2,
height: size,
width: size,
overflow: 'visible' as const,
}),
};

const sx = StyleSheet.create({
badge: {
bottom: -0,
Expand All @@ -151,39 +141,6 @@ const sx = StyleSheet.create({
shadowRadius: 6,
shadowOpacity: 0.2,
},
coinIconFallback: {
borderRadius: 16,
height: 32,
overflow: 'visible',
width: 32,
},
coinIconFallbackLarge: {
borderRadius: 18,
height: 36,
overflow: 'visible',
width: 36,
},
coinIconFallbackSmall: {
borderRadius: 8,
height: 16,
overflow: 'visible',
width: 16,
},
container: {
elevation: 6,
height: 32,
overflow: 'visible',
},
containerLarge: {
elevation: 6,
height: 36,
overflow: 'visible',
},
containerSmall: {
elevation: 6,
height: 16,
overflow: 'visible',
},
reactCoinIconContainer: {
alignItems: 'center',
justifyContent: 'center',
Expand Down
2 changes: 1 addition & 1 deletion src/__swaps__/screens/Swap/components/SwapInputAsset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ function SwapInputAmount() {
function SwapInputIcon() {
return (
<Box paddingRight="10px">
<AnimatedSwapCoinIcon assetType={'input'} large />
<AnimatedSwapCoinIcon assetType={'input'} size={36} />
</Box>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/__swaps__/screens/Swap/components/SwapOutputAsset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ function SwapOutputAmount({ handleTapWhileDisabled }: { handleTapWhileDisabled:
function SwapOutputIcon() {
return (
<Box paddingRight="10px">
<AnimatedSwapCoinIcon assetType="output" large />
<AnimatedSwapCoinIcon assetType="output" size={36} />
</Box>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/__swaps__/screens/Swap/components/SwapSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ export const SwapSlider = ({
<Columns alignHorizontal="justify" alignVertical="center">
<Inline alignVertical="center" space="6px" wrap={false}>
<Bleed vertical="4px">
<AnimatedSwapCoinIcon showBadge={false} assetType={'input'} small />
<AnimatedSwapCoinIcon showBadge={false} assetType={'input'} size={16} />
</Bleed>
<Inline alignVertical="bottom" wrap={false}>
<AnimatedText
Expand Down
Loading
Loading