More header refactors (#7441)
* Refactor notificationHeaderButton * Add Tooltips to header buttons and replace reach/ui * Decrease --header-height by 20% * more header cherry-pick Co-authored-by: Rafael <rafael.saes@odysee.com>
This commit is contained in:
parent
f095081c71
commit
618ab5e195
17 changed files with 293 additions and 278 deletions
|
@ -1,5 +1,4 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { SIMPLE_SITE } from 'config';
|
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
@ -39,33 +38,31 @@ function ChannelStakedIndicator(props: Props) {
|
||||||
const icon = getChannelIcon(level);
|
const icon = getChannelIcon(level);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
SIMPLE_SITE && (
|
<Tooltip
|
||||||
<Tooltip
|
title={
|
||||||
label={
|
<div className="channel-staked__tooltip">
|
||||||
<div className="channel-staked__tooltip">
|
<div className="channel-staked__tooltip-icons">
|
||||||
<div className="channel-staked__tooltip-icons">
|
<LevelIcon icon={icon} isControlling={isControlling} size={isControlling ? 14 : 10} />
|
||||||
<LevelIcon icon={icon} isControlling={isControlling} size={isControlling ? 14 : 10} />
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="channel-staked__tooltip-text">
|
<div className="channel-staked__tooltip-text">
|
||||||
<span>{__('Level %current_level%', { current_level: level })}</span>
|
<span>{__('Level %current_level%', { current_level: level })}</span>
|
||||||
<div className="channel-staked__amount">
|
<div className="channel-staked__amount">
|
||||||
<LbcSymbol postfix={<CreditAmount amount={amount} showLBC={false} />} size={14} />
|
<LbcSymbol postfix={<CreditAmount amount={amount} showLBC={false} />} size={14} />
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={classnames('channel-staked__wrapper', {
|
|
||||||
'channel-staked__wrapper--large': large,
|
|
||||||
'channel-staked__wrapper--inline': inline,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<LevelIcon icon={icon} large={large} isControlling={isControlling} />
|
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
}
|
||||||
)
|
>
|
||||||
|
<div
|
||||||
|
className={classnames('channel-staked__wrapper', {
|
||||||
|
'channel-staked__wrapper--large': large,
|
||||||
|
'channel-staked__wrapper--inline': inline,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<LevelIcon icon={icon} large={large} isControlling={isControlling} />
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -241,7 +241,7 @@ function Comment(props: Props) {
|
||||||
<div className="comment__meta">
|
<div className="comment__meta">
|
||||||
<div className="comment__meta-information">
|
<div className="comment__meta-information">
|
||||||
{isGlobalMod && (
|
{isGlobalMod && (
|
||||||
<Tooltip label={__('Admin')}>
|
<Tooltip title={__('Admin')}>
|
||||||
<span className="comment__badge comment__badge--global-mod">
|
<span className="comment__badge comment__badge--global-mod">
|
||||||
<Icon icon={ICONS.BADGE_MOD} size={20} />
|
<Icon icon={ICONS.BADGE_MOD} size={20} />
|
||||||
</span>
|
</span>
|
||||||
|
@ -249,7 +249,7 @@ function Comment(props: Props) {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isModerator && (
|
{isModerator && (
|
||||||
<Tooltip label={__('Moderator')}>
|
<Tooltip title={__('Moderator')}>
|
||||||
<span className="comment__badge comment__badge--mod">
|
<span className="comment__badge comment__badge--mod">
|
||||||
<Icon icon={ICONS.BADGE_MOD} size={20} />
|
<Icon icon={ICONS.BADGE_MOD} size={20} />
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,18 +1,30 @@
|
||||||
// @flow
|
// @flow
|
||||||
import type { Node } from 'react';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReachTooltip from '@reach/tooltip';
|
import MUITooltip from '@mui/material/Tooltip';
|
||||||
// import '@reach/tooltip/styles.css'; --> 'scss/third-party.scss'
|
import type { Node } from 'react';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
label: string | Node,
|
arrow?: boolean,
|
||||||
children: Node,
|
children: Node,
|
||||||
|
disableInteractive?: boolean,
|
||||||
|
enterDelay?: number,
|
||||||
|
title?: string | Node,
|
||||||
};
|
};
|
||||||
|
|
||||||
function Tooltip(props: Props) {
|
function Tooltip(props: Props) {
|
||||||
const { children, label } = props;
|
const { arrow = true, children, disableInteractive = true, enterDelay = 300, title } = props;
|
||||||
|
|
||||||
return <ReachTooltip label={label}>{children}</ReachTooltip>;
|
return (
|
||||||
|
<MUITooltip
|
||||||
|
arrow={arrow}
|
||||||
|
disableInteractive={disableInteractive}
|
||||||
|
enterDelay={enterDelay}
|
||||||
|
enterNextDelay={enterDelay}
|
||||||
|
title={title}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</MUITooltip>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Tooltip;
|
export default Tooltip;
|
||||||
|
|
|
@ -17,6 +17,10 @@ import { useHistory } from 'react-router';
|
||||||
import { isURIEqual } from 'util/lbryURI';
|
import { isURIEqual } from 'util/lbryURI';
|
||||||
import AutoplayCountdown from 'component/autoplayCountdown';
|
import AutoplayCountdown from 'component/autoplayCountdown';
|
||||||
|
|
||||||
|
// scss/init/vars.scss
|
||||||
|
// --header-height
|
||||||
|
const HEADER_HEIGHT = 64;
|
||||||
|
|
||||||
const IS_DESKTOP_MAC = typeof process === 'object' ? process.platform === 'darwin' : false;
|
const IS_DESKTOP_MAC = typeof process === 'object' ? process.platform === 'darwin' : false;
|
||||||
const DEBOUNCE_WINDOW_RESIZE_HANDLER_MS = 100;
|
const DEBOUNCE_WINDOW_RESIZE_HANDLER_MS = 100;
|
||||||
export const INLINE_PLAYER_WRAPPER_CLASS = 'inline-player__wrapper';
|
export const INLINE_PLAYER_WRAPPER_CLASS = 'inline-player__wrapper';
|
||||||
|
@ -351,8 +355,7 @@ export default function FileRenderFloating(props: Props) {
|
||||||
width: fileViewerRect.width,
|
width: fileViewerRect.width,
|
||||||
height: fileViewerRect.height,
|
height: fileViewerRect.height,
|
||||||
left: fileViewerRect.x,
|
left: fileViewerRect.x,
|
||||||
// 80px is header height in scss/init/vars.scss
|
top: fileViewerRect.windowOffset + fileViewerRect.top - HEADER_HEIGHT - (IS_DESKTOP_MAC ? 24 : 0),
|
||||||
top: fileViewerRect.windowOffset + fileViewerRect.top - 80 - (IS_DESKTOP_MAC ? 24 : 0),
|
|
||||||
}
|
}
|
||||||
: {}
|
: {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
// import 'scss/component/_header.scss'; // ody codesplits this. no.
|
||||||
|
|
||||||
import { useIsMobile } from 'effects/use-screensize';
|
import { useIsMobile } from 'effects/use-screensize';
|
||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
|
@ -11,13 +13,13 @@ import Logo from 'component/logo';
|
||||||
import NotificationBubble from 'component/notificationBubble';
|
import NotificationBubble from 'component/notificationBubble';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import SkipNavigationButton from 'component/skipNavigationButton';
|
import SkipNavigationButton from 'component/skipNavigationButton';
|
||||||
|
import Tooltip from 'component/common/tooltip';
|
||||||
import WunderBar from 'component/wunderbar';
|
import WunderBar from 'component/wunderbar';
|
||||||
import * as remote from '@electron/remote';
|
import * as remote from '@electron/remote';
|
||||||
import { IS_MAC } from 'component/app/view';
|
import { IS_MAC } from 'component/app/view';
|
||||||
import NavigationButton from 'component/navigationButton';
|
import NavigationButton from 'component/navigationButton';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
authenticated: boolean,
|
|
||||||
authHeader: boolean,
|
authHeader: boolean,
|
||||||
backout: {
|
backout: {
|
||||||
backLabel?: string,
|
backLabel?: string,
|
||||||
|
@ -49,7 +51,6 @@ type Props = {
|
||||||
|
|
||||||
const Header = (props: Props) => {
|
const Header = (props: Props) => {
|
||||||
const {
|
const {
|
||||||
authenticated,
|
|
||||||
authHeader,
|
authHeader,
|
||||||
backout,
|
backout,
|
||||||
balance,
|
balance,
|
||||||
|
@ -119,24 +120,35 @@ const Header = (props: Props) => {
|
||||||
}
|
}
|
||||||
}, [canBackout, onBackout]);
|
}, [canBackout, onBackout]);
|
||||||
|
|
||||||
const userButtons = (className: string) => (
|
const userButtons = (hideWallet?: boolean, hideProfile?: boolean) => (
|
||||||
<div className={classnames('header__menu', { 'header__menu--with-balance': authenticated })}>
|
<div className="header__menu--right">
|
||||||
<Button
|
{isMobile && !authHeader && !canBackout && <WunderBar />}
|
||||||
|
<Tooltip
|
||||||
title={
|
title={
|
||||||
balance > 0
|
balance > 0
|
||||||
? __('Immediately spendable: %spendable_balance%', { spendable_balance: roundedSpendableBalance })
|
? __('Immediately spendable: %spendable_balance%', { spendable_balance: roundedSpendableBalance })
|
||||||
: __('Your Wallet')
|
: __('Your Wallet')
|
||||||
}
|
}
|
||||||
navigate={`/$/${PAGES.WALLET}`}
|
>
|
||||||
className={classnames(className, 'header__navigation-item--balance')}
|
<div>
|
||||||
label={hideBalance || Number(roundedBalance) === 0 ? __('Your Wallet') : roundedBalance}
|
<Button
|
||||||
icon={ICONS.LBC}
|
// title={
|
||||||
// @if TARGET='app'
|
// balance > 0
|
||||||
onDoubleClick={(e) => {
|
// ? __('Immediately spendable: %spendable_balance%', { spendable_balance: roundedSpendableBalance })
|
||||||
e.stopPropagation();
|
// : __('Your Wallet')
|
||||||
}}
|
// }
|
||||||
// @endif
|
navigate={`/$/${PAGES.WALLET}`}
|
||||||
/>
|
className="button--file-action header__navigationItem--balance"
|
||||||
|
label={hideBalance || Number(roundedBalance) === 0 ? __('Your Wallet') : roundedBalance}
|
||||||
|
icon={ICONS.LBC}
|
||||||
|
// @if TARGET='app'
|
||||||
|
onDoubleClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
|
// @endif
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
<HeaderProfileMenuButton />
|
<HeaderProfileMenuButton />
|
||||||
</div>
|
</div>
|
||||||
|
@ -154,50 +166,51 @@ const Header = (props: Props) => {
|
||||||
}}
|
}}
|
||||||
// @endif
|
// @endif
|
||||||
>
|
>
|
||||||
<div className="header__contents">
|
<div className="card__actions--between header__contents">
|
||||||
{!authHeader && canBackout ? (
|
{!authHeader && canBackout ? (
|
||||||
<div className="card__actions--between">
|
<>
|
||||||
<Button onClick={onBackout} button="link" label={backLabel || __('Cancel')} icon={ICONS.ARROW_LEFT} />
|
<div className="header__menu--left">
|
||||||
|
<Button onClick={onBackout} button="link" label={backLabel || __('Cancel')} icon={ICONS.ARROW_LEFT} />
|
||||||
{backTitle && <h1 className="header__auth-title">{(isMobile && simpleBackTitle) || backTitle}</h1>}
|
</div>
|
||||||
|
{backTitle && <h1 className="header__authTitle">{(isMobile && simpleBackTitle) || backTitle}</h1>}
|
||||||
{userButtons('header__navigation-item menu__title')}
|
{userButtons(false, isMobile)}
|
||||||
</div>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className="header__navigation">
|
<div className="header__navigation">
|
||||||
<SkipNavigationButton />
|
<div className="header__menu--left">
|
||||||
|
<SkipNavigationButton />
|
||||||
|
{!authHeader && (
|
||||||
|
<span style={{ position: 'relative' }}>
|
||||||
|
<Button
|
||||||
|
aria-label={sidebarLabel}
|
||||||
|
className="header__navigationItem--icon"
|
||||||
|
icon={ICONS.MENU}
|
||||||
|
aria-expanded={sidebarOpen}
|
||||||
|
onClick={() => setSidebarOpen(!sidebarOpen)}
|
||||||
|
>
|
||||||
|
{isAbsoluteSideNavHidden && isMobile && <NotificationBubble />}
|
||||||
|
</Button>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
aria-label={__('Home')}
|
||||||
|
className="header__navigationItem--logo"
|
||||||
|
onClick={() => {
|
||||||
|
// here use state.router.location.pathname
|
||||||
|
if (history.location.pathname === '/') window.location.reload();
|
||||||
|
}}
|
||||||
|
// @if TARGET='app'
|
||||||
|
onDoubleClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
|
// @endif
|
||||||
|
{...homeButtonNavigationProps}
|
||||||
|
>
|
||||||
|
<Logo />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
{!authHeader && (
|
|
||||||
<span style={{ position: 'relative' }}>
|
|
||||||
<Button
|
|
||||||
aria-label={sidebarLabel}
|
|
||||||
className="header__navigation-item menu__title header__navigation-item--icon"
|
|
||||||
icon={ICONS.MENU}
|
|
||||||
aria-expanded={sidebarOpen}
|
|
||||||
onClick={() => setSidebarOpen(!sidebarOpen)}
|
|
||||||
>
|
|
||||||
{isAbsoluteSideNavHidden && isMobile && <NotificationBubble />}
|
|
||||||
</Button>
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Button
|
|
||||||
aria-label={__('Home')}
|
|
||||||
className="header__navigation-item header__navigation-item--lbry"
|
|
||||||
onClick={() => {
|
|
||||||
// here use state.router.location.pathname
|
|
||||||
if (history.location.pathname === '/') window.location.reload();
|
|
||||||
}}
|
|
||||||
// @if TARGET='app'
|
|
||||||
onDoubleClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
}}
|
|
||||||
// @endif
|
|
||||||
{...homeButtonNavigationProps}
|
|
||||||
>
|
|
||||||
<Logo />
|
|
||||||
</Button>
|
|
||||||
{!authHeader && (
|
{!authHeader && (
|
||||||
<div className="header__center">
|
<div className="header__center">
|
||||||
{/* @if TARGET='app' */}
|
{/* @if TARGET='app' */}
|
||||||
|
@ -212,37 +225,33 @@ const Header = (props: Props) => {
|
||||||
<HeaderMenuButtons />
|
<HeaderMenuButtons />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{!authHeader && !canBackout
|
||||||
|
? userButtons(isMobile)
|
||||||
|
: !isVerifyPage &&
|
||||||
|
!hideCancel && (
|
||||||
|
<div className="header__menu--right">
|
||||||
|
<Button
|
||||||
|
title={__('Go Back')}
|
||||||
|
button="alt"
|
||||||
|
// className="button--header-close"
|
||||||
|
icon={ICONS.REMOVE}
|
||||||
|
onClick={() => {
|
||||||
|
clearEmailEntry();
|
||||||
|
clearPasswordEntry();
|
||||||
|
|
||||||
|
if (syncError) signOut();
|
||||||
|
|
||||||
|
if ((isSignInPage && !emailToVerify) || isSignUpPage || isPwdResetPage) {
|
||||||
|
goBack();
|
||||||
|
} else {
|
||||||
|
push('/');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!authHeader && !canBackout
|
|
||||||
? userButtons('header__navigation-item menu__title mobile-hidden')
|
|
||||||
: !isVerifyPage &&
|
|
||||||
!hideCancel && (
|
|
||||||
<div className="header__menu">
|
|
||||||
{/* Add an empty span here so we can use the same style as above */}
|
|
||||||
{/* This pushes the close button to the right side */}
|
|
||||||
<span />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
title={__('Go Back')}
|
|
||||||
button="alt"
|
|
||||||
// className="button--header-close"
|
|
||||||
icon={ICONS.REMOVE}
|
|
||||||
onClick={() => {
|
|
||||||
clearEmailEntry();
|
|
||||||
clearPasswordEntry();
|
|
||||||
|
|
||||||
if (syncError) signOut();
|
|
||||||
|
|
||||||
if ((isSignInPage && !emailToVerify) || isSignUpPage || isPwdResetPage) {
|
|
||||||
goBack();
|
|
||||||
} else {
|
|
||||||
push('/');
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
// import 'scss/component/_header.scss'; // ody codesplits this; no.
|
||||||
|
|
||||||
import { ENABLE_UI_NOTIFICATIONS } from 'config';
|
import { ENABLE_UI_NOTIFICATIONS } from 'config';
|
||||||
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
|
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import * as PAGES from 'constants/pages';
|
import * as PAGES from 'constants/pages';
|
||||||
import HeaderMenuLink from 'component/common/header-menu-link';
|
import HeaderMenuLink from 'component/common/header-menu-link';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import NotificationHeaderButton from 'component/notificationHeaderButton';
|
import NotificationHeaderButton from 'component/headerNotificationButton';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import Tooltip from 'component/common/tooltip';
|
||||||
|
|
||||||
type HeaderMenuButtonProps = {
|
type HeaderMenuButtonProps = {
|
||||||
authenticated: boolean,
|
authenticated: boolean,
|
||||||
|
@ -24,13 +27,11 @@ export default function HeaderMenuButtons(props: HeaderMenuButtonProps) {
|
||||||
return (
|
return (
|
||||||
<div className="header__buttons">
|
<div className="header__buttons">
|
||||||
<Menu>
|
<Menu>
|
||||||
<MenuButton
|
<Tooltip title={__('Publish a file, or create a channel')}>
|
||||||
aria-label={__('Publish a file, or create a channel')}
|
<MenuButton className="header__navigationItem--icon">
|
||||||
title={__('Publish a file, or create a channel')}
|
<Icon size={18} icon={ICONS.PUBLISH} aria-hidden />
|
||||||
className="header__navigation-item menu__title header__navigation-item--icon mobile-hidden"
|
</MenuButton>
|
||||||
>
|
</Tooltip>
|
||||||
<Icon size={18} icon={ICONS.PUBLISH} aria-hidden />
|
|
||||||
</MenuButton>
|
|
||||||
|
|
||||||
<MenuList className="menu__list--header">
|
<MenuList className="menu__list--header">
|
||||||
<HeaderMenuLink page={PAGES.UPLOAD} icon={ICONS.PUBLISH} name={__('Upload')} />
|
<HeaderMenuLink page={PAGES.UPLOAD} icon={ICONS.PUBLISH} name={__('Upload')} />
|
||||||
|
@ -41,13 +42,11 @@ export default function HeaderMenuButtons(props: HeaderMenuButtonProps) {
|
||||||
{notificationsEnabled && <NotificationHeaderButton />}
|
{notificationsEnabled && <NotificationHeaderButton />}
|
||||||
|
|
||||||
<Menu>
|
<Menu>
|
||||||
<MenuButton
|
<Tooltip title={__('Settings')}>
|
||||||
aria-label={__('Settings')}
|
<MenuButton className="header__navigationItem--icon">
|
||||||
title={__('Settings')}
|
<Icon size={18} icon={ICONS.SETTINGS} aria-hidden />
|
||||||
className="header__navigation-item menu__title header__navigation-item--icon mobile-hidden"
|
</MenuButton>
|
||||||
>
|
</Tooltip>
|
||||||
<Icon size={18} icon={ICONS.SETTINGS} aria-hidden />
|
|
||||||
</MenuButton>
|
|
||||||
|
|
||||||
<MenuList className="menu__list--header">
|
<MenuList className="menu__list--header">
|
||||||
<HeaderMenuLink page={PAGES.SETTINGS} icon={ICONS.SETTINGS} name={__('Settings')} />
|
<HeaderMenuLink page={PAGES.SETTINGS} icon={ICONS.SETTINGS} name={__('Settings')} />
|
||||||
|
|
|
@ -1,16 +1,10 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import {
|
import { selectUnseenNotificationCount } from 'redux/selectors/notifications';
|
||||||
selectNotifications,
|
|
||||||
selectIsFetchingNotifications,
|
|
||||||
selectUnseenNotificationCount,
|
|
||||||
} from 'redux/selectors/notifications';
|
|
||||||
import { doSeeAllNotifications } from 'redux/actions/notifications';
|
import { doSeeAllNotifications } from 'redux/actions/notifications';
|
||||||
import { selectUser } from 'redux/selectors/user';
|
import { selectUser } from 'redux/selectors/user';
|
||||||
import NotificationHeaderButton from './view';
|
import NotificationHeaderButton from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = (state) => ({
|
||||||
notifications: selectNotifications(state),
|
|
||||||
fetching: selectIsFetchingNotifications(state),
|
|
||||||
unseenCount: selectUnseenNotificationCount(state),
|
unseenCount: selectUnseenNotificationCount(state),
|
||||||
user: selectUser(state),
|
user: selectUser(state),
|
||||||
});
|
});
|
|
@ -1,51 +1,41 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as PAGES from 'constants/pages';
|
// import 'scss/component/_header.scss'; // ody codesplits this; no. REMOVE THESE
|
||||||
|
|
||||||
|
import { ENABLE_UI_NOTIFICATIONS } from 'config';
|
||||||
|
import { useHistory } from 'react-router';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import React from 'react';
|
import * as PAGES from 'constants/pages';
|
||||||
|
import Button from 'component/button';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import NotificationBubble from 'component/notificationBubble';
|
import NotificationBubble from 'component/notificationBubble';
|
||||||
import Button from 'component/button';
|
import React from 'react';
|
||||||
import { useHistory } from 'react-router';
|
import Tooltip from 'component/common/tooltip';
|
||||||
import { ENABLE_UI_NOTIFICATIONS } from 'config';
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
unseenCount: number,
|
unseenCount: number,
|
||||||
doSeeAllNotifications: () => void,
|
|
||||||
user: ?User,
|
user: ?User,
|
||||||
|
doSeeAllNotifications: () => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function NotificationHeaderButton(props: Props) {
|
export default function NotificationHeaderButton(props: Props) {
|
||||||
const {
|
const { unseenCount, user, doSeeAllNotifications } = props;
|
||||||
unseenCount,
|
|
||||||
// notifications,
|
|
||||||
// fetching,
|
|
||||||
doSeeAllNotifications,
|
|
||||||
user,
|
|
||||||
} = props;
|
|
||||||
const notificationsEnabled = ENABLE_UI_NOTIFICATIONS || (user && user.experimental_ui);
|
|
||||||
const { push } = useHistory();
|
const { push } = useHistory();
|
||||||
|
const notificationsEnabled = ENABLE_UI_NOTIFICATIONS || (user && user.experimental_ui);
|
||||||
|
|
||||||
function handleMenuClick() {
|
function handleMenuClick() {
|
||||||
if (unseenCount > 0) {
|
if (unseenCount > 0) doSeeAllNotifications();
|
||||||
doSeeAllNotifications();
|
|
||||||
}
|
|
||||||
|
|
||||||
push(`/$/${PAGES.NOTIFICATIONS}`);
|
push(`/$/${PAGES.NOTIFICATIONS}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!notificationsEnabled) {
|
if (!notificationsEnabled) return null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Tooltip title={__('Notifications')}>
|
||||||
onClick={handleMenuClick}
|
<Button onClick={handleMenuClick} className="header__navigationItem--icon">
|
||||||
aria-label={__('Notifications')}
|
<Icon size={18} icon={ICONS.NOTIFICATION} aria-hidden />
|
||||||
title={__('Notifications')}
|
<NotificationBubble />
|
||||||
className="header__navigation-item menu__title header__navigation-item--icon mobile-hidden"
|
</Button>
|
||||||
>
|
</Tooltip>
|
||||||
<Icon size={18} icon={ICONS.NOTIFICATION} aria-hidden />
|
|
||||||
<NotificationBubble />
|
|
||||||
</Button>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
// import 'scss/component/_header.scss'; // REMOVE!
|
||||||
|
|
||||||
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
|
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import * as PAGES from 'constants/pages';
|
import * as PAGES from 'constants/pages';
|
||||||
|
@ -26,9 +28,9 @@ export default function HeaderProfileMenuButton(props: HeaderMenuButtonProps) {
|
||||||
<MenuButton
|
<MenuButton
|
||||||
aria-label={__('Your account')}
|
aria-label={__('Your account')}
|
||||||
title={__('Your account')}
|
title={__('Your account')}
|
||||||
className={classnames('header__navigation-item', {
|
className={classnames('header__navigationItem', {
|
||||||
'menu__title header__navigation-item--icon': !activeChannelUrl,
|
'header__navigationItem--icon': !activeChannelUrl,
|
||||||
'header__navigation-item--profile-pic': activeChannelUrl,
|
'header__navigationItem--profilePic': activeChannelUrl,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{activeChannelUrl ? (
|
{activeChannelUrl ? (
|
||||||
|
|
|
@ -363,17 +363,6 @@ $actions-z-index: 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.channel-staked__tooltip {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
line-height: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.channel-staked__tooltip-text {
|
|
||||||
margin-left: var(--spacing-xs);
|
|
||||||
font-size: var(--font-xsmall);
|
|
||||||
}
|
|
||||||
|
|
||||||
.channel-staked__wrapper {
|
.channel-staked__wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
@import '../init/vars';
|
||||||
|
@import '../init/mixins';
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
z-index: 3; // Main content uses z-index: 1, other content uses z-index: 2, this ensures it always scrolls under the header
|
z-index: 3; // Main content uses z-index: 1, other content uses z-index: 2, this ensures it always scrolls under the header
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
@ -6,6 +9,7 @@
|
||||||
background-color: var(--color-header-background);
|
background-color: var(--color-header-background);
|
||||||
box-shadow: var(--card-box-shadow);
|
box-shadow: var(--card-box-shadow);
|
||||||
font-size: var(--font-body);
|
font-size: var(--font-body);
|
||||||
|
user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-webkit-app-region: drag;
|
-webkit-app-region: drag;
|
||||||
|
|
||||||
|
@ -23,31 +27,32 @@
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: unset;
|
overflow: unset;
|
||||||
width: inherit;
|
width: unset;
|
||||||
height: inherit;
|
height: unset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& > * {
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header--minimal {
|
.header--minimal {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
background-color: var(--color-background);
|
background-color: var(--color-background);
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
|
||||||
|
|
||||||
.header--mac {
|
.header__navigation {
|
||||||
padding-top: var(--mac-titlebar-height);
|
padding: var(--spacing-xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header__navigationItem--logo {
|
||||||
|
height: 3rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__contents {
|
.header__contents {
|
||||||
height: calc(var(--header-height));
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 var(--spacing-m);
|
flex: 1;
|
||||||
|
height: var(--header-height);
|
||||||
|
padding: var(--spacing-s) var(--spacing-m);
|
||||||
|
|
||||||
@media (max-width: $breakpoint-small) {
|
@media (max-width: $breakpoint-small) {
|
||||||
padding: var(--spacing-xs);
|
padding: var(--spacing-xs);
|
||||||
|
@ -55,17 +60,42 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__navigation {
|
.header__navigation {
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex: 1;
|
||||||
|
height: var(--header-height);
|
||||||
|
padding: var(--spacing-s) var(--spacing-m);
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card__actions--between {
|
||||||
|
.header__menu--left {
|
||||||
|
@media (max-width: $breakpoint-small) {
|
||||||
|
max-width: 3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__menu {
|
.header__menu {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header__menu--left {
|
||||||
|
@extend .header__menu;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header__menu--right {
|
||||||
|
@extend .header__menu;
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
@media (max-width: $breakpoint-small) {
|
||||||
|
max-width: 4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.header__buttons {
|
.header__buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +107,7 @@
|
||||||
max-width: fit-content;
|
max-width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__navigation-item {
|
.header__navigationItem {
|
||||||
height: var(--height-button);
|
height: var(--height-button);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -89,11 +119,16 @@
|
||||||
svg {
|
svg {
|
||||||
stroke: var(--color-text);
|
stroke: var(--color-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[aria-expanded='true'] {
|
||||||
|
background-color: var(--color-header-button-active);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__navigation-item--back,
|
.header__navigation-item--back,
|
||||||
.header__navigation-item--forward,
|
.header__navigation-item--forward,
|
||||||
.header__navigation-item--icon {
|
.header__navigationItem--icon {
|
||||||
|
@extend .header__navigationItem;
|
||||||
width: var(--height-button);
|
width: var(--height-button);
|
||||||
background-color: var(--color-header-button);
|
background-color: var(--color-header-button);
|
||||||
border-radius: 1.5rem;
|
border-radius: 1.5rem;
|
||||||
|
@ -109,6 +144,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: $breakpoint-small) {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -116,8 +155,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__navigation-item--profile-pic {
|
.header__navigationItem--profilePic {
|
||||||
margin-left: var(--spacing-m);
|
margin-right: var(--spacing-s);
|
||||||
|
|
||||||
.channel-thumbnail {
|
.channel-thumbnail {
|
||||||
height: var(--height-button);
|
height: var(--height-button);
|
||||||
|
@ -130,8 +169,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__navigation-item--balance {
|
.header__navigationItem--balance {
|
||||||
@extend .button--file-action;
|
@extend .header__navigationItem;
|
||||||
margin: 0 var(--spacing-s);
|
margin: 0 var(--spacing-s);
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
|
|
||||||
|
@ -140,17 +179,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__navigation-item--forward {
|
.header__navigationItem--logo {
|
||||||
margin-right: 0;
|
@extend .header__navigationItem;
|
||||||
}
|
|
||||||
|
|
||||||
.header__navigation-item--icon {
|
|
||||||
@media (max-width: $breakpoint-small) {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.header__navigation-item--lbry {
|
|
||||||
height: 4rem;
|
height: 4rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -172,61 +202,44 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header--minimal {
|
.header__authButtons {
|
||||||
.header__navigation-item--lbry {
|
|
||||||
height: 3rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.header__navigation-dropdown {
|
|
||||||
@extend .menu__list--header;
|
|
||||||
padding: 0;
|
|
||||||
position: absolute;
|
|
||||||
list-style-type: none;
|
|
||||||
background-color: var(--color-header-background);
|
|
||||||
}
|
|
||||||
|
|
||||||
.header__navigation-button {
|
|
||||||
margin: 0;
|
|
||||||
padding: var(--spacing-xxs) var(--spacing-m);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: var(--color-menu-background--active);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.header__navigation-button-help {
|
|
||||||
@extend .help;
|
|
||||||
margin-top: 0;
|
|
||||||
margin-left: var(--spacing-s);
|
|
||||||
}
|
|
||||||
|
|
||||||
.header__auth-buttons {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-weight: var(--font-weight-bold);
|
font-weight: var(--font-weight-bold);
|
||||||
margin-left: var(--spacing-s);
|
|
||||||
|
|
||||||
& > *:not(:last-child) {
|
& > *:not(:last-child) {
|
||||||
margin: 0 var(--spacing-m);
|
margin: 0 var(--spacing-m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: $breakpoint-small) {
|
||||||
|
.button--link {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button--primary {
|
||||||
|
padding: var(--spacing-xxs);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__center {
|
.header__center {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
@media (min-width: $breakpoint-small) {
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__auth-title {
|
.header__authTitle {
|
||||||
|
@extend .header__center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
@media (min-width: $breakpoint-small) {
|
@media (min-width: $breakpoint-small) {
|
||||||
font-size: var(--font-large);
|
font-size: var(--font-large);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ReactModal__Overlay {
|
||||||
|
.button--close {
|
||||||
|
margin: 0;
|
||||||
|
margin-top: var(--spacing-xxs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,24 @@
|
||||||
[data-reach-tooltip] {
|
.MuiTooltip-tooltip {
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius) !important;
|
||||||
background-color: var(--color-tooltip-bg);
|
background-color: var(--color-tooltip-bg) !important;
|
||||||
color: var(--color-tooltip-text);
|
color: var(--color-tooltip-text) !important;
|
||||||
border: none;
|
font-size: var(--font-small) !important;
|
||||||
padding: var(--spacing-s);
|
}
|
||||||
overflow: hidden;
|
|
||||||
|
.MuiTooltip-arrow {
|
||||||
|
color: var(--color-tooltip-bg) !important;
|
||||||
|
font-size: var(--font-xxsmall) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel-staked__tooltip {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
line-height: 1rem;
|
||||||
|
padding: var(--spacing-xs);
|
||||||
|
|
||||||
|
.channel-staked__tooltip-text {
|
||||||
|
margin-left: var(--spacing-xs);
|
||||||
|
font-size: var(--font-xsmall);
|
||||||
|
font-size: var(--font-small);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import './header';
|
||||||
|
|
||||||
.wunderbar__wrapper {
|
.wunderbar__wrapper {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
max-width: 30rem;
|
max-width: 30rem;
|
||||||
|
@ -103,7 +105,7 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: calc(var(--header-height) - (var(--height-input)) + 3px);
|
top: calc(var(--header-height) - var(--spacing-m) - 3px);
|
||||||
@extend .card;
|
@extend .card;
|
||||||
box-shadow: var(--card-box-shadow);
|
box-shadow: var(--card-box-shadow);
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
|
@ -227,7 +229,7 @@
|
||||||
|
|
||||||
.wunderbar__mobile-search {
|
.wunderbar__mobile-search {
|
||||||
@extend .button--alt;
|
@extend .button--alt;
|
||||||
@extend .header__navigation-item--icon;
|
@extend .header__navigationItem--icon;
|
||||||
padding: var(--spacing-xs);
|
padding: var(--spacing-xs);
|
||||||
margin-right: var(--spacing-m);
|
margin-right: var(--spacing-m);
|
||||||
|
|
||||||
|
|
|
@ -65,12 +65,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu__title {
|
|
||||||
&[aria-expanded='true'] {
|
|
||||||
background-color: var(--color-header-button-active);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu__list {
|
.menu__list {
|
||||||
box-shadow: var(--card-box-shadow);
|
box-shadow: var(--card-box-shadow);
|
||||||
animation: menu-animate-in var(--animation-duration) var(--animation-style);
|
animation: menu-animate-in var(--animation-duration) var(--animation-style);
|
||||||
|
@ -86,7 +80,7 @@
|
||||||
|
|
||||||
.menu__list--header {
|
.menu__list--header {
|
||||||
@extend .menu__list;
|
@extend .menu__list;
|
||||||
margin-top: 19px;
|
margin-top: var(--spacing-s);
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu__list--comments {
|
.menu__list--comments {
|
||||||
|
|
|
@ -480,12 +480,6 @@ textarea {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-hidden {
|
|
||||||
@media (max-width: $breakpoint-small) {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ads-test {
|
.ads-test {
|
||||||
height: 50vh;
|
height: 50vh;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -72,7 +72,7 @@ $breakpoint-large: 1600px;
|
||||||
// Header
|
// Header
|
||||||
// This is tied to the floating player so it knows where to attach to
|
// This is tied to the floating player so it knows where to attach to
|
||||||
// ui/component/fileRenderFloating/view.jsx
|
// ui/component/fileRenderFloating/view.jsx
|
||||||
--header-height: 80px;
|
--header-height: 64px;
|
||||||
|
|
||||||
// Inline Player
|
// Inline Player
|
||||||
--inline-player-max-height: calc(100vh - var(--header-height) - var(--spacing-l) * 2);
|
--inline-player-max-height: calc(100vh - var(--header-height) - var(--spacing-l) * 2);
|
||||||
|
|
|
@ -123,6 +123,7 @@
|
||||||
--color-purchased-text: var(--color-gray-5);
|
--color-purchased-text: var(--color-gray-5);
|
||||||
--color-thumbnail-background: var(--color-gray-5);
|
--color-thumbnail-background: var(--color-gray-5);
|
||||||
--color-tooltip-bg: #2f3337;
|
--color-tooltip-bg: #2f3337;
|
||||||
|
--color-tooltip-text: #fafafa;
|
||||||
--color-help-warning-bg: #d97706;
|
--color-help-warning-bg: #d97706;
|
||||||
--color-help-warning-text: white;
|
--color-help-warning-text: white;
|
||||||
--color-blockquote: var(--color-gray-5);
|
--color-blockquote: var(--color-gray-5);
|
||||||
|
|
Loading…
Reference in a new issue