show total balance on wallet page/header

This commit is contained in:
Sean Yesmunt 2021-01-12 10:25:51 -05:00
parent 2f1fae23cf
commit 5420a6a887
15 changed files with 145 additions and 148 deletions

View file

@ -502,8 +502,9 @@
"Access to these files are equivalent to having access to your Credits, channels, and publishes. Keep any copies you make of your wallet in a secure place. For more details on backing up and best practices %helpLink%.": "Access to these files are equivalent to having access to your Credits, channels, and publishes. Keep any copies you make of your wallet in a secure place. For more details on backing up and best practices %helpLink%.",
"Your channels": "Your channels",
"Add Tags": "Add Tags",
"Available Balance": "Available Balance",
"Earned and bound in tips": "Earned and bound in tips",
"available balance": "available balance",
"currently in use": "currently in use",
"... earned and bound in tips": "... earned and bound in tips",
"... in your publishes": "... in your publishes",
"... in your supports": "... in your supports",
"Add a tag": "Add a tag",
@ -582,8 +583,8 @@
"settings": "settings",
"Content may be hidden on this %type% because of your %settings%.": "Content may be hidden on this %type% because of your %settings%.",
"Sync": "Sync",
"earned and bound in tips": "earned and bound in tips",
"currently staked": "currently staked",
"%lbc_amount% earned and bound in tips": "%lbc_amount% earned and bound in tips",
"%lbc_amount% currently staked": "%lbc_amount% currently staked",
"Sync balance and preferences across devices.": "Sync balance and preferences across devices.",
"By creating an account, you agree to our %terms% and confirm you're over the age of 13.": "By creating an account, you agree to our %terms% and confirm you're over the age of 13.",
"Advanced Editor": "Advanced Editor",
@ -701,7 +702,7 @@
"Unlock Rewards": "Unlock Rewards",
"Log in to %SITE_NAME% to earn rewards": "Log in to %SITE_NAME% to earn rewards",
"A %site_name% account allows you to earn more than %credit_amount% in rewards, backup your data, and get content and security updates.": "A %site_name% account allows you to earn more than %credit_amount% in rewards, backup your data, and get content and security updates.",
"Deposit cannot be higher than your balance": "Deposit cannot be higher than your balance",
"Deposit cannot be higher than your available balance": "Deposit cannot be higher than your available balance",
"Your deposit must be higher": "Your deposit must be higher",
"1 view": "1 view",
"%view_count% views": "%view_count% views",

View file

@ -64,7 +64,7 @@ class ChannelCreate extends React.PureComponent<Props, State> {
} else if (newChannelBid === balance) {
newChannelBidError = __('Please decrease your deposit to account for transaction fees');
} else if (newChannelBid > balance) {
newChannelBidError = __('Deposit cannot be higher than your balance');
newChannelBidError = __('Deposit cannot be higher than your available balance');
} else if (newChannelBid < MINIMUM_PUBLISH_BID) {
newChannelBidError = __('Your deposit must be higher');
}

View file

@ -138,7 +138,7 @@ function ChannelForm(props: Props) {
if (bid <= 0.0 || isNaN(bid)) {
setBidError(__('Deposit cannot be 0'));
} else if (totalAvailableBidAmount < bid) {
setBidError(__('Deposit cannot be higher than your balance'));
setBidError(__('Deposit cannot be higher than your available balance'));
} else if (totalAvailableBidAmount - bid < ESTIMATED_FEE) {
setBidError(__('Please decrease your deposit to account for transaction fees'));
} else if (bid < MINIMUM_PUBLISH_BID) {

View file

@ -42,7 +42,7 @@ function FileReactions(props: Props) {
requiresAuth={IS_WEB}
authSrc="filereaction_like"
className={classnames('button--file-action')}
label={formatNumberWithCommas(likeCount)}
label={formatNumberWithCommas(likeCount, 0)}
iconSize={18}
icon={ICONS.UPVOTE}
onClick={() => doReactionLike(uri)}
@ -52,7 +52,7 @@ function FileReactions(props: Props) {
authSrc={'filereaction_dislike'}
title={__('I dislike this')}
className={classnames('button--file-action')}
label={formatNumberWithCommas(dislikeCount)}
label={formatNumberWithCommas(dislikeCount, 0)}
iconSize={18}
icon={ICONS.DOWNVOTE}
onClick={() => doReactionDislike(uri)}

View file

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

View file

@ -88,7 +88,7 @@ function PublishName(props: Props) {
} else if (bid < MINIMUM_PUBLISH_BID) {
bidError = __('Your deposit must be higher');
} else if (totalAvailableBidAmount < bid) {
bidError = __('Deposit cannot be higher than your balance');
bidError = __('Deposit cannot be higher than your available balance');
} else if (totalAvailableBidAmount <= bid + 0.05) {
bidError = __('Please decrease your deposit to account for transaction fees or acquire more LBRY Credits.');
}

View file

@ -210,7 +210,7 @@ function RepostCreate(props: Props) {
} else if (balance === repostBid) {
rBidError = __('Please decrease your deposit to account for transaction fees');
} else if (balance < repostBid) {
rBidError = __('Deposit cannot be higher than your balance');
rBidError = __('Deposit cannot be higher than your available balance');
} else if (repostBid < MINIMUM_PUBLISH_BID) {
rBidError = __('Your deposit must be higher');
}

View file

@ -5,11 +5,11 @@ import * as PAGES from 'constants/pages';
import React from 'react';
import CreditAmount from 'component/common/credit-amount';
import Button from 'component/button';
import Icon from 'component/common/icon';
import HelpLink from 'component/common/help-link';
import Card from 'component/common/card';
import LbcSymbol from 'component/common/lbc-symbol';
import I18nMessage from 'component/i18nMessage';
import { formatNumberWithCommas } from 'util/number';
type Props = {
balance: number,
@ -44,24 +44,82 @@ const WalletBalance = (props: Props) => {
consolidatingUtxos,
utxoCounts,
} = props;
const [detailsExpanded, setDetailsExpanded] = React.useState(false);
const { other: otherCount = 0 } = utxoCounts || {};
const totalBalance = balance + tipsBalance + supportsBalance + claimsBalance;
React.useEffect(() => {
if (balance > LARGE_WALLET_BALANCE) {
doFetchUtxoCounts();
}
}, [doFetchUtxoCounts, balance]);
return (
<React.Fragment>
<section className="columns">
<div>
<div className="section">
<Card
title={<LbcSymbol postfix={balance} isTitle />}
subtitle={__('Available Balance')}
title={<LbcSymbol postfix={formatNumberWithCommas(totalBalance)} isTitle />}
subtitle={
<I18nMessage tokens={{ lbc: <LbcSymbol /> }}>
This is your total balance. Some of the %lbc% is in use on your channels and content right now.
</I18nMessage>
}
actions={
<>
<div className="section__actions--between">
<h2 className="section__title--small">
<I18nMessage tokens={{ lbc_amount: <CreditAmount amount={balance} precision={8} /> }}>
%lbc_amount% available balance
</I18nMessage>
</h2>
<h2 className="section__title--small">
<I18nMessage
tokens={{
lbc_amount: <CreditAmount amount={tipsBalance + claimsBalance + supportsBalance} precision={8} />,
}}
>
%lbc_amount% currently in use
</I18nMessage>
<Button
button="link"
label={detailsExpanded ? __('View less') : __('View more')}
iconRight={detailsExpanded ? ICONS.UP : ICONS.DOWN}
onClick={() => setDetailsExpanded(!detailsExpanded)}
/>
</h2>
{detailsExpanded && (
<div className="section__subtitle">
<dl>
<dt>{__('... earned and bound in tips')}</dt>
<dd>
<CreditAmount amount={tipsBalance} precision={8} />
</dd>
<dt>{__('... in your publishes')}</dt>
<dd>
<CreditAmount amount={claimsBalance} precision={8} />
</dd>
<dt>{__('... in your supports')}</dt>
<dd>
<CreditAmount amount={supportsBalance} precision={8} />
</dd>
</dl>
</div>
)}
{/* @if TARGET='app' */}
{!hasSynced ? (
<p className="section help">
{__('A backup of your wallet is synced with lbry.tv.')}
<HelpLink href="https://lbry.com/faq/account-sync" />
</p>
) : (
<p className="help--warning">
{__('Your wallet is not currently synced with lbry.tv. You are in control of backing up your wallet.')}
<HelpLink navigate={`/$/${PAGES.BACKUP}`} />
</p>
)}
{/* @endif */}
<div className="section__actions">
<Button button="primary" label={__('Buy')} icon={ICONS.BUY} navigate={`/$/${PAGES.BUY}`} />
<Button
@ -77,7 +135,6 @@ const WalletBalance = (props: Props) => {
onClick={() => doOpenModal(MODALS.WALLET_SEND)}
/>
</div>
</div>
{(otherCount > WALLET_CONSOLIDATE_UTXOS || pendingUtxoConsolidating.length || consolidatingUtxos) && (
<p className="help">
<I18nMessage
@ -97,87 +154,14 @@ const WalletBalance = (props: Props) => {
help: <HelpLink href="https://lbry.com/faq/transaction-types" />,
}}
>
Your wallet has a lot of change lying around. Consolidating will speed up your transactions.
This could take some time. %now%%help%
Your wallet has a lot of change lying around. Consolidating will speed up your transactions. This could
take some time. %now%%help%
</I18nMessage>
</p>
)}
</>
}
/>
</div>
</div>
<div>
<React.Fragment>
{/* @if TARGET='app' */}
{hasSynced ? (
<div className="section">
<div className="section__flex">
<Icon sectionIcon icon={ICONS.LOCK} />
<h2 className="section__title--small">
{__('A backup of your wallet is synced with lbry.tv.')}
<HelpLink href="https://lbry.com/faq/account-sync" />
</h2>
</div>
</div>
) : (
<div className="section">
<div className="section__flex">
<Icon sectionIcon icon={ICONS.UNLOCK} />
<h2 className="section__title--small">
{__(
'Your wallet is not currently synced with lbry.tv. You are in control of backing up your wallet.'
)}
<HelpLink navigate={`/$/${PAGES.BACKUP}`} />
</h2>
</div>
</div>
)}
{/* @endif */}
<div className="section">
<div className="section__flex">
<Icon sectionIcon icon={ICONS.SUPPORT} />
<h2 className="section__title--small">
<strong>
<CreditAmount amount={tipsBalance} precision={8} />
</strong>{' '}
{__('earned and bound in tips')}
</h2>
</div>
</div>
<div className="section">
<div className="section__flex">
<Icon sectionIcon icon={ICONS.LOCK} />
<div>
<h2 className="section__title--small">
<strong>
<CreditAmount amount={claimsBalance + supportsBalance} precision={8} />
</strong>{' '}
{__('currently staked')}
</h2>
<div className="section__subtitle">
<dl>
<dt>{__('... in your publishes')}</dt>
<dd>
<CreditAmount amount={claimsBalance} precision={8} />
</dd>
<dt>{__('... in your supports')}</dt>
<dd>
<CreditAmount amount={supportsBalance} precision={8} />
</dd>
</dl>
</div>
</div>
</div>
</div>
</React.Fragment>
</div>
</section>
</React.Fragment>
);
};

View file

@ -56,7 +56,7 @@ function ModalRepost(props: Props) {
} else if (balance === repostBid) {
repostBidError = __('Please decrease your deposit to account for transaction fees');
} else if (balance < repostBid) {
repostBidError = __('Deposit cannot be higher than your balance');
repostBidError = __('Deposit cannot be higher than your available balance');
} else if (repostBid < MINIMUM_PUBLISH_BID) {
repostBidError = __('Your deposit must be higher');
}

View file

@ -31,10 +31,10 @@ const WalletPage = (props: Props) => {
{showIntro ? (
<YrblWalletEmpty includeWalletLink />
) : (
<>
<div className="card-stack">
<WalletBalance />
<TxoList search={search} />
</>
</div>
)}
</>
)}

View file

@ -48,8 +48,15 @@
.section__title--small {
@extend .section__title;
font-size: var(--font-body);
.button {
margin-left: var(--spacing-s);
}
&:not(:first-of-type) {
margin-top: var(--spacing-m);
}
}
.section__title--large {
@extend .section__title;

View file

@ -231,7 +231,11 @@ textarea {
.help--warning {
@extend .help;
color: var(--color-text-help-warning);
padding: var(--spacing-s);
color: var(--color-black);
border-radius: var(--border-radius);
background-color: var(--color-help-warning-bg);
color: var(--color-help-warning-text);
margin-bottom: var(--spacing-s);
}

View file

@ -63,7 +63,8 @@
// Text
--color-text: #d8d8d8;
--color-text-error: #f5748c;
--color-text-help-warning: #f5ec74;
--color-help-warning-bg: #fbbf2450;
--color-help-warning-text: white;
--color-text-empty: var(--color-text-subtitle);
--color-text-help: #bbbbbb;

View file

@ -43,7 +43,8 @@
--color-text-help: #999999;
--color-text-subtitle: #767676;
--color-text-warning: #212529;
--color-text-help-warning: #989b20;
--color-help-warning-bg: #fef3c7;
--color-help-warning-text: black;
--color-text-warning--background: var(--lbry-yellow-1);
--color-blockquote: var(--color-gray-3);
--color-blockquote-bg: var(--color-gray-1);

View file

@ -1,5 +1,5 @@
// @flow
export function formatNumberWithCommas(num: number): string {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
export function formatNumberWithCommas(num: number, numberOfDigits?: number): string {
return num.toLocaleString('en', { minimumFractionDigits: numberOfDigits !== undefined ? numberOfDigits : 8 });
}