Improve notification localization (#3911)
* Update FeedItem.tsx * Update FeedItem.tsx * Update FeedItem.tsx * Update FeedItem.tsx * Update FeedItem.tsx * Update FeedItem.tsx * Update FeedItem.tsx * Update FeedItem.tsx * Update FeedItem.tsx * Update PostMeta.tsx * Update RightNav.tsx * Update FeedItem.tsx * Update FeedItem.tsx * a11y * Update FeedItem.tsx * Update PostThreadItem.tsx * Update PostThreadItem.tsx * revert * Update FeedItem.tsx * Update FeedItem.tsx * Update FeedItem.tsx * Revert "Merge remote-tracking branch 'upstream/main' into Improve-notification-localization" This reverts commitf435d1e7ed, reversing changes made todae2aee676. * Reapply "Merge remote-tracking branch 'upstream/main' into Improve-notification-localization" This reverts commitc93ac19048. * Update ThreadgateBtn.tsx
This commit is contained in:
+2
-2
@@ -1,6 +1,6 @@
|
||||
import 'react-native-url-polyfill/auto'
|
||||
import 'lib/sentry' // must be near top
|
||||
import 'view/icons'
|
||||
import '#/lib/sentry' // must be near top
|
||||
import '#/view/icons'
|
||||
|
||||
import React, {useEffect, useState} from 'react'
|
||||
import {GestureHandlerRootView} from 'react-native-gesture-handler'
|
||||
|
||||
@@ -5,15 +5,15 @@ import {flip, offset, shift, size, useFloating} from '@floating-ui/react-dom'
|
||||
import {msg, plural} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {isTouchDevice} from '#/lib/browser'
|
||||
import {getModerationCauseKey} from '#/lib/moderation'
|
||||
import {makeProfileLink} from '#/lib/routes/links'
|
||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {usePrefetchProfileQuery, useProfileQuery} from '#/state/queries/profile'
|
||||
import {useSession} from '#/state/session'
|
||||
import {isTouchDevice} from 'lib/browser'
|
||||
import {useProfileShadow} from 'state/cache/profile-shadow'
|
||||
import {formatCount} from '#/view/com/util/numeric/format'
|
||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||
import {ProfileHeaderHandle} from '#/screens/Profile/Header/Handle'
|
||||
|
||||
@@ -7,9 +7,9 @@ import {BottomSheetFlatListMethods} from '@discord/bottom-sheet'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender'
|
||||
import {isWeb} from 'platform/detection'
|
||||
import {useSession} from 'state/session'
|
||||
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useSession} from '#/state/session'
|
||||
import {WizardAction, WizardState} from '#/screens/StarterPack/Wizard/State'
|
||||
import {atoms as a, native, useTheme, web} from '#/alf'
|
||||
import {Button, ButtonText} from '#/components/Button'
|
||||
|
||||
@@ -2,8 +2,8 @@ import React from 'react'
|
||||
import {Pressable, View, ViewStyle} from 'react-native'
|
||||
import Animated, {LinearTransition} from 'react-native-reanimated'
|
||||
|
||||
import {HITSLOP_10} from '#/lib/constants'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {HITSLOP_10} from 'lib/constants'
|
||||
import {
|
||||
atoms as a,
|
||||
flatten,
|
||||
|
||||
@@ -3,7 +3,7 @@ import {View} from 'react-native'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {useAgent, useSession} from 'state/session'
|
||||
import {useAgent, useSession} from '#/state/session'
|
||||
import {atoms as a} from '#/alf'
|
||||
import {Button, ButtonText} from '#/components/Button'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
|
||||
@@ -13,6 +13,8 @@ import {
|
||||
RichText,
|
||||
} from '@atproto/api'
|
||||
|
||||
import {isNetworkError} from '#/lib/strings/errors'
|
||||
import {shortenLinks, stripInvalidMentions} from '#/lib/strings/rich-text-manip'
|
||||
import {logger} from '#/logger'
|
||||
import {ComposerImage, compressImage} from '#/state/gallery'
|
||||
import {writePostgateRecord} from '#/state/queries/postgate'
|
||||
@@ -22,8 +24,6 @@ import {
|
||||
threadgateAllowUISettingToAllowRecordValue,
|
||||
writeThreadgateRecord,
|
||||
} from '#/state/queries/threadgate'
|
||||
import {isNetworkError} from 'lib/strings/errors'
|
||||
import {shortenLinks, stripInvalidMentions} from 'lib/strings/rich-text-manip'
|
||||
import {LinkMeta} from '../link-meta/link-meta'
|
||||
import {uploadBlob} from './upload-blob'
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
MediaTypeOptions,
|
||||
} from 'expo-image-picker'
|
||||
|
||||
import * as Toast from 'view/com/util/Toast'
|
||||
import * as Toast from '#/view/com/util/Toast'
|
||||
import {getDataUriSize} from './util'
|
||||
|
||||
export async function openPicker(opts?: ImagePickerOptions) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import {AppBskyFeedDefs, AppBskyFeedPost} from '@atproto/api'
|
||||
import * as bcp47Match from 'bcp-47-match'
|
||||
import lande from 'lande'
|
||||
|
||||
import {hasProp} from 'lib/type-guards'
|
||||
import {hasProp} from '#/lib/type-guards'
|
||||
import {
|
||||
AppLanguage,
|
||||
LANGUAGES_MAP_CODE2,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
|
||||
import {ScrollView} from 'view/com/util/Views'
|
||||
import {ScrollView} from '#/view/com/util/Views'
|
||||
import {atoms as a} from '#/alf'
|
||||
import {Button, ButtonText} from '#/components/Button'
|
||||
import {Text} from '#/components/Typography'
|
||||
|
||||
@@ -5,18 +5,18 @@ import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {useGoBack} from '#/lib/hooks/useGoBack'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {logger} from '#/logger'
|
||||
import {RQKEY_ROOT as listQueryRoot} from '#/state/queries/list'
|
||||
import {useGoBack} from 'lib/hooks/useGoBack'
|
||||
import {sanitizeHandle} from 'lib/strings/handles'
|
||||
import {useListBlockMutation, useListMuteMutation} from 'state/queries/list'
|
||||
import {useListBlockMutation, useListMuteMutation} from '#/state/queries/list'
|
||||
import {
|
||||
UsePreferencesQueryResponse,
|
||||
useRemoveFeedMutation,
|
||||
} from 'state/queries/preferences'
|
||||
import {useSession} from 'state/session'
|
||||
import * as Toast from 'view/com/util/Toast'
|
||||
import {CenteredView} from 'view/com/util/Views'
|
||||
} from '#/state/queries/preferences'
|
||||
import {useSession} from '#/state/session'
|
||||
import * as Toast from '#/view/com/util/Toast'
|
||||
import {CenteredView} from '#/view/com/util/Views'
|
||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash'
|
||||
|
||||
@@ -15,35 +15,35 @@ import {useNavigation} from '@react-navigation/native'
|
||||
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {batchedUpdates} from '#/lib/batchedUpdates'
|
||||
import {HITSLOP_20} from '#/lib/constants'
|
||||
import {isBlockedOrBlocking, isMuted} from '#/lib/moderation/blocked-and-muted'
|
||||
import {makeProfileLink, makeStarterPackLink} from '#/lib/routes/links'
|
||||
import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types'
|
||||
import {logEvent} from '#/lib/statsig/statsig'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {getStarterPackOgCard} from '#/lib/strings/starter-pack'
|
||||
import {logger} from '#/logger'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {updateProfileShadow} from '#/state/cache/profile-shadow'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {getAllListMembers} from '#/state/queries/list-members'
|
||||
import {useResolvedStarterPackShortLink} from '#/state/queries/resolve-short-link'
|
||||
import {useResolveDidQuery} from '#/state/queries/resolve-uri'
|
||||
import {useShortenLink} from '#/state/queries/shorten-link'
|
||||
import {useDeleteStarterPackMutation} from '#/state/queries/starter-packs'
|
||||
import {useStarterPackQuery} from '#/state/queries/starter-packs'
|
||||
import {useAgent, useSession} from '#/state/session'
|
||||
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
|
||||
import {
|
||||
ProgressGuideAction,
|
||||
useProgressGuideControls,
|
||||
} from '#/state/shell/progress-guide'
|
||||
import {batchedUpdates} from 'lib/batchedUpdates'
|
||||
import {HITSLOP_20} from 'lib/constants'
|
||||
import {isBlockedOrBlocking, isMuted} from 'lib/moderation/blocked-and-muted'
|
||||
import {makeProfileLink, makeStarterPackLink} from 'lib/routes/links'
|
||||
import {CommonNavigatorParams, NavigationProp} from 'lib/routes/types'
|
||||
import {logEvent} from 'lib/statsig/statsig'
|
||||
import {getStarterPackOgCard} from 'lib/strings/starter-pack'
|
||||
import {isWeb} from 'platform/detection'
|
||||
import {updateProfileShadow} from 'state/cache/profile-shadow'
|
||||
import {useModerationOpts} from 'state/preferences/moderation-opts'
|
||||
import {getAllListMembers} from 'state/queries/list-members'
|
||||
import {useResolvedStarterPackShortLink} from 'state/queries/resolve-short-link'
|
||||
import {useResolveDidQuery} from 'state/queries/resolve-uri'
|
||||
import {useShortenLink} from 'state/queries/shorten-link'
|
||||
import {useStarterPackQuery} from 'state/queries/starter-packs'
|
||||
import {useAgent, useSession} from 'state/session'
|
||||
import {useLoggedOutViewControls} from 'state/shell/logged-out'
|
||||
import {useSetActiveStarterPack} from 'state/shell/starter-pack'
|
||||
import {useSetActiveStarterPack} from '#/state/shell/starter-pack'
|
||||
import {PagerWithHeader} from '#/view/com/pager/PagerWithHeader'
|
||||
import {ProfileSubpageHeader} from '#/view/com/profile/ProfileSubpageHeader'
|
||||
import * as Toast from '#/view/com/util/Toast'
|
||||
import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
|
||||
import {ProfileSubpageHeader} from 'view/com/profile/ProfileSubpageHeader'
|
||||
import {CenteredView} from 'view/com/util/Views'
|
||||
import {CenteredView} from '#/view/com/util/Views'
|
||||
import {bulkWriteFollows} from '#/screens/Onboarding/util'
|
||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
|
||||
@@ -19,32 +19,32 @@ import {useLingui} from '@lingui/react'
|
||||
import {useFocusEffect, useNavigation} from '@react-navigation/native'
|
||||
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||
|
||||
import {logger} from '#/logger'
|
||||
import {HITSLOP_10, STARTER_PACK_MAX_SIZE} from 'lib/constants'
|
||||
import {createSanitizedDisplayName} from 'lib/moderation/create-sanitized-display-name'
|
||||
import {CommonNavigatorParams, NavigationProp} from 'lib/routes/types'
|
||||
import {logEvent} from 'lib/statsig/statsig'
|
||||
import {sanitizeDisplayName} from 'lib/strings/display-names'
|
||||
import {sanitizeHandle} from 'lib/strings/handles'
|
||||
import {enforceLen} from 'lib/strings/helpers'
|
||||
import {HITSLOP_10, STARTER_PACK_MAX_SIZE} from '#/lib/constants'
|
||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||
import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types'
|
||||
import {logEvent} from '#/lib/statsig/statsig'
|
||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {enforceLen} from '#/lib/strings/helpers'
|
||||
import {
|
||||
getStarterPackOgCard,
|
||||
parseStarterPackUri,
|
||||
} from 'lib/strings/starter-pack'
|
||||
import {isAndroid, isNative, isWeb} from 'platform/detection'
|
||||
import {useModerationOpts} from 'state/preferences/moderation-opts'
|
||||
import {useAllListMembersQuery} from 'state/queries/list-members'
|
||||
import {useProfileQuery} from 'state/queries/profile'
|
||||
} from '#/lib/strings/starter-pack'
|
||||
import {logger} from '#/logger'
|
||||
import {isAndroid, isNative, isWeb} from '#/platform/detection'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {useAllListMembersQuery} from '#/state/queries/list-members'
|
||||
import {useProfileQuery} from '#/state/queries/profile'
|
||||
import {
|
||||
useCreateStarterPackMutation,
|
||||
useEditStarterPackMutation,
|
||||
useStarterPackQuery,
|
||||
} from 'state/queries/starter-packs'
|
||||
import {useSession} from 'state/session'
|
||||
import {useSetMinimalShellMode} from 'state/shell'
|
||||
} from '#/state/queries/starter-packs'
|
||||
import {useSession} from '#/state/session'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import * as Toast from '#/view/com/util/Toast'
|
||||
import {UserAvatar} from 'view/com/util/UserAvatar'
|
||||
import {CenteredView} from 'view/com/util/Views'
|
||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||
import {CenteredView} from '#/view/com/util/Views'
|
||||
import {useWizardState, WizardStep} from '#/screens/StarterPack/Wizard/State'
|
||||
import {StepDetails} from '#/screens/StarterPack/Wizard/StepDetails'
|
||||
import {StepFeeds} from '#/screens/StarterPack/Wizard/StepFeeds'
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from 'react'
|
||||
import {StyleProp, View, ViewStyle} from 'react-native'
|
||||
|
||||
import {ExternalEmbedDraft} from 'lib/api/index'
|
||||
import {Gif} from 'state/queries/tenor'
|
||||
import {ExternalEmbedRemoveBtn} from 'view/com/composer/ExternalEmbedRemoveBtn'
|
||||
import {ExternalLinkEmbed} from 'view/com/util/post-embeds/ExternalLinkEmbed'
|
||||
import {ExternalEmbedDraft} from '#/lib/api/index'
|
||||
import {Gif} from '#/state/queries/tenor'
|
||||
import {ExternalEmbedRemoveBtn} from '#/view/com/composer/ExternalEmbedRemoveBtn'
|
||||
import {ExternalLinkEmbed} from '#/view/com/util/post-embeds/ExternalLinkEmbed'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
|
||||
@@ -13,15 +13,15 @@ import {Text as TiptapText} from '@tiptap/extension-text'
|
||||
import {generateJSON} from '@tiptap/html'
|
||||
import {EditorContent, JSONContent, useEditor} from '@tiptap/react'
|
||||
|
||||
import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle'
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {blobToDataUri, isUriImage} from '#/lib/media/util'
|
||||
import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
|
||||
import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle'
|
||||
import {blobToDataUri, isUriImage} from 'lib/media/util'
|
||||
import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter'
|
||||
import {
|
||||
LinkFacetMatch,
|
||||
suggestLinkCardUri,
|
||||
} from 'view/com/composer/text-input/text-input-util'
|
||||
} from '#/view/com/composer/text-input/text-input-util'
|
||||
import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter'
|
||||
import {atoms as a, useAlf} from '#/alf'
|
||||
import {Portal} from '#/components/Portal'
|
||||
import {normalizeTextStyles} from '#/components/Typography'
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import React, {memo, useEffect, useMemo, useState} from 'react'
|
||||
import React, {
|
||||
memo,
|
||||
type ReactElement,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react'
|
||||
import {
|
||||
Animated,
|
||||
Pressable,
|
||||
@@ -17,7 +23,7 @@ import {
|
||||
} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/api'
|
||||
import {TID} from '@atproto/common-web'
|
||||
import {msg, plural, Trans} from '@lingui/macro'
|
||||
import {msg, Plural, plural, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useNavigation} from '@react-navigation/native'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
@@ -164,7 +170,30 @@ let FeedItem = ({
|
||||
)
|
||||
}
|
||||
|
||||
let action = ''
|
||||
const formattedCount =
|
||||
authors.length > 1 ? formatCount(i18n, authors.length - 1) : ''
|
||||
const firstAuthorName = sanitizeDisplayName(
|
||||
authors[0].profile.displayName || authors[0].profile.handle,
|
||||
)
|
||||
const niceTimestamp = niceDate(i18n, item.notification.indexedAt)
|
||||
|
||||
let a11yAuthor = firstAuthorName
|
||||
let author = (
|
||||
<TextLink
|
||||
key={authors[0].href}
|
||||
style={[pal.text, s.bold]}
|
||||
href={authors[0].href}
|
||||
text={
|
||||
<Text emoji style={[pal.text, s.bold]}>
|
||||
{forceLTR(firstAuthorName)}
|
||||
</Text>
|
||||
}
|
||||
disableMismatchWarning
|
||||
/>
|
||||
)
|
||||
|
||||
let a11yLabel = ''
|
||||
let action: ReactElement
|
||||
let icon = (
|
||||
<HeartIconFilled
|
||||
size="xl"
|
||||
@@ -174,10 +203,59 @@ let FeedItem = ({
|
||||
]}
|
||||
/>
|
||||
)
|
||||
|
||||
if (item.type === 'post-like') {
|
||||
action = _(msg`liked your post`)
|
||||
a11yLabel =
|
||||
authors.length > 1
|
||||
? _(
|
||||
msg`${a11yAuthor} and ${plural(authors.length - 1, {
|
||||
one: `${formattedCount} other`,
|
||||
other: `${formattedCount} others`,
|
||||
})} liked your post`,
|
||||
)
|
||||
: _(msg`${a11yAuthor} liked your post`)
|
||||
action =
|
||||
authors.length > 1 ? (
|
||||
<Trans>
|
||||
{author} and{' '}
|
||||
<Text style={[pal.text, s.bold]}>
|
||||
<Plural
|
||||
value={authors.length - 1}
|
||||
one={`${formattedCount} other`}
|
||||
other={`${formattedCount} others`}
|
||||
/>
|
||||
</Text>{' '}
|
||||
liked your post
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>{author} liked your post</Trans>
|
||||
)
|
||||
} else if (item.type === 'repost') {
|
||||
action = _(msg`reposted your post`)
|
||||
a11yLabel =
|
||||
authors.length > 1
|
||||
? _(
|
||||
msg`${a11yAuthor} and ${plural(authors.length - 1, {
|
||||
one: `${formattedCount} other`,
|
||||
other: `${formattedCount} others`,
|
||||
})} reposted your post`,
|
||||
)
|
||||
: _(msg`${a11yAuthor} reposted your post`)
|
||||
action =
|
||||
authors.length > 1 ? (
|
||||
<Trans>
|
||||
{author} and{' '}
|
||||
<Text style={[pal.text, s.bold]}>
|
||||
<Plural
|
||||
value={authors.length - 1}
|
||||
one={`${formattedCount} other`}
|
||||
other={`${formattedCount} others`}
|
||||
/>
|
||||
</Text>{' '}
|
||||
reposted your post
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>{author} reposted your post</Trans>
|
||||
)
|
||||
icon = <RepostIcon size="xl" style={{color: t.palette.positive_600}} />
|
||||
} else if (item.type === 'follow') {
|
||||
let isFollowBack = false
|
||||
@@ -202,39 +280,120 @@ let FeedItem = ({
|
||||
}
|
||||
|
||||
if (isFollowBack) {
|
||||
action = _(msg`followed you back`)
|
||||
a11yLabel =
|
||||
authors.length > 1
|
||||
? _(
|
||||
msg`${a11yAuthor} and ${plural(authors.length - 1, {
|
||||
one: `${formattedCount} other`,
|
||||
other: `${formattedCount} others`,
|
||||
})} followed you back`,
|
||||
)
|
||||
: _(msg`${a11yAuthor} followed you back`)
|
||||
action =
|
||||
authors.length > 1 ? (
|
||||
<Trans>
|
||||
{author} and{' '}
|
||||
<Text style={[pal.text, s.bold]}>
|
||||
<Plural
|
||||
value={authors.length - 1}
|
||||
one={`${formattedCount} other`}
|
||||
other={`${formattedCount} others`}
|
||||
/>
|
||||
</Text>{' '}
|
||||
followed you back
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>{author} followed you back</Trans>
|
||||
)
|
||||
} else {
|
||||
action = _(msg`followed you`)
|
||||
a11yLabel =
|
||||
authors.length > 1
|
||||
? _(
|
||||
msg`${a11yAuthor} and ${plural(authors.length - 1, {
|
||||
one: `${formattedCount} other`,
|
||||
other: `${formattedCount} others`,
|
||||
})} followed you`,
|
||||
)
|
||||
: _(msg`${a11yAuthor} followed you`)
|
||||
action =
|
||||
authors.length > 1 ? (
|
||||
<Trans>
|
||||
{author} and{' '}
|
||||
<Text style={[pal.text, s.bold]}>
|
||||
<Plural
|
||||
value={authors.length - 1}
|
||||
one={`${formattedCount} other`}
|
||||
other={`${formattedCount} others`}
|
||||
/>
|
||||
</Text>{' '}
|
||||
followed you
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>{author} followed you</Trans>
|
||||
)
|
||||
}
|
||||
icon = <PersonPlusIcon size="xl" style={{color: t.palette.primary_500}} />
|
||||
} else if (item.type === 'feedgen-like') {
|
||||
action = _(msg`liked your custom feed`)
|
||||
a11yLabel =
|
||||
authors.length > 1
|
||||
? _(
|
||||
msg`${a11yAuthor} and ${plural(authors.length - 1, {
|
||||
one: `${formattedCount} other`,
|
||||
other: `${formattedCount} others`,
|
||||
})} liked your custom feed`,
|
||||
)
|
||||
: _(msg`${a11yAuthor} liked your custom feed`)
|
||||
action =
|
||||
authors.length > 1 ? (
|
||||
<Trans>
|
||||
{author} and{' '}
|
||||
<Text style={[pal.text, s.bold]}>
|
||||
<Plural
|
||||
value={authors.length - 1}
|
||||
one={`${formattedCount} other`}
|
||||
other={`${formattedCount} others`}
|
||||
/>
|
||||
</Text>{' '}
|
||||
liked your custom feed
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>{author} liked your custom feed</Trans>
|
||||
)
|
||||
} else if (item.type === 'starterpack-joined') {
|
||||
a11yLabel =
|
||||
authors.length > 1
|
||||
? _(
|
||||
msg`${a11yAuthor} and ${plural(authors.length - 1, {
|
||||
one: `${formattedCount} other`,
|
||||
other: `${formattedCount} others`,
|
||||
})} signed up with your starter pack`,
|
||||
)
|
||||
: _(msg`${a11yAuthor} signed up with your starter pack`)
|
||||
action =
|
||||
authors.length > 1 ? (
|
||||
<Trans>
|
||||
{author} and{' '}
|
||||
<Text style={[pal.text, s.bold]}>
|
||||
<Plural
|
||||
value={authors.length - 1}
|
||||
one={`${formattedCount} other`}
|
||||
other={`${formattedCount} others`}
|
||||
/>
|
||||
</Text>{' '}
|
||||
signed up with your starter pack
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>{author} signed up with your starter pack</Trans>
|
||||
)
|
||||
icon = (
|
||||
<View style={{height: 30, width: 30}}>
|
||||
<StarterPack width={30} gradient="sky" />
|
||||
</View>
|
||||
)
|
||||
action = _(msg`signed up with your starter pack`)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
|
||||
const formattedCount =
|
||||
authors.length > 1 ? formatCount(i18n, authors.length - 1) : ''
|
||||
const firstAuthorName = sanitizeDisplayName(
|
||||
authors[0].profile.displayName || authors[0].profile.handle,
|
||||
)
|
||||
const niceTimestamp = niceDate(i18n, item.notification.indexedAt)
|
||||
const a11yLabelUsers =
|
||||
authors.length > 1
|
||||
? _(msg` and `) +
|
||||
plural(authors.length - 1, {
|
||||
one: `${formattedCount} other`,
|
||||
other: `${formattedCount} others`,
|
||||
})
|
||||
: ''
|
||||
const a11yLabel = `${firstAuthorName}${a11yLabelUsers} ${action} ${niceTimestamp}`
|
||||
a11yLabel += ` · ${niceTimestamp}`
|
||||
|
||||
return (
|
||||
<Link
|
||||
@@ -303,42 +462,18 @@ let FeedItem = ({
|
||||
/>
|
||||
<ExpandedAuthorsList visible={isAuthorsExpanded} authors={authors} />
|
||||
<Text
|
||||
style={[styles.meta, a.self_start]}
|
||||
style={[styles.meta, a.self_start, pal.text]}
|
||||
accessibilityHint=""
|
||||
accessibilityLabel={a11yLabel}>
|
||||
<TextLink
|
||||
key={authors[0].href}
|
||||
style={[pal.text, s.bold]}
|
||||
href={authors[0].href}
|
||||
text={
|
||||
<Text emoji style={[pal.text, s.bold]}>
|
||||
{forceLTR(firstAuthorName)}
|
||||
</Text>
|
||||
}
|
||||
disableMismatchWarning
|
||||
/>
|
||||
{authors.length > 1 ? (
|
||||
<>
|
||||
<Text style={[pal.text]}>
|
||||
{' '}
|
||||
<Trans>and</Trans>{' '}
|
||||
</Text>
|
||||
<Text style={[pal.text, s.bold]}>
|
||||
{plural(authors.length - 1, {
|
||||
one: `${formattedCount} other`,
|
||||
other: `${formattedCount} others`,
|
||||
})}
|
||||
</Text>
|
||||
</>
|
||||
) : undefined}
|
||||
<Text style={[pal.text]}> {action}</Text>
|
||||
{action}
|
||||
<TimeElapsed timestamp={item.notification.indexedAt}>
|
||||
{({timeElapsed}) => (
|
||||
<Text
|
||||
style={[pal.textLight, styles.pointer]}
|
||||
title={niceTimestamp}>
|
||||
{' ' + timeElapsed}
|
||||
</Text>
|
||||
<>
|
||||
<Text style={[a.ml_xs, pal.textLight]}>·</Text>
|
||||
<Text style={[a.ml_xs, pal.textLight]} title={niceTimestamp}>
|
||||
{timeElapsed}
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
</TimeElapsed>
|
||||
</Text>
|
||||
|
||||
Reference in New Issue
Block a user