refactor: consistent localized formatting
This commit is contained in:
@@ -67,7 +67,7 @@ let FeedItem = ({
|
||||
}): React.ReactNode => {
|
||||
const queryClient = useQueryClient()
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const {_, i18n} = useLingui()
|
||||
const [isAuthorsExpanded, setAuthorsExpanded] = useState<boolean>(false)
|
||||
const itemHref = useMemo(() => {
|
||||
if (item.type === 'post-like' || item.type === 'repost') {
|
||||
@@ -175,7 +175,8 @@ let FeedItem = ({
|
||||
return null
|
||||
}
|
||||
|
||||
let formattedCount = authors.length > 1 ? formatCount(authors.length - 1) : ''
|
||||
let formattedCount =
|
||||
authors.length > 1 ? formatCount(i18n, authors.length - 1) : ''
|
||||
return (
|
||||
<Link
|
||||
testID={`feedItem-by-${item.notification.author.handle}`}
|
||||
|
||||
@@ -165,7 +165,7 @@ let PostThreadItemLoaded = ({
|
||||
onPostReply: () => void
|
||||
}): React.ReactNode => {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const {_, i18n} = useLingui()
|
||||
const langPrefs = useLanguagePrefs()
|
||||
const {openComposer} = useComposerControls()
|
||||
const [limitLines, setLimitLines] = React.useState(
|
||||
@@ -339,7 +339,7 @@ let PostThreadItemLoaded = ({
|
||||
type="lg"
|
||||
style={pal.textLight}>
|
||||
<Text type="xl-bold" style={pal.text}>
|
||||
{formatCount(post.repostCount)}
|
||||
{formatCount(i18n, post.repostCount)}
|
||||
</Text>{' '}
|
||||
<Plural
|
||||
value={post.repostCount}
|
||||
@@ -359,7 +359,7 @@ let PostThreadItemLoaded = ({
|
||||
type="lg"
|
||||
style={pal.textLight}>
|
||||
<Text type="xl-bold" style={pal.text}>
|
||||
{formatCount(post.likeCount)}
|
||||
{formatCount(i18n, post.likeCount)}
|
||||
</Text>{' '}
|
||||
<Plural value={post.likeCount} one="like" other="likes" />
|
||||
</Text>
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
import React, {useState, useCallback} from 'react'
|
||||
import React, {useCallback, useState} from 'react'
|
||||
import {StyleProp, StyleSheet, TextStyle, View, ViewStyle} from 'react-native'
|
||||
import DatePicker from 'react-native-date-picker'
|
||||
import {
|
||||
FontAwesomeIcon,
|
||||
FontAwesomeIconStyle,
|
||||
} from '@fortawesome/react-native-fontawesome'
|
||||
import {isIOS, isAndroid} from 'platform/detection'
|
||||
import {Button, ButtonType} from './Button'
|
||||
import {Text} from '../text/Text'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {TypographyVariant} from 'lib/ThemeContext'
|
||||
import {useTheme} from 'lib/ThemeContext'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {getLocales} from 'expo-localization'
|
||||
import DatePicker from 'react-native-date-picker'
|
||||
|
||||
const LOCALE = getLocales()[0]
|
||||
import {isAndroid, isIOS} from 'platform/detection'
|
||||
import {Text} from '../text/Text'
|
||||
import {Button, ButtonType} from './Button'
|
||||
|
||||
interface Props {
|
||||
testID?: string
|
||||
@@ -30,16 +29,11 @@ interface Props {
|
||||
}
|
||||
|
||||
export function DateInput(props: Props) {
|
||||
const {i18n} = useLingui()
|
||||
const [show, setShow] = useState(false)
|
||||
const theme = useTheme()
|
||||
const pal = usePalette('default')
|
||||
|
||||
const formatter = React.useMemo(() => {
|
||||
return new Intl.DateTimeFormat(LOCALE.languageTag, {
|
||||
timeZone: props.handleAsUTC ? 'UTC' : undefined,
|
||||
})
|
||||
}, [props.handleAsUTC])
|
||||
|
||||
const onChangeInternal = useCallback(
|
||||
(date: Date) => {
|
||||
setShow(false)
|
||||
@@ -74,7 +68,9 @@ export function DateInput(props: Props) {
|
||||
<Text
|
||||
type={props.buttonLabelType}
|
||||
style={[pal.text, props.buttonLabelStyle]}>
|
||||
{formatter.format(props.value)}
|
||||
{i18n.date(props.value, {
|
||||
timeZone: props.handleAsUTC ? 'UTC' : undefined,
|
||||
})}
|
||||
</Text>
|
||||
</View>
|
||||
</Button>
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
export const formatCount = (num: number) =>
|
||||
Intl.NumberFormat('en-US', {
|
||||
import type {I18n} from '@lingui/core'
|
||||
|
||||
export const formatCount = (i18n: I18n, num: number) => {
|
||||
return i18n.number(num, {
|
||||
notation: 'compact',
|
||||
maximumFractionDigits: 1,
|
||||
// `1,953` shouldn't be rounded up to 2k, it should be truncated.
|
||||
// @ts-expect-error: `roundingMode` doesn't seem to be in the typings yet
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#roundingmode
|
||||
roundingMode: 'trunc',
|
||||
}).format(num)
|
||||
|
||||
export function formatCountShortOnly(num: number): string {
|
||||
if (num >= 1000000) {
|
||||
return (num / 1000000).toFixed(1) + 'M'
|
||||
}
|
||||
if (num >= 1000) {
|
||||
return (num / 1000).toFixed(1) + 'K'
|
||||
}
|
||||
return String(num)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {CommonNavigatorParams} from '#/lib/routes/types'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {useLanguagePrefs} from '#/state/preferences'
|
||||
import {
|
||||
useAppPasswordDeleteMutation,
|
||||
useAppPasswordsQuery,
|
||||
@@ -218,9 +217,8 @@ function AppPassword({
|
||||
privileged?: boolean
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const {_, i18n} = useLingui()
|
||||
const control = useDialogControl()
|
||||
const {contentLanguages} = useLanguagePrefs()
|
||||
const deleteMutation = useAppPasswordDeleteMutation()
|
||||
|
||||
const onDelete = React.useCallback(async () => {
|
||||
@@ -232,9 +230,6 @@ function AppPassword({
|
||||
control.open()
|
||||
}, [control])
|
||||
|
||||
const primaryLocale =
|
||||
contentLanguages.length > 0 ? contentLanguages[0] : 'en-US'
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
testID={testID}
|
||||
@@ -250,14 +245,14 @@ function AppPassword({
|
||||
<Text type="md" style={[pal.text, styles.pr10]} numberOfLines={1}>
|
||||
<Trans>
|
||||
Created{' '}
|
||||
{Intl.DateTimeFormat(primaryLocale, {
|
||||
{i18n.date(createdAt, {
|
||||
year: 'numeric',
|
||||
month: 'numeric',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
}).format(new Date(createdAt))}
|
||||
})}
|
||||
</Trans>
|
||||
</Text>
|
||||
{privileged && (
|
||||
|
||||
@@ -33,7 +33,7 @@ import {colors, s} from 'lib/styles'
|
||||
import {useTheme} from 'lib/ThemeContext'
|
||||
import {isWeb} from 'platform/detection'
|
||||
import {NavSignupCard} from '#/view/shell/NavSignupCard'
|
||||
import {formatCountShortOnly} from 'view/com/util/numeric/format'
|
||||
import {formatCount} from 'view/com/util/numeric/format'
|
||||
import {Text} from 'view/com/util/text/Text'
|
||||
import {UserAvatar} from 'view/com/util/UserAvatar'
|
||||
import {useTheme as useAlfTheme} from '#/alf'
|
||||
@@ -68,7 +68,7 @@ let DrawerProfileCard = ({
|
||||
account: SessionAccount
|
||||
onPressProfile: () => void
|
||||
}): React.ReactNode => {
|
||||
const {_} = useLingui()
|
||||
const {_, i18n} = useLingui()
|
||||
const pal = usePalette('default')
|
||||
const {data: profile} = useProfileQuery({did: account.did})
|
||||
|
||||
@@ -100,7 +100,7 @@ let DrawerProfileCard = ({
|
||||
<Text type="xl" style={[pal.textLight, styles.profileCardFollowers]}>
|
||||
<Trans>
|
||||
<Text type="xl-medium" style={pal.text}>
|
||||
{formatCountShortOnly(profile?.followersCount ?? 0)}
|
||||
{formatCount(i18n, profile?.followersCount ?? 0)}
|
||||
</Text>{' '}
|
||||
<Plural
|
||||
value={profile?.followersCount || 0}
|
||||
@@ -111,7 +111,7 @@ let DrawerProfileCard = ({
|
||||
·{' '}
|
||||
<Trans>
|
||||
<Text type="xl-medium" style={pal.text}>
|
||||
{formatCountShortOnly(profile?.followsCount ?? 0)}
|
||||
{formatCount(i18n, profile?.followsCount ?? 0)}
|
||||
</Text>{' '}
|
||||
<Plural
|
||||
value={profile?.followsCount || 0}
|
||||
|
||||
Reference in New Issue
Block a user