Skip to content

Commit

Permalink
Redesign approve screen (#7271)
Browse files Browse the repository at this point in the history
* Redesign approve screen

* Add translations to approve screen components

* Show account in header of approve screen

* Use state prop bool for unlimited vs custom check in edit-approval-permission

* Set option to custom on input change in edit-approval-permission

* Allow setting of approval amount to unlimited in edit-approval-permission

* Fix height of confirm-approval popup

* Ensure decimals prop passted to confirm-approve.component is correct type

* Ensure first param passed to calcTokenValue in confirm-approve.util is the correct type

* Fix e2e test of permission editing

* Remove unused code from edit-approval-permission.container
  • Loading branch information
danjm authored Nov 5, 2019
1 parent 99b8f2d commit 2673eef
Show file tree
Hide file tree
Showing 28 changed files with 1,340 additions and 73 deletions.
50 changes: 50 additions & 0 deletions app/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
"acceleratingATransaction": {
"message": "* Accelerating a transaction by using a higher gas price increases its chances of getting processed by the network faster, but it is not always guaranteed."
},
"accessAndSpendNotice": {
"message": "$1 may access and spend up to this max amount",
"description": "$1 is the url of the site requesting ability to spend"
},
"accessingYourCamera": {
"message": "Accessing your camera..."
},
Expand Down Expand Up @@ -113,9 +117,20 @@
"addAcquiredTokens": {
"message": "Add the tokens you've acquired using MetaMask"
},
"allowOriginSpendToken": {
"message": "Allow $1 to spend your $2?",
"description": "$1 is the url of the site and $2 is the symbol of the token they are requesting to spend"
},
"allowWithdrawAndSpend": {
"message": "Allow $1 to withdraw and spend up to the following amount:",
"description": "The url of the site that requested permission to 'withdraw and spend'"
},
"amount": {
"message": "Amount"
},
"amountWithColon": {
"message": "Amount:"
},
"appDescription": {
"message": "An Ethereum Wallet in your Browser",
"description": "The description of the application"
Expand Down Expand Up @@ -384,6 +399,9 @@
"customRPC": {
"message": "Custom RPC"
},
"customSpendLimit": {
"message": "Custom Spend Limit"
},
"dataBackupFoundInfo": {
"message": "Some of your account data was backed up during a previous installation of MetaMask. This could include your settings, contacts and tokens. Would you like to restore this data now?"
},
Expand Down Expand Up @@ -444,6 +462,9 @@
"editContact": {
"message": "Edit Contact"
},
"editPermission": {
"message": "Edit Permission"
},
"emailUs": {
"message": "Email us!"
},
Expand Down Expand Up @@ -486,6 +507,9 @@
"enterAnAlias": {
"message": "Enter an alias"
},
"enterMaxSpendLimit": {
"message": "Enter Max Spend Limit"
},
"enterPassword": {
"message": "Enter password"
},
Expand Down Expand Up @@ -516,6 +540,9 @@
"faster": {
"message": "Faster"
},
"feeAssociatedRequest": {
"message": "A fee is associated with this request."
},
"fiat": {
"message": "Fiat",
"description": "Exchange type"
Expand All @@ -533,6 +560,9 @@
"fromShapeShift": {
"message": "From ShapeShift"
},
"functionApprove": {
"message": "Function: Approve"
},
"functionType": {
"message": "Function Type"
},
Expand Down Expand Up @@ -953,6 +983,9 @@
"privateNetwork": {
"message": "Private Network"
},
"proposedApprovalLimit": {
"message": "Proposed Approval Limit"
},
"qrCode": {
"message": "Show QR Code"
},
Expand Down Expand Up @@ -1212,6 +1245,13 @@
"speedUpTransaction": {
"message": "Speed up this transaction"
},
"spendLimitPermission": {
"message": "Spend limit permission"
},
"spendLimitRequestedBy": {
"message": "Spend limit requested by $1",
"description": "Origin of the site requesting the spend limit"
},
"switchNetworks": {
"message": "Switch Networks"
},
Expand Down Expand Up @@ -1308,6 +1348,9 @@
"to": {
"message": "To"
},
"toWithColon": {
"message": "To:"
},
"toETHviaShapeShift": {
"message": "$1 to ETH via ShapeShift",
"description": "system will fill in deposit type in start of message"
Expand Down Expand Up @@ -1382,6 +1425,10 @@
"message": "We had trouble loading your token balances. You can view them ",
"description": "Followed by a link (here) to view token balances"
},
"trustSiteApprovePermission": {
"message": "Do you trust this site? By granting this permission, you’re allowing $1 to withdraw your $2 and automate transactions for you.",
"description": "$1 is the url requesting permission and $2 is the symbol of the currency that the request is for"
},
"tryAgain": {
"message": "Try again"
},
Expand Down Expand Up @@ -1409,6 +1456,9 @@
"unknownCameraError": {
"message": "There was an error while trying to access your camera. Please try again..."
},
"unlimited": {
"message": "Unlimited"
},
"unlock": {
"message": "Unlock"
},
Expand Down
3 changes: 3 additions & 0 deletions app/images/user-check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
71 changes: 43 additions & 28 deletions test/e2e/metamask-ui.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1124,8 +1124,8 @@ describe('MetaMask', function () {
await driver.switchTo().window(dapp)
await delay(tinyDelayMs)

const transferTokens = await findElement(driver, By.xpath(`//button[contains(text(), 'Approve Tokens')]`))
await transferTokens.click()
const approveTokens = await findElement(driver, By.xpath(`//button[contains(text(), 'Approve Tokens')]`))
await approveTokens.click()

await driver.switchTo().window(extension)
await delay(regularDelayMs)
Expand All @@ -1143,31 +1143,22 @@ describe('MetaMask', function () {
})

it('displays the token approval data', async () => {
const dataTab = await findElement(driver, By.xpath(`//li[contains(text(), 'Data')]`))
dataTab.click()
const fullTxDataButton = await findElement(driver, By.css('.confirm-approve-content__view-full-tx-button'))
await fullTxDataButton.click()
await delay(regularDelayMs)

const functionType = await findElement(driver, By.css('.confirm-page-container-content__function-type'))
const functionType = await findElement(driver, By.css('.confirm-approve-content__data .confirm-approve-content__small-text'))
const functionTypeText = await functionType.getText()
assert.equal(functionTypeText, 'Approve')
assert.equal(functionTypeText, 'Function: Approve')

const confirmDataDiv = await findElement(driver, By.css('.confirm-page-container-content__data-box'))
const confirmDataDiv = await findElement(driver, By.css('.confirm-approve-content__data__data-block'))
const confirmDataText = await confirmDataDiv.getText()
assert(confirmDataText.match(/0x095ea7b30000000000000000000000009bc5baf874d2da8d216ae9f137804184ee5afef4/))

const detailsTab = await findElement(driver, By.xpath(`//li[contains(text(), 'Details')]`))
detailsTab.click()
await delay(regularDelayMs)

const approvalWarning = await findElement(driver, By.css('.confirm-page-container-warning__warning'))
const approvalWarningText = await approvalWarning.getText()
assert(approvalWarningText.match(/By approving this/))
await delay(regularDelayMs)
})

it('opens the gas edit modal', async () => {
const configureGas = await driver.wait(until.elementLocated(By.css('.confirm-detail-row__header-text--edit')))
await configureGas.click()
const editButtons = await findElements(driver, By.css('.confirm-approve-content__small-blue-text.cursor-pointer'))
await editButtons[0].click()
await delay(regularDelayMs)

gasModal = await driver.findElement(By.css('span .modal'))
Expand Down Expand Up @@ -1198,14 +1189,34 @@ describe('MetaMask', function () {
await save.click()
await driver.wait(until.stalenessOf(gasModal))

const gasFeeInputs = await findElements(driver, By.css('.confirm-detail-row__primary'))
assert.equal(await gasFeeInputs[0].getText(), '0.0006')
const gasFeeInEth = await findElement(driver, By.css('.confirm-approve-content__transaction-details-content__secondary-fee'))
assert.equal(await gasFeeInEth.getText(), '0.0006')
})

it('shows the correct recipient', async function () {
const senderToRecipientDivs = await findElements(driver, By.css('.sender-to-recipient__name'))
const recipientDiv = senderToRecipientDivs[1]
assert.equal(await recipientDiv.getText(), '0x9bc5...fEF4')
it('edits the permission', async () => {
const editButtons = await findElements(driver, By.css('.confirm-approve-content__small-blue-text.cursor-pointer'))
await editButtons[1].click()
await delay(regularDelayMs)

const permissionModal = await driver.findElement(By.css('span .modal'))

const radioButtons = await findElements(driver, By.css('.edit-approval-permission__edit-section__radio-button'))
await radioButtons[1].click()

const customInput = await findElement(driver, By.css('input'))
await delay(50)
await customInput.sendKeys('5')
await delay(regularDelayMs)

const saveButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Save')]`))
await saveButton.click()
await delay(regularDelayMs)

await driver.wait(until.stalenessOf(permissionModal))

const permissionInfo = await findElements(driver, By.css('.confirm-approve-content__medium-text'))
const amountDiv = permissionInfo[0]
assert.equal(await amountDiv.getText(), '5 TST')
})

it('submits the transaction', async function () {
Expand All @@ -1221,7 +1232,7 @@ describe('MetaMask', function () {
}, 10000)

const txValues = await findElements(driver, By.css('.transaction-list-item__amount--primary'))
await driver.wait(until.elementTextMatches(txValues[0], /-7\s*TST/))
await driver.wait(until.elementTextMatches(txValues[0], /-5\s*TST/))
const txStatuses = await findElements(driver, By.css('.transaction-list-item__action'))
await driver.wait(until.elementTextMatches(txStatuses[0], /Approve/))
})
Expand Down Expand Up @@ -1305,9 +1316,13 @@ describe('MetaMask', function () {
})

it('shows the correct recipient', async function () {
const senderToRecipientDivs = await findElements(driver, By.css('.sender-to-recipient__name'))
const recipientDiv = senderToRecipientDivs[1]
assert.equal(await recipientDiv.getText(), 'Account 2')
const fullTxDataButton = await findElement(driver, By.css('.confirm-approve-content__view-full-tx-button'))
await fullTxDataButton.click()
await delay(regularDelayMs)

const permissionInfo = await findElements(driver, By.css('.confirm-approve-content__medium-text'))
const recipientDiv = permissionInfo[1]
assert.equal(await recipientDiv.getText(), '0x2f318C33...C970')
})

it('submits the transaction', async function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

.confirm-page-container-content {
overflow-y: auto;
height: 100%;
flex: 1;

&__error-container {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@ import {
ENVIRONMENT_TYPE_NOTIFICATION,
} from '../../../../../../app/scripts/lib/enums'
import NetworkDisplay from '../../network-display'
import Identicon from '../../../ui/identicon'
import { addressSlicer } from '../../../../helpers/utils/util'

export default class ConfirmPageContainerHeader extends Component {
static contextTypes = {
t: PropTypes.func,
}

static propTypes = {
accountAddress: PropTypes.string,
showAccountInHeader: PropTypes.bool,
showEdit: PropTypes.bool,
onEdit: PropTypes.func,
children: PropTypes.node,
}

renderTop () {
const { onEdit, showEdit } = this.props
const { onEdit, showEdit, accountAddress, showAccountInHeader } = this.props
const windowType = window.METAMASK_UI_TYPE
const isFullScreen = windowType !== ENVIRONMENT_TYPE_NOTIFICATION &&
windowType !== ENVIRONMENT_TYPE_POPUP
Expand All @@ -29,22 +33,39 @@ export default class ConfirmPageContainerHeader extends Component {

return (
<div className="confirm-page-container-header__row">
<div
className="confirm-page-container-header__back-button-container"
style={{
visibility: showEdit ? 'initial' : 'hidden',
}}
>
<img
src="/images/caret-left.svg"
/>
<span
className="confirm-page-container-header__back-button"
onClick={() => onEdit()}
{ !showAccountInHeader
? <div
className="confirm-page-container-header__back-button-container"
style={{
visibility: showEdit ? 'initial' : 'hidden',
}}
>
{ this.context.t('edit') }
</span>
</div>
<img
src="/images/caret-left.svg"
/>
<span
className="confirm-page-container-header__back-button"
onClick={() => onEdit()}
>
{ this.context.t('edit') }
</span>
</div>
: null
}
{ showAccountInHeader
? <div className="confirm-page-container-header__address-container">
<div className="confirm-page-container-header__address-identicon">
<Identicon
address={accountAddress}
diameter={24}
/>
</div>
<div className="confirm-page-container-header__address">
{ addressSlicer(accountAddress) }
</div>
</div>
: null
}
{ !isFullScreen && <NetworkDisplay /> }
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
border-bottom: 1px solid $geyser;
padding: 4px 13px 4px 13px;
flex: 0 0 auto;
align-items: center;
}

&__back-button-container {
Expand All @@ -28,4 +29,16 @@
font-weight: 400;
padding-left: 5px;
}

&__address-container {
display: flex;
align-items: center;
margin-top: 2px;
margin-bottom: 2px;
}

&__address {
margin-left: 6px;
font-size: 14px;
}
}
Loading

0 comments on commit 2673eef

Please sign in to comment.