mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
UX: Multichain: App header (#18363)
* UX: Multichain: App header * Export app header, provide required information, put feature flag in place * Provide available data * Implement account picker -- centered and opens account popover * Remove backgrounds, use isUnlocked * Fix placement of the global menu * Show logo when unlocked * Add selector for getting current network, provide props to AvatarNetwork and PickerNetwork * Wire up the network menu to the header * fixed ui for all the screens * updated story for header * fixed import and header settings * updated lint error * fixed tests * updated header * removed test * updated snapshot test * updated network menu * updated changes * removed comment from menu bar * updated css * updated test for network list menu * updated stylesheet * updated ButtonIcon import --------- Co-authored-by: NidhiKJha <menidhikjha@gmail.com>
This commit is contained in:
parent
643a89f24d
commit
eb51460cae
@ -208,6 +208,7 @@ browser.runtime.onConnectExternal.addListener(async (...args) => {
|
||||
* @property {boolean} isInitialized - Whether the first vault has been created.
|
||||
* @property {boolean} isUnlocked - Whether the vault is currently decrypted and accounts are available for selection.
|
||||
* @property {boolean} isAccountMenuOpen - Represents whether the main account selection UI is currently displayed.
|
||||
* @property {boolean} isNetworkMenuOpen - Represents whether the main network selection UI is currently displayed.
|
||||
* @property {object} identities - An object matching lower-case hex addresses to Identity objects with "address" and "name" (nickname) keys.
|
||||
* @property {object} unapprovedTxs - An object mapping transaction hashes to unapproved transactions.
|
||||
* @property {object} networkConfigurations - A list of network configurations, containing RPC provider details (eg chainId, rpcUrl, rpcPreferences).
|
||||
|
@ -16,7 +16,6 @@ import { getOriginOfCurrentTab } from '../../../selectors';
|
||||
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||
import { ButtonIcon } from '../../component-library/button-icon/deprecated';
|
||||
import { ICON_NAMES } from '../../component-library/icon/deprecated';
|
||||
import { GlobalMenu } from '../../multichain/global-menu';
|
||||
import AccountOptionsMenu from './account-options-menu';
|
||||
|
||||
export default function MenuBar() {
|
||||
@ -34,7 +33,7 @@ export default function MenuBar() {
|
||||
|
||||
return (
|
||||
<div className="menu-bar">
|
||||
{showStatus ? ( // TODO: Move the connection status menu icon to the correct position in header once we implement the new header
|
||||
{showStatus ? (
|
||||
<ConnectedStatusIndicator
|
||||
onClick={() => history.push(CONNECTED_ACCOUNTS_ROUTE)}
|
||||
/>
|
||||
@ -58,18 +57,12 @@ export default function MenuBar() {
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
{accountOptionsMenuOpen &&
|
||||
(process.env.MULTICHAIN ? (
|
||||
<GlobalMenu
|
||||
anchorElement={ref.current}
|
||||
closeMenu={() => setAccountOptionsMenuOpen(false)}
|
||||
/>
|
||||
) : (
|
||||
{accountOptionsMenuOpen && (
|
||||
<AccountOptionsMenu
|
||||
anchorElement={ref.current}
|
||||
onClose={() => setAccountOptionsMenuOpen(false)}
|
||||
/>
|
||||
))}
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -103,7 +103,6 @@ export const AccountListMenu = ({ onClose }) => {
|
||||
},
|
||||
});
|
||||
dispatch(setSelectedAccount(account.address));
|
||||
onClose();
|
||||
}}
|
||||
identity={account}
|
||||
key={account.address}
|
||||
|
@ -0,0 +1,224 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`App Header should match snapshot 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="box multichain-app-header multichain-app-header-shadow box--display-flex box--flex-direction-row box--align-items-center box--width-full box--background-color-background-default"
|
||||
>
|
||||
<div
|
||||
class="box multichain-app-header__lock-contents box--padding-2 box--display-flex box--gap-2 box--flex-direction-row box--justify-content-space-between box--align-items-center box--width-full box--background-color-background-default"
|
||||
>
|
||||
<button
|
||||
class="box mm-picker-network box--padding-right-4 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--align-items-center box--background-color-background-alternative box--rounded-pill"
|
||||
>
|
||||
<div
|
||||
class="box mm-text mm-avatar-base mm-avatar-base--size-xs mm-avatar-network mm-picker-network__avatar-network mm-text--body-xs mm-text--text-transform-uppercase box--display-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-text-default box--background-color-background-alternative box--rounded-full box--border-color-transparent box--border-style-solid box--border-width-1"
|
||||
>
|
||||
G
|
||||
</div>
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm mm-text--ellipsis box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Goerli
|
||||
</p>
|
||||
<span
|
||||
class="box mm-picker-network__arrow-down-icon mm-icon mm-icon--size-xs box--display-inline-block box--flex-direction-row box--color-icon-default"
|
||||
style="mask-image: url('./images/icons/arrow-down.svg');"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="app-header__logo-container app-header__logo-container--clickable"
|
||||
data-testid="app-header-logo"
|
||||
>
|
||||
<svg
|
||||
class="app-header__metafox-logo--horizontal"
|
||||
height="30"
|
||||
viewBox="0 0 1311 242"
|
||||
width="162"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
fill="none"
|
||||
>
|
||||
<g
|
||||
fill="var(--color-text-default)"
|
||||
transform="translate(361 61)"
|
||||
>
|
||||
<path
|
||||
d="m796.7 60.9c-6.8-4.5-14.3-7.7-21.4-11.7-4.6-2.6-9.5-4.9-13.5-8.2-6.8-5.6-5.4-16.6 1.7-21.4 10.2-6.8 27.1-3 28.9 10.9 0 .3.3.5.6.5h15.4c.4 0 .7-.3.6-.7-.8-9.6-4.5-17.6-11.3-22.7-6.5-4.9-13.9-7.5-21.8-7.5-40.7 0-44.4 43.1-22.5 56.7 2.5 1.6 24 12.4 31.6 17.1s10 13.3 6.7 20.1c-3 6.2-10.8 10.5-18.6 10-8.5-.5-15.1-5.1-17.4-12.3-.4-1.3-.6-3.8-.6-4.9 0-.3-.3-.6-.6-.6h-16.7c-.3 0-.6.3-.6.6 0 12.1 3 18.8 11.2 24.9 7.7 5.8 16.1 8.2 24.8 8.2 22.8 0 34.6-12.9 37-26.3 2.1-13.1-1.8-24.9-13.5-32.7z"
|
||||
/>
|
||||
<path
|
||||
d="m71.6 2.3h-7.4-8.1c-.3 0-.5.2-.6.4l-13.7 45.2c-.2.6-1 .6-1.2 0l-13.7-45.2c-.1-.3-.3-.4-.6-.4h-8.1-7.4-10c-.3 0-.6.3-.6.6v115.4c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-87.7c0-.7 1-.8 1.2-.2l13.8 45.5 1 3.2c.1.3.3.4.6.4h12.8c.3 0 .5-.2.6-.4l1-3.2 13.8-45.5c.2-.7 1.2-.5 1.2.2v87.7c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-115.4c0-.3-.3-.6-.6-.6z"
|
||||
/>
|
||||
<path
|
||||
d="m541 2.3c-.3 0-.5.2-.6.4l-13.7 45.2c-.2.6-1 .6-1.2 0l-13.7-45.2c-.1-.3-.3-.4-.6-.4h-25.4c-.3 0-.6.3-.6.6v115.4c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-87.7c0-.7 1-.8 1.2-.2l13.8 45.5 1 3.2c.1.3.3.4.6.4h12.8c.3 0 .5-.2.6-.4l1-3.2 13.8-45.5c.2-.7 1.2-.5 1.2.2v87.7c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-115.4c0-.3-.3-.6-.6-.6z"
|
||||
/>
|
||||
<path
|
||||
d="m325.6 2.3h-31.1-16.7-31.1c-.3 0-.6.3-.6.6v14.4c0 .3.3.6.6.6h30.5v100.4c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-100.4h30.5c.3 0 .6-.3.6-.6v-14.4c0-.3-.2-.6-.6-.6z"
|
||||
/>
|
||||
<path
|
||||
d="m424.1 118.9h15.2c.4 0 .7-.4.6-.8l-31.4-115.8c-.1-.3-.3-.4-.6-.4h-5.8-10.2-5.8c-.3 0-.5.2-.6.4l-31.4 115.8c-.1.4.2.8.6.8h15.2c.3 0 .5-.2.6-.4l9.1-33.7c.1-.3.3-.4.6-.4h33.6c.3 0 .5.2.6.4l9.1 33.7c.1.2.4.4.6.4zm-39.9-51 12.2-45.1c.2-.6 1-.6 1.2 0l12.2 45.1c.1.4-.2.8-.6.8h-24.4c-.4 0-.7-.4-.6-.8z"
|
||||
/>
|
||||
<path
|
||||
d="m683.3 118.9h15.2c.4 0 .7-.4.6-.8l-31.4-115.8c-.1-.3-.3-.4-.6-.4h-5.8-10.2-5.8c-.3 0-.5.2-.6.4l-31.4 115.8c-.1.4.2.8.6.8h15.2c.3 0 .5-.2.6-.4l9.1-33.7c.1-.3.3-.4.6-.4h33.6c.3 0 .5.2.6.4l9.1 33.7c.1.2.3.4.6.4zm-39.9-51 12.2-45.1c.2-.6 1-.6 1.2 0l12.2 45.1c.1.4-.2.8-.6.8h-24.4c-.4 0-.7-.4-.6-.8z"
|
||||
/>
|
||||
<path
|
||||
d="m149.8 101.8v-35.8c0-.3.3-.6.6-.6h44.5c.3 0 .6-.3.6-.6v-14.4c0-.3-.3-.6-.6-.6h-44.5c-.3 0-.6-.3-.6-.6v-30.6c0-.3.3-.6.6-.6h50.6c.3 0 .6-.3.6-.6v-14.4c0-.3-.3-.6-.6-.6h-51.2-17.3c-.3 0-.6.3-.6.6v15 31.9 15.6 37 15.8c0 .3.3.6.6.6h17.3 53.3c.3 0 .6-.3.6-.6v-15.2c0-.3-.3-.6-.6-.6h-52.8c-.3-.1-.5-.3-.5-.7z"
|
||||
/>
|
||||
<path
|
||||
d="m949.3 117.9-57.8-59.7c-.2-.2-.2-.6 0-.8l52-54c.4-.4.1-1-.4-1h-21.3c-.2 0-.3.1-.4.2l-44.1 45.8c-.4.4-1 .1-1-.4v-45c0-.3-.3-.6-.6-.6h-16.7c-.3 0-.6.3-.6.6v115.4c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-50.8c0-.5.7-.8 1-.4l50 51.6c.1.1.3.2.4.2h21.3c.4-.1.7-.8.3-1.1z"
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
transform="translate(1 1)"
|
||||
>
|
||||
<path
|
||||
d="m246.1.2-101.1 75 18.8-44.2z"
|
||||
fill="#e17726"
|
||||
stroke="#e17726"
|
||||
/>
|
||||
<g
|
||||
fill="#e27625"
|
||||
stroke="#e27625"
|
||||
transform="translate(2)"
|
||||
>
|
||||
<path
|
||||
d="m10.9.2 100.2 75.7-17.9-44.9z"
|
||||
/>
|
||||
<path
|
||||
d="m207.7 174.1-26.9 41.2 57.6 15.9 16.5-56.2z"
|
||||
/>
|
||||
<path
|
||||
d="m.2 175 16.4 56.2 57.5-15.9-26.8-41.2z"
|
||||
/>
|
||||
<path
|
||||
d="m71 104.5-16 24.2 57 2.6-1.9-61.5z"
|
||||
/>
|
||||
<path
|
||||
d="m184 104.5-39.7-35.4-1.3 62.2 57-2.6z"
|
||||
/>
|
||||
<path
|
||||
d="m74.1 215.3 34.5-16.7-29.7-23.2z"
|
||||
/>
|
||||
<path
|
||||
d="m146.4 198.6 34.4 16.7-4.7-39.9z"
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
fill="#d5bfb2"
|
||||
stroke="#d5bfb2"
|
||||
transform="translate(76 198)"
|
||||
>
|
||||
<path
|
||||
d="m106.8 17.3-34.4-16.7 2.8 22.4-.3 9.5z"
|
||||
/>
|
||||
<path
|
||||
d="m.1 17.3 32 15.2-.2-9.5 2.7-22.4z"
|
||||
/>
|
||||
</g>
|
||||
<path
|
||||
d="m108.7 160.6-28.6-8.4 20.2-9.3z"
|
||||
fill="#233447"
|
||||
stroke="#233447"
|
||||
/>
|
||||
<path
|
||||
d="m150.3 160.6 8.4-17.7 20.3 9.3z"
|
||||
fill="#233447"
|
||||
stroke="#233447"
|
||||
/>
|
||||
<g
|
||||
fill="#cc6228"
|
||||
stroke="#cc6228"
|
||||
transform="translate(49 128)"
|
||||
>
|
||||
<path
|
||||
d="m27.1 87.3 5-41.2-31.8.9z"
|
||||
/>
|
||||
<path
|
||||
d="m128.9 46.1 4.9 41.2 26.9-40.3z"
|
||||
/>
|
||||
<path
|
||||
d="m153 .7-57 2.6 5.3 29.3 8.4-17.7 20.3 9.3z"
|
||||
/>
|
||||
<path
|
||||
d="m31.1 24.2 20.2-9.3 8.4 17.7 5.3-29.3-57-2.6z"
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
fill="#e27525"
|
||||
stroke="#e27525"
|
||||
transform="translate(57 128)"
|
||||
>
|
||||
<path
|
||||
d="m0 .7 23.9 46.7-.8-23.2z"
|
||||
/>
|
||||
<path
|
||||
d="m122 24.2-.9 23.2 23.9-46.7z"
|
||||
/>
|
||||
<path
|
||||
d="m57 3.3-5.3 29.3 6.7 34.6 1.5-45.6z"
|
||||
/>
|
||||
<path
|
||||
d="m88 3.3-2.8 18.2 1.4 45.7 6.7-34.6z"
|
||||
/>
|
||||
</g>
|
||||
<path
|
||||
d="m150.3 160.6-6.7 34.6 4.8 3.4 29.7-23.2.9-23.2z"
|
||||
fill="#f5841f"
|
||||
stroke="#f5841f"
|
||||
/>
|
||||
<path
|
||||
d="m80.1 152.2.8 23.2 29.7 23.2 4.8-3.4-6.7-34.6z"
|
||||
fill="#f5841f"
|
||||
stroke="#f5841f"
|
||||
/>
|
||||
<path
|
||||
d="m150.9 230.5.3-9.5-2.6-2.2h-38.2l-2.5 2.2.2 9.5-32-15.2 11.2 9.2 22.7 15.7h38.9l22.8-15.7 11.1-9.2z"
|
||||
fill="#c0ac9d"
|
||||
stroke="#c0ac9d"
|
||||
/>
|
||||
<path
|
||||
d="m148.4 198.6-4.8-3.4h-28.2l-4.8 3.4-2.7 22.4 2.5-2.2h38.2l2.6 2.2z"
|
||||
fill="#161616"
|
||||
stroke="#161616"
|
||||
/>
|
||||
<g
|
||||
fill="#763e1a"
|
||||
stroke="#763e1a"
|
||||
>
|
||||
<path
|
||||
d="m250.4 80.1 8.5-41.4-12.8-38.5-97.7 72.5 37.6 31.8 53.1 15.5 11.7-13.7-5.1-3.7 8.1-7.4-6.2-4.8 8.1-6.2z"
|
||||
/>
|
||||
<path
|
||||
d="m.1 38.7 8.6 41.4-5.5 4.1 8.2 6.2-6.2 4.8 8.1 7.4-5.1 3.7 11.7 13.7 53.1-15.5 37.6-31.8-97.7-72.5z"
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
fill="#f5841f"
|
||||
stroke="#f5841f"
|
||||
>
|
||||
<path
|
||||
d="m239.1 120-53.1-15.5 16 24.2-23.9 46.7 31.6-.4h47.2z"
|
||||
/>
|
||||
<path
|
||||
d="m73 104.5-53.1 15.5-17.7 55h47.1l31.6.4-23.9-46.7z"
|
||||
/>
|
||||
<path
|
||||
d="m145 131.3 3.4-58.6 15.4-41.7h-68.6l15.4 41.7 3.4 58.6 1.3 18.4.1 45.5h28.2l.1-45.5z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<img
|
||||
alt=""
|
||||
class="app-header__metafox-logo--icon"
|
||||
src="./images/logo/metamask-fox.svg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
215
ui/components/multichain/app-header/app-header.js
Normal file
215
ui/components/multichain/app-header/app-header.js
Normal file
@ -0,0 +1,215 @@
|
||||
import React, { useContext, useState, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import browser from 'webextension-polyfill';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||
import {
|
||||
MetaMetricsEventCategory,
|
||||
MetaMetricsEventName,
|
||||
} from '../../../../shared/constants/metametrics';
|
||||
import {
|
||||
CONNECTED_ACCOUNTS_ROUTE,
|
||||
DEFAULT_ROUTE,
|
||||
} from '../../../helpers/constants/routes';
|
||||
|
||||
import {
|
||||
AlignItems,
|
||||
BackgroundColor,
|
||||
BLOCK_SIZES,
|
||||
DISPLAY,
|
||||
JustifyContent,
|
||||
Size,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import { AvatarNetwork, Button, PickerNetwork } from '../../component-library';
|
||||
import { ButtonIcon } from '../../component-library/button-icon/deprecated';
|
||||
import { ICON_NAMES } from '../../component-library/icon/deprecated';
|
||||
import {
|
||||
getCurrentNetwork,
|
||||
getOriginOfCurrentTab,
|
||||
getSelectedIdentity,
|
||||
} from '../../../selectors';
|
||||
import { GlobalMenu, AccountPicker } from '..';
|
||||
|
||||
import Box from '../../ui/box/box';
|
||||
import { toggleAccountMenu, toggleNetworkMenu } from '../../../store/actions';
|
||||
import MetafoxLogo from '../../ui/metafox-logo';
|
||||
import { getEnvironmentType } from '../../../../app/scripts/lib/util';
|
||||
import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app';
|
||||
import ConnectedStatusIndicator from '../../app/connected-status-indicator';
|
||||
|
||||
export const AppHeader = ({ onClick }) => {
|
||||
const trackEvent = useContext(MetaMetricsContext);
|
||||
const [accountOptionsMenuOpen, setAccountOptionsMenuOpen] = useState(false);
|
||||
const menuRef = useRef(false);
|
||||
const origin = useSelector(getOriginOfCurrentTab);
|
||||
const history = useHistory();
|
||||
const isUnlocked = useSelector((state) => state.metamask.isUnlocked);
|
||||
|
||||
// Used for account picker
|
||||
const identity = useSelector(getSelectedIdentity);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
// Used for network icon / dropdown
|
||||
const currentNetwork = useSelector(getCurrentNetwork);
|
||||
|
||||
// used to get the environment and connection status
|
||||
const popupStatus = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP;
|
||||
const showStatus =
|
||||
getEnvironmentType() === ENVIRONMENT_TYPE_POPUP &&
|
||||
origin &&
|
||||
origin !== browser.runtime.id;
|
||||
|
||||
return (
|
||||
<>
|
||||
{isUnlocked && !popupStatus ? (
|
||||
<Box
|
||||
display={DISPLAY.FLEX}
|
||||
alignItems={AlignItems.center}
|
||||
margin={2}
|
||||
className="multichain-app-header-logo"
|
||||
data-testid="app-header-logo"
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
<MetafoxLogo
|
||||
unsetIconHeight
|
||||
onClick={async () => {
|
||||
if (onClick) {
|
||||
await onClick();
|
||||
}
|
||||
history.push(DEFAULT_ROUTE);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
) : null}
|
||||
<Box
|
||||
display={DISPLAY.FLEX}
|
||||
className={`multichain-app-header ${
|
||||
!isUnlocked || popupStatus ? 'multichain-app-header-shadow' : ''
|
||||
}`}
|
||||
alignItems={AlignItems.center}
|
||||
width={BLOCK_SIZES.FULL}
|
||||
backgroundColor={
|
||||
!isUnlocked || popupStatus
|
||||
? BackgroundColor.backgroundDefault
|
||||
: BackgroundColor.backgroundAlternative
|
||||
}
|
||||
>
|
||||
<>
|
||||
{isUnlocked ? (
|
||||
<Box
|
||||
className={`multichain-app-header__contents ${
|
||||
isUnlocked && !popupStatus ? 'multichain-app-header-shadow' : ''
|
||||
}`}
|
||||
alignItems={AlignItems.center}
|
||||
width={BLOCK_SIZES.FULL}
|
||||
backgroundColor={BackgroundColor.backgroundDefault}
|
||||
padding={2}
|
||||
gap={2}
|
||||
>
|
||||
{popupStatus ? (
|
||||
<Button
|
||||
className="multichain-app-header__contents--avatar-network"
|
||||
justifyContent={JustifyContent.flexStart}
|
||||
>
|
||||
<AvatarNetwork
|
||||
name={currentNetwork?.nickname}
|
||||
src={currentNetwork?.rpcPrefs?.imageUrl}
|
||||
size={Size.SM}
|
||||
onClick={() => dispatch(toggleNetworkMenu())}
|
||||
/>
|
||||
</Button>
|
||||
) : (
|
||||
<PickerNetwork
|
||||
label={currentNetwork?.nickname}
|
||||
src={currentNetwork?.rpcPrefs?.imageUrl}
|
||||
onClick={() => dispatch(toggleNetworkMenu())}
|
||||
/>
|
||||
)}
|
||||
|
||||
<AccountPicker
|
||||
address={identity.address}
|
||||
name={identity.name}
|
||||
onClick={() => dispatch(toggleAccountMenu())}
|
||||
/>
|
||||
<Box
|
||||
display={DISPLAY.FLEX}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.spaceBetween}
|
||||
>
|
||||
{showStatus ? (
|
||||
<ConnectedStatusIndicator
|
||||
onClick={() => history.push(CONNECTED_ACCOUNTS_ROUTE)}
|
||||
/>
|
||||
) : null}
|
||||
<Box
|
||||
ref={menuRef}
|
||||
display={DISPLAY.FLEX}
|
||||
justifyContent={JustifyContent.flexEnd}
|
||||
width={BLOCK_SIZES.FULL}
|
||||
>
|
||||
<ButtonIcon
|
||||
iconName={ICON_NAMES.MORE_VERTICAL}
|
||||
data-testid="account-options-menu-button"
|
||||
ariaLabel="NEEDS NEW TRANSLATED LABEL" // TODO: Update the label
|
||||
onClick={() => {
|
||||
trackEvent({
|
||||
event: MetaMetricsEventName.NavAccountMenuOpened,
|
||||
category: MetaMetricsEventCategory.Navigation,
|
||||
properties: {
|
||||
location: 'Home',
|
||||
},
|
||||
});
|
||||
setAccountOptionsMenuOpen(true);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
{accountOptionsMenuOpen ? (
|
||||
<GlobalMenu
|
||||
anchorElement={menuRef.current}
|
||||
closeMenu={() => setAccountOptionsMenuOpen(false)}
|
||||
/>
|
||||
) : null}
|
||||
</Box>
|
||||
) : (
|
||||
<Box
|
||||
display={DISPLAY.FLEX}
|
||||
className={`multichain-app-header__lock-contents ${
|
||||
isUnlocked && !popupStatus ? 'multichain-app-header-shadow' : ''
|
||||
}`}
|
||||
alignItems={AlignItems.center}
|
||||
width={BLOCK_SIZES.FULL}
|
||||
justifyContent={JustifyContent.spaceBetween}
|
||||
backgroundColor={BackgroundColor.backgroundDefault}
|
||||
padding={2}
|
||||
gap={2}
|
||||
>
|
||||
<PickerNetwork
|
||||
label={currentNetwork?.nickname}
|
||||
src={currentNetwork?.rpcPrefs?.imageUrl}
|
||||
onClick={() => dispatch(toggleNetworkMenu())}
|
||||
/>
|
||||
<MetafoxLogo
|
||||
unsetIconHeight
|
||||
onClick={async () => {
|
||||
if (onClick) {
|
||||
await onClick();
|
||||
}
|
||||
history.push(DEFAULT_ROUTE);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
AppHeader.propTypes = {
|
||||
/**
|
||||
* The onClick handler to be passed to the MetaMask Logo in the App Header
|
||||
*/
|
||||
onClick: PropTypes.func,
|
||||
};
|
74
ui/components/multichain/app-header/app-header.scss
Normal file
74
ui/components/multichain/app-header/app-header.scss
Normal file
@ -0,0 +1,74 @@
|
||||
.multichain-app-header {
|
||||
$height-screen-sm-max: 100%;
|
||||
$width-screen-sm-min: 85vw;
|
||||
$width-screen-md-min: 80vw;
|
||||
$width-screen-lg-min: 62vw;
|
||||
|
||||
flex-flow: column nowrap;
|
||||
z-index: 55;
|
||||
min-height: 64px;
|
||||
|
||||
&__contents {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 2fr 1fr;
|
||||
height: 64px;
|
||||
|
||||
@include screen-sm-max {
|
||||
height: $height-screen-sm-max;
|
||||
}
|
||||
|
||||
@include screen-sm-min {
|
||||
width: $width-screen-sm-min;
|
||||
}
|
||||
|
||||
@include screen-md-min {
|
||||
width: $width-screen-md-min;
|
||||
}
|
||||
|
||||
@include screen-lg-min {
|
||||
width: $width-screen-lg-min;
|
||||
}
|
||||
|
||||
&--avatar-network {
|
||||
background-color: transparent;
|
||||
width: min-content;
|
||||
padding: 8px;
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
box-shadow: none;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__lock-contents {
|
||||
flex-flow: row nowrap;
|
||||
height: 64px;
|
||||
|
||||
@include screen-sm-max {
|
||||
height: $height-screen-sm-max;
|
||||
}
|
||||
|
||||
@include screen-sm-min {
|
||||
width: $width-screen-sm-min;
|
||||
}
|
||||
|
||||
@include screen-md-min {
|
||||
width: $width-screen-md-min;
|
||||
}
|
||||
|
||||
@include screen-lg-min {
|
||||
width: $width-screen-lg-min;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.multichain-app-header-shadow {
|
||||
box-shadow: var(--shadow-size-md) var(--color-shadow-default);
|
||||
}
|
||||
|
||||
.multichain-app-header-logo {
|
||||
height: 75px;
|
||||
flex: 0 0 auto;
|
||||
}
|
71
ui/components/multichain/app-header/app-header.stories.js
Normal file
71
ui/components/multichain/app-header/app-header.stories.js
Normal file
@ -0,0 +1,71 @@
|
||||
import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import configureStore from '../../../store/store';
|
||||
import testData from '../../../../.storybook/test-data';
|
||||
import { AppHeader } from '.';
|
||||
|
||||
const store = configureStore(testData);
|
||||
|
||||
export default {
|
||||
title: 'Components/Multichain/AppHeader',
|
||||
decorators: [(story) => <Provider store={store}>{story()}</Provider>],
|
||||
component: AppHeader,
|
||||
argTypes: {
|
||||
onClick: {
|
||||
action: 'onClick',
|
||||
},
|
||||
},
|
||||
};
|
||||
const customNetworkUnlockedData = {
|
||||
...testData,
|
||||
metamask: {
|
||||
...testData.metamask,
|
||||
preferences: {
|
||||
showTestNetworks: true,
|
||||
},
|
||||
isUnlocked: true,
|
||||
networkConfigurations: {
|
||||
...testData.metamask.networkConfigurations,
|
||||
},
|
||||
},
|
||||
};
|
||||
const customNetworkUnlockedStore = configureStore(customNetworkUnlockedData);
|
||||
|
||||
const customNetworkLockedData = {
|
||||
...testData,
|
||||
metamask: {
|
||||
...testData.metamask,
|
||||
preferences: {
|
||||
showTestNetworks: true,
|
||||
},
|
||||
isUnlocked: false,
|
||||
networkConfigurations: {
|
||||
...testData.metamask.networkConfigurations,
|
||||
},
|
||||
},
|
||||
};
|
||||
const customNetworkLockedStore = configureStore(customNetworkLockedData);
|
||||
|
||||
const Template = (args) => {
|
||||
return <AppHeader {...args} />;
|
||||
};
|
||||
|
||||
export const FullScreenAndUnlockedStory = Template.bind({});
|
||||
|
||||
FullScreenAndUnlockedStory.decorators = [
|
||||
(Story) => (
|
||||
<Provider store={customNetworkUnlockedStore}>
|
||||
<Story />
|
||||
</Provider>
|
||||
),
|
||||
];
|
||||
|
||||
export const FullScreenAndLockedStory = Template.bind({});
|
||||
|
||||
FullScreenAndLockedStory.decorators = [
|
||||
(Story) => (
|
||||
<Provider store={customNetworkLockedStore}>
|
||||
<Story />
|
||||
</Provider>
|
||||
),
|
||||
];
|
107
ui/components/multichain/app-header/app-header.test.js
Normal file
107
ui/components/multichain/app-header/app-header.test.js
Normal file
@ -0,0 +1,107 @@
|
||||
import React from 'react';
|
||||
import configureStore from 'redux-mock-store';
|
||||
import { CHAIN_IDS } from '../../../../shared/constants/network';
|
||||
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||
import { AppHeader } from '.';
|
||||
|
||||
describe('App Header', () => {
|
||||
it('should match snapshot', () => {
|
||||
const mockState = {
|
||||
activeTab: {
|
||||
title: 'Eth Sign Tests',
|
||||
origin: 'https://remix.ethereum.org',
|
||||
protocol: 'https:',
|
||||
url: 'https://remix.ethereum.org/',
|
||||
},
|
||||
metamask: {
|
||||
provider: {
|
||||
chainId: CHAIN_IDS.GOERLI,
|
||||
},
|
||||
accounts: {
|
||||
'0x7250739de134d33ec7ab1ee592711e15098c9d2d': {
|
||||
address: '0x7250739de134d33ec7ab1ee592711e15098c9d2d',
|
||||
},
|
||||
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5': {
|
||||
address: '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5',
|
||||
},
|
||||
},
|
||||
preferences: {
|
||||
showTestNetworks: true,
|
||||
},
|
||||
cachedBalances: {},
|
||||
subjects: {
|
||||
'https://remix.ethereum.org': {
|
||||
permissions: {
|
||||
eth_accounts: {
|
||||
caveats: [
|
||||
{
|
||||
type: 'restrictReturnedAccounts',
|
||||
value: [
|
||||
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5',
|
||||
'0x7250739de134d33ec7ab1ee592711e15098c9d2d',
|
||||
],
|
||||
},
|
||||
],
|
||||
date: 1586359844177,
|
||||
id: '3aa65a8b-3bcb-4944-941b-1baa5fe0ed8b',
|
||||
invoker: 'https://remix.ethereum.org',
|
||||
parentCapability: 'eth_accounts',
|
||||
},
|
||||
},
|
||||
},
|
||||
'peepeth.com': {
|
||||
permissions: {
|
||||
eth_accounts: {
|
||||
caveats: [
|
||||
{
|
||||
type: 'restrictReturnedAccounts',
|
||||
value: ['0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5'],
|
||||
},
|
||||
],
|
||||
date: 1585676177970,
|
||||
id: '840d72a0-925f-449f-830a-1aa1dd5ce151',
|
||||
invoker: 'peepeth.com',
|
||||
parentCapability: 'eth_accounts',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
identities: {
|
||||
'0x7250739de134d33ec7ab1ee592711e15098c9d2d': {
|
||||
address: '0x7250739de134d33ec7ab1ee592711e15098c9d2d',
|
||||
name: 'Really Long Name That Should Be Truncated',
|
||||
},
|
||||
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5': {
|
||||
address: '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5',
|
||||
lastSelected: 1586359844192,
|
||||
name: 'Account 1',
|
||||
},
|
||||
},
|
||||
keyrings: [
|
||||
{
|
||||
accounts: [
|
||||
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5',
|
||||
'0x7250739de134d33ec7ab1ee592711e15098c9d2d',
|
||||
],
|
||||
},
|
||||
],
|
||||
permissionHistory: {
|
||||
'https://remix.ethereum.org': {
|
||||
eth_accounts: {
|
||||
accounts: {
|
||||
'0x7250739de134d33ec7ab1ee592711e15098c9d2d': 1586359844192,
|
||||
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5': 1586359844192,
|
||||
},
|
||||
lastApproved: 1586359844192,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const mockStore = configureStore();
|
||||
const store = mockStore(mockState);
|
||||
const { container } = renderWithProvider(<AppHeader />, store);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
1
ui/components/multichain/app-header/index.js
Normal file
1
ui/components/multichain/app-header/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { AppHeader } from './app-header';
|
@ -2,6 +2,7 @@ export { AccountListItem } from './account-list-item';
|
||||
export { AccountListItemMenu } from './account-list-item-menu';
|
||||
export { AccountListMenu } from './account-list-menu';
|
||||
export { AccountPicker } from './account-picker';
|
||||
export { AppHeader } from './app-header';
|
||||
export { DetectedTokensBanner } from './detected-token-banner';
|
||||
export { GlobalMenu } from './global-menu';
|
||||
export { MultichainImportTokenLink } from './multichain-import-token-link';
|
||||
|
@ -8,6 +8,7 @@
|
||||
@import 'account-list-item/index';
|
||||
@import 'account-list-menu/index';
|
||||
@import 'account-picker/index';
|
||||
@import 'app-header/app-header';
|
||||
@import 'multichain-connected-site-menu/index';
|
||||
@import 'account-list-menu/';
|
||||
@import 'multichain-token-list-item/multichain-token-list-item';
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
showModal,
|
||||
setShowTestNetworks,
|
||||
setProviderType,
|
||||
toggleNetworkMenu,
|
||||
} from '../../../store/actions';
|
||||
import { CHAIN_IDS, TEST_CHAINS } from '../../../../shared/constants/network';
|
||||
import {
|
||||
@ -30,7 +31,7 @@ import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../shared/constants/app';
|
||||
|
||||
const UNREMOVABLE_CHAIN_IDS = [CHAIN_IDS.MAINNET, ...TEST_CHAINS];
|
||||
|
||||
export const NetworkListMenu = ({ closeMenu }) => {
|
||||
export const NetworkListMenu = ({ onClose }) => {
|
||||
const t = useI18nContext();
|
||||
const networks = useSelector(getAllNetworks);
|
||||
const showTestNetworks = useSelector(getShowTestNetworks);
|
||||
@ -42,7 +43,7 @@ export const NetworkListMenu = ({ closeMenu }) => {
|
||||
const isFullScreen = environmentType === ENVIRONMENT_TYPE_FULLSCREEN;
|
||||
|
||||
return (
|
||||
<Popover onClose={closeMenu} centerTitle title={t('networkMenuHeading')}>
|
||||
<Popover onClose={onClose} centerTitle title={t('networkMenuHeading')}>
|
||||
<>
|
||||
<Box className="multichain-network-list-menu">
|
||||
{networks.map((network) => {
|
||||
@ -58,16 +59,17 @@ export const NetworkListMenu = ({ closeMenu }) => {
|
||||
key={network.id || network.chainId}
|
||||
selected={isCurrentNetwork}
|
||||
onClick={() => {
|
||||
dispatch(toggleNetworkMenu());
|
||||
if (network.providerType) {
|
||||
dispatch(setProviderType(network.providerType));
|
||||
} else {
|
||||
dispatch(setActiveNetwork(network.id));
|
||||
}
|
||||
closeMenu();
|
||||
}}
|
||||
onDeleteClick={
|
||||
canDeleteNetwork
|
||||
? () => {
|
||||
dispatch(toggleNetworkMenu());
|
||||
dispatch(
|
||||
showModal({
|
||||
name: 'CONFIRM_DELETE_NETWORK',
|
||||
@ -75,7 +77,6 @@ export const NetworkListMenu = ({ closeMenu }) => {
|
||||
onConfirm: () => undefined,
|
||||
}),
|
||||
);
|
||||
closeMenu();
|
||||
}
|
||||
: null
|
||||
}
|
||||
@ -104,6 +105,7 @@ export const NetworkListMenu = ({ closeMenu }) => {
|
||||
: global.platform.openExtensionInBrowser(
|
||||
ADD_POPULAR_CUSTOM_NETWORK,
|
||||
);
|
||||
dispatch(toggleNetworkMenu());
|
||||
}}
|
||||
>
|
||||
{t('addNetwork')}
|
||||
@ -118,5 +120,5 @@ NetworkListMenu.propTypes = {
|
||||
/**
|
||||
* Executes when the menu should be closed
|
||||
*/
|
||||
closeMenu: PropTypes.func.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
};
|
||||
|
@ -42,8 +42,8 @@ export default {
|
||||
title: 'Components/Multichain/NetworkListMenu',
|
||||
component: NetworkListMenu,
|
||||
argTypes: {
|
||||
closeMenu: {
|
||||
action: 'closeMenu',
|
||||
onClose: {
|
||||
action: 'onClose',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -11,9 +11,11 @@ import { NetworkListMenu } from '.';
|
||||
|
||||
const mockSetShowTestNetworks = jest.fn();
|
||||
const mockSetProviderType = jest.fn();
|
||||
const mockToggleNetworkMenu = jest.fn();
|
||||
jest.mock('../../../store/actions.ts', () => ({
|
||||
setShowTestNetworks: () => mockSetShowTestNetworks,
|
||||
setProviderType: () => mockSetProviderType,
|
||||
toggleNetworkMenu: () => mockToggleNetworkMenu,
|
||||
}));
|
||||
|
||||
const render = (showTestNetworks = false) => {
|
||||
@ -25,7 +27,7 @@ const render = (showTestNetworks = false) => {
|
||||
},
|
||||
},
|
||||
});
|
||||
return renderWithProvider(<NetworkListMenu closeMenu={jest.fn()} />, store);
|
||||
return renderWithProvider(<NetworkListMenu onClose={jest.fn()} />, store);
|
||||
};
|
||||
|
||||
describe('NetworkListMenu', () => {
|
||||
@ -56,6 +58,7 @@ describe('NetworkListMenu', () => {
|
||||
it('switches networks when an item is clicked', () => {
|
||||
const { getByText } = render();
|
||||
fireEvent.click(getByText(MAINNET_DISPLAY_NAME));
|
||||
expect(mockToggleNetworkMenu).toHaveBeenCalled();
|
||||
expect(mockSetProviderType).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@ -26,6 +26,7 @@ const initialState = {
|
||||
isInitialized: false,
|
||||
isUnlocked: false,
|
||||
isAccountMenuOpen: false,
|
||||
isNetworkMenuOpen: false,
|
||||
identities: {},
|
||||
unapprovedTxs: {},
|
||||
networkConfigurations: {},
|
||||
@ -102,6 +103,12 @@ export default function reduceMetamask(state = initialState, action) {
|
||||
isAccountMenuOpen: !metamaskState.isAccountMenuOpen,
|
||||
};
|
||||
|
||||
case actionConstants.TOGGLE_NETWORK_MENU:
|
||||
return {
|
||||
...metamaskState,
|
||||
isNetworkMenuOpen: !metamaskState.isNetworkMenuOpen,
|
||||
};
|
||||
|
||||
case actionConstants.UPDATE_TRANSACTION_PARAMS: {
|
||||
const { id: txId, value } = action;
|
||||
let { currentNetworkTxList } = metamaskState;
|
||||
|
@ -157,6 +157,17 @@ describe('MetaMask Reducers', () => {
|
||||
expect(state.isAccountMenuOpen).toStrictEqual(true);
|
||||
});
|
||||
|
||||
it('toggles network menu', () => {
|
||||
const state = reduceMetamask(
|
||||
{},
|
||||
{
|
||||
type: actionConstants.TOGGLE_NETWORK_MENU,
|
||||
},
|
||||
);
|
||||
|
||||
expect(state.isNetworkMenuOpen).toStrictEqual(true);
|
||||
});
|
||||
|
||||
it('updates value of tx by id', () => {
|
||||
const oldState = {
|
||||
currentNetworkTxList: [
|
||||
|
@ -641,7 +641,7 @@ export default class Home extends PureComponent {
|
||||
? this.renderPopover()
|
||||
: null}
|
||||
<div className="home__main-view">
|
||||
<MenuBar />
|
||||
{process.env.MULTICHAIN ? null : <MenuBar />}
|
||||
<div className="home__balance-wrapper">
|
||||
<EthOverview />
|
||||
</div>
|
||||
|
@ -31,6 +31,11 @@ import AccountMenu from '../../components/app/account-menu';
|
||||
import { Modal } from '../../components/app/modals';
|
||||
import Alert from '../../components/ui/alert';
|
||||
import AppHeader from '../../components/app/app-header';
|
||||
import {
|
||||
AppHeader as MultichainAppHeader,
|
||||
AccountListMenu,
|
||||
NetworkListMenu,
|
||||
} from '../../components/multichain';
|
||||
import UnlockPage from '../unlock-page';
|
||||
import Alerts from '../../components/app/alerts';
|
||||
import Asset from '../asset';
|
||||
@ -90,7 +95,6 @@ import { SEND_STAGES } from '../../ducks/send';
|
||||
import DeprecatedTestNetworks from '../../components/ui/deprecated-test-networks/deprecated-test-networks';
|
||||
import NewNetworkInfo from '../../components/ui/new-network-info/new-network-info';
|
||||
import { ThemeType } from '../../../shared/constants/preferences';
|
||||
import { AccountListMenu } from '../../components/multichain';
|
||||
|
||||
export default class Routes extends Component {
|
||||
static propTypes = {
|
||||
@ -128,6 +132,8 @@ export default class Routes extends Component {
|
||||
completedOnboarding: PropTypes.bool,
|
||||
isAccountMenuOpen: PropTypes.bool,
|
||||
toggleAccountMenu: PropTypes.func,
|
||||
isNetworkMenuOpen: PropTypes.bool,
|
||||
toggleNetworkMenu: PropTypes.func,
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
@ -436,6 +442,8 @@ export default class Routes extends Component {
|
||||
completedOnboarding,
|
||||
isAccountMenuOpen,
|
||||
toggleAccountMenu,
|
||||
isNetworkMenuOpen,
|
||||
toggleNetworkMenu,
|
||||
} = this.props;
|
||||
const loadMessage =
|
||||
loadingMessage || isNetworkLoading
|
||||
@ -478,7 +486,10 @@ export default class Routes extends Component {
|
||||
<QRHardwarePopover />
|
||||
<Modal />
|
||||
<Alert visible={this.props.alertOpen} msg={alertMessage} />
|
||||
{!this.hideAppHeader() && (
|
||||
{!this.hideAppHeader() &&
|
||||
(process.env.MULTICHAIN ? (
|
||||
<MultichainAppHeader />
|
||||
) : (
|
||||
<AppHeader
|
||||
hideNetworkIndicator={this.onInitializationUnlockPage()}
|
||||
disableNetworkIndicator={this.onSwapsPage()}
|
||||
@ -489,13 +500,16 @@ export default class Routes extends Component {
|
||||
(this.onSwapsPage() && !this.onSwapsBuildQuotePage())
|
||||
}
|
||||
/>
|
||||
)}
|
||||
))}
|
||||
{this.showOnboardingHeader() && <OnboardingAppHeader />}
|
||||
{completedOnboarding ? <NetworkDropdown /> : null}
|
||||
{process.env.MULTICHAIN ? null : <AccountMenu />}
|
||||
{process.env.MULTICHAIN && isAccountMenuOpen ? (
|
||||
<AccountListMenu onClose={() => toggleAccountMenu()} />
|
||||
) : null}
|
||||
{process.env.MULTICHAIN && isNetworkMenuOpen ? (
|
||||
<NetworkListMenu onClose={() => toggleNetworkMenu()} />
|
||||
) : null}
|
||||
<div className="main-container-wrapper">
|
||||
{isLoading ? <Loading loadingMessage={loadMessage} /> : null}
|
||||
{!isLoading && isNetworkLoading ? <LoadingNetwork /> : null}
|
||||
|
@ -19,6 +19,7 @@ import {
|
||||
setLastActiveTime,
|
||||
setMouseUserState,
|
||||
toggleAccountMenu,
|
||||
toggleNetworkMenu,
|
||||
} from '../../store/actions';
|
||||
import { pageChanged } from '../../ducks/history/history';
|
||||
import { prepareToLeaveSwaps } from '../../ducks/swaps/swaps';
|
||||
@ -57,6 +58,7 @@ function mapStateToProps(state) {
|
||||
isCurrentProviderCustom: isCurrentProviderCustom(state),
|
||||
completedOnboarding,
|
||||
isAccountMenuOpen: state.metamask.isAccountMenuOpen,
|
||||
isNetworkMenuOpen: state.metamask.isNetworkMenuOpen,
|
||||
};
|
||||
}
|
||||
|
||||
@ -70,6 +72,7 @@ function mapDispatchToProps(dispatch) {
|
||||
pageChanged: (path) => dispatch(pageChanged(path)),
|
||||
prepareToLeaveSwaps: () => dispatch(prepareToLeaveSwaps()),
|
||||
toggleAccountMenu: () => dispatch(toggleAccountMenu()),
|
||||
toggleNetworkMenu: () => dispatch(toggleNetworkMenu()),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1111,6 +1111,13 @@ export function getNetworkConfigurations(state) {
|
||||
return state.metamask.networkConfigurations;
|
||||
}
|
||||
|
||||
export function getCurrentNetwork(state) {
|
||||
const allNetworks = getAllNetworks(state);
|
||||
const currentChainId = getCurrentChainId(state);
|
||||
|
||||
return allNetworks.find((network) => network.chainId === currentChainId);
|
||||
}
|
||||
|
||||
export function getAllNetworks(state) {
|
||||
const networkConfigurations = getNetworkConfigurations(state) || {};
|
||||
const showTestnetNetworks = getShowTestNetworks(state);
|
||||
|
@ -48,6 +48,7 @@ export const SHOW_LOADING = 'SHOW_LOADING_INDICATION';
|
||||
export const HIDE_LOADING = 'HIDE_LOADING_INDICATION';
|
||||
|
||||
export const TOGGLE_ACCOUNT_MENU = 'TOGGLE_ACCOUNT_MENU';
|
||||
export const TOGGLE_NETWORK_MENU = 'TOGGLE_NETWORK_MENU';
|
||||
|
||||
// preferences
|
||||
export const UPDATE_CUSTOM_NONCE = 'UPDATE_CUSTOM_NONCE';
|
||||
|
@ -3122,6 +3122,12 @@ export function toggleAccountMenu() {
|
||||
};
|
||||
}
|
||||
|
||||
export function toggleNetworkMenu() {
|
||||
return {
|
||||
type: actionConstants.TOGGLE_NETWORK_MENU,
|
||||
};
|
||||
}
|
||||
|
||||
export function setParticipateInMetaMetrics(
|
||||
participationPreference: boolean,
|
||||
): ThunkAction<
|
||||
|
Loading…
Reference in New Issue
Block a user