diff --git a/src/components/PostControls/RepostButton.tsx b/src/components/PostControls/RepostButton.tsx index cc3f0b7a0a..522e80dd3f 100644 --- a/src/components/PostControls/RepostButton.tsx +++ b/src/components/PostControls/RepostButton.tsx @@ -5,12 +5,12 @@ import {useLingui} from '@lingui/react' import {useHaptics} from '#/lib/haptics' import {useRequireAuth} from '#/state/session' -import {formatCount} from '#/view/com/util/numeric/format' import {atoms as a, useTheme} from '#/alf' import {Button, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import {CloseQuote_Stroke2_Corner1_Rounded as Quote} from '#/components/icons/Quote' import {Repost_Stroke2_Corner3_Rounded as Repost} from '#/components/icons/Repost' +import {formatPostStatCount} from '#/components/PostControls/util' import {Text} from '#/components/Typography' import { PostControlButton, @@ -25,6 +25,7 @@ interface Props { onQuote: () => void big?: boolean embeddingDisabled: boolean + compactCount?: boolean } let RepostButton = ({ @@ -34,6 +35,7 @@ let RepostButton = ({ onQuote, big, embeddingDisabled, + compactCount, }: Props): React.ReactNode => { const t = useTheme() const {_, i18n} = useLingui() @@ -86,7 +88,7 @@ let RepostButton = ({ {typeof repostCount !== 'undefined' && repostCount > 0 && ( - {formatCount(i18n, repostCount)} + {formatPostStatCount(i18n, repostCount, {compact: compactCount})} )} diff --git a/src/components/PostControls/index.tsx b/src/components/PostControls/index.tsx index 0c7ea86c22..49157171bb 100644 --- a/src/components/PostControls/index.tsx +++ b/src/components/PostControls/index.tsx @@ -24,10 +24,10 @@ import { ProgressGuideAction, useProgressGuideControls, } from '#/state/shell/progress-guide' -import {formatCount} from '#/view/com/util/numeric/format' import * as Toast from '#/view/com/util/Toast' import {atoms as a, useBreakpoints} from '#/alf' import {Reply as Bubble} from '#/components/icons/Reply' +import {formatPostStatCount} from '#/components/PostControls/util' import {BookmarkButton} from './BookmarkButton' import { PostControlButton, @@ -52,6 +52,7 @@ let PostControls = ({ threadgateRecord, onShowLess, viaRepost, + variant, }: { big?: boolean post: Shadow @@ -66,6 +67,7 @@ let PostControls = ({ threadgateRecord?: AppBskyFeedThreadgate.Record onShowLess?: (interaction: AppBskyFeedDefs.Interaction) => void viaRepost?: {uri: string; cid: string} + variant?: 'compact' | 'normal' | 'large' }): React.ReactNode => { const {_, i18n} = useLingui() const {openComposer} = useOpenComposer() @@ -224,7 +226,9 @@ let PostControls = ({ {typeof post.replyCount !== 'undefined' && post.replyCount > 0 && ( - {formatCount(i18n, post.replyCount)} + {formatPostStatCount(i18n, post.replyCount, { + compact: variant === 'compact', + })} )} @@ -237,6 +241,7 @@ let PostControls = ({ onQuote={onQuote} big={big} embeddingDisabled={Boolean(post.viewer?.embeddingDisabled)} + compactCount={variant === 'compact'} /> @@ -277,6 +282,7 @@ let PostControls = ({ big={big} isLiked={Boolean(post.viewer?.like)} hasBeenToggled={hasLikeIconBeenToggled} + compactCount={variant === 'compact'} /> diff --git a/src/components/PostControls/util.ts b/src/components/PostControls/util.ts new file mode 100644 index 0000000000..2997817cac --- /dev/null +++ b/src/components/PostControls/util.ts @@ -0,0 +1,19 @@ +import {type I18n} from '@lingui/core' + +export function formatPostStatCount( + i18n: I18n, + count: number, + { + compact = false, + }: { + compact?: boolean + } = {}, +): string { + const isOver10k = count >= 10_000 + return i18n.number(count, { + notation: 'compact', + maximumFractionDigits: isOver10k || compact ? 0 : 1, + // @ts-expect-error - roundingMode not in the types + roundingMode: 'trunc', + }) +} diff --git a/src/lib/custom-animations/CountWheel.tsx b/src/lib/custom-animations/CountWheel.tsx index 4b131db2dc..6db22554e1 100644 --- a/src/lib/custom-animations/CountWheel.tsx +++ b/src/lib/custom-animations/CountWheel.tsx @@ -10,9 +10,9 @@ import {i18n} from '@lingui/core' import {decideShouldRoll} from '#/lib/custom-animations/util' import {s} from '#/lib/styles' -import {formatCount} from '#/view/com/util/numeric/format' import {Text} from '#/view/com/util/text/Text' import {atoms as a, useTheme} from '#/alf' +import {formatPostStatCount} from '#/components/PostControls/util' const animationConfig = { duration: 400, @@ -92,11 +92,13 @@ export function CountWheel({ big, isLiked, hasBeenToggled, + compactCount, }: { likeCount: number big?: boolean isLiked: boolean hasBeenToggled: boolean + compactCount?: boolean }) { const t = useTheme() const shouldAnimate = !useReducedMotion() && hasBeenToggled @@ -109,8 +111,12 @@ export function CountWheel({ const [key, setKey] = React.useState(0) const [prevCount, setPrevCount] = React.useState(likeCount) const prevIsLiked = React.useRef(isLiked) - const formattedCount = formatCount(i18n, likeCount) - const formattedPrevCount = formatCount(i18n, prevCount) + const formattedCount = formatPostStatCount(i18n, likeCount, { + compact: compactCount, + }) + const formattedPrevCount = formatPostStatCount(i18n, prevCount, { + compact: compactCount, + }) React.useEffect(() => { if (isLiked === prevIsLiked.current) { diff --git a/src/screens/PostThread/components/ThreadItemAnchor.tsx b/src/screens/PostThread/components/ThreadItemAnchor.tsx index b59397b0b5..2386e6f339 100644 --- a/src/screens/PostThread/components/ThreadItemAnchor.tsx +++ b/src/screens/PostThread/components/ThreadItemAnchor.tsx @@ -32,7 +32,6 @@ import {useSession} from '#/state/session' import {type OnPostSuccessData} from '#/state/shell/composer' import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies' import {type PostSource} from '#/state/unstable-post-source' -import {formatCount} from '#/view/com/util/numeric/format' import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar' import {ThreadItemAnchorFollowButton} from '#/screens/PostThread/components/ThreadItemAnchorFollowButton' import { @@ -53,6 +52,7 @@ import {PostAlerts} from '#/components/moderation/PostAlerts' import {type AppModerationCause} from '#/components/Pills' import {Embed, PostEmbedViewContext} from '#/components/Post/Embed' import {PostControls} from '#/components/PostControls' +import {formatPostStatCount} from '#/components/PostControls/util' import {ProfileHoverCard} from '#/components/ProfileHoverCard' import * as Prompt from '#/components/Prompt' import {RichText} from '#/components/RichText' @@ -434,7 +434,7 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({ testID="repostCount-expanded" style={[a.text_md, t.atoms.text_contrast_medium]}> - {formatCount(i18n, post.repostCount)} + {formatPostStatCount(i18n, post.repostCount)} {' '} - {formatCount(i18n, post.quoteCount)} + {formatPostStatCount(i18n, post.quoteCount)} {' '} - {formatCount(i18n, post.likeCount)} + {formatPostStatCount(i18n, post.likeCount)} {' '} diff --git a/src/screens/PostThread/components/ThreadItemTreePost.tsx b/src/screens/PostThread/components/ThreadItemTreePost.tsx index b009695a98..5d31233585 100644 --- a/src/screens/PostThread/components/ThreadItemTreePost.tsx +++ b/src/screens/PostThread/components/ThreadItemTreePost.tsx @@ -368,6 +368,7 @@ const ThreadItemTreePostInner = memo(function ThreadItemTreePostInner({ )}