diff --git a/common/assets/images/ledger-nano-illustration.svg b/common/assets/images/ledger-nano-illustration.svg new file mode 100755 index 00000000..eb5e1a64 --- /dev/null +++ b/common/assets/images/ledger-nano-illustration.svg @@ -0,0 +1,16 @@ + + + + icn-ledger-nano + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/common/assets/images/trezor-illustration.svg b/common/assets/images/trezor-illustration.svg new file mode 100755 index 00000000..6e2ec47e --- /dev/null +++ b/common/assets/images/trezor-illustration.svg @@ -0,0 +1,22 @@ + + + + icn-trezor-new + Created with Sketch. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/common/components/Header/components/Navigation.tsx b/common/components/Header/components/Navigation.tsx index aa45b728..4cfe43f2 100644 --- a/common/components/Header/components/Navigation.tsx +++ b/common/components/Header/components/Navigation.tsx @@ -1,6 +1,6 @@ import React, { PureComponent } from 'react'; import NavigationLink from 'components/NavigationLink'; -import { navigationLinks, knowledgeBaseURL } from 'config'; +import { navigationLinks } from 'config'; import './Navigation.scss'; interface Props { diff --git a/common/components/Header/index.tsx b/common/components/Header/index.tsx index 9f01ceff..8b021849 100644 --- a/common/components/Header/index.tsx +++ b/common/components/Header/index.tsx @@ -19,7 +19,6 @@ import { Link } from 'react-router-dom'; import { TSetGasPriceField, setGasPriceField } from 'actions/transaction'; import { ANNOUNCEMENT_MESSAGE, ANNOUNCEMENT_TYPE, languages } from 'config'; import Navigation from './components/Navigation'; -import { knowledgeBaseURL } from 'config/data'; import NetworkDropdown from './components/NetworkDropdown'; import CustomNodeModal from 'components/CustomNodeModal'; import { getKeyByValue } from 'utils/helpers'; @@ -34,7 +33,6 @@ import { import { NetworkConfig } from 'types/network'; import { connect, MapStateToProps } from 'react-redux'; import './index.scss'; -import translate from 'translations'; interface OwnProps { networkParam: string | null; diff --git a/common/components/PrimaryButton/PrimaryButton.scss b/common/components/PrimaryButton/PrimaryButton.scss new file mode 100644 index 00000000..acbf65c5 --- /dev/null +++ b/common/components/PrimaryButton/PrimaryButton.scss @@ -0,0 +1,53 @@ +@import 'common/sass/variables'; +@import 'common/sass/mixins'; + +.PrimaryButton { + @include reset-button; + display: block; + color: white; + font-size: 1rem; + font-weight: 400; + background-color: $brand-primary; + padding: 0.75rem 1rem; + border-radius: 3px; + box-shadow: 0 1px 3px rgba(#32325d, 0.1), 0 1px 1px rgba(#32325d, 0.05), + 0 0 1px rgba(#32325d, 0.03); + transition: box-shadow 150ms ease, transform 150ms ease, background-color 150ms ease; + + &[disabled] { + cursor: not-allowed; + opacity: 0.5; + } + + &.loading { + transform: translateY(-1px); + background-color: darken($brand-primary, 7%); + box-shadow: 0 1px 3px rgba(#32325d, 0.1), 0 1px 1px rgba(#32325d, 0.05), + 0 0 1px rgba(#32325d, 0.03); + } + + &:not([disabled]):not(.loading) { + &:hover, + &:focus { + transform: translateY(-2px); + z-index: 2; + box-shadow: 0 7px 14px rgba(232, 234, 237, 0.5), 0 3px 6px rgba(232, 234, 237, 0.5); + } + &:active { + transform: translateY(-1px); + background-color: darken($brand-primary, 3.5%); + box-shadow: 0 1px 3px rgba(#32325d, 0.1), 0 1px 1px rgba(#32325d, 0.05), + 0 0 1px rgba(#32325d, 0.03); + } + } + + &-spinner-wrapper { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + align-items: center; + > .Spinner { + margin-right: 1rem; + } + } +} diff --git a/common/components/PrimaryButton/index.tsx b/common/components/PrimaryButton/index.tsx new file mode 100644 index 00000000..b335e7f7 --- /dev/null +++ b/common/components/PrimaryButton/index.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { Spinner } from 'components/ui'; +import './PrimaryButton.scss'; + +interface Props { + className?: string; + disabled?: boolean; + text?: string; + loading?: boolean; + loadingTxt?: string; + onClick(): void; +} + +export default class PrimaryButton extends React.Component { + public render() { + const { text, disabled, className, loading, loadingTxt, onClick } = this.props; + return ( + + ); + } +} diff --git a/common/components/SecondaryButton/SecondaryButton.scss b/common/components/SecondaryButton/SecondaryButton.scss new file mode 100644 index 00000000..e8e036cf --- /dev/null +++ b/common/components/SecondaryButton/SecondaryButton.scss @@ -0,0 +1,32 @@ +@import 'common/sass/variables'; +@import 'common/sass/mixins'; + +.SecondaryButton { + @include reset-button; + display: block; + color: #333; + font-size: 1rem; + font-weight: 400; + background-color: white; + padding: 0.75rem 1rem; + border-radius: 3px; + box-shadow: 0 1px 3px rgba(#32325d, 0.1), 0 1px 1px rgba(#32325d, 0.05), + 0 0 1px rgba(#32325d, 0.03); + transition: box-shadow 150ms ease, transform 150ms ease, background-color 150ms ease; + + &:not(.is-disabled) { + &:hover, + &:focus { + transform: translateY(-2px); + z-index: 2; + box-shadow: 0 7px 14px rgba(232, 234, 237, 0.5), 0 3px 6px rgba(232, 234, 237, 0.5); + } + } + + &:active { + transform: translateY(-1px); + background-color: darken(white, 3.5%); + box-shadow: 0 1px 3px rgba(#32325d, 0.1), 0 1px 1px rgba(#32325d, 0.05), + 0 0 1px rgba(#32325d, 0.03); + } +} diff --git a/common/components/SecondaryButton/index.tsx b/common/components/SecondaryButton/index.tsx new file mode 100644 index 00000000..1eba2e2c --- /dev/null +++ b/common/components/SecondaryButton/index.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { Spinner } from 'components/ui'; +import './SecondaryButton.scss'; + +interface Props { + className?: string; + disabled?: boolean; + text?: string; + loading?: boolean; + onClick(): void; +} + +export default class SecondaryButton extends React.Component { + public render() { + const { text, disabled, className, loading, onClick } = this.props; + return ( + + ); + } +} diff --git a/common/components/WalletDecrypt/WalletDecrypt.scss b/common/components/WalletDecrypt/WalletDecrypt.scss index 0d1809ab..c6388d25 100644 --- a/common/components/WalletDecrypt/WalletDecrypt.scss +++ b/common/components/WalletDecrypt/WalletDecrypt.scss @@ -14,20 +14,30 @@ $speed: 500ms; } } -@mixin decrypt-title { - text-align: center; - line-height: 1; - margin: 0 0 3rem; - font-weight: normal; - animation: decrypt-enter $speed ease 1; -} - .WalletDecrypt { position: relative; + &-header { + margin-bottom: 1.5rem; + } + &-wallets { &-title { - @include decrypt-title; + text-align: center; + font-size: 24px; + line-height: 1; + margin: 0; + font-weight: normal; + animation: decrypt-enter $speed ease 1; + } + &-desc { + text-align: center; + font-size: 16px; + line-height: 1; + margin: 0; + margin-top: 0.5rem; + font-weight: 400; + animation: decrypt-enter $speed ease 1; } &-row { @@ -54,11 +64,23 @@ $speed: 500ms; &-decrypt { position: relative; - text-align: center; - padding-bottom: $space; - @media (max-width: $screen-md) { - padding-bottom: $space * 2; + &-title { + text-align: center; + font-size: 24px; + line-height: 1; + margin: 0; + font-weight: normal; + animation: decrypt-enter $speed ease 1; + } + &-desc { + text-align: center; + font-size: 16px; + line-height: 1; + margin: 0; + margin-top: 0.5rem; + font-weight: 400; + animation: decrypt-enter $speed ease 1; } &-back { @@ -93,13 +115,9 @@ $speed: 500ms; } } - &-title { - @include decrypt-title; - } - &-form { - max-width: 360px; margin: 0 auto; + width: 516px; } &-label { opacity: 0.8; diff --git a/common/components/WalletDecrypt/WalletDecrypt.tsx b/common/components/WalletDecrypt/WalletDecrypt.tsx index 041731b0..338383d6 100644 --- a/common/components/WalletDecrypt/WalletDecrypt.tsx +++ b/common/components/WalletDecrypt/WalletDecrypt.tsx @@ -51,6 +51,7 @@ import { wikiLink as paritySignerHelpLink } from 'libs/wallet/non-deterministic/ import './WalletDecrypt.scss'; import { withRouter, RouteComponentProps } from 'react-router'; import { Errorable } from 'components'; +import { getNetworkConfig } from 'selectors/config'; interface OwnProps { hidden?: boolean; @@ -72,6 +73,7 @@ interface StateProps { computedDisabledWallets: DisabledWallets; isWalletPending: AppState['wallet']['isWalletPending']; isPasswordPending: AppState['wallet']['isPasswordPending']; + networkName: string; } type Props = OwnProps & StateProps & DispatchProps & RouteComponentProps<{}>; @@ -248,22 +250,28 @@ const WalletDecrypt = withRouter( return (
- -

- {!selectedWallet.isReadOnly && 'Unlock your'} {translate(selectedWallet.lid)} -

+
+

+ {translate('UNLOCK_DEVICE', { $device: translateRaw(selectedWallet.lid) })} +

+ {this.props.showGenerateLink && ( +

+ {translate('UNLOCK_DEVICE_NEXT_STEP', { $network: this.props.networkName })}{' '} +

+ )} +
+
{ if (selectedWallet.redirect) { @@ -299,7 +307,17 @@ const WalletDecrypt = withRouter( return (
-

{translate('DECRYPT_ACCESS')}

+
+

{translate('DECRYPT_ACCESS')}

+ {this.props.showGenerateLink && ( +

+ {translate('DONT_HAVE_WALLET_PROMPT')}{' '} + + {translate('Create One.')} + +

+ )} +
{SECURE_WALLETS.map((walletType: SecureWalletName) => { @@ -355,12 +373,6 @@ const WalletDecrypt = withRouter( ); })}
- - {this.props.showGenerateLink && ( -
- {translate('DONT_HAVE_WALLET_PROMPT')} -
- )}
); } @@ -437,8 +449,8 @@ const WalletDecrypt = withRouter( return; } - // some components (TrezorDecrypt) don't take an onChange prop, and thus - // this.state.value will remain unpopulated. in this case, we can expect + // some components (TrezorDecrypt) don't take an onChange prop, so + // this.state.value will remain unpopulated. In this case, we can expect // the payload to contain the unlocked wallet info. const unlockValue = value && !isEmpty(value) ? value : payload; this.WALLETS[selectedWalletKey].unlock(unlockValue); @@ -468,7 +480,8 @@ function mapStateToProps(state: AppState, ownProps: Props) { return { computedDisabledWallets, isWalletPending: state.wallet.isWalletPending, - isPasswordPending: state.wallet.isPasswordPending + isPasswordPending: state.wallet.isPasswordPending, + networkName: getNetworkConfig(state).name }; } diff --git a/common/components/WalletDecrypt/components/LedgerNano.scss b/common/components/WalletDecrypt/components/LedgerNano.scss index c18b2623..60e86d13 100644 --- a/common/components/WalletDecrypt/components/LedgerNano.scss +++ b/common/components/WalletDecrypt/components/LedgerNano.scss @@ -9,6 +9,8 @@ &-error { opacity: 0; transition: none; + border-radius: 3px; + margin-bottom: 2.5rem; &.is-showing { opacity: 1; @@ -28,4 +30,38 @@ margin-right: 16px; } } + + &-illustration { + margin-bottom: 2rem; + width: 128px; + } + + &-tip { + &-wrapper { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + margin: auto; + margin-bottom: 3rem; + max-width: 360px; + > p { + font-size: 1rem; + font-weight: 400; + color: #a8adb3; + text-align: left; + &:first-child { + color: #333; + margin-right: 0.5rem; + } + } + } + } + + &-btn { + &-wrapper { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + } + } } diff --git a/common/components/WalletDecrypt/components/LedgerNano.tsx b/common/components/WalletDecrypt/components/LedgerNano.tsx index bc46bb63..70028fb5 100644 --- a/common/components/WalletDecrypt/components/LedgerNano.tsx +++ b/common/components/WalletDecrypt/components/LedgerNano.tsx @@ -1,20 +1,23 @@ import React, { PureComponent } from 'react'; import ledger from 'ledgerco'; -import translate, { translateRaw } from 'translations'; +import { translateRaw } from 'translations'; import DeterministicWalletsModal from './DeterministicWalletsModal'; import UnsupportedNetwork from './UnsupportedNetwork'; import { LedgerWallet } from 'libs/wallet'; -import { Spinner, NewTabLink } from 'components/ui'; +import { NewTabLink } from 'components/ui'; +import { PrimaryButton, SecondaryButton } from 'components'; import { connect } from 'react-redux'; import { AppState } from 'reducers'; -import { SecureWalletName, ledgerReferralURL } from 'config'; +import { SecureWalletName } from 'config'; import { getPaths, getSingleDPath } from 'selectors/config/wallet'; import { getNetworkConfig } from 'selectors/config'; import { NetworkConfig } from 'types/network'; +import img from 'assets/images/ledger-nano-illustration.svg'; import './LedgerNano.scss'; interface OwnProps { onUnlock(param: any): void; + clearWalletChoice(): void; } interface StateProps { @@ -57,8 +60,7 @@ class LedgerNanoSDecryptClass extends PureComponent { } public render() { - const { network } = this.props; - const { dPath, publicKey, chainCode, error, isLoading, showTip } = this.state; + const { dPath, publicKey, chainCode, error, isLoading } = this.state; const showErr = error ? 'is-showing' : ''; if (!dPath) { @@ -78,37 +80,29 @@ class LedgerNanoSDecryptClass extends PureComponent { return (
- - - - {translate('LEDGER_REFERRAL_2')} - - -
{error || '-'}
- - {showTip && ( -

{translate('LEDGER_TIP', { $network: network.unit })}

+ {error && ( +
{error}
)} - -
- - {translate('HELP_ARTICLE_1')} - + Ledger nano illustration +
+

Tip:

+

Make sure you’ve enabled browser support in settings on your device.

+
+
+ +
+
- { public render() { - const { - name, - description, - example, - icon, - helpLink, - isSecure, - isReadOnly, - isDisabled, - disableReason - } = this.props; + const { name, icon, helpLink, isSecure, isReadOnly, isDisabled, disableReason } = this.props; const icons: Icon[] = []; if (isReadOnly) { @@ -90,32 +80,26 @@ export class WalletButton extends React.PureComponent { aria-disabled={isDisabled} >
+ {icon && {name}
- {icon && {name} {name}
- {description && ( + {/* {description && (
{description}
- )} - {example && ( + )} */} + {/* {example && (
{example}
- )} + )} */}
{icons.map(i => ( - {i.href ? ( - - - - ) : ( - - )} + {!i.href && } {!isDisabled && {i.tooltip}} ))} diff --git a/common/components/index.ts b/common/components/index.ts index bd5a0c95..ec277e37 100644 --- a/common/components/index.ts +++ b/common/components/index.ts @@ -25,3 +25,5 @@ export { default as ElectronNav } from './ElectronNav'; export { default as AddressBookTable } from './AddressBookTable'; export { default as Errorable } from './Errorable'; export { default as AppAlphaNotice } from './AppAlphaNotice'; +export { default as PrimaryButton } from './PrimaryButton'; +export { default as SecondaryButton } from './SecondaryButton'; diff --git a/common/config/data.tsx b/common/config/data.tsx index e2c50933..5df06647 100644 --- a/common/config/data.tsx +++ b/common/config/data.tsx @@ -1,9 +1,8 @@ -import React from 'react'; // For ANNOUNCEMENT_MESSAGE jsx +// import React from 'react'; // For ANNOUNCEMENT_MESSAGE jsx import { getValues } from '../utils/helpers'; import packageJson from '../../package.json'; import { GasPriceSetting } from 'types/network'; import { makeExplorer } from 'utils/helpers'; -import NewTabLink from 'components/ui/NewTabLink'; export const languages = require('./languages.json'); export const discordURL = 'https://discord.gg/VSaTXEA'; diff --git a/common/containers/Tabs/SendTransaction/index.tsx b/common/containers/Tabs/SendTransaction/index.tsx index f05fc178..e76fb531 100644 --- a/common/containers/Tabs/SendTransaction/index.tsx +++ b/common/containers/Tabs/SendTransaction/index.tsx @@ -43,7 +43,7 @@ class SendTransaction extends React.Component { public render() { const { wallet, match, location, history, network } = this.props; const currentPath = match.url; - const EthTabs: Tab[] = [ + const Tabs: Tab[] = [ { path: 'send', name: translate('NAV_SENDETHER'), @@ -67,21 +67,6 @@ class SendTransaction extends React.Component { name: translate('NAV_ADDRESS_BOOK') } ]; - const XmrTabs: Tab[] = [ - { - path: 'send', - name: translate('NAV_SEND'), - disabled: !!wallet && !!wallet.isReadOnly - }, - { - path: 'receive', - name: translate('NAV_REQUESTPAYMENT') - }, - { - path: 'swap', - name: translate('NAV_SWAP') - } - ]; return ( @@ -90,12 +75,7 @@ class SendTransaction extends React.Component { {wallet && (
- +
diff --git a/common/sass/variables/colors.scss b/common/sass/variables/colors.scss index 1e128e02..a6b86f99 100644 --- a/common/sass/variables/colors.scss +++ b/common/sass/variables/colors.scss @@ -1,4 +1,5 @@ $ether-navy: #163151; +$other-blue: #1eb8e7; $ether-blue: #0e97c0; $gray-base: #000; @@ -12,7 +13,7 @@ $gray-lightest: #fafafa; $border-idle: #e5ecf3; $border-disabled: #e6e6e6; -$brand-primary: #007896; +$brand-primary: #1097c0; $brand-success: #5dba5a; $brand-info: $ether-navy; $brand-warning: #ff9800; diff --git a/common/translations/lang/en.json b/common/translations/lang/en.json index 8d545e7d..3de4a253 100644 --- a/common/translations/lang/en.json +++ b/common/translations/lang/en.json @@ -69,7 +69,7 @@ "SIDEBAR_DONATE": "Donate ", "SIDEBAR_THANKS": "THANK YOU!!! ", "SIDEBAR_DISPLAY_ADDR": "Display address on $wallet", - "DECRYPT_ACCESS": "How would you like to access your wallet? ", + "DECRYPT_ACCESS": "Select a Method to Unlock Your Wallet", "X_LEDGER": "Ledger ", "ADD_LEDGER_SCAN": "Connect to Ledger Wallet ", "ADD_METAMASK": "Connect to MetaMask ", @@ -613,6 +613,10 @@ "PAYMENT_ID_TITLE": "Payment ID", "PAYMENT_ID_PLACEHOLDER": "Enter a Payment ID", "PRIVACY_RADIO": "Privacy", - "PRIORITY_RADIO": "Priority" + "PRIORITY_RADIO": "Priority", + "UNLOCK_DEVICE":"Unlock Your $device", + "ERROR_DEVICE_NOT_SUPPORTED": "$device is not supported by your browser", + "CONNECT_TO_DEVICE": "Connect to $device", + "UNLOCK_DEVICE_NEXT_STEP": "After, open the $network App on your device." } } diff --git a/tsconfig.json b/tsconfig.json index 11fd0130..f6cfe9d3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,9 +27,9 @@ "./common/", "./electron-app/", "./shared/", - "spec", - "./node_modules/types-rlp/index.d.ts", - "./node_modules/mycrypto-shepherd/dist/lib/types/btoa.d.ts" + "spec" + // "./node_modules/types-rlp/index.d.ts", + // "./node_modules/mycrypto-shepherd/dist/lib/types/btoa.d.ts" ], "awesomeTypescriptLoaderOptions": { "transpileOnly": true