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() }) })