Improve header components that need to be loaded in to display Skeleton and avoid layout shifting

This commit is contained in:
Rafael 2021-12-21 10:21:14 -03:00 committed by Thomas Zarebczan
parent 76147d89c6
commit 5c6fb9de66
4 changed files with 57 additions and 30 deletions

View file

@ -1,7 +1,6 @@
import { connect } from 'react-redux';
import { doClearEmailEntry, doClearPasswordEntry } from 'redux/actions/user';
import { doSignOut, doOpenModal } from 'redux/actions/app';
import { formatCredits } from 'util/format-credits';
import { selectClientSetting } from 'redux/selectors/settings';
import { selectGetSyncErrorMessage } from 'redux/selectors/sync';
import { selectHasNavigated } from 'redux/selectors/app';
@ -17,8 +16,7 @@ const select = (state) => ({
emailToVerify: selectEmailToVerify(state),
hasNavigated: selectHasNavigated(state),
hideBalance: selectClientSetting(state, SETTINGS.HIDE_BALANCE),
roundedBalance: formatCredits(selectTotalBalance(state), 2, true),
roundedSpendableBalance: formatCredits(selectBalance(state), 2, true),
totalBalance: selectTotalBalance(state),
syncError: selectGetSyncErrorMessage(state),
user: selectUser(state),
});

View file

@ -1,6 +1,7 @@
// @flow
import 'scss/component/_header.scss';
import { formatCredits } from 'util/format-credits';
import { useIsMobile } from 'effects/use-screensize';
import { withRouter } from 'react-router';
import * as ICONS from 'constants/icons';
@ -12,6 +13,7 @@ import HeaderProfileMenuButton from 'component/headerProfileMenuButton';
import Logo from 'component/logo';
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';
@ -37,10 +39,9 @@ type Props = {
replace: (string) => void,
},
isAbsoluteSideNavHidden: boolean,
roundedBalance: string,
roundedSpendableBalance: string,
sidebarOpen: boolean,
syncError: ?string,
totalBalance?: number,
user: ?User,
clearEmailEntry: () => void,
clearPasswordEntry: () => void,
@ -60,10 +61,9 @@ const Header = (props: Props) => {
hideCancel,
history,
isAbsoluteSideNavHidden,
roundedBalance,
roundedSpendableBalance,
sidebarOpen,
syncError,
totalBalance,
user,
clearEmailEntry,
clearPasswordEntry,
@ -90,6 +90,10 @@ const Header = (props: Props) => {
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: '/' };
@ -138,12 +142,16 @@ const Header = (props: Props) => {
}
>
<div>
<Button
navigate={`/$/${PAGES.WALLET}`}
className="button--file-action header__navigationItem--balance"
label={hideBalance || Number(roundedBalance) === 0 ? __('Your Wallet') : roundedBalance}
icon={ICONS.LBC}
/>
{balanceLoading ? (
<Skeleton variant="text" animation="wave" className="header__navigationItem--balanceLoading" />
) : (
<Button
navigate={`/$/${PAGES.WALLET}`}
className="button--file-action header__navigationItem--balance"
label={hideBalance || Number(roundedTotalBalance) === 0 ? __('Your Wallet') : roundedTotalBalance}
icon={ICONS.LBC}
/>
)}
</div>
</Tooltip>
)}

View file

@ -9,6 +9,7 @@ import classnames from 'classnames';
import HeaderMenuLink from 'component/common/header-menu-link';
import Icon from 'component/common/icon';
import React from 'react';
import Skeleton from '@mui/material/Skeleton';
type HeaderMenuButtonProps = {
activeChannelClaim: ?ChannelClaim,
@ -24,20 +25,24 @@ export default function HeaderProfileMenuButton(props: HeaderMenuButtonProps) {
return (
<div className="header__buttons">
<Menu>
<MenuButton
aria-label={__('Your account')}
title={__('Your account')}
className={classnames('header__navigationItem', {
'header__navigationItem--icon': !activeChannelUrl,
'header__navigationItem--profilePic': activeChannelUrl,
})}
>
{activeChannelUrl ? (
<ChannelThumbnail uri={activeChannelUrl} small noLazyLoad />
) : (
<Icon size={18} icon={ICONS.ACCOUNT} aria-hidden />
)}
</MenuButton>
{activeChannelUrl === undefined ? (
<Skeleton variant="circular" animation="wave" className="header__navigationItem--iconSkeleton" />
) : (
<MenuButton
aria-label={__('Your account')}
title={__('Your account')}
className={classnames('header__navigationItem', {
'header__navigationItem--icon': !activeChannelUrl,
'header__navigationItem--profilePic': activeChannelUrl,
})}
>
{activeChannelUrl ? (
<ChannelThumbnail uri={activeChannelUrl} small noLazyLoad />
) : (
<Icon size={18} icon={ICONS.ACCOUNT} aria-hidden />
)}
</MenuButton>
)}
<MenuList className="menu__list--header">
<HeaderMenuLink page={PAGES.UPLOADS} icon={ICONS.PUBLISH} name={__('Uploads')} />

View file

@ -90,9 +90,12 @@
.header__menu--right {
@extend .header__menu;
justify-content: flex-end;
width: 10rem;
min-width: 10rem;
@media (max-width: $breakpoint-small) {
max-width: 4rem;
width: unset;
min-width: unset;
}
}
@ -155,6 +158,7 @@
.header__navigationItem--profilePic {
margin-right: var(--spacing-s);
background-color: var(--color-header-button);
.channel-thumbnail {
height: var(--height-button);
@ -167,6 +171,12 @@
}
}
.header__navigationItem--iconSkeleton {
@extend .header__navigationItem--icon;
height: var(--height-button) !important;
width: var(--height-button) !important;
}
.header__navigationItem--balance {
@extend .header__navigationItem;
margin: 0 var(--spacing-s);
@ -177,22 +187,28 @@
}
}
.header__navigationItem--balanceLoading {
margin: 0 var(--spacing-s);
width: 4rem;
background-color: var(--color-header-button);
}
.header__navigationItem--logo {
@extend .header__navigationItem;
height: 4rem;
display: flex;
align-items: center;
margin-left: var(--spacing-m);
margin-right: var(--spacing-m);
color: var(--color-text);
// move to lbry theme?
.lbry-icon {
height: var(--height-button);
width: var(--height-button);
}
@media (max-width: $breakpoint-small) {
margin-right: var(--spacing-m);
height: 5rem;
.button__label {
display: none;