From df85ab6e106d1644f6f0fbca8f188e5402602bea Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Mon, 1 Jun 2020 14:54:32 -0300 Subject: [PATCH] Implement asset page (#8696) A new page has been created for viewing assets. This replaces the old `selectedToken` state, which previously would augment the home page to show token-specific information. The new asset page shows the standard token overview as seen previously on the home page, plus a history filtered to show just transactions relevant to that token. The actions that were available in the old token list menu have been moved to a "Token Options" menu that mirrors the "Account Options" menu. The `selectedTokenAddress` state has been removed, as it is no longer being used for anything. `getMetaMetricState` has been renamed to `getBackgroundMetaMetricState` because its sole purpose is extracting data from the background state to send metrics from the background. It's not really a selector, but it was convenient for it to use the same selectors the UI uses to extract background data, so I left it there for now. A new Redux store has been added to track state related to browser history. The most recent "overview" page (i.e. the home page or the asset page) is currently being tracked, so that actions taken from the asset page can return the user back to the asset page when the action has finished. --- app/_locales/am/messages.json | 3 - app/_locales/ar/messages.json | 3 - app/_locales/bg/messages.json | 3 - app/_locales/bn/messages.json | 3 - app/_locales/ca/messages.json | 3 - app/_locales/cs/messages.json | 3 - app/_locales/da/messages.json | 3 - app/_locales/de/messages.json | 3 - app/_locales/el/messages.json | 3 - app/_locales/en/messages.json | 8 ++- app/_locales/es/messages.json | 3 - app/_locales/es_419/messages.json | 3 - app/_locales/et/messages.json | 3 - app/_locales/fa/messages.json | 3 - app/_locales/fi/messages.json | 3 - app/_locales/fil/messages.json | 3 - app/_locales/fr/messages.json | 3 - app/_locales/he/messages.json | 3 - app/_locales/hi/messages.json | 3 - app/_locales/hn/messages.json | 3 - app/_locales/hr/messages.json | 3 - app/_locales/ht/messages.json | 3 - app/_locales/hu/messages.json | 3 - app/_locales/id/messages.json | 3 - app/_locales/it/messages.json | 3 - app/_locales/ja/messages.json | 3 - app/_locales/kn/messages.json | 3 - app/_locales/ko/messages.json | 3 - app/_locales/lt/messages.json | 3 - app/_locales/lv/messages.json | 3 - app/_locales/ms/messages.json | 3 - app/_locales/nl/messages.json | 3 - app/_locales/no/messages.json | 3 - app/_locales/ph/messages.json | 3 - app/_locales/pl/messages.json | 3 - app/_locales/pt/messages.json | 3 - app/_locales/pt_BR/messages.json | 3 - app/_locales/ro/messages.json | 3 - app/_locales/ru/messages.json | 3 - app/_locales/sk/messages.json | 3 - app/_locales/sl/messages.json | 3 - app/_locales/sr/messages.json | 3 - app/_locales/sv/messages.json | 3 - app/_locales/sw/messages.json | 3 - app/_locales/ta/messages.json | 3 - app/_locales/th/messages.json | 3 - app/_locales/tr/messages.json | 3 - app/_locales/uk/messages.json | 3 - app/_locales/vi/messages.json | 3 - app/_locales/zh_CN/messages.json | 3 - app/_locales/zh_TW/messages.json | 3 - app/scripts/background.js | 1 - app/scripts/lib/backend-metametrics.js | 4 +- development/states/confirm-sig-requests.json | 3 + development/states/currency-localization.json | 3 + test/data/mock-state.json | 1 - test/e2e/metamask-ui.spec.js | 18 +---- test/unit/ui/app/reducers/metamask.spec.js | 9 --- .../app/asset-list-item/asset-list-item.js | 12 +--- .../app/asset-list-item/asset-list-item.scss | 11 ++- .../components/app/asset-list/asset-list.js | 20 +++--- .../app/dropdowns/token-menu-dropdown.js | 67 ------------------- ui/app/components/app/menu-bar/index.scss | 2 - .../signature-request-original.component.js | 12 ++-- .../signature-request-original.container.js | 2 + .../app/token-cell/token-cell.component.js | 30 --------- .../app/token-cell/token-cell.container.js | 1 - .../components/app/token-cell/token-cell.scss | 4 -- .../app/token-cell/token-cell.test.js | 1 - .../app/wallet-overview/eth-overview.js | 10 ++- .../components/app/wallet-overview/index.scss | 8 ++- .../app/wallet-overview/token-overview.js | 14 ++-- .../app/wallet-overview/wallet-overview.js | 10 ++- ui/app/contexts/metametrics.js | 4 +- ui/app/ducks/history/history.js | 38 +++++++++++ ui/app/ducks/index.js | 2 + ui/app/ducks/metamask/metamask.js | 57 ++++++++-------- ui/app/helpers/constants/routes.js | 2 + ui/app/helpers/utils/util.js | 4 -- ui/app/pages/add-token/add-token.component.js | 7 +- ui/app/pages/add-token/add-token.container.js | 6 +- .../pages/add-token/tests/add-token.test.js | 1 + ui/app/pages/asset/asset.js | 65 ++++++++++++++++++ ui/app/pages/asset/asset.scss | 45 +++++++++++++ .../asset/components/asset-breadcrumb.js | 25 +++++++ .../asset/components/asset-navigation.js | 26 +++++++ .../pages/asset/components/token-options.js | 59 ++++++++++++++++ ui/app/pages/asset/index.js | 1 + .../confirm-add-suggested-token.component.js | 12 ++-- .../confirm-add-suggested-token.container.js | 6 +- .../confirm-add-token.component.js | 16 +++-- .../confirm-add-token.container.js | 6 +- .../confirm-decrypt-message.component.js | 23 ++++--- .../confirm-decrypt-message.container.js | 2 + ...confirm-encryption-public-key.component.js | 23 ++++--- ...confirm-encryption-public-key.container.js | 2 + .../confirm-transaction-base.component.js | 15 +++-- .../confirm-transaction-base.container.js | 2 + ui/app/pages/confirm-transaction/conf-tx.js | 13 ++-- .../confirm-transaction.component.js | 10 +-- .../confirm-transaction.container.js | 2 + .../connected-accounts.component.js | 6 +- .../connected-accounts.container.js | 2 + .../connected-sites.container.js | 7 +- .../create-account/connect-hardware/index.js | 12 ++-- .../create-account/import-account/json.js | 19 ++++-- .../import-account/private-key.js | 11 +-- .../create-account/new-account.component.js | 8 +-- .../create-account/new-account.container.js | 2 + ui/app/pages/home/home.component.js | 21 ++---- ui/app/pages/home/home.container.js | 2 - ui/app/pages/home/index.scss | 1 - ui/app/pages/index.scss | 2 + ui/app/pages/keychains/reveal-seed.js | 15 +++-- .../mobile-sync/mobile-sync.component.js | 6 +- .../mobile-sync/mobile-sync.container.js | 2 + ui/app/pages/routes/routes.component.js | 7 +- ui/app/pages/routes/routes.container.js | 2 + .../send-asset-row.container.js | 4 +- .../send/send-footer/send-footer.component.js | 8 ++- .../send/send-footer/send-footer.container.js | 2 + .../tests/send-footer-component.test.js | 5 +- .../send/send-header/send-header.component.js | 7 +- .../send/send-header/send-header.container.js | 2 + .../tests/send-header-component.test.js | 4 +- .../tests/send-header-container.test.js | 47 ------------- ui/app/pages/settings/settings.component.js | 6 +- ui/app/pages/settings/settings.container.js | 2 + ui/app/selectors/selectors.js | 24 +------ .../tests/send-selectors-test-data.js | 1 - ui/app/store/actionConstants.js | 2 +- ui/app/store/actions.js | 24 +++---- 132 files changed, 583 insertions(+), 555 deletions(-) delete mode 100644 ui/app/components/app/dropdowns/token-menu-dropdown.js create mode 100644 ui/app/ducks/history/history.js create mode 100644 ui/app/pages/asset/asset.js create mode 100644 ui/app/pages/asset/asset.scss create mode 100644 ui/app/pages/asset/components/asset-breadcrumb.js create mode 100644 ui/app/pages/asset/components/asset-navigation.js create mode 100644 ui/app/pages/asset/components/token-options.js create mode 100644 ui/app/pages/asset/index.js delete mode 100644 ui/app/pages/send/send-header/tests/send-header-container.test.js diff --git a/app/_locales/am/messages.json b/app/_locales/am/messages.json index 9d8f0017c..7d30ec452 100644 --- a/app/_locales/am/messages.json +++ b/app/_locales/am/messages.json @@ -519,9 +519,6 @@ "hide": { "message": "ደብቅ" }, - "hideToken": { - "message": "ተለዋጭ ስም ደብቅ" - }, "hideTokenPrompt": { "message": "ተለዋጭ ስም ይደበቅ?" }, diff --git a/app/_locales/ar/messages.json b/app/_locales/ar/messages.json index 1b1e987f3..a4ff5b403 100644 --- a/app/_locales/ar/messages.json +++ b/app/_locales/ar/messages.json @@ -515,9 +515,6 @@ "hide": { "message": "إخفاء" }, - "hideToken": { - "message": "إخفاء الرمز" - }, "hideTokenPrompt": { "message": "أتريد إخفاء العملة الرمزية؟" }, diff --git a/app/_locales/bg/messages.json b/app/_locales/bg/messages.json index 657b1d8fa..44feb5321 100644 --- a/app/_locales/bg/messages.json +++ b/app/_locales/bg/messages.json @@ -515,9 +515,6 @@ "hide": { "message": "Скриване" }, - "hideToken": { - "message": "Скриване на жетон" - }, "hideTokenPrompt": { "message": "Скриване на жетон?" }, diff --git a/app/_locales/bn/messages.json b/app/_locales/bn/messages.json index b10527c63..1b98f11c2 100644 --- a/app/_locales/bn/messages.json +++ b/app/_locales/bn/messages.json @@ -519,9 +519,6 @@ "hide": { "message": "লুকান" }, - "hideToken": { - "message": "টোকেন লুকান" - }, "hideTokenPrompt": { "message": "টোকেন লুকাবেন?" }, diff --git a/app/_locales/ca/messages.json b/app/_locales/ca/messages.json index 587d38834..11c658aa8 100644 --- a/app/_locales/ca/messages.json +++ b/app/_locales/ca/messages.json @@ -506,9 +506,6 @@ "hide": { "message": "Amaga" }, - "hideToken": { - "message": "Amagar Fitxa" - }, "hideTokenPrompt": { "message": "Amagar fitxa?" }, diff --git a/app/_locales/cs/messages.json b/app/_locales/cs/messages.json index 36bdeb957..cf2cb9b05 100644 --- a/app/_locales/cs/messages.json +++ b/app/_locales/cs/messages.json @@ -197,9 +197,6 @@ "hide": { "message": "Skrýt" }, - "hideToken": { - "message": "Skrýt token" - }, "hideTokenPrompt": { "message": "Skrýt token?" }, diff --git a/app/_locales/da/messages.json b/app/_locales/da/messages.json index 24e090b7b..92867354d 100644 --- a/app/_locales/da/messages.json +++ b/app/_locales/da/messages.json @@ -512,9 +512,6 @@ "hide": { "message": "Skjul" }, - "hideToken": { - "message": "Skjul token" - }, "hideTokenPrompt": { "message": "Skjul Token?" }, diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index 9ee94993f..8778d28fc 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -504,9 +504,6 @@ "hide": { "message": "Ausblenden" }, - "hideToken": { - "message": "Token ausblenden" - }, "hideTokenPrompt": { "message": "Token ausblenden?" }, diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index 59279bfc8..f0ca2ba3b 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -516,9 +516,6 @@ "hide": { "message": "Απόκρυψη" }, - "hideToken": { - "message": "Απόκρυψη Token" - }, "hideTokenPrompt": { "message": "Απόκρυψη του Token;" }, diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 3dec8bb4c..6ec3bb0e2 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -759,8 +759,9 @@ "hide": { "message": "Hide" }, - "hideToken": { - "message": "Hide Token" + "hideTokenSymbol": { + "message": "Hide $1", + "description": "$1 is the symbol for a token (e.g. 'DAI')" }, "hideTokenPrompt": { "message": "Hide Token?" @@ -1544,6 +1545,9 @@ "tokenContractAddress": { "message": "Token Contract Address" }, + "tokenOptions": { + "message": "Token options" + }, "tokenSymbol": { "message": "Token Symbol" }, diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index c76af937c..8c52642d6 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -419,9 +419,6 @@ "hide": { "message": "Ocultar" }, - "hideToken": { - "message": "Ocultar token" - }, "hideTokenPrompt": { "message": "¿Ocultar token?" }, diff --git a/app/_locales/es_419/messages.json b/app/_locales/es_419/messages.json index 9e0518930..88f08edd6 100644 --- a/app/_locales/es_419/messages.json +++ b/app/_locales/es_419/messages.json @@ -510,9 +510,6 @@ "hide": { "message": "Ocultar" }, - "hideToken": { - "message": "Ocultar token" - }, "hideTokenPrompt": { "message": "¿Ocultar token?" }, diff --git a/app/_locales/et/messages.json b/app/_locales/et/messages.json index 573aec5a5..cd2fd0611 100644 --- a/app/_locales/et/messages.json +++ b/app/_locales/et/messages.json @@ -515,9 +515,6 @@ "hide": { "message": "Peida" }, - "hideToken": { - "message": "Peida luba" - }, "hideTokenPrompt": { "message": "Peida luba?" }, diff --git a/app/_locales/fa/messages.json b/app/_locales/fa/messages.json index 15ba69a13..81570c579 100644 --- a/app/_locales/fa/messages.json +++ b/app/_locales/fa/messages.json @@ -519,9 +519,6 @@ "hide": { "message": "عدم نمایش" }, - "hideToken": { - "message": "مخفی سازی رمزیاب" - }, "hideTokenPrompt": { "message": "آیا رمزیاب مخفی شود؟" }, diff --git a/app/_locales/fi/messages.json b/app/_locales/fi/messages.json index be5d42d85..dad9c42b5 100644 --- a/app/_locales/fi/messages.json +++ b/app/_locales/fi/messages.json @@ -516,9 +516,6 @@ "hide": { "message": "Piilota" }, - "hideToken": { - "message": "Piilota tietue" - }, "hideTokenPrompt": { "message": "Piilotetaanko tietue?" }, diff --git a/app/_locales/fil/messages.json b/app/_locales/fil/messages.json index a69789cf2..9f8cd1f2a 100644 --- a/app/_locales/fil/messages.json +++ b/app/_locales/fil/messages.json @@ -479,9 +479,6 @@ "hide": { "message": "Itago" }, - "hideToken": { - "message": "Itago ang Token" - }, "hideTokenPrompt": { "message": "Itago ang Token?" }, diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index c24c6f088..76273f0d0 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -504,9 +504,6 @@ "hide": { "message": "Cacher" }, - "hideToken": { - "message": "Masquer le jeton" - }, "hideTokenPrompt": { "message": "Masquer le jeton?" }, diff --git a/app/_locales/he/messages.json b/app/_locales/he/messages.json index cf6dcd7b8..74f6fc9eb 100644 --- a/app/_locales/he/messages.json +++ b/app/_locales/he/messages.json @@ -519,9 +519,6 @@ "hide": { "message": "הסתר" }, - "hideToken": { - "message": "הסתר טוקן" - }, "hideTokenPrompt": { "message": "להסתיר טוקן?" }, diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index 7af47defc..6df3a9cbd 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -519,9 +519,6 @@ "hide": { "message": "छुपाएं" }, - "hideToken": { - "message": "टोकन छिपाएँ?" - }, "hideTokenPrompt": { "message": "टोकन छिपाएँ?" }, diff --git a/app/_locales/hn/messages.json b/app/_locales/hn/messages.json index a2847d2dd..81d190e0d 100644 --- a/app/_locales/hn/messages.json +++ b/app/_locales/hn/messages.json @@ -173,9 +173,6 @@ "hide": { "message": "छुपाएं" }, - "hideToken": { - "message": "टोकन छिपाएं" - }, "hideTokenPrompt": { "message": "टोकन छिपाएंn?" }, diff --git a/app/_locales/hr/messages.json b/app/_locales/hr/messages.json index 82427724e..df0e4af15 100644 --- a/app/_locales/hr/messages.json +++ b/app/_locales/hr/messages.json @@ -515,9 +515,6 @@ "hide": { "message": "Sakrij preglednik" }, - "hideToken": { - "message": "Sakrij token" - }, "hideTokenPrompt": { "message": "Sakriti token?" }, diff --git a/app/_locales/ht/messages.json b/app/_locales/ht/messages.json index ef26d522f..a2526ad88 100644 --- a/app/_locales/ht/messages.json +++ b/app/_locales/ht/messages.json @@ -287,9 +287,6 @@ "hide": { "message": "Kache" }, - "hideToken": { - "message": "Kache Token" - }, "hideTokenPrompt": { "message": "Kache Token?" }, diff --git a/app/_locales/hu/messages.json b/app/_locales/hu/messages.json index 0a75b0739..bbeb0710a 100644 --- a/app/_locales/hu/messages.json +++ b/app/_locales/hu/messages.json @@ -515,9 +515,6 @@ "hide": { "message": "Elrejtés" }, - "hideToken": { - "message": "Token elrejtése" - }, "hideTokenPrompt": { "message": "Elrejted a tokent?" }, diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index 706e801da..44c7416f4 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -506,9 +506,6 @@ "hide": { "message": "Sembunyikan" }, - "hideToken": { - "message": "Sembunyikan Token" - }, "hideTokenPrompt": { "message": "Sembunyikan Token?" }, diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json index b0e8428a4..0e2b45233 100644 --- a/app/_locales/it/messages.json +++ b/app/_locales/it/messages.json @@ -633,9 +633,6 @@ "hide": { "message": "Nascondi" }, - "hideToken": { - "message": "Nascondi Token" - }, "hideTokenPrompt": { "message": "Nascondi Token?" }, diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index 5d7d77d6a..fbb551299 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -242,9 +242,6 @@ "hide": { "message": "隠す" }, - "hideToken": { - "message": "トークンを隠す" - }, "hideTokenPrompt": { "message": "トークンを隠しますか?" }, diff --git a/app/_locales/kn/messages.json b/app/_locales/kn/messages.json index 0858c2c67..fd1b6110d 100644 --- a/app/_locales/kn/messages.json +++ b/app/_locales/kn/messages.json @@ -519,9 +519,6 @@ "hide": { "message": "ಮರೆಮಾಡಿ" }, - "hideToken": { - "message": "ಟೋಕನ್ ಮರೆಮಾಡಿ" - }, "hideTokenPrompt": { "message": "ಟೋಕನ್ ಮರೆಮಾಡುವುದೇ?" }, diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index 81633cf59..6fbe305be 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -513,9 +513,6 @@ "hide": { "message": "숨기기" }, - "hideToken": { - "message": "토큰 숨기기" - }, "hideTokenPrompt": { "message": "토큰 숨기기?" }, diff --git a/app/_locales/lt/messages.json b/app/_locales/lt/messages.json index 1bb4d0b9a..fcc5b33f6 100644 --- a/app/_locales/lt/messages.json +++ b/app/_locales/lt/messages.json @@ -519,9 +519,6 @@ "hide": { "message": "Slėpti" }, - "hideToken": { - "message": "Slėpti prieigos raktą" - }, "hideTokenPrompt": { "message": "Slėpti prieigos raktą?" }, diff --git a/app/_locales/lv/messages.json b/app/_locales/lv/messages.json index ffc0a8189..38895f49e 100644 --- a/app/_locales/lv/messages.json +++ b/app/_locales/lv/messages.json @@ -515,9 +515,6 @@ "hide": { "message": "Slēpt" }, - "hideToken": { - "message": "Paslēpt marķieri" - }, "hideTokenPrompt": { "message": "Paslēpt žetonu?" }, diff --git a/app/_locales/ms/messages.json b/app/_locales/ms/messages.json index 01bc6789c..1071db2bd 100644 --- a/app/_locales/ms/messages.json +++ b/app/_locales/ms/messages.json @@ -503,9 +503,6 @@ "hide": { "message": "Sembunyikan" }, - "hideToken": { - "message": "Sembunyikan Token" - }, "hideTokenPrompt": { "message": "Sembunyikan Token?" }, diff --git a/app/_locales/nl/messages.json b/app/_locales/nl/messages.json index 422cc0a1e..7d62e859a 100644 --- a/app/_locales/nl/messages.json +++ b/app/_locales/nl/messages.json @@ -167,9 +167,6 @@ "hide": { "message": "Verbergen" }, - "hideToken": { - "message": "Token verbergen" - }, "hideTokenPrompt": { "message": "Token verbergen?" }, diff --git a/app/_locales/no/messages.json b/app/_locales/no/messages.json index 1823f8baf..b53fde4f6 100644 --- a/app/_locales/no/messages.json +++ b/app/_locales/no/messages.json @@ -509,9 +509,6 @@ "hide": { "message": "Skjul" }, - "hideToken": { - "message": "Skjul tokenet" - }, "hideTokenPrompt": { "message": "Skjul sjetonger?" }, diff --git a/app/_locales/ph/messages.json b/app/_locales/ph/messages.json index 360faee3f..63245a297 100644 --- a/app/_locales/ph/messages.json +++ b/app/_locales/ph/messages.json @@ -137,9 +137,6 @@ "hide": { "message": "Itago" }, - "hideToken": { - "message": "Itago ang Token" - }, "hideTokenPrompt": { "message": "Itago ang Token?" }, diff --git a/app/_locales/pl/messages.json b/app/_locales/pl/messages.json index 055edddf8..069aca5b9 100644 --- a/app/_locales/pl/messages.json +++ b/app/_locales/pl/messages.json @@ -516,9 +516,6 @@ "hide": { "message": "Schowaj" }, - "hideToken": { - "message": "Schowaj token" - }, "hideTokenPrompt": { "message": "Schować token?" }, diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json index 19e114775..cda66419d 100644 --- a/app/_locales/pt/messages.json +++ b/app/_locales/pt/messages.json @@ -173,9 +173,6 @@ "hide": { "message": "Ocultar" }, - "hideToken": { - "message": "Ocultar Token" - }, "hideTokenPrompt": { "message": "Ocultar Token?" }, diff --git a/app/_locales/pt_BR/messages.json b/app/_locales/pt_BR/messages.json index 3464f21bf..70dbed539 100644 --- a/app/_locales/pt_BR/messages.json +++ b/app/_locales/pt_BR/messages.json @@ -513,9 +513,6 @@ "hide": { "message": "Ocultar" }, - "hideToken": { - "message": "Ocultar Token" - }, "hideTokenPrompt": { "message": "Esconder token?" }, diff --git a/app/_locales/ro/messages.json b/app/_locales/ro/messages.json index a1483ed12..6e73bd0ab 100644 --- a/app/_locales/ro/messages.json +++ b/app/_locales/ro/messages.json @@ -509,9 +509,6 @@ "hide": { "message": "Ascunde" }, - "hideToken": { - "message": "Ascunde tokenul" - }, "hideTokenPrompt": { "message": "Ascunde simbol?" }, diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index ea8b16d55..4739b0484 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -203,9 +203,6 @@ "hide": { "message": "Скрыть" }, - "hideToken": { - "message": "Скрыть токен" - }, "hideTokenPrompt": { "message": "Скрыть токен?" }, diff --git a/app/_locales/sk/messages.json b/app/_locales/sk/messages.json index 27caf1e4f..dce4d6899 100644 --- a/app/_locales/sk/messages.json +++ b/app/_locales/sk/messages.json @@ -507,9 +507,6 @@ "hide": { "message": "Skrýt" }, - "hideToken": { - "message": "Skrýt token" - }, "hideTokenPrompt": { "message": "Skrýt token?" }, diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json index cdfd35e40..2605948e0 100644 --- a/app/_locales/sl/messages.json +++ b/app/_locales/sl/messages.json @@ -510,9 +510,6 @@ "hide": { "message": "Skrij" }, - "hideToken": { - "message": "Skrij žeton" - }, "hideTokenPrompt": { "message": "Skrijem žeton?" }, diff --git a/app/_locales/sr/messages.json b/app/_locales/sr/messages.json index aaf95af9c..24e855f88 100644 --- a/app/_locales/sr/messages.json +++ b/app/_locales/sr/messages.json @@ -516,9 +516,6 @@ "hide": { "message": "Сакриј" }, - "hideToken": { - "message": "Sakrij token" - }, "hideTokenPrompt": { "message": "Da li želite da sakrijete token?" }, diff --git a/app/_locales/sv/messages.json b/app/_locales/sv/messages.json index 105cfa356..3efe883a1 100644 --- a/app/_locales/sv/messages.json +++ b/app/_locales/sv/messages.json @@ -509,9 +509,6 @@ "hide": { "message": "Dölj" }, - "hideToken": { - "message": "Göm token" - }, "hideTokenPrompt": { "message": "Göm token?" }, diff --git a/app/_locales/sw/messages.json b/app/_locales/sw/messages.json index ef44de126..3c757b81b 100644 --- a/app/_locales/sw/messages.json +++ b/app/_locales/sw/messages.json @@ -506,9 +506,6 @@ "hide": { "message": "Ficha" }, - "hideToken": { - "message": "Ficha Kianzio" - }, "hideTokenPrompt": { "message": "Ungependa Kianzio?" }, diff --git a/app/_locales/ta/messages.json b/app/_locales/ta/messages.json index be1c23393..dfb39b6a3 100644 --- a/app/_locales/ta/messages.json +++ b/app/_locales/ta/messages.json @@ -194,9 +194,6 @@ "hide": { "message": "மறை" }, - "hideToken": { - "message": "டோக்கனை மறை" - }, "hideTokenPrompt": { "message": "டோக்கனை மறை?" }, diff --git a/app/_locales/th/messages.json b/app/_locales/th/messages.json index b02950c3c..44bf097f0 100644 --- a/app/_locales/th/messages.json +++ b/app/_locales/th/messages.json @@ -248,9 +248,6 @@ "hide": { "message": "ซ่อน" }, - "hideToken": { - "message": "ซ่อนโทเค็น" - }, "hideTokenPrompt": { "message": "ซ่อนโทเค็นหรือไม่?" }, diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json index 86899cf1c..c47144713 100644 --- a/app/_locales/tr/messages.json +++ b/app/_locales/tr/messages.json @@ -200,9 +200,6 @@ "hide": { "message": "Gizle" }, - "hideToken": { - "message": "Jetonu gizle" - }, "hideTokenPrompt": { "message": "Jetonu gizle?" }, diff --git a/app/_locales/uk/messages.json b/app/_locales/uk/messages.json index 2a7ac2334..6be7f6156 100644 --- a/app/_locales/uk/messages.json +++ b/app/_locales/uk/messages.json @@ -519,9 +519,6 @@ "hide": { "message": "Сховати" }, - "hideToken": { - "message": "Приховати токен" - }, "hideTokenPrompt": { "message": "Приховати токен?" }, diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json index b3f513528..1c55942ac 100644 --- a/app/_locales/vi/messages.json +++ b/app/_locales/vi/messages.json @@ -149,9 +149,6 @@ "hide": { "message": "Ẩn" }, - "hideToken": { - "message": "Ẩn mã token" - }, "hideTokenPrompt": { "message": "Ẩn mã token?" }, diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index 93037dd9e..66fa5136c 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -513,9 +513,6 @@ "hide": { "message": "隐藏" }, - "hideToken": { - "message": "隐藏代币" - }, "hideTokenPrompt": { "message": "隐藏代币?" }, diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json index 76ce86bda..d05c038b4 100644 --- a/app/_locales/zh_TW/messages.json +++ b/app/_locales/zh_TW/messages.json @@ -516,9 +516,6 @@ "hide": { "message": "隱藏" }, - "hideToken": { - "message": "隱藏代幣" - }, "hideTokenPrompt": { "message": "隱藏代幣?" }, diff --git a/app/scripts/background.js b/app/scripts/background.js index b442af5d1..9e95d5252 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -102,7 +102,6 @@ initialize().catch(log.error) * @property {Object} unapprovedTxs - An object mapping transaction hashes to unapproved transactions. * @property {Array} frequentRpcList - A list of frequently used RPCs, including custom user-provided ones. * @property {Array} addressBook - A list of previously sent to addresses. - * @property {address} selectedTokenAddress - Used to indicate if a token is globally selected. Should be deprecated in favor of UI-centric token selection. * @property {Object} contractExchangeRates - Info about current token prices. * @property {Array} tokens - Tokens held by the current user, including their balances. * @property {Object} send - TODO: Document diff --git a/app/scripts/lib/backend-metametrics.js b/app/scripts/lib/backend-metametrics.js index a1962a160..baaf1c666 100644 --- a/app/scripts/lib/backend-metametrics.js +++ b/app/scripts/lib/backend-metametrics.js @@ -1,4 +1,4 @@ -import { getMetaMetricState } from '../../../ui/app/selectors' +import { getBackgroundMetaMetricState } from '../../../ui/app/selectors' import { sendMetaMetricsEvent } from '../../../ui/app/helpers/utils/metametrics.util' const inDevelopment = process.env.NODE_ENV === 'development' @@ -8,7 +8,7 @@ const METAMETRICS_TRACKING_URL = inDevelopment : 'http://www.metamask.io/metametrics-prod' export default function backEndMetaMetricsEvent (metaMaskState, eventData) { - const stateEventData = getMetaMetricState({ metamask: metaMaskState }) + const stateEventData = getBackgroundMetaMetricState({ metamask: metaMaskState }) if (stateEventData.participateInMetaMetrics) { sendMetaMetricsEvent({ diff --git a/development/states/confirm-sig-requests.json b/development/states/confirm-sig-requests.json index bd2633a03..a8eb67cdd 100644 --- a/development/states/confirm-sig-requests.json +++ b/development/states/confirm-sig-requests.json @@ -527,5 +527,8 @@ }, "unconnectedAccount": { "state": "CLOSED" + }, + "history": { + "mostRecentOverviewPage": "/" } } diff --git a/development/states/currency-localization.json b/development/states/currency-localization.json index 7235c1eaa..a61ab10ed 100644 --- a/development/states/currency-localization.json +++ b/development/states/currency-localization.json @@ -478,5 +478,8 @@ }, "unconnectedAccount": { "state": "CLOSED" + }, + "history": { + "mostRecentOverviewPage": "/" } } diff --git a/test/data/mock-state.json b/test/data/mock-state.json index ce7742114..44edee3b8 100644 --- a/test/data/mock-state.json +++ b/test/data/mock-state.json @@ -113,7 +113,6 @@ } } }, - "selectedTokenAddress": "0x108cf70c7d384c552f42c07c41c0e1e46d77ea0d", "unapprovedMsgs": {}, "unapprovedMsgCount": 0, "unapprovedPersonalMsgs": {}, diff --git a/test/e2e/metamask-ui.spec.js b/test/e2e/metamask-ui.spec.js index 871290156..e5df57820 100644 --- a/test/e2e/metamask-ui.spec.js +++ b/test/e2e/metamask-ui.spec.js @@ -903,7 +903,6 @@ 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 @@ -996,13 +995,6 @@ 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')) - await driver.delay(1000) - const tokenBalanceAmount = await driver.findElements(By.css('.token-overview__primary-balance')) await driver.wait(until.elementTextMatches(tokenBalanceAmount[0], /7.500\s*TST/), 10000) }) @@ -1025,8 +1017,6 @@ 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 @@ -1227,12 +1217,9 @@ 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('[data-testid="token-options__button"]')) - await driver.clickElement(By.css('.token-cell__ellipsis')) - - const byTokenMenuDropdownOption = By.css('.menu__item--clickable') - await driver.clickElement(byTokenMenuDropdownOption) + await driver.clickElement(By.css('[data-testid="token-options__hide"]')) const confirmHideModal = await driver.findElement(By.css('span .modal')) @@ -1245,6 +1232,7 @@ describe('MetaMask', function () { describe('Add existing token using search', function () { it('clicks on the Add Token button', async function () { + await driver.clickElement(By.css('[data-testid="asset__back"]')) await driver.clickElement(By.xpath(`//button[contains(text(), 'Add Token')]`)) await driver.delay(regularDelayMs) }) diff --git a/test/unit/ui/app/reducers/metamask.spec.js b/test/unit/ui/app/reducers/metamask.spec.js index 31684922d..c21841459 100644 --- a/test/unit/ui/app/reducers/metamask.spec.js +++ b/test/unit/ui/app/reducers/metamask.spec.js @@ -52,15 +52,6 @@ describe('MetaMask Reducers', function () { assert.equal(state.selectedAddress, 'test address') }) - it('sets select ', function () { - const state = reduceMetamask({}, { - type: actionConstants.SET_SELECTED_TOKEN, - value: 'test token', - }) - - assert.equal(state.selectedTokenAddress, 'test token') - }) - it('sets account label', function () { const state = reduceMetamask({}, { type: actionConstants.SET_ACCOUNT_LABEL, diff --git a/ui/app/components/app/asset-list-item/asset-list-item.js b/ui/app/components/app/asset-list-item/asset-list-item.js index d15b8cfe5..021ba39ab 100644 --- a/ui/app/components/app/asset-list-item/asset-list-item.js +++ b/ui/app/components/app/asset-list-item/asset-list-item.js @@ -4,12 +4,10 @@ import classnames from 'classnames' import Identicon from '../../ui/identicon' const AssetListItem = ({ - active, children, className, 'data-testid': dataTestId, iconClassName, - menu, onClick, tokenAddress, tokenImage, @@ -17,9 +15,7 @@ const AssetListItem = ({ }) => { return (
@@ -35,18 +31,16 @@ const AssetListItem = ({ { children }
{ warning } - { menu } + ) } AssetListItem.propTypes = { - active: PropTypes.bool, children: PropTypes.node.isRequired, className: PropTypes.string, 'data-testid': PropTypes.string, iconClassName: PropTypes.string, - menu: PropTypes.node, onClick: PropTypes.func.isRequired, tokenAddress: PropTypes.string, tokenImage: PropTypes.string, @@ -54,10 +48,8 @@ AssetListItem.propTypes = { } AssetListItem.defaultProps = { - active: undefined, className: undefined, 'data-testid': undefined, - menu: undefined, iconClassName: undefined, tokenAddress: undefined, tokenImage: undefined, diff --git a/ui/app/components/app/asset-list-item/asset-list-item.scss b/ui/app/components/app/asset-list-item/asset-list-item.scss index 1959bfc32..83ddcc370 100644 --- a/ui/app/components/app/asset-list-item/asset-list-item.scss +++ b/ui/app/components/app/asset-list-item/asset-list-item.scss @@ -3,9 +3,12 @@ display: flex; padding: 24px 16px; align-items: center; + border-top: 1px solid $mercury; + border-bottom: 1px solid $mercury; + cursor: pointer; - &--active { - background: #D9D7DA; + &:hover { + background-color: $Grey-000; } } @@ -16,4 +19,8 @@ flex: 1; min-width: 0; } + + &__chevron-right { + color: $Grey-500; + } } diff --git a/ui/app/components/app/asset-list/asset-list.js b/ui/app/components/app/asset-list/asset-list.js index ad9017390..c3317cc5c 100644 --- a/ui/app/components/app/asset-list/asset-list.js +++ b/ui/app/components/app/asset-list/asset-list.js @@ -1,5 +1,6 @@ import React from 'react' -import { useDispatch, useSelector } from 'react-redux' +import PropTypes from 'prop-types' +import { useSelector } from 'react-redux' import { useHistory } from 'react-router-dom' import AddTokenButton from '../add-token-button' import TokenList from '../token-list' @@ -9,14 +10,12 @@ import CurrencyDisplay from '../../ui/currency-display' import { PRIMARY, SECONDARY } from '../../../helpers/constants/common' import { useMetricEvent } from '../../../hooks/useMetricEvent' import { useUserPreferencedCurrency } from '../../../hooks/useUserPreferencedCurrency' -import { getCurrentAccountWithSendEtherInfo, getShouldShowFiat } from '../../../selectors/selectors' -import { setSelectedToken } from '../../../store/actions' +import { getCurrentAccountWithSendEtherInfo, getNativeCurrency, getShouldShowFiat } from '../../../selectors' -const AssetList = () => { - const dispatch = useDispatch() +const AssetList = ({ onClickAsset }) => { const history = useHistory() const selectedAccountBalance = useSelector((state) => getCurrentAccountWithSendEtherInfo(state).balance) - const selectedTokenAddress = useSelector((state) => state.metamask.selectedTokenAddress) + const nativeCurrency = useSelector(getNativeCurrency) const showFiat = useSelector(getShouldShowFiat) const selectTokenEvent = useMetricEvent({ eventOpts: { @@ -45,8 +44,7 @@ const AssetList = () => { return ( <> dispatch(setSelectedToken())} + onClick={() => onClickAsset(nativeCurrency)} data-testid="wallet-balance" > { { - dispatch(setSelectedToken(tokenAddress)) + onClickAsset(tokenAddress) selectTokenEvent() }} /> @@ -82,4 +80,8 @@ const AssetList = () => { ) } +AssetList.propTypes = { + onClickAsset: PropTypes.func.isRequired, +} + export default AssetList diff --git a/ui/app/components/app/dropdowns/token-menu-dropdown.js b/ui/app/components/app/dropdowns/token-menu-dropdown.js deleted file mode 100644 index a3529aa1a..000000000 --- a/ui/app/components/app/dropdowns/token-menu-dropdown.js +++ /dev/null @@ -1,67 +0,0 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import { connect } from 'react-redux' -import * as actions from '../../../store/actions' -import { createAccountLink as genAccountLink } from '@metamask/etherscan-link' -import { Menu, Item, CloseArea } from './components/menu' - -class TokenMenuDropdown extends Component { - static contextTypes = { - t: PropTypes.func, - } - - static propTypes = { - onClose: PropTypes.func.isRequired, - showHideTokenConfirmationModal: PropTypes.func.isRequired, - token: PropTypes.object.isRequired, - network: PropTypes.string.isRequired, - } - - onClose = (e) => { - e.stopPropagation() - this.props.onClose() - } - - render () { - const { showHideTokenConfirmationModal } = this.props - - return ( - - - { - e.stopPropagation() - showHideTokenConfirmationModal(this.props.token) - this.props.onClose() - }} - text={this.context.t('hideToken')} - /> - { - e.stopPropagation() - const url = genAccountLink(this.props.token.address, this.props.network) - global.platform.openTab({ url }) - this.props.onClose() - }} - text={this.context.t('viewOnEtherscan')} - /> - - ) - } -} - -export default connect(mapStateToProps, mapDispatchToProps)(TokenMenuDropdown) - -function mapStateToProps (state) { - return { - network: state.metamask.network, - } -} - -function mapDispatchToProps (dispatch) { - return { - showHideTokenConfirmationModal: (token) => { - dispatch(actions.showModal({ name: 'HIDE_TOKEN_CONFIRMATION', token })) - }, - } -} diff --git a/ui/app/components/app/menu-bar/index.scss b/ui/app/components/app/menu-bar/index.scss index e82c1ef4f..368e5a8ec 100644 --- a/ui/app/components/app/menu-bar/index.scss +++ b/ui/app/components/app/menu-bar/index.scss @@ -2,8 +2,6 @@ display: grid; grid-template-columns: 30% minmax(30%, 1fr) 30%; column-gap: 5px; - - margin-bottom: 24px; padding: 0 8px; border-bottom: 1px solid $Grey-100; diff --git a/ui/app/components/app/signature-request-original/signature-request-original.component.js b/ui/app/components/app/signature-request-original/signature-request-original.component.js index 1c105a0ab..01bb0b8c4 100644 --- a/ui/app/components/app/signature-request-original/signature-request-original.component.js +++ b/ui/app/components/app/signature-request-original/signature-request-original.component.js @@ -10,7 +10,6 @@ import Identicon from '../../ui/identicon' import AccountListItem from '../../../pages/send/account-list-item/account-list-item.component' import { conversionUtil } from '../../../helpers/utils/conversion-util' import Button from '../../ui/button' -import { DEFAULT_ROUTE } from '../../../helpers/constants/routes' export default class SignatureRequestOriginal extends Component { static contextTypes = { @@ -28,6 +27,7 @@ export default class SignatureRequestOriginal extends Component { clearConfirmTransaction: PropTypes.func.isRequired, conversionRate: PropTypes.number, history: PropTypes.object.isRequired, + mostRecentOverviewPage: PropTypes.string.isRequired, requesterAddress: PropTypes.string, sign: PropTypes.func.isRequired, txData: PropTypes.object.isRequired, @@ -268,7 +268,7 @@ export default class SignatureRequestOriginal extends Component { } renderFooter = () => { - const { cancel, sign } = this.props + const { cancel, clearConfirmTransaction, history, mostRecentOverviewPage, sign } = this.props return (
@@ -286,8 +286,8 @@ export default class SignatureRequestOriginal extends Component { name: 'Cancel', }, }) - this.props.clearConfirmTransaction() - this.props.history.push(DEFAULT_ROUTE) + clearConfirmTransaction() + history.push(mostRecentOverviewPage) }} > { this.context.t('cancel') } @@ -306,8 +306,8 @@ export default class SignatureRequestOriginal extends Component { name: 'Confirm', }, }) - this.props.clearConfirmTransaction() - this.props.history.push(DEFAULT_ROUTE) + clearConfirmTransaction() + history.push(mostRecentOverviewPage) }} > { this.context.t('sign') } diff --git a/ui/app/components/app/signature-request-original/signature-request-original.container.js b/ui/app/components/app/signature-request-original/signature-request-original.container.js index 0ee4519df..26ddad485 100644 --- a/ui/app/components/app/signature-request-original/signature-request-original.container.js +++ b/ui/app/components/app/signature-request-original/signature-request-original.container.js @@ -10,12 +10,14 @@ import { import { getAccountByAddress } from '../../../helpers/utils/util' import { clearConfirmTransaction } from '../../../ducks/confirm-transaction/confirm-transaction.duck' import SignatureRequestOriginal from './signature-request-original.component' +import { getMostRecentOverviewPage } from '../../../ducks/history/history' function mapStateToProps (state) { return { requester: null, requesterAddress: null, conversionRate: conversionRateSelector(state), + mostRecentOverviewPage: getMostRecentOverviewPage(state), // not passed to component allAccounts: accountsWithSendEtherInfoSelector(state), } diff --git a/ui/app/components/app/token-cell/token-cell.component.js b/ui/app/components/app/token-cell/token-cell.component.js index 380913e3b..a7088324c 100644 --- a/ui/app/components/app/token-cell/token-cell.component.js +++ b/ui/app/components/app/token-cell/token-cell.component.js @@ -2,7 +2,6 @@ import classnames from 'classnames' import PropTypes from 'prop-types' import React, { Component } from 'react' import { conversionUtil, multiplyCurrencies } from '../../../helpers/utils/conversion-util' -import TokenMenuDropdown from '../dropdowns/token-menu-dropdown.js' import Tooltip from '../../ui/tooltip-v2' import { I18nContext } from '../../../contexts/i18n' import AssetListItem from '../asset-list-item' @@ -15,7 +14,6 @@ export default class TokenCell extends Component { outdatedBalance: PropTypes.bool, symbol: PropTypes.string, string: PropTypes.string, - selectedTokenAddress: PropTypes.string, contractExchangeRates: PropTypes.object, conversionRate: PropTypes.number, currentCurrency: PropTypes.string, @@ -28,18 +26,12 @@ export default class TokenCell extends Component { outdatedBalance: false, } - state = { - tokenMenuOpen: false, - } - render () { const t = this.context - const { tokenMenuOpen } = this.state const { address, symbol, string, - selectedTokenAddress, contractExchangeRates, conversionRate, onClick, @@ -71,26 +63,6 @@ export default class TokenCell extends Component { const showFiat = Boolean(currentTokenInFiat) && currentCurrency.toUpperCase() !== symbol - const menu = ( - <> -
- { - e.stopPropagation() - this.setState({ tokenMenuOpen: true }) - }} - /> -
- {tokenMenuOpen && ( - this.setState({ tokenMenuOpen: false })} - token={{ symbol, address }} - /> - )} - - ) - const warning = outdatedBalance ? ( { +const EthOverview = ({ className }) => { const dispatch = useDispatch() const t = useContext(I18nContext) const sendEvent = useMetricEvent({ @@ -99,13 +100,18 @@ const EthOverview = () => { )} - icon={} + className={className} + icon={} /> ) } EthOverview.propTypes = { + className: PropTypes.string, +} +EthOverview.defaultProps = { + className: undefined, } export default EthOverview diff --git a/ui/app/components/app/wallet-overview/index.scss b/ui/app/components/app/wallet-overview/index.scss index 1772ce135..ac62d3f43 100644 --- a/ui/app/components/app/wallet-overview/index.scss +++ b/ui/app/components/app/wallet-overview/index.scss @@ -3,11 +3,12 @@ justify-content: space-between; align-items: center; flex: 1; - height: 54px; + height: 209px; min-width: 0; + padding-top: 10px; + flex-direction: column; - height: initial; width: 100%; &__balance { @@ -21,7 +22,8 @@ &__buttons { display: flex; flex-direction: row; - margin-bottom: 16px; + height: 44px; + margin-bottom: 24px; } } diff --git a/ui/app/components/app/wallet-overview/token-overview.js b/ui/app/components/app/wallet-overview/token-overview.js index 2d3914fa4..eb57d6159 100644 --- a/ui/app/components/app/wallet-overview/token-overview.js +++ b/ui/app/components/app/wallet-overview/token-overview.js @@ -11,9 +11,9 @@ import WalletOverview from './wallet-overview' import { SEND_ROUTE } from '../../../helpers/constants/routes' import { useMetricEvent } from '../../../hooks/useMetricEvent' import { getAssetImages } from '../../../selectors/selectors' -import { updateSend } from '../../../store/actions' +import { updateSendToken } from '../../../store/actions' -const TokenOverview = ({ token }) => { +const TokenOverview = ({ className, token }) => { const dispatch = useDispatch() const t = useContext(I18nContext) const sendTokenEvent = useMetricEvent({ @@ -43,16 +43,17 @@ const TokenOverview = ({ token }) => { className="token-overview__button" onClick={() => { sendTokenEvent() - dispatch(updateSend({ token })) + dispatch(updateSendToken(token)) history.push(SEND_ROUTE) }} > { t('send') } )} + className={className} icon={( @@ -62,6 +63,7 @@ const TokenOverview = ({ token }) => { } TokenOverview.propTypes = { + className: PropTypes.string, token: PropTypes.shape({ address: PropTypes.string.isRequired, decimals: PropTypes.number, @@ -69,4 +71,8 @@ TokenOverview.propTypes = { }).isRequired, } +TokenOverview.defaultProps = { + className: undefined, +} + export default TokenOverview diff --git a/ui/app/components/app/wallet-overview/wallet-overview.js b/ui/app/components/app/wallet-overview/wallet-overview.js index 6a6c27594..30bbd1529 100644 --- a/ui/app/components/app/wallet-overview/wallet-overview.js +++ b/ui/app/components/app/wallet-overview/wallet-overview.js @@ -1,9 +1,10 @@ import React from 'react' import PropTypes from 'prop-types' +import classnames from 'classnames' -const WalletOverview = ({ balance, buttons, icon }) => { +const WalletOverview = ({ balance, buttons, className, icon }) => { return ( -
+
{ icon } { balance } @@ -18,7 +19,12 @@ const WalletOverview = ({ balance, buttons, icon }) => { WalletOverview.propTypes = { balance: PropTypes.element.isRequired, buttons: PropTypes.element.isRequired, + className: PropTypes.string, icon: PropTypes.element.isRequired, } +WalletOverview.defaultProps = { + className: undefined, +} + export default WalletOverview diff --git a/ui/app/contexts/metametrics.js b/ui/app/contexts/metametrics.js index 0e811585d..df89c25c5 100644 --- a/ui/app/contexts/metametrics.js +++ b/ui/app/contexts/metametrics.js @@ -6,11 +6,11 @@ import { captureException } from '@sentry/browser' import { getCurrentNetworkId, - getSelectedAsset, getAccountType, getNumberOfAccounts, getNumberOfTokens, } from '../selectors/selectors' +import { getSendToken } from '../selectors/send' import { txDataSelector, } from '../selectors/confirm-transaction' @@ -31,7 +31,7 @@ export function MetaMetricsProvider ({ children }) { const txData = useSelector(txDataSelector) || {} const network = useSelector(getCurrentNetworkId) const environmentType = getEnvironmentType() - const activeCurrency = useSelector(getSelectedAsset) + const activeCurrency = useSelector(getSendToken)?.symbol const accountType = useSelector(getAccountType) const confirmTransactionOrigin = txData.origin const metaMetricsId = useSelector((state) => state.metamask.metaMetricsId) diff --git a/ui/app/ducks/history/history.js b/ui/app/ducks/history/history.js new file mode 100644 index 000000000..9b716375b --- /dev/null +++ b/ui/app/ducks/history/history.js @@ -0,0 +1,38 @@ +import { createSlice } from '@reduxjs/toolkit' + +import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../helpers/constants/routes' + +// Constants + +const initialState = { + mostRecentOverviewPage: DEFAULT_ROUTE, +} + +const name = 'history' + +// Slice (reducer plus auto-generated actions and action creators) + +const slice = createSlice({ + name, + initialState, + reducers: { + pageChanged: (state, action) => { + const path = action.payload + if (path === DEFAULT_ROUTE || path.startsWith(ASSET_ROUTE)) { + state.mostRecentOverviewPage = path + } + }, + }, +}) + +const { actions, reducer } = slice + +export default reducer + +// Selectors + +export const getMostRecentOverviewPage = (state) => state[name].mostRecentOverviewPage + +// Actions / action-creators + +export const { pageChanged } = actions diff --git a/ui/app/ducks/index.js b/ui/app/ducks/index.js index b0f3c125c..5e7cd7889 100644 --- a/ui/app/ducks/index.js +++ b/ui/app/ducks/index.js @@ -6,6 +6,7 @@ import appStateReducer from './app/app' import confirmTransactionReducer from './confirm-transaction/confirm-transaction.duck' import gasReducer from './gas/gas.duck' import { switchToConnected, unconnectedAccount } from './alerts' +import historyReducer from './history/history' import { ALERT_TYPES } from '../../../app/scripts/controllers/alert' export default combineReducers({ @@ -14,6 +15,7 @@ export default combineReducers({ activeTab: (s) => (s === undefined ? null : s), metamask: metamaskReducer, appState: appStateReducer, + history: historyReducer, send: sendReducer, confirmTransaction: confirmTransactionReducer, gas: gasReducer, diff --git a/ui/app/ducks/metamask/metamask.js b/ui/app/ducks/metamask/metamask.js index 40057a808..e85f717ab 100644 --- a/ui/app/ducks/metamask/metamask.js +++ b/ui/app/ducks/metamask/metamask.js @@ -11,7 +11,6 @@ export default function reduceMetamask (state = {}, action) { unapprovedTxs: {}, frequentRpcList: [], addressBook: [], - selectedTokenAddress: null, contractExchangeRates: {}, tokens: [], pendingTokens: {}, @@ -87,33 +86,6 @@ export default function reduceMetamask (state = {}, action) { selectedAddress: action.value, } - case actionConstants.SET_SELECTED_TOKEN: { - const newState = { - ...metamaskState, - selectedTokenAddress: action.value, - } - const newSend = { ...metamaskState.send } - - if (metamaskState.send.editingTransactionId && !action.value) { - delete newSend.token - const unapprovedTx = newState.unapprovedTxs[newSend.editingTransactionId] || {} - const txParams = unapprovedTx.txParams || {} - newState.unapprovedTxs = { - ...newState.unapprovedTxs, - [newSend.editingTransactionId]: { - ...unapprovedTx, - txParams: { ...txParams, data: '' }, - }, - } - newSend.tokenBalance = null - newSend.balance = '0' - newSend.from = unapprovedTx.from || '' - } - - newState.send = newSend - return newState - } - case actionConstants.SET_ACCOUNT_LABEL: const account = action.value.account const name = action.value.label @@ -227,6 +199,35 @@ export default function reduceMetamask (state = {}, action) { }, }) + case actionConstants.UPDATE_SEND_TOKEN: + const newSend = { + ...metamaskState.send, + token: action.value, + } + // erase token-related state when switching back to native currency + if (newSend.editingTransactionId && !newSend.token) { + const unapprovedTx = newSend?.unapprovedTxs?.[newSend.editingTransactionId] || {} + const txParams = unapprovedTx.txParams || {} + Object.assign(newSend, { + tokenBalance: null, + balance: '0', + from: unapprovedTx.from || '', + unapprovedTxs: { + ...newSend.unapprovedTxs, + [newSend.editingTransactionId]: { + ...unapprovedTx, + txParams: { + ...txParams, + data: '', + }, + }, + }, + }) + } + return Object.assign(metamaskState, { + send: newSend, + }) + case actionConstants.UPDATE_SEND_ENS_RESOLUTION: return { ...metamaskState, diff --git a/ui/app/helpers/constants/routes.js b/ui/app/helpers/constants/routes.js index f5a2934b0..4dcb62670 100644 --- a/ui/app/helpers/constants/routes.js +++ b/ui/app/helpers/constants/routes.js @@ -1,6 +1,7 @@ const DEFAULT_ROUTE = '/' const UNLOCK_ROUTE = '/unlock' const LOCK_ROUTE = '/lock' +const ASSET_ROUTE = '/asset' const SETTINGS_ROUTE = '/settings' const GENERAL_ROUTE = '/settings/general' const CONNECTIONS_ROUTE = '/settings/connections' @@ -57,6 +58,7 @@ const ENCRYPTION_PUBLIC_KEY_REQUEST_PATH = '/encryption-public-key-request' export { DEFAULT_ROUTE, ALERTS_ROUTE, + ASSET_ROUTE, UNLOCK_ROUTE, LOCK_ROUTE, SETTINGS_ROUTE, diff --git a/ui/app/helpers/utils/util.js b/ui/app/helpers/utils/util.js index d1e343a44..621e47438 100644 --- a/ui/app/helpers/utils/util.js +++ b/ui/app/helpers/utils/util.js @@ -256,10 +256,6 @@ export function exportAsFile (filename, data, type = 'text/csv') { } } -export function getTokenAddressFromTokenObject (token) { - return Object.values(token)[0].address.toLowerCase() -} - /** * Safely checksumms a potentially-null address * diff --git a/ui/app/pages/add-token/add-token.component.js b/ui/app/pages/add-token/add-token.component.js index fcfb4cf8b..c8ab780bf 100644 --- a/ui/app/pages/add-token/add-token.component.js +++ b/ui/app/pages/add-token/add-token.component.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types' import ethUtil from 'ethereumjs-util' import { checkExistingAddresses } from './util' import { tokenInfoGetter } from '../../helpers/utils/token-util' -import { DEFAULT_ROUTE, CONFIRM_ADD_TOKEN_ROUTE } from '../../helpers/constants/routes' +import { CONFIRM_ADD_TOKEN_ROUTE } from '../../helpers/constants/routes' import TextField from '../../components/ui/text-field' import TokenList from './token-list' import TokenSearch from './token-search' @@ -24,6 +24,7 @@ class AddToken extends Component { clearPendingTokens: PropTypes.func, tokens: PropTypes.array, identities: PropTypes.object, + mostRecentOverviewPage: PropTypes.string.isRequired, } state = { @@ -307,7 +308,7 @@ class AddToken extends Component { } render () { - const { history, clearPendingTokens } = this.props + const { history, clearPendingTokens, mostRecentOverviewPage } = this.props return ( { clearPendingTokens() - history.push(DEFAULT_ROUTE) + history.push(mostRecentOverviewPage) }} /> ) diff --git a/ui/app/pages/add-token/add-token.container.js b/ui/app/pages/add-token/add-token.container.js index af9334106..2e7354b23 100644 --- a/ui/app/pages/add-token/add-token.container.js +++ b/ui/app/pages/add-token/add-token.container.js @@ -2,11 +2,13 @@ import { connect } from 'react-redux' import AddToken from './add-token.component' import { setPendingTokens, clearPendingTokens } from '../../store/actions' +import { getMostRecentOverviewPage } from '../../ducks/history/history' -const mapStateToProps = ({ metamask }) => { - const { identities, tokens, pendingTokens } = metamask +const mapStateToProps = (state) => { + const { metamask: { identities, tokens, pendingTokens } } = state return { identities, + mostRecentOverviewPage: getMostRecentOverviewPage(state), tokens, pendingTokens, } diff --git a/ui/app/pages/add-token/tests/add-token.test.js b/ui/app/pages/add-token/tests/add-token.test.js index 761c7c5e8..ab7dea743 100644 --- a/ui/app/pages/add-token/tests/add-token.test.js +++ b/ui/app/pages/add-token/tests/add-token.test.js @@ -25,6 +25,7 @@ describe('Add Token', function () { clearPendingTokens: sinon.spy(), tokens: [], identities: {}, + mostRecentOverviewPage: '/', } describe('Add Token', function () { diff --git a/ui/app/pages/asset/asset.js b/ui/app/pages/asset/asset.js new file mode 100644 index 000000000..7393d8f1b --- /dev/null +++ b/ui/app/pages/asset/asset.js @@ -0,0 +1,65 @@ +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { Redirect, useHistory, useParams } from 'react-router-dom' +import { createAccountLink } from '@metamask/etherscan-link' + +import TransactionList from '../../components/app/transaction-list' +import { EthOverview, TokenOverview } from '../../components/app/wallet-overview' +import { getCurrentNetworkId, getSelectedIdentity } from '../../selectors/selectors' +import { getTokens } from '../../ducks/metamask/metamask' +import { DEFAULT_ROUTE } from '../../helpers/constants/routes' +import { showModal } from '../../store/actions' + +import AssetNavigation from './components/asset-navigation' +import TokenOptions from './components/token-options' + +const Asset = () => { + const dispatch = useDispatch() + const network = useSelector(getCurrentNetworkId) + const selectedAccountName = useSelector((state) => getSelectedIdentity(state).name) + const nativeCurrency = useSelector((state) => state.metamask.nativeCurrency) + const tokens = useSelector(getTokens) + const history = useHistory() + const { asset } = useParams() + + const token = tokens.find((token) => token.address === asset) + + let assetName + let optionsButton + + if (token) { + assetName = token.symbol + optionsButton = ( + dispatch(showModal({ name: 'HIDE_TOKEN_CONFIRMATION', token }))} + onViewEtherscan={() => { + const url = createAccountLink(token.address, network) + global.platform.openTab({ url }) + }} + tokenSymbol={token.symbol} + /> + ) + } else if (asset === nativeCurrency) { + assetName = nativeCurrency + } else { + return + } + + const overview = token + ? + : + return ( +
+ history.push(DEFAULT_ROUTE)} + optionsButton={optionsButton} + /> + { overview } + +
+ ) +} + +export default Asset diff --git a/ui/app/pages/asset/asset.scss b/ui/app/pages/asset/asset.scss new file mode 100644 index 000000000..7213ba11d --- /dev/null +++ b/ui/app/pages/asset/asset.scss @@ -0,0 +1,45 @@ +.asset { + &__container { + background-color: white; + } + + &__overview { + box-shadow: 0px 3px 4px rgba(135, 134, 134, 0.16); + } +} + +.asset-navigation { + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px; + height: 54px; +} + +.asset-breadcrumb { + font-size: 14px; + color: $Black-100; + + &__chevron { + padding: 0 10px 0 2px; + font-size: 16px; + background-color: inherit; + } + + &__asset { + font-weight: bold; + } +} + +.token-options { + &__button { + font-size: 20px; + color: $Black-100; + background-color: inherit; + padding: 2px 8px; + } + + &__icon { + font-size: 16px; + } +} diff --git a/ui/app/pages/asset/components/asset-breadcrumb.js b/ui/app/pages/asset/components/asset-breadcrumb.js new file mode 100644 index 000000000..827ddc49f --- /dev/null +++ b/ui/app/pages/asset/components/asset-breadcrumb.js @@ -0,0 +1,25 @@ +import React from 'react' +import PropTypes from 'prop-types' + +const AssetBreadcrumb = ({ accountName, assetName, onBack }) => { + return ( +
+
+ ) +} + +AssetBreadcrumb.propTypes = { + accountName: PropTypes.string.isRequired, + assetName: PropTypes.string.isRequired, + onBack: PropTypes.func.isRequired, +} + +export default AssetBreadcrumb diff --git a/ui/app/pages/asset/components/asset-navigation.js b/ui/app/pages/asset/components/asset-navigation.js new file mode 100644 index 000000000..5423b1094 --- /dev/null +++ b/ui/app/pages/asset/components/asset-navigation.js @@ -0,0 +1,26 @@ +import React from 'react' +import PropTypes from 'prop-types' + +import AssetBreadcrumb from './asset-breadcrumb' + +const AssetNavigation = ({ accountName, assetName, onBack, optionsButton }) => { + return ( +
+ + { optionsButton } +
+ ) +} + +AssetNavigation.propTypes = { + accountName: PropTypes.string.isRequired, + assetName: PropTypes.string.isRequired, + onBack: PropTypes.func.isRequired, + optionsButton: PropTypes.element, +} + +AssetNavigation.defaultProps = { + optionsButton: undefined, +} + +export default AssetNavigation diff --git a/ui/app/pages/asset/components/token-options.js b/ui/app/pages/asset/components/token-options.js new file mode 100644 index 000000000..eaf142d34 --- /dev/null +++ b/ui/app/pages/asset/components/token-options.js @@ -0,0 +1,59 @@ +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, tokenSymbol }) => { + const t = useContext(I18nContext) + const [tokenOptionsButtonElement, setTokenOptionsButtonElement] = useState(null) + const [tokenOptionsOpen, setTokenOptionsOpen] = useState(false) + + return ( + <> + @@ -89,7 +89,14 @@ class JsonImportSubview extends Component { } createNewKeychain () { - const { firstAddress, displayWarning, importNewJsonAccount, setSelectedAddress, history } = this.props + const { + firstAddress, + displayWarning, + history, + importNewJsonAccount, + mostRecentOverviewPage, + setSelectedAddress, + } = this.props const { fileContents } = this.state if (!fileContents) { @@ -102,7 +109,7 @@ class JsonImportSubview extends Component { importNewJsonAccount([ fileContents, password ]) .then(({ selectedAddress }) => { if (selectedAddress) { - history.push(DEFAULT_ROUTE) + history.push(mostRecentOverviewPage) this.context.metricsEvent({ eventOpts: { category: 'Accounts', @@ -143,12 +150,14 @@ JsonImportSubview.propTypes = { importNewJsonAccount: PropTypes.func, history: PropTypes.object, setSelectedAddress: PropTypes.func, + mostRecentOverviewPage: PropTypes.string.isRequired, } const mapStateToProps = (state) => { return { error: state.appState.warning, firstAddress: Object.keys(getMetaMaskAccounts(state))[0], + mostRecentOverviewPage: getMostRecentOverviewPage(state), } } diff --git a/ui/app/pages/create-account/import-account/private-key.js b/ui/app/pages/create-account/import-account/private-key.js index aa21c1bb0..5897b7e97 100644 --- a/ui/app/pages/create-account/import-account/private-key.js +++ b/ui/app/pages/create-account/import-account/private-key.js @@ -4,9 +4,9 @@ import { compose } from 'redux' import PropTypes from 'prop-types' import { connect } from 'react-redux' import * as actions from '../../../store/actions' -import { DEFAULT_ROUTE } from '../../../helpers/constants/routes' import { getMetaMaskAccounts } from '../../../selectors' import Button from '../../../components/ui/button' +import { getMostRecentOverviewPage } from '../../../ducks/history/history' class PrivateKeyImportView extends Component { static contextTypes = { @@ -21,6 +21,7 @@ class PrivateKeyImportView extends Component { setSelectedAddress: PropTypes.func.isRequired, firstAddress: PropTypes.string.isRequired, error: PropTypes.node, + mostRecentOverviewPage: PropTypes.string.isRequired, } inputRef = React.createRef() @@ -29,7 +30,7 @@ class PrivateKeyImportView extends Component { createNewKeychain () { const privateKey = this.inputRef.current.value - const { importNewAccount, history, displayWarning, setSelectedAddress, firstAddress } = this.props + const { importNewAccount, history, displayWarning, mostRecentOverviewPage, setSelectedAddress, firstAddress } = this.props importNewAccount('Private Key', [ privateKey ]) .then(({ selectedAddress }) => { @@ -41,7 +42,7 @@ class PrivateKeyImportView extends Component { name: 'Imported Account with Private Key', }, }) - history.push(DEFAULT_ROUTE) + history.push(mostRecentOverviewPage) displayWarning(null) } else { displayWarning('Error importing account.') @@ -98,8 +99,9 @@ class PrivateKeyImportView extends Component { large className="new-account-create-form__button" onClick={() => { + const { history, mostRecentOverviewPage } = this.props displayWarning(null) - this.props.history.push(DEFAULT_ROUTE) + history.push(mostRecentOverviewPage) }} > {this.context.t('cancel')} @@ -134,6 +136,7 @@ function mapStateToProps (state) { return { error: state.appState.warning, firstAddress: Object.keys(getMetaMaskAccounts(state))[0], + mostRecentOverviewPage: getMostRecentOverviewPage(state), } } diff --git a/ui/app/pages/create-account/new-account.component.js b/ui/app/pages/create-account/new-account.component.js index 8bf9397c7..ef811a84f 100644 --- a/ui/app/pages/create-account/new-account.component.js +++ b/ui/app/pages/create-account/new-account.component.js @@ -1,6 +1,5 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { DEFAULT_ROUTE } from '../../helpers/constants/routes' import Button from '../../components/ui/button' export default class NewAccountCreateForm extends Component { @@ -17,7 +16,7 @@ export default class NewAccountCreateForm extends Component { render () { const { newAccountName, defaultAccountName } = this.state - const { history, createAccount } = this.props + const { history, createAccount, mostRecentOverviewPage } = this.props const createClick = (_) => { createAccount(newAccountName || defaultAccountName) .then(() => { @@ -28,7 +27,7 @@ export default class NewAccountCreateForm extends Component { name: 'Added New Account', }, }) - history.push(DEFAULT_ROUTE) + history.push(mostRecentOverviewPage) }) .catch((e) => { this.context.metricsEvent({ @@ -61,7 +60,7 @@ export default class NewAccountCreateForm extends Component { type="default" large className="new-account-create-form__button" - onClick={() => history.push(DEFAULT_ROUTE)} + onClick={() => history.push(mostRecentOverviewPage)} > {this.context.t('cancel')} @@ -84,6 +83,7 @@ NewAccountCreateForm.propTypes = { createAccount: PropTypes.func, newAccountNumber: PropTypes.number, history: PropTypes.object, + mostRecentOverviewPage: PropTypes.string.isRequired, } NewAccountCreateForm.contextTypes = { diff --git a/ui/app/pages/create-account/new-account.container.js b/ui/app/pages/create-account/new-account.container.js index ce7f37b53..14c33c2f4 100644 --- a/ui/app/pages/create-account/new-account.container.js +++ b/ui/app/pages/create-account/new-account.container.js @@ -1,6 +1,7 @@ import { connect } from 'react-redux' import * as actions from '../../store/actions' import NewAccountCreateForm from './new-account.component' +import { getMostRecentOverviewPage } from '../../ducks/history/history' const mapStateToProps = (state) => { const { metamask: { network, selectedAddress, identities = {} } } = state @@ -11,6 +12,7 @@ const mapStateToProps = (state) => { network, address: selectedAddress, newAccountNumber, + mostRecentOverviewPage: getMostRecentOverviewPage(state), } } diff --git a/ui/app/pages/home/home.component.js b/ui/app/pages/home/home.component.js index a3798e0b4..e655eb1f0 100644 --- a/ui/app/pages/home/home.component.js +++ b/ui/app/pages/home/home.component.js @@ -12,9 +12,10 @@ import Button from '../../components/ui/button' import ConnectedSites from '../connected-sites' import ConnectedAccounts from '../connected-accounts' import { Tabs, Tab } from '../../components/ui/tabs' -import { EthOverview, TokenOverview } from '../../components/app/wallet-overview' +import { EthOverview } from '../../components/app/wallet-overview' import { + ASSET_ROUTE, RESTORE_VAULT_ROUTE, CONFIRM_TRANSACTION_ROUTE, CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE, @@ -49,11 +50,6 @@ export default class Home extends PureComponent { totalUnapprovedCount: PropTypes.number.isRequired, setConnectedStatusPopoverHasBeenShown: PropTypes.func, connectedStatusPopoverHasBeenShown: PropTypes.bool, - selectedToken: PropTypes.shape({ - address: PropTypes.string.isRequired, - decimals: PropTypes.number, - symbol: PropTypes.string, - }), defaultHomeActiveTabName: PropTypes.string, onTabClick: PropTypes.func.isRequired, } @@ -215,7 +211,6 @@ export default class Home extends PureComponent { history, connectedStatusPopoverHasBeenShown, isPopup, - selectedToken, } = this.props if (forgottenPassword) { @@ -226,10 +221,6 @@ export default class Home extends PureComponent { return null } - const homeOverview = selectedToken - ? - : - return (
@@ -239,7 +230,7 @@ export default class Home extends PureComponent {
- { homeOverview } +
- + history.push(`${ASSET_ROUTE}/${asset}`)} + /> - +
diff --git a/ui/app/pages/home/home.container.js b/ui/app/pages/home/home.container.js index bdb957f96..43a20bd20 100644 --- a/ui/app/pages/home/home.container.js +++ b/ui/app/pages/home/home.container.js @@ -4,7 +4,6 @@ import { connect } from 'react-redux' import { withRouter } from 'react-router-dom' import { unconfirmedTransactionsCountSelector, - getSelectedToken, getCurrentEthBalance, getFirstPermissionRequest, getTotalUnapprovedCount, @@ -60,7 +59,6 @@ const mapStateToProps = (state) => { threeBoxSynced, showRestorePrompt, selectedAddress, - selectedToken: getSelectedToken(state), threeBoxLastUpdated, firstPermissionsRequestId, totalUnapprovedCount, diff --git a/ui/app/pages/home/index.scss b/ui/app/pages/home/index.scss index bd4f85775..251d45f1e 100644 --- a/ui/app/pages/home/index.scss +++ b/ui/app/pages/home/index.scss @@ -18,7 +18,6 @@ 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 diff --git a/ui/app/pages/index.scss b/ui/app/pages/index.scss index 5cefd8db3..9bd1a928f 100644 --- a/ui/app/pages/index.scss +++ b/ui/app/pages/index.scss @@ -23,3 +23,5 @@ @import 'confirm-approve/index'; @import 'permissions-connect/index'; + +@import 'asset/asset'; diff --git a/ui/app/pages/keychains/reveal-seed.js b/ui/app/pages/keychains/reveal-seed.js index 238a5937e..8f9e0aec4 100644 --- a/ui/app/pages/keychains/reveal-seed.js +++ b/ui/app/pages/keychains/reveal-seed.js @@ -3,8 +3,8 @@ import { connect } from 'react-redux' import PropTypes from 'prop-types' import classnames from 'classnames' import { requestRevealSeedWords } from '../../store/actions' -import { DEFAULT_ROUTE } from '../../helpers/constants/routes' import ExportTextContainer from '../../components/ui/export-text-container' +import { getMostRecentOverviewPage } from '../../ducks/history/history' import Button from '../../components/ui/button' @@ -107,7 +107,7 @@ class RevealSeedPage extends Component { type="default" large className="page-container__footer-button" - onClick={() => this.props.history.push(DEFAULT_ROUTE)} + onClick={() => this.props.history.push(this.props.mostRecentOverviewPage)} > {this.context.t('cancel')} @@ -132,7 +132,7 @@ class RevealSeedPage extends Component { type="default" large className="page-container__footer-button" - onClick={() => this.props.history.push(DEFAULT_ROUTE)} + onClick={() => this.props.history.push(this.props.mostRecentOverviewPage)} > {this.context.t('close')} @@ -166,16 +166,23 @@ class RevealSeedPage extends Component { RevealSeedPage.propTypes = { requestRevealSeedWords: PropTypes.func, history: PropTypes.object, + mostRecentOverviewPage: PropTypes.string.isRequired, } RevealSeedPage.contextTypes = { t: PropTypes.func, } +const mapStateToProps = (state) => { + return { + mostRecentOverviewPage: getMostRecentOverviewPage(state), + } +} + const mapDispatchToProps = (dispatch) => { return { requestRevealSeedWords: (password) => dispatch(requestRevealSeedWords(password)), } } -export default connect(null, mapDispatchToProps)(RevealSeedPage) +export default connect(mapStateToProps, mapDispatchToProps)(RevealSeedPage) diff --git a/ui/app/pages/mobile-sync/mobile-sync.component.js b/ui/app/pages/mobile-sync/mobile-sync.component.js index 7b79e0f8c..4afbf93ed 100644 --- a/ui/app/pages/mobile-sync/mobile-sync.component.js +++ b/ui/app/pages/mobile-sync/mobile-sync.component.js @@ -4,7 +4,6 @@ import PropTypes from 'prop-types' import classnames from 'classnames' import PubNub from 'pubnub' import qrCode from 'qrcode-generator' -import { DEFAULT_ROUTE } from '../../helpers/constants/routes' import Button from '../../components/ui/button' import LoadingScreen from '../../components/ui/loading-screen' @@ -24,6 +23,7 @@ export default class MobileSyncPage extends Component { selectedAddress: PropTypes.string.isRequired, displayWarning: PropTypes.func.isRequired, fetchInfoToSync: PropTypes.func.isRequired, + mostRecentOverviewPage: PropTypes.string.isRequired, requestRevealSeedWords: PropTypes.func.isRequired, } @@ -78,8 +78,8 @@ export default class MobileSyncPage extends Component { } goBack () { - const { history } = this.props - history.push(DEFAULT_ROUTE) + const { history, mostRecentOverviewPage } = this.props + history.push(mostRecentOverviewPage) } clearTimeouts () { diff --git a/ui/app/pages/mobile-sync/mobile-sync.container.js b/ui/app/pages/mobile-sync/mobile-sync.container.js index 1699c3a04..da83ba013 100644 --- a/ui/app/pages/mobile-sync/mobile-sync.container.js +++ b/ui/app/pages/mobile-sync/mobile-sync.container.js @@ -1,6 +1,7 @@ import { connect } from 'react-redux' import { displayWarning, requestRevealSeedWords, fetchInfoToSync } from '../../store/actions' import MobileSyncPage from './mobile-sync.component' +import { getMostRecentOverviewPage } from '../../ducks/history/history' const mapDispatchToProps = (dispatch) => { return { @@ -18,6 +19,7 @@ const mapStateToProps = (state) => { } = state return { + mostRecentOverviewpage: getMostRecentOverviewPage(state), selectedAddress, } } diff --git a/ui/app/pages/routes/routes.component.js b/ui/app/pages/routes/routes.component.js index e7dd63df1..54a055f8d 100644 --- a/ui/app/pages/routes/routes.component.js +++ b/ui/app/pages/routes/routes.component.js @@ -30,9 +30,11 @@ import Alert from '../../components/ui/alert' import AppHeader from '../../components/app/app-header' import UnlockPage from '../unlock-page' import Alerts from '../../components/app/alerts' +import Asset from '../asset' import { ADD_TOKEN_ROUTE, + ASSET_ROUTE, CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE, CONFIRM_ADD_TOKEN_ROUTE, CONFIRM_TRANSACTION_ROUTE, @@ -78,6 +80,7 @@ export default class Routes extends Component { providerId: PropTypes.string, hasPermissionsRequests: PropTypes.bool, autoLockTimeLimit: PropTypes.number, + pageChanged: PropTypes.func.isRequired, } static contextTypes = { @@ -86,7 +89,7 @@ export default class Routes extends Component { } UNSAFE_componentWillMount () { - const { currentCurrency, setCurrentCurrencyToUSD } = this.props + const { currentCurrency, pageChanged, setCurrentCurrencyToUSD } = this.props if (!currentCurrency) { setCurrentCurrencyToUSD() @@ -94,6 +97,7 @@ export default class Routes extends Component { this.props.history.listen((locationObj, action) => { if (action === 'PUSH') { + pageChanged(locationObj.pathname) const url = `&url=${encodeURIComponent('http://www.metamask.io/metametrics' + locationObj.pathname)}` this.context.metricsEvent({}, { currentPath: '', @@ -126,6 +130,7 @@ export default class Routes extends Component { + ) diff --git a/ui/app/pages/routes/routes.container.js b/ui/app/pages/routes/routes.container.js index e243cae54..d4a638250 100644 --- a/ui/app/pages/routes/routes.container.js +++ b/ui/app/pages/routes/routes.container.js @@ -15,6 +15,7 @@ import { setLastActiveTime, setMouseUserState, } from '../../store/actions' +import { pageChanged } from '../../ducks/history/history' function mapStateToProps (state) { const { appState } = state @@ -54,6 +55,7 @@ function mapDispatchToProps (dispatch) { setCurrentCurrencyToUSD: () => dispatch(setCurrentCurrency('usd')), setMouseUserState: (isMouseUser) => dispatch(setMouseUserState(isMouseUser)), setLastActiveTime: () => dispatch(setLastActiveTime()), + pageChanged: (path) => dispatch(pageChanged(path)), } } diff --git a/ui/app/pages/send/send-content/send-asset-row/send-asset-row.container.js b/ui/app/pages/send/send-content/send-asset-row/send-asset-row.container.js index ecc057775..3fdb4803c 100644 --- a/ui/app/pages/send/send-content/send-asset-row/send-asset-row.container.js +++ b/ui/app/pages/send/send-content/send-asset-row/send-asset-row.container.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux' import SendAssetRow from './send-asset-row.component' import { getMetaMaskAccounts, getSendTokenAddress } from '../../../../selectors' -import { updateSend } from '../../../../store/actions' +import { updateSendToken } from '../../../../store/actions' function mapStateToProps (state) { return { @@ -14,7 +14,7 @@ function mapStateToProps (state) { function mapDispatchToProps (dispatch) { return { - setSendToken: (token) => dispatch(updateSend({ token })), + setSendToken: (token) => dispatch(updateSendToken(token)), } } diff --git a/ui/app/pages/send/send-footer/send-footer.component.js b/ui/app/pages/send/send-footer/send-footer.component.js index ce0675f2d..1bf61a3e4 100644 --- a/ui/app/pages/send/send-footer/send-footer.component.js +++ b/ui/app/pages/send/send-footer/send-footer.component.js @@ -1,7 +1,7 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import PageContainerFooter from '../../../components/ui/page-container/page-container-footer' -import { CONFIRM_TRANSACTION_ROUTE, DEFAULT_ROUTE } from '../../../helpers/constants/routes' +import { CONFIRM_TRANSACTION_ROUTE } from '../../../helpers/constants/routes' export default class SendFooter extends Component { @@ -27,6 +27,7 @@ export default class SendFooter extends Component { sendErrors: PropTypes.object, gasEstimateType: PropTypes.string, gasIsLoading: PropTypes.bool, + mostRecentOverviewPage: PropTypes.string.isRequired, } static contextTypes = { @@ -35,8 +36,9 @@ export default class SendFooter extends Component { } onCancel () { - this.props.clearSend() - this.props.history.push(DEFAULT_ROUTE) + const { clearSend, history, mostRecentOverviewPage } = this.props + clearSend() + history.push(mostRecentOverviewPage) } async onSubmit (event) { diff --git a/ui/app/pages/send/send-footer/send-footer.container.js b/ui/app/pages/send/send-footer/send-footer.container.js index b5b6f57d5..02379a9e6 100644 --- a/ui/app/pages/send/send-footer/send-footer.container.js +++ b/ui/app/pages/send/send-footer/send-footer.container.js @@ -32,6 +32,7 @@ import { constructTxParams, constructUpdatedTx, } from './send-footer.utils' +import { getMostRecentOverviewPage } from '../../../ducks/history/history' export default connect(mapStateToProps, mapDispatchToProps)(SendFooter) @@ -62,6 +63,7 @@ function mapStateToProps (state) { sendErrors: getSendErrors(state), gasEstimateType, gasIsLoading: getGasIsLoading(state), + mostRecentOverviewPage: getMostRecentOverviewPage(state), } } diff --git a/ui/app/pages/send/send-footer/tests/send-footer-component.test.js b/ui/app/pages/send/send-footer/tests/send-footer-component.test.js index 56b926c16..4e245573b 100644 --- a/ui/app/pages/send/send-footer/tests/send-footer-component.test.js +++ b/ui/app/pages/send/send-footer/tests/send-footer-component.test.js @@ -2,7 +2,7 @@ import React from 'react' import assert from 'assert' import { shallow } from 'enzyme' import sinon from 'sinon' -import { CONFIRM_TRANSACTION_ROUTE, DEFAULT_ROUTE } from '../../../../helpers/constants/routes' +import { CONFIRM_TRANSACTION_ROUTE } from '../../../../helpers/constants/routes' import SendFooter from '../send-footer.component.js' import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer' @@ -48,6 +48,7 @@ describe('SendFooter Component', function () { unapprovedTxs={{}} update={propsMethodSpies.update} sendErrors={{}} + mostRecentOverviewPage="mostRecentOverviewPage" /> ), { context: { t: (str) => str, metricsEvent: () => ({}) } }) }) @@ -78,7 +79,7 @@ describe('SendFooter Component', function () { assert.equal(historySpies.push.callCount, 0) wrapper.instance().onCancel() assert.equal(historySpies.push.callCount, 1) - assert.equal(historySpies.push.getCall(0).args[0], DEFAULT_ROUTE) + assert.equal(historySpies.push.getCall(0).args[0], 'mostRecentOverviewPage') }) }) diff --git a/ui/app/pages/send/send-header/send-header.component.js b/ui/app/pages/send/send-header/send-header.component.js index 6cabadae6..0ab994bb5 100644 --- a/ui/app/pages/send/send-header/send-header.component.js +++ b/ui/app/pages/send/send-header/send-header.component.js @@ -1,13 +1,13 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import PageContainerHeader from '../../../components/ui/page-container/page-container-header' -import { DEFAULT_ROUTE } from '../../../helpers/constants/routes' export default class SendHeader extends Component { static propTypes = { clearSend: PropTypes.func, history: PropTypes.object, + mostRecentOverviewPage: PropTypes.string, titleKey: PropTypes.string, } @@ -16,8 +16,9 @@ export default class SendHeader extends Component { } onClose () { - this.props.clearSend() - this.props.history.push(DEFAULT_ROUTE) + const { clearSend, history, mostRecentOverviewPage } = this.props + clearSend() + history.push(mostRecentOverviewPage) } render () { diff --git a/ui/app/pages/send/send-header/send-header.container.js b/ui/app/pages/send/send-header/send-header.container.js index 587bb51f2..e79d359c7 100644 --- a/ui/app/pages/send/send-header/send-header.container.js +++ b/ui/app/pages/send/send-header/send-header.container.js @@ -2,11 +2,13 @@ import { connect } from 'react-redux' import { clearSend } from '../../../store/actions' import SendHeader from './send-header.component' import { getTitleKey } from '../../../selectors' +import { getMostRecentOverviewPage } from '../../../ducks/history/history' export default connect(mapStateToProps, mapDispatchToProps)(SendHeader) function mapStateToProps (state) { return { + mostRecentOverviewPage: getMostRecentOverviewPage(state), titleKey: getTitleKey(state), } } diff --git a/ui/app/pages/send/send-header/tests/send-header-component.test.js b/ui/app/pages/send/send-header/tests/send-header-component.test.js index bb4f2a9a4..c5c58739f 100644 --- a/ui/app/pages/send/send-header/tests/send-header-component.test.js +++ b/ui/app/pages/send/send-header/tests/send-header-component.test.js @@ -2,7 +2,6 @@ import React from 'react' import assert from 'assert' import { shallow } from 'enzyme' import sinon from 'sinon' -import { DEFAULT_ROUTE } from '../../../../helpers/constants/routes' import SendHeader from '../send-header.component.js' import PageContainerHeader from '../../../../components/ui/page-container/page-container-header' @@ -25,6 +24,7 @@ describe('SendHeader Component', function () { ), { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }) @@ -51,7 +51,7 @@ describe('SendHeader Component', function () { assert.equal(historySpies.push.callCount, 0) wrapper.instance().onClose() assert.equal(historySpies.push.callCount, 1) - assert.equal(historySpies.push.getCall(0).args[0], DEFAULT_ROUTE) + assert.equal(historySpies.push.getCall(0).args[0], 'mostRecentOverviewPage') }) }) diff --git a/ui/app/pages/send/send-header/tests/send-header-container.test.js b/ui/app/pages/send/send-header/tests/send-header-container.test.js deleted file mode 100644 index 790ceb88a..000000000 --- a/ui/app/pages/send/send-header/tests/send-header-container.test.js +++ /dev/null @@ -1,47 +0,0 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' -import sinon from 'sinon' - -let mapStateToProps -let mapDispatchToProps - -const actionSpies = { - clearSend: sinon.spy(), -} - -proxyquire('../send-header.container.js', { - 'react-redux': { - connect: (ms, md) => { - mapStateToProps = ms - mapDispatchToProps = md - return () => ({}) - }, - }, - '../../../store/actions': actionSpies, - '../../../selectors': { - getTitleKey: (s) => `mockTitleKey:${s}`, - }, -}) - -describe('send-header container', function () { - describe('mapStateToProps()', function () { - it('should map the correct properties to props', function () { - assert.deepEqual(mapStateToProps('mockState'), { - titleKey: 'mockTitleKey:mockState', - }) - }) - }) - - describe('mapDispatchToProps()', function () { - describe('clearSend()', function () { - it('should dispatch an action', function () { - const dispatchSpy = sinon.spy() - const mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) - - mapDispatchToPropsObject.clearSend() - assert(dispatchSpy.calledOnce) - assert(actionSpies.clearSend.calledOnce) - }) - }) - }) -}) diff --git a/ui/app/pages/settings/settings.component.js b/ui/app/pages/settings/settings.component.js index 2814ee9d7..866ed4be7 100644 --- a/ui/app/pages/settings/settings.component.js +++ b/ui/app/pages/settings/settings.component.js @@ -12,7 +12,6 @@ import SecurityTab from './security-tab' import ContactListTab from './contact-list-tab' import { ALERTS_ROUTE, - DEFAULT_ROUTE, ADVANCED_ROUTE, SECURITY_ROUTE, GENERAL_ROUTE, @@ -40,6 +39,7 @@ class SettingsPage extends PureComponent { initialBreadCrumbRoute: PropTypes.string, breadCrumbTextKey: PropTypes.string, initialBreadCrumbKey: PropTypes.string, + mostRecentOverviewPage: PropTypes.string.isRequired, } static contextTypes = { @@ -47,7 +47,7 @@ class SettingsPage extends PureComponent { } render () { - const { history, backRoute, currentPath } = this.props + const { history, backRoute, currentPath, mostRecentOverviewPage } = this.props return (
history.push(DEFAULT_ROUTE)} + onClick={() => history.push(mostRecentOverviewPage)} />
diff --git a/ui/app/pages/settings/settings.container.js b/ui/app/pages/settings/settings.container.js index 503109cfa..61a443eb3 100644 --- a/ui/app/pages/settings/settings.container.js +++ b/ui/app/pages/settings/settings.container.js @@ -6,6 +6,7 @@ import { getAddressBookEntryName } from '../../selectors' import { isValidAddress } from '../../helpers/utils/util' import { ENVIRONMENT_TYPE_POPUP } from '../../../../app/scripts/lib/enums' import { getEnvironmentType } from '../../../../app/scripts/lib/util' +import { getMostRecentOverviewPage } from '../../ducks/history/history' import { CONNECTIONS_ROUTE, @@ -87,6 +88,7 @@ const mapStateToProps = (state, ownProps) => { initialBreadCrumbRoute, breadCrumbTextKey, initialBreadCrumbKey, + mostRecentOverviewPage: getMostRecentOverviewPage(state), } } diff --git a/ui/app/selectors/selectors.js b/ui/app/selectors/selectors.js index dc5929480..1e98b97d5 100644 --- a/ui/app/selectors/selectors.js +++ b/ui/app/selectors/selectors.js @@ -6,18 +6,6 @@ import { checksumAddress, getAccountByAddress, } from '../helpers/utils/util' -import { getSendToken } from './send' -import { getTokens } from '../ducks/metamask/metamask' - -export const getSelectedTokenAddress = (state) => state.metamask.selectedTokenAddress - -export const getSelectedToken = createSelector( - getTokens, - getSelectedTokenAddress, - (tokens, selectedTokenAddress) => { - return tokens.find(({ address }) => address === selectedTokenAddress) - } -) export function getNetworkIdentifier (state) { const { metamask: { provider: { type, nickname, rpcTarget } } } = state @@ -57,15 +45,6 @@ export function getAccountType (state) { } } -export const getSelectedAsset = createSelector( - getSelectedToken, - getSendToken, - (selectedToken, sendToken) => { - const token = selectedToken || sendToken - return token?.symbol || 'ETH' - } -) - export function getCurrentNetworkId (state) { return state.metamask.network } @@ -327,10 +306,9 @@ export function getTargetDomainMetadata (state, request, defaultOrigin) { return targetDomainMetadata } -export const getMetaMetricState = (state) => { +export const getBackgroundMetaMetricState = (state) => { return { network: getCurrentNetworkId(state), - activeCurrency: getSelectedAsset(state), accountType: getAccountType(state), metaMetricsId: state.metamask.metaMetricsId, numberOfTokens: getNumberOfTokens(state), diff --git a/ui/app/selectors/tests/send-selectors-test-data.js b/ui/app/selectors/tests/send-selectors-test-data.js index cc042a23f..a5bd43892 100644 --- a/ui/app/selectors/tests/send-selectors-test-data.js +++ b/ui/app/selectors/tests/send-selectors-test-data.js @@ -117,7 +117,6 @@ const state = { 'time': 1400000000000, }, ], - 'selectedTokenAddress': '0x8d6b81208414189a58339873ab429b6c47ab92d3', 'unapprovedMsgs': { '0xabc': { id: 'unapprovedMessage1', 'time': 1650000000000 }, '0xdef': { id: 'unapprovedMessage2', 'time': 1550000000000 }, diff --git a/ui/app/store/actionConstants.js b/ui/app/store/actionConstants.js index b784c9819..4a11aa111 100644 --- a/ui/app/store/actionConstants.js +++ b/ui/app/store/actionConstants.js @@ -28,7 +28,6 @@ export const LOCK_METAMASK = 'LOCK_METAMASK' export const DISPLAY_WARNING = 'DISPLAY_WARNING' export const HIDE_WARNING = 'HIDE_WARNING' // accounts screen -export const SET_SELECTED_TOKEN = 'SET_SELECTED_TOKEN' export const SHOW_ACCOUNT_DETAIL = 'SHOW_ACCOUNT_DETAIL' export const SHOW_ACCOUNTS_PAGE = 'SHOW_ACCOUNTS_PAGE' export const SHOW_CONF_TX_PAGE = 'SHOW_CONF_TX_PAGE' @@ -53,6 +52,7 @@ export const UPDATE_SEND_AMOUNT = 'UPDATE_SEND_AMOUNT' export const UPDATE_SEND_ERRORS = 'UPDATE_SEND_ERRORS' export const UPDATE_MAX_MODE = 'UPDATE_MAX_MODE' export const UPDATE_SEND = 'UPDATE_SEND' +export const UPDATE_SEND_TOKEN = 'UPDATE_SEND_TOKEN' export const CLEAR_SEND = 'CLEAR_SEND' export const GAS_LOADING_STARTED = 'GAS_LOADING_STARTED' export const GAS_LOADING_FINISHED = 'GAS_LOADING_FINISHED' diff --git a/ui/app/store/actions.js b/ui/app/store/actions.js index 2eaa33017..99aac3cac 100644 --- a/ui/app/store/actions.js +++ b/ui/app/store/actions.js @@ -1,7 +1,7 @@ import abi from 'human-standard-token-abi' import pify from 'pify' import getBuyEthUrl from '../../../app/scripts/lib/buy-eth-url' -import { getTokenAddressFromTokenObject, checksumAddress } from '../helpers/utils/util' +import { checksumAddress } from '../helpers/utils/util' import { calcTokenBalance, estimateGas } from '../pages/send/send.utils' import ethUtil from 'ethereumjs-util' import { fetchLocale } from '../helpers/utils/i18n-helper' @@ -729,6 +729,13 @@ export function updateSend (newSend) { } } +export function updateSendToken (token) { + return { + type: actionConstants.UPDATE_SEND_TOKEN, + value: token, + } +} + export function clearSend () { return { type: actionConstants.CLEAR_SEND, @@ -1153,13 +1160,6 @@ export function lockMetamask () { } } -export function setSelectedToken (tokenAddress) { - return { - type: actionConstants.SET_SELECTED_TOKEN, - value: tokenAddress || null, - } -} - async function _setSelectedAddress (dispatch, address) { log.debug(`background.setSelectedAddress`) const tokens = await promisifiedBackground.setSelectedAddress(address) @@ -1207,7 +1207,6 @@ export function showAccountDetail (address) { type: actionConstants.SHOW_ACCOUNT_DETAIL, value: address, }) - dispatch(setSelectedToken()) if (unconnectedAccountAlertIsEnabled && switchingToUnconnectedAddress) { dispatch(switchedToUnconnectedAccount()) await setSwitchToConnectedAlertShown(activeTabOrigin) @@ -1293,12 +1292,10 @@ export function removeToken (address) { export function addTokens (tokens) { return (dispatch) => { if (Array.isArray(tokens)) { - dispatch(setSelectedToken(getTokenAddressFromTokenObject(tokens[0]))) return Promise.all(tokens.map(({ address, symbol, decimals }) => ( dispatch(addToken(address, symbol, decimals)) ))) } else { - dispatch(setSelectedToken(getTokenAddressFromTokenObject(tokens))) return Promise.all( Object .entries(tokens) @@ -1435,7 +1432,6 @@ export function setProviderType (type) { } dispatch(setPreviousProvider(currentProviderType)) dispatch(updateProviderType(type)) - dispatch(setSelectedToken()) } } @@ -1483,8 +1479,6 @@ export function editRpc (oldRpc, newRpc, chainId, ticker = 'ETH', nickname, rpcP return } - dispatch(setSelectedToken()) - try { await promisifiedBackground.updateAndSetCustomRpc(newRpc, chainId, ticker, nickname || newRpc, rpcPrefs) } catch (error) { @@ -1511,7 +1505,6 @@ export function setRpcTarget (newRpc, chainId, ticker = 'ETH', nickname) { dispatch(displayWarning('Had a problem changing networks!')) return } - dispatch(setSelectedToken()) } } @@ -1525,7 +1518,6 @@ export function delRpcTarget (oldRpc) { dispatch(displayWarning('Had a problem removing network!')) return reject(err) } - dispatch(setSelectedToken()) resolve() }) })