From b49148ec54886b11042e42eed9ad4e8793840775 Mon Sep 17 00:00:00 2001 From: fragosti Date: Thu, 24 May 2018 10:11:56 -0700 Subject: Implement metamask installation flow --- .../ts/components/onboarding/onboarding_flow.tsx | 7 +++ .../onboarding/portal_onboarding_flow.tsx | 60 ++++++++++++++++++---- .../ts/components/top_bar/provider_display.tsx | 9 ++-- .../components/wallet/wallet_disconnected_item.tsx | 4 +- 4 files changed, 62 insertions(+), 18 deletions(-) (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx index 621d14260..22fc71481 100644 --- a/packages/website/ts/components/onboarding/onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx @@ -17,9 +17,16 @@ const joyrideStyleOptions: StyleOptions = { // Wrapper around Joyride with defaults and styles set export class OnboardingFlow extends React.Component { + private _joyrideRef: React.RefObject; + constructor(props: OnboardingFlowProps) { + super(props); + this._joyrideRef = React.createRef(); + } + public render(): React.ReactNode { return ( void; + userAddress: string; + providerType: ProviderType; + injectedProviderName: string; + blockchainIsLoaded: boolean; + setOnboardingStep: (stepIndex: number) => void; } -const steps: Step[] = [ - { - target: '.wallet', - content: 'You are onboarding right now!', - placement: 'right', - disableBeacon: true, - }, -]; - export class PortalOnboardingFlow extends React.Component { public render(): React.ReactNode { return ( ); } + + private _isAddressAvailable(): boolean { + return !_.isEmpty(this.props.userAddress); + } + + private _getSteps(): Step[] { + const allSteps: Step[] = [ + { + target: '.wallet', + content: + 'Before you begin, you need to connect to a wallet. This will be used across all 0x relayers and dApps', + placement: 'right', + disableBeacon: true, + }, + { + target: '.wallet', + content: 'Unlock your metamask extension to begin', + placement: 'right', + disableBeacon: true, + }, + { + target: '.wallet', + content: + 'In order to start trading on any 0x relayer in the 0x ecosystem, you need to complete two simple steps', + placement: 'right', + disableBeacon: true, + }, + ]; + const [noMetamaskStep, lockedMetamaskStep, ...restOfSteps] = allSteps; + if (this._isAddressAvailable()) { + return restOfSteps; + } + const isExternallyInjected = utils.isExternallyInjected( + this.props.providerType, + this.props.injectedProviderName, + ); + if (isExternallyInjected) { + return [lockedMetamaskStep, ...restOfSteps]; + } + return allSteps; + } } diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index fc516882a..4dc37f231 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -39,8 +39,7 @@ const styles: Styles = { export class ProviderDisplay extends React.Component { public render(): React.ReactNode { const isAddressAvailable = !_.isEmpty(this.props.userAddress); - const isExternallyInjectedProvider = - this.props.providerType === ProviderType.Injected && this.props.injectedProviderName !== '0x Public'; + const isExternallyInjectedProvider = utils.isExternallyInjected(this.props.providerType, this.props.injectedProviderName); const displayAddress = isAddressAvailable ? utils.getAddressBeginAndEnd(this.props.userAddress) : isExternallyInjectedProvider @@ -69,15 +68,13 @@ export class ProviderDisplay extends React.Component ); - const hasInjectedProvider = - this.props.injectedProviderName !== '0x Public' && this.props.providerType === ProviderType.Injected; const hasLedgerProvider = this.props.providerType === ProviderType.Ledger; - const horizontalPosition = hasInjectedProvider || hasLedgerProvider ? 'left' : 'middle'; + const horizontalPosition = isExternallyInjectedProvider || hasLedgerProvider ? 'left' : 'middle'; return (
= ( props: WalletDisconnectedItemProps, ) => { - const isExternallyInjectedProvider = - props.providerType === ProviderType.Injected && props.injectedProviderName !== '0x Public'; + const isExternallyInjectedProvider = utils.isExternallyInjected(props.providerType, props.injectedProviderName); return (
-- cgit v1.2.3 From f0af6388748bdf08ae81e079e497dc879703c97d Mon Sep 17 00:00:00 2001 From: fragosti Date: Thu, 24 May 2018 11:44:20 -0700 Subject: Fix PortalOnboardingFlowProps --- packages/website/ts/components/onboarding/portal_onboarding_flow.tsx | 1 - 1 file changed, 1 deletion(-) (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx index 7abfdabda..feaa9c997 100644 --- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx @@ -14,7 +14,6 @@ export interface PortalOnboardingFlowProps { providerType: ProviderType; injectedProviderName: string; blockchainIsLoaded: boolean; - setOnboardingStep: (stepIndex: number) => void; } export class PortalOnboardingFlow extends React.Component { -- cgit v1.2.3 From 809ac3340cb477d4b46e24d4bad028568beeec06 Mon Sep 17 00:00:00 2001 From: fragosti Date: Thu, 24 May 2018 17:10:39 -0700 Subject: Add ability to blacklist onboarding steps --- .../ts/components/onboarding/onboarding_flow.tsx | 56 +++++++++++++++++-- .../onboarding/portal_onboarding_flow.tsx | 63 ++++++++++++---------- 2 files changed, 85 insertions(+), 34 deletions(-) (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx index 22fc71481..0cb640f8f 100644 --- a/packages/website/ts/components/onboarding/onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx @@ -6,9 +6,11 @@ import { zIndex } from 'ts/utils/style'; export interface OnboardingFlowProps { steps: Step[]; + blacklistedStepIndices: number[]; stepIndex: number; isRunning: boolean; onClose: () => void; + setOnboardingStep: (stepIndex: number) => void; } const joyrideStyleOptions: StyleOptions = { @@ -17,16 +19,17 @@ const joyrideStyleOptions: StyleOptions = { // Wrapper around Joyride with defaults and styles set export class OnboardingFlow extends React.Component { - private _joyrideRef: React.RefObject; - constructor(props: OnboardingFlowProps) { - super(props); - this._joyrideRef = React.createRef(); + public componentDidMount(): void { + this._setOnboardingStepBasedOnBlacklist(this.props.stepIndex); + } + + public componentWillReceiveProps(nextProps: OnboardingFlowProps): void { + this._setOnboardingStepBasedOnBlacklist(nextProps.stepIndex); } public render(): React.ReactNode { return ( { ); } + private _setOnboardingStepBasedOnBlacklist(nextIndex: number): void { + const blacklistedSteps = this.props.blacklistedStepIndices; + const newStepIndex = this._adjustedStepBasedOnBlacklist( + this.props.stepIndex, + nextIndex, + this.props.steps.length, + blacklistedSteps, + ); + this.props.setOnboardingStep(newStepIndex); + } + + private _adjustedStepBasedOnBlacklist( + currentStep: number, + nextStep: number, + totalSteps: number, + blacklistedSteps: number[], + ): number { + if (!blacklistedSteps.includes(nextStep)) { + return nextStep; + } + let newStep = nextStep; + const op = nextStep >= currentStep ? _.add : _.subtract; + let didSearch = false; + while (blacklistedSteps.includes(newStep)) { + newStep = op(newStep, 1); + if (newStep < 0) { + if (didSearch) { + break; + } + newStep = totalSteps - 1; + didSearch = true; + } + if (newStep >= totalSteps) { + if (didSearch) { + break; + } + newStep = 0; + didSearch = true; + } + } + return newStep; + } + private _handleChange(data: CallbackData): void { switch (data.action) { case 'close': diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx index feaa9c997..c80d1dd6e 100644 --- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx @@ -2,6 +2,7 @@ import * as _ from 'lodash'; import * as React from 'react'; import { Step } from 'react-joyride'; +import { black } from 'material-ui/styles/colors'; import { OnboardingFlow } from 'ts/components/onboarding/onboarding_flow'; import { ProviderType } from 'ts/types'; import { utils } from 'ts/utils/utils'; @@ -9,21 +10,47 @@ import { utils } from 'ts/utils/utils'; export interface PortalOnboardingFlowProps { stepIndex: number; isRunning: boolean; - onClose: () => void; userAddress: string; providerType: ProviderType; injectedProviderName: string; blockchainIsLoaded: boolean; + onClose: () => void; + setOnboardingStep: (stepIndex: number) => void; } +const steps: Step[] = [ + { + target: '.wallet', + content: + 'Before you begin, you need to connect to a wallet. This will be used across all 0x relayers and dApps', + placement: 'right', + disableBeacon: true, + }, + { + target: '.wallet', + content: 'Unlock your metamask extension to begin', + placement: 'right', + disableBeacon: true, + }, + { + target: '.wallet', + content: + 'In order to start trading on any 0x relayer in the 0x ecosystem, you need to complete two simple steps', + placement: 'right', + disableBeacon: true, + }, +]; + export class PortalOnboardingFlow extends React.Component { public render(): React.ReactNode { return ( ); } @@ -32,40 +59,18 @@ export class PortalOnboardingFlow extends React.Component Date: Fri, 25 May 2018 11:36:07 -0700 Subject: Auto-show onboarding flow on first page view --- .../ts/components/onboarding/portal_onboarding_flow.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx index c80d1dd6e..ab9d58415 100644 --- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx @@ -14,7 +14,8 @@ export interface PortalOnboardingFlowProps { providerType: ProviderType; injectedProviderName: string; blockchainIsLoaded: boolean; - onClose: () => void; + hasBeenSeen: boolean; + setIsRunning: (isRunning: boolean) => void; setOnboardingStep: (stepIndex: number) => void; } @@ -42,6 +43,12 @@ const steps: Step[] = [ ]; export class PortalOnboardingFlow extends React.Component { + public componentDidMount(): void { + this._autoStartOnboardingIfShould(); + } + public componentDidUpdate(): void { + this._autoStartOnboardingIfShould(); + } public render(): React.ReactNode { return ( ); @@ -73,4 +80,10 @@ export class PortalOnboardingFlow extends React.Component Date: Fri, 25 May 2018 12:02:18 -0700 Subject: Add next button --- packages/website/ts/components/onboarding/onboarding_flow.tsx | 6 +++++- .../website/ts/components/onboarding/portal_onboarding_flow.tsx | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx index 0cb640f8f..68dfc11bf 100644 --- a/packages/website/ts/components/onboarding/onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx @@ -31,6 +31,7 @@ export class OnboardingFlow extends React.Component { return ( { this.props.steps.length, blacklistedSteps, ); - this.props.setOnboardingStep(newStepIndex); + if (newStepIndex !== nextIndex) { + this.props.setOnboardingStep(newStepIndex); + } } private _adjustedStepBasedOnBlacklist( @@ -87,6 +90,7 @@ export class OnboardingFlow extends React.Component { switch (data.action) { case 'close': this.props.onClose(); + break; } } } diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx index ab9d58415..99fe5006d 100644 --- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx @@ -40,6 +40,12 @@ const steps: Step[] = [ placement: 'right', disableBeacon: true, }, + { + target: '.wallet', + content: 'Before you begin you will need to send some ETH to your metamask wallet', + placement: 'right', + disableBeacon: true, + }, ]; export class PortalOnboardingFlow extends React.Component { -- cgit v1.2.3 From 1026952f26043611c4aa3d77b2024cae304021e9 Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 25 May 2018 13:13:06 -0700 Subject: Run linter --- packages/website/ts/components/top_bar/provider_display.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index 4dc37f231..1cead7a5d 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -39,7 +39,10 @@ const styles: Styles = { export class ProviderDisplay extends React.Component { public render(): React.ReactNode { const isAddressAvailable = !_.isEmpty(this.props.userAddress); - const isExternallyInjectedProvider = utils.isExternallyInjected(this.props.providerType, this.props.injectedProviderName); + const isExternallyInjectedProvider = utils.isExternallyInjected( + this.props.providerType, + this.props.injectedProviderName, + ); const displayAddress = isAddressAvailable ? utils.getAddressBeginAndEnd(this.props.userAddress) : isExternallyInjectedProvider -- cgit v1.2.3 From 39008372e522bd0963dc71ec91235bb81813355f Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 25 May 2018 15:31:27 -0700 Subject: Write custom tooltip component --- .../ts/components/onboarding/onboarding_flow.tsx | 39 ++++++++++++++++++---- .../components/onboarding/onboarding_tooltip.tsx | 23 +++++++++++++ 2 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 packages/website/ts/components/onboarding/onboarding_tooltip.tsx (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx index 68dfc11bf..4ed834916 100644 --- a/packages/website/ts/components/onboarding/onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx @@ -2,6 +2,7 @@ import * as _ from 'lodash'; import * as React from 'react'; import Joyride, { CallbackData, Step, StyleOptions } from 'react-joyride'; +import { OnboardingTooltip } from 'ts/components/onboarding/onboarding_tooltip'; import { zIndex } from 'ts/utils/style'; export interface OnboardingFlowProps { @@ -36,7 +37,7 @@ export class OnboardingFlow extends React.Component { steps={this.props.steps} stepIndex={this.props.stepIndex} styles={{ options: joyrideStyleOptions }} - callback={this._handleChange.bind(this)} + tooltipComponent={this._renderToolTip.bind(this)} /> ); } @@ -86,11 +87,37 @@ export class OnboardingFlow extends React.Component { return newStep; } - private _handleChange(data: CallbackData): void { - switch (data.action) { - case 'close': - this.props.onClose(); - break; + private _renderToolTip(): React.ReactNode { + const { steps, stepIndex } = this.props; + const step = steps[stepIndex]; + const isLastStep = steps.length - 1 === stepIndex; + return ( + + ); + } + + private _goToNextStep(): void { + const nextStep = this.props.stepIndex + 1; + if (nextStep < this.props.steps.length) { + this.props.setOnboardingStep(nextStep); + } else { + this.props.onClose(); + } + } + + private _goToPrevStep(): void { + const nextStep = this.props.stepIndex - 1; + if (nextStep >= 0) { + this.props.setOnboardingStep(nextStep); + } else { + this.props.onClose(); } } } diff --git a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx new file mode 100644 index 000000000..3ab18b011 --- /dev/null +++ b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx @@ -0,0 +1,23 @@ +import * as React from 'react'; + +import { Island } from 'ts/components/ui/island'; + +export interface OnboardingTooltipProps { + title: string; + content: React.ReactNode; + isLastStep: boolean; + index: number; + onClose: () => void; + onClickNext: () => void; + onClickBack: () => void; +} + +export const OnboardingTooltip: React.StatelessComponent = (props: OnboardingTooltipProps) => ( + + {props.title} + {props.content} + + + + +); -- cgit v1.2.3 From d4a366aeb13d8b3ea2ace86f5566ddf8d94bf9c2 Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 29 May 2018 10:48:44 -0700 Subject: Replace react-joyride with react-popper --- .../ts/components/onboarding/onboarding_flow.tsx | 31 +++++++++++++++------- .../components/onboarding/onboarding_tooltip.tsx | 3 +-- 2 files changed, 23 insertions(+), 11 deletions(-) (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx index 4ed834916..cd6fe2195 100644 --- a/packages/website/ts/components/onboarding/onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx @@ -1,6 +1,7 @@ import * as _ from 'lodash'; import * as React from 'react'; import Joyride, { CallbackData, Step, StyleOptions } from 'react-joyride'; +import { Popper, PopperChildrenProps } from 'react-popper'; import { OnboardingTooltip } from 'ts/components/onboarding/onboarding_tooltip'; import { zIndex } from 'ts/utils/style'; @@ -29,16 +30,13 @@ export class OnboardingFlow extends React.Component { } public render(): React.ReactNode { + if (!this.props.isRunning) { + return null; + } return ( - + + {this._renderPopperChildren.bind(this)} + ); } @@ -87,6 +85,21 @@ export class OnboardingFlow extends React.Component { return newStep; } + private _getElementForStep(): Element { + const step = this.props.steps[this.props.stepIndex]; + return document.querySelector(step.target); + } + + private _renderPopperChildren(props: any): React.ReactNode { + const { arrowProps } = props; + return ( +
+ {this._renderToolTip()} +
+
+ ); + } + private _renderToolTip(): React.ReactNode { const { steps, stepIndex } = this.props; const step = steps[stepIndex]; diff --git a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx index 3ab18b011..3994b0546 100644 --- a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx +++ b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx @@ -3,10 +3,9 @@ import * as React from 'react'; import { Island } from 'ts/components/ui/island'; export interface OnboardingTooltipProps { - title: string; + title?: string; content: React.ReactNode; isLastStep: boolean; - index: number; onClose: () => void; onClickNext: () => void; onClickBack: () => void; -- cgit v1.2.3 From 338e8be327731116a4a0308ba353266293013dce Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 29 May 2018 10:53:55 -0700 Subject: Add types for react-popper, remove types for react-joyride --- .../ts/components/onboarding/onboarding_flow.tsx | 26 +++++++++++++--------- .../onboarding/portal_onboarding_flow.tsx | 7 +----- 2 files changed, 16 insertions(+), 17 deletions(-) (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx index cd6fe2195..9c416c2e1 100644 --- a/packages/website/ts/components/onboarding/onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx @@ -1,11 +1,17 @@ import * as _ from 'lodash'; import * as React from 'react'; -import Joyride, { CallbackData, Step, StyleOptions } from 'react-joyride'; -import { Popper, PopperChildrenProps } from 'react-popper'; +import { Placement, Popper, PopperChildrenProps } from 'react-popper'; import { OnboardingTooltip } from 'ts/components/onboarding/onboarding_tooltip'; import { zIndex } from 'ts/utils/style'; +export interface Step { + target: string; + title?: string; + content: React.ReactNode; + placement?: Placement; +} + export interface OnboardingFlowProps { steps: Step[]; blacklistedStepIndices: number[]; @@ -15,11 +21,6 @@ export interface OnboardingFlowProps { setOnboardingStep: (stepIndex: number) => void; } -const joyrideStyleOptions: StyleOptions = { - zIndex: zIndex.overlay, -}; - -// Wrapper around Joyride with defaults and styles set export class OnboardingFlow extends React.Component { public componentDidMount(): void { this._setOnboardingStepBasedOnBlacklist(this.props.stepIndex); @@ -34,7 +35,7 @@ export class OnboardingFlow extends React.Component { return null; } return ( - + {this._renderPopperChildren.bind(this)} ); @@ -86,11 +87,10 @@ export class OnboardingFlow extends React.Component { } private _getElementForStep(): Element { - const step = this.props.steps[this.props.stepIndex]; - return document.querySelector(step.target); + return document.querySelector(this._getCurrentStep().target); } - private _renderPopperChildren(props: any): React.ReactNode { + private _renderPopperChildren(props: PopperChildrenProps): React.ReactNode { const { arrowProps } = props; return (
@@ -116,6 +116,10 @@ export class OnboardingFlow extends React.Component { ); } + private _getCurrentStep(): Step { + return this.props.steps[this.props.stepIndex]; + } + private _goToNextStep(): void { const nextStep = this.props.stepIndex + 1; if (nextStep < this.props.steps.length) { diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx index 99fe5006d..00d278ce0 100644 --- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx @@ -1,9 +1,8 @@ import * as _ from 'lodash'; import * as React from 'react'; -import { Step } from 'react-joyride'; import { black } from 'material-ui/styles/colors'; -import { OnboardingFlow } from 'ts/components/onboarding/onboarding_flow'; +import { OnboardingFlow, Step } from 'ts/components/onboarding/onboarding_flow'; import { ProviderType } from 'ts/types'; import { utils } from 'ts/utils/utils'; @@ -25,26 +24,22 @@ const steps: Step[] = [ content: 'Before you begin, you need to connect to a wallet. This will be used across all 0x relayers and dApps', placement: 'right', - disableBeacon: true, }, { target: '.wallet', content: 'Unlock your metamask extension to begin', placement: 'right', - disableBeacon: true, }, { target: '.wallet', content: 'In order to start trading on any 0x relayer in the 0x ecosystem, you need to complete two simple steps', placement: 'right', - disableBeacon: true, }, { target: '.wallet', content: 'Before you begin you will need to send some ETH to your metamask wallet', placement: 'right', - disableBeacon: true, }, ]; -- cgit v1.2.3 From f0bbf2cab0ca7aef47699a3954fb0444d5d6d233 Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 29 May 2018 12:53:18 -0700 Subject: Improve tooltip look --- .../ts/components/onboarding/onboarding_flow.tsx | 9 ++++-- .../components/onboarding/onboarding_tooltip.tsx | 15 ++++++---- .../ts/components/top_bar/provider_display.tsx | 3 ++ packages/website/ts/components/ui/container.tsx | 15 +++++++--- packages/website/ts/components/ui/overlay.tsx | 34 ++++++++++++++++++++++ packages/website/ts/components/wallet/wallet.tsx | 3 ++ 6 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 packages/website/ts/components/ui/overlay.tsx (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx index 9c416c2e1..8af1a3a3f 100644 --- a/packages/website/ts/components/onboarding/onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx @@ -3,6 +3,7 @@ import * as React from 'react'; import { Placement, Popper, PopperChildrenProps } from 'react-popper'; import { OnboardingTooltip } from 'ts/components/onboarding/onboarding_tooltip'; +import { Overlay } from 'ts/components/ui/overlay'; import { zIndex } from 'ts/utils/style'; export interface Step { @@ -35,9 +36,11 @@ export class OnboardingFlow extends React.Component { return null; } return ( - - {this._renderPopperChildren.bind(this)} - + + + {this._renderPopperChildren.bind(this)} + + ); } diff --git a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx index 3994b0546..2d316b6b7 100644 --- a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx +++ b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; +import { Container } from 'ts/components/ui/container'; import { Island } from 'ts/components/ui/island'; export interface OnboardingTooltipProps { @@ -13,10 +14,14 @@ export interface OnboardingTooltipProps { export const OnboardingTooltip: React.StatelessComponent = (props: OnboardingTooltipProps) => ( - {props.title} - {props.content} - - - + +
+ {props.title} + {props.content} + + + +
+
); diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index 1cead7a5d..82c95aa6d 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -11,6 +11,7 @@ import { Dispatcher } from 'ts/redux/dispatcher'; import { ProviderType } from 'ts/types'; import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; +import { zIndex } from 'ts/utils/style'; import { utils } from 'ts/utils/utils'; const ROOT_HEIGHT = 24; @@ -33,6 +34,8 @@ const styles: Styles = { backgroundColor: colors.white, borderRadius: ROOT_HEIGHT, boxShadow: `0px 4px 6px ${colors.walletBoxShadow}`, + zIndex: zIndex.aboveOverlay, + position: 'relative', }, }; diff --git a/packages/website/ts/components/ui/container.tsx b/packages/website/ts/components/ui/container.tsx index 07868608c..d577447b0 100644 --- a/packages/website/ts/components/ui/container.tsx +++ b/packages/website/ts/components/ui/container.tsx @@ -1,10 +1,17 @@ import * as React from 'react'; +type StringOrNum = string | number; + export interface ContainerProps { - marginTop?: string | number; - marginBottom?: string | number; - marginRight?: string | number; - marginLeft?: string | number; + marginTop?: StringOrNum; + marginBottom?: StringOrNum; + marginRight?: StringOrNum; + marginLeft?: StringOrNum; + paddingTop?: StringOrNum; + paddingBottom?: StringOrNum; + paddingRight?: StringOrNum; + paddingLeft?: StringOrNum; + maxWidth?: StringOrNum; children?: React.ReactNode; } diff --git a/packages/website/ts/components/ui/overlay.tsx b/packages/website/ts/components/ui/overlay.tsx new file mode 100644 index 000000000..bb2ed8e59 --- /dev/null +++ b/packages/website/ts/components/ui/overlay.tsx @@ -0,0 +1,34 @@ +import { colors } from '@0xproject/react-shared'; +import * as _ from 'lodash'; +import * as React from 'react'; + +import { zIndex } from 'ts/utils/style'; + +export interface OverlayProps { + children?: React.ReactNode; + style?: React.CSSProperties; + onClick?: () => void; +} + +const style: React.CSSProperties = { + position: 'fixed', + top: 0, + right: 0, + bottom: 0, + left: 0, + zIndex: zIndex.overlay, + backgroundColor: 'rgba(0, 0, 0, 0.6)', +}; + +export const Overlay: React.StatelessComponent = (props: OverlayProps) => ( +
+ {props.children} +
+); + +Overlay.defaultProps = { + style: {}, + onClick: _.noop, +}; + +Overlay.displayName = 'Overlay'; diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 39e591bac..eab986208 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -47,6 +47,7 @@ import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; import { utils } from 'ts/utils/utils'; import { styles as walletItemStyles } from 'ts/utils/wallet_item_styles'; +import { zIndex } from '../../utils/style'; export interface WalletProps { userAddress: string; @@ -85,6 +86,8 @@ interface AccessoryItemConfig { const styles: Styles = { root: { width: '100%', + zIndex: zIndex.aboveOverlay, + position: 'relative', }, headerItemInnerDiv: { paddingLeft: 65, -- cgit v1.2.3 From 92cb5e10be479ca0440b3c7ca91fe70a1ef94c03 Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 29 May 2018 14:26:38 -0700 Subject: Some cleanup --- .../ts/components/onboarding/onboarding_flow.tsx | 23 +++++++++++----------- .../components/onboarding/onboarding_tooltip.tsx | 1 + 2 files changed, 13 insertions(+), 11 deletions(-) (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx index 8af1a3a3f..d53f63400 100644 --- a/packages/website/ts/components/onboarding/onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx @@ -3,6 +3,7 @@ import * as React from 'react'; import { Placement, Popper, PopperChildrenProps } from 'react-popper'; import { OnboardingTooltip } from 'ts/components/onboarding/onboarding_tooltip'; +import { Container } from 'ts/components/ui/container'; import { Overlay } from 'ts/components/ui/overlay'; import { zIndex } from 'ts/utils/style'; @@ -36,7 +37,7 @@ export class OnboardingFlow extends React.Component { return null; } return ( - + {this._renderPopperChildren.bind(this)} @@ -94,11 +95,9 @@ export class OnboardingFlow extends React.Component { } private _renderPopperChildren(props: PopperChildrenProps): React.ReactNode { - const { arrowProps } = props; return (
{this._renderToolTip()} -
); } @@ -108,14 +107,16 @@ export class OnboardingFlow extends React.Component { const step = steps[stepIndex]; const isLastStep = steps.length - 1 === stepIndex; return ( - + + + ); } diff --git a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx index 2d316b6b7..5e8102af0 100644 --- a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx +++ b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; +import { colors } from '@0xproject/react-shared'; import { Container } from 'ts/components/ui/container'; import { Island } from 'ts/components/ui/island'; -- cgit v1.2.3 From 30ac5fcb5e97c1ae62045ecf84fcd75a2da1ecf2 Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 29 May 2018 15:15:30 -0700 Subject: Remove blacklist concept --- .../ts/components/onboarding/onboarding_flow.tsx | 56 +--------------------- .../components/onboarding/onboarding_tooltip.tsx | 3 +- .../onboarding/portal_onboarding_flow.tsx | 25 ++++++---- .../ts/components/top_bar/provider_display.tsx | 2 - 4 files changed, 20 insertions(+), 66 deletions(-) (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx index d53f63400..de734318e 100644 --- a/packages/website/ts/components/onboarding/onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx @@ -12,11 +12,11 @@ export interface Step { title?: string; content: React.ReactNode; placement?: Placement; + hideBackButton?: boolean; } export interface OnboardingFlowProps { steps: Step[]; - blacklistedStepIndices: number[]; stepIndex: number; isRunning: boolean; onClose: () => void; @@ -24,14 +24,6 @@ export interface OnboardingFlowProps { } export class OnboardingFlow extends React.Component { - public componentDidMount(): void { - this._setOnboardingStepBasedOnBlacklist(this.props.stepIndex); - } - - public componentWillReceiveProps(nextProps: OnboardingFlowProps): void { - this._setOnboardingStepBasedOnBlacklist(nextProps.stepIndex); - } - public render(): React.ReactNode { if (!this.props.isRunning) { return null; @@ -45,51 +37,6 @@ export class OnboardingFlow extends React.Component { ); } - private _setOnboardingStepBasedOnBlacklist(nextIndex: number): void { - const blacklistedSteps = this.props.blacklistedStepIndices; - const newStepIndex = this._adjustedStepBasedOnBlacklist( - this.props.stepIndex, - nextIndex, - this.props.steps.length, - blacklistedSteps, - ); - if (newStepIndex !== nextIndex) { - this.props.setOnboardingStep(newStepIndex); - } - } - - private _adjustedStepBasedOnBlacklist( - currentStep: number, - nextStep: number, - totalSteps: number, - blacklistedSteps: number[], - ): number { - if (!blacklistedSteps.includes(nextStep)) { - return nextStep; - } - let newStep = nextStep; - const op = nextStep >= currentStep ? _.add : _.subtract; - let didSearch = false; - while (blacklistedSteps.includes(newStep)) { - newStep = op(newStep, 1); - if (newStep < 0) { - if (didSearch) { - break; - } - newStep = totalSteps - 1; - didSearch = true; - } - if (newStep >= totalSteps) { - if (didSearch) { - break; - } - newStep = 0; - didSearch = true; - } - } - return newStep; - } - private _getElementForStep(): Element { return document.querySelector(this._getCurrentStep().target); } @@ -112,6 +59,7 @@ export class OnboardingFlow extends React.Component { title={step.title} content={step.content} isLastStep={isLastStep} + hideBackButton={step.hideBackButton} onClose={this.props.onClose} onClickNext={this._goToNextStep.bind(this)} onClickBack={this._goToPrevStep.bind(this)} diff --git a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx index 5e8102af0..41925a672 100644 --- a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx +++ b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx @@ -11,6 +11,7 @@ export interface OnboardingTooltipProps { onClose: () => void; onClickNext: () => void; onClickBack: () => void; + hideBackButton?: boolean; } export const OnboardingTooltip: React.StatelessComponent = (props: OnboardingTooltipProps) => ( @@ -19,7 +20,7 @@ export const OnboardingTooltip: React.StatelessComponent
{props.title} {props.content} - + {!props.hideBackButton && }
diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx index 00d278ce0..25570b4a7 100644 --- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx @@ -35,6 +35,7 @@ const steps: Step[] = [ content: 'In order to start trading on any 0x relayer in the 0x ecosystem, you need to complete two simple steps', placement: 'right', + hideBackButton: true, }, { target: '.wallet', @@ -45,16 +46,15 @@ const steps: Step[] = [ export class PortalOnboardingFlow extends React.Component { public componentDidMount(): void { - this._autoStartOnboardingIfShould(); + this._overrideOnboardingStateIfShould(); } public componentDidUpdate(): void { - this._autoStartOnboardingIfShould(); + this._overrideOnboardingStateIfShould(); } public render(): React.ReactNode { return ( Date: Tue, 29 May 2018 15:49:13 -0700 Subject: Address PR feedback --- .../website/ts/components/onboarding/onboarding_flow.tsx | 6 +++--- .../ts/components/onboarding/portal_onboarding_flow.tsx | 16 ++++++++-------- packages/website/ts/components/wallet/wallet.tsx | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx index de734318e..524587358 100644 --- a/packages/website/ts/components/onboarding/onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx @@ -20,7 +20,7 @@ export interface OnboardingFlowProps { stepIndex: number; isRunning: boolean; onClose: () => void; - setOnboardingStep: (stepIndex: number) => void; + updateOnboardingStep: (stepIndex: number) => void; } export class OnboardingFlow extends React.Component { @@ -75,7 +75,7 @@ export class OnboardingFlow extends React.Component { private _goToNextStep(): void { const nextStep = this.props.stepIndex + 1; if (nextStep < this.props.steps.length) { - this.props.setOnboardingStep(nextStep); + this.props.updateOnboardingStep(nextStep); } else { this.props.onClose(); } @@ -84,7 +84,7 @@ export class OnboardingFlow extends React.Component { private _goToPrevStep(): void { const nextStep = this.props.stepIndex - 1; if (nextStep >= 0) { - this.props.setOnboardingStep(nextStep); + this.props.updateOnboardingStep(nextStep); } else { this.props.onClose(); } diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx index 25570b4a7..8bcb4c749 100644 --- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx @@ -14,8 +14,8 @@ export interface PortalOnboardingFlowProps { injectedProviderName: string; blockchainIsLoaded: boolean; hasBeenSeen: boolean; - setIsRunning: (isRunning: boolean) => void; - setOnboardingStep: (stepIndex: number) => void; + updateIsRunning: (isRunning: boolean) => void; + updateOnboardingStep: (stepIndex: number) => void; } const steps: Step[] = [ @@ -57,8 +57,8 @@ export class PortalOnboardingFlow extends React.Component ); } @@ -75,7 +75,7 @@ export class PortalOnboardingFlow extends React.Component Date: Tue, 29 May 2018 16:00:42 -0700 Subject: Fix unselected relayer drawer item --- packages/website/ts/components/portal/drawer_menu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/portal/drawer_menu.tsx b/packages/website/ts/components/portal/drawer_menu.tsx index 75c8ac6c2..ace11639a 100644 --- a/packages/website/ts/components/portal/drawer_menu.tsx +++ b/packages/website/ts/components/portal/drawer_menu.tsx @@ -36,7 +36,7 @@ export interface DrawerMenuProps { } export const DrawerMenu = (props: DrawerMenuProps) => { const relayerItemEntry = { - to: `${WebsitePaths.Portal}/`, + to: `${WebsitePaths.Portal}`, labelText: 'Relayer ecosystem', iconName: 'zmdi-portable-wifi', }; -- cgit v1.2.3 From b14c3fe48dc8eb5bad6eefceac872754eec34ffe Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 29 May 2018 17:57:22 -0700 Subject: Onboarding: implement add ETH step, and stub for add WETH step --- .../ts/components/onboarding/onboarding_flow.tsx | 6 +- .../components/onboarding/onboarding_tooltip.tsx | 29 +++++++- .../onboarding/portal_onboarding_flow.tsx | 86 ++++++++++++++-------- packages/website/ts/components/wallet/wallet.tsx | 30 ++++---- 4 files changed, 106 insertions(+), 45 deletions(-) (limited to 'packages/website/ts/components') diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx index 524587358..4066babaf 100644 --- a/packages/website/ts/components/onboarding/onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx @@ -2,7 +2,7 @@ import * as _ from 'lodash'; import * as React from 'react'; import { Placement, Popper, PopperChildrenProps } from 'react-popper'; -import { OnboardingTooltip } from 'ts/components/onboarding/onboarding_tooltip'; +import { ContinueButtonDisplay, OnboardingTooltip } from 'ts/components/onboarding/onboarding_tooltip'; import { Container } from 'ts/components/ui/container'; import { Overlay } from 'ts/components/ui/overlay'; import { zIndex } from 'ts/utils/style'; @@ -13,6 +13,8 @@ export interface Step { content: React.ReactNode; placement?: Placement; hideBackButton?: boolean; + hideNextButton?: boolean; + continueButtonDisplay?: ContinueButtonDisplay; } export interface OnboardingFlowProps { @@ -60,9 +62,11 @@ export class OnboardingFlow extends React.Component { content={step.content} isLastStep={isLastStep} hideBackButton={step.hideBackButton} + hideNextButton={step.hideNextButton} onClose={this.props.onClose} onClickNext={this._goToNextStep.bind(this)} onClickBack={this._goToPrevStep.bind(this)} + continueButtonDisplay={step.continueButtonDisplay} /> ); diff --git a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx index 41925a672..eb34a87f2 100644 --- a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx +++ b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx @@ -4,6 +4,8 @@ import { colors } from '@0xproject/react-shared'; import { Container } from 'ts/components/ui/container'; import { Island } from 'ts/components/ui/island'; +export type ContinueButtonDisplay = 'enabled' | 'disabled'; + export interface OnboardingTooltipProps { title?: string; content: React.ReactNode; @@ -11,19 +13,44 @@ export interface OnboardingTooltipProps { onClose: () => void; onClickNext: () => void; onClickBack: () => void; + continueButtonDisplay?: ContinueButtonDisplay; hideBackButton?: boolean; + hideNextButton?: boolean; +} + +// TODO: Make this more general button. +export interface ContinueButtonProps { + display: ContinueButtonDisplay; + children?: string; + onClick: () => void; } +export const ContinueButton: React.StatelessComponent = (props: ContinueButtonProps) => { + const isDisabled = props.display === 'disabled'; + return ( + + ); +}; + export const OnboardingTooltip: React.StatelessComponent = (props: OnboardingTooltipProps) => (
{props.title} {props.content} + {props.continueButtonDisplay && ( + + Continue + + )} {!props.hideBackButton && } - + {!props.hideNextButton && }
); + +OnboardingTooltip.displayName = 'OnboardingTooltip'; diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx index 8bcb4c749..edaeb3736 100644 --- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx @@ -1,49 +1,25 @@ import * as _ from 'lodash'; import * as React from 'react'; -import { black } from 'material-ui/styles/colors'; +import { BigNumber } from '@0xproject/utils'; import { OnboardingFlow, Step } from 'ts/components/onboarding/onboarding_flow'; -import { ProviderType } from 'ts/types'; +import { ProviderType, TokenByAddress } from 'ts/types'; import { utils } from 'ts/utils/utils'; export interface PortalOnboardingFlowProps { stepIndex: number; isRunning: boolean; userAddress: string; + hasBeenSeen: boolean; providerType: ProviderType; injectedProviderName: string; blockchainIsLoaded: boolean; - hasBeenSeen: boolean; + userEthBalanceInWei: BigNumber; + tokenByAddress: TokenByAddress; updateIsRunning: (isRunning: boolean) => void; updateOnboardingStep: (stepIndex: number) => void; } -const steps: Step[] = [ - { - target: '.wallet', - content: - 'Before you begin, you need to connect to a wallet. This will be used across all 0x relayers and dApps', - placement: 'right', - }, - { - target: '.wallet', - content: 'Unlock your metamask extension to begin', - placement: 'right', - }, - { - target: '.wallet', - content: - 'In order to start trading on any 0x relayer in the 0x ecosystem, you need to complete two simple steps', - placement: 'right', - hideBackButton: true, - }, - { - target: '.wallet', - content: 'Before you begin you will need to send some ETH to your metamask wallet', - placement: 'right', - }, -]; - export class PortalOnboardingFlow extends React.Component { public componentDidMount(): void { this._overrideOnboardingStateIfShould(); @@ -54,7 +30,7 @@ export class PortalOnboardingFlow extends React.Component new BigNumber(0); + } + + private _userHasWeth(): boolean { + // TODO: https://app.asana.com/0/681385331277907/690722374136933 + return false; + } + private _overrideOnboardingStateIfShould(): void { this._autoStartOnboardingIfShould(); this._adjustStepIfShould(); diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 524dc1952..d72c5458f 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -131,9 +131,6 @@ const styles: Styles = { }; const ETHER_ICON_PATH = '/images/ether.png'; -const ETHER_TOKEN_SYMBOL = 'WETH'; -const ZRX_TOKEN_SYMBOL = 'ZRX'; -const ETHER_SYMBOL = 'ETH'; const ICON_DIMENSION = 24; const TOKEN_AMOUNT_DISPLAY_PRECISION = 3; const BODY_ITEM_KEY = 'BODY'; @@ -319,7 +316,7 @@ export class Wallet extends React.Component { const primaryText = this._renderAmount( this.props.userEtherBalanceInWei, constants.DECIMAL_PLACES_ETH, - ETHER_SYMBOL, + constants.ETHER_SYMBOL, ); const etherToken = this._getEthToken(); const etherPrice = this.state.trackedTokenStateByAddress[etherToken.address].price; @@ -338,13 +335,13 @@ export class Wallet extends React.Component { ? { ...walletItemStyles.focusedItem, ...styles.paddedItem } : { ...styles.tokenItem, ...styles.borderedItem, ...styles.paddedItem }; const key = ETHER_ITEM_KEY; - return this._renderBalanceRow(key, icon, primaryText, secondaryText, accessoryItemConfig); + return this._renderBalanceRow(key, icon, primaryText, secondaryText, accessoryItemConfig, 'eth-row'); } private _renderTokenRows(): React.ReactNode { const trackedTokens = this.props.trackedTokens; const trackedTokensStartingWithEtherToken = trackedTokens.sort( - firstBy((t: Token) => t.symbol !== ETHER_TOKEN_SYMBOL) - .thenBy((t: Token) => t.symbol !== ZRX_TOKEN_SYMBOL) + firstBy((t: Token) => t.symbol !== constants.ETHER_TOKEN_SYMBOL) + .thenBy((t: Token) => t.symbol !== constants.ZRX_TOKEN_SYMBOL) .thenBy('address'), ); return _.map(trackedTokensStartingWithEtherToken, this._renderTokenRow.bind(this)); @@ -359,7 +356,8 @@ export class Wallet extends React.Component { const icon = ; const primaryText = this._renderAmount(tokenState.balance, token.decimals, token.symbol); const secondaryText = this._renderValue(tokenState.balance, token.decimals, tokenState.price); - const wrappedEtherDirection = token.symbol === ETHER_TOKEN_SYMBOL ? Side.Receive : undefined; + const isWeth = token.symbol === constants.ETHER_TOKEN_SYMBOL; + const wrappedEtherDirection = isWeth ? Side.Receive : undefined; const accessoryItemConfig: AccessoryItemConfig = { wrappedEtherDirection, allowanceToggleConfig: { @@ -368,7 +366,14 @@ export class Wallet extends React.Component { }, }; const key = token.address; - return this._renderBalanceRow(key, icon, primaryText, secondaryText, accessoryItemConfig); + return this._renderBalanceRow( + key, + icon, + primaryText, + secondaryText, + accessoryItemConfig, + isWeth ? 'weth-row' : undefined, + ); } private _renderBalanceRow( key: string, @@ -376,6 +381,7 @@ export class Wallet extends React.Component { primaryText: React.ReactNode, secondaryText: React.ReactNode, accessoryItemConfig: AccessoryItemConfig, + className?: string, ): React.ReactNode { const shouldShowWrapEtherItem = !_.isUndefined(this.state.wrappedEtherDirection) && @@ -385,7 +391,7 @@ export class Wallet extends React.Component { : { ...styles.tokenItem, ...styles.borderedItem, ...styles.paddedItem }; const etherToken = this._getEthToken(); return ( -
+
{icon}
@@ -575,8 +581,6 @@ export class Wallet extends React.Component { }); } private _getEthToken(): Token { - const tokens = _.values(this.props.tokenByAddress); - const etherToken = _.find(tokens, { symbol: ETHER_TOKEN_SYMBOL }); - return etherToken; + return utils.getEthToken(this.props.tokenByAddress); } } // tslint:disable:max-file-line-count -- cgit v1.2.3