ghost-portal/packages/apps/src/Apps.tsx
Jaco Greeff 3a9d67f398
Add GlobalStyle component (#1638)
* Add GlobalStyle component

* Move all react-component/styles -> styled-components
2019-09-20 12:05:23 +02:00

186 lines
4.8 KiB
TypeScript

// Copyright 2017-2019 @polkadot/apps authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { BareProps as Props } from '@polkadot/react-components/types';
// this is disabled, Chrome + WASM memory leak makes it slow & laggy. If enabled
// we also need to export the default as hot(Apps) (last line)
// import { hot } from 'react-hot-loader/root';
import React from 'react';
import store from 'store';
import styled from 'styled-components';
import GlobalStyle from '@polkadot/react-components/styles';
import Signer from '@polkadot/react-signer';
import ConnectingOverlay from './overlays/Connecting';
import AccountsOverlay from './overlays/Accounts';
import { SideBarTransition, SIDEBAR_TRANSITION_DURATION, SIDEBAR_MENU_THRESHOLD } from './constants';
import Content from './Content';
import SideBar from './SideBar';
interface State {
isCollapsed: boolean;
isMenu: boolean;
menuOpen: boolean;
transition: SideBarTransition;
}
class Apps extends React.Component<Props, State> {
public state: State;
public constructor (props: Props) {
super(props);
const state = store.get('sidebar') || {};
this.state = {
isCollapsed: false,
menuOpen: false,
transition: SideBarTransition.COLLAPSED,
...state
};
}
public componentDidMount (): void {
this.setState({
menuOpen: false,
isMenu: window.innerWidth < SIDEBAR_MENU_THRESHOLD
});
}
public componentDidUpdate (): void {
this.handleMenuTransition();
}
public render (): React.ReactNode {
const { className } = this.props;
const { isCollapsed, isMenu, menuOpen } = this.state;
return (
<>
<GlobalStyle />
<div className={`apps-Wrapper ${isCollapsed ? 'collapsed' : 'expanded'} ${isMenu && 'fixed'} ${menuOpen && 'menu-open'} theme--default ${className}`}>
{this.renderMenuBg()}
<SideBar
collapse={this.collapse}
handleResize={this.handleResize}
menuOpen={menuOpen}
isCollapsed={isCollapsed}
toggleMenu={this.toggleMenu}
/>
<Signer>
<Content />
</Signer>
<ConnectingOverlay />
<AccountsOverlay />
</div>
</>
);
}
private collapse = (): void => {
this.setState(({ isCollapsed }: State): Pick<State, never> => ({
isCollapsed: !isCollapsed
}), (): void => {
store.set('sidebar', this.state);
});
}
private handleResize = (): void => {
const { isMenu, menuOpen } = this.state;
const dir = window.innerWidth < SIDEBAR_MENU_THRESHOLD ? 'hide' : 'show';
if (!menuOpen) {
if ((isMenu && dir === 'hide') || (!isMenu && dir === 'show')) {
return;
}
}
const transition = (dir === 'hide')
? SideBarTransition.MINIMISED_AND_EXPANDED
: SideBarTransition.EXPANDED_AND_MAXIMISED;
this.toggleMenuResize(transition);
}
private handleMenuTransition = (): void => {
const { transition } = this.state;
switch (transition) {
case SideBarTransition.MINIMISED_AND_EXPANDED:
setTimeout((): void => {
this.setState({
isMenu: true,
isCollapsed: false,
transition: SideBarTransition.COLLAPSED
});
}, SIDEBAR_TRANSITION_DURATION);
break;
case SideBarTransition.EXPANDED_AND_MAXIMISED:
setTimeout((): void => {
this.setState({
isMenu: false,
isCollapsed: store.get('sidebar').isCollapsed,
transition: SideBarTransition.EXPANDED
});
}, SIDEBAR_TRANSITION_DURATION);
break;
default:
break;
}
}
private renderMenuBg = (): React.ReactNode => {
return (
<div
className={`apps-Menu-bg ${this.state.menuOpen ? 'open' : 'closed'}`}
onClick={this.handleResize}
>
</div>
);
}
private toggleMenu = (): void => {
this.setState({
isCollapsed: false,
menuOpen: true
});
}
private toggleMenuResize = (transition: SideBarTransition): void => {
switch (transition) {
case SideBarTransition.MINIMISED_AND_EXPANDED:
this.setState({
isMenu: true,
menuOpen: false,
transition: transition
});
break;
case SideBarTransition.EXPANDED_AND_MAXIMISED:
this.setState({
menuOpen: false,
transition: transition
});
break;
default:
this.setState(({ isCollapsed }: State): Pick<State, never> => ({
isCollapsed: !isCollapsed
}));
break;
}
}
}
export default styled(Apps)`
align-items: stretch;
box-sizing: border-box;
display: flex;
min-height: 100vh;
`;