Compact follower counts (#7432)
* Factor out 'toCompactNotation' * File page: use compact view count (w/ tooltip for full res) Co-authored-by: infinite-persistence <inf.persistence@gmail.com>
This commit is contained in:
parent
caf32736b5
commit
3f0cc0bf2e
4 changed files with 34 additions and 25 deletions
|
@ -1,13 +1,16 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectClaimForUri } from 'redux/selectors/claims';
|
import { selectClaimIdForUri } from 'redux/selectors/claims';
|
||||||
import { doFetchViewCount, selectViewCountForUri } from 'lbryinc';
|
import { doFetchViewCount, selectViewCountForUri } from 'lbryinc';
|
||||||
import { doAnalyticsView } from 'redux/actions/app';
|
import { doAnalyticsView } from 'redux/actions/app';
|
||||||
import FileViewCount from './view';
|
import FileViewCount from './view';
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => {
|
||||||
claim: selectClaimForUri(state, props.uri),
|
const claimId = selectClaimIdForUri(state, props.uri);
|
||||||
|
return {
|
||||||
|
claimId,
|
||||||
viewCount: selectViewCountForUri(state, props.uri),
|
viewCount: selectViewCountForUri(state, props.uri),
|
||||||
});
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
fetchViewCount: (claimId) => dispatch(doFetchViewCount(claimId)),
|
fetchViewCount: (claimId) => dispatch(doFetchViewCount(claimId)),
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import HelpLink from 'component/common/help-link';
|
import HelpLink from 'component/common/help-link';
|
||||||
|
import Tooltip from 'component/common/tooltip';
|
||||||
|
import { toCompactNotation } from 'util/string';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
claim: ?StreamClaim,
|
claimId: ?string, // this
|
||||||
fetchViewCount: (string) => void,
|
fetchViewCount: (string) => void,
|
||||||
fetchingViewCount: boolean,
|
fetchingViewCount: boolean,
|
||||||
uri: string,
|
uri: string,
|
||||||
|
@ -11,8 +13,9 @@ type Props = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function FileViewCount(props: Props) {
|
function FileViewCount(props: Props) {
|
||||||
const { claim, uri, fetchViewCount, viewCount } = props;
|
const { claimId, uri, fetchViewCount, viewCount } = props; // claimId
|
||||||
const claimId = claim && claim.claim_id;
|
const countCompact = toCompactNotation(viewCount);
|
||||||
|
const countFullResolution = Number(viewCount).toLocaleString();
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (claimId) {
|
if (claimId) {
|
||||||
|
@ -20,13 +23,13 @@ function FileViewCount(props: Props) {
|
||||||
}
|
}
|
||||||
}, [fetchViewCount, uri, claimId]);
|
}, [fetchViewCount, uri, claimId]);
|
||||||
|
|
||||||
const formattedViewCount = Number(viewCount).toLocaleString();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<Tooltip label={countFullResolution}>
|
||||||
<span className="media__subtitle--centered">
|
<span className="media__subtitle--centered">
|
||||||
{viewCount !== 1 ? __('%view_count% views', { view_count: formattedViewCount }) : __('1 view')}
|
{viewCount !== 1 ? __('%view_count% views', { view_count: countCompact }) : __('1 view')}
|
||||||
{<HelpLink href="https://lbry.com/faq/views" />}
|
{<HelpLink href="https://lbry.com/faq/views" />}
|
||||||
</span>
|
</span>
|
||||||
|
</Tooltip>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import 'scss/component/_view_count.scss';
|
import 'scss/component/_view_count.scss';
|
||||||
import { useHistory } from 'react-router';
|
import { useHistory } from 'react-router';
|
||||||
|
import { toCompactNotation } from 'util/string';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
|
@ -16,17 +17,7 @@ export default function FileViewCountInline(props: Props) {
|
||||||
const {
|
const {
|
||||||
location: { pathname },
|
location: { pathname },
|
||||||
} = useHistory();
|
} = useHistory();
|
||||||
let formattedViewCount;
|
const formattedViewCount = toCompactNotation(viewCount, lang);
|
||||||
|
|
||||||
try {
|
|
||||||
// SI notation that changes 1234 to 1.2K, look up Intl.NumberFormat() for docs
|
|
||||||
formattedViewCount = Number(viewCount).toLocaleString(lang || 'en', {
|
|
||||||
compactDisplay: 'short',
|
|
||||||
notation: 'compact',
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
formattedViewCount = Number(viewCount).toLocaleString();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Limit the view-count visibility to Channel Pages for now. I believe we'll
|
// Limit the view-count visibility to Channel Pages for now. I believe we'll
|
||||||
// eventually show it everywhere, so this band-aid would be the easiest to
|
// eventually show it everywhere, so this band-aid would be the easiest to
|
||||||
|
|
|
@ -3,3 +3,15 @@
|
||||||
export function toCapitalCase(string: string) {
|
export function toCapitalCase(string: string) {
|
||||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toCompactNotation(number: string | number, lang: ?string) {
|
||||||
|
try {
|
||||||
|
return Number(number).toLocaleString(lang || 'en', {
|
||||||
|
compactDisplay: 'short',
|
||||||
|
notation: 'compact',
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
// Not all browsers support the addition options.
|
||||||
|
return Number(number).toLocaleString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue