lbry-desktop/ui/component/page/view.jsx

158 lines
4.3 KiB
React
Raw Permalink Normal View History

2018-03-26 23:32:43 +02:00
// @flow
2019-08-27 16:43:42 +02:00
import type { Node } from 'react';
import React, { Fragment } from 'react';
2018-03-26 23:32:43 +02:00
import classnames from 'classnames';
import { lazyImport } from 'util/lazyImport';
2019-12-18 06:27:08 +01:00
import SideNavigation from 'component/sideNavigation';
import SettingsSideNavigation from 'component/settingsSideNavigation';
2019-08-27 16:43:42 +02:00
import Header from 'component/header';
/* @if TARGET='app' */
import StatusBar from 'component/common/status-bar';
/* @endif */
2020-08-10 22:47:39 +02:00
import usePersistedState from 'effects/use-persisted-state';
import { useHistory } from 'react-router';
import { useIsMobile, useIsMediumScreen } from 'effects/use-screensize';
import { parseURI } from 'lbry-redux';
2018-03-26 23:32:43 +02:00
const Footer = lazyImport(() => import('web/component/footer' /* webpackChunkName: "secondary" */));
2021-06-11 08:06:29 +02:00
2019-10-21 00:41:28 +02:00
export const MAIN_CLASS = 'main';
2018-03-26 23:32:43 +02:00
type Props = {
2019-08-27 16:43:42 +02:00
children: Node | Array<Node>,
2019-01-09 19:39:05 +01:00
className: ?string,
2019-08-27 16:43:42 +02:00
autoUpdateDownloaded: boolean,
isUpgradeAvailable: boolean,
2019-10-28 15:04:37 +01:00
authPage: boolean,
2020-08-10 22:47:39 +02:00
filePage: boolean,
settingsPage?: boolean,
noHeader: boolean,
2020-05-08 18:48:58 +02:00
noFooter: boolean,
2020-06-01 19:03:19 +02:00
noSideNavigation: boolean,
2020-08-21 17:49:13 +02:00
fullWidthPage: boolean,
2021-01-08 16:21:27 +01:00
videoTheaterMode: boolean,
2021-03-12 17:18:09 +01:00
isMarkdown?: boolean,
livestream?: boolean,
chatDisabled: boolean,
2021-04-23 21:59:48 +02:00
rightSide?: Node,
backout: {
backLabel?: string,
backNavDefault?: string,
title: string,
simpleTitle: string, // Just use the same value as `title` if `title` is already short (~< 10 chars), unless you have a better idea for title overlfow on mobile
},
2018-03-26 23:32:43 +02:00
};
2019-06-17 22:32:38 +02:00
function Page(props: Props) {
2020-06-29 21:54:07 +02:00
const {
children,
className,
2020-08-10 22:47:39 +02:00
filePage = false,
settingsPage,
2020-08-21 17:49:13 +02:00
authPage = false,
fullWidthPage = false,
2020-06-29 21:54:07 +02:00
noHeader = false,
noFooter = false,
noSideNavigation = false,
backout,
2021-01-08 16:21:27 +01:00
videoTheaterMode,
2021-03-12 17:18:09 +01:00
isMarkdown = false,
livestream,
2021-04-23 21:59:48 +02:00
rightSide,
chatDisabled,
2020-06-29 21:54:07 +02:00
} = props;
2021-01-08 16:21:27 +01:00
2020-08-10 22:47:39 +02:00
const {
location: { pathname },
} = useHistory();
const [sidebarOpen, setSidebarOpen] = usePersistedState('sidebar', false);
2020-08-10 22:47:39 +02:00
const isMediumScreen = useIsMediumScreen();
const isMobile = useIsMobile();
2020-08-21 17:49:13 +02:00
2020-08-10 22:47:39 +02:00
let isOnFilePage = false;
try {
const url = pathname.slice(1).replace(/:/g, '#');
const { isChannel } = parseURI(url);
if (!isChannel) {
isOnFilePage = true;
}
} catch (e) {}
const isAbsoluteSideNavHidden = (isOnFilePage || isMobile) && !sidebarOpen;
function getSideNavElem() {
if (!authPage) {
if (settingsPage) {
return <SettingsSideNavigation />;
} else if (!noSideNavigation) {
return (
<SideNavigation
sidebarOpen={sidebarOpen}
setSidebarOpen={setSidebarOpen}
isMediumScreen={isMediumScreen}
isOnFilePage={isOnFilePage}
/>
);
}
}
return null;
}
2020-08-10 22:47:39 +02:00
React.useEffect(() => {
if (isOnFilePage || isMediumScreen) {
setSidebarOpen(false);
}
2020-12-17 19:43:47 +01:00
// TODO: make sure setState callback for usePersistedState uses useCallback to it doesn't cause effect to re-run
}, [isOnFilePage, isMediumScreen]);
2019-06-17 22:32:38 +02:00
2019-08-27 16:43:42 +02:00
return (
<Fragment>
2020-08-10 22:47:39 +02:00
{!noHeader && (
<Header
authHeader={authPage}
backout={backout}
sidebarOpen={sidebarOpen}
isAbsoluteSideNavHidden={isAbsoluteSideNavHidden}
setSidebarOpen={setSidebarOpen}
/>
)}
2021-01-08 16:21:27 +01:00
<div
className={classnames('main-wrapper__inner', {
'main-wrapper__inner--filepage': isOnFilePage,
'main-wrapper__inner--theater-mode': isOnFilePage && videoTheaterMode,
})}
>
{getSideNavElem()}
2020-08-10 22:47:39 +02:00
<main
id={'main-content'}
2020-08-21 17:49:13 +02:00
className={classnames(MAIN_CLASS, className, {
'main--full-width': fullWidthPage,
'main--auth-page': authPage,
'main--file-page': filePage,
'main--settings-page': settingsPage,
2021-03-12 17:18:09 +01:00
'main--markdown': isMarkdown,
'main--theater-mode': isOnFilePage && videoTheaterMode && !livestream,
'main--livestream': livestream && !chatDisabled,
2020-08-21 17:49:13 +02:00
})}
2020-08-10 22:47:39 +02:00
>
{children}
2021-04-23 21:59:48 +02:00
{!isMobile && rightSide && <div className="main__right-side">{rightSide}</div>}
2020-08-10 22:47:39 +02:00
</main>
{/* @if TARGET='app' */}
<StatusBar />
{/* @endif */}
2019-08-27 16:43:42 +02:00
</div>
2020-05-08 18:48:58 +02:00
{/* @if TARGET='web' */}
2021-06-25 10:02:45 +02:00
{!noFooter && (
<React.Suspense fallback={null}>
<Footer />
</React.Suspense>
)}
2020-05-08 18:48:58 +02:00
{/* @endif */}
2019-08-27 16:43:42 +02:00
</Fragment>
);
}
2018-03-26 23:32:43 +02:00
export default Page;