Skip to content

Commit

Permalink
Merge branch 'main' into fix/confirmation-ui-adjustments
Browse files Browse the repository at this point in the history
  • Loading branch information
OGPoyraz authored Sep 11, 2024
2 parents bc3bb76 + 1b6959f commit 0e1787f
Show file tree
Hide file tree
Showing 27 changed files with 774 additions and 181 deletions.
2 changes: 2 additions & 0 deletions app/components/UI/NetworkModal/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface NetworkProps {
navigation: any;
shouldNetworkSwitchPopToWallet: boolean;
onNetworkSwitch?: () => void;
showPopularNetworkModal: boolean;
}

jest.mock('react-redux', () => ({
Expand All @@ -36,6 +37,7 @@ describe('NetworkDetails', () => {
},
navigation: 'navigation',
shouldNetworkSwitchPopToWallet: true,
showPopularNetworkModal: true,
};
it('renders correctly', () => {
(useSelector as jest.MockedFn<typeof useSelector>).mockImplementation(
Expand Down
51 changes: 40 additions & 11 deletions app/components/UI/NetworkModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ import checkSafeNetwork from '../../../core/RPCMethods/networkChecker.util';
import NetworkVerificationInfo from '../NetworkVerificationInfo';
import createNetworkModalStyles from './index.styles';
import { useMetrics } from '../../../components/hooks/useMetrics';
import { toHex } from '@metamask/controller-utils';
import { rpcIdentifierUtility } from '../../../components/hooks/useSafeChains';
import Logger from '../../../util/Logger';

export interface SafeChain {
chainId: string;
name: string;
nativeCurrency: { symbol: string };
rpc: string[];
}

interface NetworkProps {
isVisible: boolean;
Expand All @@ -45,6 +55,8 @@ interface NetworkProps {
navigation: any;
shouldNetworkSwitchPopToWallet: boolean;
onNetworkSwitch?: () => void;
showPopularNetworkModal: boolean;
safeChains?: SafeChain[];
}

const NetworkModals = (props: NetworkProps) => {
Expand All @@ -60,8 +72,10 @@ const NetworkModals = (props: NetworkProps) => {
formattedRpcUrl,
rpcPrefs: { blockExplorerUrl, imageUrl },
},
showPopularNetworkModal,
shouldNetworkSwitchPopToWallet,
onNetworkSwitch,
safeChains,
} = props;
const { trackEvent } = useMetrics();
const [showDetails, setShowDetails] = React.useState(false);
Expand Down Expand Up @@ -90,9 +104,33 @@ const NetworkModals = (props: NetworkProps) => {
};

const addNetwork = async () => {
const validUrl = validateRpcUrl(rpcUrl);
const isValidUrl = validateRpcUrl(rpcUrl);
if (showPopularNetworkModal) {
// emit popular network
trackEvent(MetaMetricsEvents.NETWORK_ADDED, {
chain_id: toHex(chainId),
source: 'Popular network list',
symbol: ticker,
});
} else if (safeChains) {
const { safeChain, safeRPCUrl } = rpcIdentifierUtility(
rpcUrl,
safeChains,
);
// emit custom network, this shouldn't be in popular networks modal
trackEvent(MetaMetricsEvents.NETWORK_ADDED, {
chain_id: toHex(safeChain.chainId),
source: 'Custom Network Added',
symbol: safeChain.nativeCurrency.symbol,
sensitiveProperties: {
rpcUrl: safeRPCUrl,
},
});
} else {
Logger.log('MetaMetrics - Unable to capture custom network');
}

setNetworkAdded(validUrl);
setNetworkAdded(isValidUrl);
};

const cancelButtonProps: ButtonProps = {
Expand Down Expand Up @@ -188,15 +226,6 @@ const NetworkModals = (props: NetworkProps) => {
source: 'ignored',
},
);

const analyticsParamsAdd = {
chain_id: getDecimalChainId(chainId),
source: 'Popular network list',
symbol: ticker,
};

trackEvent(MetaMetricsEvents.NETWORK_ADDED, analyticsParamsAdd);

closeModal();
if (onNetworkSwitch) {
onNetworkSwitch();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { StyleSheet } from 'react-native';

const styleSheet = () =>
StyleSheet.create({
networkItemContainer: {
flexDirection: 'row',
alignItems: 'center',
padding: 10,
},
networkAvatar: {
marginHorizontal: 10,
},
networkName: {
flex: 1,
fontSize: 16,
},
networkList: { marginHorizontal: 6 },
});

export default styleSheet;
114 changes: 114 additions & 0 deletions app/components/UI/NetworkSelectorList/NetworkSelectorList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Third party dependencies.
import React, { useCallback, useRef } from 'react';
import { ListRenderItem, ImageSourcePropType } from 'react-native';
import { FlatList } from 'react-native-gesture-handler';

// External dependencies.
import { useStyles } from '../../../component-library/hooks';
import {
AvatarSize,
AvatarVariant,
} from '../../../component-library/components/Avatars/Avatar';
import Cell, {
CellVariant,
} from '../../../component-library/components/Cells/Cell';

// Internal dependencies.
import {
NetworkConnectMultiSelectorProps,
Network,
} from './NetworkSelectorList.types';
import styleSheet from './NetworkSelectorList.styles';

const NetworkSelectorList = ({
onSelectNetwork,
networks = [],
isLoading = false,
selectedNetworkIds,
isMultiSelect = true,
renderRightAccessory,
isSelectionDisabled,
isAutoScrollEnabled = true,
...props
}: NetworkConnectMultiSelectorProps) => {
const networksLengthRef = useRef<number>(0);
const { styles } = useStyles(styleSheet, {});

/**
* Ref for the FlatList component.
* The type of the ref is not explicitly defined.
*/
// TODO: Replace "any" with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const networkListRef = useRef<any>(null);

const getKeyExtractor = ({ id }: Network) => id;

const renderNetworkItem: ListRenderItem<Network> = useCallback(
({ item: { id, name, isSelected, imageSource } }) => {
const isDisabled = isLoading || isSelectionDisabled;
const cellVariant = isMultiSelect
? CellVariant.MultiSelect
: CellVariant.Select;
let isSelectedNetwork = isSelected;
if (selectedNetworkIds) {
isSelectedNetwork = selectedNetworkIds.includes(id);
}

return (
<Cell
variant={cellVariant}
isSelected={isSelectedNetwork}
title={name}
onPress={() => onSelectNetwork?.(id, isSelectedNetwork)}
avatarProps={{
variant: AvatarVariant.Network,
name,
imageSource: imageSource as ImageSourcePropType,
size: AvatarSize.Sm,
}}
disabled={isDisabled}
style={styles.networkItemContainer}
>
{renderRightAccessory?.(id, name)}
</Cell>
);
},
[
isLoading,
selectedNetworkIds,
renderRightAccessory,
isSelectionDisabled,
onSelectNetwork,
styles,
isMultiSelect,
],
);

const onContentSizeChanged = useCallback(() => {
if (!networks.length || !isAutoScrollEnabled) return;
if (networksLengthRef.current !== networks.length) {
const selectedNetwork = networks.find(({ isSelected }) => isSelected);
networkListRef?.current?.scrollToOffset({
offset: selectedNetwork?.yOffset ?? 0,
animated: false,
});
networksLengthRef.current = networks.length;
}
}, [networks, isAutoScrollEnabled]);

return (
<FlatList
style={styles.networkList}
ref={networkListRef}
onContentSizeChange={onContentSizeChanged}
data={networks}
keyExtractor={getKeyExtractor}
renderItem={renderNetworkItem}
initialNumToRender={999}
{...props}
/>
);
};

export default NetworkSelectorList;
20 changes: 20 additions & 0 deletions app/components/UI/NetworkSelectorList/NetworkSelectorList.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ImageSourcePropType } from 'react-native';
export interface Network {
id: string;
name: string;
rpcUrl: string;
isSelected: boolean;
yOffset?: number;
imageSource: ImageSourcePropType;
}

export interface NetworkConnectMultiSelectorProps {
onSelectNetwork?: (id: string, isSelected: boolean) => void;
networks?: Network[];
isLoading?: boolean;
selectedNetworkIds?: string[];
isMultiSelect?: boolean;
renderRightAccessory?: (id: string, name: string) => React.ReactNode;
isSelectionDisabled?: boolean;
isAutoScrollEnabled?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ function NetworkSwitcher() {
shouldNetworkSwitchPopToWallet={false}
customNetworksList={rampNetworksDetails}
showCompletionMessage={false}
showPopularNetworkModal
displayContinue
/>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ const AccountConnectMultiSelector = ({
<View style={styles.disconnectAllContainer}>
<View style={styles.helpTextContainer}>
<HelpText severity={HelpTextSeverity.Error}>
{strings('accounts.disconnect_you_from', {
{strings('common.disconnect_you_from', {
dappUrl: hostname,
})}
</HelpText>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ exports[`AccountPermissionsConfirmRevokeAll renders correctly 1`] = `
}
}
>
If you disconnect your accounts from test, you’ll need to reconnect to use them again.
If you disconnect from test, you’ll need to reconnect your accounts and networks to use this site again.
</Text>
</View>
<View
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { StyleSheet } from 'react-native';
import { isMutichainVersion1Enabled } from '../../../../util/networks';

const styleSheet = () =>
StyleSheet.create({
bottomSheetContainer: {
height: '100%',
},
bodyContainer: {
paddingHorizontal: 16,
},
buttonsContainer: {
marginTop: isMutichainVersion1Enabled ? 0 : 24,
marginBottom: 16,
},
updateButtonContainer: { flexDirection: 'row' },
buttonPositioning: { flex: 1 },
disabledOpacity: {
opacity: 0.5,
},
selectAllContainer: {
marginLeft: 0,
marginVertical: 12,
},
disconnectAll: {
flexDirection: 'column',
alignItems: 'center',
},
helpText: {
margin: 16,
},
disconnectAllButton: {
flexDirection: 'row',
},
});

export default styleSheet;
Loading

0 comments on commit 0e1787f

Please sign in to comment.