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

303 lines
9.8 KiB
React
Raw Normal View History

2018-03-26 23:32:43 +02:00
// @flow
2021-12-21 13:42:28 +01:00
import 'scss/component/_header.scss';
import { formatCredits } from 'util/format-credits';
import { useIsMobile } from 'effects/use-screensize';
import { withRouter } from 'react-router';
2018-11-26 02:21:25 +01:00
import * as ICONS from 'constants/icons';
2019-08-21 22:54:44 +02:00
import * as PAGES from 'constants/pages';
2018-03-26 23:32:43 +02:00
import Button from 'component/button';
import classnames from 'classnames';
import HeaderMenuButtons from 'component/headerMenuButtons';
import HeaderProfileMenuButton from 'component/headerProfileMenuButton';
import Logo from 'component/logo';
2020-08-10 22:47:39 +02:00
import NotificationBubble from 'component/notificationBubble';
import React from 'react';
import Skeleton from '@mui/material/Skeleton';
import SkipNavigationButton from 'component/skipNavigationButton';
import Tooltip from 'component/common/tooltip';
import WunderBar from 'component/wunderbar';
2019-10-09 18:34:18 +02:00
2018-03-26 23:32:43 +02:00
type Props = {
authenticated: boolean,
2019-10-28 15:04:37 +01:00
authHeader: boolean,
authRedirect?: string, // Redirects to '/' by default.
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
},
balance: number,
emailToVerify?: string,
hasNavigated: boolean,
hideBalance: boolean,
hideCancel: boolean,
history: {
goBack: () => void,
location: { pathname: string },
push: (string) => void,
replace: (string) => void,
},
isAbsoluteSideNavHidden: boolean,
2020-08-10 22:47:39 +02:00
sidebarOpen: boolean,
syncError: ?string,
totalBalance?: number,
user: ?User,
prefsReady: boolean,
doClearClaimSearch: () => void,
clearEmailEntry: () => void,
clearPasswordEntry: () => void,
openChangelog: ({}) => void,
setSidebarOpen: (boolean) => void,
signOut: () => void,
2018-03-26 23:32:43 +02:00
};
const Header = (props: Props) => {
2019-08-21 22:54:44 +02:00
const {
authenticated,
authHeader,
authRedirect,
backout,
balance,
emailToVerify,
hideBalance,
hideCancel,
history,
isAbsoluteSideNavHidden,
sidebarOpen,
syncError,
totalBalance,
user,
prefsReady,
doClearClaimSearch,
clearEmailEntry,
clearPasswordEntry,
openChangelog,
2020-08-10 22:47:39 +02:00
setSidebarOpen,
signOut,
2019-08-21 22:54:44 +02:00
} = props;
const {
location: { pathname },
goBack,
push,
} = history;
const isMobile = useIsMobile();
2019-11-22 22:13:00 +01:00
// on the verify page don't let anyone escape other than by closing the tab to keep session data consistent
const isVerifyPage = pathname.includes(PAGES.AUTH_VERIFY);
const isSignUpPage = pathname.includes(PAGES.AUTH);
const isSignInPage = pathname.includes(PAGES.AUTH_SIGNIN);
const isPwdResetPage = pathname.includes(PAGES.AUTH_PASSWORD_RESET);
2021-12-21 20:01:27 +01:00
const iYTSyncPage = pathname.includes(PAGES.YOUTUBE_SYNC);
// For pages that allow for "backing out", shows a backout option instead of the Home logo
const canBackout = Boolean(backout);
const { backLabel, backNavDefault, title: backTitle, simpleTitle: simpleBackTitle } = backout || {};
const balanceLoading = totalBalance === undefined;
const roundedSpendableBalance = formatCredits(balance, 2, true);
const roundedTotalBalance = formatCredits(totalBalance, 2, true);
// Sign out if they click the "x" when they are on the password prompt
const authHeaderAction = syncError && { onClick: signOut };
const homeButtonNavigationProps = (isVerifyPage && {}) || (authHeader && authHeaderAction) || { navigate: '/' };
const sidebarLabel = sidebarOpen
? __('Close sidebar - hide channels you are following.')
: __('Expand sidebar - view channels you are following.');
2018-03-26 23:32:43 +02:00
const authRedirectParam = authRedirect ? `?redirect=${authRedirect}` : '';
const onBackout = React.useCallback(
(e: any) => {
const { hasNavigated } = props;
const { replace } = history;
window.removeEventListener('popstate', onBackout);
if (e.type !== 'popstate') {
// if not initiated by pop (back button)
if (hasNavigated && !backNavDefault) {
goBack();
} else {
replace(backNavDefault || `/`);
}
}
},
[backNavDefault, goBack, history, props]
);
2020-07-27 16:43:55 +02:00
React.useEffect(() => {
if (canBackout) {
2020-07-27 16:43:55 +02:00
window.addEventListener('popstate', onBackout);
return () => window.removeEventListener('popstate', onBackout);
}
}, [canBackout, onBackout]);
2020-07-27 16:43:55 +02:00
2021-12-21 13:42:28 +01:00
const userButtons = (hideWallet?: boolean, hideProfile?: boolean) => (
<div className="header__menu--right">
{isMobile && !authHeader && !canBackout && <WunderBar />}
{authenticated ? (
<>
2021-12-21 13:42:28 +01:00
{!hideWallet && (
<Tooltip
title={
balance > 0
? __('Immediately spendable: %spendable_balance%', { spendable_balance: roundedSpendableBalance })
: __('Your Wallet')
}
>
<div>
{balanceLoading ? (
<Skeleton variant="text" animation="wave" className="header__navigationItem--balanceLoading" />
) : (
<Button
navigate={`/$/${PAGES.WALLET}`}
className="button--file-action header__navigationItem--balance"
2021-12-21 19:49:18 +01:00
label={
hideBalance || Number(roundedTotalBalance) === 0 || !prefsReady
? __(isMobile ? 'Wallet' : 'Your Wallet')
2021-12-21 19:49:18 +01:00
: roundedTotalBalance
}
icon={ICONS.LBC}
/>
)}
2021-12-21 13:42:28 +01:00
</div>
</Tooltip>
)}
2018-03-26 23:32:43 +02:00
2021-12-21 13:42:28 +01:00
{!hideProfile && <HeaderProfileMenuButton />}
</>
) : !isMobile ? (
2021-12-21 13:42:28 +01:00
<div className="header__authButtons">
<Button
navigate={`/$/${PAGES.AUTH_SIGNIN}${authRedirectParam}`}
button="link"
label={__('Log In')}
disabled={user === null}
/>
<Button
navigate={`/$/${PAGES.AUTH}${authRedirectParam}`}
button="primary"
label={__('Sign Up')}
disabled={user === null}
/>
</div>
) : (
<HeaderProfileMenuButton />
)}
2020-11-10 06:21:04 +01:00
</div>
);
2017-06-06 23:19:12 +02:00
return (
<header className={classnames('header', { 'header--minimal': authHeader })}>
2021-12-21 13:42:28 +01:00
{!authHeader && canBackout ? (
<div className="card__actions--between header__contents">
<div className="header__menu--left">
<Button onClick={onBackout} button="link" label={backLabel || __('Cancel')} icon={ICONS.ARROW_LEFT} />
2021-12-21 13:42:28 +01:00
</div>
2021-12-21 13:42:28 +01:00
{backTitle && <h1 className="header__authTitle">{(isMobile && simpleBackTitle) || backTitle}</h1>}
2021-12-21 13:42:28 +01:00
{userButtons(false, isMobile)}
</div>
) : (
<>
<div className="header__navigation">
<div className="header__menu--left">
<SkipNavigationButton />
2020-08-11 22:32:03 +02:00
{!authHeader && (
<span style={{ position: 'relative' }}>
<Button
aria-label={sidebarLabel}
className="header__navigationItem--icon button-rotate"
2020-08-11 22:32:03 +02:00
icon={ICONS.MENU}
aria-expanded={sidebarOpen}
2020-08-11 22:32:03 +02:00
onClick={() => setSidebarOpen(!sidebarOpen)}
/>
{isAbsoluteSideNavHidden && isMobile && <NotificationBubble />}
2020-08-11 22:32:03 +02:00
</span>
)}
2020-06-29 21:54:07 +02:00
<Button
aria-label={__('Home')}
2021-12-21 13:42:28 +01:00
className="header__navigationItem--logo"
onClick={() => {
if (pathname === '/') {
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' });
doClearClaimSearch();
}
}}
2020-06-29 21:54:07 +02:00
{...homeButtonNavigationProps}
2021-07-21 17:33:28 +02:00
>
<Logo />
</Button>
2021-12-13 09:17:30 +01:00
{/* @if process.env.DEV_CHANGELOG */}
{history.location.pathname === '/' && (
<Button
title="Changelog"
2021-12-13 09:17:30 +01:00
className="badge--alert"
label="Changelog"
2021-12-13 09:17:30 +01:00
icon={ICONS.FEEDBACK}
onClick={() =>
openChangelog({
2021-12-13 09:17:30 +01:00
title: __('Changelog'),
subtitle: __('Warning: this is a test instance.'),
body: <p style={{ whiteSpace: 'pre-wrap' }}>{process.env.DEV_CHANGELOG}</p>,
onConfirm: (closeModal) => closeModal(),
hideCancel: true,
})
}
2021-12-13 09:17:30 +01:00
/>
)}
{/* @endif */}
2020-08-10 22:47:39 +02:00
</div>
2021-12-21 13:42:28 +01:00
{!authHeader && !isMobile && (
<div className="header__center">
<WunderBar />
<HeaderMenuButtons />
</div>
)}
{!authHeader && !canBackout
2021-12-21 13:42:28 +01:00
? userButtons(isMobile)
: !isVerifyPage &&
!hideCancel && (
2021-12-21 13:42:28 +01:00
<div className="header__menu--right">
<Button
title={__('Go Back')}
button="alt"
// className="button--header-close"
icon={ICONS.REMOVE}
onClick={() => {
2021-12-29 21:08:04 +01:00
if (!iYTSyncPage && !isPwdResetPage) {
2021-12-21 20:01:27 +01:00
clearEmailEntry();
clearPasswordEntry();
}
if (syncError) signOut();
2021-12-21 20:01:27 +01:00
if ((isSignInPage && !emailToVerify) || isSignUpPage || isPwdResetPage || iYTSyncPage) {
goBack();
} else {
push('/');
}
}}
/>
</div>
)}
2021-12-21 13:42:28 +01:00
</div>
</>
)}
2017-06-06 23:19:12 +02:00
</header>
);
2017-06-06 06:21:55 +02:00
};
2019-06-17 22:32:38 +02:00
export default withRouter(Header);