import { DocsInfo, DocsMenu } from '@0xproject/react-docs'; import { colors, constants as sharedConstants, MenuSubsectionsBySection, NestedSidebarMenu, Styles, } from '@0xproject/react-shared'; import * as _ from 'lodash'; import Drawer from 'material-ui/Drawer'; import Menu from 'material-ui/Menu'; import MenuItem from 'material-ui/MenuItem'; import * as React from 'react'; import { Link } from 'react-router-dom'; import { Blockchain } from 'ts/blockchain'; import { DrawerMenu } from 'ts/components/portal/drawer_menu'; import { ProviderDisplay } from 'ts/components/top_bar/provider_display'; import { TopBarMenuItem } from 'ts/components/top_bar/top_bar_menu_item'; import { Container } from 'ts/components/ui/container'; import { DropDown } from 'ts/components/ui/drop_down'; import { Dispatcher } from 'ts/redux/dispatcher'; import { Deco, Key, ProviderType, WebsiteLegacyPaths, WebsitePaths } from 'ts/types'; import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; export enum TopBarDisplayType { Default, Expanded, } export interface TopBarProps { userAddress?: string; networkId?: number; injectedProviderName?: string; providerType?: ProviderType; onToggleLedgerDialog?: () => void; blockchain?: Blockchain; dispatcher?: Dispatcher; blockchainIsLoaded: boolean; location: Location; translate: Translate; docsVersion?: string; availableDocVersions?: string[]; menu?: DocsMenu; menuSubsectionsBySection?: MenuSubsectionsBySection; displayType?: TopBarDisplayType; docsInfo?: DocsInfo; style?: React.CSSProperties; isNightVersion?: boolean; onVersionSelected?: (semver: string) => void; sidebarHeader?: React.ReactNode; maxWidth?: number; paddingLeft?: number; paddingRight?: number; } interface TopBarState { isDrawerOpen: boolean; } const styles: Styles = { topBar: { backgroundColor: colors.white, width: '100%', position: 'relative', top: 0, paddingBottom: 1, zIndex: 1, }, bottomBar: { boxShadow: 'rgba(0, 0, 0, 0.187647) 0px 1px 3px', }, menuItem: { fontSize: 14, color: colors.darkestGrey, paddingTop: 6, paddingBottom: 6, cursor: 'pointer', fontWeight: 400, }, }; const DOC_WEBSITE_PATHS_TO_KEY = { [WebsitePaths.SolCov]: Key.SolCov, [WebsitePaths.SmartContracts]: Key.SmartContracts, [WebsitePaths.Web3Wrapper]: Key.Web3Wrapper, [WebsitePaths.SolCompiler]: Key.SolCompiler, [WebsitePaths.JSONSchemas]: Key.JsonSchemas, [WebsitePaths.Subproviders]: Key.Subproviders, [WebsitePaths.ContractWrappers]: Key.ContractWrappers, [WebsitePaths.Connect]: Key.Connect, [WebsitePaths.ZeroExJs]: Key.ZeroExJs, [WebsitePaths.OrderUtils]: Key.OrderUtils, [WebsitePaths.OrderWatcher]: Key.OrderWatcher, }; const DEFAULT_HEIGHT = 68; const EXPANDED_HEIGHT = 75; export class TopBar extends React.Component { public static defaultProps: Partial = { displayType: TopBarDisplayType.Default, style: {}, isNightVersion: false, paddingLeft: 20, paddingRight: 20, }; public static heightForDisplayType(displayType: TopBarDisplayType): number { const result = displayType === TopBarDisplayType.Expanded ? EXPANDED_HEIGHT : DEFAULT_HEIGHT; return result + 1; } constructor(props: TopBarProps) { super(props); this.state = { isDrawerOpen: false, }; } public componentWillReceiveProps(nextProps: TopBarProps): void { if (nextProps.location.pathname !== this.props.location.pathname) { this.setState({ isDrawerOpen: false, }); } } public render(): React.ReactNode { const isNightVersion = this.props.isNightVersion; const isExpandedDisplayType = this.props.displayType === TopBarDisplayType.Expanded; const parentClassNames = !isExpandedDisplayType ? 'flex mx-auto items-center max-width-4' : 'flex mx-auto items-center'; const height = isExpandedDisplayType ? EXPANDED_HEIGHT : DEFAULT_HEIGHT; const developerSectionMenuItems = [ , , , , , , , , , , , , , , , ]; const bottomBorderStyle = this._shouldDisplayBottomBar() ? styles.bottomBar : {}; const fullWidthClasses = isExpandedDisplayType ? 'pr4' : ''; const logoUrl = isNightVersion ? '/images/protocol_logo_white.png' : '/images/protocol_logo_black.png'; const menuClasses = `col col-${ isExpandedDisplayType ? '4' : '5' } ${fullWidthClasses} lg-pr0 md-pr2 sm-hide xs-hide`; const menuIconStyle = { fontSize: 25, color: isNightVersion ? 'white' : 'black', cursor: 'pointer', }; const activeNode = (
{this.props.translate.get(Key.Developers, Deco.Cap)}
); const popoverContent = {developerSectionMenuItems}; return (
{!this._isViewingPortal() && (
)} {this._isViewingPortal() && (
)}
{this._isViewingPortal() ? this._renderPortalDrawer() : this._renderDrawer()}
); } private _renderPortalDrawer(): React.ReactNode { return ( ); } private _renderDrawer(): React.ReactNode { return (
{this._renderDocsMenu()} {this._renderWiki()}
{this.props.translate.get(Key.Website, Deco.Cap)}
{this.props.translate.get(Key.Home, Deco.Cap)} {this.props.translate.get(Key.Wiki, Deco.Cap)} {_.map(DOC_WEBSITE_PATHS_TO_KEY, (key, websitePath) => { if (!this._doesUrlInclude(websitePath)) { return ( {this.props.translate.get(key, Deco.Cap)}{' '} {this.props.translate.get(Key.Docs, Deco.Cap)} ); } return null; })} {!this._isViewingPortal() && ( {this.props.translate.get(Key.PortalDApp, Deco.CapWords)} )} {this.props.translate.get(Key.Whitepaper, Deco.Cap)} {this.props.translate.get(Key.About, Deco.Cap)} {this.props.translate.get(Key.Blog, Deco.Cap)} {this.props.translate.get(Key.Faq, Deco.Cap)}
); } private _renderDocsMenu(): React.ReactNode { const isViewingDocsPage = _.some(DOC_WEBSITE_PATHS_TO_KEY, (_key, websitePath) => { return this._doesUrlInclude(websitePath); }); // HACK: We need to make sure the SCROLL_CONTAINER is loaded before rendering the Sidebar // because the sidebar renders `react-scroll` links which depend on the scroll container already // being rendered. const documentationContainer = document.getElementById(sharedConstants.SCROLL_CONTAINER_ID); if (!isViewingDocsPage || _.isUndefined(this.props.menu) || _.isNull(documentationContainer)) { return undefined; } return (
); } private _renderWiki(): React.ReactNode { if (!this._isViewingWiki()) { return undefined; } return (
); } private _onMenuButtonClick(): void { this.setState({ isDrawerOpen: !this.state.isDrawerOpen, }); } private _isViewingPortal(): boolean { return _.includes(this.props.location.pathname, WebsitePaths.Portal); } private _isViewingDocs(): boolean { return _.includes(this.props.location.pathname, WebsitePaths.Docs); } private _isViewingFAQ(): boolean { return _.includes(this.props.location.pathname, WebsitePaths.FAQ); } private _doesUrlInclude(aPath: string): boolean { return _.includes(this.props.location.pathname, aPath); } private _isViewingWiki(): boolean { return _.includes(this.props.location.pathname, WebsitePaths.Wiki); } private _shouldDisplayBottomBar(): boolean { const isViewingDocsPage = _.some(DOC_WEBSITE_PATHS_TO_KEY, (_key, websitePath) => { return this._doesUrlInclude(websitePath); }); return ( isViewingDocsPage || this._isViewingWiki() || this._isViewingFAQ() || this._isViewingDocs() || this._isViewingPortal() ); } } // tslint:disable:max-file-line-count