about summary refs log tree commit diff
path: root/src/components/PostControls
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2025-09-04 19:36:23 -0500
committerGitHub <noreply@github.com>2025-09-04 19:36:23 -0500
commitc129108b786a3389181c401b0bdfe1a3de528ebb (patch)
treee075d0c41c8829d9c0b66464ba7cb86dd105be4e /src/components/PostControls
parent0b480bdaf862b0f93ed480589f81433bd6c93126 (diff)
downloadvoidsky-c129108b786a3389181c401b0bdfe1a3de528ebb.tar.zst
108 fixes (#8977)
* Translation comment

* Fix error handling in starter pack generation

* Allow access to DM settings for age restricted users

* Leave post stat unit formatting up to translators
Diffstat (limited to 'src/components/PostControls')
-rw-r--r--src/components/PostControls/RepostButton.tsx9
-rw-r--r--src/components/PostControls/index.tsx11
-rw-r--r--src/components/PostControls/util.ts58
3 files changed, 49 insertions, 29 deletions
diff --git a/src/components/PostControls/RepostButton.tsx b/src/components/PostControls/RepostButton.tsx
index 522e80dd3..d4a3960a7 100644
--- a/src/components/PostControls/RepostButton.tsx
+++ b/src/components/PostControls/RepostButton.tsx
@@ -10,7 +10,7 @@ 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 {useFormatPostStatCount} from '#/components/PostControls/util'
 import {Text} from '#/components/Typography'
 import {
   PostControlButton,
@@ -25,7 +25,6 @@ interface Props {
   onQuote: () => void
   big?: boolean
   embeddingDisabled: boolean
-  compactCount?: boolean
 }
 
 let RepostButton = ({
@@ -35,12 +34,12 @@ let RepostButton = ({
   onQuote,
   big,
   embeddingDisabled,
-  compactCount,
 }: Props): React.ReactNode => {
   const t = useTheme()
-  const {_, i18n} = useLingui()
+  const {_} = useLingui()
   const requireAuth = useRequireAuth()
   const dialogControl = Dialog.useDialogControl()
+  const formatPostStatCount = useFormatPostStatCount()
 
   const onPress = () => requireAuth(() => dialogControl.open())
 
@@ -88,7 +87,7 @@ let RepostButton = ({
         <PostControlButtonIcon icon={Repost} />
         {typeof repostCount !== 'undefined' && repostCount > 0 && (
           <PostControlButtonText testID="repostCount">
-            {formatPostStatCount(i18n, repostCount, {compact: compactCount})}
+            {formatPostStatCount(repostCount)}
           </PostControlButtonText>
         )}
       </PostControlButton>
diff --git a/src/components/PostControls/index.tsx b/src/components/PostControls/index.tsx
index 834ad8e7d..f91bcd8a5 100644
--- a/src/components/PostControls/index.tsx
+++ b/src/components/PostControls/index.tsx
@@ -27,7 +27,7 @@ import {
 import * as Toast from '#/view/com/util/Toast'
 import {atoms as a, flatten, useBreakpoints} from '#/alf'
 import {Reply as Bubble} from '#/components/icons/Reply'
-import {formatPostStatCount} from '#/components/PostControls/util'
+import {useFormatPostStatCount} from '#/components/PostControls/util'
 import {BookmarkButton} from './BookmarkButton'
 import {
   PostControlButton,
@@ -69,7 +69,7 @@ let PostControls = ({
   viaRepost?: {uri: string; cid: string}
   variant?: 'compact' | 'normal' | 'large'
 }): React.ReactNode => {
-  const {_, i18n} = useLingui()
+  const {_} = useLingui()
   const {openComposer} = useOpenComposer()
   const {feedDescriptor} = useFeedFeedbackContext()
   const [queueLike, queueUnlike] = usePostLikeMutationQueue(
@@ -95,6 +95,7 @@ let PostControls = ({
   )
   const replyDisabled = post.viewer?.replyDisabled
   const {gtPhone} = useBreakpoints()
+  const formatPostStatCount = useFormatPostStatCount()
 
   const [hasLikeIconBeenToggled, setHasLikeIconBeenToggled] = useState(false)
 
@@ -232,9 +233,7 @@ let PostControls = ({
             <PostControlButtonIcon icon={Bubble} />
             {typeof post.replyCount !== 'undefined' && post.replyCount > 0 && (
               <PostControlButtonText>
-                {formatPostStatCount(i18n, post.replyCount, {
-                  compact: variant === 'compact',
-                })}
+                {formatPostStatCount(post.replyCount)}
               </PostControlButtonText>
             )}
           </PostControlButton>
@@ -247,7 +246,6 @@ let PostControls = ({
             onQuote={onQuote}
             big={big}
             embeddingDisabled={Boolean(post.viewer?.embeddingDisabled)}
-            compactCount={variant === 'compact'}
           />
         </View>
         <View style={[a.flex_1, a.align_start]}>
@@ -288,7 +286,6 @@ let PostControls = ({
               big={big}
               isLiked={Boolean(post.viewer?.like)}
               hasBeenToggled={hasLikeIconBeenToggled}
-              compactCount={variant === 'compact'}
             />
           </PostControlButton>
         </View>
diff --git a/src/components/PostControls/util.ts b/src/components/PostControls/util.ts
index 5d3ea74e4..b8050a85a 100644
--- a/src/components/PostControls/util.ts
+++ b/src/components/PostControls/util.ts
@@ -1,24 +1,48 @@
-import {type I18n} from '@lingui/core'
+import {useCallback} from 'react'
+import {msg} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
 
 /**
  * This matches `formatCount` from `view/com/util/numeric/format.ts`, but has
  * additional truncation logic for large numbers. `roundingMode` should always
  * match the original impl, regardless of if we add more formatting here.
  */
-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',
-  })
+export function useFormatPostStatCount() {
+  const {i18n} = useLingui()
+
+  return useCallback(
+    (postStatCount: number) => {
+      const isOver1k = postStatCount >= 1_000
+      const isOver10k = postStatCount >= 10_000
+      const isOver1M = postStatCount >= 1_000_000
+      const formatted = i18n.number(postStatCount, {
+        notation: 'compact',
+        maximumFractionDigits: isOver10k ? 0 : 1,
+        // @ts-expect-error - roundingMode not in the types
+        roundingMode: 'trunc',
+      })
+      const count = formatted.replace(/\D+$/g, '')
+
+      if (isOver1M) {
+        return i18n._(
+          msg({
+            message: `${count}M`,
+            comment:
+              'For post statistics. Indicates a number in the millions. Please use the shortest format appropriate for your language.',
+          }),
+        )
+      } else if (isOver1k) {
+        return i18n._(
+          msg({
+            message: `${count}K`,
+            comment:
+              'For post statistics. Indicates a number in the thousands. Please use the shortest format appropriate for your language.',
+          }),
+        )
+      } else {
+        return count
+      }
+    },
+    [i18n],
+  )
 }