File page: compact form for View and Follower Count (#658)

This commit is contained in:
infinite-persistence 2022-01-10 11:16:45 +08:00
commit 6fffae6d46
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0
4 changed files with 37 additions and 25 deletions

View file

@ -10,6 +10,7 @@ import * as COLLECTIONS_CONSTS from 'constants/collections';
import { isChannelClaim } from 'util/claim'; import { isChannelClaim } from 'util/claim';
import { formatLbryUrlForWeb } from 'util/url'; import { formatLbryUrlForWeb } from 'util/url';
import { formatClaimPreviewTitle } from 'util/formatAriaLabel'; import { formatClaimPreviewTitle } from 'util/formatAriaLabel';
import { toCompactNotation } from 'util/string';
import FileThumbnail from 'component/fileThumbnail'; import FileThumbnail from 'component/fileThumbnail';
import UriIndicator from 'component/uriIndicator'; import UriIndicator from 'component/uriIndicator';
import PreviewOverlayProperties from 'component/previewOverlayProperties'; import PreviewOverlayProperties from 'component/previewOverlayProperties';
@ -165,10 +166,12 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
if (channelSubCount === undefined) { if (channelSubCount === undefined) {
return <span />; return <span />;
} }
const formattedSubCount = Number(channelSubCount).toLocaleString();
return ( return (
<span className="claim-preview__channel-sub-count"> <span className="claim-preview__channel-sub-count">
{channelSubCount === 1 ? __('1 Follower') : __('%formattedSubCount% Followers', { formattedSubCount })} {channelSubCount === 1
? __('1 Follower')
: __('%formattedSubCount% Followers', { formattedSubCount: toCompactNotation(channelSubCount) })}
</span> </span>
); );
}, [channelSubCount]); }, [channelSubCount]);

View file

@ -2,6 +2,8 @@
import { SIMPLE_SITE } from 'config'; import { SIMPLE_SITE } from 'config';
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 = {
livestream?: boolean, livestream?: boolean,
@ -16,6 +18,9 @@ type Props = {
function FileViewCount(props: Props) { function FileViewCount(props: Props) {
const { claimId, fetchViewCount, viewCount, livestream, activeViewers, isLive = false } = props; const { claimId, fetchViewCount, viewCount, livestream, activeViewers, isLive = false } = props;
const count = livestream ? activeViewers || 0 : viewCount;
const countCompact = toCompactNotation(count);
const countFullResolution = Number(count).toLocaleString();
React.useEffect(() => { React.useEffect(() => {
if (claimId) { if (claimId) {
@ -23,20 +28,20 @@ function FileViewCount(props: Props) {
} }
}, [claimId]); // eslint-disable-line react-hooks/exhaustive-deps }, [claimId]); // eslint-disable-line react-hooks/exhaustive-deps
const formattedViewCount = Number(viewCount).toLocaleString();
return ( return (
<span className="media__subtitle--centered"> <Tooltip title={countFullResolution}>
{livestream && <span className="media__subtitle--centered">
__('%viewer_count% currently %viewer_state%', { {livestream &&
viewer_count: activeViewers === undefined ? '...' : activeViewers, __('%viewer_count% currently %viewer_state%', {
viewer_state: isLive ? __('watching') : __('waiting'), viewer_count: activeViewers === undefined ? '...' : countCompact,
})} viewer_state: isLive ? __('watching') : __('waiting'),
{!livestream && })}
activeViewers === undefined && {!livestream &&
(viewCount !== 1 ? __('%view_count% views', { view_count: formattedViewCount }) : __('1 view'))} activeViewers === undefined &&
{!SIMPLE_SITE && <HelpLink href="https://odysee.com/@OdyseeHelp:b/OdyseeBasics:c" />} (viewCount !== 1 ? __('%view_count% views', { view_count: countCompact }) : __('1 view'))}
</span> {!SIMPLE_SITE && <HelpLink href="https://odysee.com/@OdyseeHelp:b/OdyseeBasics:c" />}
</span>
</Tooltip>
); );
} }

View file

@ -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 * as PAGES from 'constants/pages'; import * as PAGES from 'constants/pages';
import { toCompactNotation } from 'util/string';
type Props = { type Props = {
uri: string, uri: string,
@ -14,16 +15,7 @@ type Props = {
export default function FileViewCountInline(props: Props) { export default function FileViewCountInline(props: Props) {
const { isLivestream, claim, viewCount, lang } = props; const { isLivestream, claim, viewCount, lang } = props;
let formattedViewCount; const formattedViewCount = toCompactNotation(viewCount, lang);
try {
formattedViewCount = Number(viewCount).toLocaleString(lang || 'en', {
compactDisplay: 'short',
notation: 'compact',
});
} catch (err) {
formattedViewCount = Number(viewCount).toLocaleString();
}
// Limit the view-count visibility to specific pages for now. We'll eventually // Limit the view-count visibility to specific pages for now. We'll eventually
// show it everywhere, so this band-aid would be the easiest to clean up // show it everywhere, so this band-aid would be the easiest to clean up

View file

@ -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();
}
}