1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 01:39:44 +01:00

Implement new fullscreen design (#8657)

The fullscreen UI now shows roughly the same design as the popup UI.
A few additional changes depicted in the new fullscreen designs will
be implemented in subsequent PRs (e.g. the inline buttons on assets)

This was done now to make asset pages easier to implement. Implementing
asset pages solely for the popup UI would have been complicated by the
fact that we use viewport size to switch between the two layouts, so we
would have had to re-route upon resizing the window.
This commit is contained in:
Mark Stacey 2020-05-27 17:28:33 -03:00 committed by GitHub
parent 398f2647c0
commit a0d64c7932
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 101 additions and 609 deletions

View File

@ -154,7 +154,6 @@
"react-dom": "^16.12.0",
"react-idle-timer": "^4.2.5",
"react-inspector": "^2.3.0",
"react-media": "^1.8.0",
"react-popper": "^2.2.3",
"react-redux": "^7.2.0",
"react-router-dom": "^5.1.2",

View File

@ -195,6 +195,7 @@ describe('MetaMask', function () {
})
it('finds the transaction in the transactions list', async function () {
await driver.clickElement(By.css('[data-testid="home__history-tab"]'))
await driver.wait(async () => {
const confirmedTxes = await driver.findElements(By.css('.transaction-list__completed-transactions .transaction-list-item'))
return confirmedTxes.length === 1

View File

@ -16,7 +16,7 @@ async function measurePage (pageName) {
const passwordField = await driver.findElement(By.css('#password'))
await passwordField.sendKeys('correct horse battery staple')
await passwordField.sendKeys(Key.ENTER)
await driver.findElement(By.css('.account-details__account-name'))
await driver.findElement(By.css('.selected-account__name'))
await driver.navigate(pageName)
await driver.delay(1000)
metrics = await driver.collectMetrics()

View File

@ -84,8 +84,8 @@ describe('MetaMask', function () {
await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.remindMeLater.message}')]`))
await driver.delay(regularDelayMs)
await driver.clickElement(By.css('.account-details__details-button'))
await driver.delay(regularDelayMs)
await driver.clickElement(By.css('[data-testid="account-options-menu-button"]'))
await driver.clickElement(By.css('[data-testid="account-options-menu__account-details"]'))
})
it('gets the current accounts address', async function () {

View File

@ -98,7 +98,8 @@ describe('Using MetaMask with an existing account', function () {
describe('Show account information', function () {
it('shows the correct account address', async function () {
await driver.clickElement(By.css('.account-details__details-button'))
await driver.clickElement(By.css('[data-testid="account-options-menu-button"]'))
await driver.clickElement(By.css('[data-testid="account-options-menu__account-details"]'))
await driver.findVisibleElement(By.css('.qr-wrapper'))
await driver.delay(regularDelayMs)
@ -110,7 +111,8 @@ describe('Using MetaMask with an existing account', function () {
})
it('shows a QR code for the account', async function () {
await driver.clickElement(By.css('.account-details__details-button'))
await driver.clickElement(By.css('[data-testid="account-options-menu-button"]'))
await driver.clickElement(By.css('[data-testid="account-options-menu__account-details"]'))
await driver.findVisibleElement(By.css('.qr-wrapper'))
const detailModal = await driver.findElement(By.css('span .modal'))
await driver.delay(regularDelayMs)
@ -167,7 +169,7 @@ describe('Using MetaMask with an existing account', function () {
})
it('should show the correct account name', async function () {
const [accountName] = await driver.findElements(By.css('.account-details__account-name'))
const accountName = await driver.findElement(By.css('.selected-account__name'))
assert.equal(await accountName.getText(), '2nd account')
await driver.delay(regularDelayMs)
})
@ -214,6 +216,7 @@ describe('Using MetaMask with an existing account', function () {
})
it('finds the transaction in the transactions list', async function () {
await driver.clickElement(By.css('[data-testid="home__history-tab"]'))
await driver.wait(async () => {
const confirmedTxes = await driver.findElements(By.css('.transaction-list__completed-transactions .transaction-list-item'))
return confirmedTxes.length === 1
@ -243,23 +246,26 @@ describe('Using MetaMask with an existing account', function () {
})
it('should show the correct account name', async function () {
const [accountName] = await driver.findElements(By.css('.account-details__account-name'))
const accountName = await driver.findElement(By.css('.selected-account__name'))
assert.equal(await accountName.getText(), 'Account 4')
await driver.delay(regularDelayMs)
})
it('should show the imported label', async function () {
const [importedLabel] = await driver.findElements(By.css('.account-details__keyring-label'))
await driver.clickElement(By.css('.account-menu__icon'))
// confirm 4th account is account 4, as expected
const accountMenuItemSelector = '.account-menu__account:nth-child(4)'
const accountName = await driver.findElement(By.css(`${accountMenuItemSelector} .account-menu__name`))
assert.equal(await accountName.getText(), 'Account 4')
// confirm label is present on the same menu item
const importedLabel = await driver.findElement(By.css(`${accountMenuItemSelector} .keyring-label`))
assert.equal(await importedLabel.getText(), 'IMPORTED')
await driver.delay(regularDelayMs)
})
})
describe('Imports and removes an account', function () {
it('choose Create Account from the account menu', async function () {
await driver.clickElement(By.css('.account-menu__icon'))
await driver.delay(regularDelayMs)
await driver.clickElement(By.xpath(`//div[contains(text(), 'Import Account')]`))
await driver.delay(regularDelayMs)
})
@ -273,7 +279,7 @@ describe('Using MetaMask with an existing account', function () {
})
it('should open the remove account modal', async function () {
const [accountName] = await driver.findElements(By.css('.account-details__account-name'))
const accountName = await driver.findElement(By.css('.selected-account__name'))
assert.equal(await accountName.getText(), 'Account 5')
await driver.delay(regularDelayMs)
@ -294,7 +300,7 @@ describe('Using MetaMask with an existing account', function () {
await driver.delay(regularDelayMs)
const [accountName] = await driver.findElements(By.css('.account-details__account-name'))
const accountName = await driver.findElement(By.css('.selected-account__name'))
assert.equal(await accountName.getText(), 'Account 1')
await driver.delay(regularDelayMs)

View File

@ -90,8 +90,8 @@ describe('MetaMask', function () {
await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.remindMeLater.message}')]`))
await driver.delay(regularDelayMs)
await driver.clickElement(By.css('.account-details__details-button'))
await driver.delay(regularDelayMs)
await driver.clickElement(By.css('[data-testid="account-options-menu-button"]'))
await driver.clickElement(By.css('[data-testid="account-options-menu__account-details"]'))
})
it('gets the current accounts address', async function () {

View File

@ -119,7 +119,8 @@ describe('MetaMask', function () {
describe('Show account information', function () {
it('shows the QR code for the account', async function () {
await driver.clickElement(By.css('.account-details__details-button'))
await driver.clickElement(By.css('[data-testid="account-options-menu-button"]'))
await driver.clickElement(By.css('[data-testid="account-options-menu__account-details"]'))
await driver.findVisibleElement(By.css('.qr-wrapper'))
await driver.delay(regularDelayMs)
@ -169,7 +170,7 @@ describe('MetaMask', function () {
})
it('should display correct account name', async function () {
const accountName = await driver.findElement(By.css('.account-details__account-name'))
const accountName = await driver.findElement(By.css('.selected-account__name'))
assert.equal(await accountName.getText(), '2nd account')
await driver.delay(regularDelayMs)
})
@ -265,6 +266,7 @@ describe('MetaMask', function () {
})
it('finds the transaction in the transactions list', async function () {
await driver.clickElement(By.css('[data-testid="home__history-tab"]'))
await driver.wait(async () => {
const confirmedTxes = await driver.findElements(By.css('.transaction-list__completed-transactions .transaction-list-item'))
return confirmedTxes.length === 1
@ -810,6 +812,7 @@ describe('MetaMask', function () {
})
it('clicks on the Add Token button', async function () {
await driver.clickElement(By.css(`[data-testid="home__asset-tab"]`))
await driver.clickElement(By.xpath(`//button[contains(text(), 'Add Token')]`))
await driver.delay(regularDelayMs)
})
@ -900,6 +903,7 @@ describe('MetaMask', function () {
})
it('finds the transaction in the transactions list', async function () {
await driver.clickElement(By.css(`[data-testid="home__history-tab"]`))
await driver.wait(async () => {
const confirmedTxes = await driver.findElements(By.css('.transaction-list__completed-transactions .transaction-list-item'))
return confirmedTxes.length === 1
@ -992,6 +996,8 @@ describe('MetaMask', function () {
const txStatuses = await driver.findElements(By.css('.list-item__heading'))
await driver.wait(until.elementTextMatches(txStatuses[0], /Send\sTST/), 10000)
await driver.clickElement(By.css('[data-testid="home__asset-tab"]'))
await driver.clickElement(By.css('[data-testid="wallet-balance"]'))
await driver.clickElement(By.css('.token-cell'))
@ -1019,6 +1025,8 @@ describe('MetaMask', function () {
await driver.switchToWindow(extension)
await driver.delay(regularDelayMs)
await driver.clickElement(By.css('[data-testid="home__history-tab"]'))
await driver.wait(async () => {
const pendingTxes = await driver.findElements(By.css('.transaction-list__pending-transactions .transaction-list-item'))
return pendingTxes.length === 1
@ -1219,6 +1227,8 @@ describe('MetaMask', function () {
describe('Hide token', function () {
it('hides the token when clicked', async function () {
await driver.clickElement(By.css('[data-testid="home__asset-tab"]'))
await driver.clickElement(By.css('.token-cell__ellipsis'))
const byTokenMenuDropdownOption = By.css('.menu__item--clickable')

View File

@ -85,8 +85,8 @@ describe('MetaMask', function () {
await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.remindMeLater.message}')]`))
await driver.delay(regularDelayMs)
await driver.clickElement(By.css('.account-details__details-button'))
await driver.delay(regularDelayMs)
await driver.clickElement(By.css('[data-testid="account-options-menu-button"]'))
await driver.clickElement(By.css('[data-testid="account-options-menu__account-details"]'))
})
it('gets the current accounts address', async function () {
@ -132,7 +132,8 @@ describe('MetaMask', function () {
})
it('shows connected sites', async function () {
await driver.clickElement(By.xpath(`//button[contains(text(), 'Connected sites')]`))
await driver.clickElement(By.css('[data-testid="account-options-menu-button"]'))
await driver.clickElement(By.css('[data-testid="account-options-menu__connected-sites"]'))
await driver.findElement(By.xpath(`//h2[contains(text(), 'Connected sites')]`))

View File

@ -197,6 +197,7 @@ describe('Using MetaMask with an existing account', function () {
})
it('finds the transaction in the transactions list', async function () {
await driver.clickElement(By.css('[data-testid="home__history-tab"]'))
await driver.wait(async () => {
const confirmedTxes = await driver.findElements(By.css('.transaction-list__completed-transactions .transaction-list-item'))
return confirmedTxes.length === 1

View File

@ -120,7 +120,8 @@ describe('MetaMask', function () {
})
it('gets the current accounts address', async function () {
await driver.clickElement(By.css('.account-details__details-button'))
await driver.clickElement(By.css('[data-testid="account-options-menu-button"]'))
await driver.clickElement(By.css('[data-testid="account-options-menu__account-details"]'))
await driver.delay(regularDelayMs)
const addressInput = await driver.findElement(By.css('.qr-ellip-address'))

View File

@ -22,6 +22,7 @@ describe('MetaMask Browser Extension', function () {
await amountField.sendKeys('1')
await driver.clickElement(By.css('[data-testid="page-container-footer-next"]'))
await driver.clickElement(By.css('[data-testid="page-container-footer-next"]'))
await driver.clickElement(By.css('[data-testid="home__history-tab"]'))
await driver.findElement(By.css('.transaction-list-item'))
})
})

View File

@ -1,67 +0,0 @@
const reactTriggerChange = require('../../lib/react-trigger-change')
const {
queryAsync,
findAsync,
} = require('../../lib/util')
const fetchMockResponses = require('../../data/fetch-mocks.json')
QUnit.module('tx list items')
QUnit.test('renders list items successfully', (assert) => {
const done = assert.async()
runTxListItemsTest(assert).then(done).catch((err) => {
assert.notOk(err, `Error was thrown: ${err.stack}`)
done()
})
})
global.ethQuery = global.ethQuery || {}
global.ethQuery.getTransactionCount = (_, cb) => {
cb(null, '0x4')
}
async function runTxListItemsTest (assert) {
console.log('*** start runTxListItemsTest')
const selectState = await queryAsync($, 'select')
selectState.val('tx list items')
reactTriggerChange(selectState[0])
const realFetch = window.fetch.bind(window)
window.fetch = (...args) => {
if (args[0] === 'https://ethgasstation.info/json/ethgasAPI.json') {
return Promise.resolve({ json: () => Promise.resolve(JSON.parse(fetchMockResponses.ethGasBasic)) })
} else if (args[0] === 'https://ethgasstation.info/json/predictTable.json') {
return Promise.resolve({ json: () => Promise.resolve(JSON.parse(fetchMockResponses.ethGasPredictTable)) })
} else if (args[0].match(/chromeextensionmm/)) {
return Promise.resolve({ json: () => Promise.resolve(JSON.parse(fetchMockResponses.metametrics)) })
}
return realFetch.fetch(...args)
}
const metamaskLogo = await queryAsync($, '.app-header__logo-container')
assert.ok(metamaskLogo[0], 'metamask logo present')
metamaskLogo[0].click()
const txListItems = await queryAsync($, '.transaction-list-item')
assert.equal(txListItems.length, 6, 'all tx list items are rendered')
const unapprovedMsg = txListItems[0]
const unapprovedMsgDescription = await findAsync($(unapprovedMsg), '.transaction-list-item__status--unapproved')
assert.equal(unapprovedMsgDescription[0].textContent, 'Unapproved', 'unapprovedMsg has correct description')
const approvedTx = txListItems[2]
const approvedTxRenderedStatus = await findAsync($(approvedTx), '.transaction-list-item__status--queued')
assert.equal(approvedTxRenderedStatus[0].textContent, 'Queued', 'approvedTx has correct label')
const confirmedTokenTx1 = txListItems[4]
const confirmedTokenTx1Token = await findAsync($(confirmedTokenTx1), '.list-item__heading')
const confirmedTokenTx1Address = await findAsync($(confirmedTokenTx1), '.list-item__subheading')
assert.equal(confirmedTokenTx1Token[0].textContent, 'Send FTO ', 'Confirm token symbol is correct')
assert.equal(confirmedTokenTx1Address[0].textContent, 'Mar 29, 2018 · To: 0xe788...81a9', 'confirmedTokenTx has correct status')
const confirmedTokenTx2 = txListItems[5]
const confirmedTokenTx2Address = await findAsync($(confirmedTokenTx2), '.list-item__subheading')
const confirmedTokenTx2Token = await findAsync($(confirmedTokenTx2), '.list-item__heading')
assert.equal(confirmedTokenTx2Token[0].textContent, 'Send FTT ', 'Confirm token symbol is correct')
assert.equal(confirmedTokenTx2Address[0].textContent, 'Mar 29, 2018 · To: 0xe788...81a9', 'confirmedTokenTx has correct status')
}

View File

@ -1,106 +0,0 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import Identicon from '../../ui/identicon'
import Tooltip from '../../ui/tooltip-v2'
import copyToClipboard from 'copy-to-clipboard'
export default class AccountDetails extends Component {
static contextTypes = {
t: PropTypes.func.isRequired,
metricsEvent: PropTypes.func,
}
static defaultProps = {
hideSidebar: () => {},
showAccountDetailModal: () => {},
}
static propTypes = {
hideSidebar: PropTypes.func,
showAccountDetailModal: PropTypes.func,
showConnectedSites: PropTypes.func.isRequired,
label: PropTypes.string.isRequired,
checksummedAddress: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
}
state = {
hasCopied: false,
copyToClipboardPressed: false,
}
copyAddress () {
copyToClipboard(this.props.checksummedAddress)
this.context.metricsEvent({
eventOpts: {
category: 'Navigation',
action: 'Home',
name: 'Copied Address',
},
})
this.setState({ hasCopied: true })
setTimeout(() => this.setState({ hasCopied: false }), 3000)
}
render () {
const { t } = this.context
const {
hideSidebar,
showAccountDetailModal,
showConnectedSites,
label,
checksummedAddress,
name,
} = this.props
const {
hasCopied,
copyToClipboardPressed,
} = this.state
return (
<div>
<div className="flex-column account-details">
<div className="account-details__sidebar-close" onClick={hideSidebar} />
<div className="account-details__keyring-label allcaps">
{label}
</div>
<div className="flex-column flex-center account-details__name-container">
<Identicon diameter={54} address={checksummedAddress} onClick={showAccountDetailModal} />
<span className="account-details__account-name">
{name}
</span>
<div className="account-details__details-buttons">
<button className="btn-secondary account-details__details-button" onClick={showAccountDetailModal} >
{t('details')}
</button>
<button className="btn-secondary account-details__details-button" onClick={showConnectedSites}>
{t('connectedSites')}
</button>
</div>
</div>
</div>
<Tooltip
position="bottom"
title={hasCopied ? t('copiedExclamation') : t('copyToClipboard')}
wrapperClassName="account-details__tooltip"
>
<button
className={classnames({
'account-details__address': true,
'account-details__address__pressed': copyToClipboardPressed,
})}
onClick={() => this.copyAddress()}
onMouseDown={() => this.setState({ copyToClipboardPressed: true })}
onMouseUp={() => this.setState({ copyToClipboardPressed: false })}
>
{checksummedAddress.slice(0, 6)}...{checksummedAddress.slice(-4)}
<i className="fa fa-clipboard" style={{ marginLeft: '8px' }} />
</button>
</Tooltip>
</div>
)
}
}

View File

@ -1,24 +0,0 @@
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { hideSidebar, showModal } from '../../../store/actions'
import AccountDetails from './account-details.component'
function mapDispatchToProps (dispatch) {
return {
hideSidebar: () => dispatch(hideSidebar()),
showAccountDetailModal: () => {
dispatch(showModal({ name: 'ACCOUNT_DETAILS' }))
},
}
}
const AccountDetailsContainer = connect(null, mapDispatchToProps)(AccountDetails)
AccountDetailsContainer.propTypes = {
label: PropTypes.string.isRequired,
checksummedAddress: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
showConnectedSites: PropTypes.func.isRequired,
}
export default AccountDetailsContainer

View File

@ -1 +0,0 @@
export { default } from './account-details.container'

View File

@ -1,85 +0,0 @@
.account-details {
flex: 0 0 auto;
&__keyring-label {
height: 50px;
color: $dusty-gray;
font-family: Roboto;
font-size: 10px;
text-align: right;
padding: 17px 20px 0;
box-sizing: border-box;
}
&__name-container {
flex: 0 0 auto;
cursor: pointer;
width: 100%;
margin: 0 auto;
}
&__account-name {
font-size: 24px;
color: $black;
margin-top: 8px;
margin-bottom: .9rem;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
width: 100%;
padding: 0 8px;
text-align: center;
}
&__details-buttons {
display: flex;
justify-content: space-between;
width: 175px;
}
&__details-button {
font-size: 10px;
border-radius: 17px;
background-color: transparent;
margin: 0 auto;
padding: 4px 12px;
flex: 0 0 auto;
}
&__tooltip {
display: flex;
justify-content: center;
align-items: center;
padding: 24px;
}
&__address {
border-radius: 3px;
background-color: $alto;
color: $scorpion;
font-size: 14px;
line-height: 12px;
padding: 4px 12px;
cursor: pointer;
flex: 0 0 auto;
&__pressed {
background-color: $manatee,
}
}
&__sidebar-close {
@media screen and (max-width: 575px) {
&::after {
content: '\00D7';
font-size: 40px;
color: $tundora;
position: absolute;
top: 12px;
left: 12px;
cursor: pointer;
}
}
}
}

View File

@ -1,5 +1,3 @@
@import 'account-details/index';
@import 'account-menu/index';
@import 'add-token-button/index';

View File

@ -69,6 +69,7 @@ export default function AccountOptionsMenu ({ anchorElement, onClose }) {
{ t('expandView') }
</MenuItem>
<MenuItem
data-testid="account-options-menu__account-details"
onClick={() => {
dispatch(showModal({ name: 'ACCOUNT_DETAILS' }))
viewAccountDetailsEvent()
@ -102,6 +103,7 @@ export default function AccountOptionsMenu ({ anchorElement, onClose }) {
}
</MenuItem>
<MenuItem
data-testid="account-options-menu__connected-sites"
onClick={() => {
openConnectedSitesEvent()
history.push(CONNECTED_ROUTE)

View File

@ -6,49 +6,35 @@
height: 54px;
min-width: 0;
@media screen and (max-width: $break-small) {
flex-direction: column;
height: initial;
width: 100%;
}
flex-direction: column;
height: initial;
width: 100%;
&__balance {
flex: 1;
display: flex;
flex-direction: row;
flex-direction: column;
align-items: center;
min-width: 0;
@media screen and (max-width: $break-small) {
flex-direction: column;
width: 100%;
}
width: 100%;
}
&__buttons {
display: flex;
flex-direction: row;
@media screen and (max-width: $break-small) {
margin-bottom: 16px;
}
margin-bottom: 16px;
}
}
.eth-overview {
&__balance {
margin: 0 12px;
display: flex;
flex-direction: column;
min-width: 0;
position: relative;
@media screen and (max-width: $break-small) {
align-items: center;
margin: 16px 0;
padding: 0 16px;
max-width: 100%;
}
align-items: center;
margin: 16px 0;
padding: 0 16px;
max-width: 100%;
}
&__primary-container {
@ -56,15 +42,11 @@
}
&__primary-balance {
font-size: 1.5rem;
color: $black;
@media screen and (max-width: $break-small) {
font-size: 32px;
line-height: 45px;
width: 100%;
justify-content: center;
}
font-size: 32px;
line-height: 45px;
width: 100%;
justify-content: center;
}
&__cached-star {
@ -100,30 +82,22 @@
.token-overview {
&__balance {
margin: 0 12px;
display: flex;
flex-direction: column;
min-width: 0;
position: relative;
@media screen and (max-width: $break-small) {
align-items: center;
margin: 16px 0;
padding: 0 16px;
max-width: 100%;
}
align-items: center;
margin: 16px 0;
padding: 0 16px;
max-width: 100%;
}
&__primary-balance {
font-size: 1.5rem;
color: $black;
@media screen and (max-width: $break-small) {
font-size: 32px;
line-height: 45px;
width: 100%;
justify-content: center;
}
font-size: 32px;
line-height: 45px;
width: 100%;
justify-content: center;
}
&__button {

View File

@ -1 +0,0 @@
export { default } from './wallet-view.container'

View File

@ -1,72 +0,0 @@
import classnames from 'classnames'
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import AccountDetails from '../account-details'
import { checksumAddress } from '../../../helpers/utils/util'
import AssetList from '../asset-list'
import { CONNECTED_ROUTE } from '../../../helpers/constants/routes'
export default class WalletView extends Component {
static contextTypes = {
t: PropTypes.func,
metricsEvent: PropTypes.func,
}
static defaultProps = {
responsiveDisplayClassname: '',
}
static propTypes = {
history: PropTypes.object.isRequired,
identities: PropTypes.object.isRequired,
keyrings: PropTypes.array.isRequired,
responsiveDisplayClassname: PropTypes.string,
selectedAddress: PropTypes.string.isRequired,
}
showConnectedSites = () => {
const { history } = this.props
history.push(CONNECTED_ROUTE)
}
render () {
const {
identities,
keyrings,
responsiveDisplayClassname,
selectedAddress,
} = this.props
const checksummedAddress = checksumAddress(selectedAddress)
const keyring = keyrings.find((kr) => {
return kr.accounts.includes(selectedAddress)
})
let label = ''
let type
if (keyring) {
type = keyring.type
if (type !== 'HD Key Tree') {
if (type.toLowerCase().search('hardware') !== -1) {
label = this.context.t('hardware')
} else {
label = this.context.t('imported')
}
}
}
return (
<div className={classnames('wallet-view', 'flex-column', responsiveDisplayClassname)}>
<AccountDetails
label={label}
checksummedAddress={checksummedAddress}
name={identities[selectedAddress].name}
showConnectedSites={this.showConnectedSites}
/>
<AssetList />
</div>
)
}
}

View File

@ -1,18 +0,0 @@
import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
import { compose } from 'redux'
import WalletView from './wallet-view.component'
import { getSelectedAddress } from '../../../selectors'
function mapStateToProps (state) {
return {
identities: state.metamask.identities,
keyrings: state.metamask.keyrings,
selectedAddress: getSelectedAddress(state),
}
}
export default compose(
withRouter,
connect(mapStateToProps)
)(WalletView)

View File

@ -2,8 +2,8 @@ import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
const MenuItem = ({ children, className, iconClassName, onClick, subtitle }) => (
<button className={classnames('menu-item', className)} onClick={onClick}>
const MenuItem = ({ children, className, 'data-testid': dataTestId, iconClassName, onClick, subtitle }) => (
<button className={classnames('menu-item', className)} data-testid={dataTestId} onClick={onClick}>
{
iconClassName
? (
@ -19,6 +19,7 @@ const MenuItem = ({ children, className, iconClassName, onClick, subtitle }) =>
MenuItem.propTypes = {
children: PropTypes.node.isRequired,
className: PropTypes.string,
'data-testid': PropTypes.string,
iconClassName: PropTypes.string,
onClick: PropTypes.func,
subtitle: PropTypes.node,
@ -26,6 +27,7 @@ MenuItem.propTypes = {
MenuItem.defaultProps = {
className: undefined,
'data-testid': undefined,
iconClassName: undefined,
onClick: undefined,
subtitle: undefined,

View File

@ -5,9 +5,6 @@ $sub-mid-size-breakpoint-range: "screen and (min-width: #{$break-large}) and (ma
NewUI Container Elements
*/
// Component Colors
$wallet-view-bg: $alabaster;
.app {
display: flex;
flex-direction: column;
@ -35,77 +32,6 @@ $wallet-view-bg: $alabaster;
width: 100%;
}
// wallet view and sidebar
.wallet-view {
display: flex;
flex-direction: column;
flex: 32 1 32%;
width: 0;
background: $wallet-view-bg;
z-index: 200;
position: relative;
[dir='rtl'] & i.fa.fa-clipboard {
/*rtl:ignore*/
margin-left: 0 !important;
/*rtl:ignore*/
margin-right: 8px !important;
}
@media screen and (min-width: 576px) {
overflow-y: scroll;
overflow-x: hidden;
}
@media #{$sub-mid-size-breakpoint-range} {
min-width: 160px;
}
}
@media screen and (min-width: 576px) {
.wallet-view::-webkit-scrollbar {
display: none;
}
}
.wallet-view-title-wrapper {
flex: 0 0 25px;
}
.wallet-view-title {
margin-left: 15px;
font-size: 16px;
// No title on mobile
@media screen and (max-width: 575px) {
display: none;
}
}
.wallet-view.sidebar-right {
flex: 1 0 230px;
background: rgb(250, 250, 250);
z-index: $sidebar-z-index;
position: fixed;
top: 66px;
left: 0;
right: 0;
bottom: 0;
opacity: 1;
visibility: visible;
will-change: transform;
overflow-y: auto;
box-shadow: rgba(0, 0, 0, .15) 2px 2px 4px;
width: 85%;
height: calc(100% - 56px);
[dir='rtl'] & {
/* rtl:ignore */
left: 15%;
}
}
// main-container media queries
@media screen and (min-width: 576px) {

View File

@ -1,12 +1,10 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import Media from 'react-media'
import { Redirect, Route } from 'react-router-dom'
import { formatDate } from '../../helpers/utils/util'
import AssetList from '../../components/app/asset-list'
import HomeNotification from '../../components/app/home-notification'
import MultipleNotifications from '../../components/app/multiple-notifications'
import WalletView from '../../components/app/wallet-view'
import TransactionList from '../../components/app/transaction-list'
import MenuBar from '../../components/app/menu-bar'
import Popover from '../../components/ui/popover'
@ -238,52 +236,30 @@ export default class Home extends PureComponent {
<Route path={CONNECTED_ACCOUNTS_ROUTE} component={ConnectedAccounts} exact />
<div className="home__container">
{ isPopup && !connectedStatusPopoverHasBeenShown ? this.renderPopover() : null }
<Media
query="(min-width: 576px)"
>
{
(isWideViewport) => (
isWideViewport
? (
<>
<WalletView />
<div className="home__main-view">
<div className="home__balance-wrapper">
{ homeOverview }
</div>
<TransactionList isWideViewport />
</div>
</>
)
: (
<div className="home__main-view">
<MenuBar />
<div className="home__balance-wrapper">
{ homeOverview }
</div>
<Tabs defaultActiveTabName={defaultHomeActiveTabName} onTabClick={onTabClick}>
<Tab
activeClassName="home__tab--active"
className="home__tab"
data-testid="home__asset-tab"
name="Assets"
>
<AssetList />
</Tab>
<Tab
activeClassName="home__tab--active"
className="home__tab"
data-testid="home__history-tab"
name="History"
>
<TransactionList />
</Tab>
</Tabs>
</div>
)
)
}
</Media>
<div className="home__main-view">
<MenuBar />
<div className="home__balance-wrapper">
{ homeOverview }
</div>
<Tabs defaultActiveTabName={defaultHomeActiveTabName} onTabClick={onTabClick}>
<Tab
activeClassName="home__tab--active"
className="home__tab"
data-testid="home__asset-tab"
name="Assets"
>
<AssetList />
</Tab>
<Tab
activeClassName="home__tab--active"
className="home__tab"
data-testid="home__history-tab"
name="History"
>
<TransactionList />
</Tab>
</Tabs>
</div>
{ this.renderNotifications() }
</div>
</div>

View File

@ -13,23 +13,12 @@
}
&__balance-wrapper {
@media screen and (max-width: $break-small) {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
flex: 0 0 auto;
padding-top: 16px;
}
@media screen and (min-width: $break-large) {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
margin: 2.3em 2.37em .8em;
flex: 0 0 auto;
}
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
flex: 0 0 auto;
padding-top: 16px;
}
// TODO: fix style import order so this isn't required to override specificity of `tab` class

View File

@ -16059,13 +16059,6 @@ json-text-sequence@~0.1.0:
dependencies:
delimit-stream "0.1.0"
json2mq@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/json2mq/-/json2mq-0.2.0.tgz#b637bd3ba9eabe122c83e9720483aeb10d2c904a"
integrity sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=
dependencies:
string-convert "^0.2.0"
json3@^3.3.2:
version "3.3.3"
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
@ -22560,15 +22553,6 @@ react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4:
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
react-media@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/react-media/-/react-media-1.8.0.tgz#b86d6d62313f95d53af7d06e23d4f49adfb131d3"
integrity sha512-XcfqkDQj5/hmJod/kXUAZljJyMVkWrBWOkzwynAR8BXOGlbFLGBwezM0jQHtp2BrSymhf14/XrQrb3gGBnGK4g==
dependencies:
invariant "^2.2.2"
json2mq "^0.2.0"
prop-types "^15.5.10"
react-motion@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.5.2.tgz#0dd3a69e411316567927917c6626551ba0607316"
@ -25470,11 +25454,6 @@ strict-uri-encode@^1.0.0:
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
string-convert@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/string-convert/-/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97"
integrity sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=
string-template@~0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add"