mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-10-22 11:22:43 +02:00
* UX: Multichain: Move location of test networks * Re-add Linea
This commit is contained in:
parent
ecea2d7506
commit
fdac94e361
@ -1,4 +1,4 @@
|
|||||||
import React, { useContext, useEffect, useRef } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
@ -15,8 +15,9 @@ import {
|
|||||||
import { CHAIN_IDS, TEST_CHAINS } from '../../../../shared/constants/network';
|
import { CHAIN_IDS, TEST_CHAINS } from '../../../../shared/constants/network';
|
||||||
import {
|
import {
|
||||||
getShowTestNetworks,
|
getShowTestNetworks,
|
||||||
getAllEnabledNetworks,
|
|
||||||
getCurrentChainId,
|
getCurrentChainId,
|
||||||
|
getNonTestNetworks,
|
||||||
|
getTestNetworks,
|
||||||
} from '../../../selectors';
|
} from '../../../selectors';
|
||||||
import ToggleButton from '../../ui/toggle-button';
|
import ToggleButton from '../../ui/toggle-button';
|
||||||
import {
|
import {
|
||||||
@ -50,7 +51,10 @@ const UNREMOVABLE_CHAIN_IDS = [
|
|||||||
|
|
||||||
export const NetworkListMenu = ({ onClose }) => {
|
export const NetworkListMenu = ({ onClose }) => {
|
||||||
const t = useI18nContext();
|
const t = useI18nContext();
|
||||||
const networks = useSelector(getAllEnabledNetworks);
|
|
||||||
|
const nonTestNetworks = useSelector(getNonTestNetworks);
|
||||||
|
const testNetworks = useSelector(getTestNetworks);
|
||||||
|
|
||||||
const showTestNetworks = useSelector(getShowTestNetworks);
|
const showTestNetworks = useSelector(getShowTestNetworks);
|
||||||
const currentChainId = useSelector(getCurrentChainId);
|
const currentChainId = useSelector(getCurrentChainId);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@ -60,20 +64,61 @@ export const NetworkListMenu = ({ onClose }) => {
|
|||||||
const environmentType = getEnvironmentType();
|
const environmentType = getEnvironmentType();
|
||||||
const isFullScreen = environmentType === ENVIRONMENT_TYPE_FULLSCREEN;
|
const isFullScreen = environmentType === ENVIRONMENT_TYPE_FULLSCREEN;
|
||||||
|
|
||||||
const showTestNetworksRef = useRef(showTestNetworks);
|
|
||||||
const networkListRef = useRef(null);
|
|
||||||
|
|
||||||
const completedOnboarding = useSelector(getCompletedOnboarding);
|
const completedOnboarding = useSelector(getCompletedOnboarding);
|
||||||
|
|
||||||
const lineaMainnetReleased = useSelector(isLineaMainnetNetworkReleased);
|
const lineaMainnetReleased = useSelector(isLineaMainnetNetworkReleased);
|
||||||
|
|
||||||
useEffect(() => {
|
const generateMenuItems = (desiredNetworks) => {
|
||||||
if (showTestNetworks && !showTestNetworksRef.current) {
|
return desiredNetworks.map((network, index) => {
|
||||||
// Scroll to the bottom of the list
|
if (!lineaMainnetReleased && network.providerType === 'linea-mainnet') {
|
||||||
networkListRef.current.lastChild.scrollIntoView();
|
return null;
|
||||||
}
|
}
|
||||||
showTestNetworksRef.current = showTestNetworks;
|
const isCurrentNetwork = currentChainId === network.chainId;
|
||||||
}, [showTestNetworks, showTestNetworksRef]);
|
const canDeleteNetwork =
|
||||||
|
!isCurrentNetwork && !UNREMOVABLE_CHAIN_IDS.includes(network.chainId);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NetworkListItem
|
||||||
|
name={network.nickname}
|
||||||
|
iconSrc={network?.rpcPrefs?.imageUrl}
|
||||||
|
key={`${network.id || network.chainId}-${index}`}
|
||||||
|
selected={isCurrentNetwork}
|
||||||
|
onClick={async () => {
|
||||||
|
dispatch(toggleNetworkMenu());
|
||||||
|
if (network.providerType) {
|
||||||
|
dispatch(setProviderType(network.providerType));
|
||||||
|
} else {
|
||||||
|
dispatch(setActiveNetwork(network.id));
|
||||||
|
}
|
||||||
|
trackEvent({
|
||||||
|
event: MetaMetricsEventName.NavNetworkSwitched,
|
||||||
|
category: MetaMetricsEventCategory.Network,
|
||||||
|
properties: {
|
||||||
|
location: 'Network Menu',
|
||||||
|
chain_id: currentChainId,
|
||||||
|
from_network: currentChainId,
|
||||||
|
to_network: network.id || network.chainId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
onDeleteClick={
|
||||||
|
canDeleteNetwork
|
||||||
|
? () => {
|
||||||
|
dispatch(toggleNetworkMenu());
|
||||||
|
dispatch(
|
||||||
|
showModal({
|
||||||
|
name: 'CONFIRM_DELETE_NETWORK',
|
||||||
|
target: network.id || network.chainId,
|
||||||
|
onConfirm: () => undefined,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover
|
<Popover
|
||||||
@ -83,60 +128,8 @@ export const NetworkListMenu = ({ onClose }) => {
|
|||||||
title={t('networkMenuHeading')}
|
title={t('networkMenuHeading')}
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<Box className="multichain-network-list-menu" ref={networkListRef}>
|
<Box className="multichain-network-list-menu">
|
||||||
{networks.map((network, index) => {
|
{generateMenuItems(nonTestNetworks)}
|
||||||
if (
|
|
||||||
!lineaMainnetReleased &&
|
|
||||||
network.providerType === 'linea-mainnet'
|
|
||||||
) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const isCurrentNetwork = currentChainId === network.chainId;
|
|
||||||
const canDeleteNetwork =
|
|
||||||
!isCurrentNetwork &&
|
|
||||||
!UNREMOVABLE_CHAIN_IDS.includes(network.chainId);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<NetworkListItem
|
|
||||||
name={network.nickname}
|
|
||||||
iconSrc={network?.rpcPrefs?.imageUrl}
|
|
||||||
key={`${network.id || network.chainId}-${index}`}
|
|
||||||
selected={isCurrentNetwork}
|
|
||||||
onClick={async () => {
|
|
||||||
dispatch(toggleNetworkMenu());
|
|
||||||
if (network.providerType) {
|
|
||||||
dispatch(setProviderType(network.providerType));
|
|
||||||
} else {
|
|
||||||
dispatch(setActiveNetwork(network.id));
|
|
||||||
}
|
|
||||||
trackEvent({
|
|
||||||
event: MetaMetricsEventName.NavNetworkSwitched,
|
|
||||||
category: MetaMetricsEventCategory.Network,
|
|
||||||
properties: {
|
|
||||||
location: 'Network Menu',
|
|
||||||
chain_id: currentChainId,
|
|
||||||
from_network: currentChainId,
|
|
||||||
to_network: network.id || network.chainId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
onDeleteClick={
|
|
||||||
canDeleteNetwork
|
|
||||||
? () => {
|
|
||||||
dispatch(toggleNetworkMenu());
|
|
||||||
dispatch(
|
|
||||||
showModal({
|
|
||||||
name: 'CONFIRM_DELETE_NETWORK',
|
|
||||||
target: network.id || network.chainId,
|
|
||||||
onConfirm: () => undefined,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
padding={4}
|
padding={4}
|
||||||
@ -158,6 +151,11 @@ export const NetworkListMenu = ({ onClose }) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
{showTestNetworks ? (
|
||||||
|
<Box className="multichain-network-list-menu">
|
||||||
|
{generateMenuItems(testNetworks)}
|
||||||
|
</Box>
|
||||||
|
) : null}
|
||||||
<Box padding={4}>
|
<Box padding={4}>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
size={BUTTON_SECONDARY_SIZES.LG}
|
size={BUTTON_SECONDARY_SIZES.LG}
|
||||||
|
@ -34,8 +34,8 @@ import {
|
|||||||
CURRENCY_SYMBOLS,
|
CURRENCY_SYMBOLS,
|
||||||
TEST_NETWORK_TICKER_MAP,
|
TEST_NETWORK_TICKER_MAP,
|
||||||
LINEA_GOERLI_TOKEN_IMAGE_URL,
|
LINEA_GOERLI_TOKEN_IMAGE_URL,
|
||||||
LINEA_MAINNET_TOKEN_IMAGE_URL,
|
|
||||||
LINEA_MAINNET_DISPLAY_NAME,
|
LINEA_MAINNET_DISPLAY_NAME,
|
||||||
|
LINEA_MAINNET_TOKEN_IMAGE_URL,
|
||||||
} from '../../shared/constants/network';
|
} from '../../shared/constants/network';
|
||||||
import {
|
import {
|
||||||
WebHIDConnectedStatuses,
|
WebHIDConnectedStatuses,
|
||||||
@ -1176,46 +1176,17 @@ export function getCurrentNetwork(state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getAllEnabledNetworks(state) {
|
export function getAllEnabledNetworks(state) {
|
||||||
|
const nonTestNetworks = getNonTestNetworks(state);
|
||||||
const allNetworks = getAllNetworks(state);
|
const allNetworks = getAllNetworks(state);
|
||||||
const showTestnetNetworks = getShowTestNetworks(state);
|
const showTestnetNetworks = getShowTestNetworks(state);
|
||||||
|
|
||||||
return showTestnetNetworks
|
return showTestnetNetworks ? allNetworks : nonTestNetworks;
|
||||||
? allNetworks
|
|
||||||
: allNetworks.filter(
|
|
||||||
(network) => TEST_CHAINS.includes(network.chainId) === false,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAllNetworks(state) {
|
export function getTestNetworks(state) {
|
||||||
const networkConfigurations = getNetworkConfigurations(state) || {};
|
const networkConfigurations = getNetworkConfigurations(state) || {};
|
||||||
|
|
||||||
const networks = [
|
return [
|
||||||
// Mainnet always first
|
|
||||||
{
|
|
||||||
chainId: CHAIN_IDS.MAINNET,
|
|
||||||
nickname: MAINNET_DISPLAY_NAME,
|
|
||||||
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.MAINNET],
|
|
||||||
rpcPrefs: {
|
|
||||||
imageUrl: ETH_TOKEN_IMAGE_URL,
|
|
||||||
},
|
|
||||||
providerType: NETWORK_TYPES.MAINNET,
|
|
||||||
ticker: CURRENCY_SYMBOLS.ETH,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
chainId: CHAIN_IDS.LINEA_MAINNET,
|
|
||||||
nickname: LINEA_MAINNET_DISPLAY_NAME,
|
|
||||||
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.LINEA_MAINNET],
|
|
||||||
rpcPrefs: {
|
|
||||||
imageUrl: LINEA_MAINNET_TOKEN_IMAGE_URL,
|
|
||||||
},
|
|
||||||
providerType: NETWORK_TYPES.LINEA_MAINNET,
|
|
||||||
ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.LINEA_MAINNET],
|
|
||||||
},
|
|
||||||
// Custom networks added by the user
|
|
||||||
...Object.values(networkConfigurations).filter(
|
|
||||||
({ chainId }) => ![CHAIN_IDS.LOCALHOST].includes(chainId),
|
|
||||||
),
|
|
||||||
// Test networks
|
|
||||||
{
|
{
|
||||||
chainId: CHAIN_IDS.GOERLI,
|
chainId: CHAIN_IDS.GOERLI,
|
||||||
nickname: GOERLI_DISPLAY_NAME,
|
nickname: GOERLI_DISPLAY_NAME,
|
||||||
@ -1245,6 +1216,47 @@ export function getAllNetworks(state) {
|
|||||||
({ chainId }) => chainId === CHAIN_IDS.LOCALHOST,
|
({ chainId }) => chainId === CHAIN_IDS.LOCALHOST,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNonTestNetworks(state) {
|
||||||
|
const networkConfigurations = getNetworkConfigurations(state) || {};
|
||||||
|
|
||||||
|
return [
|
||||||
|
// Mainnet always first
|
||||||
|
{
|
||||||
|
chainId: CHAIN_IDS.MAINNET,
|
||||||
|
nickname: MAINNET_DISPLAY_NAME,
|
||||||
|
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.MAINNET],
|
||||||
|
rpcPrefs: {
|
||||||
|
imageUrl: ETH_TOKEN_IMAGE_URL,
|
||||||
|
},
|
||||||
|
providerType: NETWORK_TYPES.MAINNET,
|
||||||
|
ticker: CURRENCY_SYMBOLS.ETH,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
chainId: CHAIN_IDS.LINEA_MAINNET,
|
||||||
|
nickname: LINEA_MAINNET_DISPLAY_NAME,
|
||||||
|
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.LINEA_MAINNET],
|
||||||
|
rpcPrefs: {
|
||||||
|
imageUrl: LINEA_MAINNET_TOKEN_IMAGE_URL,
|
||||||
|
},
|
||||||
|
providerType: NETWORK_TYPES.LINEA_MAINNET,
|
||||||
|
ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.LINEA_MAINNET],
|
||||||
|
},
|
||||||
|
// Custom networks added by the user
|
||||||
|
...Object.values(networkConfigurations).filter(
|
||||||
|
({ chainId }) => ![CHAIN_IDS.LOCALHOST].includes(chainId),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAllNetworks(state) {
|
||||||
|
const networks = [
|
||||||
|
// Mainnet and custom networks
|
||||||
|
...getNonTestNetworks(state),
|
||||||
|
// Test networks
|
||||||
|
...getTestNetworks(state),
|
||||||
|
];
|
||||||
|
|
||||||
return networks;
|
return networks;
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ describe('Selectors', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('#getAllEnabledNetworks', () => {
|
describe('#getAllEnabledNetworks', () => {
|
||||||
it('returns only MainNet with showTestNetworks off', () => {
|
it('returns only Mainnet and Linea with showTestNetworks off', () => {
|
||||||
const networks = selectors.getAllEnabledNetworks({
|
const networks = selectors.getAllEnabledNetworks({
|
||||||
metamask: {
|
metamask: {
|
||||||
preferences: {
|
preferences: {
|
||||||
|
Loading…
Reference in New Issue
Block a user