// @flow import { observable } from "mobx"; import { observer, inject } from "mobx-react"; import * as React from "react"; import { Helmet } from "react-helmet"; import { withTranslation, type TFunction } from "react-i18next"; import keydown from "react-keydown"; import { Switch, Route, Redirect } from "react-router-dom"; import styled, { withTheme } from "styled-components"; import breakpoint from "styled-components-breakpoint"; import AuthStore from "stores/AuthStore"; import DocumentsStore from "stores/DocumentsStore"; import UiStore from "stores/UiStore"; import ErrorSuspended from "scenes/ErrorSuspended"; import KeyboardShortcuts from "scenes/KeyboardShortcuts"; import Analytics from "components/Analytics"; import DocumentHistory from "components/DocumentHistory"; import { GlobalStyles } from "components/DropToImport"; import Flex from "components/Flex"; import { LoadingIndicatorBar } from "components/LoadingIndicator"; import Modal from "components/Modal"; import Sidebar from "components/Sidebar"; import SettingsSidebar from "components/Sidebar/Settings"; import { type Theme } from "types"; import { homeUrl, searchUrl, matchDocumentSlug as slug, } from "utils/routeHelpers"; type Props = { documents: DocumentsStore, children?: ?React.Node, actions?: ?React.Node, title?: ?React.Node, auth: AuthStore, ui: UiStore, notifications?: React.Node, theme: Theme, i18n: Object, t: TFunction, }; @observer class Layout extends React.Component { scrollable: ?HTMLDivElement; @observable redirectTo: ?string; @observable keyboardShortcutsOpen: boolean = false; constructor(props: Props) { super(); this.updateBackground(props); } componentDidUpdate() { this.updateBackground(this.props); if (this.redirectTo) { this.redirectTo = undefined; } } updateBackground(props: Props) { // ensure the wider page color always matches the theme window.document.body.style.background = props.theme.background; } @keydown("shift+/") handleOpenKeyboardShortcuts() { if (this.props.ui.editMode) return; this.keyboardShortcutsOpen = true; } handleCloseKeyboardShortcuts = () => { this.keyboardShortcutsOpen = false; }; @keydown(["t", "/", "meta+k"]) goToSearch(ev: SyntheticEvent<>) { if (this.props.ui.editMode) return; ev.preventDefault(); ev.stopPropagation(); this.redirectTo = searchUrl(); } @keydown("d") goToDashboard() { if (this.props.ui.editMode) return; this.redirectTo = homeUrl(); } render() { const { auth, t, ui } = this.props; const { user, team } = auth; const showSidebar = auth.authenticated && user && team; if (auth.isSuspended) return ; if (this.redirectTo) return ; return ( {team && team.name ? team.name : "Outline"} {this.props.ui.progressBarVisible && } {this.props.notifications} {showSidebar && ( )} {this.props.children} ); } } const Container = styled(Flex)` background: ${(props) => props.theme.background}; transition: ${(props) => props.theme.backgroundTransition}; position: relative; width: 100%; min-height: 100%; `; const Content = styled(Flex)` margin: 0; transition: margin-left 100ms ease-out; @media print { margin: 0; } ${breakpoint("tablet")` margin-left: ${(props) => (props.editMode ? 0 : props.theme.sidebarWidth)}; `}; `; export default withTranslation()( inject("auth", "ui", "documents")(withTheme(Layout)) );