aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts/components/relayer_index
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2018-05-10 23:08:07 +0800
committerFabio Berger <me@fabioberger.com>2018-05-10 23:08:07 +0800
commitcd5f00ac4d41221c99eb8ce767e63e09a6de6a11 (patch)
tree2b1865b5fa6ef86965ea753c032ffaba48403921 /packages/website/ts/components/relayer_index
parent23c4027c83b9f30fad352615386b988084f8b39f (diff)
parentc64ad1af28ef116e210aafb3ea6ad2138361cd7c (diff)
downloaddexon-0x-contracts-cd5f00ac4d41221c99eb8ce767e63e09a6de6a11.tar
dexon-0x-contracts-cd5f00ac4d41221c99eb8ce767e63e09a6de6a11.tar.gz
dexon-0x-contracts-cd5f00ac4d41221c99eb8ce767e63e09a6de6a11.tar.bz2
dexon-0x-contracts-cd5f00ac4d41221c99eb8ce767e63e09a6de6a11.tar.lz
dexon-0x-contracts-cd5f00ac4d41221c99eb8ce767e63e09a6de6a11.tar.xz
dexon-0x-contracts-cd5f00ac4d41221c99eb8ce767e63e09a6de6a11.tar.zst
dexon-0x-contracts-cd5f00ac4d41221c99eb8ce767e63e09a6de6a11.zip
Merge branch 'development' into breakUp0xjs
* development: (38 commits) Add fallback image support to relayer grid tile Clear relayer grid state when fetching Configure the compiler to generate artifacts with deployedBytecode Implement loading and error state for relayer grid Fallback image for relayer grid tile Change relayer grid tile to link on header Display top tokens from backend Remove overflowZ property from portal Suggestions and fix bad merge Fix typo Only show untracked tokens Make wallet scrollable Add token flow Update The Ocean logo Fix artifacts paths Create an artifacts folder Introduce a var Add removeHexPrefix util method CHeck if ABI exists Improve the readability of the check for should compile ... # Conflicts: # .gitignore # packages/contracts/test/multi_sig_with_time_lock.ts # packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts # packages/contracts/util/artifacts.ts
Diffstat (limited to 'packages/website/ts/components/relayer_index')
-rw-r--r--packages/website/ts/components/relayer_index/relayer_grid_tile.tsx102
-rw-r--r--packages/website/ts/components/relayer_index/relayer_index.tsx70
-rw-r--r--packages/website/ts/components/relayer_index/relayer_top_tokens.tsx16
3 files changed, 119 insertions, 69 deletions
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 0b9b8165e..d88a59d15 100644
--- a/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx
+++ b/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx
@@ -12,37 +12,6 @@ export interface RelayerGridTileProps {
networkId: number;
}
-// TODO: Get top tokens from remote
-const topTokens = [
- {
- address: '0x1dad4783cf3fe3085c1426157ab175a6119a04ba',
- decimals: 18,
- iconUrl: '/images/token_icons/makerdao.png',
- isRegistered: true,
- isTracked: true,
- name: 'Maker DAO',
- symbol: 'MKR',
- },
- {
- address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
- decimals: 18,
- iconUrl: '/images/token_icons/melon.png',
- isRegistered: true,
- isTracked: true,
- name: 'Melon Token',
- symbol: 'MLN',
- },
- {
- address: '0xb18845c260f680d5b9d84649638813e342e4f8c9',
- decimals: 18,
- iconUrl: '/images/token_icons/augur.png',
- isRegistered: true,
- isTracked: true,
- name: 'Augur Reputation Token',
- symbol: 'REP',
- },
-];
-
const styles: Styles = {
root: {
backgroundColor: colors.white,
@@ -93,28 +62,63 @@ const styles: Styles = {
},
};
+const FALLBACK_IMG_SRC = '/images/landing/hero_chip_image.png';
+
export const RelayerGridTile: React.StatelessComponent<RelayerGridTileProps> = (props: RelayerGridTileProps) => {
const link = props.relayerInfo.appUrl || props.relayerInfo.url;
return (
- <a href={link} target="_blank" style={{ textDecoration: 'none' }}>
- <GridTile style={styles.root}>
- <div style={styles.innerDiv}>
- <img src={props.relayerInfo.headerImgUrl} style={styles.header} />
- <div style={styles.body}>
- <div className="py1" style={styles.relayerNameLabel}>
- {props.relayerInfo.name}
- </div>
- <div style={styles.dailyTradeVolumeLabel}>{props.relayerInfo.dailyTxnVolume}</div>
- <div className="py1" style={styles.subLabel}>
- Daily Trade Volume
- </div>
- <TopTokens tokens={topTokens} networkId={props.networkId} />
- <div className="py1" style={styles.subLabel}>
- Top tokens
- </div>
+ <GridTile style={styles.root}>
+ <div style={styles.innerDiv}>
+ <a href={link} target="_blank" style={{ textDecoration: 'none' }}>
+ <ImgWithFallback
+ src={props.relayerInfo.headerImgUrl}
+ fallbackSrc={FALLBACK_IMG_SRC}
+ style={styles.header}
+ />
+ </a>
+ <div style={styles.body}>
+ <div className="py1" style={styles.relayerNameLabel}>
+ {props.relayerInfo.name}
+ </div>
+ <div style={styles.dailyTradeVolumeLabel}>{props.relayerInfo.dailyTxnVolume}</div>
+ <div className="py1" style={styles.subLabel}>
+ Daily Trade Volume
+ </div>
+ <TopTokens tokens={props.relayerInfo.topTokens} networkId={props.networkId} />
+ <div className="py1" style={styles.subLabel}>
+ Top tokens
</div>
</div>
- </GridTile>
- </a>
+ </div>
+ </GridTile>
);
};
+
+interface ImgWithFallbackProps {
+ src?: string;
+ fallbackSrc: string;
+ style: React.CSSProperties;
+}
+interface ImgWithFallbackState {
+ imageLoadFailed: boolean;
+}
+class ImgWithFallback extends React.Component<ImgWithFallbackProps, ImgWithFallbackState> {
+ constructor(props: ImgWithFallbackProps) {
+ super(props);
+ this.state = {
+ imageLoadFailed: false,
+ };
+ }
+ public render() {
+ if (this.state.imageLoadFailed || _.isUndefined(this.props.src)) {
+ return <img src={this.props.fallbackSrc} style={this.props.style} />;
+ } else {
+ return <img src={this.props.src} onError={this._onError.bind(this)} style={this.props.style} />;
+ }
+ }
+ private _onError() {
+ this.setState({
+ imageLoadFailed: true,
+ });
+ }
+}
diff --git a/packages/website/ts/components/relayer_index/relayer_index.tsx b/packages/website/ts/components/relayer_index/relayer_index.tsx
index c1ab4227a..dffd0f83f 100644
--- a/packages/website/ts/components/relayer_index/relayer_index.tsx
+++ b/packages/website/ts/components/relayer_index/relayer_index.tsx
@@ -1,5 +1,7 @@
import { colors, Styles } from '@0xproject/react-shared';
import * as _ from 'lodash';
+import CircularProgress from 'material-ui/CircularProgress';
+import FlatButton from 'material-ui/FlatButton';
import { GridList } from 'material-ui/GridList';
import * as React from 'react';
@@ -32,9 +34,9 @@ const styles: Styles = {
},
};
-const CELL_HEIGHT = 260;
+const CELL_HEIGHT = 290;
const NUMBER_OF_COLUMNS = 4;
-const GRID_PADDING = 16;
+const GRID_PADDING = 20;
export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerIndexState> {
private _isUnmounted: boolean;
@@ -55,7 +57,24 @@ export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerInde
}
public render() {
const readyToRender = _.isUndefined(this.state.error) && !_.isUndefined(this.state.relayerInfos);
- if (readyToRender) {
+ if (!readyToRender) {
+ return (
+ <div className="col col-12" style={{ ...styles.root, height: '100%' }}>
+ <div
+ className="relative sm-px2 sm-pt2 sm-m1"
+ style={{ height: 122, top: '33%', transform: 'translateY(-50%)' }}
+ >
+ <div className="center pb2">
+ {_.isUndefined(this.state.error) ? (
+ <CircularProgress size={40} thickness={5} />
+ ) : (
+ <Retry onRetry={this._fetchRelayerInfosAsync.bind(this)} />
+ )}
+ </div>
+ </div>
+ </div>
+ );
+ } else {
return (
<div style={styles.root}>
<GridList
@@ -64,23 +83,22 @@ export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerInde
padding={GRID_PADDING}
style={styles.gridList}
>
- {this.state.relayerInfos.map((relayerInfo: WebsiteBackendRelayerInfo) => (
- <RelayerGridTile
- key={relayerInfo.name}
- relayerInfo={relayerInfo}
- networkId={this.props.networkId}
- />
+ {this.state.relayerInfos.map((relayerInfo: WebsiteBackendRelayerInfo, index) => (
+ <RelayerGridTile key={index} relayerInfo={relayerInfo} networkId={this.props.networkId} />
))}
</GridList>
</div>
);
- } else {
- // TODO: loading and error states with a scrolling container
- return null;
}
}
private async _fetchRelayerInfosAsync(): Promise<void> {
try {
+ if (!this._isUnmounted) {
+ this.setState({
+ relayerInfos: undefined,
+ error: undefined,
+ });
+ }
const relayerInfos = await backendClient.getRelayerInfosAsync();
if (!this._isUnmounted) {
this.setState({
@@ -96,3 +114,31 @@ export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerInde
}
}
}
+
+interface RetryProps {
+ onRetry: () => void;
+}
+const Retry = (props: RetryProps) => (
+ <div className="clearfix center" style={{ color: colors.black }}>
+ <div className="mx-auto inline-block align-middle" style={{ lineHeight: '44px', textAlign: 'center' }}>
+ <div className="h2" style={{ fontFamily: 'Roboto Mono' }}>
+ Something went wrong.
+ </div>
+ <div className="py3">
+ <FlatButton
+ label={'reload'}
+ backgroundColor={colors.black}
+ labelStyle={{
+ fontSize: 18,
+ fontFamily: 'Roboto Mono',
+ fontWeight: 'lighter',
+ color: colors.white,
+ textTransform: 'lowercase',
+ }}
+ style={{ width: 280, height: 62, borderRadius: 5 }}
+ onClick={props.onRetry}
+ />
+ </div>
+ </div>
+ </div>
+);
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 233590b78..db4d3a211 100644
--- a/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx
+++ b/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx
@@ -3,10 +3,10 @@ import * as _ from 'lodash';
import * as React from 'react';
import { TokenIcon } from 'ts/components/ui/token_icon';
-import { Token } from 'ts/types';
+import { WebsiteBackendTokenInfo } from 'ts/types';
export interface TopTokensProps {
- tokens: Token[];
+ tokens: WebsiteBackendTokenInfo[];
networkId: number;
}
@@ -23,17 +23,17 @@ const styles: Styles = {
export const TopTokens: React.StatelessComponent<TopTokensProps> = (props: TopTokensProps) => {
return (
<div className="flex">
- {_.map(props.tokens, (token: Token, index: number) => {
+ {_.map(props.tokens, (tokenInfo: WebsiteBackendTokenInfo, index: number) => {
const firstItemStyle = { ...styles.tokenLabel, ...styles.followingTokenLabel };
const style = index !== 0 ? firstItemStyle : styles.tokenLabel;
return (
<a
- key={token.address}
- href={tokenLinkFromToken(token, props.networkId)}
+ key={tokenInfo.address}
+ href={tokenLinkFromToken(tokenInfo, props.networkId)}
target="_blank"
style={style}
>
- {token.symbol}
+ {tokenInfo.symbol}
</a>
);
})}
@@ -41,6 +41,6 @@ export const TopTokens: React.StatelessComponent<TopTokensProps> = (props: TopTo
);
};
-function tokenLinkFromToken(token: Token, networkId: number) {
- return sharedUtils.getEtherScanLinkIfExists(token.address, networkId, EtherscanLinkSuffixes.Address);
+function tokenLinkFromToken(tokenInfo: WebsiteBackendTokenInfo, networkId: number) {
+ return sharedUtils.getEtherScanLinkIfExists(tokenInfo.address, networkId, EtherscanLinkSuffixes.Address);
}