lbry-desktop/ui/component/page/view.jsx
saltrafael ea9c7a4a27
[Live Chat] Break down componets for Page Layout + Add ability to Pop Out chat window + Hide chat option (#681)
* Refactor CommentBadge

* Refactor livestreamComment component

* Refactor and split livestreamComment CSS

* Refactor livestreamComments component

* Refactor and split livestreamComments CSS

* Remove never used spinner

* Refactor livestream Page

* Refactor page component

* Refactor livestreamLayout component

* Break apart livestreamComments into separate sibling components

- This helps separating LivestreamComments to deal with only the comments, and the LivestreamLayout to be used for its own Page as a Popout option, and also for a layered approach for mobile

* Create Popout Chat Page, Add Popout Chat Menu Option

* Add Hide Chat option

* sockety improvements

* Websocket changes

Co-authored-by: Thomas Zarebczan <thomas.zarebczan@gmail.com>
2022-01-14 15:24:16 -05:00

157 lines
4.5 KiB
JavaScript

// @flow
import { lazyImport } from 'util/lazyImport';
import { MAIN_CLASS } from 'constants/classnames';
import { parseURI } from 'util/lbryURI';
import { useHistory } from 'react-router';
import { useIsMobile, useIsMediumScreen } from 'effects/use-screensize';
import classnames from 'classnames';
import Header from 'component/header';
import React from 'react';
import SettingsSideNavigation from 'component/settingsSideNavigation';
import SideNavigation from 'component/sideNavigation';
import type { Node } from 'react';
import usePersistedState from 'effects/use-persisted-state';
const Footer = lazyImport(() => import('web/component/footer' /* webpackChunkName: "footer" */));
type Props = {
authPage: boolean,
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
},
chatDisabled: boolean,
children: Node | Array<Node>,
className: ?string,
filePage: boolean,
fullWidthPage: boolean,
isMarkdown?: boolean,
livestream?: boolean,
noFooter: boolean,
noHeader: boolean,
noSideNavigation: boolean,
rightSide?: Node,
settingsPage?: boolean,
videoTheaterMode: boolean,
isPopoutWindow?: boolean,
};
function Page(props: Props) {
const {
authPage = false,
backout,
chatDisabled,
children,
className,
filePage = false,
fullWidthPage = false,
isMarkdown = false,
livestream,
noFooter = false,
noHeader = false,
noSideNavigation = false,
rightSide,
settingsPage,
videoTheaterMode,
isPopoutWindow,
} = props;
const {
location: { pathname },
} = useHistory();
const isMediumScreen = useIsMediumScreen();
const isMobile = useIsMobile();
const [sidebarOpen, setSidebarOpen] = usePersistedState('sidebar', false);
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;
React.useEffect(() => {
if (isOnFilePage || isMediumScreen) setSidebarOpen(false);
// TODO: make sure setState callback for usePersistedState uses useCallback to it doesn't cause effect to re-run
}, [isOnFilePage, isMediumScreen, setSidebarOpen]);
return (
<>
{!noHeader && (
<Header
authHeader={authPage}
backout={backout}
sidebarOpen={sidebarOpen}
isAbsoluteSideNavHidden={isAbsoluteSideNavHidden}
setSidebarOpen={setSidebarOpen}
/>
)}
<div
className={classnames('main-wrapper__inner', {
'main-wrapper__inner--filepage': isOnFilePage,
'main-wrapper__inner--theater-mode': isOnFilePage && videoTheaterMode,
'main-wrapper__inner--auth': authPage,
'main--popout-chat': isPopoutWindow,
})}
>
{!authPage &&
(settingsPage ? (
<SettingsSideNavigation />
) : (
!noSideNavigation && (
<SideNavigation
sidebarOpen={sidebarOpen}
setSidebarOpen={setSidebarOpen}
isMediumScreen={isMediumScreen}
isOnFilePage={isOnFilePage}
/>
)
))}
<div
className={classnames({
'sidebar--pusher': fullWidthPage,
'sidebar--pusher--open': sidebarOpen && fullWidthPage,
'sidebar--pusher--filepage': !fullWidthPage,
})}
>
<main
id={'main-content'}
className={classnames(MAIN_CLASS, className, {
'main--full-width': fullWidthPage,
'main--auth-page': authPage,
'main--file-page': filePage,
'main--settings-page': settingsPage,
'main--markdown': isMarkdown,
'main--theater-mode': isOnFilePage && videoTheaterMode && !livestream,
'main--livestream': livestream && !chatDisabled,
'main--popout-chat': isPopoutWindow,
})}
>
{children}
{!isMobile && rightSide && (!livestream || !chatDisabled) && (
<div className="main__right-side">{rightSide}</div>
)}
</main>
{!noFooter && (
<React.Suspense fallback={null}>
<Footer />
</React.Suspense>
)}
</div>
</div>
</>
);
}
export default Page;