Skip to content

Commit

Permalink
refactor(token-bottom-sheet): remove deprecated option (#5468)
Browse files Browse the repository at this point in the history
### Description

All usages of token bottom sheet (Swap screen, send enter amount) uses
the token balance item option.

### Test plan

Unit tests, manually checking both Swap and Send flows

### Related issues

- Part of ACT-1170

### Backwards compatibility

Yes

### Network scalability

If a new NetworkId and/or Network are added in the future, the changes
in this PR will:

- [x] Continue to work without code changes, OR trigger a compilation
error (guaranteeing we find it when a new network is added)
  • Loading branch information
satish-ravi authored May 24, 2024
1 parent 96c9e13 commit 76082c3
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 164 deletions.
76 changes: 20 additions & 56 deletions src/components/TokenBottomSheet.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import { Provider } from 'react-redux'
import { TokenBottomSheetEvents } from 'src/analytics/Events'
import ValoraAnalytics from 'src/analytics/ValoraAnalytics'
import TokenBottomSheet, {
DEBOUCE_WAIT_TIME,
TokenBalanceItemOption,
DEBOUNCE_WAIT_TIME,
TokenBottomSheetProps,
TokenPickerOrigin,
} from 'src/components/TokenBottomSheet'
Expand Down Expand Up @@ -131,17 +130,7 @@ describe('TokenBottomSheet', () => {
}

it('renders correctly', () => {
const { getByTestId } = renderBottomSheet()

expect(getByTestId('cUSDBalance')).toHaveTextContent('10.00 cUSD')
expect(getByTestId('LocalcUSDBalance')).toHaveTextContent('₱13.30')
expect(getByTestId('cEURBalance')).toHaveTextContent('20.00 cEUR')
expect(getByTestId('LocalcEURBalance')).toHaveTextContent('₱31.92') // 20 * 1.2 (cEUR price) * 1.33 (PHP price)
expect(getByTestId('TTBalance')).toHaveTextContent('10.00 TT')
})

it('renders correctly with TokenBalanceItem', () => {
const { getAllByTestId } = renderBottomSheet({ TokenOptionComponent: TokenBalanceItemOption })
const { getAllByTestId } = renderBottomSheet()

expect(getAllByTestId('TokenBalanceItem')).toHaveLength(3)
expect(getAllByTestId('TokenBalanceItem')[0]).toHaveTextContent('10.00 cUSD')
Expand All @@ -152,36 +141,14 @@ describe('TokenBottomSheet', () => {
})

it('handles the choosing of a token correctly', () => {
const { getByTestId } = renderBottomSheet()

fireEvent.press(getByTestId('cUSDTouchable'))
expect(onTokenSelectedMock).toHaveBeenLastCalledWith(
tokens.find((token) => token.tokenId === mockCusdTokenId),
0
)

fireEvent.press(getByTestId('cEURTouchable'))
expect(onTokenSelectedMock).toHaveBeenLastCalledWith(
tokens.find((token) => token.tokenId === mockCeurTokenId),
1
)

fireEvent.press(getByTestId('TTTouchable'))
expect(onTokenSelectedMock).toHaveBeenLastCalledWith(
tokens.find((token) => token.tokenId === mockTestTokenTokenId),
2
)
})

it('handles the choosing of a token correctly with TokenBalanceItem', () => {
const commonAnalyticsProps = {
areSwapTokensShuffled: undefined,
networkId: 'celo-alfajores',
origin: 'Send',
selectedFilters: [],
usedSearchTerm: false,
}
const { getAllByTestId } = renderBottomSheet({ TokenOptionComponent: TokenBalanceItemOption })
const { getAllByTestId } = renderBottomSheet()

fireEvent.press(getAllByTestId('TokenBalanceItem')[0])
expect(onTokenSelectedMock).toHaveBeenLastCalledWith(
Expand Down Expand Up @@ -227,51 +194,51 @@ describe('TokenBottomSheet', () => {
const searchInput = getByPlaceholderText('tokenBottomSheet.searchAssets')
expect(searchInput).toBeTruthy()

expect(getByTestId('cUSDTouchable')).toBeTruthy()
expect(getByTestId('cEURTouchable')).toBeTruthy()
expect(getByTestId('TTTouchable')).toBeTruthy()
expect(getByTestId(`TokenBalanceItemTouchable/${mockCusdTokenId}`)).toBeTruthy()
expect(getByTestId(`TokenBalanceItemTouchable/${mockCeurTokenId}`)).toBeTruthy()
expect(getByTestId(`TokenBalanceItemTouchable/${mockTestTokenTokenId}`)).toBeTruthy()

fireEvent.changeText(searchInput, 'Celo')
// Wait for the analytics debounce
jest.advanceTimersByTime(DEBOUCE_WAIT_TIME)
jest.advanceTimersByTime(DEBOUNCE_WAIT_TIME)

expect(ValoraAnalytics.track).toBeCalledTimes(1)
expect(ValoraAnalytics.track).toHaveBeenCalledWith(TokenBottomSheetEvents.search_token, {
origin: TokenPickerOrigin.Send,
searchInput: 'Celo',
})

expect(getByTestId('cUSDTouchable')).toBeTruthy()
expect(getByTestId('cEURTouchable')).toBeTruthy()
expect(queryByTestId('TTTouchable')).toBeNull()
expect(getByTestId(`TokenBalanceItemTouchable/${mockCusdTokenId}`)).toBeTruthy()
expect(getByTestId(`TokenBalanceItemTouchable/${mockCeurTokenId}`)).toBeTruthy()
expect(queryByTestId(`TokenBalanceItemTouchable/${mockTestTokenTokenId}`)).toBeNull()

fireEvent.changeText(searchInput, 'Test')
// Wait for the analytics debounce
jest.advanceTimersByTime(DEBOUCE_WAIT_TIME)
jest.advanceTimersByTime(DEBOUNCE_WAIT_TIME)

expect(ValoraAnalytics.track).toBeCalledTimes(2)
expect(ValoraAnalytics.track).toHaveBeenCalledWith(TokenBottomSheetEvents.search_token, {
origin: TokenPickerOrigin.Send,
searchInput: 'Test',
})

expect(queryByTestId('cUSDTouchable')).toBeNull()
expect(queryByTestId('cEURTouchable')).toBeNull()
expect(getByTestId('TTTouchable')).toBeTruthy()
expect(queryByTestId(`TokenBalanceItemTouchable/${mockCusdTokenId}`)).toBeNull()
expect(queryByTestId(`TokenBalanceItemTouchable/${mockCeurTokenId}`)).toBeNull()
expect(getByTestId(`TokenBalanceItemTouchable/${mockTestTokenTokenId}`)).toBeTruthy()

fireEvent.changeText(searchInput, 'Usd')
// Wait for the analytics debounce
jest.advanceTimersByTime(DEBOUCE_WAIT_TIME)
jest.advanceTimersByTime(DEBOUNCE_WAIT_TIME)

expect(ValoraAnalytics.track).toBeCalledTimes(3)
expect(ValoraAnalytics.track).toHaveBeenCalledWith(TokenBottomSheetEvents.search_token, {
origin: TokenPickerOrigin.Send,
searchInput: 'Usd',
})

expect(getByTestId('cUSDTouchable')).toBeTruthy()
expect(queryByTestId('cEURTouchable')).toBeNull()
expect(queryByTestId('TTTouchable')).toBeNull()
expect(getByTestId(`TokenBalanceItemTouchable/${mockCusdTokenId}`)).toBeTruthy()
expect(queryByTestId(`TokenBalanceItemTouchable/${mockCeurTokenId}`)).toBeNull()
expect(queryByTestId(`TokenBalanceItemTouchable/${mockTestTokenTokenId}`)).toBeNull()
})

it('renders and applies a filter', () => {
Expand All @@ -284,7 +251,6 @@ describe('TokenBottomSheet', () => {
isSelected: false,
},
],
TokenOptionComponent: TokenBalanceItemOption,
tokens,
})

Expand All @@ -305,7 +271,6 @@ describe('TokenBottomSheet', () => {
}
const { getByText, getAllByTestId } = renderBottomSheet({
filterChips: [fitler],
TokenOptionComponent: TokenBalanceItemOption,
tokens,
})

Expand All @@ -328,7 +293,6 @@ describe('TokenBottomSheet', () => {
const { getByPlaceholderText, getAllByTestId } = renderBottomSheet({
filterChips: [fitler],
searchEnabled: true,
TokenOptionComponent: TokenBalanceItemOption,
tokens,
areSwapTokensShuffled: true,
origin: TokenPickerOrigin.SwapFrom,
Expand All @@ -342,7 +306,7 @@ describe('TokenBottomSheet', () => {
fireEvent.changeText(getByPlaceholderText('tokenBottomSheet.searchAssets'), 'Celo')

// Wait for the analytics debounce
jest.advanceTimersByTime(DEBOUCE_WAIT_TIME)
jest.advanceTimersByTime(DEBOUNCE_WAIT_TIME)

expect(getAllByTestId('TokenBalanceItem')).toHaveLength(1)
expect(getAllByTestId('TokenBalanceItem')[0]).toHaveTextContent('Celo Dollar')
Expand All @@ -367,7 +331,7 @@ describe('TokenBottomSheet', () => {
fireEvent.changeText(searchInput, 'TemporaryInput')
fireEvent.changeText(searchInput, 'FinalInput')
// Wait for the analytics debounce
jest.advanceTimersByTime(DEBOUCE_WAIT_TIME)
jest.advanceTimersByTime(DEBOUNCE_WAIT_TIME)

expect(ValoraAnalytics.track).toBeCalledTimes(1)
// We don't send events for intermediate search inputs
Expand Down
101 changes: 6 additions & 95 deletions src/components/TokenBottomSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ import FilterChipsCarousel, {
isNetworkChip,
} from 'src/components/FilterChipsCarousel'
import SearchInput from 'src/components/SearchInput'
import TokenDisplay from 'src/components/TokenDisplay'
import TokenIcon, { IconSize } from 'src/components/TokenIcon'
import Touchable from 'src/components/Touchable'
import NetworkMultiSelectBottomSheet from 'src/components/multiSelect/NetworkMultiSelectBottomSheet'
import InfoIcon from 'src/icons/InfoIcon'
import colors, { Colors } from 'src/styles/colors'
Expand All @@ -35,7 +32,7 @@ export enum TokenPickerOrigin {
SwapTo = 'Swap/To',
}

export const DEBOUCE_WAIT_TIME = 200
export const DEBOUNCE_WAIT_TIME = 200

export interface TokenBottomSheetProps<T extends TokenBalance> {
forwardedRef: RefObject<BottomSheetRefType>
Expand All @@ -59,57 +56,6 @@ interface TokenOptionProps {
showPriceUsdUnavailableWarning?: boolean
}

/**
* @deprecated new bottom sheets should use TokenBalanceItemOption
*/
const TokenOption = React.memo(({ tokenInfo, onPress, index }: TokenOptionProps) => {
return (
<>
{index > 0 && <View style={styles.separator} />}
<Touchable onPress={onPress} testID={`${tokenInfo.symbol}Touchable`}>
<View style={styles.tokenOptionContainer}>
<TokenIcon token={tokenInfo} viewStyle={styles.tokenImage} size={IconSize.LARGE} />
<View style={styles.tokenNameContainer}>
<Text style={styles.localBalance}>{tokenInfo.symbol}</Text>
<Text style={styles.currencyBalance}>{tokenInfo.name}</Text>
</View>
<View style={styles.tokenBalanceContainer}>
<TokenDisplay
style={styles.localBalance}
amount={tokenInfo.balance}
tokenId={tokenInfo.tokenId}
showLocalAmount={true}
testID={`Local${tokenInfo.symbol}Balance`}
/>
<TokenDisplay
style={styles.currencyBalance}
amount={tokenInfo.balance}
tokenId={tokenInfo.tokenId}
showLocalAmount={false}
testID={`${tokenInfo.symbol}Balance`}
/>
</View>
</View>
</Touchable>
</>
)
})

export const TokenBalanceItemOption = React.memo(
({ tokenInfo, onPress, showPriceUsdUnavailableWarning }: TokenOptionProps) => {
const { t } = useTranslation()
return (
<TokenBalanceItem
token={tokenInfo}
balanceUsdErrorFallback={t('tokenDetails.priceUnavailable') ?? undefined}
onPress={onPress}
containerStyle={styles.tokenBalanceItemContainer}
showPriceUsdUnavailableWarning={showPriceUsdUnavailableWarning}
/>
)
}
)

function NoResults({
testID = 'TokenBottomSheet/NoResult',
searchTerm,
Expand Down Expand Up @@ -150,7 +96,6 @@ function TokenBottomSheet<T extends TokenBalance>({
searchEnabled,
title,
titleStyle,
TokenOptionComponent = TokenOption,
showPriceUsdUnavailableWarning,
filterChips = [],
areSwapTokensShuffled,
Expand Down Expand Up @@ -232,7 +177,7 @@ function TokenBottomSheet<T extends TokenBalance>({
origin,
searchInput,
})
}, DEBOUCE_WAIT_TIME),
}, DEBOUNCE_WAIT_TIME),
[]
)

Expand Down Expand Up @@ -298,10 +243,11 @@ function TokenBottomSheet<T extends TokenBalance>({
scrollIndicatorInsets={{ top: headerHeight }}
renderItem={({ item, index }) => {
return (
<TokenOptionComponent
tokenInfo={item}
<TokenBalanceItem
token={item}
balanceUsdErrorFallback={t('tokenDetails.priceUnavailable') ?? undefined}
onPress={onTokenPressed(item, index)}
index={index}
containerStyle={styles.tokenBalanceItemContainer}
showPriceUsdUnavailableWarning={showPriceUsdUnavailableWarning}
/>
)
Expand Down Expand Up @@ -373,41 +319,6 @@ const styles = StyleSheet.create({
container: {
flex: 1,
},
tokenOptionContainer: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: Spacing.Regular16,
},
tokenImage: {
width: 40,
height: 40,
borderRadius: 20,
marginRight: Spacing.Small12,
},
tokenNameContainer: {
flex: 3,
alignItems: 'flex-start',
flexShrink: 1,
},
tokenBalanceContainer: {
flex: 2,
flexShrink: 1,
alignItems: 'flex-end',
},
localBalance: {
flexShrink: 1,
...typeScale.labelMedium,
},
currencyBalance: {
flexShrink: 1,
...typeScale.bodySmall,
color: colors.gray4,
},
separator: {
width: '100%',
height: 1,
backgroundColor: colors.gray2,
},
searchInput: {
marginTop: Spacing.Regular16,
},
Expand Down
6 changes: 1 addition & 5 deletions src/send/EnterAmount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ import KeyboardAwareScrollView from 'src/components/KeyboardAwareScrollView'
import KeyboardSpacer from 'src/components/KeyboardSpacer'
import SkeletonPlaceholder from 'src/components/SkeletonPlaceholder'
import TextInput from 'src/components/TextInput'
import TokenBottomSheet, {
TokenBalanceItemOption,
TokenPickerOrigin,
} from 'src/components/TokenBottomSheet'
import TokenBottomSheet, { TokenPickerOrigin } from 'src/components/TokenBottomSheet'
import TokenDisplay from 'src/components/TokenDisplay'
import TokenIcon, { IconSize } from 'src/components/TokenIcon'
import Touchable from 'src/components/Touchable'
Expand Down Expand Up @@ -459,7 +456,6 @@ function EnterAmount({
onTokenSelected={onSelectToken}
tokens={tokens}
title={t('sendEnterAmountScreen.selectToken')}
TokenOptionComponent={TokenBalanceItemOption}
titleStyle={styles.title}
/>
</SafeAreaView>
Expand Down
12 changes: 4 additions & 8 deletions src/swap/SwapScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ import BottomSheet, { BottomSheetRefType } from 'src/components/BottomSheet'
import Button, { BtnSizes, BtnTypes } from 'src/components/Button'
import InLineNotification, { NotificationVariant } from 'src/components/InLineNotification'
import Toast from 'src/components/Toast'
import TokenBottomSheet, {
TokenBalanceItemOption,
TokenPickerOrigin,
} from 'src/components/TokenBottomSheet'
import TokenBottomSheet, { TokenPickerOrigin } from 'src/components/TokenBottomSheet'
import Touchable from 'src/components/Touchable'
import CustomHeader from 'src/components/header/CustomHeader'
import { SWAP_LEARN_MORE } from 'src/config'
import { FiatExchangeFlow } from 'src/fiatExchanges/utils'
import CircledIcon from 'src/icons/CircledIcon'
import DownIndicator from 'src/icons/DownIndicator'
import { getLocalCurrencyCode } from 'src/localCurrency/selectors'
import { navigate } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
Expand Down Expand Up @@ -57,9 +57,6 @@ import { getFeeCurrencyAndAmounts } from 'src/viem/prepareTransactions'
import { getSerializablePreparedTransactions } from 'src/viem/preparedTransactionSerialization'
import networkConfig from 'src/web3/networkConfig'
import { v4 as uuidv4 } from 'uuid'
import DownIndicator from 'src/icons/DownIndicator'
import CircledIcon from 'src/icons/CircledIcon'
import Touchable from 'src/components/Touchable'

const TAG = 'SwapScreen'

Expand Down Expand Up @@ -868,7 +865,6 @@ export function SwapScreen({ route }: Props) {
snapPoints={['90%']}
onTokenSelected={handleSelectToken}
searchEnabled={true}
TokenOptionComponent={TokenBalanceItemOption}
showPriceUsdUnavailableWarning={true}
areSwapTokensShuffled={areSwapTokensShuffled}
/>
Expand Down

0 comments on commit 76082c3

Please sign in to comment.