mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
add hamburger menu to eth page (#10938)
* add hamburger menu to eth page * change token-options to asset-options, use more direct selector for user address fetch
This commit is contained in:
parent
37159a58e1
commit
13a0389c96
@ -179,6 +179,9 @@
|
||||
"asset": {
|
||||
"message": "Asset"
|
||||
},
|
||||
"assetOptions": {
|
||||
"message": "Asset options"
|
||||
},
|
||||
"assets": {
|
||||
"message": "Assets"
|
||||
},
|
||||
@ -2132,9 +2135,6 @@
|
||||
"tokenContractAddress": {
|
||||
"message": "Token Contract Address"
|
||||
},
|
||||
"tokenOptions": {
|
||||
"message": "Token options"
|
||||
},
|
||||
"tokenSymbol": {
|
||||
"message": "Token Symbol"
|
||||
},
|
||||
|
@ -1855,9 +1855,6 @@
|
||||
"tokenContractAddress": {
|
||||
"message": "Dirección del contrato de token"
|
||||
},
|
||||
"tokenOptions": {
|
||||
"message": "Opciones del Token"
|
||||
},
|
||||
"tokenSymbol": {
|
||||
"message": "Símbolo del token"
|
||||
},
|
||||
|
@ -1855,9 +1855,6 @@
|
||||
"tokenContractAddress": {
|
||||
"message": "Dirección de contrato del token"
|
||||
},
|
||||
"tokenOptions": {
|
||||
"message": "Opciones del Token"
|
||||
},
|
||||
"tokenSymbol": {
|
||||
"message": "Símbolo del token"
|
||||
},
|
||||
|
@ -1819,9 +1819,6 @@
|
||||
"tokenContractAddress": {
|
||||
"message": "टोकन अनुबंध पता"
|
||||
},
|
||||
"tokenOptions": {
|
||||
"message": "टोकन के विकल्प"
|
||||
},
|
||||
"tokenSymbol": {
|
||||
"message": "टोकन का प्रतीक"
|
||||
},
|
||||
|
@ -1819,9 +1819,6 @@
|
||||
"tokenContractAddress": {
|
||||
"message": "Alamat Kontrak Token"
|
||||
},
|
||||
"tokenOptions": {
|
||||
"message": "Opsi token"
|
||||
},
|
||||
"tokenSymbol": {
|
||||
"message": "Simbol Token"
|
||||
},
|
||||
|
@ -1878,9 +1878,6 @@
|
||||
"tokenContractAddress": {
|
||||
"message": "Indirizzo Contratto Token"
|
||||
},
|
||||
"tokenOptions": {
|
||||
"message": "Opzioni token"
|
||||
},
|
||||
"tokenSymbol": {
|
||||
"message": "Simbolo Token"
|
||||
},
|
||||
|
@ -1855,9 +1855,6 @@
|
||||
"tokenContractAddress": {
|
||||
"message": "トークンコントラクトのアドレス"
|
||||
},
|
||||
"tokenOptions": {
|
||||
"message": "トークンのオプション"
|
||||
},
|
||||
"tokenSymbol": {
|
||||
"message": "トークンシンボル"
|
||||
},
|
||||
|
@ -1819,9 +1819,6 @@
|
||||
"tokenContractAddress": {
|
||||
"message": "토큰 계약 주소"
|
||||
},
|
||||
"tokenOptions": {
|
||||
"message": "토큰 옵션"
|
||||
},
|
||||
"tokenSymbol": {
|
||||
"message": "토큰 기호"
|
||||
},
|
||||
|
@ -1819,9 +1819,6 @@
|
||||
"tokenContractAddress": {
|
||||
"message": "Адрес контракта токена"
|
||||
},
|
||||
"tokenOptions": {
|
||||
"message": "Опции токена"
|
||||
},
|
||||
"tokenSymbol": {
|
||||
"message": "Символ токена"
|
||||
},
|
||||
|
@ -1816,9 +1816,6 @@
|
||||
"tokenContractAddress": {
|
||||
"message": "Address ng Kontrata ng Token"
|
||||
},
|
||||
"tokenOptions": {
|
||||
"message": "Mga opsyon ng token"
|
||||
},
|
||||
"tokenSymbol": {
|
||||
"message": "Simbolo ng Token"
|
||||
},
|
||||
|
@ -1819,9 +1819,6 @@
|
||||
"tokenContractAddress": {
|
||||
"message": "Địa chỉ hợp đồng token"
|
||||
},
|
||||
"tokenOptions": {
|
||||
"message": "Tùy chọn token"
|
||||
},
|
||||
"tokenSymbol": {
|
||||
"message": "Ký hiệu token"
|
||||
},
|
||||
|
@ -1855,9 +1855,6 @@
|
||||
"tokenContractAddress": {
|
||||
"message": "代币合约地址"
|
||||
},
|
||||
"tokenOptions": {
|
||||
"message": "代币选项"
|
||||
},
|
||||
"tokenSymbol": {
|
||||
"message": "代币符号"
|
||||
},
|
||||
|
@ -1508,9 +1508,9 @@ describe('MetaMask', function () {
|
||||
|
||||
describe('Hide token', function () {
|
||||
it('hides the token when clicked', async function () {
|
||||
await driver.clickElement('[data-testid="token-options__button"]');
|
||||
await driver.clickElement('[data-testid="asset-options__button"]');
|
||||
|
||||
await driver.clickElement('[data-testid="token-options__hide"]');
|
||||
await driver.clickElement('[data-testid="asset-options__hide"]');
|
||||
|
||||
// wait for confirm hide modal to be visible
|
||||
const confirmHideModal = await driver.findVisibleElement('span .modal');
|
||||
|
@ -32,7 +32,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.token-options {
|
||||
.asset-options {
|
||||
&__button {
|
||||
font-size: $font-size-paragraph;
|
||||
color: $Black-100;
|
||||
|
80
ui/app/pages/asset/components/asset-options.js
Normal file
80
ui/app/pages/asset/components/asset-options.js
Normal file
@ -0,0 +1,80 @@
|
||||
import React, { useContext, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { I18nContext } from '../../../contexts/i18n';
|
||||
import { Menu, MenuItem } from '../../../components/ui/menu';
|
||||
|
||||
const AssetOptions = ({
|
||||
onRemove,
|
||||
onViewEtherscan,
|
||||
onViewAccountDetails,
|
||||
tokenSymbol,
|
||||
isNativeAsset,
|
||||
}) => {
|
||||
const t = useContext(I18nContext);
|
||||
const [assetOptionsButtonElement, setAssetOptionsButtonElement] = useState(
|
||||
null,
|
||||
);
|
||||
const [assetOptionsOpen, setAssetOptionsOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
className="fas fa-ellipsis-v asset-options__button"
|
||||
data-testid="asset-options__button"
|
||||
onClick={() => setAssetOptionsOpen(true)}
|
||||
ref={setAssetOptionsButtonElement}
|
||||
title={t('assetOptions')}
|
||||
/>
|
||||
{assetOptionsOpen ? (
|
||||
<Menu
|
||||
anchorElement={assetOptionsButtonElement}
|
||||
onHide={() => setAssetOptionsOpen(false)}
|
||||
>
|
||||
<MenuItem
|
||||
iconClassName="fas fa-qrcode"
|
||||
data-testid="asset-options__account-details"
|
||||
onClick={() => {
|
||||
setAssetOptionsOpen(false);
|
||||
onViewAccountDetails();
|
||||
}}
|
||||
>
|
||||
{t('accountDetails')}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
iconClassName="fas fa-external-link-alt asset-options__icon"
|
||||
data-testid="asset-options__etherscan"
|
||||
onClick={() => {
|
||||
setAssetOptionsOpen(false);
|
||||
onViewEtherscan();
|
||||
}}
|
||||
>
|
||||
{t('viewOnEtherscan')}
|
||||
</MenuItem>
|
||||
{isNativeAsset ? null : (
|
||||
<MenuItem
|
||||
iconClassName="fas fa-trash-alt asset-options__icon"
|
||||
data-testid="asset-options__hide"
|
||||
onClick={() => {
|
||||
setAssetOptionsOpen(false);
|
||||
onRemove();
|
||||
}}
|
||||
>
|
||||
{t('hideTokenSymbol', [tokenSymbol])}
|
||||
</MenuItem>
|
||||
)}
|
||||
</Menu>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
AssetOptions.propTypes = {
|
||||
isNativeAsset: PropTypes.bool,
|
||||
onRemove: PropTypes.func.isRequired,
|
||||
onViewEtherscan: PropTypes.func.isRequired,
|
||||
onViewAccountDetails: PropTypes.func.isRequired,
|
||||
tokenSymbol: PropTypes.string,
|
||||
};
|
||||
|
||||
export default AssetOptions;
|
@ -1,19 +1,30 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import TransactionList from '../../../components/app/transaction-list';
|
||||
import { EthOverview } from '../../../components/app/wallet-overview';
|
||||
import { getSelectedIdentity } from '../../../selectors/selectors';
|
||||
import {
|
||||
getSelectedIdentity,
|
||||
getCurrentChainId,
|
||||
getRpcPrefsForCurrentProvider,
|
||||
getSelectedAddress,
|
||||
} from '../../../selectors/selectors';
|
||||
import { showModal } from '../../../store/actions';
|
||||
import getAccountLink from '../../../../lib/account-link';
|
||||
import { DEFAULT_ROUTE } from '../../../helpers/constants/routes';
|
||||
|
||||
import AssetNavigation from './asset-navigation';
|
||||
import AssetOptions from './asset-options';
|
||||
|
||||
export default function NativeAsset({ nativeCurrency }) {
|
||||
const selectedAccountName = useSelector(
|
||||
(state) => getSelectedIdentity(state).name,
|
||||
);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const chainId = useSelector(getCurrentChainId);
|
||||
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider);
|
||||
const address = useSelector(getSelectedAddress);
|
||||
const history = useHistory();
|
||||
|
||||
return (
|
||||
@ -22,6 +33,19 @@ export default function NativeAsset({ nativeCurrency }) {
|
||||
accountName={selectedAccountName}
|
||||
assetName={nativeCurrency}
|
||||
onBack={() => history.push(DEFAULT_ROUTE)}
|
||||
optionsButton={
|
||||
<AssetOptions
|
||||
isNativeAsset
|
||||
onViewEtherscan={() => {
|
||||
global.platform.openTab({
|
||||
url: getAccountLink(address, chainId, rpcPrefs),
|
||||
});
|
||||
}}
|
||||
onViewAccountDetails={() => {
|
||||
dispatch(showModal({ name: 'ACCOUNT_DETAILS' }));
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<EthOverview className="asset__overview" />
|
||||
<TransactionList hideTokenTransactions />
|
||||
|
@ -14,7 +14,7 @@ import { DEFAULT_ROUTE } from '../../../helpers/constants/routes';
|
||||
import { showModal } from '../../../store/actions';
|
||||
|
||||
import AssetNavigation from './asset-navigation';
|
||||
import TokenOptions from './token-options';
|
||||
import AssetOptions from './asset-options';
|
||||
|
||||
export default function TokenAsset({ token }) {
|
||||
const dispatch = useDispatch();
|
||||
@ -31,7 +31,7 @@ export default function TokenAsset({ token }) {
|
||||
assetName={token.symbol}
|
||||
onBack={() => history.push(DEFAULT_ROUTE)}
|
||||
optionsButton={
|
||||
<TokenOptions
|
||||
<AssetOptions
|
||||
onRemove={() =>
|
||||
dispatch(showModal({ name: 'HIDE_TOKEN_CONFIRMATION', token }))
|
||||
}
|
||||
|
@ -1,76 +0,0 @@
|
||||
import React, { useContext, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { I18nContext } from '../../../contexts/i18n';
|
||||
import { Menu, MenuItem } from '../../../components/ui/menu';
|
||||
|
||||
const TokenOptions = ({
|
||||
onRemove,
|
||||
onViewEtherscan,
|
||||
onViewAccountDetails,
|
||||
tokenSymbol,
|
||||
}) => {
|
||||
const t = useContext(I18nContext);
|
||||
const [tokenOptionsButtonElement, setTokenOptionsButtonElement] = useState(
|
||||
null,
|
||||
);
|
||||
const [tokenOptionsOpen, setTokenOptionsOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
className="fas fa-ellipsis-v token-options__button"
|
||||
data-testid="token-options__button"
|
||||
onClick={() => setTokenOptionsOpen(true)}
|
||||
ref={setTokenOptionsButtonElement}
|
||||
title={t('tokenOptions')}
|
||||
/>
|
||||
{tokenOptionsOpen ? (
|
||||
<Menu
|
||||
anchorElement={tokenOptionsButtonElement}
|
||||
onHide={() => setTokenOptionsOpen(false)}
|
||||
>
|
||||
<MenuItem
|
||||
iconClassName="fas fa-qrcode"
|
||||
data-testid="token-options__account-details"
|
||||
onClick={() => {
|
||||
setTokenOptionsOpen(false);
|
||||
onViewAccountDetails();
|
||||
}}
|
||||
>
|
||||
{t('accountDetails')}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
iconClassName="fas fa-external-link-alt token-options__icon"
|
||||
data-testid="token-options__etherscan"
|
||||
onClick={() => {
|
||||
setTokenOptionsOpen(false);
|
||||
onViewEtherscan();
|
||||
}}
|
||||
>
|
||||
{t('viewOnEtherscan')}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
iconClassName="fas fa-trash-alt token-options__icon"
|
||||
data-testid="token-options__hide"
|
||||
onClick={() => {
|
||||
setTokenOptionsOpen(false);
|
||||
onRemove();
|
||||
}}
|
||||
>
|
||||
{t('hideTokenSymbol', [tokenSymbol])}
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
TokenOptions.propTypes = {
|
||||
onRemove: PropTypes.func.isRequired,
|
||||
onViewEtherscan: PropTypes.func.isRequired,
|
||||
onViewAccountDetails: PropTypes.func.isRequired,
|
||||
tokenSymbol: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default TokenOptions;
|
Loading…
x
Reference in New Issue
Block a user