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": {
|
"asset": {
|
||||||
"message": "Asset"
|
"message": "Asset"
|
||||||
},
|
},
|
||||||
|
"assetOptions": {
|
||||||
|
"message": "Asset options"
|
||||||
|
},
|
||||||
"assets": {
|
"assets": {
|
||||||
"message": "Assets"
|
"message": "Assets"
|
||||||
},
|
},
|
||||||
@ -2132,9 +2135,6 @@
|
|||||||
"tokenContractAddress": {
|
"tokenContractAddress": {
|
||||||
"message": "Token Contract Address"
|
"message": "Token Contract Address"
|
||||||
},
|
},
|
||||||
"tokenOptions": {
|
|
||||||
"message": "Token options"
|
|
||||||
},
|
|
||||||
"tokenSymbol": {
|
"tokenSymbol": {
|
||||||
"message": "Token Symbol"
|
"message": "Token Symbol"
|
||||||
},
|
},
|
||||||
|
@ -1855,9 +1855,6 @@
|
|||||||
"tokenContractAddress": {
|
"tokenContractAddress": {
|
||||||
"message": "Dirección del contrato de token"
|
"message": "Dirección del contrato de token"
|
||||||
},
|
},
|
||||||
"tokenOptions": {
|
|
||||||
"message": "Opciones del Token"
|
|
||||||
},
|
|
||||||
"tokenSymbol": {
|
"tokenSymbol": {
|
||||||
"message": "Símbolo del token"
|
"message": "Símbolo del token"
|
||||||
},
|
},
|
||||||
|
@ -1855,9 +1855,6 @@
|
|||||||
"tokenContractAddress": {
|
"tokenContractAddress": {
|
||||||
"message": "Dirección de contrato del token"
|
"message": "Dirección de contrato del token"
|
||||||
},
|
},
|
||||||
"tokenOptions": {
|
|
||||||
"message": "Opciones del Token"
|
|
||||||
},
|
|
||||||
"tokenSymbol": {
|
"tokenSymbol": {
|
||||||
"message": "Símbolo del token"
|
"message": "Símbolo del token"
|
||||||
},
|
},
|
||||||
|
@ -1819,9 +1819,6 @@
|
|||||||
"tokenContractAddress": {
|
"tokenContractAddress": {
|
||||||
"message": "टोकन अनुबंध पता"
|
"message": "टोकन अनुबंध पता"
|
||||||
},
|
},
|
||||||
"tokenOptions": {
|
|
||||||
"message": "टोकन के विकल्प"
|
|
||||||
},
|
|
||||||
"tokenSymbol": {
|
"tokenSymbol": {
|
||||||
"message": "टोकन का प्रतीक"
|
"message": "टोकन का प्रतीक"
|
||||||
},
|
},
|
||||||
|
@ -1819,9 +1819,6 @@
|
|||||||
"tokenContractAddress": {
|
"tokenContractAddress": {
|
||||||
"message": "Alamat Kontrak Token"
|
"message": "Alamat Kontrak Token"
|
||||||
},
|
},
|
||||||
"tokenOptions": {
|
|
||||||
"message": "Opsi token"
|
|
||||||
},
|
|
||||||
"tokenSymbol": {
|
"tokenSymbol": {
|
||||||
"message": "Simbol Token"
|
"message": "Simbol Token"
|
||||||
},
|
},
|
||||||
|
@ -1878,9 +1878,6 @@
|
|||||||
"tokenContractAddress": {
|
"tokenContractAddress": {
|
||||||
"message": "Indirizzo Contratto Token"
|
"message": "Indirizzo Contratto Token"
|
||||||
},
|
},
|
||||||
"tokenOptions": {
|
|
||||||
"message": "Opzioni token"
|
|
||||||
},
|
|
||||||
"tokenSymbol": {
|
"tokenSymbol": {
|
||||||
"message": "Simbolo Token"
|
"message": "Simbolo Token"
|
||||||
},
|
},
|
||||||
|
@ -1855,9 +1855,6 @@
|
|||||||
"tokenContractAddress": {
|
"tokenContractAddress": {
|
||||||
"message": "トークンコントラクトのアドレス"
|
"message": "トークンコントラクトのアドレス"
|
||||||
},
|
},
|
||||||
"tokenOptions": {
|
|
||||||
"message": "トークンのオプション"
|
|
||||||
},
|
|
||||||
"tokenSymbol": {
|
"tokenSymbol": {
|
||||||
"message": "トークンシンボル"
|
"message": "トークンシンボル"
|
||||||
},
|
},
|
||||||
|
@ -1819,9 +1819,6 @@
|
|||||||
"tokenContractAddress": {
|
"tokenContractAddress": {
|
||||||
"message": "토큰 계약 주소"
|
"message": "토큰 계약 주소"
|
||||||
},
|
},
|
||||||
"tokenOptions": {
|
|
||||||
"message": "토큰 옵션"
|
|
||||||
},
|
|
||||||
"tokenSymbol": {
|
"tokenSymbol": {
|
||||||
"message": "토큰 기호"
|
"message": "토큰 기호"
|
||||||
},
|
},
|
||||||
|
@ -1819,9 +1819,6 @@
|
|||||||
"tokenContractAddress": {
|
"tokenContractAddress": {
|
||||||
"message": "Адрес контракта токена"
|
"message": "Адрес контракта токена"
|
||||||
},
|
},
|
||||||
"tokenOptions": {
|
|
||||||
"message": "Опции токена"
|
|
||||||
},
|
|
||||||
"tokenSymbol": {
|
"tokenSymbol": {
|
||||||
"message": "Символ токена"
|
"message": "Символ токена"
|
||||||
},
|
},
|
||||||
|
@ -1816,9 +1816,6 @@
|
|||||||
"tokenContractAddress": {
|
"tokenContractAddress": {
|
||||||
"message": "Address ng Kontrata ng Token"
|
"message": "Address ng Kontrata ng Token"
|
||||||
},
|
},
|
||||||
"tokenOptions": {
|
|
||||||
"message": "Mga opsyon ng token"
|
|
||||||
},
|
|
||||||
"tokenSymbol": {
|
"tokenSymbol": {
|
||||||
"message": "Simbolo ng Token"
|
"message": "Simbolo ng Token"
|
||||||
},
|
},
|
||||||
|
@ -1819,9 +1819,6 @@
|
|||||||
"tokenContractAddress": {
|
"tokenContractAddress": {
|
||||||
"message": "Địa chỉ hợp đồng token"
|
"message": "Địa chỉ hợp đồng token"
|
||||||
},
|
},
|
||||||
"tokenOptions": {
|
|
||||||
"message": "Tùy chọn token"
|
|
||||||
},
|
|
||||||
"tokenSymbol": {
|
"tokenSymbol": {
|
||||||
"message": "Ký hiệu token"
|
"message": "Ký hiệu token"
|
||||||
},
|
},
|
||||||
|
@ -1855,9 +1855,6 @@
|
|||||||
"tokenContractAddress": {
|
"tokenContractAddress": {
|
||||||
"message": "代币合约地址"
|
"message": "代币合约地址"
|
||||||
},
|
},
|
||||||
"tokenOptions": {
|
|
||||||
"message": "代币选项"
|
|
||||||
},
|
|
||||||
"tokenSymbol": {
|
"tokenSymbol": {
|
||||||
"message": "代币符号"
|
"message": "代币符号"
|
||||||
},
|
},
|
||||||
|
@ -1508,9 +1508,9 @@ describe('MetaMask', function () {
|
|||||||
|
|
||||||
describe('Hide token', function () {
|
describe('Hide token', function () {
|
||||||
it('hides the token when clicked', async 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
|
// wait for confirm hide modal to be visible
|
||||||
const confirmHideModal = await driver.findVisibleElement('span .modal');
|
const confirmHideModal = await driver.findVisibleElement('span .modal');
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.token-options {
|
.asset-options {
|
||||||
&__button {
|
&__button {
|
||||||
font-size: $font-size-paragraph;
|
font-size: $font-size-paragraph;
|
||||||
color: $Black-100;
|
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 React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
import TransactionList from '../../../components/app/transaction-list';
|
import TransactionList from '../../../components/app/transaction-list';
|
||||||
import { EthOverview } from '../../../components/app/wallet-overview';
|
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 { DEFAULT_ROUTE } from '../../../helpers/constants/routes';
|
||||||
|
|
||||||
import AssetNavigation from './asset-navigation';
|
import AssetNavigation from './asset-navigation';
|
||||||
|
import AssetOptions from './asset-options';
|
||||||
|
|
||||||
export default function NativeAsset({ nativeCurrency }) {
|
export default function NativeAsset({ nativeCurrency }) {
|
||||||
const selectedAccountName = useSelector(
|
const selectedAccountName = useSelector(
|
||||||
(state) => getSelectedIdentity(state).name,
|
(state) => getSelectedIdentity(state).name,
|
||||||
);
|
);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const chainId = useSelector(getCurrentChainId);
|
||||||
|
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider);
|
||||||
|
const address = useSelector(getSelectedAddress);
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -22,6 +33,19 @@ export default function NativeAsset({ nativeCurrency }) {
|
|||||||
accountName={selectedAccountName}
|
accountName={selectedAccountName}
|
||||||
assetName={nativeCurrency}
|
assetName={nativeCurrency}
|
||||||
onBack={() => history.push(DEFAULT_ROUTE)}
|
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" />
|
<EthOverview className="asset__overview" />
|
||||||
<TransactionList hideTokenTransactions />
|
<TransactionList hideTokenTransactions />
|
||||||
|
@ -14,7 +14,7 @@ import { DEFAULT_ROUTE } from '../../../helpers/constants/routes';
|
|||||||
import { showModal } from '../../../store/actions';
|
import { showModal } from '../../../store/actions';
|
||||||
|
|
||||||
import AssetNavigation from './asset-navigation';
|
import AssetNavigation from './asset-navigation';
|
||||||
import TokenOptions from './token-options';
|
import AssetOptions from './asset-options';
|
||||||
|
|
||||||
export default function TokenAsset({ token }) {
|
export default function TokenAsset({ token }) {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@ -31,7 +31,7 @@ export default function TokenAsset({ token }) {
|
|||||||
assetName={token.symbol}
|
assetName={token.symbol}
|
||||||
onBack={() => history.push(DEFAULT_ROUTE)}
|
onBack={() => history.push(DEFAULT_ROUTE)}
|
||||||
optionsButton={
|
optionsButton={
|
||||||
<TokenOptions
|
<AssetOptions
|
||||||
onRemove={() =>
|
onRemove={() =>
|
||||||
dispatch(showModal({ name: 'HIDE_TOKEN_CONFIRMATION', token }))
|
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