Rm decimals over 10k
This commit is contained in:
@@ -5,12 +5,12 @@ import {useLingui} from '@lingui/react'
|
|||||||
|
|
||||||
import {useHaptics} from '#/lib/haptics'
|
import {useHaptics} from '#/lib/haptics'
|
||||||
import {useRequireAuth} from '#/state/session'
|
import {useRequireAuth} from '#/state/session'
|
||||||
import {formatCount} from '#/view/com/util/numeric/format'
|
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {Button, ButtonText} from '#/components/Button'
|
import {Button, ButtonText} from '#/components/Button'
|
||||||
import * as Dialog from '#/components/Dialog'
|
import * as Dialog from '#/components/Dialog'
|
||||||
import {CloseQuote_Stroke2_Corner1_Rounded as Quote} from '#/components/icons/Quote'
|
import {CloseQuote_Stroke2_Corner1_Rounded as Quote} from '#/components/icons/Quote'
|
||||||
import {Repost_Stroke2_Corner3_Rounded as Repost} from '#/components/icons/Repost'
|
import {Repost_Stroke2_Corner3_Rounded as Repost} from '#/components/icons/Repost'
|
||||||
|
import {formatPostStatCount} from '#/components/PostControls/util'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {
|
import {
|
||||||
PostControlButton,
|
PostControlButton,
|
||||||
@@ -25,6 +25,7 @@ interface Props {
|
|||||||
onQuote: () => void
|
onQuote: () => void
|
||||||
big?: boolean
|
big?: boolean
|
||||||
embeddingDisabled: boolean
|
embeddingDisabled: boolean
|
||||||
|
compactCount?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
let RepostButton = ({
|
let RepostButton = ({
|
||||||
@@ -34,6 +35,7 @@ let RepostButton = ({
|
|||||||
onQuote,
|
onQuote,
|
||||||
big,
|
big,
|
||||||
embeddingDisabled,
|
embeddingDisabled,
|
||||||
|
compactCount,
|
||||||
}: Props): React.ReactNode => {
|
}: Props): React.ReactNode => {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {_, i18n} = useLingui()
|
const {_, i18n} = useLingui()
|
||||||
@@ -86,7 +88,7 @@ let RepostButton = ({
|
|||||||
<PostControlButtonIcon icon={Repost} />
|
<PostControlButtonIcon icon={Repost} />
|
||||||
{typeof repostCount !== 'undefined' && repostCount > 0 && (
|
{typeof repostCount !== 'undefined' && repostCount > 0 && (
|
||||||
<PostControlButtonText testID="repostCount">
|
<PostControlButtonText testID="repostCount">
|
||||||
{formatCount(i18n, repostCount)}
|
{formatPostStatCount(i18n, repostCount, {compact: compactCount})}
|
||||||
</PostControlButtonText>
|
</PostControlButtonText>
|
||||||
)}
|
)}
|
||||||
</PostControlButton>
|
</PostControlButton>
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ import {
|
|||||||
ProgressGuideAction,
|
ProgressGuideAction,
|
||||||
useProgressGuideControls,
|
useProgressGuideControls,
|
||||||
} from '#/state/shell/progress-guide'
|
} from '#/state/shell/progress-guide'
|
||||||
import {formatCount} from '#/view/com/util/numeric/format'
|
|
||||||
import * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {atoms as a, useBreakpoints} from '#/alf'
|
import {atoms as a, useBreakpoints} from '#/alf'
|
||||||
import {Reply as Bubble} from '#/components/icons/Reply'
|
import {Reply as Bubble} from '#/components/icons/Reply'
|
||||||
|
import {formatPostStatCount} from '#/components/PostControls/util'
|
||||||
import {BookmarkButton} from './BookmarkButton'
|
import {BookmarkButton} from './BookmarkButton'
|
||||||
import {
|
import {
|
||||||
PostControlButton,
|
PostControlButton,
|
||||||
@@ -52,6 +52,7 @@ let PostControls = ({
|
|||||||
threadgateRecord,
|
threadgateRecord,
|
||||||
onShowLess,
|
onShowLess,
|
||||||
viaRepost,
|
viaRepost,
|
||||||
|
variant,
|
||||||
}: {
|
}: {
|
||||||
big?: boolean
|
big?: boolean
|
||||||
post: Shadow<AppBskyFeedDefs.PostView>
|
post: Shadow<AppBskyFeedDefs.PostView>
|
||||||
@@ -66,6 +67,7 @@ let PostControls = ({
|
|||||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
threadgateRecord?: AppBskyFeedThreadgate.Record
|
||||||
onShowLess?: (interaction: AppBskyFeedDefs.Interaction) => void
|
onShowLess?: (interaction: AppBskyFeedDefs.Interaction) => void
|
||||||
viaRepost?: {uri: string; cid: string}
|
viaRepost?: {uri: string; cid: string}
|
||||||
|
variant?: 'compact' | 'normal' | 'large'
|
||||||
}): React.ReactNode => {
|
}): React.ReactNode => {
|
||||||
const {_, i18n} = useLingui()
|
const {_, i18n} = useLingui()
|
||||||
const {openComposer} = useOpenComposer()
|
const {openComposer} = useOpenComposer()
|
||||||
@@ -224,7 +226,9 @@ let PostControls = ({
|
|||||||
<PostControlButtonIcon icon={Bubble} />
|
<PostControlButtonIcon icon={Bubble} />
|
||||||
{typeof post.replyCount !== 'undefined' && post.replyCount > 0 && (
|
{typeof post.replyCount !== 'undefined' && post.replyCount > 0 && (
|
||||||
<PostControlButtonText>
|
<PostControlButtonText>
|
||||||
{formatCount(i18n, post.replyCount)}
|
{formatPostStatCount(i18n, post.replyCount, {
|
||||||
|
compact: variant === 'compact',
|
||||||
|
})}
|
||||||
</PostControlButtonText>
|
</PostControlButtonText>
|
||||||
)}
|
)}
|
||||||
</PostControlButton>
|
</PostControlButton>
|
||||||
@@ -237,6 +241,7 @@ let PostControls = ({
|
|||||||
onQuote={onQuote}
|
onQuote={onQuote}
|
||||||
big={big}
|
big={big}
|
||||||
embeddingDisabled={Boolean(post.viewer?.embeddingDisabled)}
|
embeddingDisabled={Boolean(post.viewer?.embeddingDisabled)}
|
||||||
|
compactCount={variant === 'compact'}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View style={[a.flex_1, a.align_start]}>
|
<View style={[a.flex_1, a.align_start]}>
|
||||||
@@ -277,6 +282,7 @@ let PostControls = ({
|
|||||||
big={big}
|
big={big}
|
||||||
isLiked={Boolean(post.viewer?.like)}
|
isLiked={Boolean(post.viewer?.like)}
|
||||||
hasBeenToggled={hasLikeIconBeenToggled}
|
hasBeenToggled={hasLikeIconBeenToggled}
|
||||||
|
compactCount={variant === 'compact'}
|
||||||
/>
|
/>
|
||||||
</PostControlButton>
|
</PostControlButton>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -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',
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -10,9 +10,9 @@ import {i18n} from '@lingui/core'
|
|||||||
|
|
||||||
import {decideShouldRoll} from '#/lib/custom-animations/util'
|
import {decideShouldRoll} from '#/lib/custom-animations/util'
|
||||||
import {s} from '#/lib/styles'
|
import {s} from '#/lib/styles'
|
||||||
import {formatCount} from '#/view/com/util/numeric/format'
|
|
||||||
import {Text} from '#/view/com/util/text/Text'
|
import {Text} from '#/view/com/util/text/Text'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
|
import {formatPostStatCount} from '#/components/PostControls/util'
|
||||||
|
|
||||||
const animationConfig = {
|
const animationConfig = {
|
||||||
duration: 400,
|
duration: 400,
|
||||||
@@ -92,11 +92,13 @@ export function CountWheel({
|
|||||||
big,
|
big,
|
||||||
isLiked,
|
isLiked,
|
||||||
hasBeenToggled,
|
hasBeenToggled,
|
||||||
|
compactCount,
|
||||||
}: {
|
}: {
|
||||||
likeCount: number
|
likeCount: number
|
||||||
big?: boolean
|
big?: boolean
|
||||||
isLiked: boolean
|
isLiked: boolean
|
||||||
hasBeenToggled: boolean
|
hasBeenToggled: boolean
|
||||||
|
compactCount?: boolean
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const shouldAnimate = !useReducedMotion() && hasBeenToggled
|
const shouldAnimate = !useReducedMotion() && hasBeenToggled
|
||||||
@@ -109,8 +111,12 @@ export function CountWheel({
|
|||||||
const [key, setKey] = React.useState(0)
|
const [key, setKey] = React.useState(0)
|
||||||
const [prevCount, setPrevCount] = React.useState(likeCount)
|
const [prevCount, setPrevCount] = React.useState(likeCount)
|
||||||
const prevIsLiked = React.useRef(isLiked)
|
const prevIsLiked = React.useRef(isLiked)
|
||||||
const formattedCount = formatCount(i18n, likeCount)
|
const formattedCount = formatPostStatCount(i18n, likeCount, {
|
||||||
const formattedPrevCount = formatCount(i18n, prevCount)
|
compact: compactCount,
|
||||||
|
})
|
||||||
|
const formattedPrevCount = formatPostStatCount(i18n, prevCount, {
|
||||||
|
compact: compactCount,
|
||||||
|
})
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isLiked === prevIsLiked.current) {
|
if (isLiked === prevIsLiked.current) {
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import {useSession} from '#/state/session'
|
|||||||
import {type OnPostSuccessData} from '#/state/shell/composer'
|
import {type OnPostSuccessData} from '#/state/shell/composer'
|
||||||
import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
|
import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
|
||||||
import {type PostSource} from '#/state/unstable-post-source'
|
import {type PostSource} from '#/state/unstable-post-source'
|
||||||
import {formatCount} from '#/view/com/util/numeric/format'
|
|
||||||
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
|
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import {ThreadItemAnchorFollowButton} from '#/screens/PostThread/components/ThreadItemAnchorFollowButton'
|
import {ThreadItemAnchorFollowButton} from '#/screens/PostThread/components/ThreadItemAnchorFollowButton'
|
||||||
import {
|
import {
|
||||||
@@ -53,6 +52,7 @@ import {PostAlerts} from '#/components/moderation/PostAlerts'
|
|||||||
import {type AppModerationCause} from '#/components/Pills'
|
import {type AppModerationCause} from '#/components/Pills'
|
||||||
import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
|
import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
|
||||||
import {PostControls} from '#/components/PostControls'
|
import {PostControls} from '#/components/PostControls'
|
||||||
|
import {formatPostStatCount} from '#/components/PostControls/util'
|
||||||
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
|
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
|
||||||
import * as Prompt from '#/components/Prompt'
|
import * as Prompt from '#/components/Prompt'
|
||||||
import {RichText} from '#/components/RichText'
|
import {RichText} from '#/components/RichText'
|
||||||
@@ -434,7 +434,7 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
|
|||||||
testID="repostCount-expanded"
|
testID="repostCount-expanded"
|
||||||
style={[a.text_md, t.atoms.text_contrast_medium]}>
|
style={[a.text_md, t.atoms.text_contrast_medium]}>
|
||||||
<Text style={[a.text_md, a.font_bold, t.atoms.text]}>
|
<Text style={[a.text_md, a.font_bold, t.atoms.text]}>
|
||||||
{formatCount(i18n, post.repostCount)}
|
{formatPostStatCount(i18n, post.repostCount)}
|
||||||
</Text>{' '}
|
</Text>{' '}
|
||||||
<Plural
|
<Plural
|
||||||
value={post.repostCount}
|
value={post.repostCount}
|
||||||
@@ -452,7 +452,7 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
|
|||||||
testID="quoteCount-expanded"
|
testID="quoteCount-expanded"
|
||||||
style={[a.text_md, t.atoms.text_contrast_medium]}>
|
style={[a.text_md, t.atoms.text_contrast_medium]}>
|
||||||
<Text style={[a.text_md, a.font_bold, t.atoms.text]}>
|
<Text style={[a.text_md, a.font_bold, t.atoms.text]}>
|
||||||
{formatCount(i18n, post.quoteCount)}
|
{formatPostStatCount(i18n, post.quoteCount)}
|
||||||
</Text>{' '}
|
</Text>{' '}
|
||||||
<Plural
|
<Plural
|
||||||
value={post.quoteCount}
|
value={post.quoteCount}
|
||||||
@@ -468,7 +468,7 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
|
|||||||
testID="likeCount-expanded"
|
testID="likeCount-expanded"
|
||||||
style={[a.text_md, t.atoms.text_contrast_medium]}>
|
style={[a.text_md, t.atoms.text_contrast_medium]}>
|
||||||
<Text style={[a.text_md, a.font_bold, t.atoms.text]}>
|
<Text style={[a.text_md, a.font_bold, t.atoms.text]}>
|
||||||
{formatCount(i18n, post.likeCount)}
|
{formatPostStatCount(i18n, post.likeCount)}
|
||||||
</Text>{' '}
|
</Text>{' '}
|
||||||
<Plural value={post.likeCount} one="like" other="likes" />
|
<Plural value={post.likeCount} one="like" other="likes" />
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -368,6 +368,7 @@ const ThreadItemTreePostInner = memo(function ThreadItemTreePostInner({
|
|||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
<PostControls
|
<PostControls
|
||||||
|
variant="compact"
|
||||||
post={postShadow}
|
post={postShadow}
|
||||||
record={record}
|
record={record}
|
||||||
richText={richText}
|
richText={richText}
|
||||||
|
|||||||
Reference in New Issue
Block a user