From 5c6fb9de6634e700733a1aa164164467b63b096f Mon Sep 17 00:00:00 2001 From: Rafael Date: Tue, 21 Dec 2021 10:21:14 -0300 Subject: [PATCH] Improve header components that need to be loaded in to display Skeleton and avoid layout shifting --- ui/component/header/index.js | 4 +-- ui/component/header/view.jsx | 28 ++++++++++------ ui/component/headerProfileMenuButton/view.jsx | 33 +++++++++++-------- ui/scss/component/_header.scss | 22 +++++++++++-- 4 files changed, 57 insertions(+), 30 deletions(-) diff --git a/ui/component/header/index.js b/ui/component/header/index.js index cfc14f561..de30b51ce 100644 --- a/ui/component/header/index.js +++ b/ui/component/header/index.js @@ -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), }); diff --git a/ui/component/header/view.jsx b/ui/component/header/view.jsx index 93b051868..31ec5a1d8 100644 --- a/ui/component/header/view.jsx +++ b/ui/component/header/view.jsx @@ -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) => { } >
-
)} diff --git a/ui/component/headerProfileMenuButton/view.jsx b/ui/component/headerProfileMenuButton/view.jsx index 26c57ec96..bb67a5565 100644 --- a/ui/component/headerProfileMenuButton/view.jsx +++ b/ui/component/headerProfileMenuButton/view.jsx @@ -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 (
- - {activeChannelUrl ? ( - - ) : ( - - )} - + {activeChannelUrl === undefined ? ( + + ) : ( + + {activeChannelUrl ? ( + + ) : ( + + )} + + )} diff --git a/ui/scss/component/_header.scss b/ui/scss/component/_header.scss index f5fcebb56..c803e9e77 100644 --- a/ui/scss/component/_header.scss +++ b/ui/scss/component/_header.scss @@ -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;