Merge pull request #648 from 0xProject/feature/website/fill-order
Add shared order support
This commit is contained in:
commit
9ca41b9536
@ -38,6 +38,7 @@ import {
|
||||
} from 'ts/types';
|
||||
import { configs } from 'ts/utils/configs';
|
||||
import { constants } from 'ts/utils/constants';
|
||||
import { orderParser } from 'ts/utils/order_parser';
|
||||
import { Translate } from 'ts/utils/translate';
|
||||
import { utils } from 'ts/utils/utils';
|
||||
|
||||
@ -86,7 +87,7 @@ export class LegacyPortal extends React.Component<LegacyPortalProps, LegacyPorta
|
||||
}
|
||||
constructor(props: LegacyPortalProps) {
|
||||
super(props);
|
||||
this._sharedOrderIfExists = this._getSharedOrderIfExists();
|
||||
this._sharedOrderIfExists = orderParser.parse(window.location.search);
|
||||
this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
|
||||
|
||||
const isViewingBalances = _.includes(props.location.pathname, `${WebsitePaths.Portal}/balances`);
|
||||
@ -362,32 +363,6 @@ export class LegacyPortal extends React.Component<LegacyPortalProps, LegacyPorta
|
||||
isWethNoticeDialogOpen: false,
|
||||
});
|
||||
}
|
||||
private _getSharedOrderIfExists(): Order | undefined {
|
||||
const queryString = window.location.search;
|
||||
if (queryString.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
const queryParams = queryString.substring(1).split('&');
|
||||
const orderQueryParam = _.find(queryParams, queryParam => {
|
||||
const queryPair = queryParam.split('=');
|
||||
return queryPair[0] === 'order';
|
||||
});
|
||||
if (_.isUndefined(orderQueryParam)) {
|
||||
return undefined;
|
||||
}
|
||||
const orderPair = orderQueryParam.split('=');
|
||||
if (orderPair.length !== 2) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const order = JSON.parse(decodeURIComponent(orderPair[1]));
|
||||
const validationResult = validator.validate(order, portalOrderSchema);
|
||||
if (validationResult.errors.length > 0) {
|
||||
logUtils.log(`Invalid shared order: ${validationResult.errors}`);
|
||||
return undefined;
|
||||
}
|
||||
return order;
|
||||
}
|
||||
private _updateScreenWidth(): void {
|
||||
const newScreenWidth = utils.getScreenWidth();
|
||||
this.props.dispatcher.updateScreenWidth(newScreenWidth);
|
||||
|
@ -43,9 +43,14 @@ export const defaultMenuItemEntries: MenuItemEntry[] = [
|
||||
iconName: 'zmdi-circle-o',
|
||||
},
|
||||
{
|
||||
to: `${WebsitePaths.Portal}/direct`,
|
||||
labelText: 'Trade direct',
|
||||
iconName: 'zmdi-swap',
|
||||
to: `${WebsitePaths.Portal}/generate`,
|
||||
labelText: 'Generate order',
|
||||
iconName: 'zmdi-arrow-right-top',
|
||||
},
|
||||
{
|
||||
to: `${WebsitePaths.Portal}/fill`,
|
||||
labelText: 'Fill order',
|
||||
iconName: 'zmdi-arrow-left-bottom',
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -10,6 +10,7 @@ import { BlockchainErrDialog } from 'ts/components/dialogs/blockchain_err_dialog
|
||||
import { LedgerConfigDialog } from 'ts/components/dialogs/ledger_config_dialog';
|
||||
import { PortalDisclaimerDialog } from 'ts/components/dialogs/portal_disclaimer_dialog';
|
||||
import { EthWrappers } from 'ts/components/eth_wrappers';
|
||||
import { FillOrder } from 'ts/components/fill_order';
|
||||
import { AssetPicker } from 'ts/components/generate_order/asset_picker';
|
||||
import { BackButton } from 'ts/components/portal/back_button';
|
||||
import { Loading } from 'ts/components/portal/loading';
|
||||
@ -42,6 +43,7 @@ import {
|
||||
} from 'ts/types';
|
||||
import { configs } from 'ts/utils/configs';
|
||||
import { constants } from 'ts/utils/constants';
|
||||
import { orderParser } from 'ts/utils/order_parser';
|
||||
import { Translate } from 'ts/utils/translate';
|
||||
import { utils } from 'ts/utils/utils';
|
||||
|
||||
@ -116,9 +118,11 @@ const styles: Styles = {
|
||||
|
||||
export class Portal extends React.Component<PortalProps, PortalState> {
|
||||
private _blockchain: Blockchain;
|
||||
private _sharedOrderIfExists: Order;
|
||||
private _throttledScreenWidthUpdate: () => void;
|
||||
constructor(props: PortalProps) {
|
||||
super(props);
|
||||
this._sharedOrderIfExists = orderParser.parse(window.location.search);
|
||||
this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
|
||||
const didAcceptPortalDisclaimer = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER);
|
||||
const hasAcceptedDisclaimer =
|
||||
@ -336,9 +340,14 @@ export class Portal extends React.Component<PortalProps, PortalState> {
|
||||
render: this._renderTradeHistory.bind(this),
|
||||
},
|
||||
{
|
||||
pathName: `${WebsitePaths.Portal}/direct`,
|
||||
headerText: 'Trade Direct',
|
||||
render: this._renderTradeDirect.bind(this),
|
||||
pathName: `${WebsitePaths.Portal}/generate`,
|
||||
headerText: 'Generate Order',
|
||||
render: this._renderGenerateOrderForm.bind(this),
|
||||
},
|
||||
{
|
||||
pathName: `${WebsitePaths.Portal}/fill`,
|
||||
headerText: 'Fill Order',
|
||||
render: this._renderFillOrder.bind(this),
|
||||
},
|
||||
];
|
||||
return (
|
||||
@ -386,7 +395,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
|
||||
/>
|
||||
);
|
||||
}
|
||||
private _renderTradeDirect(match: any, location: Location, history: History): React.ReactNode {
|
||||
private _renderGenerateOrderForm(): React.ReactNode {
|
||||
return (
|
||||
<GenerateOrderForm
|
||||
blockchain={this._blockchain}
|
||||
@ -395,6 +404,25 @@ export class Portal extends React.Component<PortalProps, PortalState> {
|
||||
/>
|
||||
);
|
||||
}
|
||||
private _renderFillOrder(): React.ReactNode {
|
||||
const initialFillOrder = !_.isUndefined(this.props.userSuppliedOrderCache)
|
||||
? this.props.userSuppliedOrderCache
|
||||
: this._sharedOrderIfExists;
|
||||
return (
|
||||
<FillOrder
|
||||
blockchain={this._blockchain}
|
||||
blockchainErr={this.props.blockchainErr}
|
||||
initialOrder={initialFillOrder}
|
||||
isOrderInUrl={!_.isUndefined(this._sharedOrderIfExists)}
|
||||
orderFillAmount={this.props.orderFillAmount}
|
||||
networkId={this.props.networkId}
|
||||
userAddress={this.props.userAddress}
|
||||
tokenByAddress={this.props.tokenByAddress}
|
||||
dispatcher={this.props.dispatcher}
|
||||
lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
|
||||
/>
|
||||
);
|
||||
}
|
||||
private _renderTokenBalances(): React.ReactNode {
|
||||
const allTokens = _.values(this.props.tokenByAddress);
|
||||
const trackedTokens = _.filter(allTokens, t => t.isTracked);
|
||||
|
33
packages/website/ts/utils/order_parser.ts
Normal file
33
packages/website/ts/utils/order_parser.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { logUtils } from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { portalOrderSchema } from 'ts/schemas/portal_order_schema';
|
||||
import { validator } from 'ts/schemas/validator';
|
||||
import { Order } from 'ts/types';
|
||||
|
||||
export const orderParser = {
|
||||
parse(queryString: string): Order | undefined {
|
||||
if (queryString.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
const queryParams = queryString.substring(1).split('&');
|
||||
const orderQueryParam = _.find(queryParams, queryParam => {
|
||||
const queryPair = queryParam.split('=');
|
||||
return queryPair[0] === 'order';
|
||||
});
|
||||
if (_.isUndefined(orderQueryParam)) {
|
||||
return undefined;
|
||||
}
|
||||
const orderPair = orderQueryParam.split('=');
|
||||
if (orderPair.length !== 2) {
|
||||
return undefined;
|
||||
}
|
||||
const order = JSON.parse(decodeURIComponent(orderPair[1]));
|
||||
const validationResult = validator.validate(order, portalOrderSchema);
|
||||
if (validationResult.errors.length > 0) {
|
||||
logUtils.log(`Invalid shared order: ${validationResult.errors}`);
|
||||
return undefined;
|
||||
}
|
||||
return order;
|
||||
},
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user