Skip to content

Commit

Permalink
Address book send plus contact list (#6914)
Browse files Browse the repository at this point in the history
* Style Send Header

* Move Send to-row to send view and restyle

* Add "Recents" group to select recipient view

* Rename SendToRow to AddRecipient

* Basic UI and Layout

* New ENSInput component

* wip - fuzzy search for input

* small refactor

* Add Dialog

* contact list initial

* initial error on invalid address

* clean up edit

* Click to open modal

* Create AddToAddressBookModal component

* Modal styling and layout

* modal i18n

* Add to Addressbook

* ens wip

* ens wip

* ENS Resolution

* Reset input

* Send to explicit address

* Happy Path Complete

* Add back error checking

* Reset send-to when emptying input

* Add back warning object

* Fix linter

* Fix unit test #1 - fix import paths

* Remove dead tests

* One more to go

* Fix all unit tests

* add unit test for reducers and actions

* test rendering AddRecipient

* Add tests for dialog boxes in AddRecipient

* Add test for validating

* Fix linter

* Fix e2e tests

* Token send e2e fix

* Style View Contact

* Style edit-contact

* Fix e2e

* Fix from-import-beta-ui e2e spec

* Make section header say "add recipient” by default

* Auto-focus add recipient input

* Update placeholder text

* Update input title font size

* Auto advance to next step if user paste a valid address

* Ellipsify address when recipient is selected

* Fix app header background color on desktop

* Give each form row a margin of 16px

* Use .container/.component naming pattern for ens-input

* Auto-focus on input when add to addressbook modal is opened; Save on Enter

* Fix and add unit test

* Fix selectors name in e2e tests

* Correct e2e test token amount for address-book-send changes

* Adds e2e test for editing a transaction

* Delete test/integration/lib/send-new-ui.js

* Add tests for amount max button and high value error on send screen to test/e2e/metamask-ui.spec.js

* lint and revert to address as object keys

* add chainId based on current network to address book entry

* fix test

* only display contacts for the current network

* Improve ENS message when not found on current network

* Add error to indicate when network does not support ENS

* bump gaba

* address book, resolve comments

* Move contact-list to its own component

* De-duplicate getaddressbook selector and refactor name selection logic in contact-list-tab/

* Use contact-list component in contact-list-tab.component (i.e. in settings)

* Improve/fix settings headers for popup and browser views

* Lint fixes related to address book updates

* Add 'My accounts' page to settings address book

* Update add new contact button in settings to match floating circular design

* Improve styles of view contact page

* Improve styles and labels of the add-contact.component

* Further lint fixes related to address book updates

* Update unit tests as per address book updates

* Ensure that contact list groups are sorted alphabetically

* Refactor settings component to use a container for connection to redux; allow display of addressbook name in settings header

* Decouple ens-input.component from send context

* Add ens resolution to add contact screen in settings

* Switching networks when an ens address is shown on send form removes the ens address.

* Resolve send screen search for ensAddress to matching address book entry if it exists

* Show resolved ens icon and address if exists (settings: add-contact.component)

* Make the displayed and copied address in view-contact.component the checksummed address

* Default alias state prop in AddToAddressBookModal to empty string

* Use keyCode to detect enter key in AddToAddressBookModal

* Ensure add-contact component properly updates after QR code detection

* Fix display of all recents after clicking 'Load More' in contact list

* Fix send screen contact searching after network switching

* Code cleanup related to address book changes

* Update unit tests for address book changes

* Update ENS name not found on network message

* Add ens registration error message

* Cancel on edit mode takes user back to view screen

* Adds support for memo to settings contact list view and edit screens

* Modify designs of edit and view contact in popup environment

* Update settings content list UX to show split columns in fullscreen and proper internal navigation

* Correct background address book API usages in UI
  • Loading branch information
danjm authored Jul 31, 2019
1 parent 1fd3dc9 commit e9c7df2
Show file tree
Hide file tree
Showing 98 changed files with 4,147 additions and 1,001 deletions.
81 changes: 81 additions & 0 deletions app/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,21 @@
"activityLog": {
"message": "activity log"
},
"add": {
"message": "Add"
},
"address": {
"message": "Address"
},
"addNetwork": {
"message": "Add Network"
},
"addRecipient": {
"message": "Add Recipient"
},
"addressBook": {
"message": "Address Book"
},
"advanced": {
"message": "Advanced"
},
Expand All @@ -98,6 +107,18 @@
"addCustomToken": {
"message": "Add custom token"
},
"addToAddressBook": {
"message": "Add to address book"
},
"addToAddressBookModalPlaceholder": {
"message": "e.g. John D."
},
"addAlias": {
"message": "Add alias"
},
"addEthAddress": {
"message": "Add an Ethereum address"
},
"addToken": {
"message": "Add Token"
},
Expand Down Expand Up @@ -172,6 +193,9 @@
"back": {
"message": "Back"
},
"backToAll": {
"message": "Back to All"
},
"balance": {
"message": "Balance"
},
Expand Down Expand Up @@ -354,6 +378,12 @@
"connectToTrezor": {
"message": "Connect to Trezor"
},
"contactList": {
"message": "Contact List"
},
"contactListDescription": {
"message": "Add, edit, remove, and manage your contacts"
},
"continue": {
"message": "Continue"
},
Expand Down Expand Up @@ -463,6 +493,9 @@
"delete": {
"message": "Delete"
},
"deleteAccount": {
"message": "Delete Account"
},
"denExplainer": {
"message": "Your DEN is your password-encrypted storage within MetaMask."
},
Expand Down Expand Up @@ -529,6 +562,9 @@
"editAccountName": {
"message": "Edit Account Name"
},
"editContact":{
"message": "Edit Contact"
},
"editingTransaction": {
"message": "Make changes to your transaction"
},
Expand Down Expand Up @@ -571,6 +607,15 @@
"ensNameNotFound": {
"message": "ENS name not found"
},
"ensRegistrationError": {
"message": "Error in ENS name registration"
},
"ensNotFoundOnCurrentNetwork": {
"message": "ENS name not found on the current network. Try switching to Main Ethereum Network."
},
"enterAnAlias": {
"message": "Enter an alias"
},
"enterPassword": {
"message": "Enter password"
},
Expand All @@ -583,6 +628,9 @@
"eth": {
"message": "ETH"
},
"ethereumPublicAddress": {
"message": "Ethereum Public Address"
},
"etherscanView": {
"message": "View account on Etherscan"
},
Expand Down Expand Up @@ -893,6 +941,9 @@
"loadingTokens": {
"message": "Loading Tokens..."
},
"loadMore": {
"message": "Load More"
},
"localhost": {
"message": "Localhost 8545"
},
Expand All @@ -914,6 +965,9 @@
"memorizePhrase": {
"message": "Memorize this phrase."
},
"memo": {
"message": "memo"
},
"menu": {
"message": "Menu"
},
Expand Down Expand Up @@ -947,6 +1001,12 @@
"myAccounts": {
"message": "My Accounts"
},
"myWalletAccounts": {
"message": "My Wallet Accounts"
},
"myWalletAccountsDescription": {
"message": "All of your MetaMask created accounts will automatically be added to this section."
},
"mustSelectOne": {
"message": "Must select at least 1 token."
},
Expand Down Expand Up @@ -979,10 +1039,16 @@
"newAccount": {
"message": "New Account"
},
"newAccountDetectedDialogMessage": {
"message": "New address detected! Click here to add to your address book."
},
"newAccountNumberName": {
"message": "Account $1",
"description": "Default name of next account to be created on create account screen"
},
"newContact": {
"message": "New Contact"
},
"newContract": {
"message": "New Contract"
},
Expand Down Expand Up @@ -1193,9 +1259,15 @@
"receive": {
"message": "Receive"
},
"recents": {
"message": "Recents"
},
"recipientAddress": {
"message": "Recipient Address"
},
"recipientAddressPlaceholder": {
"message": "Search, public address (0x), or ENS"
},
"refundAddress": {
"message": "Your Refund Address"
},
Expand Down Expand Up @@ -1670,6 +1742,9 @@
"transfer": {
"message": "Transfer"
},
"transferBetweenAccounts": {
"message": "Transfer between my accounts"
},
"transferFrom": {
"message": "Transfer From"
},
Expand Down Expand Up @@ -1750,6 +1825,9 @@
"useOldUI": {
"message": "Use old UI"
},
"userName":{
"message": "Username"
},
"validFileImport": {
"message": "You must select a valid file to import."
},
Expand All @@ -1762,6 +1840,9 @@
"viewinExplorer": {
"message": "View in Explorer"
},
"viewContact": {
"message": "View Contact"
},
"viewOnCustomBlockExplorer": {
"message": "View at $1"
},
Expand Down
4 changes: 4 additions & 0 deletions app/images/check-green-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions app/images/close-gray.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions app/images/qr-blue.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions app/images/search-black.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ module.exports = class MetamaskController extends EventEmitter {

// AddressController
setAddressBook: this.addressBookController.set.bind(this.addressBookController),
removeFromAddressBook: this.addressBookController.delete.bind(this.addressBookController),

// AppStateController
setLastActiveTime: nodeify(this.appStateController.setLastActiveTime, this.appStateController),
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
"extensionizer": "^1.0.1",
"fast-json-patch": "^2.0.4",
"fuse.js": "^3.2.0",
"gaba": "^1.4.1",
"gaba": "^1.5.0",
"human-standard-token-abi": "^2.0.0",
"jazzicon": "^1.2.0",
"json-rpc-engine": "^4.0.0",
Expand Down
3 changes: 2 additions & 1 deletion test/data/mock-state.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@
"addressBook": [
{
"address": "0xc42edfcc21ed14dda456aa0756c153f7985d8813",
"name": ""
"name": "",
"chainId": 4
}
],
"selectedTokenAddress": "0x108cf70c7d384c552f42c07c41c0e1e46d77ea0d",
Expand Down
9 changes: 7 additions & 2 deletions test/e2e/from-import-ui.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,14 @@ describe('Using MetaMask with an existing account', function () {
await sendButton.click()
await delay(regularDelayMs)

const inputAddress = await findElement(driver, By.css('input[placeholder="Recipient Address"]'))
const inputAmount = await findElement(driver, By.css('.unit-input__input'))
const inputAddress = await findElement(driver, By.css('input[placeholder="Search, public address (0x), or ENS"]'))
await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970')

const recipientRow = await findElement(driver, By.css('.send__select-recipient-wrapper__group-item'))
await recipientRow.click()
await delay(regularDelayMs)

const inputAmount = await findElement(driver, By.css('.unit-input__input'))
await inputAmount.sendKeys('1')

// Set the gas limit
Expand Down
9 changes: 7 additions & 2 deletions test/e2e/metamask-responsive-ui.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,14 @@ describe('MetaMask', function () {
await sendButton.click()
await delay(regularDelayMs)

const inputAddress = await findElement(driver, By.css('input[placeholder="Recipient Address"]'))
const inputAmount = await findElement(driver, By.css('.unit-input__input'))
const inputAddress = await findElement(driver, By.css('input[placeholder="Search, public address (0x), or ENS"]'))
await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970')

const recipientRow = await findElement(driver, By.css('.send__select-recipient-wrapper__group-item'))
await recipientRow.click()
await delay(regularDelayMs)

const inputAmount = await findElement(driver, By.css('.unit-input__input'))
await inputAmount.sendKeys('1')

const inputValue = await inputAmount.getAttribute('value')
Expand Down
65 changes: 56 additions & 9 deletions test/e2e/metamask-ui.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,12 +322,44 @@ describe('MetaMask', function () {
await sendButton.click()
await delay(regularDelayMs)

const inputAddress = await findElement(driver, By.css('input[placeholder="Recipient Address"]'))
const inputAmount = await findElement(driver, By.css('.unit-input__input'))
const inputAddress = await findElement(driver, By.css('input[placeholder="Search, public address (0x), or ENS"]'))
await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970')

const recipientRow = await findElement(driver, By.css('.send__select-recipient-wrapper__group-item'))
await recipientRow.click()
await delay(regularDelayMs)

const inputAmount = await findElement(driver, By.css('.unit-input__input'))
await inputAmount.sendKeys('1000')

const errorAmount = await findElement(driver, By.css('.send-v2__error-amount'))
assert.equal(await errorAmount.getText(), 'Insufficient funds.', 'send screen should render an insufficient fund error message')

await inputAmount.sendKeys(Key.BACK_SPACE)
await delay(50)
await inputAmount.sendKeys(Key.BACK_SPACE)
await delay(50)
await inputAmount.sendKeys(Key.BACK_SPACE)
await delay(tinyDelayMs)

await assertElementNotPresent(webdriver, driver, By.css('.send-v2__error-amount'))

const amountMax = await findElement(driver, By.css('.send-v2__amount-max'))
await amountMax.click()

assert.equal(await inputAmount.isEnabled(), false)

let inputValue = await inputAmount.getAttribute('value')

assert(Number(inputValue) > 99)

await amountMax.click()

assert.equal(await inputAmount.isEnabled(), true)

await inputAmount.sendKeys('1')

const inputValue = await inputAmount.getAttribute('value')
inputValue = await inputAmount.getAttribute('value')
assert.equal(inputValue, '1')
await delay(regularDelayMs)

Expand Down Expand Up @@ -360,9 +392,14 @@ describe('MetaMask', function () {
await sendButton.click()
await delay(regularDelayMs)

const inputAddress = await findElement(driver, By.css('input[placeholder="Recipient Address"]'))
const inputAmount = await findElement(driver, By.css('.unit-input__input'))
const inputAddress = await findElement(driver, By.css('input[placeholder="Search, public address (0x), or ENS"]'))
await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970')

const recipientRow = await findElement(driver, By.css('.send__select-recipient-wrapper__group-item'))
await recipientRow.click()
await delay(regularDelayMs)

const inputAmount = await findElement(driver, By.css('.unit-input__input'))
await inputAmount.sendKeys('1')

const inputValue = await inputAmount.getAttribute('value')
Expand Down Expand Up @@ -402,9 +439,14 @@ describe('MetaMask', function () {
await sendButton.click()
await delay(regularDelayMs)

const inputAddress = await findElement(driver, By.css('input[placeholder="Recipient Address"]'))
const inputAmount = await findElement(driver, By.css('.unit-input__input'))
const inputAddress = await findElement(driver, By.css('input[placeholder="Search, public address (0x), or ENS"]'))
await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970')

const recipientRow = await findElement(driver, By.css('.send__select-recipient-wrapper__group-item'))
await recipientRow.click()
await delay(regularDelayMs)

const inputAmount = await findElement(driver, By.css('.unit-input__input'))
await inputAmount.sendKeys('1')

const inputValue = await inputAmount.getAttribute('value')
Expand Down Expand Up @@ -1005,9 +1047,14 @@ describe('MetaMask', function () {
await sendButton.click()
await delay(regularDelayMs)

const inputAddress = await findElement(driver, By.css('input[placeholder="Recipient Address"]'))
const inputAmount = await findElement(driver, By.css('.unit-input__input'))
const inputAddress = await findElement(driver, By.css('input[placeholder="Search, public address (0x), or ENS"]'))
await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970')

const recipientRow = await findElement(driver, By.css('.send__select-recipient-wrapper__group-item'))
await recipientRow.click()
await delay(regularDelayMs)

const inputAmount = await findElement(driver, By.css('.unit-input__input'))
await inputAmount.sendKeys('1')

// Set the gas limit
Expand Down
Loading

0 comments on commit e9c7df2

Please sign in to comment.