Merge pull request #598 from 0xProject/feature/website/mobile-optimize
Mobile optimize the portal layout
This commit is contained in:
@@ -1,4 +1,12 @@
|
||||
[
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Removed portal specific colors"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1525477860,
|
||||
"version": "0.1.6",
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
|
||||
68
packages/website/ts/components/portal/drawer_menu.tsx
Normal file
68
packages/website/ts/components/portal/drawer_menu.tsx
Normal file
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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'),
|
||||
);
|
||||
|
||||
19
packages/website/ts/utils/colors.ts
Normal file
19
packages/website/ts/utils/colors.ts
Normal file
@@ -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,
|
||||
};
|
||||
@@ -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();
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user