diff --git a/locales/base/translation.json b/locales/base/translation.json index e4133a82740..53148e23ec7 100644 --- a/locales/base/translation.json +++ b/locales/base/translation.json @@ -1847,7 +1847,8 @@ "tokens": "Tokens", "collectibles": "Collectibles", "dappPositions": "Dapp Positions" - } + }, + "importToken": "Import" }, "notificationCenterSpotlight": { "message": "Introducing a new way to claim rewards, view alerts, and see updates in one place", diff --git a/src/statsig/constants.ts b/src/statsig/constants.ts index 3cd5bb2fc98..001220bf103 100644 --- a/src/statsig/constants.ts +++ b/src/statsig/constants.ts @@ -42,6 +42,7 @@ export const FeatureGates = { [StatsigFeatureGates.USE_VIEM_FOR_WALLETCONNECT_TRANSACTIONS]: false, [StatsigFeatureGates.USE_NEW_RECIPIENT_SCREEN]: false, [StatsigFeatureGates.USE_NEW_SEND_FLOW]: false, + [StatsigFeatureGates.SHOW_IMPORT_TOKENS_FLOW]: false, [StatsigFeatureGates.SHOW_HIDE_HOME_BALANCES_TOGGLE]: false, } diff --git a/src/statsig/types.ts b/src/statsig/types.ts index 3f64bb6b55c..df4fa977643 100644 --- a/src/statsig/types.ts +++ b/src/statsig/types.ts @@ -40,6 +40,7 @@ export enum StatsigFeatureGates { USE_VIEM_FOR_WALLETCONNECT_TRANSACTIONS = 'use_viem_for_walletconnect_transactions', USE_NEW_RECIPIENT_SCREEN = 'use_new_recipient_screen', USE_NEW_SEND_FLOW = 'use_new_send_flow', + SHOW_IMPORT_TOKENS_FLOW = 'show_import_tokens_flow', SHOW_HIDE_HOME_BALANCES_TOGGLE = 'show_hide_home_balances_toggle', } diff --git a/src/tokens/Assets.test.tsx b/src/tokens/Assets.test.tsx index bcdcf58352e..ff310cef4a6 100644 --- a/src/tokens/Assets.test.tsx +++ b/src/tokens/Assets.test.tsx @@ -2,7 +2,7 @@ import { fireEvent, render } from '@testing-library/react-native' import * as React from 'react' import { Provider } from 'react-redux' import ValoraAnalytics from 'src/analytics/ValoraAnalytics' -import { navigate } from 'src/navigator/NavigationService' +import { navigate, navigateBack } from 'src/navigator/NavigationService' import { Screens } from 'src/navigator/Screens' import { getDynamicConfigParams, getFeatureGate } from 'src/statsig' import { StatsigFeatureGates } from 'src/statsig/types' @@ -99,6 +99,7 @@ const storeWithNfts = { describe('AssetsScreen', () => { beforeEach(() => { jest.clearAllMocks() + jest.mocked(getFeatureGate).mockRestore() }) it('renders tokens and collectibles tabs when positions is disabled', () => { @@ -336,6 +337,40 @@ describe('AssetsScreen', () => { expect(navigate).toHaveBeenCalledWith(Screens.DappShortcutsRewards) }) + it('does not render Import Token when feature flag is off', () => { + const store = createMockStore(storeWithPositions) + + const component = ( + + + + ) + const { queryByText } = render(component) + const button = queryByText('assets.importToken') + + expect(button).toBeNull() + }) + + it('clicking Import Token opens a screen', () => { + jest + .mocked(getFeatureGate) + .mockImplementation( + (gate: StatsigFeatureGates) => gate === StatsigFeatureGates.SHOW_IMPORT_TOKENS_FLOW + ) + const store = createMockStore(storeWithPositions) + + const component = ( + + + + ) + const { getByText } = render(component) + const button = getByText('assets.importToken') + fireEvent.press(button) + + expect(navigateBack).toHaveBeenCalled() + }) + it('displays tokens with balance and ones marked with showZeroBalance in the expected order', () => { jest.mocked(getDynamicConfigParams).mockReturnValueOnce({ showBalances: [NetworkId['celo-alfajores'], NetworkId['ethereum-sepolia']], diff --git a/src/tokens/Assets.tsx b/src/tokens/Assets.tsx index 76fbeebde68..69c0a1952c3 100644 --- a/src/tokens/Assets.tsx +++ b/src/tokens/Assets.tsx @@ -1,6 +1,6 @@ import { NativeStackScreenProps } from '@react-navigation/native-stack' import BigNumber from 'bignumber.js' -import React, { useMemo, useState } from 'react' +import React, { useLayoutEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { LayoutChangeEvent, @@ -27,9 +27,10 @@ import ImageErrorIcon from 'src/icons/ImageErrorIcon' import { useDollarsToLocalAmount } from 'src/localCurrency/hooks' import { getLocalCurrencySymbol } from 'src/localCurrency/selectors' import { headerWithBackButton } from 'src/navigator/Headers' -import { navigate } from 'src/navigator/NavigationService' +import { navigate, navigateBack } from 'src/navigator/NavigationService' import { Screens } from 'src/navigator/Screens' import useScrollAwareHeader from 'src/navigator/ScrollAwareHeader' +import { TopBarTextButton } from 'src/navigator/TopBarButton' import { StackParamList } from 'src/navigator/types' import NftMedia from 'src/nfts/NftMedia' import NftsLoadError from 'src/nfts/NftsLoadError' @@ -221,6 +222,19 @@ function AssetsScreen({ navigation, route }: Props) { } }, [footerPosition.value]) + useLayoutEffect(() => { + navigation.setOptions({ + headerRight: () => + getFeatureGate(StatsigFeatureGates.SHOW_IMPORT_TOKENS_FLOW) && ( + + ), + }) + }, [navigation]) + useScrollAwareHeader({ navigation, title: t('totalAssets'), @@ -572,6 +586,10 @@ const styles = StyleSheet.create({ ...typeScale.labelMedium, color: Colors.dark, }, + topBarTextButton: { + ...typeScale.bodyMedium, + paddingRight: Spacing.Smallest8, + }, nftsPairingContainer: { flexDirection: 'row', gap: Spacing.Regular16,