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

fix: create nft auto detection modal and remove nft polling logic #9857

Merged
merged 58 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
e0abc2e
fix: create nft auto detection modal and remove nft polling logic
sahar-fehri Jun 5, 2024
45f2cfc
fix: fix patch
sahar-fehri Jun 10, 2024
66be754
fix: fix
sahar-fehri Jun 10, 2024
de5c3fc
fix: fix
sahar-fehri Jun 10, 2024
d1a0702
fix: fix
sahar-fehri Jun 10, 2024
d9d6299
fix: fix
sahar-fehri Jun 10, 2024
e8eee4a
fix: fix
sahar-fehri Jun 10, 2024
f655a98
fix: fix
sahar-fehri Jun 10, 2024
a01ecaf
fix: fix
sahar-fehri Jun 10, 2024
dc031a2
fix: fix test
sahar-fehri Jun 10, 2024
f4a1226
fix: test
sahar-fehri Jun 10, 2024
e8088d2
empty commit
sahar-fehri Jun 10, 2024
400f465
Revert "fix: test"
sahar-fehri Jun 10, 2024
72948df
fix: revert and re-apply changes
sahar-fehri Jun 10, 2024
24c6caa
fix: update test
sahar-fehri Jun 10, 2024
c061bab
fix: lint
sahar-fehri Jun 10, 2024
c034ed5
fix: e2e
sahar-fehri Jun 10, 2024
93905b6
fix: fix
sahar-fehri Jun 10, 2024
b3132c8
Merge branch 'main' into feat/call-nft-detection-on-components
sahar-fehri Jun 10, 2024
00840bf
Merge branch 'main' into feat/call-nft-detection-on-components
sahar-fehri Jun 12, 2024
99b69c4
fix: patch new core changes and update collectible component
sahar-fehri Jun 12, 2024
d63a0fa
fix: add new toast for in nft banner
sahar-fehri Jun 14, 2024
1b6e966
empty commit
sahar-fehri Jun 14, 2024
dfaf2cc
fix: conflicts
sahar-fehri Jun 14, 2024
ad32b83
fix: fix snapshot
sahar-fehri Jun 14, 2024
df9067f
fix: fix
sahar-fehri Jun 14, 2024
9f3342c
fix: lint
sahar-fehri Jun 14, 2024
239e6cf
fix: show nft modal only on mainnet and enable displayNftMedia before…
sahar-fehri Jun 14, 2024
a567689
fix: lint
sahar-fehri Jun 14, 2024
29f261b
fix: update e2e tests
sahar-fehri Jun 18, 2024
98d1813
fix: update e2e tests
sahar-fehri Jun 18, 2024
bf1b5ec
fix: update e2e tests
sahar-fehri Jun 18, 2024
1f293f4
Merge branch 'main' into feat/call-nft-detection-on-components
sahar-fehri Jun 18, 2024
8927f1a
fix: update e2e tests
sahar-fehri Jun 18, 2024
b33f2c2
fix: update e2e tests
sahar-fehri Jun 19, 2024
a2f4b0c
fix: minor review fix
sahar-fehri Jun 19, 2024
a55e54f
fix: minor review fix
sahar-fehri Jun 19, 2024
0577595
fix: lint
sahar-fehri Jun 19, 2024
808f3ef
Merge branch 'main' into feat/call-nft-detection-on-components
sahar-fehri Jun 19, 2024
e43a345
fix: update e2e
sahar-fehri Jun 19, 2024
6872a33
fix: merge conflicts
sahar-fehri Jun 21, 2024
6261d87
chore: New Crowdin translations by Github Action (#9777)
metamaskbot Jun 21, 2024
6cb43c2
fix: merge conflicts
sahar-fehri Jun 21, 2024
6a1cbed
fix: merge conflicts and catch errs
sahar-fehri Jun 21, 2024
31000b8
fix: lint
sahar-fehri Jun 21, 2024
06d7fc9
fix: fix
sahar-fehri Jun 21, 2024
9b011d4
fix: fix lint
sahar-fehri Jun 21, 2024
fc8733e
fix: fix
sahar-fehri Jun 23, 2024
972300d
Merge branch 'main' into feat/call-nft-detection-on-components
sahar-fehri Jun 24, 2024
23b765a
fix: minor review changes
sahar-fehri Jun 24, 2024
8768c67
fix: refactor
sahar-fehri Jun 24, 2024
082add9
fix: fix
sahar-fehri Jun 24, 2024
ab34cc4
Update app/components/UI/CollectibleContracts/index.test.tsx
NicolasMassart Jun 24, 2024
c68584a
fix: fix types
sahar-fehri Jun 25, 2024
82710fa
fix: fix types
sahar-fehri Jun 25, 2024
9e69501
fix: fix lint
sahar-fehri Jun 25, 2024
deb5a4a
fix: update test type
sahar-fehri Jun 25, 2024
899d714
fix: refactor test name
sahar-fehri Jun 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
16 changes: 15 additions & 1 deletion app/actions/security/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export enum ActionType {
USER_SELECTED_AUTOMATIC_SECURITY_CHECKS_OPTION = 'USER_SELECTED_AUTOMATIC_SECURITY_CHECKS_OPTION',
SET_AUTOMATIC_SECURITY_CHECKS_MODAL_OPEN = 'SET_AUTOMATIC_SECURITY_CHECKS_MODAL_OPEN',
SET_DATA_COLLECTION_FOR_MARKETING = 'SET_DATA_COLLECTION_FOR_MARKETING',
SET_NFT_AUTO_DETECTION_MODAL_OPEN = 'SET_NFT_AUTO_DETECTION_MODAL_OPEN',
}

export interface AllowLoginWithRememberMeUpdated
Expand All @@ -29,6 +30,11 @@ export interface SetAutomaticSecurityChecksModalOpen
open: boolean;
}

export interface SetNftAutoDetectionModalOpen
extends ReduxAction<ActionType.SET_NFT_AUTO_DETECTION_MODAL_OPEN> {
open: boolean;
}

export interface SetDataCollectionForMarketing
extends ReduxAction<ActionType.SET_DATA_COLLECTION_FOR_MARKETING> {
enabled: boolean;
Expand All @@ -39,7 +45,8 @@ export type Action =
| AutomaticSecurityChecks
| UserSelectedAutomaticSecurityChecksOptions
| SetAutomaticSecurityChecksModalOpen
| SetDataCollectionForMarketing;
| SetDataCollectionForMarketing
| SetNftAutoDetectionModalOpen;

export const setAllowLoginWithRememberMe = (
enabled: boolean,
Expand Down Expand Up @@ -68,6 +75,13 @@ export const setAutomaticSecurityChecksModalOpen = (
open,
});

export const setNftAutoDetectionModalOpen = (
open: boolean,
): SetNftAutoDetectionModalOpen => ({
type: ActionType.SET_NFT_AUTO_DETECTION_MODAL_OPEN,
open,
});

export const setDataCollectionForMarketing = (enabled: boolean) => ({
type: ActionType.SET_DATA_COLLECTION_FOR_MARKETING,
enabled,
Expand Down
1 change: 1 addition & 0 deletions app/actions/security/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export interface SecuritySettingsState {
automaticSecurityChecksEnabled: boolean;
hasUserSelectedAutomaticSecurityCheckOption: boolean;
isAutomaticSecurityChecksModalOpen: boolean;
isNFTAutoDetectionModalViewed: boolean;
// 'null' represents the user not having set his preference over dataCollectionForMarketing yet
dataCollectionForMarketing: boolean | null;
}
12 changes: 12 additions & 0 deletions app/component-library/components/Toast/Toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,18 @@ const Toast = forwardRef((_, ref: React.ForwardedRef<ToastRef>) => {
/>
);
}
case ToastVariants.Icon: {
const { iconName, iconColor, backgroundColor } = toastOptions;
return (
<Avatar
variant={AvatarVariant.Icon}
name={iconName}
iconColor={iconColor}
backgroundColor={backgroundColor}
style={styles.avatar}
/>
);
}
}
};

Expand Down
11 changes: 10 additions & 1 deletion app/component-library/components/Toast/Toast.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export enum ToastVariants {
Plain = 'Plain',
Account = 'Account',
Network = 'Network',
Icon = 'Icon',
}

/**
Expand Down Expand Up @@ -65,13 +66,21 @@ interface NetworkToastOption extends BaseToastVariants {
networkImageSource: ImageSourcePropType;
}

interface IconToastOption extends BaseToastVariants {
variant: ToastVariants.Icon;
iconName?: string;
iconColor?: string;
backgroundColor?: string;
}

/**
* Different toast options combined in a union type.
*/
export type ToastOptions =
| PlainToastOption
| AccountToastOption
| NetworkToastOption;
| NetworkToastOption
| IconToastOption;

/**
* Toast component reference.
Expand Down
5 changes: 5 additions & 0 deletions app/components/Nav/App/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ import OnboardingSuccess from '../../Views/OnboardingSuccess';
import DefaultSettings from '../../Views/OnboardingSuccess/DefaultSettings';
import BasicFunctionalityModal from '../../UI/BasicFunctionality/BasicFunctionalityModal/BasicFunctionalityModal';
import SmartTransactionsOptInModal from '../../Views/SmartTransactionsOptInModal/SmartTranactionsOptInModal';
import NFTAutoDetectionModal from '../../../../app/components/Views/NFTAutoDetectionModal/NFTAutoDetectionModal';

const clearStackNavigatorOptions = {
headerShown: false,
Expand Down Expand Up @@ -693,6 +694,10 @@ const App = ({ userLoggedIn }) => {
name={Routes.SHEET.SHOW_NFT_DISPLAY_MEDIA}
component={ShowDisplayNftMediaSheet}
/>
<Stack.Screen
name={Routes.MODAL.NFT_AUTO_DETECTION_MODAL}
component={NFTAutoDetectionModal}
/>
</Stack.Navigator>
);

Expand Down
5 changes: 2 additions & 3 deletions app/components/UI/CollectibleContracts/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
const RefreshTestId = 'refreshControl';

export default RefreshTestId;
export const RefreshTestId = 'refreshControl';
export const SpinnerTestId = 'spinner';
30 changes: 24 additions & 6 deletions app/components/UI/CollectibleContracts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
Platform,
FlatList,
RefreshControl,
ActivityIndicator,
} from 'react-native';
import { connect } from 'react-redux';
import { fontStyles } from '../../../styles/common';
Expand All @@ -19,6 +20,7 @@ import {
collectibleContractsSelector,
collectiblesSelector,
favoritesCollectiblesSelector,
isNftFetchingProgressSelector,
} from '../../../reducers/collectibles';
import { removeFavoriteCollectible } from '../../../actions/collectibles';
import Text from '../../Base/Text';
Expand All @@ -44,7 +46,7 @@ import {
NFT_TAB_CONTAINER_ID,
} from '../../../../wdio/screen-objects/testIDs/Screens/WalletView.testIds';
import { useMetrics } from '../../../components/hooks/useMetrics';
import RefreshTestId from './constants';
import { RefreshTestId, SpinnerTestId } from './constants';

const createStyles = (colors) =>
StyleSheet.create({
Expand Down Expand Up @@ -87,6 +89,9 @@ const createStyles = (colors) =>
marginBottom: 8,
fontSize: 14,
},
spinner: {
marginBottom: 8,
},
});

/**
Expand All @@ -100,6 +105,7 @@ const CollectibleContracts = ({
navigation,
collectibleContracts,
collectibles: allCollectibles,
isNftFetchingProgress,
favoriteCollectibles,
removeFavoriteCollectible,
useNftDetection,
Expand Down Expand Up @@ -219,6 +225,14 @@ const CollectibleContracts = ({
const renderFooter = useCallback(
() => (
<View style={styles.footer} key={'collectible-contracts-footer'}>
{isNftFetchingProgress ? (
<ActivityIndicator
size="large"
style={styles.spinner}
testID={SpinnerTestId}
/>
) : null}

<Text style={styles.emptyText}>
{strings('wallet.no_collectibles')}
</Text>
Expand All @@ -233,7 +247,7 @@ const CollectibleContracts = ({
</TouchableOpacity>
</View>
),
[goToAddCollectible, isAddNFTEnabled, styles],
[goToAddCollectible, isAddNFTEnabled, styles, isNftFetchingProgress],
);

const renderCollectibleContract = useCallback(
Expand Down Expand Up @@ -282,7 +296,7 @@ const CollectibleContracts = ({
NftDetectionController.detectNfts(),
NftController.checkAndUpdateAllNftsOwnershipStatus(),
];
await Promise.all(actions);
await Promise.allSettled(actions);
setRefreshing(false);
});
}, [setRefreshing]);
Expand Down Expand Up @@ -322,7 +336,7 @@ const CollectibleContracts = ({
<>
{isCollectionDetectionBannerVisible && (
<View style={styles.emptyView}>
<CollectibleDetectionModal navigation={navigation} />
<CollectibleDetectionModal />
</View>
)}
{renderFavoriteCollectibles()}
Expand Down Expand Up @@ -355,7 +369,6 @@ const CollectibleContracts = ({
renderFooter,
renderEmpty,
isCollectionDetectionBannerVisible,
navigation,
styles.emptyView,
],
);
Expand Down Expand Up @@ -391,7 +404,11 @@ CollectibleContracts.propTypes = {
* Array of collectibles objects
*/
collectibles: PropTypes.array,

/**
* boolean indicating if fetching status is
* still in progress
*/
isNftFetchingProgress: PropTypes.bool,
/**
* Navigation object required to push
* the Asset detail view
Expand Down Expand Up @@ -426,6 +443,7 @@ const mapStateToProps = (state) => ({
useNftDetection: selectUseNftDetection(state),
collectibleContracts: collectibleContractsSelector(state),
collectibles: collectiblesSelector(state),
isNftFetchingProgress: isNftFetchingProgressSelector(state),
favoriteCollectibles: favoritesCollectiblesSelector(state),
isIpfsGatewayEnabled: selectIsIpfsGatewayEnabled(state),
displayNftMedia: selectDisplayNftMedia(state),
Expand Down
120 changes: 120 additions & 0 deletions app/components/UI/CollectibleContracts/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -495,4 +495,124 @@ describe('CollectibleContracts', () => {
expect(spyOnUpdateNftMetadata).toHaveBeenCalledTimes(0);
expect(spyOnDetectNfts).toHaveBeenCalledTimes(1);
});

it('shows spinner if nfts are still being fetched', async () => {
const CURRENT_ACCOUNT = '0x1a';
const mockState = {
collectibles: {
favorites: {},
isNftFetchingProgress: true,
},
engine: {
backgroundState: {
...initialBackgroundState,
NetworkController: {
network: '1',
providerConfig: {
ticker: 'ETH',
type: 'mainnet',
chainId: '1',
},
},
AccountTrackerController: {
accounts: { [CURRENT_ACCOUNT]: { balance: '0' } },
},
PreferencesController: {
useNftDetection: true,
displayNftMedia: true,
selectedAddress: CURRENT_ACCOUNT,
identities: {
[CURRENT_ACCOUNT]: {
address: CURRENT_ACCOUNT,
name: 'Account 1',
},
},
},
NftController: {
addNft: jest.fn(),
updateNftMetadata: jest.fn(),
allNfts: {
[CURRENT_ACCOUNT]: {
'1': [],
},
},
allNftContracts: {
[CURRENT_ACCOUNT]: {
'1': [],
},
},
},
NftDetectionController: {
detectNfts: jest.fn(),
},
},
},
};
const { queryByTestId } = renderWithProvider(<CollectibleContracts />, {
state: mockState,
});

const spinner = queryByTestId('spinner');
expect(spinner).not.toBeNull();
});

it('Does not show spinner if nfts are not still being fetched', async () => {
const CURRENT_ACCOUNT = '0x1a';
const mockState = {
collectibles: {
favorites: {},
},
engine: {
backgroundState: {
...initialBackgroundState,
NetworkController: {
network: '1',
providerConfig: {
ticker: 'ETH',
type: 'mainnet',
chainId: '1',
},
},
AccountTrackerController: {
accounts: { [CURRENT_ACCOUNT]: { balance: '0' } },
},
PreferencesController: {
useNftDetection: true,
displayNftMedia: true,
selectedAddress: CURRENT_ACCOUNT,
identities: {
[CURRENT_ACCOUNT]: {
address: CURRENT_ACCOUNT,
name: 'Account 1',
},
},
},
NftController: {
addNft: jest.fn(),
updateNftMetadata: jest.fn(),
allNfts: {
[CURRENT_ACCOUNT]: {
'1': [],
},
},
allNftContracts: {
[CURRENT_ACCOUNT]: {
'1': [],
},
},
},
NftDetectionController: {
detectNfts: jest.fn(),
},
},
},
};

const { queryByTestId } = renderWithProvider(<CollectibleContracts />, {
state: mockState,
});

const spinner = queryByTestId('spinner');
expect(spinner).toBeNull();
});
});
Loading
Loading