2018-03-26 23:32:43 +02:00
// @flow
2021-12-21 13:42:28 +01:00
import 'scss/component/_header.scss' ;
2021-12-21 14:21:14 +01:00
import { formatCredits } from 'util/format-credits' ;
2021-12-20 13:29:51 +01:00
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' ;
2021-12-20 13:29:51 +01:00
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' ;
2021-12-20 13:29:51 +01:00
import React from 'react' ;
2021-12-21 14:21:14 +01:00
import Skeleton from '@mui/material/Skeleton' ;
2021-07-21 02:31:26 +02:00
import SkipNavigationButton from 'component/skipNavigationButton' ;
2021-12-20 13:38:12 +01:00
import Tooltip from 'component/common/tooltip' ;
2021-12-20 13:29:51 +01:00
import WunderBar from 'component/wunderbar' ;
2019-10-09 18:34:18 +02:00
2018-03-26 23:32:43 +02:00
type Props = {
2020-01-03 20:34:17 +01:00
authenticated : boolean ,
2019-10-28 15:04:37 +01:00
authHeader : boolean ,
2020-06-30 07:51:15 +02:00
backout : {
2020-07-10 23:04:36 +02:00
backLabel ? : string ,
backNavDefault ? : string ,
2020-06-30 07:51:15 +02:00
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
} ,
2021-12-20 13:29:51 +01:00
balance : number ,
2020-04-13 21:16:07 +02:00
emailToVerify ? : string ,
2020-07-10 23:04:36 +02:00
hasNavigated : boolean ,
2021-12-20 13:29:51 +01:00
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 ,
2021-12-20 13:29:51 +01:00
syncError : ? string ,
2021-12-21 14:21:14 +01:00
totalBalance ? : number ,
2021-12-20 13:29:51 +01:00
user : ? User ,
clearEmailEntry : ( ) => void ,
clearPasswordEntry : ( ) => void ,
openChangelog : ( { } ) => void ,
2021-03-03 19:50:16 +01:00
setSidebarOpen : ( boolean ) => void ,
2021-12-20 13:29:51 +01:00
signOut : ( ) => void ,
2018-03-26 23:32:43 +02:00
} ;
const Header = ( props : Props ) => {
2019-08-21 22:54:44 +02:00
const {
2021-12-20 13:29:51 +01:00
authenticated ,
authHeader ,
backout ,
2021-01-25 19:34:21 +01:00
balance ,
2021-12-20 13:29:51 +01:00
emailToVerify ,
hideBalance ,
hideCancel ,
history ,
isAbsoluteSideNavHidden ,
sidebarOpen ,
2019-11-01 17:19:28 +01:00
syncError ,
2021-12-21 14:21:14 +01:00
totalBalance ,
2021-12-20 13:29:51 +01:00
user ,
2020-04-13 21:16:07 +02:00
clearEmailEntry ,
clearPasswordEntry ,
2021-12-20 13:29:51 +01:00
openChangelog ,
2020-08-10 22:47:39 +02:00
setSidebarOpen ,
2021-12-20 13:29:51 +01:00
signOut ,
2019-08-21 22:54:44 +02:00
} = props ;
2021-12-20 13:29:51 +01:00
const {
location : { pathname } ,
goBack ,
push ,
} = history ;
2020-06-30 07:51:15 +02:00
const isMobile = useIsMobile ( ) ;
2021-12-20 13:29:51 +01:00
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
2021-12-20 13:29:51 +01:00
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 ) ;
2021-12-20 13:29:51 +01:00
// For pages that allow for "backing out", shows a backout option instead of the Home logo
const canBackout = Boolean ( backout ) ;
2020-07-30 21:14:22 +02:00
const { backLabel , backNavDefault , title : backTitle , simpleTitle : simpleBackTitle } = backout || { } ;
2021-02-09 17:05:56 +01:00
2021-12-21 14:21:14 +01:00
const balanceLoading = totalBalance === undefined ;
const roundedSpendableBalance = formatCredits ( balance , 2 , true ) ;
const roundedTotalBalance = formatCredits ( totalBalance , 2 , true ) ;
2019-11-01 17:19:28 +01:00
// Sign out if they click the "x" when they are on the password prompt
2021-12-20 13:29:51 +01:00
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
2021-12-20 13:29:51 +01:00
const onBackout = React . useCallback (
( e : any ) => {
const { hasNavigated } = props ;
const { replace } = history ;
2020-07-10 23:04:36 +02:00
2021-12-20 13:29:51 +01:00
window . removeEventListener ( 'popstate' , onBackout ) ;
2020-07-10 23:04:36 +02:00
2021-12-20 13:29:51 +01:00
if ( e . type !== 'popstate' ) {
// if not initiated by pop (back button)
if ( hasNavigated && ! backNavDefault ) {
goBack ( ) ;
} else {
replace ( backNavDefault || ` / ` ) ;
}
2020-07-10 23:04:36 +02:00
}
2021-12-20 13:29:51 +01:00
} ,
[ backNavDefault , goBack , history , props ]
) ;
2020-07-10 23:04:36 +02:00
2020-07-27 16:43:55 +02:00
React . useEffect ( ( ) => {
2021-12-20 13:29:51 +01:00
if ( canBackout ) {
2020-07-27 16:43:55 +02:00
window . addEventListener ( 'popstate' , onBackout ) ;
return ( ) => window . removeEventListener ( 'popstate' , onBackout ) ;
}
2021-12-20 13:29:51 +01:00
} , [ 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 / > }
2021-12-20 13:29:51 +01:00
{ authenticated ? (
< >
2021-12-21 13:42:28 +01:00
{ ! hideWallet && (
< Tooltip
title = {
balance > 0
? _ _ ( 'Immediately spendable: %spendable_balance%' , { spendable _balance : roundedSpendableBalance } )
: _ _ ( 'Your Wallet' )
}
>
< div >
2021-12-21 14:21:14 +01:00
{ 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
? isMobile
? _ _ ( 'Wallet' )
: _ _ ( 'Your Wallet' )
: roundedTotalBalance
}
2021-12-21 14:21:14 +01:00
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 / > }
2021-12-20 13:29:51 +01:00
< / >
2021-12-21 16:09:19 +01:00
) : ! isMobile ? (
2021-12-21 13:42:28 +01:00
< div className = "header__authButtons" >
2021-12-21 16:09:19 +01:00
< Button navigate = { ` / $ / ${ PAGES . AUTH _SIGNIN } ` } button = "link" label = { _ _ ( 'Log In' ) } disabled = { user === null } / >
2021-12-20 13:29:51 +01:00
< Button navigate = { ` / $ / ${ PAGES . AUTH } ` } button = "primary" label = { _ _ ( 'Sign Up' ) } disabled = { user === null } / >
< / div >
2021-12-21 16:09:19 +01:00
) : (
< HeaderProfileMenuButton / >
2021-12-20 13:29:51 +01:00
) }
2020-11-10 06:21:04 +01:00
< / div >
) ;
2017-06-06 23:19:12 +02:00
return (
2021-12-20 13:29:51 +01:00
< 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" >
2021-12-20 13:29:51 +01:00
< Button onClick = { onBackout } button = "link" label = { backLabel || _ _ ( 'Cancel' ) } icon = { ICONS . ARROW _LEFT } / >
2021-12-21 13:42:28 +01:00
< / div >
2021-12-20 13:29:51 +01:00
2021-12-21 13:42:28 +01:00
{ backTitle && < h1 className = "header__authTitle" > { ( isMobile && simpleBackTitle ) || backTitle } < / h1 > }
2021-12-20 13:29:51 +01:00
2021-12-21 13:42:28 +01:00
{ userButtons ( false , isMobile ) }
< / div >
) : (
< >
< div className = "header__navigation" >
< div className = "header__menu--left" >
2021-07-15 20:32:58 +02:00
< SkipNavigationButton / >
2021-12-20 13:29:51 +01:00
2020-08-11 22:32:03 +02:00
{ ! authHeader && (
< span style = { { position : 'relative' } } >
< Button
2021-12-20 13:29:51 +01:00
aria - label = { sidebarLabel }
2022-02-11 19:50:55 +01:00
className = "header__navigationItem--icon button-rotate"
2020-08-11 22:32:03 +02:00
icon = { ICONS . MENU }
2021-07-13 23:23:29 +02:00
aria - expanded = { sidebarOpen }
2020-08-11 22:32:03 +02:00
onClick = { ( ) => setSidebarOpen ( ! sidebarOpen ) }
2022-02-11 19:50:55 +01:00
/ >
{ isAbsoluteSideNavHidden && isMobile && < NotificationBubble / > }
2020-08-11 22:32:03 +02:00
< / span >
) }
2021-12-20 13:29:51 +01:00
2020-06-29 21:54:07 +02:00
< Button
2021-07-15 05:08:30 +02:00
aria - label = { _ _ ( 'Home' ) }
2021-12-21 13:42:28 +01:00
className = "header__navigationItem--logo"
2021-12-20 13:29:51 +01:00
onClick = { ( ) => pathname === '/' && window . location . reload ( ) }
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
2021-12-20 13:29:51 +01:00
title = "Changelog"
2021-12-13 09:17:30 +01:00
className = "badge--alert"
2021-12-20 13:29:51 +01:00
label = "Changelog"
2021-12-13 09:17:30 +01:00
icon = { ICONS . FEEDBACK }
2021-12-20 13:29:51 +01:00
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-20 13:29:51 +01:00
} )
}
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 >
) }
2021-12-20 13:29:51 +01:00
{ ! authHeader && ! canBackout
2021-12-21 13:42:28 +01:00
? userButtons ( isMobile )
2021-12-20 13:29:51 +01:00
: ! isVerifyPage &&
! hideCancel && (
2021-12-21 13:42:28 +01:00
< div className = "header__menu--right" >
2021-12-20 13:29:51 +01:00
< 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 ( ) ;
}
2021-03-04 07:03:58 +01:00
2021-12-20 13:29:51 +01:00
if ( syncError ) signOut ( ) ;
2021-03-04 07:03:58 +01:00
2021-12-21 20:01:27 +01:00
if ( ( isSignInPage && ! emailToVerify ) || isSignUpPage || isPwdResetPage || iYTSyncPage ) {
2021-12-20 13:29:51 +01:00
goBack ( ) ;
} else {
push ( '/' ) ;
}
} }
/ >
< / div >
2021-03-04 07:03:58 +01:00
) }
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
} ;
2016-08-27 16:12:56 +02:00
2019-06-17 22:32:38 +02:00
export default withRouter ( Header ) ;