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
This commit is contained in:
@@ -10,7 +10,7 @@ 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 {useFormatPostStatCount} from '#/components/PostControls/util'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {
|
import {
|
||||||
PostControlButton,
|
PostControlButton,
|
||||||
@@ -25,7 +25,6 @@ interface Props {
|
|||||||
onQuote: () => void
|
onQuote: () => void
|
||||||
big?: boolean
|
big?: boolean
|
||||||
embeddingDisabled: boolean
|
embeddingDisabled: boolean
|
||||||
compactCount?: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let RepostButton = ({
|
let RepostButton = ({
|
||||||
@@ -35,12 +34,12 @@ 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 {_} = useLingui()
|
||||||
const requireAuth = useRequireAuth()
|
const requireAuth = useRequireAuth()
|
||||||
const dialogControl = Dialog.useDialogControl()
|
const dialogControl = Dialog.useDialogControl()
|
||||||
|
const formatPostStatCount = useFormatPostStatCount()
|
||||||
|
|
||||||
const onPress = () => requireAuth(() => dialogControl.open())
|
const onPress = () => requireAuth(() => dialogControl.open())
|
||||||
|
|
||||||
@@ -88,7 +87,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">
|
||||||
{formatPostStatCount(i18n, repostCount, {compact: compactCount})}
|
{formatPostStatCount(repostCount)}
|
||||||
</PostControlButtonText>
|
</PostControlButtonText>
|
||||||
)}
|
)}
|
||||||
</PostControlButton>
|
</PostControlButton>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import {
|
|||||||
import * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {atoms as a, flatten, useBreakpoints} from '#/alf'
|
import {atoms as a, flatten, 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 {useFormatPostStatCount} from '#/components/PostControls/util'
|
||||||
import {BookmarkButton} from './BookmarkButton'
|
import {BookmarkButton} from './BookmarkButton'
|
||||||
import {
|
import {
|
||||||
PostControlButton,
|
PostControlButton,
|
||||||
@@ -69,7 +69,7 @@ let PostControls = ({
|
|||||||
viaRepost?: {uri: string; cid: string}
|
viaRepost?: {uri: string; cid: string}
|
||||||
variant?: 'compact' | 'normal' | 'large'
|
variant?: 'compact' | 'normal' | 'large'
|
||||||
}): React.ReactNode => {
|
}): React.ReactNode => {
|
||||||
const {_, i18n} = useLingui()
|
const {_} = useLingui()
|
||||||
const {openComposer} = useOpenComposer()
|
const {openComposer} = useOpenComposer()
|
||||||
const {feedDescriptor} = useFeedFeedbackContext()
|
const {feedDescriptor} = useFeedFeedbackContext()
|
||||||
const [queueLike, queueUnlike] = usePostLikeMutationQueue(
|
const [queueLike, queueUnlike] = usePostLikeMutationQueue(
|
||||||
@@ -95,6 +95,7 @@ let PostControls = ({
|
|||||||
)
|
)
|
||||||
const replyDisabled = post.viewer?.replyDisabled
|
const replyDisabled = post.viewer?.replyDisabled
|
||||||
const {gtPhone} = useBreakpoints()
|
const {gtPhone} = useBreakpoints()
|
||||||
|
const formatPostStatCount = useFormatPostStatCount()
|
||||||
|
|
||||||
const [hasLikeIconBeenToggled, setHasLikeIconBeenToggled] = useState(false)
|
const [hasLikeIconBeenToggled, setHasLikeIconBeenToggled] = useState(false)
|
||||||
|
|
||||||
@@ -232,9 +233,7 @@ let PostControls = ({
|
|||||||
<PostControlButtonIcon icon={Bubble} />
|
<PostControlButtonIcon icon={Bubble} />
|
||||||
{typeof post.replyCount !== 'undefined' && post.replyCount > 0 && (
|
{typeof post.replyCount !== 'undefined' && post.replyCount > 0 && (
|
||||||
<PostControlButtonText>
|
<PostControlButtonText>
|
||||||
{formatPostStatCount(i18n, post.replyCount, {
|
{formatPostStatCount(post.replyCount)}
|
||||||
compact: variant === 'compact',
|
|
||||||
})}
|
|
||||||
</PostControlButtonText>
|
</PostControlButtonText>
|
||||||
)}
|
)}
|
||||||
</PostControlButton>
|
</PostControlButton>
|
||||||
@@ -247,7 +246,6 @@ 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]}>
|
||||||
@@ -288,7 +286,6 @@ 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>
|
||||||
|
|||||||
@@ -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
|
* This matches `formatCount` from `view/com/util/numeric/format.ts`, but has
|
||||||
* additional truncation logic for large numbers. `roundingMode` should always
|
* additional truncation logic for large numbers. `roundingMode` should always
|
||||||
* match the original impl, regardless of if we add more formatting here.
|
* match the original impl, regardless of if we add more formatting here.
|
||||||
*/
|
*/
|
||||||
export function formatPostStatCount(
|
export function useFormatPostStatCount() {
|
||||||
i18n: I18n,
|
const {i18n} = useLingui()
|
||||||
count: number,
|
|
||||||
{
|
return useCallback(
|
||||||
compact = false,
|
(postStatCount: number) => {
|
||||||
}: {
|
const isOver1k = postStatCount >= 1_000
|
||||||
compact?: boolean
|
const isOver10k = postStatCount >= 10_000
|
||||||
} = {},
|
const isOver1M = postStatCount >= 1_000_000
|
||||||
): string {
|
const formatted = i18n.number(postStatCount, {
|
||||||
const isOver10k = count >= 10_000
|
notation: 'compact',
|
||||||
return i18n.number(count, {
|
maximumFractionDigits: isOver10k ? 0 : 1,
|
||||||
notation: 'compact',
|
// @ts-expect-error - roundingMode not in the types
|
||||||
maximumFractionDigits: isOver10k || compact ? 0 : 1,
|
roundingMode: 'trunc',
|
||||||
// @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],
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ function Empty() {
|
|||||||
onError: e => {
|
onError: e => {
|
||||||
logger.error('Failed to generate starter pack', {safeMessage: e})
|
logger.error('Failed to generate starter pack', {safeMessage: e})
|
||||||
setIsGenerating(false)
|
setIsGenerating(false)
|
||||||
if (e.name === 'NOT_ENOUGH_FOLLOWERS') {
|
if (e.message.includes('NOT_ENOUGH_FOLLOWERS')) {
|
||||||
followersDialogControl.open()
|
followersDialogControl.open()
|
||||||
} else {
|
} else {
|
||||||
errorDialogControl.open()
|
errorDialogControl.open()
|
||||||
|
|||||||
@@ -18,10 +18,12 @@ export function AgeRestrictedScreen({
|
|||||||
children,
|
children,
|
||||||
screenTitle,
|
screenTitle,
|
||||||
infoText,
|
infoText,
|
||||||
|
rightHeaderSlot,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
screenTitle?: string
|
screenTitle?: string
|
||||||
infoText?: string
|
infoText?: string
|
||||||
|
rightHeaderSlot?: React.ReactNode
|
||||||
}) {
|
}) {
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const copy = useAgeAssuranceCopy()
|
const copy = useAgeAssuranceCopy()
|
||||||
@@ -46,12 +48,12 @@ export function AgeRestrictedScreen({
|
|||||||
<Layout.Screen>
|
<Layout.Screen>
|
||||||
<Layout.Header.Outer>
|
<Layout.Header.Outer>
|
||||||
<Layout.Header.BackButton />
|
<Layout.Header.BackButton />
|
||||||
<Layout.Header.Content>
|
<Layout.Header.Content align="left">
|
||||||
<Layout.Header.TitleText>
|
<Layout.Header.TitleText>
|
||||||
{screenTitle ?? <Trans>Unavailable</Trans>}
|
{screenTitle ?? <Trans>Unavailable</Trans>}
|
||||||
</Layout.Header.TitleText>
|
</Layout.Header.TitleText>
|
||||||
</Layout.Header.Content>
|
</Layout.Header.Content>
|
||||||
<Layout.Header.Slot />
|
{rightHeaderSlot ?? <Layout.Header.Slot />}
|
||||||
</Layout.Header.Outer>
|
</Layout.Header.Outer>
|
||||||
<Layout.Content>
|
<Layout.Content>
|
||||||
<View style={[a.p_lg]}>
|
<View style={[a.p_lg]}>
|
||||||
|
|||||||
@@ -117,7 +117,11 @@ export function BookmarksAnnouncement() {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
alt={_(
|
alt={_(
|
||||||
msg`A screenshot of a post with a new button next to the share button that allows you to save the post to your bookmarks. The post is from @jcsalterego.bsky.social and reads "inventing a saturday that immediately follows monday".`,
|
msg({
|
||||||
|
message: `A screenshot of a post with a new button next to the share button that allows you to save the post to your bookmarks. The post is from @jcsalterego.bsky.social and reads "inventing a saturday that immediately follows monday".`,
|
||||||
|
comment:
|
||||||
|
'Contains a post that originally appeared in English. Consider translating the post text if it makes sense in your language, and noting that the post was translated from English.',
|
||||||
|
}),
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -6,13 +6,12 @@ import Animated, {
|
|||||||
useReducedMotion,
|
useReducedMotion,
|
||||||
withTiming,
|
withTiming,
|
||||||
} from 'react-native-reanimated'
|
} from 'react-native-reanimated'
|
||||||
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 {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'
|
import {useFormatPostStatCount} from '#/components/PostControls/util'
|
||||||
|
|
||||||
const animationConfig = {
|
const animationConfig = {
|
||||||
duration: 400,
|
duration: 400,
|
||||||
@@ -92,13 +91,11 @@ 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
|
||||||
@@ -111,12 +108,9 @@ 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 = formatPostStatCount(i18n, likeCount, {
|
const formatPostStatCount = useFormatPostStatCount()
|
||||||
compact: compactCount,
|
const formattedCount = formatPostStatCount(likeCount)
|
||||||
})
|
const formattedPrevCount = formatPostStatCount(prevCount)
|
||||||
const formattedPrevCount = formatPostStatCount(i18n, prevCount, {
|
|
||||||
compact: compactCount,
|
|
||||||
})
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isLiked === prevIsLiked.current) {
|
if (isLiked === prevIsLiked.current) {
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {useReducedMotion} from 'react-native-reanimated'
|
import {useReducedMotion} from 'react-native-reanimated'
|
||||||
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 {useFormatPostStatCount} from '#/components/PostControls/util'
|
||||||
|
|
||||||
const animationConfig = {
|
const animationConfig = {
|
||||||
duration: 400,
|
duration: 400,
|
||||||
@@ -55,8 +54,9 @@ export function CountWheel({
|
|||||||
|
|
||||||
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 formatPostStatCount = useFormatPostStatCount()
|
||||||
const formattedPrevCount = formatCount(i18n, prevCount)
|
const formattedCount = formatPostStatCount(likeCount)
|
||||||
|
const formattedPrevCount = formatPostStatCount(prevCount)
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isLiked === prevIsLiked.current) {
|
if (isLiked === prevIsLiked.current) {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {isNative} from '#/platform/detection'
|
|||||||
import {useAgeAssuranceContext} from '#/state/ageAssurance'
|
import {useAgeAssuranceContext} from '#/state/ageAssurance'
|
||||||
import {type SessionAccount, useAgent, useSession} from '#/state/session'
|
import {type SessionAccount, useAgent, useSession} from '#/state/session'
|
||||||
import BackgroundNotificationHandler from '#/../modules/expo-background-notification-handler'
|
import BackgroundNotificationHandler from '#/../modules/expo-background-notification-handler'
|
||||||
|
import {IS_DEV} from '#/env'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@@ -129,7 +130,7 @@ export function useGetAndRegisterPushToken() {
|
|||||||
}: {
|
}: {
|
||||||
isAgeRestricted?: boolean
|
isAgeRestricted?: boolean
|
||||||
} = {}) => {
|
} = {}) => {
|
||||||
if (!isNative) return
|
if (!isNative || IS_DEV) return
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This will also fire the listener added via `addPushTokenListener`. That
|
* This will also fire the listener added via `addPushTokenListener`. That
|
||||||
|
|||||||
@@ -74,7 +74,18 @@ export function MessagesScreen(props: Props) {
|
|||||||
return (
|
return (
|
||||||
<AgeRestrictedScreen
|
<AgeRestrictedScreen
|
||||||
screenTitle={_(msg`Chats`)}
|
screenTitle={_(msg`Chats`)}
|
||||||
infoText={aaCopy.chatsInfoText}>
|
infoText={aaCopy.chatsInfoText}
|
||||||
|
rightHeaderSlot={
|
||||||
|
<Link
|
||||||
|
to="/messages/settings"
|
||||||
|
label={_(msg`Chat settings`)}
|
||||||
|
size="small"
|
||||||
|
color="secondary">
|
||||||
|
<ButtonText>
|
||||||
|
<Trans>Chat settings</Trans>
|
||||||
|
</ButtonText>
|
||||||
|
</Link>
|
||||||
|
}>
|
||||||
<MessagesScreenInner {...props} />
|
<MessagesScreenInner {...props} />
|
||||||
</AgeRestrictedScreen>
|
</AgeRestrictedScreen>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ import {useSession} from '#/state/session'
|
|||||||
import * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {atoms as a} from '#/alf'
|
import {atoms as a} from '#/alf'
|
||||||
import {Admonition} from '#/components/Admonition'
|
import {Admonition} from '#/components/Admonition'
|
||||||
import {AgeRestrictedScreen} from '#/components/ageAssurance/AgeRestrictedScreen'
|
|
||||||
import {useAgeAssuranceCopy} from '#/components/ageAssurance/useAgeAssuranceCopy'
|
|
||||||
import {Divider} from '#/components/Divider'
|
import {Divider} from '#/components/Divider'
|
||||||
import * as Toggle from '#/components/forms/Toggle'
|
import * as Toggle from '#/components/forms/Toggle'
|
||||||
import * as Layout from '#/components/Layout'
|
import * as Layout from '#/components/Layout'
|
||||||
@@ -25,16 +23,7 @@ type AllowIncoming = 'all' | 'none' | 'following'
|
|||||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'MessagesSettings'>
|
type Props = NativeStackScreenProps<CommonNavigatorParams, 'MessagesSettings'>
|
||||||
|
|
||||||
export function MessagesSettingsScreen(props: Props) {
|
export function MessagesSettingsScreen(props: Props) {
|
||||||
const {_} = useLingui()
|
return <MessagesSettingsScreenInner {...props} />
|
||||||
const aaCopy = useAgeAssuranceCopy()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AgeRestrictedScreen
|
|
||||||
screenTitle={_(msg`Chat Settings`)}
|
|
||||||
infoText={aaCopy.chatsInfoText}>
|
|
||||||
<MessagesSettingsScreenInner {...props} />
|
|
||||||
</AgeRestrictedScreen>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function MessagesSettingsScreenInner({}: Props) {
|
export function MessagesSettingsScreenInner({}: Props) {
|
||||||
|
|||||||
@@ -52,7 +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 {useFormatPostStatCount} 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'
|
||||||
@@ -176,11 +176,12 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
|
|||||||
postSource?: PostSource
|
postSource?: PostSource
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {_, i18n} = useLingui()
|
const {_} = useLingui()
|
||||||
const {openComposer} = useOpenComposer()
|
const {openComposer} = useOpenComposer()
|
||||||
const {currentAccount, hasSession} = useSession()
|
const {currentAccount, hasSession} = useSession()
|
||||||
const {gtTablet} = useBreakpoints()
|
const {gtTablet} = useBreakpoints()
|
||||||
const feedFeedback = useFeedFeedback(postSource?.feedSourceInfo, hasSession)
|
const feedFeedback = useFeedFeedback(postSource?.feedSourceInfo, hasSession)
|
||||||
|
const formatPostStatCount = useFormatPostStatCount()
|
||||||
|
|
||||||
const post = postShadow
|
const post = postShadow
|
||||||
const record = item.value.post.record
|
const record = item.value.post.record
|
||||||
@@ -439,7 +440,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]}>
|
||||||
{formatPostStatCount(i18n, post.repostCount)}
|
{formatPostStatCount(post.repostCount)}
|
||||||
</Text>{' '}
|
</Text>{' '}
|
||||||
<Plural
|
<Plural
|
||||||
value={post.repostCount}
|
value={post.repostCount}
|
||||||
@@ -457,7 +458,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]}>
|
||||||
{formatPostStatCount(i18n, post.quoteCount)}
|
{formatPostStatCount(post.quoteCount)}
|
||||||
</Text>{' '}
|
</Text>{' '}
|
||||||
<Plural
|
<Plural
|
||||||
value={post.quoteCount}
|
value={post.quoteCount}
|
||||||
@@ -473,7 +474,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]}>
|
||||||
{formatPostStatCount(i18n, post.likeCount)}
|
{formatPostStatCount(post.likeCount)}
|
||||||
</Text>{' '}
|
</Text>{' '}
|
||||||
<Plural value={post.likeCount} one="like" other="likes" />
|
<Plural value={post.likeCount} one="like" other="likes" />
|
||||||
</Text>
|
</Text>
|
||||||
@@ -485,7 +486,7 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
|
|||||||
testID="bookmarkCount-expanded"
|
testID="bookmarkCount-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]}>
|
||||||
{formatPostStatCount(i18n, post.bookmarkCount)}
|
{formatPostStatCount(post.bookmarkCount)}
|
||||||
</Text>{' '}
|
</Text>{' '}
|
||||||
<Plural
|
<Plural
|
||||||
value={post.bookmarkCount}
|
value={post.bookmarkCount}
|
||||||
|
|||||||
Reference in New Issue
Block a user