Localization: Respect locale number format for floats (#5863)
This commit is contained in:
parent
b3c6ae2089
commit
29ec767eb2
@ -6,6 +6,7 @@ import { getAllNotificationsCount } from '../../util/folderManager';
|
||||
import { formatIntegerCompact } from '../../util/textFormat';
|
||||
|
||||
import { useFolderManagerForUnreadCounters } from '../../hooks/useFolderManager';
|
||||
import useLang from '../../hooks/useLang';
|
||||
|
||||
interface OwnProps {
|
||||
isForAppBadge?: boolean;
|
||||
@ -15,6 +16,8 @@ const UnreadCounter: FC<OwnProps> = ({ isForAppBadge }) => {
|
||||
useFolderManagerForUnreadCounters();
|
||||
const unreadNotificationsCount = getAllNotificationsCount();
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
useEffect(() => {
|
||||
if (isForAppBadge) {
|
||||
updateAppBadge(unreadNotificationsCount);
|
||||
@ -26,7 +29,7 @@ const UnreadCounter: FC<OwnProps> = ({ isForAppBadge }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="unread-count active">{formatIntegerCompact(unreadNotificationsCount)}</div>
|
||||
<div className="unread-count active">{formatIntegerCompact(lang, unreadNotificationsCount)}</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -69,7 +69,7 @@ const SavedGift = ({
|
||||
const ribbonText = gift.isPinned && gift.gift.type === 'starGiftUnique'
|
||||
? lang('GiftSavedNumber', { number: gift.gift.number })
|
||||
: totalIssued
|
||||
? lang('ActionStarGiftLimitedRibbon', { total: formatIntegerCompact(totalIssued) })
|
||||
? lang('ActionStarGiftLimitedRibbon', { total: formatIntegerCompact(lang, totalIssued) })
|
||||
: undefined;
|
||||
|
||||
const {
|
||||
|
||||
@ -118,7 +118,7 @@ const Archive: FC<OwnProps> = ({
|
||||
</div>
|
||||
<Badge
|
||||
className={styles.unreadCount}
|
||||
text={archiveUnreadCount ? formatIntegerCompact(archiveUnreadCount) : undefined}
|
||||
text={archiveUnreadCount ? formatIntegerCompact(lang, archiveUnreadCount) : undefined}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -143,7 +143,7 @@ const Archive: FC<OwnProps> = ({
|
||||
</div>
|
||||
<Badge
|
||||
className={styles.unreadCount}
|
||||
text={archiveUnreadCount ? formatIntegerCompact(archiveUnreadCount) : undefined}
|
||||
text={archiveUnreadCount ? formatIntegerCompact(lang, archiveUnreadCount) : undefined}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -12,6 +12,7 @@ import { formatIntegerCompact } from '../../../util/textFormat';
|
||||
import { extractCurrentThemeParams } from '../../../util/themeStyle';
|
||||
|
||||
import useDerivedState from '../../../hooks/useDerivedState';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
import useOldLang from '../../../hooks/useOldLang';
|
||||
|
||||
@ -52,6 +53,7 @@ const ChatBadge: FC<OwnProps> = ({
|
||||
const { requestMainWebView } = getActions();
|
||||
|
||||
const oldLang = useOldLang();
|
||||
const lang = useLang();
|
||||
|
||||
const {
|
||||
unreadMentionsCount = 0, unreadReactionsCount = 0,
|
||||
@ -136,7 +138,7 @@ const ChatBadge: FC<OwnProps> = ({
|
||||
|
||||
const unreadCountElement = (hasUnreadMark || unreadCount) ? (
|
||||
<div className={className}>
|
||||
{!hasUnreadMark && <AnimatedCounter text={formatIntegerCompact(unreadCount!)} />}
|
||||
{!hasUnreadMark && <AnimatedCounter text={formatIntegerCompact(lang, unreadCount!)} />}
|
||||
</div>
|
||||
) : undefined;
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ import { formatIntegerCompact } from '../../util/textFormat';
|
||||
|
||||
import useFlag from '../../hooks/useFlag';
|
||||
import useInfiniteScroll from '../../hooks/useInfiniteScroll';
|
||||
import useLang from '../../hooks/useLang';
|
||||
import useLastCallback from '../../hooks/useLastCallback';
|
||||
import useOldLang from '../../hooks/useOldLang';
|
||||
|
||||
@ -67,7 +68,8 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
|
||||
const chatsById = getGlobal().chats.byId;
|
||||
const usersById = getGlobal().users.byId;
|
||||
|
||||
const lang = useOldLang();
|
||||
const oldLang = useOldLang();
|
||||
const lang = useLang();
|
||||
const [isClosing, startClosing, stopClosing] = useFlag(false);
|
||||
const [chosenTab, setChosenTab] = useState<ApiReaction | undefined>(undefined);
|
||||
const canShowFilters = reactors && reactions && reactors.count >= MIN_REACTIONS_COUNT_FOR_FILTERS
|
||||
@ -143,11 +145,11 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
|
||||
isOpen={isOpen && !isClosing}
|
||||
onClose={handleClose}
|
||||
className="ReactorListModal narrow"
|
||||
title={lang('Reactions')}
|
||||
title={oldLang('Reactions')}
|
||||
onCloseAnimationEnd={handleCloseAnimationEnd}
|
||||
>
|
||||
{canShowFilters && (
|
||||
<div className="Reactions" dir={lang.isRtl ? 'rtl' : undefined}>
|
||||
<div className="Reactions" dir={oldLang.isRtl ? 'rtl' : undefined}>
|
||||
<Button
|
||||
className={buildClassName(!chosenTab && 'chosen')}
|
||||
size="tiny"
|
||||
@ -156,7 +158,7 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
|
||||
onClick={() => setChosenTab(undefined)}
|
||||
>
|
||||
<Icon name="heart" />
|
||||
{Boolean(reactors?.count) && formatIntegerCompact(reactors.count)}
|
||||
{Boolean(reactors?.count) && formatIntegerCompact(lang, reactors.count)}
|
||||
</Button>
|
||||
{allReactions.map((reaction) => {
|
||||
const count = reactions?.results
|
||||
@ -175,14 +177,14 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
|
||||
className="reaction-filter-emoji"
|
||||
availableReactions={availableReactions}
|
||||
/>
|
||||
{Boolean(count) && formatIntegerCompact(count)}
|
||||
{Boolean(count) && formatIntegerCompact(lang, count)}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div dir={lang.isRtl ? 'rtl' : undefined} className="reactor-list-wrapper">
|
||||
<div dir={oldLang.isRtl ? 'rtl' : undefined} className="reactor-list-wrapper">
|
||||
{viewportIds?.length ? (
|
||||
<InfiniteScroll
|
||||
className="reactor-list custom-scroll"
|
||||
@ -212,7 +214,7 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
|
||||
<FullNameTitle peer={peer} withEmojiStatus />
|
||||
<span className="status" dir="auto">
|
||||
<Icon name="heart-outline" className="status-icon" />
|
||||
{formatDateAtTime(lang, r.addedDate * 1000)}
|
||||
{formatDateAtTime(oldLang, r.addedDate * 1000)}
|
||||
</span>
|
||||
</div>
|
||||
{r.reaction && (
|
||||
@ -238,7 +240,7 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
|
||||
userId={peerId}
|
||||
noStatusOrTyping
|
||||
avatarSize="medium"
|
||||
status={seenByUser ? formatDateAtTime(lang, seenByUser * 1000) : undefined}
|
||||
status={seenByUser ? formatDateAtTime(oldLang, seenByUser * 1000) : undefined}
|
||||
statusIcon="message-read"
|
||||
/>
|
||||
</ListItem>,
|
||||
@ -255,7 +257,7 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
|
||||
isText
|
||||
onClick={handleClose}
|
||||
>
|
||||
{lang('Close')}
|
||||
{oldLang('Close')}
|
||||
</Button>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
@ -7,6 +7,7 @@ import buildClassName from '../../util/buildClassName';
|
||||
import { formatIntegerCompact } from '../../util/textFormat';
|
||||
|
||||
import useContextMenuHandlers from '../../hooks/useContextMenuHandlers';
|
||||
import useLang from '../../hooks/useLang';
|
||||
import useOldLang from '../../hooks/useOldLang';
|
||||
|
||||
import Icon from '../common/icons/Icon';
|
||||
@ -33,7 +34,8 @@ const ScrollDownButton: FC<OwnProps> = ({
|
||||
onReadAll,
|
||||
className,
|
||||
}) => {
|
||||
const lang = useOldLang();
|
||||
const oldLang = useOldLang();
|
||||
const lang = useLang();
|
||||
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
@ -52,11 +54,11 @@ const ScrollDownButton: FC<OwnProps> = ({
|
||||
className={styles.button}
|
||||
onClick={onClick}
|
||||
onContextMenu={handleContextMenu}
|
||||
ariaLabel={lang(ariaLabelLang)}
|
||||
ariaLabel={oldLang(ariaLabelLang)}
|
||||
>
|
||||
<Icon name={icon} className={styles.icon} />
|
||||
</Button>
|
||||
{Boolean(unreadCount) && <div className={styles.unreadCount}>{formatIntegerCompact(unreadCount)}</div>}
|
||||
{Boolean(unreadCount) && <div className={styles.unreadCount}>{formatIntegerCompact(lang, unreadCount)}</div>}
|
||||
{onReadAll && (
|
||||
<Menu
|
||||
isOpen={isContextMenuOpen}
|
||||
@ -66,7 +68,7 @@ const ScrollDownButton: FC<OwnProps> = ({
|
||||
positionX="right"
|
||||
positionY="bottom"
|
||||
>
|
||||
<MenuItem icon="readchats" onClick={onReadAll}>{lang('MarkAllAsRead')}</MenuItem>
|
||||
<MenuItem icon="readchats" onClick={onReadAll}>{oldLang('MarkAllAsRead')}</MenuItem>
|
||||
</Menu>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -8,6 +8,7 @@ import { selectIsCurrentUserFrozen, selectPeer } from '../../../global/selectors
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
import { formatIntegerCompact } from '../../../util/textFormat';
|
||||
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
import useOldLang from '../../../hooks/useOldLang';
|
||||
import useAsyncRendering from '../../right/hooks/useAsyncRendering';
|
||||
@ -40,7 +41,8 @@ const CommentButton: FC<OwnProps> = ({
|
||||
|
||||
const shouldRenderLoading = useAsyncRendering([isLoading], SHOW_LOADER_DELAY);
|
||||
|
||||
const lang = useOldLang();
|
||||
const oldLang = useOldLang();
|
||||
const lang = useLang();
|
||||
const {
|
||||
originMessageId, chatId, messagesCount, lastMessageId, lastReadInboxMessageId, recentReplierIds, originChannelId,
|
||||
} = threadInfo;
|
||||
@ -76,7 +78,7 @@ const CommentButton: FC<OwnProps> = ({
|
||||
function renderRecentRepliers() {
|
||||
return (
|
||||
Boolean(recentRepliers?.length) && (
|
||||
<div className="recent-repliers" dir={lang.isRtl ? 'rtl' : 'ltr'}>
|
||||
<div className="recent-repliers" dir={oldLang.isRtl ? 'rtl' : 'ltr'}>
|
||||
{recentRepliers!.map((peer) => (
|
||||
<Avatar
|
||||
key={peer.id}
|
||||
@ -91,16 +93,16 @@ const CommentButton: FC<OwnProps> = ({
|
||||
|
||||
const hasUnread = Boolean(lastReadInboxMessageId && lastMessageId && lastReadInboxMessageId < lastMessageId);
|
||||
|
||||
const commentsText = messagesCount ? (lang('CommentsCount', '%COMMENTS_COUNT%', undefined, messagesCount) as string)
|
||||
const commentsText = messagesCount ? (oldLang('CommentsCount', '%COMMENTS_COUNT%', undefined, messagesCount))
|
||||
.split('%')
|
||||
.map((s) => {
|
||||
return (s === 'COMMENTS_COUNT' ? <AnimatedCounter text={formatIntegerCompact(messagesCount)} /> : s);
|
||||
return (s === 'COMMENTS_COUNT' ? <AnimatedCounter text={formatIntegerCompact(lang, messagesCount)} /> : s);
|
||||
})
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<div
|
||||
data-cnt={formatIntegerCompact(messagesCount)}
|
||||
data-cnt={formatIntegerCompact(lang, messagesCount)}
|
||||
className={buildClassName(
|
||||
'CommentButton',
|
||||
hasUnread && 'has-unread',
|
||||
@ -109,7 +111,7 @@ const CommentButton: FC<OwnProps> = ({
|
||||
isLoading && 'loading',
|
||||
asActionButton && 'as-action-button',
|
||||
)}
|
||||
dir={lang.isRtl ? 'rtl' : 'ltr'}
|
||||
dir={oldLang.isRtl ? 'rtl' : 'ltr'}
|
||||
onClick={handleClick}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
@ -124,7 +126,7 @@ const CommentButton: FC<OwnProps> = ({
|
||||
{!recentRepliers?.length && <Icon name="comments" />}
|
||||
{renderRecentRepliers()}
|
||||
<div className="label" dir="auto">
|
||||
{messagesCount ? commentsText : lang('LeaveAComment')}
|
||||
{messagesCount ? commentsText : oldLang('LeaveAComment')}
|
||||
</div>
|
||||
<div className="CommentButton_right">
|
||||
{isLoading && (
|
||||
|
||||
@ -112,10 +112,14 @@ const MessageMeta: FC<OwnProps> = ({
|
||||
|
||||
const viewsTitle = useMemo(() => {
|
||||
if (!message.viewsCount) return undefined;
|
||||
let text = lang('MessageTooltipViews', { count: message.viewsCount }, { pluralValue: message.viewsCount });
|
||||
let text = lang('MessageTooltipViews', {
|
||||
count: lang.number(message.viewsCount),
|
||||
}, { pluralValue: message.viewsCount });
|
||||
if (message.forwardsCount) {
|
||||
text += '\n';
|
||||
text += lang('MessageTooltipForwards', { count: message.forwardsCount }, { pluralValue: message.forwardsCount });
|
||||
text += lang('MessageTooltipForwards', {
|
||||
count: lang.number(message.forwardsCount),
|
||||
}, { pluralValue: message.forwardsCount });
|
||||
}
|
||||
|
||||
return text;
|
||||
@ -160,7 +164,7 @@ const MessageMeta: FC<OwnProps> = ({
|
||||
{Boolean(message.viewsCount) && (
|
||||
<>
|
||||
<span className="message-views" title={viewsTitle}>
|
||||
{formatIntegerCompact(message.viewsCount!)}
|
||||
{formatIntegerCompact(lang, message.viewsCount!)}
|
||||
</span>
|
||||
<Icon name="channelviews" />
|
||||
</>
|
||||
@ -168,7 +172,7 @@ const MessageMeta: FC<OwnProps> = ({
|
||||
{!noReplies && Boolean(repliesThreadInfo?.messagesCount) && (
|
||||
<span onClick={handleOpenThread} className="message-replies-wrapper" title={repliesTitle}>
|
||||
<span className="message-replies">
|
||||
<AnimatedCounter text={formatIntegerCompact(repliesThreadInfo!.messagesCount!)} />
|
||||
<AnimatedCounter text={formatIntegerCompact(lang, repliesThreadInfo!.messagesCount!)} />
|
||||
</span>
|
||||
<Icon name="reply-filled" />
|
||||
</span>
|
||||
|
||||
@ -19,6 +19,7 @@ import useTimeout from '../../../hooks/schedulers/useTimeout';
|
||||
import useAverageColor from '../../../hooks/useAverageColor';
|
||||
import useFlag from '../../../hooks/useFlag';
|
||||
import useHorizontalScroll from '../../../hooks/useHorizontalScroll';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
import useOldLang from '../../../hooks/useOldLang';
|
||||
|
||||
@ -203,13 +204,14 @@ const SimilarChannels = ({
|
||||
function SimilarChannel({ channel }: { channel: ApiChat }) {
|
||||
const { openChat } = getActions();
|
||||
const color = useAverageColor(channel, DEFAULT_BADGE_COLOR);
|
||||
const lang = useLang();
|
||||
|
||||
return (
|
||||
<div className={styles.item} onClick={() => openChat({ id: channel.id })}>
|
||||
<Avatar className={styles.avatar} key={channel.id} size="large" peer={channel} />
|
||||
<div style={`background: ${color}`} className={styles.badge}>
|
||||
<Icon name="user-filled" className={styles.icon} />
|
||||
<span className={styles.membersCount}>{formatIntegerCompact(channel?.membersCount || 0)}
|
||||
<span className={styles.membersCount}>{formatIntegerCompact(lang, channel?.membersCount || 0)}
|
||||
</span>
|
||||
</div>
|
||||
<span className={styles.channelTitle}>{channel.title}</span>
|
||||
|
||||
@ -145,7 +145,9 @@ const StarGiftAction = ({
|
||||
{action.gift.availabilityTotal && (
|
||||
<GiftRibbon
|
||||
color={backgroundColor || 'blue'}
|
||||
text={lang('ActionStarGiftLimitedRibbon', { total: formatIntegerCompact(action.gift.availabilityTotal) })}
|
||||
text={lang('ActionStarGiftLimitedRibbon', {
|
||||
total: formatIntegerCompact(lang, action.gift.availabilityTotal),
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
<div className={styles.info}>
|
||||
|
||||
@ -15,6 +15,7 @@ import { REM } from '../../../common/helpers/mediaDimensions';
|
||||
import useSelector from '../../../../hooks/data/useSelector';
|
||||
import useContextMenuHandlers from '../../../../hooks/useContextMenuHandlers';
|
||||
import useEffectWithPrevDeps from '../../../../hooks/useEffectWithPrevDeps';
|
||||
import useLang from '../../../../hooks/useLang';
|
||||
import useLastCallback from '../../../../hooks/useLastCallback';
|
||||
import usePrevious from '../../../../hooks/usePrevious';
|
||||
import useShowTransition from '../../../../hooks/useShowTransition';
|
||||
@ -76,6 +77,8 @@ const ReactionButton = ({
|
||||
const counterRef = useRef<HTMLSpanElement>(null);
|
||||
const animationRef = useRef<Animation>();
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
const isPaid = reaction.reaction.type === 'paid';
|
||||
|
||||
const starsState = useSelector(selectStarsState);
|
||||
@ -198,7 +201,7 @@ const ReactionButton = ({
|
||||
{shouldRenderPaidCounter && (
|
||||
<AnimatedCounter
|
||||
ref={counterRef}
|
||||
text={`+${formatIntegerCompact(reaction.localAmount || prevAmount!)}`}
|
||||
text={`+${formatIntegerCompact(lang, reaction.localAmount || prevAmount!)}`}
|
||||
className={styles.paidCounter}
|
||||
/>
|
||||
)}
|
||||
@ -216,7 +219,7 @@ const ReactionButton = ({
|
||||
<AvatarList size="mini" peers={recentReactors} />
|
||||
) : (
|
||||
<AnimatedCounter
|
||||
text={formatIntegerCompact(reaction.count + (reaction.localAmount || 0))}
|
||||
text={formatIntegerCompact(lang, reaction.count + (reaction.localAmount || 0))}
|
||||
className={styles.counter}
|
||||
/>
|
||||
)}
|
||||
|
||||
@ -12,6 +12,7 @@ import buildClassName from '../../../util/buildClassName';
|
||||
import { formatIntegerCompact } from '../../../util/textFormat';
|
||||
import { extractCurrentThemeParams } from '../../../util/themeStyle';
|
||||
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
|
||||
import PeerBadge from '../../common/PeerBadge';
|
||||
@ -33,6 +34,8 @@ function WebAppGridItem({ user, isPopularApp }: OwnProps & StateProps) {
|
||||
requestMainWebView,
|
||||
} = getActions();
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
const handleClick = useLastCallback(() => {
|
||||
if (!user) {
|
||||
return;
|
||||
@ -55,7 +58,7 @@ function WebAppGridItem({ user, isPopularApp }: OwnProps & StateProps) {
|
||||
|
||||
const title = user?.firstName;
|
||||
const activeUserCount = user?.botActiveUsers;
|
||||
const badgeText = activeUserCount && isPopularApp ? formatIntegerCompact(activeUserCount) : undefined;
|
||||
const badgeText = activeUserCount && isPopularApp ? formatIntegerCompact(lang, activeUserCount) : undefined;
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@ -11,6 +11,7 @@ import buildClassName from '../../../util/buildClassName';
|
||||
import { formatFullDate } from '../../../util/dates/dateFormat';
|
||||
import { formatInteger, formatIntegerCompact } from '../../../util/textFormat';
|
||||
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useOldLang from '../../../hooks/useOldLang';
|
||||
|
||||
import Icon from '../../common/icons/Icon';
|
||||
@ -121,7 +122,8 @@ const StatisticsOverview: FC<OwnProps> = ({
|
||||
className,
|
||||
subtitle,
|
||||
}) => {
|
||||
const lang = useOldLang();
|
||||
const oldLang = useOldLang();
|
||||
const lang = useLang();
|
||||
|
||||
const renderOverviewItemValue = ({ change, percentage }: StatisticsOverviewItem) => {
|
||||
if (!change) {
|
||||
@ -132,7 +134,9 @@ const StatisticsOverview: FC<OwnProps> = ({
|
||||
|
||||
return (
|
||||
<span className={buildClassName(styles.value, isChangeNegative && styles.negative)}>
|
||||
{isChangeNegative ? `-${formatIntegerCompact(Math.abs(change))}` : `+${formatIntegerCompact(change)}`}
|
||||
{isChangeNegative
|
||||
? `-${formatIntegerCompact(lang, Math.abs(change))}`
|
||||
: `+${formatIntegerCompact(lang, change)}`}
|
||||
{percentage && (
|
||||
<>
|
||||
{' '}
|
||||
@ -156,7 +160,7 @@ const StatisticsOverview: FC<OwnProps> = ({
|
||||
<span className={styles.tableHeading}>
|
||||
≈ ${integerUsdPart}<span className={styles.decimalUsdPart}>.{decimalUsdPart}</span>
|
||||
</span>
|
||||
<h3 className={styles.tableHeading}>{lang(text)}</h3>
|
||||
<h3 className={styles.tableHeading}>{oldLang(text)}</h3>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -177,7 +181,7 @@ const StatisticsOverview: FC<OwnProps> = ({
|
||||
|
||||
{period && (
|
||||
<div className={styles.caption}>
|
||||
{formatFullDate(lang, period.minDate * 1000)} — {formatFullDate(lang, period.maxDate * 1000)}
|
||||
{formatFullDate(oldLang, period.minDate * 1000)} — {formatFullDate(oldLang, period.maxDate * 1000)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@ -202,7 +206,7 @@ const StatisticsOverview: FC<OwnProps> = ({
|
||||
<b className={styles.tableValue}>
|
||||
{`${cell.isApproximate ? '≈' : ''}${formatInteger(field)}`}
|
||||
</b>
|
||||
<h3 className={styles.tableHeading}>{lang(cell.title)}</h3>
|
||||
<h3 className={styles.tableHeading}>{oldLang(cell.title)}</h3>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
@ -218,7 +222,7 @@ const StatisticsOverview: FC<OwnProps> = ({
|
||||
<span className={cell.withAbsoluteValue ? styles.tableSecondaryValue : styles.tableValue}>
|
||||
{field.percentage}%
|
||||
</span>
|
||||
<h3 className={styles.tableHeading}>{lang(cell.title)}</h3>
|
||||
<h3 className={styles.tableHeading}>{oldLang(cell.title)}</h3>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
@ -226,11 +230,11 @@ const StatisticsOverview: FC<OwnProps> = ({
|
||||
return (
|
||||
<td className={styles.tableCell}>
|
||||
<b className={styles.tableValue}>
|
||||
{formatIntegerCompact(field.current)}
|
||||
{formatIntegerCompact(lang, field.current)}
|
||||
</b>
|
||||
{' '}
|
||||
{renderOverviewItemValue(field)}
|
||||
<h3 className={styles.tableHeading}>{lang(cell.title)}</h3>
|
||||
<h3 className={styles.tableHeading}>{oldLang(cell.title)}</h3>
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
|
||||
@ -4,6 +4,7 @@ import type { StatisticsMessageInteractionCounter, StatisticsStoryInteractionCou
|
||||
|
||||
import { formatIntegerCompact } from '../../../util/textFormat';
|
||||
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useOldLang from '../../../hooks/useOldLang';
|
||||
|
||||
import Icon from '../../common/icons/Icon';
|
||||
@ -15,25 +16,26 @@ interface OwnProps {
|
||||
}
|
||||
|
||||
function StatisticsRecentPostMeta({ postStatistic }: OwnProps) {
|
||||
const lang = useOldLang();
|
||||
const oldLang = useOldLang();
|
||||
const lang = useLang();
|
||||
return (
|
||||
<div className={styles.meta}>
|
||||
{postStatistic.reactionsCount > 0 && (
|
||||
<span className={styles.metaWithIcon}>
|
||||
<Icon name="heart-outline" className={styles.metaIcon} />
|
||||
{formatIntegerCompact(postStatistic.reactionsCount)}
|
||||
{formatIntegerCompact(lang, postStatistic.reactionsCount)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{postStatistic.forwardsCount > 0 && (
|
||||
<span className={styles.metaWithIcon}>
|
||||
<Icon name="forward" className={styles.metaIcon} />
|
||||
{formatIntegerCompact(postStatistic.forwardsCount)}
|
||||
{formatIntegerCompact(lang, postStatistic.forwardsCount)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{!postStatistic.forwardsCount && !postStatistic.reactionsCount
|
||||
&& lang('ChannelStats.SharesCount_ZeroValueHolder')}
|
||||
&& oldLang('ChannelStats.SharesCount_ZeroValueHolder')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
export const clamp = (num: number, min: number, max: number) => (Math.min(max, Math.max(min, num)));
|
||||
export const isBetween = (num: number, min: number, max: number) => (num >= min && num <= max);
|
||||
export const round = (num: number, decimals: number = 0) => Math.round(num * 10 ** decimals) / 10 ** decimals;
|
||||
export const ceil = (num: number, decimals: number = 0) => Math.ceil(num * 10 ** decimals) / 10 ** decimals;
|
||||
export const floor = (num: number, decimals: number = 0) => Math.floor(num * 10 ** decimals) / 10 ** decimals;
|
||||
export const lerp = (start: number, end: number, interpolationRatio: number) => {
|
||||
return (1 - interpolationRatio) * start + interpolationRatio * end;
|
||||
};
|
||||
|
||||
@ -1,32 +1,25 @@
|
||||
import type { OldLangFn } from '../hooks/useOldLang';
|
||||
import type { LangFn } from './localization';
|
||||
|
||||
import EMOJI_REGEX from '../lib/twemojiRegex';
|
||||
import fixNonStandardEmoji from './emoji/fixNonStandardEmoji';
|
||||
import { floor } from './math';
|
||||
import withCache from './withCache';
|
||||
|
||||
export function formatInteger(value: number) {
|
||||
return String(value).replace(/\d(?=(\d{3})+$)/g, '$& ');
|
||||
}
|
||||
|
||||
function formatFixedNumber(number: number) {
|
||||
const fixed = String(number.toFixed(1));
|
||||
if (fixed.substr(-2) === '.0') {
|
||||
return Math.floor(number);
|
||||
}
|
||||
|
||||
return number.toFixed(1).replace('.', ',');
|
||||
}
|
||||
|
||||
export function formatIntegerCompact(views: number) {
|
||||
export function formatIntegerCompact(lang: LangFn, views: number) {
|
||||
if (views < 1e3) {
|
||||
return views.toString();
|
||||
return lang.number(views);
|
||||
}
|
||||
|
||||
if (views < 1e6) {
|
||||
return `${formatFixedNumber(views / 1e3)}K`;
|
||||
return `${lang.number(floor(views / 1e3, 1))}K`;
|
||||
}
|
||||
|
||||
return `${formatFixedNumber(views / 1e6)}M`;
|
||||
return `${lang.number(floor(views / 1e6, 1))}M`;
|
||||
}
|
||||
|
||||
export function formatPercent(value: number, fractionDigits = 1) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user