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

chore: Convert token sort ActionSheet to BottomSheet #11853

Open
wants to merge 87 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
0248c74
feat: Add sortAssets utility function
gambinish Sep 27, 2024
6a2e8c7
chore: Breakup monolithic Tokens/index.tsx into smaller components
gambinish Sep 27, 2024
7a78717
fix: Correctly handle null check for buyable footer button
gambinish Sep 27, 2024
57295ee
fix: Tweak boolean logic for rendering footer components
gambinish Sep 27, 2024
d00354f
chore: Update snapshot
gambinish Sep 27, 2024
be87f81
chore: Type out tokens as TokenI[]
gambinish Sep 27, 2024
68c7b2e
chore: Remove unecessary comments around import statements in Networt…
gambinish Sep 27, 2024
a02e139
Merge branch 'main' into chore/componetize-tokens-screen
gambinish Sep 27, 2024
de5bbed
Merge branch 'main' into chore/componetize-tokens-screen
gambinish Sep 27, 2024
0fd9ad5
Merge branch 'main' into chore/componetize-tokens-screen
gambinish Sep 27, 2024
032618c
chore: Add unit tests to utility file, provide exports from index file
gambinish Sep 30, 2024
a58f1ba
chore: Rename handleBalance to me more descriptive of what its logic …
gambinish Sep 30, 2024
1dd31e3
chore: rename Networth to PortfolioBalance for clarity
gambinish Sep 30, 2024
16ded6a
chore: Cleanup styles extra whitespace
gambinish Sep 30, 2024
52d3d85
Merge branch 'main' into chore/componetize-tokens-screen
gambinish Sep 30, 2024
dd3ffdf
fix: Update snapshot tests
gambinish Sep 30, 2024
da640bc
Merge branch 'chore/componetize-tokens-screen' of github.com:MetaMask…
gambinish Sep 30, 2024
ebcbcf6
fix: Remove unused component
gambinish Sep 30, 2024
31fad19
Merge branch 'main' into chore/componetize-tokens-screen
gambinish Sep 30, 2024
4a8d927
chore: Move PotfolioBalance above TabView
gambinish Oct 1, 2024
a7b4c17
fix: Wrap PortfolioBalance and ScrollableView in fragment for token r…
gambinish Oct 1, 2024
658fcf6
fix: Padding tweak below tab bar for consistency of token list
gambinish Oct 1, 2024
18035d4
fix: Reorganize test suite for PortfolioBalance
gambinish Oct 1, 2024
c570c2c
fix: Revert changes to wallet test
gambinish Oct 1, 2024
a97128b
fix: Update fiatBalance text style to DisplayMD
gambinish Oct 1, 2024
8036a0a
chore: Patch PreferencesController with tokenSortConfig
gambinish Oct 1, 2024
1f0ac51
chore: Patch preferences controller with type
gambinish Oct 1, 2024
34d987c
feat: Build token sorting UI, patch PreferencesController
gambinish Oct 4, 2024
d57558b
chore: Merge main, address merge conflicts
gambinish Oct 7, 2024
c5c954c
fix: ListHeaderComponent not needed in FlatList anymore
gambinish Oct 7, 2024
4f635e8
fix: Update snapshots and lint
gambinish Oct 7, 2024
469270a
chore: Merge develop, address conflicts
gambinish Oct 8, 2024
82eb1a2
chore: Remove destructive index
gambinish Oct 9, 2024
f18b820
Merge branch 'main' into feat/mmassets_357-sort-import-tokens-mobile-…
gambinish Oct 10, 2024
d3a79fc
chore: Merge main, address conflicts
gambinish Oct 10, 2024
5fc979c
chore: Repatch preferences controller with tokenSortConfig
gambinish Oct 10, 2024
2890148
fix: Declning balance sort
gambinish Oct 10, 2024
25a7238
fix: Export raw value from deriveBalanceFromAssetMarketDetails
gambinish Oct 10, 2024
6637303
fix: deriveBalanceFromAssetMarketDetails.test.ts
gambinish Oct 10, 2024
0415b73
fix: Update unit tests and snapshots
gambinish Oct 10, 2024
ff32cc4
fix: Lint unused imports from Tokens/index.tsx
gambinish Oct 10, 2024
f4f2519
chore: Update testIds and locale strings
gambinish Oct 11, 2024
bd61eff
fix: Update WalletView import selector
gambinish Oct 11, 2024
f28b6fe
fix: Update snapshots
gambinish Oct 11, 2024
7c9d5cc
chore: Cleanup
gambinish Oct 11, 2024
e747848
fix: Add navigation type
gambinish Oct 11, 2024
71ce22f
fix: fix snapshot
salimtb Oct 11, 2024
6aa6f3f
Merge branch 'main' into feat/mmassets_357-sort-import-tokens-mobile-…
salimtb Oct 15, 2024
fe21f40
chore: Update snapshots
gambinish Oct 15, 2024
6f52163
Merge branch 'feat/mmassets_357-sort-import-tokens-mobile--reorg-port…
gambinish Oct 15, 2024
579f012
fix: Update placeholders in switch statement
gambinish Oct 15, 2024
68338a3
Merge branch 'feat/mmassets_357-sort-import-tokens-mobile--token-sort…
gambinish Oct 15, 2024
ff95c72
chore: Add additional e2e test for import token footer link
gambinish Oct 15, 2024
1d929ce
chore: Update snapshots
gambinish Oct 15, 2024
a926d64
fix: Break out of switch statement rather than returning arbitrary st…
gambinish Oct 16, 2024
d3c5d81
chore: Init BottomSheet refactor
gambinish Oct 16, 2024
e925da3
fix: Remove arbitrary 8 second delays from import-tokens.spec
gambinish Oct 16, 2024
0c9ca35
fix: Use ButtonBase component to customize button text color more dir…
gambinish Oct 16, 2024
63bb1a2
fix: Update snapshot
gambinish Oct 16, 2024
a5d8b71
fix: Mock initial state that PortfolioBalance component needs
gambinish Oct 16, 2024
0b617f2
fix: Mock tabs in snapshot
gambinish Oct 16, 2024
96436be
fix: Consider Error boundary during Wallet rendering process
gambinish Oct 16, 2024
1365f4d
fix: Update localized string
gambinish Oct 16, 2024
bd9ad0d
Merge branch 'feat/mmassets_357-sort-import-tokens-mobile--reorg-port…
gambinish Oct 16, 2024
da5862d
Merge branch 'main' into feat/mmassets_357-sort-import-tokens-mobile-…
gambinish Oct 17, 2024
c0a28bc
Merge branch 'feat/mmassets_357-sort-import-tokens-mobile--reorg-port…
gambinish Oct 17, 2024
2934811
Merge branch 'main' into feat/mmassets_357-sort-import-tokens-mobile-…
gambinish Oct 17, 2024
8cb67f7
Merge branch 'feat/mmassets_357-sort-import-tokens-mobile--reorg-port…
gambinish Oct 17, 2024
990067f
Merge branch 'main' into feat/mmassets_357-sort-import-tokens-mobile-…
gambinish Oct 17, 2024
1f5ad7f
chore: Add TokenSortBottomSheet to RootModalFlow in Routes
gambinish Oct 17, 2024
e5b060e
fix: Resolve upstream conflicts
gambinish Oct 17, 2024
c057c24
fix: Lint:tsc
gambinish Oct 17, 2024
4e9f8d9
fix: Lint
gambinish Oct 17, 2024
319706d
chore: Init unit tests for new UI
gambinish Oct 18, 2024
dd3de6f
chore: Merge main, address conflicts
gambinish Oct 23, 2024
e8b22c4
fix: Add test for refresh control on tokens screen
gambinish Oct 23, 2024
d5a41ba
chore: Update testID selectors for token list
gambinish Oct 23, 2024
ce983b8
chore: Add tokenSort BottomSheet trigger test
gambinish Oct 23, 2024
931b122
chore: Lint
gambinish Oct 23, 2024
3fd170f
fix: Update snapshots
gambinish Oct 23, 2024
0d00f62
chore: TokenSortBottomSheet unit tests
gambinish Oct 23, 2024
784c39f
chore: Cleanup
gambinish Oct 23, 2024
6a4a64e
chore: Cleanup, and queryByTestID for test stability
gambinish Oct 23, 2024
1dfd1bf
chore: More cleanup
gambinish Oct 23, 2024
0fe13d9
fix: Lint
gambinish Oct 24, 2024
321743e
chore: Use ListItemSelect rather than Cellbase to avoid component lib…
gambinish Oct 25, 2024
48c7a3f
fix: Lint
gambinish Oct 25, 2024
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
5 changes: 5 additions & 0 deletions app/components/Nav/App/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import Toast, {
ToastContext,
} from '../../../component-library/components/Toast';
import AccountSelector from '../../../components/Views/AccountSelector';
import TokenSortBottomSheet from '../../../components/UI/Tokens/TokensBottomSheet/TokenSortBottomSheet.tsx';
import AccountConnect from '../../../components/Views/AccountConnect';
import AccountPermissions from '../../../components/Views/AccountPermissions';
import { AccountPermissionsScreens } from '../../../components/Views/AccountPermissions/AccountPermissions.types';
Expand Down Expand Up @@ -422,6 +423,10 @@ const RootModalFlow = () => (
name={Routes.SHEET.NETWORK_SELECTOR}
component={NetworkSelector}
/>
<Stack.Screen
name={Routes.SHEET.TOKEN_SORT}
component={TokenSortBottomSheet}
/>
<Stack.Screen
name={Routes.SHEET.BASIC_FUNCTIONALITY}
component={BasicFunctionalityModal}
Expand Down
2 changes: 2 additions & 0 deletions app/components/UI/Tokens/TokenList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { TokenI } from '../types';
import { strings } from '../../../../../locales/i18n';
import { TokenListFooter } from './TokenListFooter';
import { TokenListItem } from './TokenListItem';
import { WalletViewSelectorsIDs } from '../../../../../e2e/selectors/wallet/WalletView.selectors';

interface TokenListProps {
tokens: TokenI[];
Expand Down Expand Up @@ -71,6 +72,7 @@ export const TokenList = ({

return tokens?.length ? (
<FlatList
testID={WalletViewSelectorsIDs.TOKENS_CONTAINER_LIST}
data={tokens}
renderItem={({ item }) => (
<TokenListItem
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import React from 'react';
import { render, fireEvent, waitFor } from '@testing-library/react-native';
import TokenSortBottomSheet from './TokenSortBottomSheet';
import { useSelector } from 'react-redux';
import Engine from '../../../../core/Engine';
import { selectTokenSortConfig } from '../../../../selectors/preferencesController';
import { selectCurrentCurrency } from '../../../../selectors/currencyRateController';
import { WalletViewSelectorsIDs } from '../../../../../e2e/selectors/wallet/WalletView.selectors';

jest.mock('react-redux', () => ({
useSelector: jest.fn(),
}));

jest.mock('../../../../util/theme', () => ({
useTheme: jest.fn(),
}));

jest.mock('../../../../core/Engine', () => ({
context: {
PreferencesController: {
setTokenSortConfig: jest.fn(),
},
},
}));

jest.mock('@react-navigation/native', () => {
const reactNavigationModule = jest.requireActual('@react-navigation/native');
return {
...reactNavigationModule,
useNavigation: () => ({
navigate: jest.fn(),
}),
};
});

jest.mock('react-native-safe-area-context', () => {
// copied from BottomSheetDialog.test.tsx
const inset = { top: 1, right: 2, bottom: 3, left: 4 };
const frame = { width: 5, height: 6, x: 7, y: 8 };
return {
SafeAreaProvider: jest.fn().mockImplementation(({ children }) => children),
SafeAreaConsumer: jest
.fn()
.mockImplementation(({ children }) => children(inset)),
useSafeAreaInsets: jest.fn().mockImplementation(() => inset),
useSafeAreaFrame: jest.fn().mockImplementation(() => frame),
};
});

describe('TokenSortBottomSheet', () => {
beforeEach(() => {
(useSelector as jest.Mock).mockImplementation((selector) => {
if (selector === selectTokenSortConfig) {
return {
key: 'tokenFiatAmount',
order: 'dsc',
sortCallback: 'stringNumeric',
}; // Default token sort config
} else if (selector === selectCurrentCurrency) {
return 'USD';
}
return null;
});
});

afterEach(() => {
jest.clearAllMocks();
});

it('renders correctly with the default sort option selected', () => {
const { queryByTestId } = render(<TokenSortBottomSheet />);

expect(queryByTestId(WalletViewSelectorsIDs.SORT_BY)).toBeTruthy();
expect(
queryByTestId(WalletViewSelectorsIDs.SORT_DECLINING_BALANCE),
).toBeTruthy();
expect(
queryByTestId(WalletViewSelectorsIDs.SORT_ALPHABETICAL),
).toBeTruthy();
});

it('triggers PreferencesController to sort by token fiat amount when first cell is pressed', async () => {
const { queryByTestId } = render(<TokenSortBottomSheet />);

fireEvent.press(
queryByTestId(WalletViewSelectorsIDs.SORT_DECLINING_BALANCE),
);

await waitFor(() => {
expect(
Engine.context.PreferencesController.setTokenSortConfig,
).toHaveBeenCalledWith({
key: 'tokenFiatAmount',
order: 'dsc',
sortCallback: 'stringNumeric',
});
});
});

it('triggers PreferencesController to sort alphabetically when the second cell is pressed', async () => {
const { queryByTestId } = render(<TokenSortBottomSheet />);

fireEvent.press(queryByTestId(WalletViewSelectorsIDs.SORT_ALPHABETICAL));

await waitFor(() => {
expect(
Engine.context.PreferencesController.setTokenSortConfig,
).toHaveBeenCalledWith({
key: 'symbol',
sortCallback: 'alphaNumeric',
order: 'asc',
});
});
});

it('displays the correct selection based on tokenSortConfig', () => {
(useSelector as jest.Mock).mockImplementation((selector) => {
if (selector === selectTokenSortConfig) {
return { key: 'symbol', order: 'dsc', sortCallback: 'stringNumeric' };
}
return null;
});

const { queryByTestId } = render(<TokenSortBottomSheet />);

expect(
queryByTestId(WalletViewSelectorsIDs.SORT_ALPHABETICAL),
).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import React from 'react';
import { View } from 'react-native';
import { useSelector } from 'react-redux';
import { useTheme } from '../../../../util/theme';
import Engine from '../../../../core/Engine';
import createStyles from '../styles';
import { strings } from '../../../../../locales/i18n';
import { selectTokenSortConfig } from '../../../../selectors/preferencesController';
import { selectCurrentCurrency } from '../../../../selectors/currencyRateController';
import BottomSheet from '../../../../component-library/components/BottomSheets/BottomSheet';
import Text, {
TextVariant,
} from '../../../../component-library/components/Texts/Text';
import currencySymbols from '../../../../util/currency-symbols.json';
import { WalletViewSelectorsIDs } from '../../../../../e2e/selectors/wallet/WalletView.selectors';
import ListItemSelect from '../../../../component-library/components/List/ListItemSelect';
import { VerticalAlignment } from '../../../../component-library/components/List/ListItem';

const TokenSortBottomSheet = () => {
const { colors } = useTheme();
const styles = createStyles(colors);

const tokenSortConfig = useSelector(selectTokenSortConfig);
const currentCurrency = useSelector(selectCurrentCurrency);

const onSortControlsBottomSheetPress = (index: number) => {
const { PreferencesController } = Engine.context;
switch (index) {
case 0:
PreferencesController.setTokenSortConfig({
key: 'tokenFiatAmount',
order: 'dsc',
sortCallback: 'stringNumeric',
});
break;
case 1:
PreferencesController.setTokenSortConfig({
key: 'symbol',
sortCallback: 'alphaNumeric',
order: 'asc',
});
break;
default:
break;
}
};

return (
<BottomSheet shouldNavigateBack>
<View style={styles.bottomSheetWrapper}>
<Text
testID={WalletViewSelectorsIDs.SORT_BY}
variant={TextVariant.HeadingMD}
style={styles.bottomSheetTitle}
>
{strings('wallet.sort_by')}
</Text>
<ListItemSelect
testID={WalletViewSelectorsIDs.SORT_DECLINING_BALANCE}
onPress={() => onSortControlsBottomSheetPress(0)}
isSelected={tokenSortConfig.key === 'tokenFiatAmount'}
isDisabled={false}
gap={8}
verticalAlignment={VerticalAlignment.Center}
>
<Text style={styles.bottomSheetText}>
{strings('wallet.declining_balance', {
currency:
currencySymbols[
currentCurrency as keyof typeof currencySymbols
] ?? currentCurrency,
})}
</Text>
</ListItemSelect>
<ListItemSelect
testID={WalletViewSelectorsIDs.SORT_ALPHABETICAL}
onPress={() => onSortControlsBottomSheetPress(1)}
isSelected={tokenSortConfig.key !== 'tokenFiatAmount'}
isDisabled={false}
gap={8}
verticalAlignment={VerticalAlignment.Center}
>
<Text style={styles.bottomSheetText}>
{strings('wallet.alphabetically')}
</Text>
</ListItemSelect>
</View>
</BottomSheet>
);
};

export default TokenSortBottomSheet;
8 changes: 8 additions & 0 deletions app/components/UI/Tokens/TokensBottomSheet/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Routes from '../../../../constants/navigation/Routes';
import { createNavigationDetails } from '../../../../util/navigation/navUtils';

export const createTokensBottomSheetNavDetails = createNavigationDetails(
Routes.MODAL.ROOT_MODAL_FLOW,
Routes.SHEET.TOKEN_SORT,
);
export { default } from './TokenSortBottomSheet';
3 changes: 3 additions & 0 deletions app/components/UI/Tokens/__snapshots__/index.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ exports[`Tokens should hide zero balance tokens when setting is on 1`] = `
renderItem={[Function]}
scrollEventThrottle={50}
stickyHeaderIndices={[]}
testID="token-list"
viewabilityConfigCallbackPairs={[]}
>
<RCTRefreshControl />
Expand Down Expand Up @@ -1746,6 +1747,7 @@ exports[`Tokens should render correctly 1`] = `
renderItem={[Function]}
scrollEventThrottle={50}
stickyHeaderIndices={[]}
testID="token-list"
viewabilityConfigCallbackPairs={[]}
>
<RCTRefreshControl />
Expand Down Expand Up @@ -3005,6 +3007,7 @@ exports[`Tokens should show all balance tokens when hideZeroBalanceTokens settin
renderItem={[Function]}
scrollEventThrottle={50}
stickyHeaderIndices={[]}
testID="token-list"
viewabilityConfigCallbackPairs={[]}
>
<RCTRefreshControl />
Expand Down
Loading
Loading