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 'react-native-url-polyfill/auto'
|
||||||
import 'lib/sentry' // must be near top
|
import '#/lib/sentry' // must be near top
|
||||||
import 'view/icons'
|
import '#/view/icons'
|
||||||
|
|
||||||
import React, {useEffect, useState} from 'react'
|
import React, {useEffect, useState} from 'react'
|
||||||
import {GestureHandlerRootView} from 'react-native-gesture-handler'
|
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 {msg, plural} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
|
import {isTouchDevice} from '#/lib/browser'
|
||||||
import {getModerationCauseKey} from '#/lib/moderation'
|
import {getModerationCauseKey} from '#/lib/moderation'
|
||||||
import {makeProfileLink} from '#/lib/routes/links'
|
import {makeProfileLink} from '#/lib/routes/links'
|
||||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
|
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
||||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
import {usePrefetchProfileQuery, useProfileQuery} from '#/state/queries/profile'
|
import {usePrefetchProfileQuery, useProfileQuery} from '#/state/queries/profile'
|
||||||
import {useSession} from '#/state/session'
|
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 {formatCount} from '#/view/com/util/numeric/format'
|
||||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import {ProfileHeaderHandle} from '#/screens/Profile/Header/Handle'
|
import {ProfileHeaderHandle} from '#/screens/Profile/Header/Handle'
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import {BottomSheetFlatListMethods} from '@discord/bottom-sheet'
|
|||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender'
|
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
||||||
import {isWeb} from 'platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
import {useSession} from 'state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {WizardAction, WizardState} from '#/screens/StarterPack/Wizard/State'
|
import {WizardAction, WizardState} from '#/screens/StarterPack/Wizard/State'
|
||||||
import {atoms as a, native, useTheme, web} from '#/alf'
|
import {atoms as a, native, useTheme, web} from '#/alf'
|
||||||
import {Button, ButtonText} from '#/components/Button'
|
import {Button, ButtonText} from '#/components/Button'
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import React from 'react'
|
|||||||
import {Pressable, View, ViewStyle} from 'react-native'
|
import {Pressable, View, ViewStyle} from 'react-native'
|
||||||
import Animated, {LinearTransition} from 'react-native-reanimated'
|
import Animated, {LinearTransition} from 'react-native-reanimated'
|
||||||
|
|
||||||
|
import {HITSLOP_10} from '#/lib/constants'
|
||||||
import {isNative} from '#/platform/detection'
|
import {isNative} from '#/platform/detection'
|
||||||
import {HITSLOP_10} from 'lib/constants'
|
|
||||||
import {
|
import {
|
||||||
atoms as a,
|
atoms as a,
|
||||||
flatten,
|
flatten,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {View} from 'react-native'
|
|||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
import {useAgent, useSession} from 'state/session'
|
import {useAgent, useSession} from '#/state/session'
|
||||||
import {atoms as a} from '#/alf'
|
import {atoms as a} 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'
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import {
|
|||||||
RichText,
|
RichText,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
|
|
||||||
|
import {isNetworkError} from '#/lib/strings/errors'
|
||||||
|
import {shortenLinks, stripInvalidMentions} from '#/lib/strings/rich-text-manip'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {ComposerImage, compressImage} from '#/state/gallery'
|
import {ComposerImage, compressImage} from '#/state/gallery'
|
||||||
import {writePostgateRecord} from '#/state/queries/postgate'
|
import {writePostgateRecord} from '#/state/queries/postgate'
|
||||||
@@ -22,8 +24,6 @@ import {
|
|||||||
threadgateAllowUISettingToAllowRecordValue,
|
threadgateAllowUISettingToAllowRecordValue,
|
||||||
writeThreadgateRecord,
|
writeThreadgateRecord,
|
||||||
} from '#/state/queries/threadgate'
|
} 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 {LinkMeta} from '../link-meta/link-meta'
|
||||||
import {uploadBlob} from './upload-blob'
|
import {uploadBlob} from './upload-blob'
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {
|
|||||||
MediaTypeOptions,
|
MediaTypeOptions,
|
||||||
} from 'expo-image-picker'
|
} from 'expo-image-picker'
|
||||||
|
|
||||||
import * as Toast from 'view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {getDataUriSize} from './util'
|
import {getDataUriSize} from './util'
|
||||||
|
|
||||||
export async function openPicker(opts?: ImagePickerOptions) {
|
export async function openPicker(opts?: ImagePickerOptions) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import {AppBskyFeedDefs, AppBskyFeedPost} from '@atproto/api'
|
|||||||
import * as bcp47Match from 'bcp-47-match'
|
import * as bcp47Match from 'bcp-47-match'
|
||||||
import lande from 'lande'
|
import lande from 'lande'
|
||||||
|
|
||||||
import {hasProp} from 'lib/type-guards'
|
import {hasProp} from '#/lib/type-guards'
|
||||||
import {
|
import {
|
||||||
AppLanguage,
|
AppLanguage,
|
||||||
LANGUAGES_MAP_CODE2,
|
LANGUAGES_MAP_CODE2,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {View} from 'react-native'
|
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 {atoms as a} from '#/alf'
|
||||||
import {Button, ButtonText} from '#/components/Button'
|
import {Button, ButtonText} from '#/components/Button'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
|||||||
@@ -5,18 +5,18 @@ import {msg, Trans} from '@lingui/macro'
|
|||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {useGoBack} from '#/lib/hooks/useGoBack'
|
||||||
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {RQKEY_ROOT as listQueryRoot} from '#/state/queries/list'
|
import {RQKEY_ROOT as listQueryRoot} from '#/state/queries/list'
|
||||||
import {useGoBack} from 'lib/hooks/useGoBack'
|
import {useListBlockMutation, useListMuteMutation} from '#/state/queries/list'
|
||||||
import {sanitizeHandle} from 'lib/strings/handles'
|
|
||||||
import {useListBlockMutation, useListMuteMutation} from 'state/queries/list'
|
|
||||||
import {
|
import {
|
||||||
UsePreferencesQueryResponse,
|
UsePreferencesQueryResponse,
|
||||||
useRemoveFeedMutation,
|
useRemoveFeedMutation,
|
||||||
} from 'state/queries/preferences'
|
} from '#/state/queries/preferences'
|
||||||
import {useSession} from 'state/session'
|
import {useSession} from '#/state/session'
|
||||||
import * as Toast from 'view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {CenteredView} from 'view/com/util/Views'
|
import {CenteredView} from '#/view/com/util/Views'
|
||||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash'
|
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 {NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
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 {cleanError} from '#/lib/strings/errors'
|
||||||
|
import {getStarterPackOgCard} from '#/lib/strings/starter-pack'
|
||||||
import {logger} from '#/logger'
|
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 {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 {
|
import {
|
||||||
ProgressGuideAction,
|
ProgressGuideAction,
|
||||||
useProgressGuideControls,
|
useProgressGuideControls,
|
||||||
} from '#/state/shell/progress-guide'
|
} from '#/state/shell/progress-guide'
|
||||||
import {batchedUpdates} from 'lib/batchedUpdates'
|
import {useSetActiveStarterPack} from '#/state/shell/starter-pack'
|
||||||
import {HITSLOP_20} from 'lib/constants'
|
import {PagerWithHeader} from '#/view/com/pager/PagerWithHeader'
|
||||||
import {isBlockedOrBlocking, isMuted} from 'lib/moderation/blocked-and-muted'
|
import {ProfileSubpageHeader} from '#/view/com/profile/ProfileSubpageHeader'
|
||||||
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 * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
|
import {CenteredView} from '#/view/com/util/Views'
|
||||||
import {ProfileSubpageHeader} from 'view/com/profile/ProfileSubpageHeader'
|
|
||||||
import {CenteredView} from 'view/com/util/Views'
|
|
||||||
import {bulkWriteFollows} from '#/screens/Onboarding/util'
|
import {bulkWriteFollows} from '#/screens/Onboarding/util'
|
||||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
|
|||||||
@@ -19,32 +19,32 @@ import {useLingui} from '@lingui/react'
|
|||||||
import {useFocusEffect, useNavigation} from '@react-navigation/native'
|
import {useFocusEffect, useNavigation} from '@react-navigation/native'
|
||||||
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||||
|
|
||||||
import {logger} from '#/logger'
|
import {HITSLOP_10, STARTER_PACK_MAX_SIZE} from '#/lib/constants'
|
||||||
import {HITSLOP_10, STARTER_PACK_MAX_SIZE} from 'lib/constants'
|
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||||
import {createSanitizedDisplayName} from 'lib/moderation/create-sanitized-display-name'
|
import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types'
|
||||||
import {CommonNavigatorParams, NavigationProp} from 'lib/routes/types'
|
import {logEvent} from '#/lib/statsig/statsig'
|
||||||
import {logEvent} from 'lib/statsig/statsig'
|
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||||
import {sanitizeDisplayName} from 'lib/strings/display-names'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
import {sanitizeHandle} from 'lib/strings/handles'
|
import {enforceLen} from '#/lib/strings/helpers'
|
||||||
import {enforceLen} from 'lib/strings/helpers'
|
|
||||||
import {
|
import {
|
||||||
getStarterPackOgCard,
|
getStarterPackOgCard,
|
||||||
parseStarterPackUri,
|
parseStarterPackUri,
|
||||||
} from 'lib/strings/starter-pack'
|
} from '#/lib/strings/starter-pack'
|
||||||
import {isAndroid, isNative, isWeb} from 'platform/detection'
|
import {logger} from '#/logger'
|
||||||
import {useModerationOpts} from 'state/preferences/moderation-opts'
|
import {isAndroid, isNative, isWeb} from '#/platform/detection'
|
||||||
import {useAllListMembersQuery} from 'state/queries/list-members'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
import {useProfileQuery} from 'state/queries/profile'
|
import {useAllListMembersQuery} from '#/state/queries/list-members'
|
||||||
|
import {useProfileQuery} from '#/state/queries/profile'
|
||||||
import {
|
import {
|
||||||
useCreateStarterPackMutation,
|
useCreateStarterPackMutation,
|
||||||
useEditStarterPackMutation,
|
useEditStarterPackMutation,
|
||||||
useStarterPackQuery,
|
useStarterPackQuery,
|
||||||
} from 'state/queries/starter-packs'
|
} from '#/state/queries/starter-packs'
|
||||||
import {useSession} from 'state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {useSetMinimalShellMode} from 'state/shell'
|
import {useSetMinimalShellMode} from '#/state/shell'
|
||||||
import * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {UserAvatar} from 'view/com/util/UserAvatar'
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import {CenteredView} from 'view/com/util/Views'
|
import {CenteredView} from '#/view/com/util/Views'
|
||||||
import {useWizardState, WizardStep} from '#/screens/StarterPack/Wizard/State'
|
import {useWizardState, WizardStep} from '#/screens/StarterPack/Wizard/State'
|
||||||
import {StepDetails} from '#/screens/StarterPack/Wizard/StepDetails'
|
import {StepDetails} from '#/screens/StarterPack/Wizard/StepDetails'
|
||||||
import {StepFeeds} from '#/screens/StarterPack/Wizard/StepFeeds'
|
import {StepFeeds} from '#/screens/StarterPack/Wizard/StepFeeds'
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {StyleProp, View, ViewStyle} from 'react-native'
|
import {StyleProp, View, ViewStyle} from 'react-native'
|
||||||
|
|
||||||
import {ExternalEmbedDraft} from 'lib/api/index'
|
import {ExternalEmbedDraft} from '#/lib/api/index'
|
||||||
import {Gif} from 'state/queries/tenor'
|
import {Gif} from '#/state/queries/tenor'
|
||||||
import {ExternalEmbedRemoveBtn} from 'view/com/composer/ExternalEmbedRemoveBtn'
|
import {ExternalEmbedRemoveBtn} from '#/view/com/composer/ExternalEmbedRemoveBtn'
|
||||||
import {ExternalLinkEmbed} from 'view/com/util/post-embeds/ExternalLinkEmbed'
|
import {ExternalLinkEmbed} from '#/view/com/util/post-embeds/ExternalLinkEmbed'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {Loader} from '#/components/Loader'
|
import {Loader} from '#/components/Loader'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
|||||||
@@ -13,15 +13,15 @@ import {Text as TiptapText} from '@tiptap/extension-text'
|
|||||||
import {generateJSON} from '@tiptap/html'
|
import {generateJSON} from '@tiptap/html'
|
||||||
import {EditorContent, JSONContent, useEditor} from '@tiptap/react'
|
import {EditorContent, JSONContent, useEditor} from '@tiptap/react'
|
||||||
|
|
||||||
|
import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle'
|
||||||
import {usePalette} from '#/lib/hooks/usePalette'
|
import {usePalette} from '#/lib/hooks/usePalette'
|
||||||
|
import {blobToDataUri, isUriImage} from '#/lib/media/util'
|
||||||
import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
|
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 {
|
import {
|
||||||
LinkFacetMatch,
|
LinkFacetMatch,
|
||||||
suggestLinkCardUri,
|
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 {atoms as a, useAlf} from '#/alf'
|
||||||
import {Portal} from '#/components/Portal'
|
import {Portal} from '#/components/Portal'
|
||||||
import {normalizeTextStyles} from '#/components/Typography'
|
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 {
|
import {
|
||||||
Animated,
|
Animated,
|
||||||
Pressable,
|
Pressable,
|
||||||
@@ -17,7 +23,7 @@ import {
|
|||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {AtUri} from '@atproto/api'
|
import {AtUri} from '@atproto/api'
|
||||||
import {TID} from '@atproto/common-web'
|
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 {useLingui} from '@lingui/react'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
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 = (
|
let icon = (
|
||||||
<HeartIconFilled
|
<HeartIconFilled
|
||||||
size="xl"
|
size="xl"
|
||||||
@@ -174,10 +203,59 @@ let FeedItem = ({
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
if (item.type === 'post-like') {
|
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') {
|
} 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}} />
|
icon = <RepostIcon size="xl" style={{color: t.palette.positive_600}} />
|
||||||
} else if (item.type === 'follow') {
|
} else if (item.type === 'follow') {
|
||||||
let isFollowBack = false
|
let isFollowBack = false
|
||||||
@@ -202,39 +280,120 @@ let FeedItem = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isFollowBack) {
|
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 {
|
} 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}} />
|
icon = <PersonPlusIcon size="xl" style={{color: t.palette.primary_500}} />
|
||||||
} else if (item.type === 'feedgen-like') {
|
} 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') {
|
} 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 = (
|
icon = (
|
||||||
<View style={{height: 30, width: 30}}>
|
<View style={{height: 30, width: 30}}>
|
||||||
<StarterPack width={30} gradient="sky" />
|
<StarterPack width={30} gradient="sky" />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
action = _(msg`signed up with your starter pack`)
|
|
||||||
} else {
|
} else {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
a11yLabel += ` · ${niceTimestamp}`
|
||||||
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}`
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
@@ -303,42 +462,18 @@ let FeedItem = ({
|
|||||||
/>
|
/>
|
||||||
<ExpandedAuthorsList visible={isAuthorsExpanded} authors={authors} />
|
<ExpandedAuthorsList visible={isAuthorsExpanded} authors={authors} />
|
||||||
<Text
|
<Text
|
||||||
style={[styles.meta, a.self_start]}
|
style={[styles.meta, a.self_start, pal.text]}
|
||||||
accessibilityHint=""
|
accessibilityHint=""
|
||||||
accessibilityLabel={a11yLabel}>
|
accessibilityLabel={a11yLabel}>
|
||||||
<TextLink
|
{action}
|
||||||
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>
|
|
||||||
<TimeElapsed timestamp={item.notification.indexedAt}>
|
<TimeElapsed timestamp={item.notification.indexedAt}>
|
||||||
{({timeElapsed}) => (
|
{({timeElapsed}) => (
|
||||||
<Text
|
<>
|
||||||
style={[pal.textLight, styles.pointer]}
|
<Text style={[a.ml_xs, pal.textLight]}>·</Text>
|
||||||
title={niceTimestamp}>
|
<Text style={[a.ml_xs, pal.textLight]} title={niceTimestamp}>
|
||||||
{' ' + timeElapsed}
|
{timeElapsed}
|
||||||
</Text>
|
</Text>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</TimeElapsed>
|
</TimeElapsed>
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
Reference in New Issue
Block a user