diff options
author | Brandon Millman <brandon@0xproject.com> | 2018-05-19 06:38:04 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-19 06:38:04 +0800 |
commit | c70540e7f4ead1f25d1436de3b4dcda06c3e1e68 (patch) | |
tree | 03c9c8b6cc1c66b462b7009edb470e340b17a46f | |
parent | 85020c74cf8622d131b21f82a8027d437717712e (diff) | |
parent | e291146443e2dca839e9ee58f823dde3ab71093e (diff) | |
download | dexon-sol-tools-c70540e7f4ead1f25d1436de3b4dcda06c3e1e68.tar dexon-sol-tools-c70540e7f4ead1f25d1436de3b4dcda06c3e1e68.tar.gz dexon-sol-tools-c70540e7f4ead1f25d1436de3b4dcda06c3e1e68.tar.bz2 dexon-sol-tools-c70540e7f4ead1f25d1436de3b4dcda06c3e1e68.tar.lz dexon-sol-tools-c70540e7f4ead1f25d1436de3b4dcda06c3e1e68.tar.xz dexon-sol-tools-c70540e7f4ead1f25d1436de3b4dcda06c3e1e68.tar.zst dexon-sol-tools-c70540e7f4ead1f25d1436de3b4dcda06c3e1e68.zip |
Merge pull request #598 from 0xProject/feature/website/mobile-optimize
Mobile optimize the portal layout
19 files changed, 297 insertions, 94 deletions
diff --git a/packages/react-shared/CHANGELOG.json b/packages/react-shared/CHANGELOG.json index 1095c78ee..3e03f81f1 100644 --- a/packages/react-shared/CHANGELOG.json +++ b/packages/react-shared/CHANGELOG.json @@ -1,5 +1,13 @@ [ { + "version": "0.2.0", + "changes": [ + { + "note": "Removed portal specific colors" + } + ] + }, + { "timestamp": 1525477860, "version": "0.1.6", "changes": [ diff --git a/packages/react-shared/src/utils/colors.ts b/packages/react-shared/src/utils/colors.ts index 4617fa5dc..71d92c290 100644 --- a/packages/react-shared/src/utils/colors.ts +++ b/packages/react-shared/src/utils/colors.ts @@ -48,20 +48,7 @@ const baseColors = { darkYellow: '#caca03', }; -const appColors = { - // wallet specific colors - walletBoxShadow: 'rgba(56, 59, 137, 0.2)', - walletBorder: '#ededee', - walletDefaultItemBackground: '#fbfbfc', - walletFocusedItemBackground: '#f0f1f4', - allowanceToggleShadow: 'rgba(0, 0, 0, 0)', - allowanceToggleOffTrack: '#adadad', - allowanceToggleOnTrack: baseColors.mediumBlue, - wrapEtherConfirmationButton: baseColors.mediumBlue, -}; - export const colors = { ...materialUiColors, ...baseColors, - ...appColors, }; diff --git a/packages/website/ts/components/inputs/allowance_toggle.tsx b/packages/website/ts/components/inputs/allowance_toggle.tsx index 48c7f9f57..d61dfa87d 100644 --- a/packages/website/ts/components/inputs/allowance_toggle.tsx +++ b/packages/website/ts/components/inputs/allowance_toggle.tsx @@ -1,4 +1,4 @@ -import { colors, constants as sharedConstants, Styles } from '@0xproject/react-shared'; +import { constants as sharedConstants, Styles } from '@0xproject/react-shared'; import { BigNumber, logUtils } from '@0xproject/utils'; import * as _ from 'lodash'; import Toggle from 'material-ui/Toggle'; @@ -7,6 +7,7 @@ import { Blockchain } from 'ts/blockchain'; import { Dispatcher } from 'ts/redux/dispatcher'; import { BalanceErrs, Token, TokenState } from 'ts/types'; import { analytics } from 'ts/utils/analytics'; +import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; import { errorReporter } from 'ts/utils/error_reporter'; import { utils } from 'ts/utils/utils'; diff --git a/packages/website/ts/components/portal/back_button.tsx b/packages/website/ts/components/portal/back_button.tsx index 68934f88e..48858613c 100644 --- a/packages/website/ts/components/portal/back_button.tsx +++ b/packages/website/ts/components/portal/back_button.tsx @@ -1,7 +1,9 @@ -import { colors, Styles } from '@0xproject/react-shared'; +import { Styles } from '@0xproject/react-shared'; import * as React from 'react'; import { Link } from 'react-router-dom'; +import { colors } from 'ts/utils/colors'; + export interface BackButtonProps { to: string; labelText: string; diff --git a/packages/website/ts/components/portal/drawer_menu.tsx b/packages/website/ts/components/portal/drawer_menu.tsx new file mode 100644 index 000000000..75c8ac6c2 --- /dev/null +++ b/packages/website/ts/components/portal/drawer_menu.tsx @@ -0,0 +1,68 @@ +import { Styles } from '@0xproject/react-shared'; +import * as _ from 'lodash'; +import * as React from 'react'; + +import { defaultMenuItemEntries, Menu } from 'ts/components/portal/menu'; +import { Identicon } from 'ts/components/ui/identicon'; +import { WebsitePaths } from 'ts/types'; +import { colors } from 'ts/utils/colors'; +import { utils } from 'ts/utils/utils'; + +const IDENTICON_DIAMETER = 45; +const BORDER_RADIUS = '50%'; + +const styles: Styles = { + root: { + backgroundColor: colors.drawerMenuBackground, + width: '100%', + height: '100%', + }, + identicon: { + borderWidth: 3, + borderStyle: 'solid', + borderColor: colors.white, + borderRadius: BORDER_RADIUS, + MozBorderRadius: BORDER_RADIUS, + WebkitBorderRadius: BORDER_RADIUS, + }, + userAddress: { + color: colors.white, + }, +}; + +export interface DrawerMenuProps { + selectedPath?: string; + userAddress?: string; +} +export const DrawerMenu = (props: DrawerMenuProps) => { + const relayerItemEntry = { + to: `${WebsitePaths.Portal}/`, + labelText: 'Relayer ecosystem', + iconName: 'zmdi-portable-wifi', + }; + const menuItemEntries = _.concat(relayerItemEntry, defaultMenuItemEntries); + return ( + <div style={styles.root}> + <Header userAddress={props.userAddress} /> + <Menu selectedPath={props.selectedPath} menuItemEntries={menuItemEntries} /> + </div> + ); +}; + +interface HeaderProps { + userAddress?: string; +} +const Header = (props: HeaderProps) => { + return ( + <div className="flex flex-center py4"> + <div className="flex flex-column mx-auto"> + <Identicon address={props.userAddress} diameter={IDENTICON_DIAMETER} style={styles.identicon} /> + {!_.isUndefined(props.userAddress) && ( + <div className="pt2" style={styles.userAddress}> + {utils.getAddressBeginAndEnd(props.userAddress)} + </div> + )} + </div> + </div> + ); +}; diff --git a/packages/website/ts/components/portal/menu.tsx b/packages/website/ts/components/portal/menu.tsx index 9014d8d42..e8353a3b0 100644 --- a/packages/website/ts/components/portal/menu.tsx +++ b/packages/website/ts/components/portal/menu.tsx @@ -1,21 +1,32 @@ -import { colors, Styles } from '@0xproject/react-shared'; +import { Styles } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import { MenuItem } from 'ts/components/ui/menu_item'; import { Environments, WebsitePaths } from 'ts/types'; +import { colors } from 'ts/utils/colors'; import { configs } from 'ts/utils/configs'; -export interface MenuProps { - selectedPath?: string; +export interface MenuTheme { + paddingLeft: number; + textColor: string; + iconColor: string; + selectedIconColor: string; + selectedBackgroundColor: string; } -interface MenuItemEntry { +export interface MenuItemEntry { to: string; labelText: string; iconName: string; } -const menuItemEntries: MenuItemEntry[] = [ +export interface MenuProps { + selectedPath?: string; + theme?: MenuTheme; + menuItemEntries?: MenuItemEntry[]; +} + +export const defaultMenuItemEntries: MenuItemEntry[] = [ { to: `${WebsitePaths.Portal}/account`, labelText: 'Account overview', @@ -38,49 +49,66 @@ const menuItemEntries: MenuItemEntry[] = [ }, ]; -const DEFAULT_LABEL_COLOR = colors.darkerGrey; -const DEFAULT_ICON_COLOR = colors.darkerGrey; -const SELECTED_ICON_COLOR = colors.yellow900; - -const LEFT_PADDING = 185; +const DEFAULT_MENU_THEME: MenuTheme = { + paddingLeft: 30, + textColor: colors.white, + iconColor: colors.white, + selectedIconColor: colors.white, + selectedBackgroundColor: colors.menuItemDefaultSelectedBackground, +}; export const Menu: React.StatelessComponent<MenuProps> = (props: MenuProps) => { return ( - <div style={{ paddingLeft: LEFT_PADDING }}> - {_.map(menuItemEntries, entry => { + <div> + {_.map(props.menuItemEntries, entry => { const selected = entry.to === props.selectedPath; return ( - <MenuItem key={entry.to} className="py2" to={entry.to}> - <MenuItemLabel title={entry.labelText} iconName={entry.iconName} selected={selected} /> + <MenuItem key={entry.to} to={entry.to}> + <MenuItemLabel + title={entry.labelText} + iconName={entry.iconName} + selected={selected} + theme={props.theme} + /> </MenuItem> ); })} </div> ); }; +Menu.defaultProps = { + theme: DEFAULT_MENU_THEME, + menuItemEntries: defaultMenuItemEntries, +}; interface MenuItemLabelProps { title: string; iconName: string; selected: boolean; + theme: MenuTheme; } const MenuItemLabel: React.StatelessComponent<MenuItemLabelProps> = (props: MenuItemLabelProps) => { const styles: Styles = { - iconStyle: { - color: props.selected ? SELECTED_ICON_COLOR : DEFAULT_ICON_COLOR, + root: { + backgroundColor: props.selected ? props.theme.selectedBackgroundColor : undefined, + paddingLeft: props.theme.paddingLeft, + }, + icon: { + color: props.selected ? props.theme.selectedIconColor : props.theme.iconColor, fontSize: 20, }, - textStyle: { - color: DEFAULT_LABEL_COLOR, + text: { + color: props.theme.textColor, fontWeight: props.selected ? 'bold' : 'normal', + fontSize: 16, }, }; return ( - <div className="flex"> + <div className="flex py2" style={styles.root}> <div className="pr1"> - <i style={styles.iconStyle} className={`zmdi ${props.iconName}`} /> + <i style={styles.icon} className={`zmdi ${props.iconName}`} /> </div> - <div className="pl1" style={styles.textStyle}> + <div className="pl1" style={styles.text}> {props.title} </div> </div> diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx index d9d50c5ab..b992204a7 100644 --- a/packages/website/ts/components/portal/portal.tsx +++ b/packages/website/ts/components/portal/portal.tsx @@ -13,7 +13,7 @@ import { EthWrappers } from 'ts/components/eth_wrappers'; import { AssetPicker } from 'ts/components/generate_order/asset_picker'; import { BackButton } from 'ts/components/portal/back_button'; import { Loading } from 'ts/components/portal/loading'; -import { Menu } from 'ts/components/portal/menu'; +import { Menu, MenuTheme } from 'ts/components/portal/menu'; import { Section } from 'ts/components/portal/section'; import { TextHeader } from 'ts/components/portal/text_header'; import { RelayerIndex } from 'ts/components/relayer_index/relayer_index'; @@ -89,6 +89,7 @@ enum TokenManagementState { const THROTTLE_TIMEOUT = 100; const TOP_BAR_HEIGHT = TopBar.heightForDisplayType(TopBarDisplayType.Expanded); const LEFT_COLUMN_WIDTH = 346; +const MENU_PADDING_LEFT = 185; const styles: Styles = { root: { @@ -199,14 +200,11 @@ export class Portal extends React.Component<PortalProps, PortalState> { /> <div id="portal" style={styles.body}> <Switch> - <Route - path={`${WebsitePaths.Portal}/:route`} - render={this._renderMenuAndAccountManagement.bind(this)} - /> + <Route path={`${WebsitePaths.Portal}/:route`} render={this._renderOtherRoutes.bind(this)} /> <Route exact={true} path={`${WebsitePaths.Portal}/`} - render={this._renderWalletAndRelayerIndex.bind(this)} + render={this._renderMainRoute.bind(this)} /> </Switch> <BlockchainErrDialog @@ -247,17 +245,32 @@ export class Portal extends React.Component<PortalProps, PortalState> { </div> ); } - private _renderWalletAndRelayerIndex(): React.ReactNode { - return <PortalLayout left={this._renderWallet()} right={this._renderRelayerIndexSection()} />; + private _renderMainRoute(): React.ReactNode { + if (this._isSmallScreen()) { + return <SmallLayout content={this._renderRelayerIndexSection()} />; + } else { + return <LargeLayout left={this._renderWalletSection()} right={this._renderRelayerIndexSection()} />; + } } - private _renderMenuAndAccountManagement(routeComponentProps: RouteComponentProps<any>): React.ReactNode { - return <PortalLayout left={this._renderMenu(routeComponentProps)} right={this._renderAccountManagement()} />; + private _renderOtherRoutes(routeComponentProps: RouteComponentProps<any>): React.ReactNode { + if (this._isSmallScreen()) { + return <SmallLayout content={this._renderAccountManagement()} />; + } else { + return <LargeLayout left={this._renderMenu(routeComponentProps)} right={this._renderAccountManagement()} />; + } } private _renderMenu(routeComponentProps: RouteComponentProps<any>): React.ReactNode { + const menuTheme: MenuTheme = { + paddingLeft: MENU_PADDING_LEFT, + textColor: colors.darkerGrey, + iconColor: colors.darkerGrey, + selectedIconColor: colors.yellow800, + selectedBackgroundColor: 'transparent', + }; return ( <Section header={<BackButton to={`${WebsitePaths.Portal}`} labelText="back to Relayers" />} - body={<Menu selectedPath={routeComponentProps.location.pathname} />} + body={<Menu selectedPath={routeComponentProps.location.pathname} theme={menuTheme} />} /> ); } @@ -265,30 +278,28 @@ export class Portal extends React.Component<PortalProps, PortalState> { const allTokens = _.values(this.props.tokenByAddress); const trackedTokens = _.filter(allTokens, t => t.isTracked); return ( - <Section - header={<TextHeader labelText="Your Account" />} - body={ - <Wallet - userAddress={this.props.userAddress} - networkId={this.props.networkId} - blockchain={this._blockchain} - blockchainIsLoaded={this.props.blockchainIsLoaded} - blockchainErr={this.props.blockchainErr} - dispatcher={this.props.dispatcher} - tokenByAddress={this.props.tokenByAddress} - trackedTokens={trackedTokens} - userEtherBalanceInWei={this.props.userEtherBalanceInWei} - lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch} - injectedProviderName={this.props.injectedProviderName} - providerType={this.props.providerType} - onToggleLedgerDialog={this._onToggleLedgerDialog.bind(this)} - onAddToken={this._onAddToken.bind(this)} - onRemoveToken={this._onRemoveToken.bind(this)} - /> - } + <Wallet + userAddress={this.props.userAddress} + networkId={this.props.networkId} + blockchain={this._blockchain} + blockchainIsLoaded={this.props.blockchainIsLoaded} + blockchainErr={this.props.blockchainErr} + dispatcher={this.props.dispatcher} + tokenByAddress={this.props.tokenByAddress} + trackedTokens={trackedTokens} + userEtherBalanceInWei={this.props.userEtherBalanceInWei} + lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch} + injectedProviderName={this.props.injectedProviderName} + providerType={this.props.providerType} + onToggleLedgerDialog={this._onToggleLedgerDialog.bind(this)} + onAddToken={this._onAddToken.bind(this)} + onRemoveToken={this._onRemoveToken.bind(this)} /> ); } + private _renderWalletSection(): React.ReactNode { + return <Section header={<TextHeader labelText="Your Account" />} body={this._renderWallet()} />; + } private _renderAccountManagement(): React.ReactNode { const accountManagementItems: AccountManagementItem[] = [ { @@ -299,7 +310,7 @@ export class Portal extends React.Component<PortalProps, PortalState> { { pathName: `${WebsitePaths.Portal}/account`, headerText: 'Your Account', - render: this._renderTokenBalances.bind(this), + render: this._isSmallScreen() ? this._renderWallet.bind(this) : this._renderTokenBalances.bind(this), }, { pathName: `${WebsitePaths.Portal}/trades`, @@ -315,7 +326,13 @@ export class Portal extends React.Component<PortalProps, PortalState> { return ( <Switch> {_.map(accountManagementItems, item => { - return <Route path={item.pathName} render={this._renderAccountManagementItem.bind(this, item)} />; + return ( + <Route + key={item.pathName} + path={item.pathName} + render={this._renderAccountManagementItem.bind(this, item)} + /> + ); })}} <Route render={this._renderNotFoundMessage.bind(this)} /> </Switch> @@ -383,7 +400,7 @@ export class Portal extends React.Component<PortalProps, PortalState> { return ( <Section header={<TextHeader labelText="Explore 0x Relayers" />} - body={<RelayerIndex networkId={this.props.networkId} />} + body={<RelayerIndex networkId={this.props.networkId} screenWidth={this.props.screenWidth} />} /> ); } @@ -448,13 +465,17 @@ export class Portal extends React.Component<PortalProps, PortalState> { const newScreenWidth = utils.getScreenWidth(); this.props.dispatcher.updateScreenWidth(newScreenWidth); } + private _isSmallScreen(): boolean { + const result = this.props.screenWidth === ScreenWidths.Sm; + return result; + } } -interface PortalLayoutProps { +interface LargeLayoutProps { left: React.ReactNode; right: React.ReactNode; } -const PortalLayout = (props: PortalLayoutProps) => { +const LargeLayout = (props: LargeLayoutProps) => { return ( <div className="sm-flex flex-center"> <div className="flex-last px3"> @@ -465,4 +486,17 @@ const PortalLayout = (props: PortalLayoutProps) => { </div> </div> ); +}; + +interface SmallLayoutProps { + content: React.ReactNode; +} +const SmallLayout = (props: SmallLayoutProps) => { + return ( + <div className="sm-flex flex-center"> + <div className="flex-auto px3" style={styles.scrollContainer}> + {props.content} + </div> + </div> + ); }; // tslint:disable:max-file-line-count diff --git a/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx b/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx index 5964dcd56..dc9eeb29d 100644 --- a/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx +++ b/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx @@ -1,4 +1,4 @@ -import { colors, Styles } from '@0xproject/react-shared'; +import { Styles } from '@0xproject/react-shared'; import * as _ from 'lodash'; import { GridTile } from 'material-ui/GridList'; import * as React from 'react'; @@ -6,6 +6,7 @@ import * as React from 'react'; import { TopTokens } from 'ts/components/relayer_index/relayer_top_tokens'; import { TokenIcon } from 'ts/components/ui/token_icon'; import { Token, WebsiteBackendRelayerInfo } from 'ts/types'; +import { colors } from 'ts/utils/colors'; export interface RelayerGridTileProps { relayerInfo: WebsiteBackendRelayerInfo; diff --git a/packages/website/ts/components/relayer_index/relayer_index.tsx b/packages/website/ts/components/relayer_index/relayer_index.tsx index b327c9817..8da4e0e10 100644 --- a/packages/website/ts/components/relayer_index/relayer_index.tsx +++ b/packages/website/ts/components/relayer_index/relayer_index.tsx @@ -1,4 +1,4 @@ -import { colors, Styles } from '@0xproject/react-shared'; +import { Styles } from '@0xproject/react-shared'; import * as _ from 'lodash'; import CircularProgress from 'material-ui/CircularProgress'; import FlatButton from 'material-ui/FlatButton'; @@ -6,11 +6,13 @@ import { GridList } from 'material-ui/GridList'; import * as React from 'react'; import { RelayerGridTile } from 'ts/components/relayer_index/relayer_grid_tile'; -import { WebsiteBackendRelayerInfo } from 'ts/types'; +import { ScreenWidths, WebsiteBackendRelayerInfo } from 'ts/types'; import { backendClient } from 'ts/utils/backend_client'; +import { colors } from 'ts/utils/colors'; export interface RelayerIndexProps { networkId: number; + screenWidth: ScreenWidths; } interface RelayerIndexState { @@ -35,7 +37,9 @@ const styles: Styles = { }; const CELL_HEIGHT = 290; -const NUMBER_OF_COLUMNS = 4; +const NUMBER_OF_COLUMNS_LARGE = 4; +const NUMBER_OF_COLUMNS_MEDIUM = 3; +const NUMBER_OF_COLUMNS_SMALL = 1; const GRID_PADDING = 20; export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerIndexState> { @@ -69,11 +73,12 @@ export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerInde </div> ); } else { + const numberOfColumns = this._numberOfColumnsForScreenWidth(this.props.screenWidth); return ( <div style={styles.root}> <GridList cellHeight={CELL_HEIGHT} - cols={NUMBER_OF_COLUMNS} + cols={numberOfColumns} padding={GRID_PADDING} style={styles.gridList} > @@ -107,6 +112,17 @@ export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerInde } } } + private _numberOfColumnsForScreenWidth(screenWidth: ScreenWidths): number { + switch (screenWidth) { + case ScreenWidths.Md: + return NUMBER_OF_COLUMNS_MEDIUM; + case ScreenWidths.Sm: + return NUMBER_OF_COLUMNS_SMALL; + case ScreenWidths.Lg: + default: + return NUMBER_OF_COLUMNS_LARGE; + } + } } interface RetryProps { diff --git a/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx b/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx index 03c70c9dd..40ab7bd03 100644 --- a/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx +++ b/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx @@ -26,7 +26,14 @@ export const TopTokens: React.StatelessComponent<TopTokensProps> = (props: TopTo {_.map(props.tokens, (tokenInfo: WebsiteBackendTokenInfo, index: number) => { const firstItemStyle = { ...styles.tokenLabel, ...styles.followingTokenLabel }; const style = index !== 0 ? firstItemStyle : styles.tokenLabel; - return <TokenLink tokenInfo={tokenInfo} style={style} networkId={props.networkId} />; + return ( + <TokenLink + key={tokenInfo.address} + tokenInfo={tokenInfo} + style={style} + networkId={props.networkId} + /> + ); })} </div> ); @@ -56,7 +63,6 @@ class TokenLink extends React.Component<TokenLinkProps, TokenLinkState> { }; return ( <a - key={this.props.tokenInfo.address} href={tokenLinkFromToken(this.props.tokenInfo, this.props.networkId)} target="_blank" style={style} diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index bebaa5341..fc516882a 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -1,13 +1,15 @@ -import { colors, Styles } from '@0xproject/react-shared'; +import { Styles } from '@0xproject/react-shared'; import * as _ from 'lodash'; import RaisedButton from 'material-ui/RaisedButton'; import * as React from 'react'; + import { Blockchain } from 'ts/blockchain'; import { ProviderPicker } from 'ts/components/top_bar/provider_picker'; import { DropDown } from 'ts/components/ui/drop_down'; import { Identicon } from 'ts/components/ui/identicon'; import { Dispatcher } from 'ts/redux/dispatcher'; import { ProviderType } from 'ts/types'; +import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; import { utils } from 'ts/utils/utils'; diff --git a/packages/website/ts/components/top_bar/top_bar.tsx b/packages/website/ts/components/top_bar/top_bar.tsx index 5fde007d6..2c3273dee 100644 --- a/packages/website/ts/components/top_bar/top_bar.tsx +++ b/packages/website/ts/components/top_bar/top_bar.tsx @@ -9,6 +9,7 @@ import { Link } from 'react-router-dom'; import ReactTooltip = require('react-tooltip'); import { Blockchain } from 'ts/blockchain'; import { LegacyPortalMenu } from 'ts/components/legacy_portal/legacy_portal_menu'; +import { DrawerMenu } from 'ts/components/portal/drawer_menu'; import { SidebarHeader } from 'ts/components/sidebar_header'; import { ProviderDisplay } from 'ts/components/top_bar/provider_display'; import { TopBarMenuItem } from 'ts/components/top_bar/top_bar_menu_item'; @@ -18,6 +19,7 @@ import { Dispatcher } from 'ts/redux/dispatcher'; import { Deco, Key, ProviderType, WebsiteLegacyPaths, WebsitePaths } from 'ts/types'; import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; +import { utils } from 'ts/utils/utils'; export enum TopBarDisplayType { Default, @@ -93,6 +95,13 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { isDrawerOpen: false, }; } + public componentWillReceiveProps(nextProps: TopBarProps): void { + if (nextProps.location.pathname !== this.props.location.pathname) { + this.setState({ + isDrawerOpen: false, + }); + } + } public render(): React.ReactNode { const isNightVersion = this.props.isNightVersion; const isExpandedDisplayType = this.props.displayType === TopBarDisplayType.Expanded; @@ -202,6 +211,8 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { </div> ); const popoverContent = <Menu style={{ color: colors.darkGrey }}>{developerSectionMenuItems}</Menu>; + // TODO : Remove this once we ship portal v2 + const shouldShowPortalV2Drawer = this._isViewingPortal() && utils.shouldShowPortalV2(); return ( <div style={{ ...styles.topBar, ...bottomBorderStyle, ...this.props.style, ...{ height } }} className="pb1"> <div className={parentClassNames}> @@ -274,10 +285,22 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { </div> </div> </div> - {this._renderDrawer()} + {shouldShowPortalV2Drawer ? this._renderPortalV2Drawer() : this._renderDrawer()} </div> ); } + private _renderPortalV2Drawer(): React.ReactNode { + return ( + <Drawer + open={this.state.isDrawerOpen} + docked={false} + openSecondary={true} + onRequestChange={this._onMenuButtonClick.bind(this)} + > + <DrawerMenu selectedPath={this.props.location.pathname} userAddress={this.props.userAddress} /> + </Drawer> + ); + } private _renderDrawer(): React.ReactNode { return ( <Drawer diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 75dbd12e9..dab8b7d2f 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -1,6 +1,5 @@ import { ZeroEx } from '0x.js'; import { - colors, constants as sharedConstants, EtherscanLinkSuffixes, Styles, @@ -42,6 +41,7 @@ import { WebsitePaths, } from 'ts/types'; import { backendClient } from 'ts/utils/backend_client'; +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'; diff --git a/packages/website/ts/components/wallet/wallet_disconnected_item.tsx b/packages/website/ts/components/wallet/wallet_disconnected_item.tsx index 89e32f7be..d334f1748 100644 --- a/packages/website/ts/components/wallet/wallet_disconnected_item.tsx +++ b/packages/website/ts/components/wallet/wallet_disconnected_item.tsx @@ -1,9 +1,10 @@ -import { colors, Styles } from '@0xproject/react-shared'; +import { Styles } from '@0xproject/react-shared'; import FlatButton from 'material-ui/FlatButton'; import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet'; import * as React from 'react'; import { ProviderType } from 'ts/types'; +import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; export interface WalletDisconnectedItemProps { diff --git a/packages/website/ts/components/wallet/wrap_ether_item.tsx b/packages/website/ts/components/wallet/wrap_ether_item.tsx index db0983407..98b28b3ad 100644 --- a/packages/website/ts/components/wallet/wrap_ether_item.tsx +++ b/packages/website/ts/components/wallet/wrap_ether_item.tsx @@ -1,5 +1,5 @@ import { ZeroEx } from '0x.js'; -import { colors, Styles } from '@0xproject/react-shared'; +import { Styles } from '@0xproject/react-shared'; import { BigNumber, logUtils } from '@0xproject/utils'; import * as _ from 'lodash'; import FlatButton from 'material-ui/FlatButton'; @@ -11,6 +11,7 @@ import { EthAmountInput } from 'ts/components/inputs/eth_amount_input'; import { TokenAmountInput } from 'ts/components/inputs/token_amount_input'; import { Dispatcher } from 'ts/redux/dispatcher'; import { BlockchainCallErrs, Side, Token } from 'ts/types'; +import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; import { errorReporter } from 'ts/utils/error_reporter'; import { utils } from 'ts/utils/utils'; diff --git a/packages/website/ts/index.tsx b/packages/website/ts/index.tsx index f255f81e7..7fc180449 100644 --- a/packages/website/ts/index.tsx +++ b/packages/website/ts/index.tsx @@ -34,14 +34,15 @@ import 'less/all.less'; // cause we only want to import the module when the user navigates to the page. // At the same time webpack statically parses for System.import() to determine bundle chunk split points // so each lazy import needs it's own `System.import()` declaration. -const LazyPortal = - utils.isDevelopment() || utils.isStaging() || utils.isDogfood() - ? createLazyComponent('Portal', async () => - System.import<any>(/* webpackChunkName: "portal" */ 'ts/containers/portal'), - ) - : createLazyComponent('LegacyPortal', async () => - System.import<any>(/* webpackChunkName: "legacyPortal" */ 'ts/containers/legacy_portal'), - ); + +// TODO: Remove this once we ship V2 +const LazyPortal = utils.shouldShowPortalV2() + ? createLazyComponent('Portal', async () => + System.import<any>(/* webpackChunkName: "portal" */ 'ts/containers/portal'), + ) + : createLazyComponent('LegacyPortal', async () => + System.import<any>(/* webpackChunkName: "legacyPortal" */ 'ts/containers/legacy_portal'), + ); const LazyZeroExJSDocumentation = createLazyComponent('Documentation', async () => System.import<any>(/* webpackChunkName: "zeroExDocs" */ 'ts/containers/zero_ex_js_documentation'), ); diff --git a/packages/website/ts/utils/colors.ts b/packages/website/ts/utils/colors.ts new file mode 100644 index 000000000..5ffdd6ba7 --- /dev/null +++ b/packages/website/ts/utils/colors.ts @@ -0,0 +1,19 @@ +import { colors as sharedColors } from '@0xproject/react-shared'; + +const appColors = { + walletBoxShadow: 'rgba(56, 59, 137, 0.2)', + walletBorder: '#ededee', + walletDefaultItemBackground: '#fbfbfc', + walletFocusedItemBackground: '#f0f1f4', + allowanceToggleShadow: 'rgba(0, 0, 0, 0)', + allowanceToggleOffTrack: '#adadad', + allowanceToggleOnTrack: sharedColors.mediumBlue, + wrapEtherConfirmationButton: sharedColors.mediumBlue, + drawerMenuBackground: '#4a4a4a', + menuItemDefaultSelectedBackground: '#424242', +}; + +export const colors = { + ...sharedColors, + ...appColors, +}; diff --git a/packages/website/ts/utils/utils.ts b/packages/website/ts/utils/utils.ts index 3c99bd2fe..c370ac90c 100644 --- a/packages/website/ts/utils/utils.ts +++ b/packages/website/ts/utils/utils.ts @@ -314,4 +314,7 @@ export const utils = { return _.includes(window.location.href, configs.DOMAIN_STAGING); }, isDogfood, + shouldShowPortalV2(): boolean { + return this.isDevelopment() || this.isStaging() || this.isDogfood(); + }, }; diff --git a/packages/website/ts/utils/wallet_item_styles.ts b/packages/website/ts/utils/wallet_item_styles.ts index 1ad304ce1..6b038efd2 100644 --- a/packages/website/ts/utils/wallet_item_styles.ts +++ b/packages/website/ts/utils/wallet_item_styles.ts @@ -1,4 +1,6 @@ -import { colors, Styles } from '@0xproject/react-shared'; +import { Styles } from '@0xproject/react-shared'; + +import { colors } from 'ts/utils/colors'; export const styles: Styles = { focusedItem: { |