From d8179ff030f8a861e5404f2b09c73da39331e741 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Thu, 2 Apr 2020 06:39:53 -0230 Subject: [PATCH] Connect Screen Multi Select (#8078) * Add UI for selecting multiple accounts on the first permissions connect screen * Make accounts list scrollable on connect screen * Change title wording on connect screen to 'select your accounts' * Add select all tooltip to info circle on top of connect screen account list * Add security info footer to the first screen of the connect flow * Apply redesigns to page 2 of connect flow * Display number of accounts on connect flow second screen if there are multiple to connect * Update e2e tests for connect screen multi-select changes * Remove unused chooseAnAcount message * Fix styling/display of redirect elements on second page of connect flow * Assorted small fixes in permissions connect * Remove unnecessary tiny delays in spec files * Remove incorrect use of bem modified in choose-account * Remove unused locale * Use Set for managing selected accounts in choose-acount and permissions-connect componets * Compone! * Move connect flow header into a reusable component, and implement new header designs * Update locales and add missing locales * Improve permission list item design (second screen of connect flow) * Check box component improvements * Fixes in variables.scss * Simplfy code in selectAll of choose-account.component * Hide checkboxes on first pages on connect flow when there is only one account * Allow autofill of default new account modal text with right arrow * Disable next button on first screen of connect flow when no accounts selected * Improve choose-account/index.scss * Remove metamask secure graphic * Fix connect flow redirect screen * Fix connectToMultiple locale * Remove locales no longer used after connect flow multiple connect updates * Fix size of dapp icon on redirect screen of connect flow * Clean up choose-account code * Stop using placeholder in new-account-modal * Remove unused styles in permission-page-container/index.scss * Pass origin instead of site name to PermissionsConnectHeader in connect flow * Make iconName a required prop in permissions-connect-header * Show checkbox in cases where there is one account in the choose-account list * Do not render select all checkbox when only 1 list item, instead of just hiding it * Small cleanup in choose-account/index.scss --- 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/da/messages.json | 3 - app/_locales/de/messages.json | 3 - app/_locales/el/messages.json | 3 - app/_locales/en/messages.json | 50 ++- 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/hr/messages.json | 3 - app/_locales/hu/messages.json | 3 - app/_locales/id/messages.json | 3 - app/_locales/it/messages.json | 19 +- 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/no/messages.json | 3 - app/_locales/pl/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/th/messages.json | 3 - app/_locales/uk/messages.json | 3 - app/_locales/zh_CN/messages.json | 3 - app/_locales/zh_TW/messages.json | 3 - app/images/broken-line.svg | 2 +- test/e2e/ethereum-on.spec.js | 1 + test/e2e/metamask-ui.spec.js | 1 + test/e2e/permissions.spec.js | 1 + test/e2e/signature-request.spec.js | 1 + ui/app/components/app/index.scss | 4 + .../new-account-modal.component.js | 3 +- .../app/permission-page-container/index.scss | 304 +++++++----------- ...ission-page-container-content.component.js | 100 +++--- .../permission-page-container.component.js | 12 +- .../permission-page-container.container.js | 9 +- .../app}/permissions-connect-header/index.js | 0 .../app/permissions-connect-header/index.scss | 39 +++ .../permissions-connect-header.component.js | 44 +++ .../ui/check-box/check-box.component.js | 36 +++ ui/app/components/ui/check-box/index.js | 1 + ui/app/components/ui/check-box/index.scss | 26 ++ ui/app/css/itcss/settings/variables.scss | 4 +- .../choose-account.component.js | 141 ++++++-- .../choose-account/index.scss | 90 +++++- ui/app/pages/permissions-connect/index.scss | 18 +- .../permissions-connect-footer.component.js | 3 +- .../permissions-connect-header/index.scss | 15 - .../permissions-connect-header.component.js | 23 -- .../permissions-connect.component.js | 74 +++-- .../permissions-connect.container.js | 4 + ui/app/selectors/selectors.js | 11 + 69 files changed, 635 insertions(+), 521 deletions(-) rename ui/app/{pages/permissions-connect => components/app}/permissions-connect-header/index.js (100%) create mode 100644 ui/app/components/app/permissions-connect-header/index.scss create mode 100644 ui/app/components/app/permissions-connect-header/permissions-connect-header.component.js create mode 100644 ui/app/components/ui/check-box/check-box.component.js create mode 100644 ui/app/components/ui/check-box/index.js create mode 100644 ui/app/components/ui/check-box/index.scss delete mode 100644 ui/app/pages/permissions-connect/permissions-connect-header/index.scss delete mode 100644 ui/app/pages/permissions-connect/permissions-connect-header/permissions-connect-header.component.js diff --git a/app/_locales/am/messages.json b/app/_locales/am/messages.json index 850b645ea..0b58b5d86 100644 --- a/app/_locales/am/messages.json +++ b/app/_locales/am/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "አይቀበሉ" }, - "likeToConnect": { - "message": "$1ከመለያዎ ጋር ለመገናኘት ይፈልጋል" - }, "about": { "message": "ስለ" }, diff --git a/app/_locales/ar/messages.json b/app/_locales/ar/messages.json index 6f1175cd0..05cc5ddb0 100644 --- a/app/_locales/ar/messages.json +++ b/app/_locales/ar/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "رفض" }, - "likeToConnect": { - "message": "يرغب $1 في الاتصال بحسابك" - }, "about": { "message": "حول" }, diff --git a/app/_locales/bg/messages.json b/app/_locales/bg/messages.json index f32bd22e1..d4c72149f 100644 --- a/app/_locales/bg/messages.json +++ b/app/_locales/bg/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Отхвърляне" }, - "likeToConnect": { - "message": "$1 би искал да се свърже с вашия акаунт" - }, "about": { "message": "Информация" }, diff --git a/app/_locales/bn/messages.json b/app/_locales/bn/messages.json index b5e11e08f..5b2c67291 100644 --- a/app/_locales/bn/messages.json +++ b/app/_locales/bn/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "প্রত্যাখ্যান" }, - "likeToConnect": { - "message": "$1 আপনার অ্যাকাউন্টের সাথে সংযোগ করতে চায়" - }, "about": { "message": "সম্পর্কে" }, diff --git a/app/_locales/ca/messages.json b/app/_locales/ca/messages.json index 6991aff0d..42849f804 100644 --- a/app/_locales/ca/messages.json +++ b/app/_locales/ca/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Rebutja" }, - "likeToConnect": { - "message": "a $1 li agradaria connectar-se al teu compte" - }, "about": { "message": "Informació" }, diff --git a/app/_locales/da/messages.json b/app/_locales/da/messages.json index b764ec4a7..9294d37be 100644 --- a/app/_locales/da/messages.json +++ b/app/_locales/da/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Afvis" }, - "likeToConnect": { - "message": "$1 ønsker at forbinde til din konto" - }, "about": { "message": "Om" }, diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index 1956b25ca..abbbbb949 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Ablehnen" }, - "likeToConnect": { - "message": "$1 möchte sich mit deinem Account verbinden" - }, "about": { "message": "Über" }, diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index a802f6032..8dc15f54d 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Απόρριψη" }, - "likeToConnect": { - "message": "Αίτημα σύνδεσης στον λογαριασμό σας από $1" - }, "about": { "message": "Σχετικά με" }, diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 0f3769029..50c70cef1 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -32,17 +32,31 @@ "showIncomingTransactionsDescription": { "message": "Select this to use Etherscan to show incoming transactions in the transactions list" }, + "cancelling": { + "message": "Cancelling..." + }, "cancelledConnectionWithMetaMask": { "message": "Cancelled Connection With MetaMask" }, "chartOnlyAvailableEth": { "message": "Chart only available on Ethereum networks." }, + "connecting": { + "message": "Connecting..." + }, + "connectWithMetaMask": { + "message": "Connect With MetaMask" + }, "connectingWithMetaMask": { "message": "Connecting With MetaMask..." }, - "chooseAnAcount": { - "message": "Choose an account" + "connectTo": { + "message": "Connect to $1", + "description": "$1 is the name/origin of a site/dapp that the user can connect to metamask" + }, + "connectToMultiple": { + "message": "Connect to $1 accounts", + "description": "$1 is the number of accounts to connect to" }, "contractInteraction": { "message": "Contract Interaction" @@ -50,9 +64,6 @@ "reject": { "message": "Reject" }, - "redirectingBackToDapp": { - "message": "Redirecting back to dapp..." - }, "about": { "message": "About" }, @@ -266,6 +277,9 @@ "chainId": { "message": "Chain ID" }, + "chooseAccountsToUse": { + "message": "Choose the account(s) to use on this site" + }, "clickToRevealSeed": { "message": "Click here to reveal secret words" }, @@ -290,6 +304,9 @@ "congratulations": { "message": "Congratulations" }, + "connectAccountOrCreate": { + "message": "Connect account or create new" + }, "connectHardwareWallet": { "message": "Connect Hardware Wallet" }, @@ -788,9 +805,6 @@ "learnMore": { "message": "Learn more" }, - "learnAboutRisks": { - "message": "Learn about the risks here." - }, "ledgerAccountRestriction": { "message": "You need to make use your last account before you can add a new one." }, @@ -800,10 +814,6 @@ "likeToAddTokens": { "message": "Would you like to add these tokens?" }, - "likeToConnect": { - "message": "$1 would like to connect to your MetaMask account", - "description": "$1 is the name/url of a site/dapp asking to connect to MetaMask" - }, "links": { "message": "Links" }, @@ -1006,6 +1016,12 @@ "pending": { "message": "pending" }, + "permissionCheckedIconDescription": { + "message": "You have approved this permission" + }, + "permissionUncheckedIconDescription": { + "message": "You have not approved this permission" + }, "personalAddressDetected": { "message": "Personal address detected. Input the token contract address." }, @@ -1185,6 +1201,12 @@ "seedPhraseReq": { "message": "Seed phrases contain 12, 15, 18, 21, or 24 words" }, + "selectingAllWillAllow": { + "message": "Selecting all will allow this site to view all of your current accounts. Make sure you trust this site." + }, + "selectAll": { + "message": "Select all" + }, "selectCurrency": { "message": "Select Currency" }, @@ -1422,10 +1444,6 @@ "toWithColon": { "message": "To:" }, - "toConnectWith": { - "message": "To connect with $1", - "description": "$1 is the name or domain of a site/dapp that asking to connect with MetaMask" - }, "toETHviaShapeShift": { "message": "$1 to ETH via ShapeShift", "description": "system will fill in deposit type in start of message" diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index 9f5886305..33b5f88ad 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Rechazar" }, - "likeToConnect": { - "message": "$1 quisiera conectar con tu cuenta" - }, "about": { "message": "Acerca" }, diff --git a/app/_locales/es_419/messages.json b/app/_locales/es_419/messages.json index 5be2808da..104963908 100644 --- a/app/_locales/es_419/messages.json +++ b/app/_locales/es_419/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Rechazar" }, - "likeToConnect": { - "message": "$1 desea conectarse a tu cuenta" - }, "about": { "message": "Acerca de" }, diff --git a/app/_locales/et/messages.json b/app/_locales/et/messages.json index afa914e09..2b54919f0 100644 --- a/app/_locales/et/messages.json +++ b/app/_locales/et/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Lükka tagasi" }, - "likeToConnect": { - "message": "$1 soovib teie kontoga ühenduse luua" - }, "about": { "message": "Teave" }, diff --git a/app/_locales/fa/messages.json b/app/_locales/fa/messages.json index 2ca8558c7..bc6299612 100644 --- a/app/_locales/fa/messages.json +++ b/app/_locales/fa/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "عدم پذیرش" }, - "likeToConnect": { - "message": "1$1 میخواهید تا با حساب تان وصل شوید" - }, "about": { "message": "درباره" }, diff --git a/app/_locales/fi/messages.json b/app/_locales/fi/messages.json index 20c900807..fefce0a81 100644 --- a/app/_locales/fi/messages.json +++ b/app/_locales/fi/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Hylkää" }, - "likeToConnect": { - "message": "$1 haluaisi yhdistää tiliisi" - }, "about": { "message": "Tietoja asetuksista" }, diff --git a/app/_locales/fil/messages.json b/app/_locales/fil/messages.json index b9cd84232..25a8c488b 100644 --- a/app/_locales/fil/messages.json +++ b/app/_locales/fil/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Tanggihan" }, - "likeToConnect": { - "message": "Gusto ng $1 na kumonekta sa iyong account" - }, "about": { "message": "Tungkol sa" }, diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index c83646c2e..5a99ca09f 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Rejeter" }, - "likeToConnect": { - "message": "$1 voudrait se connecter à votre compte" - }, "about": { "message": "À propos" }, diff --git a/app/_locales/he/messages.json b/app/_locales/he/messages.json index be958c974..4f0b89c4e 100644 --- a/app/_locales/he/messages.json +++ b/app/_locales/he/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "דחה" }, - "likeToConnect": { - "message": "$1 מבקש להתחבר לחשבון שלך" - }, "about": { "message": "מידע כללי" }, diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index 3fdd88203..f3a2626d9 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "अस्‍वीकार करें" }, - "likeToConnect": { - "message": "$1 आपके खाते से कनेक्ट होता चाहता हैं" - }, "about": { "message": "इसके बारे में" }, diff --git a/app/_locales/hr/messages.json b/app/_locales/hr/messages.json index b153a9130..6f055a9a6 100644 --- a/app/_locales/hr/messages.json +++ b/app/_locales/hr/messages.json @@ -12,9 +12,6 @@ "reject": { "message": "Odbaci" }, - "likeToConnect": { - "message": "Korisnik $1 želi se povezati na vaš račun" - }, "about": { "message": "O opcijama" }, diff --git a/app/_locales/hu/messages.json b/app/_locales/hu/messages.json index 6bbaeb67a..94a97b8a9 100644 --- a/app/_locales/hu/messages.json +++ b/app/_locales/hu/messages.json @@ -12,9 +12,6 @@ "reject": { "message": "Elutasítás" }, - "likeToConnect": { - "message": "$1 szeretne kapcsolódni az ön fiókjához" - }, "about": { "message": "Névjegy" }, diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index 7b161be24..b8c046ce4 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -12,9 +12,6 @@ "reject": { "message": "Tolak" }, - "likeToConnect": { - "message": "$1 ingin menghubungkan ke akun Anda" - }, "about": { "message": "Tentang" }, diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json index 90a501876..445f04596 100644 --- a/app/_locales/it/messages.json +++ b/app/_locales/it/messages.json @@ -26,8 +26,9 @@ "connectingWithMetaMask": { "message": "Connettendo con MetaMask..." }, - "chooseAnAcount": { - "message": "Scegli un account" + "connectTo": { + "message": "Collegati a $1", + "description": "$1 is the name/origin of a site/dapp that the user can connect to metamask" }, "contractInteraction": { "message": "Interazione Contratto" @@ -35,9 +36,6 @@ "reject": { "message": "Annulla" }, - "redirectingBackToDapp": { - "message": "Ritornando alla dapp..." - }, "about": { "message": "Informazioni" }, @@ -773,9 +771,6 @@ "learnMore": { "message": "Scopri di più" }, - "learnAboutRisks": { - "message": "Scopri di piu sui rischi qua." - }, "ledgerAccountRestriction": { "message": "E' necessario utilizzare l'ultimo account prima di poterne aggiungere uno nuovo." }, @@ -785,10 +780,6 @@ "likeToAddTokens": { "message": "Vorresti aggiungere questi token?" }, - "likeToConnect": { - "message": "$1 vorrebbe connettersi al tuo account", - "description": "$1 is the name/url of a site/dapp asking to connect to MetaMask" - }, "links": { "message": "Collegamenti" }, @@ -1401,10 +1392,6 @@ "toWithColon": { "message": "To:" }, - "toConnectWith": { - "message": "Di connettersi con $1", - "description": "$1 is the name or domain of a site/dapp that asking to connect with MetaMask" - }, "toETHviaShapeShift": { "message": "$1 a ETH con ShapeShift", "description": "system will fill in deposit type in start of message" diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index c157470d3..840a450a3 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "拒否" }, - "likeToConnect": { - "message": "$1 はあなたのアカウントにアクセスしようとしています。" - }, "aboutSettingsDescription": { "message": "バージョンやサポート、問合せ先など" }, diff --git a/app/_locales/kn/messages.json b/app/_locales/kn/messages.json index 8f6e7b88e..00a1456ad 100644 --- a/app/_locales/kn/messages.json +++ b/app/_locales/kn/messages.json @@ -12,9 +12,6 @@ "reject": { "message": "ತಿರಸ್ಕರಿಸಿ" }, - "likeToConnect": { - "message": "$1 ನಿಮ್ಮ ಖಾತೆಗೆ ಸಂಪರ್ಕಿಸಲು ಬಯಸುತ್ತಿದೆ" - }, "about": { "message": "ಕುರಿತು" }, diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index abf255f64..504ed9d27 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "거부" }, - "likeToConnect": { - "message": "$1이 당신의 계정에 연결하길 원합니다." - }, "about": { "message": "정보" }, diff --git a/app/_locales/lt/messages.json b/app/_locales/lt/messages.json index bc383babd..0e1a07e9a 100644 --- a/app/_locales/lt/messages.json +++ b/app/_locales/lt/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Atmesti" }, - "likeToConnect": { - "message": "$1 norėtų prisijungti prie jūsų paskyros" - }, "about": { "message": "Apie" }, diff --git a/app/_locales/lv/messages.json b/app/_locales/lv/messages.json index 395609a77..dfe92ee03 100644 --- a/app/_locales/lv/messages.json +++ b/app/_locales/lv/messages.json @@ -12,9 +12,6 @@ "reject": { "message": "Noraidīt" }, - "likeToConnect": { - "message": "$1 vēlas izveidot savienojumu ar jūsu kontu" - }, "about": { "message": "Par" }, diff --git a/app/_locales/ms/messages.json b/app/_locales/ms/messages.json index 0bc23a5fd..d5c81e319 100644 --- a/app/_locales/ms/messages.json +++ b/app/_locales/ms/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Tolak" }, - "likeToConnect": { - "message": "$1 ingin menyambung kepada akaun anda" - }, "about": { "message": "Mengenai" }, diff --git a/app/_locales/no/messages.json b/app/_locales/no/messages.json index 9e98d681d..a1ec637de 100644 --- a/app/_locales/no/messages.json +++ b/app/_locales/no/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Avslå" }, - "likeToConnect": { - "message": "$1 ønsker å forbindes med kontoen din " - }, "about": { "message": "Info" }, diff --git a/app/_locales/pl/messages.json b/app/_locales/pl/messages.json index 8d4095ee6..02476cf02 100644 --- a/app/_locales/pl/messages.json +++ b/app/_locales/pl/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Odrzuć" }, - "likeToConnect": { - "message": "$1 chce połączyć się z Twoim kontem" - }, "about": { "message": "Informacje" }, diff --git a/app/_locales/pt_BR/messages.json b/app/_locales/pt_BR/messages.json index eef7b332b..c62e68eba 100644 --- a/app/_locales/pt_BR/messages.json +++ b/app/_locales/pt_BR/messages.json @@ -12,9 +12,6 @@ "reject": { "message": "Rejeitar" }, - "likeToConnect": { - "message": "$1 gostaria de se conectar à sua conta" - }, "about": { "message": "Sobre" }, diff --git a/app/_locales/ro/messages.json b/app/_locales/ro/messages.json index 64c1038d3..da63bed5e 100644 --- a/app/_locales/ro/messages.json +++ b/app/_locales/ro/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Respingeți" }, - "likeToConnect": { - "message": "$1 ar dori să se conecteze la contul dvs." - }, "about": { "message": "Despre" }, diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index 31388c8f1..1a816afd9 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -527,9 +527,6 @@ "contractInteraction": { "message": "Взаимодействие с контрактом" }, - "likeToConnect": { - "message": "$1 запрашивает доступ к вашему аккаунту" - }, "about": { "message": "О нас" }, diff --git a/app/_locales/sk/messages.json b/app/_locales/sk/messages.json index c9ad8ef45..189086031 100644 --- a/app/_locales/sk/messages.json +++ b/app/_locales/sk/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Odmítnout" }, - "likeToConnect": { - "message": "$1 sa chce pripojiť k vášmu účtu" - }, "about": { "message": "Informácie" }, diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json index 85fda71e8..13cad75ff 100644 --- a/app/_locales/sl/messages.json +++ b/app/_locales/sl/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Zavrni" }, - "likeToConnect": { - "message": "$1 se želi povezati z vašim računom." - }, "about": { "message": "O možnostih" }, diff --git a/app/_locales/sr/messages.json b/app/_locales/sr/messages.json index 481b00415..aae8f1926 100644 --- a/app/_locales/sr/messages.json +++ b/app/_locales/sr/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Одбиј" }, - "likeToConnect": { - "message": "$1 bi hteo da se poveže sa vašim nalogom" - }, "about": { "message": "Основни подаци" }, diff --git a/app/_locales/sv/messages.json b/app/_locales/sv/messages.json index 54c075bf3..b9b42d1ab 100644 --- a/app/_locales/sv/messages.json +++ b/app/_locales/sv/messages.json @@ -12,9 +12,6 @@ "reject": { "message": "Avvisa" }, - "likeToConnect": { - "message": "$1 vill ansluta till ditt konto" - }, "about": { "message": "Om" }, diff --git a/app/_locales/sw/messages.json b/app/_locales/sw/messages.json index 79bc204b7..ee168aee7 100644 --- a/app/_locales/sw/messages.json +++ b/app/_locales/sw/messages.json @@ -12,9 +12,6 @@ "reject": { "message": "Kataa" }, - "likeToConnect": { - "message": "$1 ingependa kuunganishwa kwenye akaunti yako" - }, "about": { "message": "Kuhusu" }, diff --git a/app/_locales/th/messages.json b/app/_locales/th/messages.json index b7553f29c..fc84f87de 100644 --- a/app/_locales/th/messages.json +++ b/app/_locales/th/messages.json @@ -2,9 +2,6 @@ "reject": { "message": "ปฏิเสธ" }, - "likeToConnect": { - "message": "$1 ต้องการเชื่อมต่อกับบัญชีของคุณ" - }, "about": { "message": "เกี่ยวกับ" }, diff --git a/app/_locales/uk/messages.json b/app/_locales/uk/messages.json index c48a45950..60085ef0a 100644 --- a/app/_locales/uk/messages.json +++ b/app/_locales/uk/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "Відхилити" }, - "likeToConnect": { - "message": "$1 бажає підключитися до вашого облікового запису" - }, "about": { "message": "Про Google Chrome" }, diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index b7e4513dd..67a137260 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "拒绝" }, - "likeToConnect": { - "message": "$1 希望关联您的账户" - }, "about": { "message": "关于" }, diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json index 611ea6fdf..14d083514 100644 --- a/app/_locales/zh_TW/messages.json +++ b/app/_locales/zh_TW/messages.json @@ -8,9 +8,6 @@ "reject": { "message": "拒絕" }, - "likeToConnect": { - "message": "$1 請求訪問帳戶權限" - }, "about": { "message": "關於" }, diff --git a/app/images/broken-line.svg b/app/images/broken-line.svg index ec4ed0d9c..71e1a4f23 100644 --- a/app/images/broken-line.svg +++ b/app/images/broken-line.svg @@ -1,3 +1,3 @@ - + diff --git a/test/e2e/ethereum-on.spec.js b/test/e2e/ethereum-on.spec.js index deb7c16f1..53a87874a 100644 --- a/test/e2e/ethereum-on.spec.js +++ b/test/e2e/ethereum-on.spec.js @@ -127,6 +127,7 @@ describe('MetaMask', function () { await driver.clickElement(By.css('.permissions-connect-choose-account__account')) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.clickElement(By.xpath(`//button[contains(text(), 'Submit')]`)) await driver.waitUntilXWindowHandles(2) diff --git a/test/e2e/metamask-ui.spec.js b/test/e2e/metamask-ui.spec.js index 324d43d29..abfac9dfa 100644 --- a/test/e2e/metamask-ui.spec.js +++ b/test/e2e/metamask-ui.spec.js @@ -415,6 +415,7 @@ describe('MetaMask', function () { await driver.clickElement(By.css('.permissions-connect-choose-account__account')) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.clickElement(By.xpath(`//button[contains(text(), 'Submit')]`)) await driver.waitUntilXWindowHandles(2) diff --git a/test/e2e/permissions.spec.js b/test/e2e/permissions.spec.js index 5ba6a0da3..b032b3418 100644 --- a/test/e2e/permissions.spec.js +++ b/test/e2e/permissions.spec.js @@ -125,6 +125,7 @@ describe('MetaMask', function () { await driver.clickElement(By.css('.permissions-connect-choose-account__account')) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.clickElement(By.xpath(`//button[contains(text(), 'Submit')]`)) await driver.waitUntilXWindowHandles(2) diff --git a/test/e2e/signature-request.spec.js b/test/e2e/signature-request.spec.js index b17bf48c5..c90f37c04 100644 --- a/test/e2e/signature-request.spec.js +++ b/test/e2e/signature-request.spec.js @@ -86,6 +86,7 @@ describe('MetaMask', function () { await driver.clickElement(By.css('.permissions-connect-choose-account__account')) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.clickElement(By.xpath(`//button[contains(text(), 'Submit')]`)) await driver.waitUntilXWindowHandles(2) diff --git a/ui/app/components/app/index.scss b/ui/app/components/app/index.scss index d0f3f4dc7..6b77907b1 100644 --- a/ui/app/components/app/index.scss +++ b/ui/app/components/app/index.scss @@ -95,3 +95,7 @@ @import './connected-status-indicator/index'; @import './dropdowns/account-details-dropdown/index'; + +@import '../ui/check-box/index'; + +@import 'permissions-connect-header/index'; diff --git a/ui/app/components/app/modals/new-account-modal/new-account-modal.component.js b/ui/app/components/app/modals/new-account-modal/new-account-modal.component.js index 01940cbc0..547b93285 100644 --- a/ui/app/components/app/modals/new-account-modal/new-account-modal.component.js +++ b/ui/app/components/app/modals/new-account-modal/new-account-modal.component.js @@ -15,7 +15,7 @@ export default class NewAccountModal extends Component { } state = { - alias: '', + alias: this.context.t('newAccountNumberName', [this.props.newAccountNumber]), } onChange = (e) => { @@ -53,7 +53,6 @@ export default class NewAccountModal extends Component { onChange={this.onChange} onKeyPress={this.onKeyPress} value={this.state.alias} - placeholder={ t('account', [this.props.newAccountNumber]) } autoFocus /> diff --git a/ui/app/components/app/permission-page-container/index.scss b/ui/app/components/app/permission-page-container/index.scss index a7ba97151..08e7465d8 100644 --- a/ui/app/components/app/permission-page-container/index.scss +++ b/ui/app/components/app/permission-page-container/index.scss @@ -18,8 +18,7 @@ @extend %header--18; line-height: 25px; text-align: center; - position: fixed; - left: 0; + margin-top: 32px; width: 100%; } @@ -31,214 +30,38 @@ color: #7C808E; &--redirect { - margin-top: 60px; - } - - h1, h2 { - color: #4A4A4A; + margin-top: 50px; + width: 100%; display: flex; - justify-content: center; - text-align: center; - } - - h2 { - font-size: 16px; - line-height: 18px; - padding: 20px; - } - - h1 { - font-size: 22px; - line-height: 26px; - padding: 20px; - } - - p { - padding: 0 40px; - text-align: center; - font-size: 12px; - line-height: 18px; + align-items: center; + padding-top: 8px; } a, a:hover { color: $dodger-blue; } - section { - h1 { - padding: 30px 0px 0px 0px; - } - - h2 { - padding: 0px 0px 20px 0px; - } - } - &__requested { text-align: left; } &__revoke-note { - margin-top: 24px; - } - - &__checkbox { - margin-right: 10px; + margin-top: 60px; } &__permission { + display: flex; margin-top: 18px; i { - color: #6A737D; + font-size: 1.4rem; + color: $Grey-200; } label { margin-left: 6px; - color: #24292E; + color: $Black-100; } } - - .permission-approval-visual { - display: flex; - flex-direction: row; - justify-content: space-evenly; - position: relative; - margin: 0 32px; - margin-top: 40px; - - section { - display: flex; - flex-direction: column; - align-items: center; - flex: 1; - } - - h1 { - font-size: 14px; - line-height: 18px; - padding: 8px 0 0; - } - - h2 { - font-size: 12px; - line-height: 17px; - color: #6A737D; - padding: 0; - } - - &__check { - width: 40px; - height: 40px; - background: white url("/images/permissions-check.svg") no-repeat; - margin-top: 24px; - z-index: 1; - } - - &__reject { - background: white; - z-index: 1; - display: flex; - justify-content: center; - align-items: center; - - i { - color: #D73A49; - transform: scale(3); - } - } - - &__broken-line { - z-index: 0; - position: absolute; - top: 43px; - } - - &__identicon, .icon-with-fallback__identicon { - width: 32px; - height: 32px; - z-index: 1; - - &--default { - background-color: #777A87; - color: white; - width: 64px; - height: 64px; - border-radius: 32px; - display: flex; - align-items: center; - justify-content: center; - font-weight: bold; - z-index: 1; - } - } - - &__identicon-container, .icon-with-fallback__identicon-container { - padding: 1rem; - flex: 1; - position: relative; - width: 100%; - display: flex; - justify-content: center; - align-items: center; - } - - &__identicon-border, .icon-with-fallback__identicon-border { - height: 64px; - width: 64px; - border-radius: 50%; - border: 1px solid white; - background: #FFFFFF; - box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.25); - } - - &__identicon-border { - display: flex; - justify-content: center; - align-items: center; - } - - .icon-with-fallback__identicon-border { - position: absolute; - } - - &:before { - border-top: 2px dashed #CDD1E4; - content: ""; - margin: 0 auto; - position: absolute; - top: 32px; - left: 0; - bottom: 0; - right: 0; - width: 65%; - z-index: -1; - } - - &__account-info { - display: flex; - flex-direction: column; - align-items: center; - - &__label { - @extend %content-text; - line-height: 20px; - color: #000000; - } - - &__address { - @extend %font; - font-size: 12px; - line-height: 17px; - color: #6A737D; - } - } - } - - .secure-badge { - display: flex; - justify-content: center; - padding: 25px; - } } &__permissions-header { @@ -266,10 +89,6 @@ } } - &__permissions-header-redirect { - text-align: center; - } - @media screen and (max-width: 575px) { width: 100%; margin-top: 25px; @@ -288,3 +107,106 @@ } } } + +.permission-result { + @extend %header--24; + + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + text-align: center; + color: $Black-100; + height: 114px; + + &__icons { + display: flex; + } + + &__center-icon { + display: flex; + position: relative; + justify-content: center; + align-items: center; + font-size: 12px; + } + + h1 { + font-size: 14px; + line-height: 18px; + padding: 8px 0 0; + } + + h2 { + font-size: 12px; + line-height: 17px; + color: #6A737D; + padding: 0; + } + + &__check { + width: 40px; + height: 40px; + background: white url("/images/permissions-check.svg") no-repeat; + position: absolute; + } + + &__reject { + position: absolute; + background: white; + display: flex; + justify-content: center; + align-items: center; + + i { + color: #D73A49; + transform: scale(3); + } + } + + &__identicon, .icon-with-fallback__identicon { + width: 32px; + height: 32px; + + &--default { + background-color: #777A87; + color: white; + width: 64px; + height: 64px; + border-radius: 32px; + display: flex; + align-items: center; + justify-content: center; + font-weight: bold; + } + } + + &__identicon-container, .icon-with-fallback__identicon-container { + height: auto; + position: relative; + display: flex; + justify-content: center; + align-items: center; + height: 64px; + width: 64px; + } + + &__identicon-border, .icon-with-fallback__identicon-border { + height: 64px; + width: 64px; + border-radius: 50%; + border: 1px solid white; + background: #FFFFFF; + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.25); + } + + &__identicon-border { + display: flex; + justify-content: center; + align-items: center; + } + + .icon-with-fallback__identicon-border { + position: absolute; + } +} diff --git a/ui/app/components/app/permission-page-container/permission-page-container-content/permission-page-container-content.component.js b/ui/app/components/app/permission-page-container/permission-page-container-content/permission-page-container-content.component.js index 3836507b2..8360548e9 100644 --- a/ui/app/components/app/permission-page-container/permission-page-container-content/permission-page-container-content.component.js +++ b/ui/app/components/app/permission-page-container/permission-page-container-content/permission-page-container-content.component.js @@ -2,17 +2,17 @@ import PropTypes from 'prop-types' import React, { PureComponent } from 'react' import Identicon from '../../../ui/identicon' import IconWithFallBack from '../../../ui/icon-with-fallback' +import PermissionsConnectHeader from '../../permissions-connect-header' import classnames from 'classnames' export default class PermissionPageContainerContent extends PureComponent { static propTypes = { - requestMetadata: PropTypes.object.isRequired, domainMetadata: PropTypes.object.isRequired, selectedPermissions: PropTypes.object.isRequired, permissionsDescriptions: PropTypes.object.isRequired, onPermissionToggle: PropTypes.func.isRequired, - selectedAccount: PropTypes.object, + selectedIdentities: PropTypes.array, redirect: PropTypes.bool, permissionRejected: PropTypes.bool, } @@ -20,55 +20,38 @@ export default class PermissionPageContainerContent extends PureComponent { static defaultProps = { redirect: null, permissionRejected: null, - selectedAccount: {}, + selectedIdentities: [], } static contextTypes = { t: PropTypes.func, } - renderAccountInfo = (account) => { + renderRedirect () { + const { t } = this.context + const { permissionRejected, selectedIdentities, domainMetadata } = this.props return ( -
-
- { account.label } -
-
- { account.truncatedAddress } -
-
- ) - } - - renderPermissionApprovalVisual = () => { - const { - requestMetadata, domainMetadata, selectedAccount, redirect, permissionRejected, - } = this.props - - return ( -
-
+
+ { permissionRejected ? t('cancelling') : t('connecting') } +
- { redirect ? null :

{domainMetadata.name}

} - { redirect ? null :

{requestMetadata.origin}

} -
- { permissionRejected - ? - : - } - -
-
-
+
+ { permissionRejected + ? + : + } + +
+
+
- { redirect ? null : this.renderAccountInfo(selectedAccount) } -
+
) } @@ -100,8 +83,8 @@ export default class PermissionPageContainerContent extends PureComponent { }} > { selectedPermissions[methodName] - ? - : + ? + : } @@ -117,7 +100,7 @@ export default class PermissionPageContainerContent extends PureComponent { } render () { - const { domainMetadata, redirect, permissionRejected } = this.props + const { domainMetadata, redirect, permissionRejected, selectedIdentities } = this.props const { t } = this.context let titleArgs @@ -127,8 +110,14 @@ export default class PermissionPageContainerContent extends PureComponent { titleArgs = [ 'connectingWithMetaMask' ] } else if (domainMetadata.extensionId) { titleArgs = [ 'externalExtension', [domainMetadata.extensionId] ] + } else if (selectedIdentities.length > 1) { + titleArgs = ['connectToMultiple', [ selectedIdentities.length ] ] } else { - titleArgs = [ 'likeToConnect', [domainMetadata.name] ] + titleArgs = [ + 'connectTo', [ + `${selectedIdentities[0].label} (...${selectedIdentities[0].address.slice(selectedIdentities[0].address.length - 4)})`, + ], + ] } return ( @@ -137,27 +126,24 @@ export default class PermissionPageContainerContent extends PureComponent { 'permission-approval-container__content--redirect': redirect, })} > -
- { t(...titleArgs) } -
- {this.renderPermissionApprovalVisual()} { !redirect ? ( -
-
- { domainMetadata.extensionId +
+ - { this.renderRequestedPermissions() } -
- ) - : ( -
- { t('redirectingBackToDapp') } + /> +
+ { this.renderRequestedPermissions() } +
) + : this.renderRedirect() } ) diff --git a/ui/app/components/app/permission-page-container/permission-page-container.component.js b/ui/app/components/app/permission-page-container/permission-page-container.component.js index 35e111ba2..62ad04940 100644 --- a/ui/app/components/app/permission-page-container/permission-page-container.component.js +++ b/ui/app/components/app/permission-page-container/permission-page-container.component.js @@ -9,7 +9,7 @@ export default class PermissionPageContainer extends Component { static propTypes = { approvePermissionsRequest: PropTypes.func.isRequired, rejectPermissionsRequest: PropTypes.func.isRequired, - selectedIdentity: PropTypes.object, + selectedIdentities: PropTypes.array, permissionsDescriptions: PropTypes.object.isRequired, request: PropTypes.object, redirect: PropTypes.bool, @@ -23,7 +23,7 @@ export default class PermissionPageContainer extends Component { permissionRejected: null, request: {}, requestMetadata: {}, - selectedIdentity: {}, + selectedIdentities: [], } static contextTypes = { @@ -88,7 +88,7 @@ export default class PermissionPageContainer extends Component { onSubmit = () => { const { - request: _request, approvePermissionsRequest, rejectPermissionsRequest, selectedIdentity, + request: _request, approvePermissionsRequest, rejectPermissionsRequest, selectedIdentities, } = this.props const request = { @@ -103,7 +103,7 @@ export default class PermissionPageContainer extends Component { }) if (Object.keys(request.permissions).length > 0) { - approvePermissionsRequest(request, [selectedIdentity.address]) + approvePermissionsRequest(request, selectedIdentities.map((selectedIdentity) => selectedIdentity.address)) } else { rejectPermissionsRequest(request.metadata.id) } @@ -114,7 +114,7 @@ export default class PermissionPageContainer extends Component { requestMetadata, targetDomainMetadata, permissionsDescriptions, - selectedIdentity, + selectedIdentities, redirect, permissionRejected, } = this.props @@ -127,7 +127,7 @@ export default class PermissionPageContainer extends Component { selectedPermissions={this.state.selectedPermissions} permissionsDescriptions={permissionsDescriptions} onPermissionToggle={this.onPermissionToggle} - selectedAccount={selectedIdentity} + selectedIdentities={selectedIdentities} redirect={redirect} permissionRejected={permissionRejected} /> diff --git a/ui/app/components/app/permission-page-container/permission-page-container.container.js b/ui/app/components/app/permission-page-container/permission-page-container.container.js index e8c97cd04..ddad61ebf 100644 --- a/ui/app/components/app/permission-page-container/permission-page-container.container.js +++ b/ui/app/components/app/permission-page-container/permission-page-container.container.js @@ -2,20 +2,15 @@ import { connect } from 'react-redux' import PermissionPageContainer from './permission-page-container.component' import { getPermissionsDescriptions, - getDomainMetadata, + getTargetDomainMetadata, } from '../../../selectors/selectors' const mapStateToProps = (state, ownProps) => { const { request, cachedOrigin } = ownProps - const { metadata: requestMetadata = {} } = request || {} - - const domainMetadata = getDomainMetadata(state) - const origin = requestMetadata.origin || cachedOrigin - const targetDomainMetadata = (domainMetadata[origin] || { name: origin, icon: null }) + const targetDomainMetadata = getTargetDomainMetadata(state, request, cachedOrigin) return { permissionsDescriptions: getPermissionsDescriptions(state), - requestMetadata, targetDomainMetadata, } } diff --git a/ui/app/pages/permissions-connect/permissions-connect-header/index.js b/ui/app/components/app/permissions-connect-header/index.js similarity index 100% rename from ui/app/pages/permissions-connect/permissions-connect-header/index.js rename to ui/app/components/app/permissions-connect-header/index.js diff --git a/ui/app/components/app/permissions-connect-header/index.scss b/ui/app/components/app/permissions-connect-header/index.scss new file mode 100644 index 000000000..c6104aff7 --- /dev/null +++ b/ui/app/components/app/permissions-connect-header/index.scss @@ -0,0 +1,39 @@ +.permissions-connect-header { + display: flex; + flex-direction: column; + justify-content: center; + + &__icon { + display: flex; + flex-direction: column; + align-items: center; + + .icon-with-fallback__identicon-container, + .icon-with-fallback__identicon-border { + height: 64px; + width: 64px; + } + + .icon-with-fallback__identicon-border { + border: 1px solid $Grey-100; + } + + .icon-with-fallback__identicon-container { + margin-bottom: 8px; + } + } + + &__title { + @extend %header--24; + text-align: center; + color: $Black-100; + margin-top: 16px; + } + + &__text { + @extend %content-text; + text-align: center; + margin-top: 4px; + color: $Grey-500; + } +} \ No newline at end of file diff --git a/ui/app/components/app/permissions-connect-header/permissions-connect-header.component.js b/ui/app/components/app/permissions-connect-header/permissions-connect-header.component.js new file mode 100644 index 000000000..9e11e6d52 --- /dev/null +++ b/ui/app/components/app/permissions-connect-header/permissions-connect-header.component.js @@ -0,0 +1,44 @@ +import PropTypes from 'prop-types' +import React, { Component } from 'react' +import IconWithFallBack from '../../ui/icon-with-fallback' + +export default class PermissionsConnectHeader extends Component { + static propTypes = { + icon: PropTypes.string, + iconName: PropTypes.string.isRequired, + headerTitle: PropTypes.node, + headerText: PropTypes.string, + } + + static defaultProps = { + icon: null, + headerTitle: '', + headerText: '', + } + + renderHeaderIcon () { + const { icon, iconName } = this.props + + return ( +
+ +
{iconName }
+
+ ) + } + + render () { + const { headerTitle, headerText } = this.props + return ( +
+ { this.renderHeaderIcon() } +
+ { headerTitle } +
+
+ { headerText } +
+
+ ) + } +} diff --git a/ui/app/components/ui/check-box/check-box.component.js b/ui/app/components/ui/check-box/check-box.component.js new file mode 100644 index 000000000..c7ed09734 --- /dev/null +++ b/ui/app/components/ui/check-box/check-box.component.js @@ -0,0 +1,36 @@ +import React, { PureComponent } from 'react' +import PropTypes from 'prop-types' +import classnames from 'classnames' + +export default class CheckBox extends PureComponent { + static propTypes = { + className: PropTypes.string, + checked: PropTypes.bool, + onClick: PropTypes.func.isRequired, + } + + static defaultProps = { + className: '', + checked: false, + } + + render () { + const { className, checked, onClick } = this.props + + return ( +
onClick() } + className={classnames('check-box', className, { + 'check-box--checked': checked, + 'check-box--un-checked': !checked, + })} + > + { + checked + ? + : null + } +
+ ) + } +} diff --git a/ui/app/components/ui/check-box/index.js b/ui/app/components/ui/check-box/index.js new file mode 100644 index 000000000..aee60a436 --- /dev/null +++ b/ui/app/components/ui/check-box/index.js @@ -0,0 +1 @@ +export { default } from './check-box.component' diff --git a/ui/app/components/ui/check-box/index.scss b/ui/app/components/ui/check-box/index.scss new file mode 100644 index 000000000..90f8b77ad --- /dev/null +++ b/ui/app/components/ui/check-box/index.scss @@ -0,0 +1,26 @@ +.check-box { + cursor: pointer; + + &--checked { + background: $curious-blue; + border: 2px solid $curious-blue; + border-radius: 2px; + width: 18px; + height: 18px; + display: flex; + justify-content: center; + align-items: center; + + i { + color: $white; + } + } + + &--un-checked { + background: $white; + border: 2px solid $Grey-100; + border-radius: 2px; + width: 18px; + height: 18px; + } +} \ No newline at end of file diff --git a/ui/app/css/itcss/settings/variables.scss b/ui/app/css/itcss/settings/variables.scss index 5d0330d38..740d765a5 100644 --- a/ui/app/css/itcss/settings/variables.scss +++ b/ui/app/css/itcss/settings/variables.scss @@ -176,6 +176,8 @@ $Orange-300: #faa66c; $Orange-600: #c65507; $Orange-500: #F66A0A; +$Black-100: #24292E; + // Font Sizes %h3 { font-size: 1.5rem; @@ -265,7 +267,7 @@ $xxlarge-spacing: 64px; %header--24 { @extend %font; - font-size: 18px; + font-size: 24px; } %content-text { diff --git a/ui/app/pages/permissions-connect/choose-account/choose-account.component.js b/ui/app/pages/permissions-connect/choose-account/choose-account.component.js index 72cb419d3..d369ce54f 100644 --- a/ui/app/pages/permissions-connect/choose-account/choose-account.component.js +++ b/ui/app/pages/permissions-connect/choose-account/choose-account.component.js @@ -1,8 +1,13 @@ import PropTypes from 'prop-types' import React, { Component } from 'react' +import classnames from 'classnames' import Identicon from '../../../components/ui/identicon' +import Button from '../../../components/ui/button' +import CheckBox from '../../../components/ui/check-box' +import Tooltip from '../../../components/ui/tooltip-v2' import { PRIMARY } from '../../../helpers/constants/common' import UserPreferencedCurrencyDisplay from '../../../components/app/user-preferenced-currency-display' +import PermissionsConnectHeader from '../../../components/app/permissions-connect-header' export default class ChooseAccount extends Component { static propTypes = { @@ -12,13 +17,18 @@ export default class ChooseAccount extends Component { lastConnectedDate: PropTypes.string, balance: PropTypes.string, })).isRequired, - originName: PropTypes.string.isRequired, - selectAccount: PropTypes.func.isRequired, + selectAccounts: PropTypes.func.isRequired, selectNewAccountViaModal: PropTypes.func.isRequired, nativeCurrency: PropTypes.string.isRequired, addressLastConnectedMap: PropTypes.object, cancelPermissionsRequest: PropTypes.func.isRequired, permissionsRequestId: PropTypes.string.isRequired, + selectedAccountAddresses: PropTypes.object.isRequired, + targetDomainMetadata: PropTypes.object, + } + + state = { + selectedAccounts: this.props.selectedAccountAddresses, } static defaultProps = { @@ -29,8 +39,42 @@ export default class ChooseAccount extends Component { t: PropTypes.func, } + handleAccountClick (address) { + const { selectedAccounts } = this.state + + const newSelectedAccounts = new Set(selectedAccounts) + + if (newSelectedAccounts.has(address)) { + newSelectedAccounts.delete(address) + } else { + newSelectedAccounts.add(address) + } + + this.setState({ selectedAccounts: newSelectedAccounts }) + } + + selectAll () { + const { accounts } = this.props + + const newSelectedAccounts = new Set(accounts.map((account) => account.address)) + + this.setState({ selectedAccounts: newSelectedAccounts }) + } + + deselectAll () { + this.setState({ selectedAccounts: new Set() }) + } + + allAreSelected () { + const { accounts } = this.props + const { selectedAccounts } = this.state + + return accounts.every(({ address }) => selectedAccounts.has(address)) + } + renderAccountsList = () => { - const { accounts, selectAccount, nativeCurrency, addressLastConnectedMap } = this.props + const { accounts, nativeCurrency, addressLastConnectedMap } = this.props + const { selectedAccounts } = this.state return (
{ @@ -39,10 +83,14 @@ export default class ChooseAccount extends Component { return (
selectAccount(address) } + onClick={ () => this.handleAccountClick(address) } className="permissions-connect-choose-account__account" >
+ 1, + })} + > + { accounts.length > 1 + ? ( +
+ (this.allAreSelected() ? this.deselectAll() : this.selectAll())} + /> +
{ this.context.t('selectAll') }
+ + {t('selectingAllWillAllow')} +
+ )} + > + + +
+ ) + : null + } +
selectNewAccountViaModal(this.handleAccountClick.bind(this))} + > + { this.context.t('newAccount') } +
+
+ ) + } + render () { - const { originName, selectNewAccountViaModal, permissionsRequestId, cancelPermissionsRequest } = this.props + const { + selectAccounts, + permissionsRequestId, + cancelPermissionsRequest, + targetDomainMetadata, + accounts, + } = this.props + const { selectedAccounts } = this.state const { t } = this.context return (
-
- { t('chooseAnAcount') } -
-
- { t('toConnectWith', [originName]) } -
+ 0 + ? t('chooseAccountsToUse') + : t('connectAccountOrCreate') + } + /> + { this.renderAccountsListHeader() } { this.renderAccountsList() }
-
cancelPermissionsRequest(permissionsRequestId) } - className="permissions-connect-choose-account__cancel" + type="default" > { t('cancel') } -
-
selectNewAccountViaModal() } - className="permissions-connect-choose-account__new-account" + +
+ { t('next') } +
) diff --git a/ui/app/pages/permissions-connect/choose-account/index.scss b/ui/app/pages/permissions-connect/choose-account/index.scss index 12c124b18..dec8803d7 100644 --- a/ui/app/pages/permissions-connect/choose-account/index.scss +++ b/ui/app/pages/permissions-connect/choose-account/index.scss @@ -1,34 +1,93 @@ .permissions-connect-choose-account { display: flex; flex-direction: column; - margin-top: 40px; - width: 100%; align-items: center; + margin-top: 40px; + width: 428px; + margin-left: auto; + margin-right: auto; &__title { @extend %header--18; } - &__text { + &__text, &__text--blue, &__text--grey { @extend %content-text; line-height: 25px; } + &__text-blue { + color: $curious-blue; + cursor: pointer; + } + + &__text-grey { + color: $Grey-500; + } + &__accounts-list { - width: 393px; + width: 100%; border: 1px solid #D0D5DA; box-sizing: border-box; border-radius: 8px; - margin-top: 36px; + margin-top: 8px; + max-height: 338px; + overflow-y: auto; @media screen and (max-width: 575px) { width: 100%; } } + &__accounts-list-header--one-item, + &__accounts-list-header--two-items { + display: flex; + margin-top: 36px; + width: 100%; + padding-right: 2px; + } + + &__accounts-list-header--one-item { + justify-content: flex-end; + } + + &__accounts-list-header--two-items { + justify-content: space-between; + } + &__account-info-wrapper { display: flex; justify-content: flex-start; + align-items: center; + } + + &__list-check-box { + margin-right: 24px; + } + + &__header-check-box { + margin-right: 16px; + } + + &__select-all { + display: flex; + margin-left: 16px; + align-items: center; + + .fa-info-circle, .fa-info-circle:hover { + color: $silver; + cursor: pointer; + margin-left: 8px; + font-size: 0.9rem; + } + + .fa-info-circle { + cursor: pointer; + } + + .fa-info-circle:hover { + color: $mid-gray; + } } &__account { @@ -76,22 +135,23 @@ } } - &__new-account, &__cancel { - @extend %content-text; - line-height: 20px; - color: #037DD6; - margin-top: 24px; - cursor: pointer; - } - &__cancel { color: $Red-400; } &__bottom-buttons { display: flex; - justify-content: space-around; - width: 393px; + justify-content: space-between; + width: 100%; + margin-top: 16px; + + button { + width: 124px; + } + + .btn-default { + background: white; + } } } \ No newline at end of file diff --git a/ui/app/pages/permissions-connect/index.scss b/ui/app/pages/permissions-connect/index.scss index fe2f5182a..a577ea8c3 100644 --- a/ui/app/pages/permissions-connect/index.scss +++ b/ui/app/pages/permissions-connect/index.scss @@ -1,5 +1,3 @@ -@import 'permissions-connect-header/index'; - @import 'permissions-connect-footer/index'; @import 'choose-account/index'; @@ -8,4 +6,20 @@ width: 100%; position: relative; background: white; + + &__page-count-wrapper { + margin-top: 26px; + margin-left: 20px; + display: flex; + justify-content: flex-end; + align-items: flex-end; + + &__page-count { + @extend %content-text; + margin-right: 30px; + font-size: 12px; + line-height: 17px; + color: #6A737D; + } + } } diff --git a/ui/app/pages/permissions-connect/permissions-connect-footer/permissions-connect-footer.component.js b/ui/app/pages/permissions-connect/permissions-connect-footer/permissions-connect-footer.component.js index b8fad97a3..825e77f5d 100644 --- a/ui/app/pages/permissions-connect/permissions-connect-footer/permissions-connect-footer.component.js +++ b/ui/app/pages/permissions-connect/permissions-connect-footer/permissions-connect-footer.component.js @@ -10,7 +10,6 @@ export default class PermissionsConnectFooter extends Component { const { t } = this.context return (
-
{ t('onlyConnectTrust') }
{ global.platform.openWindow({ url: 'https://medium.com/metamask/privacy-mode-is-now-enabled-by-default-1c1c957f4d57' }) }} - >{ t('learnAboutRisks') } + >{ t('learnMore') }
diff --git a/ui/app/pages/permissions-connect/permissions-connect-header/index.scss b/ui/app/pages/permissions-connect/permissions-connect-header/index.scss deleted file mode 100644 index ca239bf17..000000000 --- a/ui/app/pages/permissions-connect/permissions-connect-header/index.scss +++ /dev/null @@ -1,15 +0,0 @@ -.permissions-connect-header { - margin-top: 26px; - margin-left: 20px; - display: flex; - justify-content: space-between; - align-items: flex-end; - - &__page-count { - @extend %content-text; - margin-right: 30px; - font-size: 12px; - line-height: 17px; - color: #6A737D; - } -} \ No newline at end of file diff --git a/ui/app/pages/permissions-connect/permissions-connect-header/permissions-connect-header.component.js b/ui/app/pages/permissions-connect/permissions-connect-header/permissions-connect-header.component.js deleted file mode 100644 index 68499b9ae..000000000 --- a/ui/app/pages/permissions-connect/permissions-connect-header/permissions-connect-header.component.js +++ /dev/null @@ -1,23 +0,0 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import MetaFoxLogo from '../../../components/ui/metafox-logo' - -export default class PermissionsConnectHeader extends Component { - static propTypes = { - page: PropTypes.number.isRequired, - } - - render () { - const { page } = this.props - return ( -
- -
- { `${page}/2` } -
-
- ) - } -} diff --git a/ui/app/pages/permissions-connect/permissions-connect.component.js b/ui/app/pages/permissions-connect/permissions-connect.component.js index 3630f1e7b..daed76c51 100644 --- a/ui/app/pages/permissions-connect/permissions-connect.component.js +++ b/ui/app/pages/permissions-connect/permissions-connect.component.js @@ -1,7 +1,6 @@ import PropTypes from 'prop-types' import React, { Component } from 'react' import { Switch, Route } from 'react-router-dom' -import PermissionsConnectHeader from './permissions-connect-header' import PermissionsConnectFooter from './permissions-connect-footer' import ChooseAccount from './choose-account' import { getEnvironmentType } from '../../../../app/scripts/lib/util' @@ -37,6 +36,7 @@ export default class PermissionConnect extends Component { confirmPermissionPath: PropTypes.string.isRequired, page: PropTypes.string.isRequired, redirecting: PropTypes.bool, + targetDomainMetadata: PropTypes.object, } static defaultProps = { @@ -56,7 +56,7 @@ export default class PermissionConnect extends Component { state = { redirecting: false, - selectedAccountAddress: '', + selectedAccountAddresses: new Set(), permissionAccepted: null, originName: this.props.originName, } @@ -94,9 +94,9 @@ export default class PermissionConnect extends Component { } } - selectAccount = (address) => { + selectAccounts = (addresses) => { this.setState({ - selectedAccountAddress: address, + selectedAccountAddresses: addresses, }, () => this.props.history.push(this.props.confirmPermissionPath)) } @@ -161,13 +161,25 @@ export default class PermissionConnect extends Component { connectPath, confirmPermissionPath, page, + targetDomainMetadata, } = this.props - const { selectedAccountAddress, permissionAccepted, originName, redirecting } = this.state + const { + selectedAccountAddresses, + permissionAccepted, + originName, + redirecting, + } = this.state return (
{ !redirecting - ? + ? ( +
+
+ { `${page}/2` } +
+
+ ) : null } @@ -175,26 +187,31 @@ export default class PermissionConnect extends Component { path={connectPath} exact render={() => ( - this.selectAccount(address)} - selectNewAccountViaModal={() => { - showNewAccountModal({ - onCreateNewAccount: this.selectAccount, - newAccountNumber, - }) - }} - addressLastConnectedMap={addressLastConnectedMap} - cancelPermissionsRequest={(requestId) => { - if (requestId) { - rejectPermissionsRequest(requestId) - this.redirectFlow(false) - } - }} - permissionsRequestId={permissionsRequestId} - /> +
+ this.selectAccounts(addresses)} + selectNewAccountViaModal={(handleAccountClick) => { + showNewAccountModal({ + onCreateNewAccount: (address) => handleAccountClick(address), + newAccountNumber, + }) + }} + addressLastConnectedMap={addressLastConnectedMap} + cancelPermissionsRequest={(requestId) => { + if (requestId) { + rejectPermissionsRequest(requestId) + this.redirectFlow(false) + } + }} + permissionsRequestId={permissionsRequestId} + selectedAccountAddresses={selectedAccountAddresses} + targetDomainMetadata={targetDomainMetadata} + /> + { !redirecting ? : null } +
)} /> account.address === selectedAccountAddress)} + selectedIdentities={accounts.filter((account) => selectedAccountAddresses.has(account.address))} redirect={redirecting} permissionRejected={ permissionAccepted === false } + cachedOrigin={originName} /> - + { !redirecting ? : null }
)} /> diff --git a/ui/app/pages/permissions-connect/permissions-connect.container.js b/ui/app/pages/permissions-connect/permissions-connect.container.js index 3a56a3f45..a58958731 100644 --- a/ui/app/pages/permissions-connect/permissions-connect.container.js +++ b/ui/app/pages/permissions-connect/permissions-connect.container.js @@ -7,6 +7,7 @@ import { getAccountsWithLabels, getLastConnectedInfo, getPermissionsDomains, + getTargetDomainMetadata, } from '../../selectors/selectors' import { formatDate } from '../../helpers/utils/util' import { approvePermissionsRequest, rejectPermissionsRequest, showModal, getCurrentWindowTab, getRequestAccountTabIds } from '../../store/actions' @@ -52,6 +53,8 @@ const mapStateToProps = (state, ownProps) => { throw new Error('Incorrect path for permissions-connect component') } + const targetDomainMetadata = getTargetDomainMetadata(state, permissionsRequest, origin) + return { permissionsRequest, permissionsRequestId, @@ -65,6 +68,7 @@ const mapStateToProps = (state, ownProps) => { connectPath, confirmPermissionPath, page, + targetDomainMetadata, } } diff --git a/ui/app/selectors/selectors.js b/ui/app/selectors/selectors.js index aca01076a..e7ae9bb8d 100644 --- a/ui/app/selectors/selectors.js +++ b/ui/app/selectors/selectors.js @@ -376,6 +376,17 @@ export function getDomainMetadata (state) { return state.metamask.domainMetadata } +export function getTargetDomainMetadata (state, request, defaultOrigin) { + const domainMetadata = getDomainMetadata(state) + + const { metadata: requestMetadata = {} } = request || {} + const origin = requestMetadata.origin || defaultOrigin + const targetDomainMetadata = (domainMetadata[origin] || { name: origin, icon: null }) + targetDomainMetadata.origin = origin + + return targetDomainMetadata +} + export function getActiveTab (state) { return state.activeTab }