add 'immediately spendable' balance on header balance hover

This commit is contained in:
Sean Yesmunt 2021-01-25 13:34:21 -05:00
parent 00cdb5197c
commit 6903836ebe
6 changed files with 67 additions and 78 deletions

View file

@ -1557,6 +1557,7 @@
"%lbc_amount% currently in use": "%lbc_amount% currently in use", "%lbc_amount% currently in use": "%lbc_amount% currently in use",
"View less": "View less", "View less": "View less",
"Your total balance.": "Your total balance.", "Your total balance.": "Your total balance.",
"Immediately spendable": "Immediately spendable",
"%lbc_amount% immediately spendable": "%lbc_amount% immediately spendable", "%lbc_amount% immediately spendable": "%lbc_amount% immediately spendable",
"%lbc_amount% contributing to content": "%lbc_amount% contributing to content", "%lbc_amount% contributing to content": "%lbc_amount% contributing to content",
"...earned from others": "...earned from others", "...earned from others": "...earned from others",

View file

@ -1,7 +1,6 @@
// @flow // @flow
import * as ICONS from 'constants/icons'; import * as ICONS from 'constants/icons';
import React from 'react'; import React from 'react';
import Tooltip from 'component/common/tooltip';
import classnames from 'classnames'; import classnames from 'classnames';
import { icons } from './icon-custom'; import { icons } from './icon-custom';
@ -70,6 +69,7 @@ class IconComponent extends React.PureComponent<Props> {
const component = ( const component = (
<Icon <Icon
title={tooltipText}
size={size || (sectionIcon ? 20 : 16)} size={size || (sectionIcon ? 20 : 16)}
className={classnames(`icon icon--${icon}`, className)} className={classnames(`icon icon--${icon}`, className)}
color={color} color={color}
@ -77,9 +77,7 @@ class IconComponent extends React.PureComponent<Props> {
/> />
); );
const inner = sectionIcon ? <span className={`icon__wrapper icon__wrapper--${icon}`}>{component}</span> : component; return sectionIcon ? <span className={`icon__wrapper icon__wrapper--${icon}`}>{component}</span> : component;
return tooltipText ? <Tooltip label={tooltipText}>{inner}</Tooltip> : inner;
} }
} }

View file

@ -10,7 +10,6 @@ import UriIndicator from 'component/uriIndicator';
import usePersistedState from 'effects/use-persisted-state'; import usePersistedState from 'effects/use-persisted-state';
import { PRIMARY_PLAYER_WRAPPER_CLASS } from 'page/file/view'; import { PRIMARY_PLAYER_WRAPPER_CLASS } from 'page/file/view';
import Draggable from 'react-draggable'; import Draggable from 'react-draggable';
import Tooltip from 'component/common/tooltip';
import { onFullscreenChange } from 'util/full-screen'; import { onFullscreenChange } from 'util/full-screen';
import { useIsMobile } from 'effects/use-screensize'; import { useIsMobile } from 'effects/use-screensize';
import debounce from 'util/debounce'; import debounce from 'util/debounce';
@ -270,14 +269,13 @@ export default function FileRenderFloating(props: Props) {
})} })}
> >
{isFloating && ( {isFloating && (
<Tooltip label={__('Close')}> <Button
<Button title={__('Close')}
onClick={closeFloatingPlayer} onClick={closeFloatingPlayer}
icon={ICONS.REMOVE} icon={ICONS.REMOVE}
button="primary" button="primary"
className="content__floating-close" className="content__floating-close"
/> />
</Tooltip>
)} )}
{isReadyToPlay ? ( {isReadyToPlay ? (
@ -296,7 +294,7 @@ export default function FileRenderFloating(props: Props) {
<div className="claim-preview__title" title={title || uri}> <div className="claim-preview__title" title={title || uri}>
<Button label={title || uri} navigate={uri} button="link" className="content__floating-link" /> <Button label={title || uri} navigate={uri} button="link" className="content__floating-link" />
</div> </div>
<UriIndicator link addTooltip={false} uri={uri} /> <UriIndicator link uri={uri} />
</div> </div>
)} )}
</div> </div>

View file

@ -1,6 +1,6 @@
import * as MODALS from 'constants/modal_types'; import * as MODALS from 'constants/modal_types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { selectTotalBalance, formatCredits, selectMyChannelClaims, SETTINGS } from 'lbry-redux'; import { selectTotalBalance, selectBalance, formatCredits, selectMyChannelClaims, SETTINGS } from 'lbry-redux';
import { selectGetSyncErrorMessage } from 'redux/selectors/sync'; import { selectGetSyncErrorMessage } from 'redux/selectors/sync';
import { selectUserVerifiedEmail, selectUserEmail, selectEmailToVerify, selectUser } from 'redux/selectors/user'; import { selectUserVerifiedEmail, selectUserEmail, selectEmailToVerify, selectUser } from 'redux/selectors/user';
import { doClearEmailEntry, doClearPasswordEntry } from 'redux/actions/user'; import { doClearEmailEntry, doClearPasswordEntry } from 'redux/actions/user';
@ -13,6 +13,8 @@ import { selectHasNavigated } from 'redux/selectors/app';
const select = state => ({ const select = state => ({
language: selectLanguage(state), language: selectLanguage(state),
balance: selectBalance(state),
roundedSpendableBalance: formatCredits(selectBalance(state), 2, true),
roundedBalance: formatCredits(selectTotalBalance(state), 2, true), roundedBalance: formatCredits(selectTotalBalance(state), 2, true),
currentTheme: makeSelectClientSetting(SETTINGS.THEME)(state), currentTheme: makeSelectClientSetting(SETTINGS.THEME)(state),
automaticDarkModeEnabled: makeSelectClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED)(state), automaticDarkModeEnabled: makeSelectClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED)(state),

View file

@ -9,7 +9,6 @@ import Button from 'component/button';
import WunderBar from 'component/wunderbar'; import WunderBar from 'component/wunderbar';
import Icon from 'component/common/icon'; import Icon from 'component/common/icon';
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button'; import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
import Tooltip from 'component/common/tooltip';
import NavigationButton from 'component/navigationButton'; import NavigationButton from 'component/navigationButton';
import { LOGO_TITLE } from 'config'; import { LOGO_TITLE } from 'config';
import { useIsMobile } from 'effects/use-screensize'; import { useIsMobile } from 'effects/use-screensize';
@ -24,7 +23,9 @@ import { IS_MAC } from 'component/app/view';
type Props = { type Props = {
user: ?User, user: ?User,
balance: string, balance: string,
roundedBalance: number, balance: number,
roundedBalance: string,
roundedSpendableBalance: string,
history: { history: {
entities: {}[], entities: {}[],
goBack: () => void, goBack: () => void,
@ -66,7 +67,9 @@ type Props = {
const Header = (props: Props) => { const Header = (props: Props) => {
const { const {
balance,
roundedBalance, roundedBalance,
roundedSpendableBalance,
history, history,
setClientSetting, setClientSetting,
currentTheme, currentTheme,
@ -170,10 +173,6 @@ const Header = (props: Props) => {
} }
} }
function getWalletTitle() {
return hideBalance || Number(roundedBalance) === 0 ? __('Your Wallet') : roundedBalance;
}
const loginButtons = ( const loginButtons = (
<div className="header__auth-buttons"> <div className="header__auth-buttons">
<Button navigate={`/$/${PAGES.AUTH_SIGNIN}`} button="link" label={__('Log In')} className="mobile-hidden" /> <Button navigate={`/$/${PAGES.AUTH_SIGNIN}`} button="link" label={__('Log In')} className="mobile-hidden" />
@ -181,6 +180,26 @@ const Header = (props: Props) => {
</div> </div>
); );
type BalanceButtonProps = { className: string };
const BalanceButton = (balanceButtonProps: BalanceButtonProps) => (
<Button
title={
balance > 0
? __('Immediately spendable: %spendable_balance%', { spendable_balance: roundedSpendableBalance })
: __('Your Wallet')
}
navigate={`/$/${PAGES.WALLET}`}
className={balanceButtonProps.className}
label={hideBalance || Number(roundedBalance) === 0 ? __('Your Wallet') : roundedBalance}
icon={ICONS.LBC}
// @if TARGET='app'
onDoubleClick={e => {
e.stopPropagation();
}}
// @endif
/>
);
return ( return (
<header <header
className={classnames('header', { className={classnames('header', {
@ -206,18 +225,7 @@ const Header = (props: Props) => {
/> />
{backTitle && <h1 className="header__auth-title">{isMobile ? simpleBackTitle || backTitle : backTitle}</h1>} {backTitle && <h1 className="header__auth-title">{isMobile ? simpleBackTitle || backTitle : backTitle}</h1>}
{authenticated || !IS_WEB ? ( {authenticated || !IS_WEB ? (
<Button <BalanceButton className="header__navigation-item menu__title header__navigation-item--balance" />
aria-label={__('Your wallet')}
navigate={`/$/${PAGES.WALLET}`}
className="header__navigation-item menu__title header__navigation-item--balance"
label={getWalletTitle()}
icon={ICONS.LBC}
// @if TARGET='app'
onDoubleClick={e => {
e.stopPropagation();
}}
// @endif
/>
) : ( ) : (
loginButtons loginButtons
)} )}
@ -292,20 +300,7 @@ const Header = (props: Props) => {
{!authHeader && !backout ? ( {!authHeader && !backout ? (
<div className={classnames('header__menu', { 'header__menu--with-balance': !IS_WEB || authenticated })}> <div className={classnames('header__menu', { 'header__menu--with-balance': !IS_WEB || authenticated })}>
{(!IS_WEB || authenticated) && ( {(!IS_WEB || authenticated) && (
<Button <BalanceButton className="header__navigation-item menu__title header__navigation-item--balance mobile-hidden" />
button="link"
aria-label={__('Your wallet')}
navigate={`/$/${PAGES.WALLET}`}
className="header__navigation-item menu__title header__navigation-item--balance mobile-hidden"
label={getWalletTitle()}
icon={ICONS.LBC}
iconSize={20}
// @if TARGET='app'
onDoubleClick={e => {
e.stopPropagation();
}}
// @endif
/>
)} )}
{IS_WEB && !authenticated && loginButtons} {IS_WEB && !authenticated && loginButtons}
@ -317,19 +312,19 @@ const Header = (props: Props) => {
{/* Add an empty span here so we can use the same style as above */} {/* Add an empty span here so we can use the same style as above */}
{/* This pushes the close button to the right side */} {/* This pushes the close button to the right side */}
<span /> <span />
<Tooltip label={__('Go Back')}>
<Button <Button
button="alt" title={__('Go Back')}
// className="button--header-close" button="alt"
icon={ICONS.REMOVE} // className="button--header-close"
{...closeButtonNavigationProps} icon={ICONS.REMOVE}
// @if TARGET='app' {...closeButtonNavigationProps}
onDoubleClick={e => { // @if TARGET='app'
e.stopPropagation(); onDoubleClick={e => {
}} e.stopPropagation();
// @endif }}
/> // @endif
</Tooltip> />
</div> </div>
) )
)} )}

View file

@ -3,15 +3,13 @@ import type { Node } from 'react';
import React from 'react'; import React from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
import Button from 'component/button'; import Button from 'component/button';
import Tooltip from 'component/common/tooltip';
import ClaimPreview from 'component/claimPreview';
type Props = { type Props = {
isResolvingUri: boolean, isResolvingUri: boolean,
channelUri: ?string, channelUri: ?string,
link: ?boolean, link: ?boolean,
claim: ?Claim, claim: ?Claim,
addTooltip: boolean,
hideAnonymous: boolean, hideAnonymous: boolean,
// Lint thinks we aren't using these, even though we are. // Lint thinks we aren't using these, even though we are.
// Possibly because the resolve function is an arrow function that is passed in props? // Possibly because the resolve function is an arrow function that is passed in props?
@ -23,10 +21,6 @@ type Props = {
}; };
class UriIndicator extends React.PureComponent<Props> { class UriIndicator extends React.PureComponent<Props> {
static defaultProps = {
addTooltip: true,
};
componentDidMount() { componentDidMount() {
this.resolve(this.props); this.resolve(this.props);
} }
@ -44,7 +38,7 @@ class UriIndicator extends React.PureComponent<Props> {
}; };
render() { render() {
const { link, isResolvingUri, claim, addTooltip, children, inline, hideAnonymous = false } = this.props; const { link, isResolvingUri, claim, children, inline, hideAnonymous = false } = this.props;
if (!claim) { if (!claim) {
return <span className="empty">{isResolvingUri ? 'Validating...' : 'Unused'}</span>; return <span className="empty">{isResolvingUri ? 'Validating...' : 'Unused'}</span>;
@ -57,7 +51,11 @@ class UriIndicator extends React.PureComponent<Props> {
return null; return null;
} }
return <span dir="auto" className={classnames('channel-name', { 'channel-name--inline': inline })}>Anonymous</span>; return (
<span dir="auto" className={classnames('channel-name', { 'channel-name--inline': inline })}>
Anonymous
</span>
);
} }
const channelClaim = isChannelClaim ? claim : claim.signing_channel; const channelClaim = isChannelClaim ? claim : claim.signing_channel;
@ -66,7 +64,11 @@ class UriIndicator extends React.PureComponent<Props> {
const { name } = channelClaim; const { name } = channelClaim;
const channelLink = link ? channelClaim.canonical_url || channelClaim.permanent_url : false; const channelLink = link ? channelClaim.canonical_url || channelClaim.permanent_url : false;
const inner = <span dir="auto" className={classnames('channel-name', { 'channel-name--inline': inline })}>{name}</span>; const inner = (
<span dir="auto" className={classnames('channel-name', { 'channel-name--inline': inline })}>
{name}
</span>
);
if (!channelLink) { if (!channelLink) {
return inner; return inner;
@ -75,16 +77,9 @@ class UriIndicator extends React.PureComponent<Props> {
if (children) { if (children) {
return <Button navigate={channelLink}>{children}</Button>; return <Button navigate={channelLink}>{children}</Button>;
} else { } else {
const Wrapper = addTooltip
? ({ children }) => (
<Tooltip label={<ClaimPreview uri={channelLink} type="tooltip" placeholder={false} />}>
{children}
</Tooltip>
)
: 'span';
return ( return (
<Button className="button--uri-indicator" navigate={channelLink}> <Button className="button--uri-indicator" navigate={channelLink}>
<Wrapper>{inner}</Wrapper> {inner}
</Button> </Button>
); );
} }