Merge branch 'development' into v2-prototype

* development: (29 commits)
  Do not remove artifacts when running `clean`
  fix style errors
  Fix circular dependency
  Add my profile image to images
  Add myself to about page
  Add dogfood configs to website
  Revert to lerna:run lint
  Do lint sequentially
  Exclude monorepo-scripts from tslint as test
  Fix prettier
  Add hover state to top tokens
  Change to weekly txn volume
  Change minimum Node version to 6.12
  Document Node.js version requirement and add it to package.json
  Apply prettier to some files which were not formatted correctly
  Fix TSLint issues
  Fix TSLint issues
  Update ethereeumjs-testrpc to ganache-cli
  Fix infinite loop
  Add changelog entries for packages where executable binary exporting fixed
  ...

# Conflicts:
#	packages/contracts/package.json
#	packages/contracts/util/formatters.ts
#	packages/contracts/util/signed_order_utils.ts
#	packages/migrations/package.json
#	yarn.lock
This commit is contained in:
Fabio Berger
2018-05-16 16:18:47 +02:00
236 changed files with 2191 additions and 1184 deletions

View File

@@ -30,18 +30,16 @@ yarn install
### Initial setup
The **first** time you work with this package, you must build **all** packages within the monorepo. This is because packages that depend on other packages located inside this monorepo are symlinked when run from **within** the monorepo. This allows you to make changes across multiple packages without first publishing dependent packages to NPM. To build all packages, run the following from the monorepo root directory:
To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory:
```bash
yarn lerna:rebuild
PKG=@0xproject/website yarn build
```
### Run dev server
The the `website` root directory, run:
```bash
yarn dev
PKG=@0xproject/website yarn watch
```
Visit [0xproject.localhost:3572](http://0xproject.localhost:3572) in your browser.

View File

@@ -1,13 +1,17 @@
{
"name": "@0xproject/website",
"version": "0.0.32",
"engines": {
"node" : ">=6.12"
},
"private": true,
"description": "Website and 0x portal dapp",
"scripts": {
"build": "NODE_ENV=production webpack; exit 0;",
"clean": "shx rm -f public/bundle*",
"lint": "tslint --project . 'ts/**/*.ts' 'ts/**/*.tsx'",
"dev": "webpack-dev-server --content-base public --https",
"watch": "webpack-dev-server --content-base public --https",
"deploy_dogfood": "npm run build; aws s3 sync ./public/. s3://dogfood-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers",
"deploy_staging": "npm run build; aws s3 sync ./public/. s3://staging-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers",
"deploy_live": "npm run build; aws s3 sync ./public/. s3://0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers"
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -39,6 +39,7 @@ import {
BlockchainCallErrs,
BlockchainErrs,
ContractInstance,
Fill,
Order as PortalOrder,
Providers,
ProviderType,
@@ -88,7 +89,7 @@ export class Blockchain {
}
return providerNameIfExists;
}
private static async _getProviderAsync(injectedWeb3: Web3, networkIdIfExists: number) {
private static async _getProviderAsync(injectedWeb3: Web3, networkIdIfExists: number): Promise<Provider> {
const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
const publicNodeUrlsIfExistsForNetworkId = configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkIdIfExists];
const isPublicNodeAvailableForNetworkId = !_.isUndefined(publicNodeUrlsIfExistsForNetworkId);
@@ -137,7 +138,7 @@ export class Blockchain {
// tslint:disable-next-line:no-floating-promises
this._onPageLoadInitFireAndForgetAsync();
}
public async networkIdUpdatedFireAndForgetAsync(newNetworkId: number) {
public async networkIdUpdatedFireAndForgetAsync(newNetworkId: number): Promise<void> {
const isConnected = !_.isUndefined(newNetworkId);
if (!isConnected) {
this.networkId = newNetworkId;
@@ -147,17 +148,17 @@ export class Blockchain {
this.networkId = newNetworkId;
this._dispatcher.encounteredBlockchainError(BlockchainErrs.NoError);
await this.fetchTokenInformationAsync();
await this._rehydrateStoreWithContractEvents();
await this._rehydrateStoreWithContractEventsAsync();
}
}
public async userAddressUpdatedFireAndForgetAsync(newUserAddress: string) {
public async userAddressUpdatedFireAndForgetAsync(newUserAddress: string): Promise<void> {
if (this._userAddressIfExists !== newUserAddress) {
this._userAddressIfExists = newUserAddress;
await this.fetchTokenInformationAsync();
await this._rehydrateStoreWithContractEvents();
await this._rehydrateStoreWithContractEventsAsync();
}
}
public async nodeVersionUpdatedFireAndForgetAsync(nodeVersion: string) {
public async nodeVersionUpdatedFireAndForgetAsync(nodeVersion: string): Promise<void> {
if (this.nodeVersion !== nodeVersion) {
this.nodeVersion = nodeVersion;
}
@@ -174,13 +175,13 @@ export class Blockchain {
const path = this._ledgerSubprovider.getPath();
return path;
}
public updateLedgerDerivationPathIfExists(path: string) {
public updateLedgerDerivationPathIfExists(path: string): void {
if (_.isUndefined(this._ledgerSubprovider)) {
return; // noop
}
this._ledgerSubprovider.setPath(path);
}
public async updateProviderToLedgerAsync(networkId: number) {
public async updateProviderToLedgerAsync(networkId: number): Promise<void> {
utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
const isU2FSupported = await utils.isU2FSupportedAsync();
@@ -228,7 +229,7 @@ export class Blockchain {
this._blockchainWatcher.startEmittingNetworkConnectionAndUserBalanceState();
this._dispatcher.updateProviderType(ProviderType.Ledger);
}
public async updateProviderToInjectedAsync() {
public async updateProviderToInjectedAsync(): Promise<void> {
utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
if (_.isUndefined(this._cachedProvider)) {
@@ -367,7 +368,7 @@ export class Blockchain {
const unavailableTakerAmount = await this._zeroEx.exchange.getUnavailableTakerAmountAsync(orderHash);
return unavailableTakerAmount;
}
public getExchangeContractAddressIfExists() {
public getExchangeContractAddressIfExists(): string | undefined {
return this._zeroEx.exchange.getContractAddress();
}
public async validateFillOrderThrowIfInvalidAsync(
@@ -391,7 +392,7 @@ export class Blockchain {
const lowercaseAddress = address.toLowerCase();
return Web3Wrapper.isAddress(lowercaseAddress);
}
public async pollTokenBalanceAsync(token: Token) {
public async pollTokenBalanceAsync(token: Token): Promise<BigNumber> {
utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
const [currBalance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddressIfExists, token.address);
@@ -445,7 +446,7 @@ export class Blockchain {
this._dispatcher.updateECSignature(ecSignature);
return ecSignature;
}
public async mintTestTokensAsync(token: Token) {
public async mintTestTokensAsync(token: Token): Promise<void> {
utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
const mintableContract = await this._instantiateContractIfExistsAsync(MintableArtifacts, token.address);
@@ -489,7 +490,7 @@ export class Blockchain {
);
await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
}
public async doesContractExistAtAddressAsync(address: string) {
public async doesContractExistAtAddressAsync(address: string): Promise<boolean> {
const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(address);
return doesContractExist;
}
@@ -520,7 +521,7 @@ export class Blockchain {
}
return [balance, allowance];
}
public async getUserAccountsAsync() {
public async getUserAccountsAsync(): Promise<string[]> {
utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
const userAccountsIfExists = await this._zeroEx.getAvailableAddressesAsync();
return userAccountsIfExists;
@@ -528,14 +529,14 @@ export class Blockchain {
// HACK: When a user is using a Ledger, we simply dispatch the selected userAddress, which
// by-passes the web3Wrapper logic for updating the prevUserAddress. We therefore need to
// manually update it. This should only be called by the LedgerConfigDialog.
public updateWeb3WrapperPrevUserAddress(newUserAddress: string) {
public updateWeb3WrapperPrevUserAddress(newUserAddress: string): void {
this._blockchainWatcher.updatePrevUserAddress(newUserAddress);
}
public destroy() {
public destroy(): void {
this._blockchainWatcher.destroy();
this._stopWatchingExchangeLogFillEvents();
}
public async fetchTokenInformationAsync() {
public async fetchTokenInformationAsync(): Promise<void> {
utils.assert(
!_.isUndefined(this.networkId),
'Cannot call fetchTokenInformationAsync if disconnected from Ethereum node',
@@ -624,7 +625,7 @@ export class Blockchain {
private _doesUserAddressExist(): boolean {
return !_.isUndefined(this._userAddressIfExists);
}
private async _rehydrateStoreWithContractEvents() {
private async _rehydrateStoreWithContractEventsAsync(): Promise<void> {
// Ensure we are only ever listening to one set of events
this._stopWatchingExchangeLogFillEvents();
@@ -675,7 +676,7 @@ export class Blockchain {
},
);
}
private async _fetchHistoricalExchangeLogFillEventsAsync(indexFilterValues: IndexedFilterValues) {
private async _fetchHistoricalExchangeLogFillEventsAsync(indexFilterValues: IndexedFilterValues): Promise<void> {
utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
const fromBlock = tradeHistoryStorage.getFillsLatestBlock(this._userAddressIfExists, this.networkId);
@@ -697,7 +698,9 @@ export class Blockchain {
tradeHistoryStorage.addFillToUser(this._userAddressIfExists, this.networkId, fill);
}
}
private async _convertDecodedLogToFillAsync(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) {
private async _convertDecodedLogToFillAsync(
decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>,
): Promise<Fill> {
const args = decodedLog.args;
const blockTimestamp = await this._web3Wrapper.getBlockTimestampAsync(decodedLog.blockHash);
const fill = {
@@ -716,12 +719,12 @@ export class Blockchain {
};
return fill;
}
private _doesLogEventInvolveUser(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) {
private _doesLogEventInvolveUser(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>): boolean {
const args = decodedLog.args;
const isUserMakerOrTaker = args.maker === this._userAddressIfExists || args.taker === this._userAddressIfExists;
return isUserMakerOrTaker;
}
private _updateLatestFillsBlockIfNeeded(blockNumber: number) {
private _updateLatestFillsBlockIfNeeded(blockNumber: number): void {
utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
const isBlockPending = _.isNull(blockNumber);
@@ -762,7 +765,7 @@ export class Blockchain {
});
return tokenByAddress;
}
private async _onPageLoadInitFireAndForgetAsync() {
private async _onPageLoadInitFireAndForgetAsync(): Promise<void> {
await utils.onPageLoadAsync(); // wait for page to load
// Hack: We need to know the networkId the injectedWeb3 is connected to (if it is defined) in
@@ -807,9 +810,9 @@ export class Blockchain {
this._dispatcher.updateUserAddress(this._userAddressIfExists);
await this.fetchTokenInformationAsync();
this._blockchainWatcher.startEmittingNetworkConnectionAndUserBalanceState();
await this._rehydrateStoreWithContractEvents();
await this._rehydrateStoreWithContractEventsAsync();
}
private _updateProviderName(injectedWeb3: Web3) {
private _updateProviderName(injectedWeb3: Web3): void {
const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
const providerName = doesInjectedWeb3Exist
? Blockchain._getNameGivenProvider(injectedWeb3.currentProvider)
@@ -851,12 +854,12 @@ export class Blockchain {
}
}
}
private _showFlashMessageIfLedger() {
private _showFlashMessageIfLedger(): void {
if (!_.isUndefined(this._ledgerSubprovider)) {
this._dispatcher.showFlashMessage('Confirm the transaction on your Ledger Nano S');
}
}
private async _updateDefaultGasPriceAsync() {
private async _updateDefaultGasPriceAsync(): Promise<void> {
try {
const gasInfo = await backendClient.getGasInfoAsync();
const gasPriceInGwei = new BigNumber(gasInfo.average / 10);

View File

@@ -23,8 +23,8 @@ export class BlockchainWatcher {
this._shouldPollUserAddress = shouldPollUserAddress;
this._web3Wrapper = web3Wrapper;
}
public destroy() {
this._stopEmittingNetworkConnectionAndUserBalanceStateAsync();
public destroy(): void {
this._stopEmittingNetworkConnectionAndUserBalanceState();
// HACK: stop() is only available on providerEngine instances
const provider = this._web3Wrapper.getProvider();
if (!_.isUndefined((provider as any).stop)) {
@@ -32,10 +32,10 @@ export class BlockchainWatcher {
}
}
// This should only be called from the LedgerConfigDialog
public updatePrevUserAddress(userAddress: string) {
public updatePrevUserAddress(userAddress: string): void {
this._prevUserAddressIfExists = userAddress;
}
public startEmittingNetworkConnectionAndUserBalanceState() {
public startEmittingNetworkConnectionAndUserBalanceState(): void {
if (!_.isUndefined(this._watchNetworkAndBalanceIntervalId)) {
return; // we are already emitting the state
}
@@ -88,18 +88,18 @@ export class BlockchainWatcher {
5000,
(err: Error) => {
logUtils.log(`Watching network and balances failed: ${err.stack}`);
this._stopEmittingNetworkConnectionAndUserBalanceStateAsync();
this._stopEmittingNetworkConnectionAndUserBalanceState();
},
);
}
private async _updateUserWeiBalanceAsync(userAddress: string) {
private async _updateUserWeiBalanceAsync(userAddress: string): Promise<void> {
const balanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(userAddress);
if (!balanceInWei.eq(this._prevUserEtherBalanceInWei)) {
this._prevUserEtherBalanceInWei = balanceInWei;
this._dispatcher.updateUserWeiBalance(balanceInWei);
}
}
private _stopEmittingNetworkConnectionAndUserBalanceStateAsync() {
private _stopEmittingNetworkConnectionAndUserBalanceState(): void {
if (!_.isUndefined(this._watchNetworkAndBalanceIntervalId)) {
intervalUtils.clearAsyncExcludingInterval(this._watchNetworkAndBalanceIntervalId);
}

View File

@@ -18,7 +18,7 @@ interface BlockchainErrDialogProps {
}
export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProps, undefined> {
public render() {
public render(): React.ReactNode {
const dialogActions = [
<FlatButton
key="blockchainErrOk"
@@ -45,7 +45,7 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
</Dialog>
);
}
private _getTitle(hasWalletAddress: boolean) {
private _getTitle(hasWalletAddress: boolean): string {
if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) {
return '0x smart contracts not found';
} else if (!hasWalletAddress) {
@@ -58,7 +58,7 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
return 'Unexpected error';
}
}
private _renderExplanation(hasWalletAddress: boolean) {
private _renderExplanation(hasWalletAddress: boolean): React.ReactNode {
if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) {
return this._renderContractsNotDeployedExplanation();
} else if (!hasWalletAddress) {
@@ -71,7 +71,7 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
return this._renderUnexpectedErrorExplanation();
}
}
private _renderDisconnectedFromNode() {
private _renderDisconnectedFromNode(): React.ReactNode {
return (
<div>
You were disconnected from the backing Ethereum node. If using{' '}
@@ -86,7 +86,7 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
</div>
);
}
private _renderDefaultTokenNotInTokenRegistry() {
private _renderDefaultTokenNotInTokenRegistry(): React.ReactNode {
return (
<div>
The TokenRegistry deployed on your network does not contain the needed default tokens for 0x Portal to
@@ -96,10 +96,10 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
</div>
);
}
private _renderUnexpectedErrorExplanation() {
private _renderUnexpectedErrorExplanation(): React.ReactNode {
return <div>We encountered an unexpected error. Please try refreshing the page.</div>;
}
private _renderNoWalletFoundExplanation() {
private _renderNoWalletFoundExplanation(): React.ReactNode {
return (
<div>
<div>
@@ -137,7 +137,7 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
</div>
);
}
private _renderContractsNotDeployedExplanation() {
private _renderContractsNotDeployedExplanation(): React.ReactNode {
return (
<div>
<div>

View File

@@ -47,14 +47,14 @@ export class EthWethConversionDialog extends React.Component<
ethTokenBalance: new BigNumber(0),
};
}
public componentWillMount() {
public componentWillMount(): void {
// tslint:disable-next-line:no-floating-promises
this._fetchEthTokenBalanceAsync();
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this._isUnmounted = true;
}
public render() {
public render(): React.ReactNode {
const convertDialogActions = [
<FlatButton key="cancel" label="Cancel" onTouchTap={this._onCancel.bind(this)} />,
<FlatButton key="convert" label="Convert" primary={true} onTouchTap={this._onConvertClick.bind(this)} />,
@@ -72,7 +72,7 @@ export class EthWethConversionDialog extends React.Component<
</Dialog>
);
}
private _renderConversionDialogBody() {
private _renderConversionDialogBody(): React.ReactNode {
const explanation =
this.props.direction === Side.Deposit
? 'Convert your Ether into a tokenized, tradable form.'
@@ -137,7 +137,7 @@ export class EthWethConversionDialog extends React.Component<
</div>
);
}
private _renderCurrency(isWrappedVersion: boolean) {
private _renderCurrency(isWrappedVersion: boolean): React.ReactNode {
const name = isWrappedVersion ? 'Wrapped Ether' : 'Ether';
const iconUrl = isWrappedVersion ? '/images/token_icons/ether_erc20.png' : '/images/ether.png';
const symbol = isWrappedVersion ? 'WETH' : 'ETH';
@@ -155,18 +155,18 @@ export class EthWethConversionDialog extends React.Component<
</div>
);
}
private _onMaxClick() {
private _onMaxClick(): void {
this.setState({
value: this.state.ethTokenBalance,
});
}
private _onValueChange(isValid: boolean, amount?: BigNumber) {
private _onValueChange(isValid: boolean, amount?: BigNumber): void {
this.setState({
value: amount,
hasErrors: !isValid,
});
}
private _onConvertClick() {
private _onConvertClick(): void {
if (this.state.hasErrors) {
this.setState({
shouldShowIncompleteErrs: true,
@@ -179,13 +179,13 @@ export class EthWethConversionDialog extends React.Component<
this.props.onComplete(this.props.direction, value);
}
}
private _onCancel() {
private _onCancel(): void {
this.setState({
value: undefined,
});
this.props.onCancelled();
}
private async _fetchEthTokenBalanceAsync() {
private async _fetchEthTokenBalanceAsync(): Promise<void> {
const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress;
const [balance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(
userAddressIfExists,

View File

@@ -59,7 +59,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
preferredNetworkId: props.networkId,
};
}
public render() {
public render(): React.ReactNode {
const dialogActions = [
<FlatButton key="ledgerConnectCancel" label="Cancel" onTouchTap={this._onClose.bind(this)} />,
];
@@ -82,7 +82,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
</Dialog>
);
}
private _renderConnectStep() {
private _renderConnectStep(): React.ReactNode {
const networkIds = _.values(sharedConstants.NETWORK_ID_BY_NAME);
return (
<div>
@@ -122,7 +122,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
</div>
);
}
private _renderSelectAddressStep() {
private _renderSelectAddressStep(): React.ReactNode {
return (
<div>
<div>
@@ -159,7 +159,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
</div>
);
}
private _renderAddressTableRows() {
private _renderAddressTableRows(): React.ReactNode {
const rows = _.map(this.state.userAddresses, (userAddress: string, i: number) => {
const balanceInWei = this.state.addressBalances[i];
const addressTooltipId = `address-${userAddress}`;
@@ -189,7 +189,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
});
return rows;
}
private _onClose() {
private _onClose(): void {
this.setState({
connectionErrMsg: '',
stepIndex: LedgerSteps.CONNECT,
@@ -197,7 +197,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
const isOpen = false;
this.props.toggleDialogFn(isOpen);
}
private _onAddressSelected(selectedRowIndexes: number[]) {
private _onAddressSelected(selectedRowIndexes: number[]): void {
const selectedRowIndex = selectedRowIndexes[0];
const selectedAddress = this.state.userAddresses[selectedRowIndex];
const selectAddressBalance = this.state.addressBalances[selectedRowIndex];
@@ -228,7 +228,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
}
return didSucceed;
}
private async _fetchAddressesAndBalancesAsync() {
private async _fetchAddressesAndBalancesAsync(): Promise<boolean> {
let userAddresses: string[];
const addressBalances: BigNumber[] = [];
try {
@@ -250,7 +250,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
});
return true;
}
private _onDerivationPathChanged(e: any, derivationPath: string) {
private _onDerivationPathChanged(e: any, derivationPath: string): void {
let derivationErrMsg = '';
if (!_.startsWith(derivationPath, VALID_ETHEREUM_DERIVATION_PATH_PREFIX)) {
derivationErrMsg = 'Must be valid Ethereum path.';
@@ -261,7 +261,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
derivationErrMsg,
});
}
private async _onConnectLedgerClickAsync() {
private async _onConnectLedgerClickAsync(): Promise<boolean> {
const isU2FSupported = await utils.isU2FSupportedAsync();
if (!isU2FSupported) {
logUtils.log(`U2F not supported in this browser`);
@@ -295,7 +295,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
}
return userAddresses;
}
private _onSelectedNetworkUpdated(e: any, index: number, networkId: number) {
private _onSelectedNetworkUpdated(e: any, index: number, networkId: number): void {
this.setState({
preferredNetworkId: networkId,
});

View File

@@ -8,7 +8,7 @@ interface PortalDisclaimerDialogProps {
onToggleDialog: () => void;
}
export function PortalDisclaimerDialog(props: PortalDisclaimerDialogProps) {
export const PortalDisclaimerDialog = (props: PortalDisclaimerDialogProps) => {
return (
<Dialog
title="0x Portal Disclaimer"
@@ -33,4 +33,4 @@ export function PortalDisclaimerDialog(props: PortalDisclaimerDialogProps) {
</div>
</Dialog>
);
}
};

View File

@@ -35,7 +35,7 @@ export class SendDialog extends React.Component<SendDialogProps, SendDialogState
isAmountValid: false,
};
}
public render() {
public render(): React.ReactNode {
const transferDialogActions = [
<FlatButton key="cancelTransfer" label="Cancel" onTouchTap={this._onCancel.bind(this)} />,
<FlatButton
@@ -57,7 +57,7 @@ export class SendDialog extends React.Component<SendDialogProps, SendDialogState
</Dialog>
);
}
private _renderSendDialogBody() {
private _renderSendDialogBody(): React.ReactNode {
return (
<div className="mx-auto" style={{ maxWidth: 300 }}>
<div style={{ height: 80 }}>
@@ -86,19 +86,19 @@ export class SendDialog extends React.Component<SendDialogProps, SendDialogState
</div>
);
}
private _onRecipientChange(recipient?: string) {
private _onRecipientChange(recipient?: string): void {
this.setState({
shouldShowIncompleteErrs: false,
recipient,
});
}
private _onValueChange(isValid: boolean, amount?: BigNumber) {
private _onValueChange(isValid: boolean, amount?: BigNumber): void {
this.setState({
isAmountValid: isValid,
value: amount,
});
}
private _onSendClick() {
private _onSendClick(): void {
if (this._hasErrors()) {
this.setState({
shouldShowIncompleteErrs: true,
@@ -112,13 +112,13 @@ export class SendDialog extends React.Component<SendDialogProps, SendDialogState
this.props.onComplete(this.state.recipient, value);
}
}
private _onCancel() {
private _onCancel(): void {
this.setState({
value: undefined,
});
this.props.onCancelled();
}
private _hasErrors() {
private _hasErrors(): boolean {
return _.isUndefined(this.state.recipient) || _.isUndefined(this.state.value) || !this.state.isAmountValid;
}
}

View File

@@ -33,7 +33,7 @@ export class TrackTokenConfirmationDialog extends React.Component<
isAddingTokenToTracked: false,
};
}
public render() {
public render(): React.ReactNode {
const tokens = this.props.tokens;
return (
<Dialog
@@ -66,7 +66,7 @@ export class TrackTokenConfirmationDialog extends React.Component<
</Dialog>
);
}
private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean) {
private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean): Promise<void> {
if (!didUserAcceptTracking) {
this.props.onToggleDialog(didUserAcceptTracking);
return;

View File

@@ -9,7 +9,7 @@ interface U2fNotSupportedDialogProps {
onToggleDialog: () => void;
}
export function U2fNotSupportedDialog(props: U2fNotSupportedDialogProps) {
export const U2fNotSupportedDialog = (props: U2fNotSupportedDialogProps) => {
return (
<Dialog
title="U2F Not Supported"
@@ -43,4 +43,4 @@ export function U2fNotSupportedDialog(props: U2fNotSupportedDialogProps) {
</div>
</Dialog>
);
}
};

View File

@@ -8,7 +8,7 @@ interface WrappedEthSectionNoticeDialogProps {
onToggleDialog: () => void;
}
export function WrappedEthSectionNoticeDialog(props: WrappedEthSectionNoticeDialogProps) {
export const WrappedEthSectionNoticeDialog = (props: WrappedEthSectionNoticeDialogProps) => {
return (
<Dialog
title="Dedicated Wrapped Ether Section"
@@ -30,4 +30,4 @@ export function WrappedEthSectionNoticeDialog(props: WrappedEthSectionNoticeDial
</div>
</Dialog>
);
}
};

View File

@@ -13,7 +13,7 @@ interface NetworkDropDownProps {
interface NetworkDropDownState {}
export class NetworkDropDown extends React.Component<NetworkDropDownProps, NetworkDropDownState> {
public render() {
public render(): React.ReactNode {
return (
<div className="mx-auto" style={{ width: 120 }}>
<DropDownMenu value={this.props.selectedNetworkId} onChange={this.props.updateSelectedNetwork}>
@@ -22,7 +22,7 @@ export class NetworkDropDown extends React.Component<NetworkDropDownProps, Netwo
</div>
);
}
private _renderDropDownItems() {
private _renderDropDownItems(): React.ReactNode {
const items = _.map(this.props.avialableNetworkIds, networkId => {
const networkName = sharedConstants.NETWORK_NAME_BY_ID[networkId];
const primaryText = (

View File

@@ -46,7 +46,7 @@ export class EthWethConversionButton extends React.Component<
isEthConversionHappening: false,
};
}
public render() {
public render(): React.ReactNode {
const labelStyle = this.state.isEthConversionHappening ? { fontSize: 10 } : {};
let callToActionLabel;
let inProgressLabel;
@@ -81,12 +81,12 @@ export class EthWethConversionButton extends React.Component<
</div>
);
}
private _toggleConversionDialog() {
private _toggleConversionDialog(): void {
this.setState({
isEthConversionDialogVisible: !this.state.isEthConversionDialogVisible,
});
}
private async _onConversionAmountSelectedAsync(direction: Side, value: BigNumber) {
private async _onConversionAmountSelectedAsync(direction: Side, value: BigNumber): Promise<void> {
this.setState({
isEthConversionHappening: true,
});

View File

@@ -65,7 +65,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
},
};
}
public componentWillReceiveProps(nextProps: EthWrappersProps) {
public componentWillReceiveProps(nextProps: EthWrappersProps): void {
if (
nextProps.userAddress !== this.props.userAddress ||
nextProps.networkId !== this.props.networkId ||
@@ -75,15 +75,15 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
this._fetchWETHStateAsync();
}
}
public componentDidMount() {
public componentDidMount(): void {
window.scrollTo(0, 0);
// tslint:disable-next-line:no-floating-promises
this._fetchWETHStateAsync();
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this._isUnmounted = true;
}
public render() {
public render(): React.ReactNode {
const etherToken = this._getEthToken();
const wethBalance = ZeroEx.toUnitAmount(this.state.ethTokenState.balance, constants.DECIMAL_PLACES_ETH);
const isBidirectional = true;
@@ -222,7 +222,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
</div>
);
}
private _renderActionColumnTitle(isBidirectional: boolean) {
private _renderActionColumnTitle(isBidirectional: boolean): React.ReactNode {
let iconClass = 'zmdi-long-arrow-right';
let leftSymbol = 'WETH';
let rightSymbol = 'ETH';
@@ -241,7 +241,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
</div>
);
}
private _renderOutdatedWeths(etherToken: Token, etherTokenState: TokenState) {
private _renderOutdatedWeths(etherToken: Token, etherTokenState: TokenState): React.ReactNode {
const rows = _.map(
configs.OUTDATED_WRAPPED_ETHERS,
(outdatedWETHByNetworkId: OutdatedWrappedEtherByNetworkId) => {
@@ -313,7 +313,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
);
return rows;
}
private _renderTokenLink(tokenLabel: React.ReactNode, etherscanUrl: string) {
private _renderTokenLink(tokenLabel: React.ReactNode, etherscanUrl: string): React.ReactNode {
return (
<span>
{_.isUndefined(etherscanUrl) ? (
@@ -326,7 +326,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
</span>
);
}
private _renderToken(name: string, address: string, imgPath: string) {
private _renderToken(name: string, address: string, imgPath: string): React.ReactNode {
const tooltipId = `tooltip-${address}`;
return (
<div className="flex">
@@ -340,7 +340,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
</div>
);
}
private async _onOutdatedConversionSuccessfulAsync(outdatedWETHAddress: string) {
private async _onOutdatedConversionSuccessfulAsync(outdatedWETHAddress: string): Promise<void> {
const currentOutdatedWETHState = this.state.outdatedWETHStateByAddress[outdatedWETHAddress];
this.setState({
outdatedWETHStateByAddress: {
@@ -368,7 +368,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
},
});
}
private async _fetchWETHStateAsync() {
private async _fetchWETHStateAsync(): Promise<void> {
const tokens = _.values(this.props.tokenByAddress);
const wethToken = _.find(tokens, token => token.symbol === 'WETH');
const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress;
@@ -414,12 +414,12 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
);
return outdatedWETHAddresses;
}
private _getEthToken() {
private _getEthToken(): Token {
const tokens = _.values(this.props.tokenByAddress);
const etherToken = _.find(tokens, { symbol: 'WETH' });
return etherToken;
}
private async _refetchEthTokenStateAsync() {
private async _refetchEthTokenStateAsync(): Promise<void> {
const etherToken = this._getEthToken();
const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress;
const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(

View File

@@ -82,19 +82,19 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
tokensToTrack: [],
};
}
public componentWillMount() {
public componentWillMount(): void {
if (!_.isEmpty(this.state.orderJSON)) {
// tslint:disable-next-line:no-floating-promises
this._validateFillOrderFireAndForgetAsync(this.state.orderJSON);
}
}
public componentDidMount() {
public componentDidMount(): void {
window.scrollTo(0, 0);
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this._isUnmounted = true;
}
public render() {
public render(): React.ReactNode {
return (
<div className="clearfix lg-px4 md-px4 sm-px2" style={{ minHeight: 600 }}>
<h3>Fill an order</h3>
@@ -159,7 +159,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
</div>
);
}
private _renderOrderJsonNotices() {
private _renderOrderJsonNotices(): React.ReactNode {
return (
<div>
{!_.isUndefined(this.props.initialOrder) &&
@@ -177,7 +177,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
</div>
);
}
private _renderVisualOrder() {
private _renderVisualOrder(): React.ReactNode {
const takerTokenAddress = this.state.parsedOrder.signedOrder.takerTokenAddress;
const takerToken = this.props.tokenByAddress[takerTokenAddress];
const orderTakerAmount = new BigNumber(this.state.parsedOrder.signedOrder.takerTokenAmount);
@@ -306,7 +306,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
</div>
);
}
private _renderFillSuccessMsg() {
private _renderFillSuccessMsg(): React.ReactNode {
return (
<div>
Order successfully filled. See the trade details in your{' '}
@@ -316,10 +316,10 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
</div>
);
}
private _renderCancelSuccessMsg() {
private _renderCancelSuccessMsg(): React.ReactNode {
return <div>Order successfully cancelled.</div>;
}
private _onFillOrderClick() {
private _onFillOrderClick(): void {
if (!this.state.isMakerTokenAddressInRegistry || !this.state.isTakerTokenAddressInRegistry) {
this.setState({
isFillWarningDialogOpen: true,
@@ -329,7 +329,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
this._onFillOrderClickFireAndForgetAsync();
}
}
private _onFillWarningClosed(didUserCancel: boolean) {
private _onFillWarningClosed(didUserCancel: boolean): void {
this.setState({
isFillWarningDialogOpen: false,
});
@@ -338,10 +338,10 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
this._onFillOrderClickFireAndForgetAsync();
}
}
private _onFillAmountChange(isValid: boolean, amount?: BigNumber) {
private _onFillAmountChange(isValid: boolean, amount?: BigNumber): void {
this.props.dispatcher.updateOrderFillAmount(amount);
}
private _onFillOrderJSONChanged(event: any) {
private _onFillOrderJSONChanged(event: any): void {
const orderJSON = event.target.value;
this.setState({
didOrderValidationRun: _.isEmpty(orderJSON) && _.isEmpty(this.state.orderJSONErrMsg),
@@ -350,7 +350,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
// tslint:disable-next-line:no-floating-promises
this._validateFillOrderFireAndForgetAsync(orderJSON);
}
private async _checkForUntrackedTokensAndAskToAdd() {
private async _checkForUntrackedTokensAndAskToAddAsync(): Promise<void> {
if (!_.isEmpty(this.state.orderJSONErrMsg)) {
return;
}
@@ -396,7 +396,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
});
}
}
private async _validateFillOrderFireAndForgetAsync(orderJSON: string) {
private async _validateFillOrderFireAndForgetAsync(orderJSON: string): Promise<void> {
let orderJSONErrMsg = '';
let parsedOrder: Order;
let orderHash: string;
@@ -491,7 +491,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
unavailableTakerAmount,
});
await this._checkForUntrackedTokensAndAskToAdd();
await this._checkForUntrackedTokensAndAskToAddAsync();
}
private async _onFillOrderClickFireAndForgetAsync(): Promise<void> {
if (this.props.blockchainErr !== BlockchainErrs.NoError || _.isEmpty(this.props.userAddress)) {
@@ -650,7 +650,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
const roundedUnitAmount = Math.round(unitAmount.toNumber() * 100000) / 100000;
return roundedUnitAmount;
}
private _onToggleTrackConfirmDialog(didConfirmTokenTracking: boolean) {
private _onToggleTrackConfirmDialog(didConfirmTokenTracking: boolean): void {
if (!didConfirmTokenTracking) {
this.setState({
orderJSON: '',

View File

@@ -19,7 +19,7 @@ interface FillOrderJSONProps {
interface FillOrderJSONState {}
export class FillOrderJSON extends React.Component<FillOrderJSONProps, FillOrderJSONState> {
public render() {
public render(): React.ReactNode {
const tokenAddresses = _.keys(this.props.tokenByAddress);
const exchangeContract = this.props.blockchain.getExchangeContractAddressIfExists();
const hintSideToAssetToken = {

View File

@@ -8,7 +8,7 @@ interface FillWarningDialogProps {
onToggleDialog: (didUserCancel: boolean) => void;
}
export function FillWarningDialog(props: FillWarningDialogProps) {
export const FillWarningDialog = (props: FillWarningDialogProps) => {
const didCancel = true;
return (
<Dialog
@@ -42,4 +42,4 @@ export function FillWarningDialog(props: FillWarningDialogProps) {
</div>
</Dialog>
);
}
};

View File

@@ -16,7 +16,7 @@ interface TokenSendCompletedProps {
interface TokenSendCompletedState {}
export class TokenSendCompleted extends React.Component<TokenSendCompletedProps, TokenSendCompletedState> {
public render() {
public render(): React.ReactNode {
const etherScanLink = !_.isUndefined(this.props.etherScanLinkIfExists) && (
<a style={{ color: colors.white }} href={`${this.props.etherScanLinkIfExists}`} target="_blank">
Verify on Etherscan

View File

@@ -9,7 +9,7 @@ interface TransactionSubmittedProps {
interface TransactionSubmittedState {}
export class TransactionSubmitted extends React.Component<TransactionSubmittedProps, TransactionSubmittedState> {
public render() {
public render(): React.ReactNode {
if (_.isUndefined(this.props.etherScanLinkIfExists)) {
return <div>Transaction submitted to the network</div>;
} else {

View File

@@ -50,7 +50,7 @@ export class Footer extends React.Component<FooterProps, FooterState> {
selectedLanguage: props.translate.getLanguage(),
};
}
public render() {
public render(): React.ReactNode {
const menuItemsBySection: MenuItemsBySection = {
[Key.Documentation]: [
{
@@ -180,14 +180,14 @@ export class Footer extends React.Component<FooterProps, FooterState> {
</div>
);
}
private _renderIcon(fileName: string) {
private _renderIcon(fileName: string): React.ReactNode {
return (
<div style={{ height: ICON_DIMENSION, width: ICON_DIMENSION }}>
<img src={`/images/social/${fileName}`} style={{ width: ICON_DIMENSION }} />
</div>
);
}
private _renderMenuItem(item: FooterMenuItem) {
private _renderMenuItem(item: FooterMenuItem): React.ReactNode {
const titleToIcon: { [title: string]: string } = {
[this.props.translate.get(Key.RocketChat, Deco.Cap)]: 'rocketchat.png',
[this.props.translate.get(Key.Blog, Deco.Cap)]: 'medium.png',
@@ -222,7 +222,7 @@ export class Footer extends React.Component<FooterProps, FooterState> {
</div>
);
}
private _renderHeader(key: Key) {
private _renderHeader(key: Key): React.ReactNode {
const headerStyle = {
color: colors.grey400,
letterSpacing: 2,
@@ -235,7 +235,7 @@ export class Footer extends React.Component<FooterProps, FooterState> {
</div>
);
}
private _updateLanguage(e: any, index: number, value: Language) {
private _updateLanguage(e: any, index: number, value: Language): void {
this.setState({
selectedLanguage: value,
});

View File

@@ -79,7 +79,7 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
},
};
}
public render() {
public render(): React.ReactNode {
const dialogConfigs: DialogConfigs = this._dialogConfigsByAssetView[this.state.assetView];
return (
<Dialog
@@ -102,7 +102,7 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
</Dialog>
);
}
private _renderConfirmTrackToken() {
private _renderConfirmTrackToken(): React.ReactNode {
const token = this.props.tokenByAddress[this.state.chosenTrackTokenAddress];
return (
<TrackTokenConfirmation
@@ -113,7 +113,7 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
/>
);
}
private _renderAssetPicker() {
private _renderAssetPicker(): React.ReactNode {
return (
<div
className="clearfix flex flex-wrap"
@@ -128,7 +128,7 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
</div>
);
}
private _renderGridTiles() {
private _renderGridTiles(): React.ReactNode {
let isHovered;
let tileStyles;
const gridTiles = _.map(this.props.tokenByAddress, (token: Token, address: string) => {
@@ -195,19 +195,19 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
}
return gridTiles;
}
private _onToggleHover(address: string, isHovered: boolean) {
private _onToggleHover(address: string, isHovered: boolean): void {
const hoveredAddress = isHovered ? address : undefined;
this.setState({
hoveredAddress,
});
}
private _onCloseDialog() {
private _onCloseDialog(): void {
this.setState({
assetView: AssetViews.ASSET_PICKER,
});
this.props.onTokenChosen(this.props.currentTokenAddress);
}
private _onChooseToken(tokenAddress: string) {
private _onChooseToken(tokenAddress: string): void {
const token = this.props.tokenByAddress[tokenAddress];
if (token.isTracked) {
this.props.onTokenChosen(tokenAddress);
@@ -218,12 +218,12 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
});
}
}
private _onCustomAssetChosen() {
private _onCustomAssetChosen(): void {
this.setState({
assetView: AssetViews.NEW_TOKEN_FORM,
});
}
private _onNewTokenSubmitted(newToken: Token) {
private _onNewTokenSubmitted(newToken: Token): void {
trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newToken);
this.props.dispatcher.addTokenToTokenByAddress(newToken);
this.setState({
@@ -231,7 +231,7 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
});
this.props.onTokenChosen(newToken.address);
}
private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean) {
private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean): Promise<void> {
if (!didUserAcceptTracking) {
this.setState({
isAddingTokenToTracked: false,

View File

@@ -63,10 +63,10 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
signingState: SigningState.UNSIGNED,
};
}
public componentDidMount() {
public componentDidMount(): void {
window.scrollTo(0, 0);
}
public render() {
public render(): React.ReactNode {
const dispatcher = this.props.dispatcher;
const depositTokenAddress = this.props.sideToAssetToken[Side.Deposit].address;
const depositToken = this.props.tokenByAddress[depositTokenAddress];
@@ -214,13 +214,13 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
</div>
);
}
private _onTokenAmountChange(token: Token, side: Side, isValid: boolean, amount?: BigNumber) {
private _onTokenAmountChange(token: Token, side: Side, isValid: boolean, amount?: BigNumber): void {
this.props.dispatcher.updateChosenAssetToken(side, {
address: token.address,
amount,
});
}
private _onCloseOrderJSONDialog() {
private _onCloseOrderJSONDialog(): void {
// Upon closing the order JSON dialog, we update the orderSalt stored in the Redux store
// with a new value so that if a user signs the identical order again, the newly signed
// orderHash will not collide with the previously generated orderHash.

View File

@@ -42,7 +42,7 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
decimalsErrText: '',
};
}
public render() {
public render(): React.ReactNode {
return (
<div className="mx-auto pb2" style={{ width: 256 }}>
<div>
@@ -96,7 +96,7 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
</div>
);
}
private async _onAddNewTokenClickAsync() {
private async _onAddNewTokenClickAsync(): Promise<void> {
// Trigger validation of name and symbol
this._onTokenNameChanged(undefined, this.state.name);
this._onTokenSymbolChanged(undefined, this.state.symbol);
@@ -152,7 +152,7 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
};
this.props.onNewTokenSubmitted(newToken);
}
private _onTokenNameChanged(e: any, name: string) {
private _onTokenNameChanged(e: any, name: string): void {
let nameErrText = '';
const maxLength = 30;
const tokens = _.values(this.props.tokenByAddress);
@@ -173,7 +173,7 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
nameErrText,
});
}
private _onTokenSymbolChanged(e: any, symbol: string) {
private _onTokenSymbolChanged(e: any, symbol: string): void {
let symbolErrText = '';
const maxLength = 5;
const tokens = _.values(this.props.tokenByAddress);
@@ -193,7 +193,7 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
symbolErrText,
});
}
private _onTokenDecimalsChanged(e: any, decimals: string) {
private _onTokenDecimalsChanged(e: any, decimals: string): void {
let decimalsErrText = '';
const maxLength = 2;
if (decimals === '') {
@@ -209,20 +209,20 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
decimalsErrText,
});
}
private _onTokenAddressChanged(address?: string) {
private _onTokenAddressChanged(address?: string): void {
if (!_.isUndefined(address)) {
this.setState({
address,
});
}
}
private _isValidName(input: string) {
private _isValidName(input: string): boolean {
return /^[a-z0-9 ]+$/i.test(input);
}
private _isInteger(input: string) {
private _isInteger(input: string): boolean {
return /^[0-9]+$/i.test(input);
}
private _isAlphanumeric(input: string) {
private _isAlphanumeric(input: string): boolean {
return /^[a-zA-Z0-9]+$/i.test(input);
}
}

View File

@@ -29,14 +29,14 @@ export class AddressInput extends React.Component<AddressInputProps, AddressInpu
errMsg: '',
};
}
public componentWillReceiveProps(nextProps: AddressInputProps) {
public componentWillReceiveProps(nextProps: AddressInputProps): void {
if (nextProps.shouldShowIncompleteErrs && this.props.isRequired && this.state.address === '') {
this.setState({
errMsg: 'Address is required',
});
}
}
public render() {
public render(): React.ReactNode {
const label = this.props.isRequired ? <RequiredLabel label={this.props.label} /> : this.props.label;
const labelDisplay = this.props.shouldHideLabel ? 'hidden' : 'block';
const hintText = this.props.hintText ? this.props.hintText : '';
@@ -57,7 +57,7 @@ export class AddressInput extends React.Component<AddressInputProps, AddressInpu
</div>
);
}
private _onOrderTakerAddressUpdated(e: any) {
private _onOrderTakerAddressUpdated(e: any): void {
const address = e.target.value.toLowerCase();
const isValidAddress = addressUtils.isAddress(address) || address === '';
const errMsg = isValidAddress ? '' : 'Invalid ethereum address';

View File

@@ -63,7 +63,7 @@ export class AllowanceToggle extends React.Component<AllowanceToggleProps, Allow
prevAllowance: props.tokenState.allowance,
};
}
public componentWillReceiveProps(nextProps: AllowanceToggleProps) {
public componentWillReceiveProps(nextProps: AllowanceToggleProps): void {
if (!nextProps.tokenState.allowance.eq(this.state.prevAllowance)) {
this.setState({
isSpinnerVisible: false,
@@ -71,7 +71,7 @@ export class AllowanceToggle extends React.Component<AllowanceToggleProps, Allow
});
}
}
public render() {
public render(): React.ReactNode {
return (
<div className="flex">
<div>
@@ -128,7 +128,7 @@ export class AllowanceToggle extends React.Component<AllowanceToggleProps, Allow
await errorReporter.reportAsync(err);
}
}
private _isAllowanceSet() {
private _isAllowanceSet(): boolean {
return !this.props.tokenState.allowance.eq(0);
}
}

View File

@@ -46,7 +46,7 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
amountString,
};
}
public componentWillReceiveProps(nextProps: BalanceBoundedInputProps) {
public componentWillReceiveProps(nextProps: BalanceBoundedInputProps): void {
if (nextProps === this.props) {
return;
}
@@ -76,7 +76,7 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
});
}
}
public render() {
public render(): React.ReactNode {
let errorText;
if (this.props.shouldShowErrs) {
errorText =
@@ -104,7 +104,7 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
/>
);
}
private _onValueChange(e: any, amountString: string) {
private _onValueChange(e: any, amountString: string): void {
const errMsg = this._validate(amountString, this.props.balance);
this.setState(
{
@@ -135,7 +135,7 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
const errMsg = _.isUndefined(this.props.validate) ? undefined : this.props.validate(amount);
return errMsg;
}
private _renderIncreaseBalanceLink() {
private _renderIncreaseBalanceLink(): React.ReactNode {
if (this.props.shouldHideVisitBalancesLink) {
return null;
}

View File

@@ -29,7 +29,7 @@ export class EthAmountInput extends React.Component<EthAmountInputProps, EthAmou
shouldShowUnderline: true,
style: { height: 63 },
};
public render() {
public render(): React.ReactNode {
const amount = this.props.amount
? ZeroEx.toUnitAmount(this.props.amount, constants.DECIMAL_PLACES_ETH)
: undefined;
@@ -52,7 +52,7 @@ export class EthAmountInput extends React.Component<EthAmountInputProps, EthAmou
</div>
);
}
private _onChange(isValid: boolean, amount?: BigNumber) {
private _onChange(isValid: boolean, amount?: BigNumber): void {
const baseUnitAmountIfExists = _.isUndefined(amount)
? undefined
: ZeroEx.toBaseUnitAmount(amount, constants.DECIMAL_PLACES_ETH);

View File

@@ -30,7 +30,7 @@ export class ExpirationInput extends React.Component<ExpirationInputProps, Expir
timeMoment: didUserSetExpiry ? expirationMoment : undefined,
};
}
public render() {
public render(): React.ReactNode {
const date = this.state.dateMoment ? this.state.dateMoment.toDate() : undefined;
const time = this.state.timeMoment ? this.state.timeMoment.toDate() : undefined;
return (
@@ -72,7 +72,7 @@ export class ExpirationInput extends React.Component<ExpirationInputProps, Expir
.startOf('day')
.isBefore(this._earliestPickableMoment);
}
private _clearDates() {
private _clearDates(): void {
this.setState({
dateMoment: undefined,
timeMoment: undefined,
@@ -80,7 +80,7 @@ export class ExpirationInput extends React.Component<ExpirationInputProps, Expir
const defaultDateTime = utils.initialOrderExpiryUnixTimestampSec();
this.props.updateOrderExpiry(defaultDateTime);
}
private _onDateChanged(e: any, date: Date) {
private _onDateChanged(e: any, date: Date): void {
const dateMoment = moment(date);
this.setState({
dateMoment,
@@ -88,7 +88,7 @@ export class ExpirationInput extends React.Component<ExpirationInputProps, Expir
const timestamp = utils.convertToUnixTimestampSeconds(dateMoment, this.state.timeMoment);
this.props.updateOrderExpiry(timestamp);
}
private _onTimeChanged(e: any, time: Date) {
private _onTimeChanged(e: any, time: Date): void {
const timeMoment = moment(time);
this.setState({
timeMoment,

View File

@@ -27,7 +27,7 @@ interface HashInputProps {
interface HashInputState {}
export class HashInput extends React.Component<HashInputProps, HashInputState> {
public render() {
public render(): React.ReactNode {
const msgHashHex = this.props.blockchainIsLoaded ? this._generateMessageHashHex() : '';
return (
<div>
@@ -40,7 +40,7 @@ export class HashInput extends React.Component<HashInputProps, HashInputState> {
</div>
);
}
private _generateMessageHashHex() {
private _generateMessageHashHex(): string {
const exchangeContractAddress = this.props.blockchain.getExchangeContractAddressIfExists();
const hashData = this.props.hashData;
const order: Order = {

View File

@@ -23,7 +23,7 @@ export class IdenticonAddressInput extends React.Component<IdenticonAddressInput
address: props.initialAddress,
};
}
public render() {
public render(): React.ReactNode {
const label = this.props.isRequired ? <RequiredLabel label={this.props.label} /> : this.props.label;
return (
<div className="relative" style={{ width: '100%' }}>

View File

@@ -52,14 +52,14 @@ export class TokenAmountInput extends React.Component<TokenAmountInputProps, Tok
isBalanceAndAllowanceLoaded: false,
};
}
public componentWillMount() {
public componentWillMount(): void {
// tslint:disable-next-line:no-floating-promises
this._fetchBalanceAndAllowanceAsync(this.props.token.address, this.props.userAddress);
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this._isUnmounted = true;
}
public componentWillReceiveProps(nextProps: TokenAmountInputProps) {
public componentWillReceiveProps(nextProps: TokenAmountInputProps): void {
if (
nextProps.userAddress !== this.props.userAddress ||
nextProps.networkId !== this.props.networkId ||
@@ -70,7 +70,7 @@ export class TokenAmountInput extends React.Component<TokenAmountInputProps, Tok
this._fetchBalanceAndAllowanceAsync(nextProps.token.address, nextProps.userAddress);
}
}
public render() {
public render(): React.ReactNode {
const amount = this.props.amount
? ZeroEx.toUnitAmount(this.props.amount, this.props.token.decimals)
: undefined;
@@ -98,7 +98,7 @@ export class TokenAmountInput extends React.Component<TokenAmountInputProps, Tok
</div>
);
}
private _onChange(isValid: boolean, amount?: BigNumber) {
private _onChange(isValid: boolean, amount?: BigNumber): void {
let baseUnitAmount;
if (!_.isUndefined(amount)) {
baseUnitAmount = ZeroEx.toBaseUnitAmount(amount, this.props.token.decimals);
@@ -122,7 +122,7 @@ export class TokenAmountInput extends React.Component<TokenAmountInputProps, Tok
return undefined;
}
}
private async _fetchBalanceAndAllowanceAsync(tokenAddress: string, userAddress: string) {
private async _fetchBalanceAndAllowanceAsync(tokenAddress: string, userAddress: string): Promise<void> {
this.setState({
isBalanceAndAllowanceLoaded: false,
});

View File

@@ -38,7 +38,7 @@ export class TokenInput extends React.Component<TokenInputProps, TokenInputState
isPickerOpen: false,
};
}
public render() {
public render(): React.ReactNode {
const token = this.props.tokenByAddress[this.props.assetToken.address];
const iconStyles = {
cursor: 'pointer',
@@ -76,7 +76,7 @@ export class TokenInput extends React.Component<TokenInputProps, TokenInputState
</div>
);
}
private _onTokenChosen(tokenAddress: string) {
private _onTokenChosen(tokenAddress: string): void {
const assetToken: AssetToken = {
address: tokenAddress,
amount: this.props.assetToken.amount,
@@ -86,12 +86,12 @@ export class TokenInput extends React.Component<TokenInputProps, TokenInputState
isPickerOpen: false,
});
}
private _onToggleHover(isHoveringIcon: boolean) {
private _onToggleHover(isHoveringIcon: boolean): void {
this.setState({
isHoveringIcon,
});
}
private _onAssetClicked() {
private _onAssetClicked(): void {
if (this.props.blockchainErr !== BlockchainErrs.NoError) {
this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
return;

View File

@@ -79,7 +79,7 @@ export class LegacyPortal extends React.Component<LegacyPortalProps, LegacyPorta
private _blockchain: Blockchain;
private _sharedOrderIfExists: Order;
private _throttledScreenWidthUpdate: () => void;
public static hasAlreadyDismissedWethNotice() {
public static hasAlreadyDismissedWethNotice(): boolean {
const didDismissWethNotice = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE);
const hasAlreadyDismissedWethNotice = !_.isUndefined(didDismissWethNotice) && !_.isEmpty(didDismissWethNotice);
return hasAlreadyDismissedWethNotice;
@@ -105,14 +105,14 @@ export class LegacyPortal extends React.Component<LegacyPortalProps, LegacyPorta
isLedgerDialogOpen: false,
};
}
public componentDidMount() {
public componentDidMount(): void {
window.addEventListener('resize', this._throttledScreenWidthUpdate);
window.scrollTo(0, 0);
}
public componentWillMount() {
public componentWillMount(): void {
this._blockchain = new Blockchain(this.props.dispatcher);
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this._blockchain.destroy();
window.removeEventListener('resize', this._throttledScreenWidthUpdate);
// We re-set the entire redux state when the portal is unmounted so that when it is re-rendered
@@ -121,7 +121,7 @@ export class LegacyPortal extends React.Component<LegacyPortalProps, LegacyPorta
// become disconnected from their backing Ethereum node, changes user accounts, etc...)
this.props.dispatcher.resetState();
}
public componentWillReceiveProps(nextProps: LegacyPortalProps) {
public componentWillReceiveProps(nextProps: LegacyPortalProps): void {
if (nextProps.networkId !== this.state.prevNetworkId) {
// tslint:disable-next-line:no-floating-promises
this._blockchain.networkIdUpdatedFireAndForgetAsync(nextProps.networkId);
@@ -150,7 +150,7 @@ export class LegacyPortal extends React.Component<LegacyPortalProps, LegacyPorta
});
}
}
public render() {
public render(): React.ReactNode {
const updateShouldBlockchainErrDialogBeOpen = this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen.bind(
this.props.dispatcher,
);
@@ -276,12 +276,12 @@ export class LegacyPortal extends React.Component<LegacyPortalProps, LegacyPorta
</div>
);
}
public onToggleLedgerDialog() {
public onToggleLedgerDialog(): void {
this.setState({
isLedgerDialogOpen: !this.state.isLedgerDialogOpen,
});
}
private _renderEthWrapper() {
private _renderEthWrapper(): React.ReactNode {
return (
<EthWrappers
networkId={this.props.networkId}
@@ -294,7 +294,7 @@ export class LegacyPortal extends React.Component<LegacyPortalProps, LegacyPorta
/>
);
}
private _renderTradeHistory() {
private _renderTradeHistory(): React.ReactNode {
return (
<TradeHistory
tokenByAddress={this.props.tokenByAddress}
@@ -303,7 +303,7 @@ export class LegacyPortal extends React.Component<LegacyPortalProps, LegacyPorta
/>
);
}
private _renderTokenBalances() {
private _renderTokenBalances(): React.ReactNode {
const allTokens = _.values(this.props.tokenByAddress);
const trackedTokens = _.filter(allTokens, t => t.isTracked);
return (
@@ -322,7 +322,7 @@ export class LegacyPortal extends React.Component<LegacyPortalProps, LegacyPorta
/>
);
}
private _renderFillOrder(match: any, location: Location, history: History) {
private _renderFillOrder(match: any, location: Location, history: History): React.ReactNode {
const initialFillOrder = !_.isUndefined(this.props.userSuppliedOrderCache)
? this.props.userSuppliedOrderCache
: this._sharedOrderIfExists;
@@ -341,7 +341,7 @@ export class LegacyPortal extends React.Component<LegacyPortalProps, LegacyPorta
/>
);
}
private _renderGenerateOrderForm(match: any, location: Location, history: History) {
private _renderGenerateOrderForm(match: any, location: Location, history: History): React.ReactNode {
return (
<GenerateOrderForm
blockchain={this._blockchain}
@@ -350,13 +350,13 @@ export class LegacyPortal extends React.Component<LegacyPortalProps, LegacyPorta
/>
);
}
private _onPortalDisclaimerAccepted() {
private _onPortalDisclaimerAccepted(): void {
localStorage.setItem(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER, 'set');
this.setState({
isDisclaimerDialogOpen: false,
});
}
private _onWethNoticeAccepted() {
private _onWethNoticeAccepted(): void {
localStorage.setItem(constants.LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE, 'set');
this.setState({
isWethNoticeDialogOpen: false,
@@ -388,7 +388,7 @@ export class LegacyPortal extends React.Component<LegacyPortalProps, LegacyPorta
}
return order;
}
private _updateScreenWidth() {
private _updateScreenWidth(): void {
const newScreenWidth = utils.getScreenWidth();
this.props.dispatcher.updateScreenWidth(newScreenWidth);
}

View File

@@ -15,7 +15,7 @@ export class LegacyPortalMenu extends React.Component<LegacyPortalMenuProps, Leg
public static defaultProps: Partial<LegacyPortalMenuProps> = {
onClick: _.noop,
};
public render() {
public render(): React.ReactNode {
return (
<div>
<MenuItem
@@ -61,7 +61,7 @@ export class LegacyPortalMenu extends React.Component<LegacyPortalMenuProps, Leg
</div>
);
}
private _renderMenuItemWithIcon(title: string, iconName: string) {
private _renderMenuItemWithIcon(title: string, iconName: string): React.ReactNode {
return (
<div className="flex" style={{ fontWeight: 100 }}>
<div className="pr1 pl2">

View File

@@ -38,7 +38,7 @@ export class OrderJSON extends React.Component<OrderJSONProps, OrderJSONState> {
// tslint:disable-next-line:no-floating-promises
this._setShareLinkAsync();
}
public render() {
public render(): React.ReactNode {
const order = utils.generateOrder(
this.props.exchangeContractIfExists,
this.props.sideToAssetToken,
@@ -116,11 +116,11 @@ export class OrderJSON extends React.Component<OrderJSONProps, OrderJSONState> {
</div>
);
}
private async _shareViaTwitterAsync() {
private _shareViaTwitterAsync(): void {
const tweetText = encodeURIComponent(`Fill my order using the 0x protocol: ${this.state.shareLink}`);
window.open(`https://twitter.com/intent/tweet?text=${tweetText}`, 'Share your order', 'width=500,height=400');
}
private async _shareViaFacebook() {
private _shareViaFacebook(): void {
(window as any).FB.ui(
{
display: 'popup',
@@ -130,14 +130,14 @@ export class OrderJSON extends React.Component<OrderJSONProps, OrderJSONState> {
_.noop,
);
}
private async _shareViaEmailAsync() {
private _shareViaEmailAsync(): void {
const encodedSubject = encodeURIComponent("Let's trade using the 0x protocol");
const encodedBody = encodeURIComponent(`I generated an order with the 0x protocol.
You can see and fill it here: ${this.state.shareLink}`);
const mailToLink = `mailto:mail@example.org?subject=${encodedSubject}&body=${encodedBody}`;
window.open(mailToLink, '_blank');
}
private async _setShareLinkAsync() {
private async _setShareLinkAsync(): Promise<void> {
const shareLink = await this._generateShareLinkAsync();
this.setState({
shareLink,
@@ -159,7 +159,7 @@ You can see and fill it here: ${this.state.shareLink}`);
}
return bodyObj.data.url;
}
private _getOrderUrl() {
private _getOrderUrl(): string {
const order = utils.generateOrder(
this.props.exchangeContractIfExists,
this.props.sideToAssetToken,

View File

@@ -102,14 +102,14 @@ export class Portal extends React.Component<PortalProps, PortalState> {
isLedgerDialogOpen: false,
};
}
public componentDidMount() {
public componentDidMount(): void {
window.addEventListener('resize', this._throttledScreenWidthUpdate);
window.scrollTo(0, 0);
}
public componentWillMount() {
public componentWillMount(): void {
this._blockchain = new Blockchain(this.props.dispatcher);
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this._blockchain.destroy();
window.removeEventListener('resize', this._throttledScreenWidthUpdate);
// We re-set the entire redux state when the portal is unmounted so that when it is re-rendered
@@ -118,7 +118,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
// become disconnected from their backing Ethereum node, changed user accounts, etc...)
this.props.dispatcher.resetState();
}
public componentWillReceiveProps(nextProps: PortalProps) {
public componentWillReceiveProps(nextProps: PortalProps): void {
if (nextProps.networkId !== this.state.prevNetworkId) {
// tslint:disable-next-line:no-floating-promises
this._blockchain.networkIdUpdatedFireAndForgetAsync(nextProps.networkId);
@@ -144,7 +144,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
});
}
}
public render() {
public render(): React.ReactNode {
const updateShouldBlockchainErrDialogBeOpen = this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen.bind(
this.props.dispatcher,
);
@@ -241,7 +241,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
</div>
);
}
private _onTokenChosen(tokenAddress: string) {
private _onTokenChosen(tokenAddress: string): void {
if (_.isEmpty(tokenAddress)) {
this.setState({
tokenManagementState: TokenManagementState.None,
@@ -269,28 +269,28 @@ export class Portal extends React.Component<PortalProps, PortalState> {
tokenManagementState: TokenManagementState.None,
});
}
private _onToggleLedgerDialog() {
private _onToggleLedgerDialog(): void {
this.setState({
isLedgerDialogOpen: !this.state.isLedgerDialogOpen,
});
}
private _onAddToken() {
private _onAddToken(): void {
this.setState({
tokenManagementState: TokenManagementState.Add,
});
}
private _onRemoveToken() {
private _onRemoveToken(): void {
this.setState({
tokenManagementState: TokenManagementState.Remove,
});
}
private _onPortalDisclaimerAccepted() {
private _onPortalDisclaimerAccepted(): void {
localStorage.setItem(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER, 'set');
this.setState({
isDisclaimerDialogOpen: false,
});
}
private _updateScreenWidth() {
private _updateScreenWidth(): void {
const newScreenWidth = utils.getScreenWidth();
this.props.dispatcher.updateScreenWidth(newScreenWidth);
}

View File

@@ -5,6 +5,6 @@ interface RedirecterProps {
location: string;
}
export function Redirecter(props: RedirecterProps) {
export function Redirecter(props: RedirecterProps): void {
window.location.href = constants.URL_ANGELLIST;
}

View File

@@ -47,7 +47,7 @@ const styles: Styles = {
width: '100%',
boxSizing: 'border-box',
},
dailyTradeVolumeLabel: {
weeklyTradeVolumeLabel: {
fontSize: 14,
color: colors.mediumBlue,
},
@@ -80,9 +80,9 @@ export const RelayerGridTile: React.StatelessComponent<RelayerGridTileProps> = (
<div className="py1" style={styles.relayerNameLabel}>
{props.relayerInfo.name}
</div>
<div style={styles.dailyTradeVolumeLabel}>{props.relayerInfo.dailyTxnVolume}</div>
<div style={styles.weeklyTradeVolumeLabel}>{props.relayerInfo.weeklyTxnVolume}</div>
<div className="py1" style={styles.subLabel}>
Daily Trade Volume
Weekly Trade Volume
</div>
<TopTokens tokens={props.relayerInfo.topTokens} networkId={props.networkId} />
<div className="py1" style={styles.subLabel}>
@@ -109,14 +109,14 @@ class ImgWithFallback extends React.Component<ImgWithFallbackProps, ImgWithFallb
imageLoadFailed: false,
};
}
public render() {
public render(): React.ReactNode {
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() {
private _onError(): void {
this.setState({
imageLoadFailed: true,
});

View File

@@ -48,14 +48,14 @@ export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerInde
error: undefined,
};
}
public componentWillMount() {
public componentWillMount(): void {
// tslint:disable-next-line:no-floating-promises
this._fetchRelayerInfosAsync();
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this._isUnmounted = true;
}
public render() {
public render(): React.ReactNode {
const readyToRender = _.isUndefined(this.state.error) && !_.isUndefined(this.state.relayerInfos);
if (!readyToRender) {
return (

View File

@@ -26,21 +26,54 @@ 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 (
<a
key={tokenInfo.address}
href={tokenLinkFromToken(tokenInfo, props.networkId)}
target="_blank"
style={style}
>
{tokenInfo.symbol}
</a>
);
return <TokenLink tokenInfo={tokenInfo} style={style} networkId={props.networkId} />;
})}
</div>
);
};
function tokenLinkFromToken(tokenInfo: WebsiteBackendTokenInfo, networkId: number) {
interface TokenLinkProps {
tokenInfo: WebsiteBackendTokenInfo;
style: React.CSSProperties;
networkId: number;
}
interface TokenLinkState {
isHovering: boolean;
}
class TokenLink extends React.Component<TokenLinkProps, TokenLinkState> {
constructor(props: TokenLinkProps) {
super(props);
this.state = {
isHovering: false,
};
}
public render(): React.ReactNode {
const style = {
...this.props.style,
cursor: 'pointer',
opacity: this.state.isHovering ? 0.5 : 1,
};
return (
<a
key={this.props.tokenInfo.address}
href={tokenLinkFromToken(this.props.tokenInfo, this.props.networkId)}
target="_blank"
style={style}
onMouseEnter={this._onToggleHover.bind(this, true)}
onMouseLeave={this._onToggleHover.bind(this, false)}
>
{this.props.tokenInfo.symbol}
</a>
);
}
private _onToggleHover(isHovering: boolean): void {
this.setState({
isHovering,
});
}
}
function tokenLinkFromToken(tokenInfo: WebsiteBackendTokenInfo, networkId: number): string {
return sharedUtils.getEtherScanLinkIfExists(tokenInfo.address, networkId, EtherscanLinkSuffixes.Address);
}

View File

@@ -33,7 +33,7 @@ export class SendButton extends React.Component<SendButtonProps, SendButtonState
isSending: false,
};
}
public render() {
public render(): React.ReactNode {
const labelStyle = this.state.isSending ? { fontSize: 10 } : {};
return (
<div>
@@ -57,12 +57,12 @@ export class SendButton extends React.Component<SendButtonProps, SendButtonState
</div>
);
}
private _toggleSendDialog() {
private _toggleSendDialog(): void {
this.setState({
isSendDialogVisible: !this.state.isSendDialogVisible,
});
}
private async _onSendAmountSelectedAsync(recipient: string, value: BigNumber) {
private async _onSendAmountSelectedAsync(recipient: string, value: BigNumber): Promise<void> {
this.setState({
isSending: true,
});

View File

@@ -12,7 +12,7 @@ interface SidebarHeaderProps {
interface SidebarHeaderState {}
export class SidebarHeader extends React.Component<SidebarHeaderProps, SidebarHeaderState> {
public render() {
public render(): React.ReactNode {
return (
<div className="pt2 md-px1 sm-px2" style={{ color: colors.black, paddingBottom: 18 }}>
<div className="flex" style={{ fontSize: 25 }}>

View File

@@ -99,15 +99,15 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
trackedTokenStateByAddress: initialTrackedTokenStateByAddress,
};
}
public componentWillMount() {
public componentWillMount(): void {
const trackedTokenAddresses = _.keys(this.state.trackedTokenStateByAddress);
// tslint:disable-next-line:no-floating-promises
this._fetchBalancesAndAllowancesAsync(trackedTokenAddresses);
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this._isUnmounted = true;
}
public componentWillReceiveProps(nextProps: TokenBalancesProps) {
public componentWillReceiveProps(nextProps: TokenBalancesProps): void {
if (nextProps.userEtherBalanceInWei !== this.props.userEtherBalanceInWei) {
if (this.state.isBalanceSpinnerVisible) {
const receivedAmountInWei = nextProps.userEtherBalanceInWei.minus(this.props.userEtherBalanceInWei);
@@ -153,10 +153,10 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
this._fetchBalancesAndAllowancesAsync(newTokenAddresses);
}
}
public componentDidMount() {
public componentDidMount(): void {
window.scrollTo(0, 0);
}
public render() {
public render(): React.ReactNode {
const errorDialogActions = [
<FlatButton
key="errorOkBtn"
@@ -294,7 +294,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
</div>
);
}
private _renderTokenTableRows() {
private _renderTokenTableRows(): React.ReactNode {
if (!this.props.blockchainIsLoaded || this.props.blockchainErr !== BlockchainErrs.NoError) {
return '';
}
@@ -313,7 +313,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
);
return tableRows;
}
private _renderTokenRow(tokenColSpan: number, actionPaddingX: number, token: Token) {
private _renderTokenRow(tokenColSpan: number, actionPaddingX: number, token: Token): React.ReactNode {
const tokenState = this.state.trackedTokenStateByAddress[token.address];
const tokenLink = sharedUtils.getEtherScanLinkIfExists(
token.address,
@@ -411,7 +411,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
</TableRow>
);
}
private _onAssetTokenPicked(tokenAddress: string) {
private _onAssetTokenPicked(tokenAddress: string): void {
if (_.isEmpty(tokenAddress)) {
this.setState({
isTokenPickerOpen: false,
@@ -439,16 +439,16 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
isTokenPickerOpen: false,
});
}
private _onSendFailed() {
private _onSendFailed(): void {
this.setState({
errorType: BalanceErrs.sendFailed,
});
}
private _renderAmount(amount: BigNumber, decimals: number) {
private _renderAmount(amount: BigNumber, decimals: number): React.ReactNode {
const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
return unitAmount.toNumber().toFixed(configs.AMOUNT_DISPLAY_PRECSION);
}
private _renderTokenName(token: Token) {
private _renderTokenName(token: Token): React.ReactNode {
const tooltipId = `tooltip-${token.address}`;
return (
<div className="flex">
@@ -460,7 +460,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
</div>
);
}
private _renderErrorDialogBody() {
private _renderErrorDialogBody(): React.ReactNode {
switch (this.state.errorType) {
case BalanceErrs.incorrectNetworkForFaucet:
return (
@@ -499,7 +499,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
throw utils.spawnSwitchErr('errorType', this.state.errorType);
}
}
private _onErrorOccurred(errorType: BalanceErrs) {
private _onErrorOccurred(errorType: BalanceErrs): void {
this.setState({
errorType,
});
@@ -577,24 +577,24 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
}
return true;
}
private _onErrorDialogToggle(isOpen: boolean) {
private _onErrorDialogToggle(isOpen: boolean): void {
this.setState({
errorType: undefined,
});
}
private _onAddTokenClicked() {
private _onAddTokenClicked(): void {
this.setState({
isTokenPickerOpen: true,
isAddingToken: true,
});
}
private _onRemoveTokenClicked() {
private _onRemoveTokenClicked(): void {
this.setState({
isTokenPickerOpen: true,
isAddingToken: false,
});
}
private async _startPollingZrxBalanceAsync() {
private async _startPollingZrxBalanceAsync(): Promise<void> {
const tokens = _.values(this.props.tokenByAddress);
const zrxToken = _.find(tokens, t => t.symbol === ZRX_TOKEN_SYMBOL);
@@ -609,7 +609,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
isZRXSpinnerVisible: false,
});
}
private async _fetchBalancesAndAllowancesAsync(tokenAddresses: string[]) {
private async _fetchBalancesAndAllowancesAsync(tokenAddresses: string[]): Promise<void> {
const trackedTokenStateByAddress = this.state.trackedTokenStateByAddress;
const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress;
for (const tokenAddress of tokenAddresses) {
@@ -629,7 +629,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
});
}
}
private _getInitialTrackedTokenStateByAddress(trackedTokens: Token[]) {
private _getInitialTrackedTokenStateByAddress(trackedTokens: Token[]): TokenStateByAddress {
const trackedTokenStateByAddress: TokenStateByAddress = {};
_.each(trackedTokens, token => {
trackedTokenStateByAddress[token.address] = {
@@ -640,7 +640,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
});
return trackedTokenStateByAddress;
}
private async _refetchTokenStateAsync(tokenAddress: string) {
private async _refetchTokenStateAsync(tokenAddress: string): Promise<void> {
const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress;
const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(
userAddressIfExists,

View File

@@ -35,7 +35,7 @@ const styles: Styles = {
};
export class ProviderDisplay extends React.Component<ProviderDisplayProps, ProviderDisplayState> {
public render() {
public render(): React.ReactNode {
const isAddressAvailable = !_.isEmpty(this.props.userAddress);
const isExternallyInjectedProvider =
this.props.providerType === ProviderType.Injected && this.props.injectedProviderName !== '0x Public';
@@ -83,7 +83,7 @@ export class ProviderDisplay extends React.Component<ProviderDisplayProps, Provi
</div>
);
}
public renderPopoverContent(hasInjectedProvider: boolean, hasLedgerProvider: boolean) {
public renderPopoverContent(hasInjectedProvider: boolean, hasLedgerProvider: boolean): React.ReactNode {
if (hasInjectedProvider || hasLedgerProvider) {
return (
<ProviderPicker

View File

@@ -19,7 +19,7 @@ interface ProviderPickerProps {
interface ProviderPickerState {}
export class ProviderPicker extends React.Component<ProviderPickerProps, ProviderPickerState> {
public render() {
public render(): React.ReactNode {
const isLedgerSelected = this.props.providerType === ProviderType.Ledger;
const menuStyle = {
padding: 10,
@@ -46,7 +46,7 @@ export class ProviderPicker extends React.Component<ProviderPickerProps, Provide
</div>
);
}
private _renderLabel(title: string, shouldShowNetwork: boolean) {
private _renderLabel(title: string, shouldShowNetwork: boolean): React.ReactNode {
const label = (
<div className="flex">
<div style={{ fontSize: 14 }}>{title}</div>
@@ -55,7 +55,7 @@ export class ProviderPicker extends React.Component<ProviderPickerProps, Provide
);
return label;
}
private _renderNetwork() {
private _renderNetwork(): React.ReactNode {
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
return (
<div className="flex" style={{ marginTop: 1 }}>
@@ -70,7 +70,7 @@ export class ProviderPicker extends React.Component<ProviderPickerProps, Provide
</div>
);
}
private _onProviderRadioChanged(value: string) {
private _onProviderRadioChanged(value: string): void {
if (value === ProviderType.Ledger) {
this.props.onToggleLedgerDialog();
} else {

View File

@@ -83,7 +83,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
style: {},
isNightVersion: false,
};
public static heightForDisplayType(displayType: TopBarDisplayType) {
public static heightForDisplayType(displayType: TopBarDisplayType): number {
const result = displayType === TopBarDisplayType.Expanded ? EXPANDED_HEIGHT : DEFAULT_HEIGHT;
return result + 1;
}
@@ -93,7 +93,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
isDrawerOpen: false,
};
}
public render() {
public render(): React.ReactNode {
const isNightVersion = this.props.isNightVersion;
const isExpandedDisplayType = this.props.displayType === TopBarDisplayType.Expanded;
const parentClassNames = `flex mx-auto ${isExpandedDisplayType ? 'pl3 py1' : 'max-width-4'}`;
@@ -278,7 +278,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
</div>
);
}
private _renderDrawer() {
private _renderDrawer(): React.ReactNode {
return (
<Drawer
open={this.state.isDrawerOpen}
@@ -447,51 +447,51 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
</div>
);
}
private _onMenuButtonClick() {
private _onMenuButtonClick(): void {
this.setState({
isDrawerOpen: !this.state.isDrawerOpen,
});
}
private _isViewingPortal() {
private _isViewingPortal(): boolean {
return _.includes(this.props.location.pathname, WebsitePaths.Portal);
}
private _isViewingFAQ() {
private _isViewingFAQ(): boolean {
return _.includes(this.props.location.pathname, WebsitePaths.FAQ);
}
private _isViewing0xjsDocs() {
private _isViewing0xjsDocs(): boolean {
return (
_.includes(this.props.location.pathname, WebsitePaths.ZeroExJs) ||
_.includes(this.props.location.pathname, WebsiteLegacyPaths.ZeroExJs)
);
}
private _isViewingConnectDocs() {
private _isViewingConnectDocs(): boolean {
return _.includes(this.props.location.pathname, WebsitePaths.Connect);
}
private _isViewingSmartContractsDocs() {
private _isViewingSmartContractsDocs(): boolean {
return _.includes(this.props.location.pathname, WebsitePaths.SmartContracts);
}
private _isViewingWeb3WrapperDocs() {
private _isViewingWeb3WrapperDocs(): boolean {
return (
_.includes(this.props.location.pathname, WebsitePaths.Web3Wrapper) ||
_.includes(this.props.location.pathname, WebsiteLegacyPaths.Web3Wrapper)
);
}
private _isViewingSolCompilerDocs() {
private _isViewingSolCompilerDocs(): boolean {
return _.includes(this.props.location.pathname, WebsitePaths.SolCompiler);
}
private _isViewingJsonSchemasDocs() {
private _isViewingJsonSchemasDocs(): boolean {
return _.includes(this.props.location.pathname, WebsitePaths.JSONSchemas);
}
private _isViewingSolCovDocs() {
private _isViewingSolCovDocs(): boolean {
return _.includes(this.props.location.pathname, WebsitePaths.SolCov);
}
private _isViewingSubprovidersDocs() {
private _isViewingSubprovidersDocs(): boolean {
return _.includes(this.props.location.pathname, WebsitePaths.Subproviders);
}
private _isViewingWiki() {
private _isViewingWiki(): boolean {
return _.includes(this.props.location.pathname, WebsitePaths.Wiki);
}
private _shouldDisplayBottomBar() {
private _shouldDisplayBottomBar(): boolean {
return (
this._isViewingWiki() ||
this._isViewing0xjsDocs() ||

View File

@@ -26,7 +26,7 @@ export class TopBarMenuItem extends React.Component<TopBarMenuItemProps, TopBarM
className: '',
isNightVersion: false,
};
public render() {
public render(): React.ReactNode {
const primaryStyles = this.props.isPrimary
? {
borderRadius: 4,

View File

@@ -15,7 +15,7 @@ interface TrackTokenConfirmationProps {
interface TrackTokenConfirmationState {}
export class TrackTokenConfirmation extends React.Component<TrackTokenConfirmationProps, TrackTokenConfirmationState> {
public render() {
public render(): React.ReactNode {
const isMultipleTokens = this.props.tokens.length > 1;
const allTokens = _.values(this.props.tokenByAddress);
return (

View File

@@ -28,16 +28,16 @@ export class TradeHistory extends React.Component<TradeHistoryProps, TradeHistor
sortedFills,
};
}
public componentWillMount() {
public componentWillMount(): void {
this._startPollingForFills();
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this._stopPollingForFills();
}
public componentDidMount() {
public componentDidMount(): void {
window.scrollTo(0, 0);
}
public render() {
public render(): React.ReactNode {
return (
<div className="lg-px4 md-px4 sm-px2">
<h3>Trade history</h3>
@@ -48,7 +48,7 @@ export class TradeHistory extends React.Component<TradeHistoryProps, TradeHistor
</div>
);
}
private _renderTrades() {
private _renderTrades(): React.ReactNode {
const numNonCustomFills = this._numFillsWithoutCustomERC20Tokens();
if (numNonCustomFills === 0) {
return this._renderEmptyNotice();
@@ -66,14 +66,14 @@ export class TradeHistory extends React.Component<TradeHistoryProps, TradeHistor
);
});
}
private _renderEmptyNotice() {
private _renderEmptyNotice(): React.ReactNode {
return (
<Paper className="mt1 p2 mx-auto center" style={{ width: '80%' }}>
No filled orders yet.
</Paper>
);
}
private _numFillsWithoutCustomERC20Tokens() {
private _numFillsWithoutCustomERC20Tokens(): number {
let numNonCustomFills = 0;
const tokens = _.values(this.props.tokenByAddress);
_.each(this.state.sortedFills, fill => {
@@ -93,7 +93,7 @@ export class TradeHistory extends React.Component<TradeHistoryProps, TradeHistor
});
return numNonCustomFills;
}
private _startPollingForFills() {
private _startPollingForFills(): void {
this._fillPollingIntervalId = window.setInterval(() => {
const sortedFills = this._getSortedFills();
if (!utils.deepEqual(sortedFills, this.state.sortedFills)) {
@@ -103,10 +103,10 @@ export class TradeHistory extends React.Component<TradeHistoryProps, TradeHistor
}
}, FILL_POLLING_INTERVAL);
}
private _stopPollingForFills() {
private _stopPollingForFills(): void {
clearInterval(this._fillPollingIntervalId);
}
private _getSortedFills() {
private _getSortedFills(): Fill[] {
const fillsByHash = tradeHistoryStorage.getUserFillsByHash(this.props.userAddress, this.props.networkId);
const fills = _.values(fillsByHash);
const sortedFills = _.sortBy(fills, [(fill: Fill) => fill.blockTimestamp * -1]);

View File

@@ -23,7 +23,7 @@ interface TradeHistoryItemProps {
interface TradeHistoryItemState {}
export class TradeHistoryItem extends React.Component<TradeHistoryItemProps, TradeHistoryItemState> {
public render() {
public render(): React.ReactNode {
const fill = this.props.fill;
const tokens = _.values(this.props.tokenByAddress);
const takerToken = _.find(tokens, token => {
@@ -88,7 +88,7 @@ export class TradeHistoryItem extends React.Component<TradeHistoryItemProps, Tra
</Paper>
);
}
private _renderAmounts(makerToken: Token, takerToken: Token) {
private _renderAmounts(makerToken: Token, takerToken: Token): React.ReactNode {
const fill = this.props.fill;
const filledTakerTokenAmountInUnits = ZeroEx.toUnitAmount(fill.filledTakerTokenAmount, takerToken.decimals);
const filledMakerTokenAmountInUnits = ZeroEx.toUnitAmount(fill.filledMakerTokenAmount, takerToken.decimals);
@@ -136,7 +136,7 @@ export class TradeHistoryItem extends React.Component<TradeHistoryItemProps, Tra
</div>
);
}
private _renderDate() {
private _renderDate(): React.ReactNode {
const blockMoment = moment.unix(this.props.fill.blockTimestamp);
if (!blockMoment.isValid()) {
return null;
@@ -159,7 +159,7 @@ export class TradeHistoryItem extends React.Component<TradeHistoryItemProps, Tra
</div>
);
}
private _renderAmount(amount: BigNumber, symbol: string, decimals: number) {
private _renderAmount(amount: BigNumber, symbol: string, decimals: number): React.ReactNode {
const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
return (
<span>

View File

@@ -7,7 +7,7 @@ interface AlertProps {
message: string | React.ReactNode;
}
export function Alert(props: AlertProps) {
export const Alert = (props: AlertProps) => {
const isAlert = props.type === AlertTypes.ERROR;
const errMsgStyles = {
background: isAlert ? colors.red200 : colors.lightestGreen,
@@ -22,4 +22,4 @@ export function Alert(props: AlertProps) {
{props.message}
</div>
);
}
};

View File

@@ -23,14 +23,14 @@ export class CopyIcon extends React.Component<CopyIconProps, CopyIconState> {
isHovering: false,
};
}
public componentDidUpdate() {
public componentDidUpdate(): void {
// Remove tooltip if hover away
if (!this.state.isHovering && this._copyTooltipTimeoutId) {
clearInterval(this._copyTooltipTimeoutId);
this._hideTooltip();
}
}
public render() {
public render(): React.ReactNode {
return (
<div className="inline-block">
<CopyToClipboard text={this.props.data} onCopy={this._onCopy.bind(this)}>
@@ -55,15 +55,15 @@ export class CopyIcon extends React.Component<CopyIconProps, CopyIconState> {
</div>
);
}
private _setRefToProperty(el: HTMLInputElement) {
private _setRefToProperty(el: HTMLInputElement): void {
this._copyable = el;
}
private _setHoverState(isHovering: boolean) {
private _setHoverState(isHovering: boolean): void {
this.setState({
isHovering,
});
}
private _onCopy() {
private _onCopy(): void {
if (this._copyTooltipTimeoutId) {
clearInterval(this._copyTooltipTimeoutId);
}
@@ -73,7 +73,7 @@ export class CopyIcon extends React.Component<CopyIconProps, CopyIconState> {
this._hideTooltip();
}, tooltipLifespanMs);
}
private _hideTooltip() {
private _hideTooltip(): void {
ReactTooltip.hide(ReactDOM.findDOMNode(this._copyable));
}
}

View File

@@ -35,15 +35,15 @@ export class DropDown extends React.Component<DropDownProps, DropDownState> {
isDropDownOpen: false,
};
}
public componentDidMount() {
public componentDidMount(): void {
this._popoverCloseCheckIntervalId = window.setInterval(() => {
this._checkIfShouldClosePopover();
}, CHECK_CLOSE_POPOVER_INTERVAL_MS);
}
public componentWillUnmount() {
public componentWillUnmount(): void {
window.clearInterval(this._popoverCloseCheckIntervalId);
}
public componentWillReceiveProps(nextProps: DropDownProps) {
public componentWillReceiveProps(nextProps: DropDownProps): void {
// HACK: If the popoverContent is updated to a different dimension and the users
// mouse is no longer above it, the dropdown can enter an inconsistent state where
// it believes the user is still hovering over it. In order to remedy this, we
@@ -52,7 +52,7 @@ export class DropDown extends React.Component<DropDownProps, DropDownState> {
// dropdowns from having dynamic content.
this._onHoverOff();
}
public render() {
public render(): React.ReactNode {
return (
<div
style={{ ...this.props.style, width: 'fit-content', height: '100%' }}
@@ -77,11 +77,11 @@ export class DropDown extends React.Component<DropDownProps, DropDownState> {
</div>
);
}
private _onHover(event: React.FormEvent<HTMLInputElement>) {
private _onHover(event: React.FormEvent<HTMLInputElement>): void {
this._isHovering = true;
this._checkIfShouldOpenPopover(event);
}
private _checkIfShouldOpenPopover(event: React.FormEvent<HTMLInputElement>) {
private _checkIfShouldOpenPopover(event: React.FormEvent<HTMLInputElement>): void {
if (this.state.isDropDownOpen) {
return; // noop
}
@@ -91,16 +91,16 @@ export class DropDown extends React.Component<DropDownProps, DropDownState> {
anchorEl: event.currentTarget,
});
}
private _onHoverOff() {
private _onHoverOff(): void {
this._isHovering = false;
}
private _checkIfShouldClosePopover() {
private _checkIfShouldClosePopover(): void {
if (!this.state.isDropDownOpen || this._isHovering) {
return; // noop
}
this._closePopover();
}
private _closePopover() {
private _closePopover(): void {
this.setState({
isDropDownOpen: false,
});

View File

@@ -35,6 +35,6 @@ export const EtherScanIcon = (props: EtherScanIconProps) => {
);
};
function renderIcon() {
function renderIcon(): React.ReactNode {
return <i style={{ color: colors.amber600 }} className="zmdi zmdi-open-in-new" />;
}

View File

@@ -21,7 +21,7 @@ interface FakeTextFieldProps {
children?: any;
}
export function FakeTextField(props: FakeTextFieldProps) {
export const FakeTextField = (props: FakeTextFieldProps) => {
return (
<div className="relative">
{props.label !== '' && <InputLabel text={props.label} />}
@@ -31,4 +31,4 @@ export function FakeTextField(props: FakeTextFieldProps) {
<hr style={styles.hr} />
</div>
);
}
};

View File

@@ -19,7 +19,7 @@ export class FlashMessage extends React.Component<FlashMessageProps, FlashMessag
showDurationMs: SHOW_DURATION_MS,
bodyStyle: {},
};
public render() {
public render(): React.ReactNode {
if (!_.isUndefined(this.props.flashMessage)) {
return (
<Snackbar
@@ -34,7 +34,7 @@ export class FlashMessage extends React.Component<FlashMessageProps, FlashMessag
return null;
}
}
private _onClose() {
private _onClose(): void {
this.props.dispatcher.hideFlashMessage();
}
}

View File

@@ -15,7 +15,7 @@ export class Identicon extends React.Component<IdenticonProps, IdenticonState> {
public static defaultProps: Partial<IdenticonProps> = {
style: {},
};
public render() {
public render(): React.ReactNode {
let address = this.props.address;
if (_.isEmpty(address)) {
address = constants.NULL_ADDRESS;

View File

@@ -42,11 +42,11 @@ export class LifeCycleRaisedButton extends React.Component<LifeCycleRaisedButton
buttonState: ButtonState.READY,
};
}
public componentWillUnmount() {
public componentWillUnmount(): void {
clearTimeout(this._buttonTimeoutId);
this._didUnmount = true;
}
public render() {
public render(): React.ReactNode {
if (this.props.isHidden) {
return <span />;
}
@@ -77,7 +77,7 @@ export class LifeCycleRaisedButton extends React.Component<LifeCycleRaisedButton
/>
);
}
public async onClickAsync() {
public async onClickAsync(): Promise<void> {
this.setState({
buttonState: ButtonState.LOADING,
});

View File

@@ -24,7 +24,7 @@ export class MenuItem extends React.Component<MenuItemProps, MenuItemState> {
isHovering: false,
};
}
public render() {
public render(): React.ReactNode {
const menuItemStyles = {
cursor: 'pointer',
opacity: this.state.isHovering ? 0.5 : 1,
@@ -43,7 +43,7 @@ export class MenuItem extends React.Component<MenuItemProps, MenuItemState> {
</Link>
);
}
private _onToggleHover(isHovering: boolean) {
private _onToggleHover(isHovering: boolean): void {
this.setState({
isHovering,
});

View File

@@ -27,7 +27,7 @@ export class Party extends React.Component<PartyProps, PartyState> {
identiconStyle: {},
identiconDiameter: IDENTICON_DIAMETER,
};
public render() {
public render(): React.ReactNode {
const label = this.props.label;
const address = this.props.address;
const identiconDiameter = this.props.identiconDiameter;

View File

@@ -17,7 +17,7 @@ export class SwapIcon extends React.Component<SwapIconProps, SwapIconState> {
isHovering: false,
};
}
public render() {
public render(): React.ReactNode {
const swapStyles = {
color: this.state.isHovering ? colors.amber600 : colors.amber800,
fontSize: 50,
@@ -34,7 +34,7 @@ export class SwapIcon extends React.Component<SwapIconProps, SwapIconState> {
</div>
);
}
private _onToggleHover(isHovering: boolean) {
private _onToggleHover(isHovering: boolean): void {
this.setState({
isHovering,
});

View File

@@ -11,7 +11,7 @@ interface TokenIconProps {
interface TokenIconState {}
export class TokenIcon extends React.Component<TokenIconProps, TokenIconState> {
public render() {
public render(): React.ReactNode {
const token = this.props.token;
const diameter = this.props.diameter;
return (

View File

@@ -20,7 +20,7 @@ interface VisualOrderProps {
interface VisualOrderState {}
export class VisualOrder extends React.Component<VisualOrderProps, VisualOrderState> {
public render() {
public render(): React.ReactNode {
const allTokens = _.values(this.props.tokenByAddress);
const makerImage = this.props.makerToken.iconUrl;
const takerImage = this.props.takerToken.iconUrl;
@@ -62,7 +62,7 @@ export class VisualOrder extends React.Component<VisualOrderProps, VisualOrderSt
</div>
);
}
private _renderAmount(assetToken: AssetToken, token: Token) {
private _renderAmount(assetToken: AssetToken, token: Token): React.ReactNode {
const unitAmount = ZeroEx.toUnitAmount(assetToken.amount, token.decimals);
return (
<div style={{ fontSize: 13 }}>

View File

@@ -162,15 +162,15 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
isHoveringSidebar: false,
};
}
public componentWillMount() {
public componentWillMount(): void {
const trackedTokenAddresses = _.keys(this.state.trackedTokenStateByAddress);
// tslint:disable-next-line:no-floating-promises
this._fetchBalancesAndAllowancesAsync(trackedTokenAddresses);
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this._isUnmounted = true;
}
public componentWillReceiveProps(nextProps: WalletProps) {
public componentWillReceiveProps(nextProps: WalletProps): void {
if (
nextProps.userAddress !== this.props.userAddress ||
nextProps.networkId !== this.props.networkId ||
@@ -196,11 +196,11 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
this._fetchBalancesAndAllowancesAsync(newTokenAddresses);
}
}
public render() {
public render(): React.ReactNode {
const isReadyToRender = this.props.blockchainIsLoaded && this.props.blockchainErr === BlockchainErrs.NoError;
return <div style={styles.root}>{isReadyToRender && this._renderRows()}</div>;
}
private _renderRows() {
private _renderRows(): React.ReactNode {
const isAddressAvailable = !_.isEmpty(this.props.userAddress);
return (
<List style={styles.list}>
@@ -210,7 +210,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
</List>
);
}
private _renderDisconnectedHeaderRows() {
private _renderDisconnectedHeaderRows(): React.ReactElement<{}> {
const userAddress = this.props.userAddress;
const primaryText = 'wallet';
return (
@@ -223,7 +223,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
/>
);
}
private _renderDisconnectedRows() {
private _renderDisconnectedRows(): React.ReactElement<{}> {
return (
<WalletDisconnectedItem
key={DISCONNECTED_ITEM_KEY}
@@ -233,7 +233,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
/>
);
}
private _renderConnectedHeaderRows() {
private _renderConnectedHeaderRows(): React.ReactElement<{}> {
const userAddress = this.props.userAddress;
const primaryText = utils.getAddressBeginAndEnd(userAddress);
return (
@@ -246,7 +246,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
/>
);
}
private _renderBody() {
private _renderBody(): React.ReactElement<{}> {
const bodyStyle: React.CSSProperties = {
...styles.bodyInnerDiv,
overflow: this.state.isHoveringSidebar ? 'auto' : 'hidden',
@@ -263,17 +263,17 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
</ListItem>
);
}
private _onSidebarHover(event: React.FormEvent<HTMLInputElement>) {
private _onSidebarHover(event: React.FormEvent<HTMLInputElement>): void {
this.setState({
isHoveringSidebar: true,
});
}
private _onSidebarHoverOff() {
private _onSidebarHoverOff(): void {
this.setState({
isHoveringSidebar: false,
});
}
private _renderFooterRows() {
private _renderFooterRows(): React.ReactElement<{}> {
return (
<ListItem
key={FOOTER_ITEM_KEY}
@@ -302,7 +302,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
/>
);
}
private _renderEthRows() {
private _renderEthRows(): React.ReactNode {
const primaryText = this._renderAmount(
this.props.userEtherBalanceInWei,
constants.DECIMAL_PLACES_ETH,
@@ -352,7 +352,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
</div>
);
}
private _renderTokenRows() {
private _renderTokenRows(): React.ReactNode {
const trackedTokens = this.props.trackedTokens;
const trackedTokensStartingWithEtherToken = trackedTokens.sort(
firstBy((t: Token) => t.symbol !== ETHER_TOKEN_SYMBOL)
@@ -361,7 +361,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
);
return _.map(trackedTokensStartingWithEtherToken, this._renderTokenRow.bind(this));
}
private _renderTokenRow(token: Token, index: number) {
private _renderTokenRow(token: Token, index: number): React.ReactNode {
const tokenState = this.state.trackedTokenStateByAddress[token.address];
const tokenLink = sharedUtils.getEtherScanLinkIfExists(
token.address,
@@ -415,7 +415,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
</div>
);
}
private _renderAccessoryItems(config: AccessoryItemConfig) {
private _renderAccessoryItems(config: AccessoryItemConfig): React.ReactElement<{}> {
const shouldShowWrappedEtherAction = !_.isUndefined(config.wrappedEtherDirection);
const shouldShowToggle = !_.isUndefined(config.allowanceToggleConfig);
return (
@@ -431,7 +431,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
</div>
);
}
private _renderAllowanceToggle(config: AllowanceToggleConfig) {
private _renderAllowanceToggle(config: AllowanceToggleConfig): React.ReactNode {
return (
<AllowanceToggle
networkId={this.props.networkId}
@@ -446,13 +446,13 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
/>
);
}
private _renderAmount(amount: BigNumber, decimals: number, symbol: string) {
private _renderAmount(amount: BigNumber, decimals: number, symbol: string): React.ReactNode {
const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
const formattedAmount = unitAmount.toPrecision(TOKEN_AMOUNT_DISPLAY_PRECISION);
const result = `${formattedAmount} ${symbol}`;
return <div style={styles.amountLabel}>{result}</div>;
}
private _renderValue(amount: BigNumber, decimals: number, price?: BigNumber) {
private _renderValue(amount: BigNumber, decimals: number, price?: BigNumber): React.ReactNode {
if (_.isUndefined(price)) {
return null;
}
@@ -462,7 +462,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
const result = `$${formattedAmount}`;
return result;
}
private _renderTokenIcon(token: Token, tokenLink?: string) {
private _renderTokenIcon(token: Token, tokenLink?: string): React.ReactElement<{}> {
const tooltipId = `tooltip-${token.address}`;
const tokenIcon = <TokenIcon token={token} diameter={ICON_DIMENSION} />;
if (_.isUndefined(tokenLink)) {
@@ -475,7 +475,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
);
}
}
private _renderWrappedEtherButton(wrappedEtherDirection: Side) {
private _renderWrappedEtherButton(wrappedEtherDirection: Side): React.ReactNode {
const isWrappedEtherDirectionOpen = this.state.wrappedEtherDirection === wrappedEtherDirection;
let buttonLabel;
let buttonIcon;
@@ -510,7 +510,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
/>
);
}
private _getInitialTrackedTokenStateByAddress(tokenAddresses: string[]) {
private _getInitialTrackedTokenStateByAddress(tokenAddresses: string[]): TokenStateByAddress {
const trackedTokenStateByAddress: TokenStateByAddress = {};
_.each(tokenAddresses, tokenAddress => {
trackedTokenStateByAddress[tokenAddress] = {
@@ -521,7 +521,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
});
return trackedTokenStateByAddress;
}
private async _fetchBalancesAndAllowancesAsync(tokenAddresses: string[]) {
private async _fetchBalancesAndAllowancesAsync(tokenAddresses: string[]): Promise<void> {
const balanceAndAllowanceTupleByAddress: ItemByAddress<BigNumber[]> = {};
const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress;
for (const tokenAddress of tokenAddresses) {
@@ -554,7 +554,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
});
}
}
private async _refetchTokenStateAsync(tokenAddress: string) {
private async _refetchTokenStateAsync(tokenAddress: string): Promise<void> {
await this._fetchBalancesAndAllowancesAsync([tokenAddress]);
}
private async _getPriceByAddressAsync(tokenAddresses: string[]): Promise<ItemByAddress<BigNumber>> {
@@ -584,17 +584,17 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
return {};
}
}
private _openWrappedEtherActionRow(wrappedEtherDirection: Side) {
private _openWrappedEtherActionRow(wrappedEtherDirection: Side): void {
this.setState({
wrappedEtherDirection,
});
}
private _closeWrappedEtherActionRow() {
private _closeWrappedEtherActionRow(): void {
this.setState({
wrappedEtherDirection: undefined,
});
}
private _getEthToken() {
private _getEthToken(): Token {
const tokens = _.values(this.props.tokenByAddress);
const etherToken = _.find(tokens, { symbol: ETHER_TOKEN_SYMBOL });
return etherToken;

View File

@@ -64,7 +64,7 @@ export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEther
isEthConversionHappening: false,
};
}
public render() {
public render(): React.ReactNode {
const etherBalanceInEth = ZeroEx.toUnitAmount(this.props.userEtherBalanceInWei, constants.DECIMAL_PLACES_ETH);
const isWrappingEth = this.props.direction === Side.Deposit;
const topLabelText = isWrappingEth ? 'Convert ETH into WETH 1:1' : 'Convert WETH into ETH 1:1';
@@ -116,20 +116,20 @@ export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEther
/>
);
}
private _onValueChange(isValid: boolean, amount?: BigNumber) {
private _onValueChange(isValid: boolean, amount?: BigNumber): void {
this.setState({
currentInputAmount: amount,
currentInputHasErrors: !isValid,
});
}
private _renderIsEthConversionHappeningSpinner() {
private _renderIsEthConversionHappeningSpinner(): React.ReactElement<{}> {
return this.state.isEthConversionHappening ? (
<div className="pl1" style={{ paddingTop: 10 }}>
<i className="zmdi zmdi-spinner zmdi-hc-spin" />
</div>
) : null;
}
private _renderWrapEtherConfirmationButton() {
private _renderWrapEtherConfirmationButton(): React.ReactElement<{}> {
const isWrappingEth = this.props.direction === Side.Deposit;
const labelText = isWrappingEth ? 'wrap' : 'unwrap';
return (
@@ -138,13 +138,13 @@ export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEther
backgroundColor={colors.wrapEtherConfirmationButton}
label={labelText}
labelStyle={styles.wrapEtherConfirmationButtonLabel}
onClick={this._wrapEtherConfirmationAction.bind(this)}
onClick={this._wrapEtherConfirmationActionAsync.bind(this)}
disabled={this.state.isEthConversionHappening}
/>
</div>
);
}
private async _wrapEtherConfirmationAction() {
private async _wrapEtherConfirmationActionAsync(): Promise<void> {
this.setState({
isEthConversionHappening: true,
});

View File

@@ -35,7 +35,7 @@ import 'less/all.less';
// 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.isDevelopment() || utils.isStaging() || utils.isDogfood()
? createLazyComponent('Portal', async () =>
System.import<any>(/* webpackChunkName: "portal" */ 'ts/containers/portal'),
)

View File

@@ -21,22 +21,22 @@ export class LazyComponent extends React.Component<LazyComponentProps, LazyCompo
component: undefined,
};
}
public componentWillMount() {
public componentWillMount(): void {
// tslint:disable-next-line:no-floating-promises
this._loadComponentFireAndForgetAsync(this.props);
}
public componentWillReceiveProps(nextProps: LazyComponentProps) {
public componentWillReceiveProps(nextProps: LazyComponentProps): void {
if (nextProps.reactComponentPromise !== this.props.reactComponentPromise) {
// tslint:disable-next-line:no-floating-promises
this._loadComponentFireAndForgetAsync(nextProps);
}
}
public render() {
public render(): React.ReactNode {
return _.isUndefined(this.state.component)
? null
: React.createElement(this.state.component, this.props.reactComponentProps);
}
private async _loadComponentFireAndForgetAsync(props: LazyComponentProps) {
private async _loadComponentFireAndForgetAsync(props: LazyComponentProps): Promise<void> {
const component = await props.reactComponentPromise;
this.setState({
component,

View File

@@ -1,7 +1,7 @@
import * as _ from 'lodash';
export const localStorage = {
doesExist() {
doesExist(): boolean {
return !!window.localStorage;
},
getItemIfExists(key: string): string {
@@ -14,13 +14,13 @@ export const localStorage = {
}
return item;
},
setItem(key: string, value: string) {
setItem(key: string, value: string): void {
if (!this.doesExist || _.isUndefined(value)) {
return;
}
window.localStorage.setItem(key, value);
},
removeItem(key: string) {
removeItem(key: string): void {
if (!this.doesExist) {
return;
}

View File

@@ -14,7 +14,7 @@ export const tradeHistoryStorage = {
// Clear all fill related localStorage if we've updated the config variable in an update
// that introduced a backward incompatible change requiring the user to re-fetch the fills from
// the blockchain
clearIfRequired() {
clearIfRequired(): void {
const lastClearFillDate = localStorage.getItemIfExists(FILL_CLEAR_KEY);
if (lastClearFillDate !== configs.LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE) {
const localStorageKeys = localStorage.getAllKeys();
@@ -26,7 +26,7 @@ export const tradeHistoryStorage = {
}
localStorage.setItem(FILL_CLEAR_KEY, configs.LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE);
},
addFillToUser(userAddress: string, networkId: number, fill: Fill) {
addFillToUser(userAddress: string, networkId: number, fill: Fill): void {
const fillsByHash = this.getUserFillsByHash(userAddress, networkId);
const fillHash = this._getFillHash(fill);
const doesFillExist = !_.isUndefined(fillsByHash[fillHash]);
@@ -38,7 +38,7 @@ export const tradeHistoryStorage = {
const userFillsKey = this._getUserFillsKey(userAddress, networkId);
localStorage.setItem(userFillsKey, userFillsJSONString);
},
removeFillFromUser(userAddress: string, networkId: number, fill: Fill) {
removeFillFromUser(userAddress: string, networkId: number, fill: Fill): void {
const fillsByHash = this.getUserFillsByHash(userAddress, networkId);
const fillHash = this._getFillHash(fill);
const doesFillExist = !_.isUndefined(fillsByHash[fillHash]);
@@ -74,15 +74,15 @@ export const tradeHistoryStorage = {
const blockNumber = _.parseInt(blockNumberStr);
return blockNumber;
},
setFillsLatestBlock(userAddress: string, networkId: number, blockNumber: number) {
setFillsLatestBlock(userAddress: string, networkId: number, blockNumber: number): void {
const userFillsLatestBlockKey = this._getFillsLatestBlockKey(userAddress, networkId);
localStorage.setItem(userFillsLatestBlockKey, `${blockNumber}`);
},
_getUserFillsKey(userAddress: string, networkId: number) {
_getUserFillsKey(userAddress: string, networkId: number): string {
const userFillsKey = `${FILLS_KEY}-${userAddress}-${networkId}`;
return userFillsKey;
},
_getFillsLatestBlockKey(userAddress: string, networkId: number) {
_getFillsLatestBlockKey(userAddress: string, networkId: number): string {
const userFillsLatestBlockKey = `${FILLS_LATEST_BLOCK}-${userAddress}-${networkId}`;
return userFillsLatestBlockKey;
},

View File

@@ -128,9 +128,6 @@ const teamRow4: ProfileInfo[] = [
github: '',
medium: '',
},
];
const teamRow5: ProfileInfo[] = [
{
name: 'Greg Hysen',
title: 'Blockchain Engineer',
@@ -140,6 +137,9 @@ const teamRow5: ProfileInfo[] = [
github: 'https://github.com/hysz',
medium: '',
},
];
const teamRow5: ProfileInfo[] = [
{
name: 'Remco Bloemen',
title: 'Technical Fellow',
@@ -149,6 +149,14 @@ const teamRow5: ProfileInfo[] = [
github: 'http://github.com/recmo',
medium: '',
},
{
name: 'Francesco Agosti',
title: 'Senior Frontend Engineer',
description: `Full-stack engineer. Previously senior software engineer at Yelp. Computer science Duke.`,
image: 'images/team/fragosti.png',
linkedIn: 'https://www.linkedin.com/in/fragosti/',
github: 'http://github.com/fragosti',
},
];
const advisors: ProfileInfo[] = [
@@ -210,10 +218,10 @@ const styles: Styles = {
};
export class About extends React.Component<AboutProps, AboutState> {
public componentDidMount() {
public componentDidMount(): void {
window.scrollTo(0, 0);
}
public render() {
public render(): React.ReactNode {
return (
<div style={{ backgroundColor: colors.lightestGrey }}>
<DocumentTitle title="0x About Us" />
@@ -284,7 +292,7 @@ export class About extends React.Component<AboutProps, AboutState> {
</div>
);
}
private _renderProfiles(profiles: ProfileInfo[]) {
private _renderProfiles(profiles: ProfileInfo[]): React.ReactNode {
const numIndiv = profiles.length;
const colSize = utils.getColSize(numIndiv);
return _.map(profiles, profile => {

View File

@@ -22,7 +22,7 @@ interface ProfileProps {
profileInfo: ProfileInfo;
}
export function Profile(props: ProfileProps) {
export const Profile = (props: ProfileProps) => {
return (
<div className={`lg-col md-col lg-col-${props.colSize} md-col-6`}>
<div style={{ maxWidth: 300 }} className="mx-auto lg-px3 md-px3 sm-px4 sm-pb3">
@@ -53,9 +53,9 @@ export function Profile(props: ProfileProps) {
</div>
</div>
);
}
};
function renderSocialMediaIcons(profileInfo: ProfileInfo) {
function renderSocialMediaIcons(profileInfo: ProfileInfo): React.ReactNode {
const icons = [
renderSocialMediaIcon('zmdi-github-box', profileInfo.github),
renderSocialMediaIcon('zmdi-linkedin-box', profileInfo.linkedIn),
@@ -64,7 +64,7 @@ function renderSocialMediaIcons(profileInfo: ProfileInfo) {
return icons;
}
function renderSocialMediaIcon(iconName: string, url: string) {
function renderSocialMediaIcon(iconName: string, url: string): React.ReactNode {
if (_.isEmpty(url)) {
return null;
}

View File

@@ -59,7 +59,7 @@ export class DocPage extends React.Component<DocPageProps, DocPageState> {
docAgnosticFormat: undefined,
};
}
public componentWillMount() {
public componentWillMount(): void {
const pathName = this.props.location.pathname;
const lastSegment = pathName.substr(pathName.lastIndexOf('/') + 1);
const versions = findVersions(lastSegment);
@@ -67,10 +67,10 @@ export class DocPage extends React.Component<DocPageProps, DocPageState> {
// tslint:disable-next-line:no-floating-promises
this._fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists);
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this._isUnmounted = true;
}
public render() {
public render(): React.ReactNode {
const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat)
? {}
: this.props.docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat);
@@ -135,7 +135,7 @@ export class DocPage extends React.Component<DocPageProps, DocPageState> {
});
}
}
private _getSourceUrl() {
private _getSourceUrl(): string {
const url = this.props.docsInfo.packageUrl;
let pkg = docIdToSubpackageName[this.props.docsInfo.id];
let tagPrefix = pkg;
@@ -155,7 +155,7 @@ export class DocPage extends React.Component<DocPageProps, DocPageState> {
const sourceUrl = `${url}/blob/${tagPrefix}%40${this.props.docsVersion}/packages${pkg}`;
return sourceUrl;
}
private _onVersionSelected(semver: string) {
private _onVersionSelected(semver: string): void {
let path = window.location.pathname;
const lastChar = path[path.length - 1];
if (_.isFinite(_.parseInt(lastChar))) {

View File

@@ -404,10 +404,10 @@ const sections: FAQSection[] = [
];
export class FAQ extends React.Component<FAQProps, FAQState> {
public componentDidMount() {
public componentDidMount(): void {
window.scrollTo(0, 0);
}
public render() {
public render(): React.ReactNode {
return (
<div>
<DocumentTitle title="0x FAQ" />
@@ -422,7 +422,7 @@ export class FAQ extends React.Component<FAQProps, FAQState> {
</div>
);
}
private _renderSections() {
private _renderSections(): React.ReactNode {
const renderedSections = _.map(sections, (section: FAQSection, i: number) => {
const isFirstSection = i === 0;
return (
@@ -434,7 +434,7 @@ export class FAQ extends React.Component<FAQProps, FAQState> {
});
return renderedSections;
}
private _renderQuestions(questions: FAQQuestion[], isFirstSection: boolean) {
private _renderQuestions(questions: FAQQuestion[], isFirstSection: boolean): React.ReactNode {
const renderedQuestions = _.map(questions, (question: FAQQuestion, i: number) => {
const isFirstQuestion = i === 0;
return (

View File

@@ -20,7 +20,7 @@ export class Question extends React.Component<QuestionProps, QuestionState> {
isExpanded: props.shouldDisplayExpanded,
};
}
public render() {
public render(): React.ReactNode {
return (
<div className="py1">
<Card
@@ -43,7 +43,7 @@ export class Question extends React.Component<QuestionProps, QuestionState> {
</div>
);
}
private _onExchangeChange() {
private _onExchangeChange(): void {
this.setState({
isExpanded: !this.state.isExpanded,
});

View File

@@ -177,14 +177,14 @@ export class Landing extends React.Component<LandingProps, LandingState> {
};
this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
}
public componentDidMount() {
public componentDidMount(): void {
window.addEventListener('resize', this._throttledScreenWidthUpdate);
window.scrollTo(0, 0);
}
public componentWillUnmount() {
public componentWillUnmount(): void {
window.removeEventListener('resize', this._throttledScreenWidthUpdate);
}
public render() {
public render(): React.ReactNode {
return (
<div id="landing" className="clearfix" style={{ color: colors.grey500 }}>
<DocumentTitle title="0x Protocol" />
@@ -218,7 +218,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
</div>
);
}
private _renderHero() {
private _renderHero(): React.ReactNode {
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
const buttonLabelStyle: React.CSSProperties = {
textTransform: 'none',
@@ -305,7 +305,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
</div>
);
}
private _renderWhatsNew() {
private _renderWhatsNew(): React.ReactNode {
return (
<div className="sm-center sm-px1">
<a href={WHATS_NEW_URL} target="_blank" className="inline-block text-decoration-none">
@@ -327,7 +327,12 @@ export class Landing extends React.Component<LandingProps, LandingState> {
</div>
);
}
private _renderProjects(projects: Project[], title: string, backgroundColor: string, isTitleCenter: boolean) {
private _renderProjects(
projects: Project[],
title: string,
backgroundColor: string,
isTitleCenter: boolean,
): React.ReactNode {
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
const projectList = _.map(projects, (project: Project, i: number) => {
const isRelayersOnly = projects.length === 12;
@@ -393,7 +398,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
</div>
);
}
private _renderTokenizationSection() {
private _renderTokenizationSection(): React.ReactNode {
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
return (
<div className="clearfix lg-py4 md-py4 sm-pb4 sm-pt2" style={{ backgroundColor: colors.grey100 }}>
@@ -424,7 +429,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
</div>
);
}
private _renderProtocolSection() {
private _renderProtocolSection(): React.ReactNode {
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
return (
<div className="clearfix pt4" style={{ backgroundColor: colors.heroGrey }}>
@@ -469,7 +474,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
</div>
);
}
private _renderBuildingBlocksSection() {
private _renderBuildingBlocksSection(): React.ReactNode {
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
const descriptionStyle: React.CSSProperties = {
fontFamily: 'Roboto Mono',
@@ -526,7 +531,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
</div>
);
}
private _renderBlockChipImage() {
private _renderBlockChipImage(): React.ReactNode {
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
return (
<div className="col lg-col-6 md-col-6 col-12 sm-center">
@@ -534,7 +539,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
</div>
);
}
private _renderTokenCloud() {
private _renderTokenCloud(): React.ReactNode {
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
return (
<div className="col lg-col-6 md-col-6 col-12 center">
@@ -542,7 +547,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
</div>
);
}
private _renderAssetTypes() {
private _renderAssetTypes(): React.ReactNode {
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
const assetTypes: AssetType[] = [
{
@@ -585,7 +590,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
});
return assets;
}
private _renderInfoBoxes() {
private _renderInfoBoxes(): React.ReactNode {
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
const boxStyle: React.CSSProperties = {
maxWidth: 253,
@@ -648,7 +653,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
</div>
);
}
private _renderUseCases() {
private _renderUseCases(): React.ReactNode {
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
const useCases: UseCase[] = [
@@ -746,7 +751,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
</div>
);
}
private _renderCallToAction() {
private _renderCallToAction(): React.ReactNode {
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
const buttonLabelStyle: React.CSSProperties = {
textTransform: 'none',
@@ -793,7 +798,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
</div>
);
}
private _updateScreenWidth() {
private _updateScreenWidth(): void {
const newScreenWidth = utils.getScreenWidth();
if (newScreenWidth !== this.state.screenWidth) {
this.setState({
@@ -801,7 +806,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
});
}
}
private _onLanguageSelected(language: Language) {
private _onLanguageSelected(language: Language): void {
this.props.dispatcher.updateSelectedLanguage(language);
}
} // tslint:disable:max-file-line-count

View File

@@ -21,7 +21,7 @@ const styles: Styles = {
};
export class NotFound extends React.Component<NotFoundProps, NotFoundState> {
public render() {
public render(): React.ReactNode {
return (
<div>
<TopBar blockchainIsLoaded={false} location={this.props.location} translate={this.props.translate} />

View File

@@ -69,19 +69,19 @@ export class Wiki extends React.Component<WikiProps, WikiState> {
isHoveringSidebar: false,
};
}
public componentDidMount() {
public componentDidMount(): void {
window.addEventListener('hashchange', this._onHashChanged.bind(this), false);
}
public componentWillMount() {
public componentWillMount(): void {
// tslint:disable-next-line:no-floating-promises
this._fetchArticlesBySectionAsync();
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this._isUnmounted = true;
clearTimeout(this._wikiBackoffTimeoutId);
window.removeEventListener('hashchange', this._onHashChanged.bind(this), false);
}
public render() {
public render(): React.ReactNode {
const menuSubsectionsBySection = _.isUndefined(this.state.articlesBySection)
? {}
: this._getMenuSubsectionsBySection(this.state.articlesBySection);
@@ -171,7 +171,7 @@ export class Wiki extends React.Component<WikiProps, WikiState> {
const sections = _.map(sectionNames, sectionName => this._renderSection(sectionName));
return sections;
}
private _renderSection(sectionName: string) {
private _renderSection(sectionName: string): React.ReactNode {
const articles = this.state.articlesBySection[sectionName];
const renderedArticles = _.map(articles, (article: Article) => {
const githubLink = `${constants.URL_GITHUB_WIKI}/edit/master/${sectionName}/${article.fileName}`;
@@ -227,7 +227,7 @@ export class Wiki extends React.Component<WikiProps, WikiState> {
}
}
}
private _getMenuSubsectionsBySection(articlesBySection: ArticlesBySection) {
private _getMenuSubsectionsBySection(articlesBySection: ArticlesBySection): { [section: string]: string[] } {
const sectionNames = _.keys(articlesBySection);
const menuSubsectionsBySection: { [section: string]: string[] } = {};
for (const sectionName of sectionNames) {
@@ -237,17 +237,17 @@ export class Wiki extends React.Component<WikiProps, WikiState> {
}
return menuSubsectionsBySection;
}
private _onSidebarHover(event: React.FormEvent<HTMLInputElement>) {
private _onSidebarHover(event: React.FormEvent<HTMLInputElement>): void {
this.setState({
isHoveringSidebar: true,
});
}
private _onSidebarHoverOff() {
private _onSidebarHoverOff(): void {
this.setState({
isHoveringSidebar: false,
});
}
private _onHashChanged(event: any) {
private _onHashChanged(event: any): void {
const hash = window.location.hash.slice(1);
sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID);
}

View File

@@ -22,47 +22,47 @@ export class Dispatcher {
this._dispatch = dispatch;
}
// Portal
public resetState() {
public resetState(): void {
this._dispatch({
type: ActionTypes.ResetState,
});
}
public updateNodeVersion(nodeVersion: string) {
public updateNodeVersion(nodeVersion: string): void {
this._dispatch({
data: nodeVersion,
type: ActionTypes.UpdateNodeVersion,
});
}
public updateScreenWidth(screenWidth: ScreenWidths) {
public updateScreenWidth(screenWidth: ScreenWidths): void {
this._dispatch({
data: screenWidth,
type: ActionTypes.UpdateScreenWidth,
});
}
public swapAssetTokenSymbols() {
public swapAssetTokenSymbols(): void {
this._dispatch({
type: ActionTypes.SwapAssetTokens,
});
}
public updateOrderSalt(salt: BigNumber) {
public updateOrderSalt(salt: BigNumber): void {
this._dispatch({
data: salt,
type: ActionTypes.UpdateOrderSalt,
});
}
public updateUserSuppliedOrderCache(order: Order) {
public updateUserSuppliedOrderCache(order: Order): void {
this._dispatch({
data: order,
type: ActionTypes.UpdateUserSuppliedOrderCache,
});
}
public updateShouldBlockchainErrDialogBeOpen(shouldBeOpen: boolean) {
public updateShouldBlockchainErrDialogBeOpen(shouldBeOpen: boolean): void {
this._dispatch({
data: shouldBeOpen,
type: ActionTypes.UpdateShouldBlockchainErrDialogBeOpen,
});
}
public updateChosenAssetToken(side: Side, token: AssetToken) {
public updateChosenAssetToken(side: Side, token: AssetToken): void {
this._dispatch({
data: {
side,
@@ -71,7 +71,7 @@ export class Dispatcher {
type: ActionTypes.UpdateChosenAssetToken,
});
}
public updateChosenAssetTokenAddress(side: Side, address: string) {
public updateChosenAssetTokenAddress(side: Side, address: string): void {
this._dispatch({
data: {
address,
@@ -80,43 +80,43 @@ export class Dispatcher {
type: ActionTypes.UpdateChosenAssetTokenAddress,
});
}
public updateOrderTakerAddress(address: string) {
public updateOrderTakerAddress(address: string): void {
this._dispatch({
data: address,
type: ActionTypes.UpdateOrderTakerAddress,
});
}
public updateUserAddress(address?: string) {
public updateUserAddress(address?: string): void {
this._dispatch({
data: address,
type: ActionTypes.UpdateUserAddress,
});
}
public updateOrderExpiry(unixTimestampSec: BigNumber) {
public updateOrderExpiry(unixTimestampSec: BigNumber): void {
this._dispatch({
data: unixTimestampSec,
type: ActionTypes.UpdateOrderExpiry,
});
}
public encounteredBlockchainError(err: BlockchainErrs) {
public encounteredBlockchainError(err: BlockchainErrs): void {
this._dispatch({
data: err,
type: ActionTypes.BlockchainErrEncountered,
});
}
public updateBlockchainIsLoaded(isLoaded: boolean) {
public updateBlockchainIsLoaded(isLoaded: boolean): void {
this._dispatch({
data: isLoaded,
type: ActionTypes.UpdateBlockchainIsLoaded,
});
}
public addTokenToTokenByAddress(token: Token) {
public addTokenToTokenByAddress(token: Token): void {
this._dispatch({
data: token,
type: ActionTypes.AddTokenToTokenByAddress,
});
}
public removeTokenToTokenByAddress(token: Token) {
public removeTokenToTokenByAddress(token: Token): void {
this._dispatch({
data: token,
type: ActionTypes.RemoveTokenFromTokenByAddress,
@@ -127,7 +127,7 @@ export class Dispatcher {
networkId: number,
userAddressIfExists: string | undefined,
sideToAssetToken: SideToAssetToken,
) {
): void {
this._dispatch({
data: {
tokenByAddress,
@@ -138,36 +138,36 @@ export class Dispatcher {
type: ActionTypes.BatchDispatch,
});
}
public updateTokenByAddress(tokens: Token[]) {
public updateTokenByAddress(tokens: Token[]): void {
this._dispatch({
data: tokens,
type: ActionTypes.UpdateTokenByAddress,
});
}
public forceTokenStateRefetch() {
public forceTokenStateRefetch(): void {
this._dispatch({
type: ActionTypes.ForceTokenStateRefetch,
});
}
public updateECSignature(ecSignature: ECSignature) {
public updateECSignature(ecSignature: ECSignature): void {
this._dispatch({
data: ecSignature,
type: ActionTypes.UpdateOrderECSignature,
});
}
public updateUserWeiBalance(balance: BigNumber) {
public updateUserWeiBalance(balance: BigNumber): void {
this._dispatch({
data: balance,
type: ActionTypes.UpdateUserEtherBalance,
});
}
public updateNetworkId(networkId: number) {
public updateNetworkId(networkId: number): void {
this._dispatch({
data: networkId,
type: ActionTypes.UpdateNetworkId,
});
}
public updateOrderFillAmount(amount: BigNumber) {
public updateOrderFillAmount(amount: BigNumber): void {
this._dispatch({
data: amount,
type: ActionTypes.UpdateOrderFillAmount,
@@ -175,13 +175,13 @@ export class Dispatcher {
}
// Docs
public updateCurrentDocsVersion(version: string) {
public updateCurrentDocsVersion(version: string): void {
this._dispatch({
data: version,
type: ActionTypes.UpdateLibraryVersion,
});
}
public updateAvailableDocVersions(versions: string[]) {
public updateAvailableDocVersions(versions: string[]): void {
this._dispatch({
data: versions,
type: ActionTypes.UpdateAvailableLibraryVersions,
@@ -189,30 +189,30 @@ export class Dispatcher {
}
// Shared
public showFlashMessage(msg: string | React.ReactNode) {
public showFlashMessage(msg: string | React.ReactNode): void {
this._dispatch({
data: msg,
type: ActionTypes.ShowFlashMessage,
});
}
public hideFlashMessage() {
public hideFlashMessage(): void {
this._dispatch({
type: ActionTypes.HideFlashMessage,
});
}
public updateProviderType(providerType: ProviderType) {
public updateProviderType(providerType: ProviderType): void {
this._dispatch({
type: ActionTypes.UpdateProviderType,
data: providerType,
});
}
public updateInjectedProviderName(injectedProviderName: string) {
public updateInjectedProviderName(injectedProviderName: string): void {
this._dispatch({
type: ActionTypes.UpdateInjectedProviderName,
data: injectedProviderName,
});
}
public updateSelectedLanguage(language: Language) {
public updateSelectedLanguage(language: Language): void {
this._dispatch({
type: ActionTypes.UpdateSelectedLanguage,
data: language,

View File

@@ -91,7 +91,7 @@ const INITIAL_STATE: State = {
translate: new Translate(),
};
export function reducer(state: State = INITIAL_STATE, action: Action) {
export function reducer(state: State = INITIAL_STATE, action: Action): State {
switch (action.type) {
// Portal
case ActionTypes.ResetState:

View File

@@ -506,7 +506,7 @@ export interface TokenState {
export interface WebsiteBackendRelayerInfo {
name: string;
dailyTxnVolume: string;
weeklyTxnVolume: string;
url: string;
appUrl?: string;
headerImgUrl?: string;

View File

@@ -5,10 +5,10 @@ import { utils } from 'ts/utils/utils';
import * as Web3 from 'web3';
export const analytics = {
init() {
init(): void {
ReactGA.initialize(configs.GOOGLE_ANALYTICS_ID);
},
logEvent(category: string, action: string, label: string, value?: any) {
logEvent(category: string, action: string, label: string, value?: any): void {
ReactGA.event({
category,
action,
@@ -16,7 +16,7 @@ export const analytics = {
value,
});
},
async logProviderAsync(web3IfExists: Web3) {
async logProviderAsync(web3IfExists: Web3): Promise<void> {
await utils.onPageLoadAsync();
const providerType = !_.isUndefined(web3IfExists)
? utils.getProviderType(web3IfExists.currentProvider)

View File

@@ -1,8 +1,8 @@
import * as _ from 'lodash';
import { ArticlesBySection, WebsiteBackendGasInfo, WebsiteBackendPriceInfo, WebsiteBackendRelayerInfo } from 'ts/types';
import { configs } from 'ts/utils/configs';
import { fetchUtils } from 'ts/utils/fetch_utils';
import { utils } from 'ts/utils/utils';
const ETH_GAS_STATION_ENDPOINT = '/eth_gas_station';
const PRICES_ENDPOINT = '/prices';
@@ -11,7 +11,7 @@ const WIKI_ENDPOINT = '/wiki';
export const backendClient = {
async getGasInfoAsync(): Promise<WebsiteBackendGasInfo> {
const result = await fetchUtils.requestAsync(configs.BACKEND_BASE_URL, ETH_GAS_STATION_ENDPOINT);
const result = await fetchUtils.requestAsync(utils.getBackendBaseUrl(), ETH_GAS_STATION_ENDPOINT);
return result;
},
async getPriceInfoAsync(tokenSymbols: string[]): Promise<WebsiteBackendPriceInfo> {
@@ -22,15 +22,15 @@ export const backendClient = {
const queryParams = {
tokens: joinedTokenSymbols,
};
const result = await fetchUtils.requestAsync(configs.BACKEND_BASE_URL, PRICES_ENDPOINT, queryParams);
const result = await fetchUtils.requestAsync(utils.getBackendBaseUrl(), PRICES_ENDPOINT, queryParams);
return result;
},
async getRelayerInfosAsync(): Promise<WebsiteBackendRelayerInfo[]> {
const result = await fetchUtils.requestAsync(configs.BACKEND_BASE_URL, RELAYERS_ENDPOINT);
const result = await fetchUtils.requestAsync(utils.getBackendBaseUrl(), RELAYERS_ENDPOINT);
return result;
},
async getWikiArticlesBySectionAsync(): Promise<ArticlesBySection> {
const result = await fetchUtils.requestAsync(configs.BACKEND_BASE_URL, WIKI_ENDPOINT);
const result = await fetchUtils.requestAsync(utils.getBackendBaseUrl(), WIKI_ENDPOINT);
return result;
},
};

View File

@@ -1,5 +1,6 @@
import * as _ from 'lodash';
import { Environments, OutdatedWrappedEtherByNetworkId, PublicNodeUrlsByNetworkId } from 'ts/types';
import { utils } from 'ts/utils/utils';
const BASE_URL = window.location.origin;
const isDevelopment = _.includes(
@@ -10,13 +11,15 @@ const INFURA_API_KEY = 'T5WSC8cautR4KXyYgsRs';
export const configs = {
AMOUNT_DISPLAY_PRECSION: 5,
BACKEND_BASE_URL: 'https://website-api.0xproject.com',
BACKEND_BASE_PROD_URL: 'https://website-api.0xproject.com',
BACKEND_BASE_STAGING_URL: 'http://ec2-52-91-181-85.compute-1.amazonaws.com',
BASE_URL,
BITLY_ACCESS_TOKEN: 'ffc4c1a31e5143848fb7c523b39f91b9b213d208',
DEFAULT_DERIVATION_PATH: `44'/60'/0'`,
// WARNING: ZRX & WETH MUST always be default trackedTokens
DEFAULT_TRACKED_TOKEN_SYMBOLS: ['WETH', 'ZRX'],
DOMAIN_STAGING: 'staging-0xproject.s3-website-us-east-1.amazonaws.com',
DOMAIN_DOGFOOD: 'dogfood-0xproject.s3-website-us-east-1.amazonaws.com',
DOMAIN_DEVELOPMENT: '0xproject.localhost:3572',
DOMAIN_PRODUCTION: '0xproject.com',
ENVIRONMENT: isDevelopment ? Environments.DEVELOPMENT : Environments.PRODUCTION,

View File

@@ -42,10 +42,10 @@ export class Translate {
}
this.setLanguage(language);
}
public getLanguage() {
public getLanguage(): Language {
return this._selectedLanguage;
}
public setLanguage(language: Language) {
public setLanguage(language: Language): void {
const isLanguageSupported = !_.isUndefined(languageToTranslations[language]);
if (!isLanguageSupported) {
throw new Error(`${language} not supported`);
@@ -53,7 +53,7 @@ export class Translate {
this._selectedLanguage = language;
this._translation = languageToTranslations[language];
}
public get(key: Key, decoration?: Deco) {
public get(key: Key, decoration?: Deco): string {
let text = this._translation[key];
if (!_.isUndefined(decoration) && !_.includes(languagesWithoutCaps, this._selectedLanguage)) {
switch (decoration) {
@@ -77,7 +77,7 @@ export class Translate {
}
return text;
}
private _capitalize(text: string) {
private _capitalize(text: string): string {
return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
}
}

View File

@@ -24,16 +24,18 @@ import * as u2f from 'ts/vendor/u2f_api';
const LG_MIN_EM = 64;
const MD_MIN_EM = 52;
const isDogfood = (): boolean => _.includes(window.location.href, configs.DOMAIN_DOGFOOD);
export const utils = {
assert(condition: boolean, message: string) {
assert(condition: boolean, message: string): void {
if (!condition) {
throw new Error(message);
}
},
spawnSwitchErr(name: string, value: any) {
spawnSwitchErr(name: string, value: any): Error {
return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
},
isNumeric(n: string) {
isNumeric(n: string): boolean {
return !isNaN(parseFloat(n)) && isFinite(Number(n));
},
// This default unix timestamp is used for orders where the user does not specify an expiry date.
@@ -106,13 +108,13 @@ export const utils = {
};
return order;
},
async sleepAsync(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
async sleepAsync(ms: number): Promise<NodeJS.Timer> {
return new Promise<NodeJS.Timer>(resolve => setTimeout(resolve, ms));
},
deepEqual(actual: any, expected: any, opts?: { strict: boolean }) {
deepEqual(actual: any, expected: any, opts?: { strict: boolean }): boolean {
return deepEqual(actual, expected, opts);
},
getColSize(items: number) {
getColSize(items: number): number {
const bassCssGridSize = 12; // Source: http://basscss.com/#basscss-grid
const colSize = bassCssGridSize / items;
if (!_.isInteger(colSize)) {
@@ -120,7 +122,7 @@ export const utils = {
}
return colSize;
},
getScreenWidth() {
getScreenWidth(): ScreenWidths {
const documentEl = document.documentElement;
const body = document.getElementsByTagName('body')[0];
const widthInPx = window.innerWidth || documentEl.clientWidth || body.clientWidth;
@@ -162,7 +164,7 @@ export const utils = {
// This checks the error message returned from an injected Web3 instance on the page
// after a user was prompted to sign a message or send a transaction and decided to
// reject the request.
didUserDenyWeb3Request(errMsg: string) {
didUserDenyWeb3Request(errMsg: string): boolean {
const metamaskDenialErrMsg = 'User denied';
const paritySignerDenialErrMsg = 'Request has been rejected';
const ledgerDenialErrMsg = 'Invalid status 6985';
@@ -172,7 +174,7 @@ export const utils = {
_.includes(errMsg, ledgerDenialErrMsg);
return isUserDeniedErrMsg;
},
getCurrentEnvironment() {
getCurrentEnvironment(): string {
switch (location.host) {
case configs.DOMAIN_DEVELOPMENT:
return 'development';
@@ -188,7 +190,7 @@ export const utils = {
const truncatedAddress = `${address.substring(0, 6)}...${address.substr(-4)}`; // 0x3d5a...b287
return truncatedAddress;
},
hasUniqueNameAndSymbol(tokens: Token[], token: Token) {
hasUniqueNameAndSymbol(tokens: Token[], token: Token): boolean {
if (token.isRegistered) {
return true; // Since it's registered, it is the canonical token
}
@@ -269,7 +271,7 @@ export const utils = {
);
return isTestNetwork;
},
getCurrentBaseUrl() {
getCurrentBaseUrl(): string {
const port = window.location.port;
const hasPort = !_.isUndefined(port);
const baseUrl = `https://${window.location.hostname}${hasPort ? `:${port}` : ''}`;
@@ -302,10 +304,14 @@ export const utils = {
}
return parsedProviderName;
},
isDevelopment() {
getBackendBaseUrl(): string {
return isDogfood() ? configs.BACKEND_BASE_STAGING_URL : configs.BACKEND_BASE_PROD_URL;
},
isDevelopment(): boolean {
return configs.ENVIRONMENT === Environments.DEVELOPMENT;
},
isStaging() {
isStaging(): boolean {
return _.includes(window.location.href, configs.DOMAIN_STAGING);
},
isDogfood,
};