Skip to content

Commit

Permalink
fix: create nft auto detection modal and remove nft polling logic
Browse files Browse the repository at this point in the history
  • Loading branch information
sahar-fehri committed Jun 5, 2024
1 parent da288b5 commit 72d4c1b
Show file tree
Hide file tree
Showing 14 changed files with 481 additions and 68 deletions.
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;
isNFTAutoDetectionModalOpened: boolean;
// 'null' represents the user not having set his preference over dataCollectionForMarketing yet
dataCollectionForMarketing: boolean | null;
}
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 @@ -689,6 +690,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
18 changes: 17 additions & 1 deletion 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,
isNftFetchingInProgressSelector,
} from '../../../reducers/collectibles';
import { removeFavoriteCollectible } from '../../../actions/collectibles';
import Text from '../../Base/Text';
Expand Down Expand Up @@ -86,6 +88,9 @@ const createStyles = (colors) =>
marginBottom: 8,
fontSize: 14,
},
spinner: {
marginBottom: 8,
},
});

/**
Expand All @@ -99,6 +104,7 @@ const CollectibleContracts = ({
navigation,
collectibleContracts,
collectibles: allCollectibles,
isNftFetchingInProgress,
favoriteCollectibles,
removeFavoriteCollectible,
useNftDetection,
Expand Down Expand Up @@ -244,6 +250,10 @@ const CollectibleContracts = ({
const renderFooter = useCallback(
() => (
<View style={styles.footer} key={'collectible-contracts-footer'}>
{isNftFetchingInProgress.isFetchingInProgress ? (
<ActivityIndicator size="large" style={styles.spinner} />
) : null}

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

const renderCollectibleContract = useCallback(
Expand Down Expand Up @@ -421,6 +431,11 @@ CollectibleContracts.propTypes = {
* the Asset detail view
*/
navigation: PropTypes.object,
/**
* NftFetching object to indicate if
* we are still fetching nfts in the background.
*/
isNftFetchingInProgress: PropTypes.object,
/**
* Object of collectibles
*/
Expand Down Expand Up @@ -450,6 +465,7 @@ const mapStateToProps = (state) => ({
useNftDetection: selectUseNftDetection(state),
collectibleContracts: collectibleContractsSelector(state),
collectibles: collectiblesSelector(state),
isNftFetchingInProgress: isNftFetchingInProgressSelector(state),
favoriteCollectibles: favoritesCollectiblesSelector(state),
isIpfsGatewayEnabled: selectIsIpfsGatewayEnabled(state),
displayNftMedia: selectDisplayNftMedia(state),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { StyleSheet } from 'react-native';

/**
* Style sheet function for NFT auto detection modal component.
*
* @returns StyleSheet object.
*/
const styleSheet = () =>
StyleSheet.create({
container: {
alignItems: 'center',
},
image: {
width: 219,
height: 219,
},
description: {
marginLeft: 32,
marginRight: 32,
},
buttonsContainer: {
paddingTop: 24,
marginLeft: 16,
marginRight: 16,
},
spacer: { height: 8 },
});

export default styleSheet;
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* eslint-disable no-console */

import React, { useRef } from 'react';
import BottomSheet, {
BottomSheetRef,
} from '../../../component-library/components/BottomSheets/BottomSheet';
import { strings } from '../../../../locales/i18n';
import { useStyles } from '../../../component-library/hooks';
import styleSheet from './NFTAutoDetectionModal.styles';
import SheetHeader from '../../../component-library/components/Sheet/SheetHeader';
import Text from '../../../component-library/components/Texts/Text';
import { View, Image } from 'react-native';

import Button, {
ButtonSize,
ButtonVariants,
ButtonWidthTypes,
} from '../../../component-library/components/Buttons/Button';
import { useNavigation } from '@react-navigation/native';
import Engine from '../../../core/Engine';

const NFTAutoDetectionModal = () => {
const { styles } = useStyles(styleSheet, {});
const sheetRef = useRef<BottomSheetRef>(null);
const walletImage = require('../../../images/wallet-alpha.png'); // eslint-disable-line
const navigation = useNavigation();
const dismissModal = (): void => {
if (sheetRef?.current) {
sheetRef.current.onCloseBottomSheet();
} else {
navigation.goBack();
}
};

const enableNftDetectionAndDismissModal = (): void => {
const { PreferencesController } = Engine.context;
PreferencesController.setUseNftDetection(true);
dismissModal();
};

return (
<BottomSheet ref={sheetRef}>
<SheetHeader title={strings('enable_nft-auto-detection.title')} />
<View>
<View style={styles.container}>
<Image source={walletImage} style={styles.image} />
</View>
<View style={styles.description}>
<Text>{strings('enable_nft-auto-detection.description')}</Text>

<Text>{strings('enable_nft-auto-detection.immediateAccess')}</Text>
<Text>{strings('enable_nft-auto-detection.navigate')}</Text>
<Text>{strings('enable_nft-auto-detection.dive')}</Text>
</View>
<View style={styles.buttonsContainer}>
<Button
variant={ButtonVariants.Primary}
size={ButtonSize.Lg}
width={ButtonWidthTypes.Full}
label={strings('enable_nft-auto-detection.allow')}
onPress={enableNftDetectionAndDismissModal}
/>
<View style={styles.spacer} />

<Button
variant={ButtonVariants.Link}
size={ButtonSize.Lg}
width={ButtonWidthTypes.Full}
label={strings('enable_nft-auto-detection.notRightNow')}
onPress={dismissModal}
//onPress={() => sheetRef.current?.onCloseBottomSheet()}
/>
</View>
</View>
</BottomSheet>
);
};

export default NFTAutoDetectionModal;
33 changes: 26 additions & 7 deletions app/components/Views/Wallet/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
Linking,
} from 'react-native';
import type { Theme } from '@metamask/design-tokens';
import { connect, useSelector } from 'react-redux';
import { connect, useDispatch, useSelector } from 'react-redux';
import ScrollableTabView from 'react-native-scrollable-tab-view';
import DefaultTabBar from 'react-native-scrollable-tab-view/DefaultTabBar';
import { baseStyles } from '../../../styles/common';
Expand Down Expand Up @@ -70,6 +70,8 @@ import { RootState } from '../../../reducers';
import usePrevious from '../../hooks/usePrevious';
import { selectSelectedInternalAccountChecksummedAddress } from '../../../selectors/accountsController';
import { selectAccountBalanceByChainId } from '../../../selectors/accountTrackerController';
import { selectUseNftDetection } from '../../../selectors/preferencesController';
import { setNftAutoDetectionModalOpen } from '../../../actions/security';

const createStyles = ({ colors, typography }: Theme) =>
StyleSheet.create({
Expand Down Expand Up @@ -126,6 +128,7 @@ const Wallet = ({
const { trackEvent } = useMetrics();
const styles = createStyles(theme);
const { colors } = theme;
const dispatch = useDispatch();

/**
* Object containing the balance of the current selected account
Expand Down Expand Up @@ -246,6 +249,10 @@ const Wallet = ({
const networkName = useSelector(selectNetworkName);

const networkImageSource = useSelector(selectNetworkImageSource);
const useNftDetection = useSelector(selectUseNftDetection);
const isNFTAutoDetectionModalOpened = useSelector(
(state: any) => state.security.isNFTAutoDetectionModalOpened,
);

/**
* Callback to trigger when pressing the navigation title.
Expand All @@ -259,6 +266,19 @@ const Wallet = ({
});
}, [navigate, providerConfig.chainId, trackEvent]);

const checkNftAutoDetectionModal = () => {
if (!useNftDetection && !isNFTAutoDetectionModalOpened) {
navigation.navigate(Routes.MODAL.ROOT_MODAL_FLOW, {
screen: Routes.MODAL.NFT_AUTO_DETECTION_MODAL,
});
dispatch(setNftAutoDetectionModalOpen(true));
}
};

useEffect(() => {
checkNftAutoDetectionModal();
});

/**
* Check to see if we need to show What's New modal and Smart Transactions Opt In modal
*/
Expand Down Expand Up @@ -328,13 +348,9 @@ const Wallet = ({
useEffect(
() => {
requestAnimationFrame(async () => {
const {
TokenDetectionController,
NftDetectionController,
AccountTrackerController,
} = Engine.context as any;
const { TokenDetectionController, AccountTrackerController } =
Engine.context as any;
TokenDetectionController.detectTokens();
NftDetectionController.detectNfts();
AccountTrackerController.refresh();
});
},
Expand Down Expand Up @@ -388,6 +404,9 @@ const Wallet = ({
trackEvent(MetaMetricsEvents.WALLET_TOKENS);
} else {
trackEvent(MetaMetricsEvents.WALLET_COLLECTIBLES);
// Call detect nfts
const { NftDetectionController } = Engine.context as any;
NftDetectionController.detectNfts();
}
},
[trackEvent],
Expand Down
1 change: 1 addition & 0 deletions app/constants/navigation/Routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const Routes = {
DETECTED_TOKENS: 'DetectedTokens',
SRP_REVEAL_QUIZ: 'SRPRevealQuiz',
WALLET_ACTIONS: 'WalletActions',
NFT_AUTO_DETECTION_MODAL: 'NFTAutoDetectionModal',
},
ONBOARDING: {
ROOT_NAV: 'OnboardingRootNav',
Expand Down
6 changes: 3 additions & 3 deletions app/core/Engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ class Engine {
ipfsGateway: AppConstants.IPFS_DEFAULT_GATEWAY_URL,
useTokenDetection:
initialState?.PreferencesController?.useTokenDetection ?? true,
useNftDetection: false,
useNftDetection: true, // set this to true to enable nft detection by default to new users
displayNftMedia: true,
securityAlertsEnabled: true,
...initialState.PreferencesController,
Expand Down Expand Up @@ -1187,6 +1187,8 @@ class Engine {
chainId: networkController.state.providerConfig.chainId,
getOpenSeaApiKey: () => nftController.openSeaApiKey,
addNft: nftController.addNft.bind(nftController),
updateNftFetchingProgressStatus:
nftController.updateNftFetchingProgressStatus.bind(nftController),
getNftApi: nftController.getNftApi.bind(nftController),
getNftState: () => nftController.state,
//@ts-expect-error - Network Controller mismatch version
Expand Down Expand Up @@ -1454,7 +1456,6 @@ class Engine {
AccountTrackerController,
AssetsContractController,
TokenDetectionController,
NftDetectionController,
NetworkController,
TransactionController,
SwapsController,
Expand All @@ -1479,7 +1480,6 @@ class Engine {
});
TransactionController.hub.emit('networkChange');
TokenDetectionController.detectTokens();
NftDetectionController.detectNfts();
AccountTrackerController.refresh();
}

Expand Down
Binary file added app/images/wallet-alpha.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 72d4c1b

Please sign in to comment.