Fix localization for Following and Discover feed names (#11572)
This commit is contained in:
@@ -1528,11 +1528,6 @@
|
|||||||
"count": 1
|
"count": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"src/view/screens/Home.tsx": {
|
|
||||||
"typescript/no-floating-promises": {
|
|
||||||
"count": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"src/view/screens/ModerationBlockedAccounts.tsx": {
|
"src/view/screens/ModerationBlockedAccounts.tsx": {
|
||||||
"typescript/no-misused-promises": {
|
"typescript/no-misused-promises": {
|
||||||
"count": 3
|
"count": 3
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import {type I18n} from '@lingui/core'
|
||||||
|
import {msg} from '@lingui/core/macro'
|
||||||
|
|
||||||
|
import {DISCOVER_FEED_URI, TIMELINE_SAVED_FEED} from '#/lib/constants'
|
||||||
|
|
||||||
|
type FeedNameSource = {
|
||||||
|
displayName: string
|
||||||
|
uri: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getLocalizedFeedName(feed: FeedNameSource, i18n: I18n): string {
|
||||||
|
if (feed.uri === TIMELINE_SAVED_FEED.value) {
|
||||||
|
return i18n._(msg({message: 'Following', context: 'feed-name'}))
|
||||||
|
}
|
||||||
|
if (feed.uri === DISCOVER_FEED_URI) {
|
||||||
|
return i18n._(msg({message: 'Discover', context: 'feed-name'}))
|
||||||
|
}
|
||||||
|
return feed.displayName
|
||||||
|
}
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
import {useCallback, useMemo} from 'react'
|
import {useCallback, useMemo} from 'react'
|
||||||
|
import {useLingui} from '@lingui/react/macro'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {TIMELINE_SAVED_FEED} from '#/lib/constants'
|
||||||
import {type NavigationProp} from '#/lib/routes/types'
|
import {type NavigationProp} from '#/lib/routes/types'
|
||||||
|
import {getLocalizedFeedName} from '#/lib/strings/feed-names'
|
||||||
import {type FeedSourceInfo} from '#/state/queries/feed'
|
import {type FeedSourceInfo} from '#/state/queries/feed'
|
||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {type RenderTabBarFnProps} from '#/view/com/pager/Pager'
|
import {type RenderTabBarFnProps} from '#/view/com/pager/Pager'
|
||||||
@@ -12,28 +15,29 @@ export function HomeHeader(
|
|||||||
props: RenderTabBarFnProps & {
|
props: RenderTabBarFnProps & {
|
||||||
testID?: string
|
testID?: string
|
||||||
onPressSelected: () => void
|
onPressSelected: () => void
|
||||||
feeds: FeedSourceInfo[]
|
feeds: Pick<FeedSourceInfo, 'displayName' | 'uri'>[]
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
const {feeds, onSelect: onSelectProp} = props
|
const {feeds, onSelect: onSelectProp} = props
|
||||||
const {hasSession} = useSession()
|
const {hasSession} = useSession()
|
||||||
|
const {t: l, i18n} = useLingui()
|
||||||
const navigation = useNavigation<NavigationProp>()
|
const navigation = useNavigation<NavigationProp>()
|
||||||
|
|
||||||
const hasPinnedCustom = useMemo<boolean>(() => {
|
const hasPinnedCustom = useMemo<boolean>(() => {
|
||||||
if (!hasSession) return false
|
if (!hasSession) return false
|
||||||
return feeds.some(tab => {
|
return feeds.some(tab => {
|
||||||
const isFollowing = tab.uri === 'following'
|
const isFollowing = tab.uri === TIMELINE_SAVED_FEED.value
|
||||||
return !isFollowing
|
return !isFollowing
|
||||||
})
|
})
|
||||||
}, [feeds, hasSession])
|
}, [feeds, hasSession])
|
||||||
|
|
||||||
const items = useMemo(() => {
|
const items = useMemo(() => {
|
||||||
const pinnedNames = feeds.map(f => f.displayName)
|
const pinnedNames = feeds.map(f => getLocalizedFeedName(f, i18n))
|
||||||
if (!hasPinnedCustom) {
|
if (!hasPinnedCustom) {
|
||||||
return pinnedNames.concat('Feeds ✨')
|
return pinnedNames.concat(l`Feeds ✨`)
|
||||||
}
|
}
|
||||||
return pinnedNames
|
return pinnedNames
|
||||||
}, [hasPinnedCustom, feeds])
|
}, [i18n, l, hasPinnedCustom, feeds])
|
||||||
|
|
||||||
const onPressFeedsLink = useCallback(() => {
|
const onPressFeedsLink = useCallback(() => {
|
||||||
navigation.navigate('Feeds')
|
navigation.navigate('Feeds')
|
||||||
|
|||||||
@@ -4,9 +4,14 @@ import {
|
|||||||
Reanimated3DefaultSpringConfig,
|
Reanimated3DefaultSpringConfig,
|
||||||
withSpring,
|
withSpring,
|
||||||
} from 'react-native-reanimated'
|
} from 'react-native-reanimated'
|
||||||
|
import {useLingui} from '@lingui/react/macro'
|
||||||
import {useFocusEffect} from '@react-navigation/native'
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
|
|
||||||
import {PROD_DEFAULT_FEED} from '#/lib/constants'
|
import {
|
||||||
|
DISCOVER_FEED_URI,
|
||||||
|
PROD_DEFAULT_FEED,
|
||||||
|
TIMELINE_SAVED_FEED,
|
||||||
|
} from '#/lib/constants'
|
||||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||||
import {useOTAUpdates} from '#/lib/hooks/useOTAUpdates'
|
import {useOTAUpdates} from '#/lib/hooks/useOTAUpdates'
|
||||||
import {useSetTitle} from '#/lib/hooks/useSetTitle'
|
import {useSetTitle} from '#/lib/hooks/useSetTitle'
|
||||||
@@ -15,6 +20,7 @@ import {
|
|||||||
type HomeTabNavigatorParams,
|
type HomeTabNavigatorParams,
|
||||||
type NativeStackScreenProps,
|
type NativeStackScreenProps,
|
||||||
} from '#/lib/routes/types'
|
} from '#/lib/routes/types'
|
||||||
|
import {getLocalizedFeedName} from '#/lib/strings/feed-names'
|
||||||
import {emitSoftReset} from '#/state/events'
|
import {emitSoftReset} from '#/state/events'
|
||||||
import {
|
import {
|
||||||
type SavedFeedSourceInfo,
|
type SavedFeedSourceInfo,
|
||||||
@@ -114,6 +120,7 @@ function HomeScreenReady({
|
|||||||
preferences: UsePreferencesQueryResponse
|
preferences: UsePreferencesQueryResponse
|
||||||
pinnedFeedInfos: SavedFeedSourceInfo[]
|
pinnedFeedInfos: SavedFeedSourceInfo[]
|
||||||
}) {
|
}) {
|
||||||
|
const {i18n} = useLingui()
|
||||||
const ax = useAnalytics()
|
const ax = useAnalytics()
|
||||||
const allFeeds = useMemo(
|
const allFeeds = useMemo(
|
||||||
() => pinnedFeedInfos.map(f => f.feedDescriptor),
|
() => pinnedFeedInfos.map(f => f.feedDescriptor),
|
||||||
@@ -125,13 +132,14 @@ function HomeScreenReady({
|
|||||||
const maybeFoundIndex = allFeeds.indexOf(maybeRawSelectedFeed)
|
const maybeFoundIndex = allFeeds.indexOf(maybeRawSelectedFeed)
|
||||||
const selectedIndex = Math.max(0, maybeFoundIndex)
|
const selectedIndex = Math.max(0, maybeFoundIndex)
|
||||||
const maybeSelectedFeed: FeedDescriptor | undefined = allFeeds[selectedIndex]
|
const maybeSelectedFeed: FeedDescriptor | undefined = allFeeds[selectedIndex]
|
||||||
|
const selectedFeedInfo = pinnedFeedInfos[selectedIndex]
|
||||||
const requestNotificationsPermission = useRequestNotificationsPermission()
|
const requestNotificationsPermission = useRequestNotificationsPermission()
|
||||||
|
|
||||||
useSetTitle(pinnedFeedInfos[selectedIndex]?.displayName)
|
useSetTitle(selectedFeedInfo && getLocalizedFeedName(selectedFeedInfo, i18n))
|
||||||
useOTAUpdates()
|
useOTAUpdates()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
requestNotificationsPermission('Home')
|
void requestNotificationsPermission('Home')
|
||||||
}, [requestNotificationsPermission])
|
}, [requestNotificationsPermission])
|
||||||
|
|
||||||
const pagerRef = useRef<PagerRef>(null)
|
const pagerRef = useRef<PagerRef>(null)
|
||||||
@@ -223,8 +231,13 @@ function HomeScreenReady({
|
|||||||
{...props}
|
{...props}
|
||||||
testID="homeScreenFeedTabs"
|
testID="homeScreenFeedTabs"
|
||||||
onPressSelected={onPressSelected}
|
onPressSelected={onPressSelected}
|
||||||
// @ts-expect-error
|
feeds={[
|
||||||
feeds={[{displayName: 'Following'}, {displayName: 'Discover'}]}
|
{
|
||||||
|
displayName: 'Following',
|
||||||
|
uri: TIMELINE_SAVED_FEED.value,
|
||||||
|
},
|
||||||
|
{displayName: 'Discover', uri: DISCOVER_FEED_URI},
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {Pressable, View} from 'react-native'
|
import {Pressable, View} from 'react-native'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
|
||||||
import {useNavigation, useNavigationState} from '@react-navigation/native'
|
import {useNavigation, useNavigationState} from '@react-navigation/native'
|
||||||
|
|
||||||
import {getCurrentRoute} from '#/lib/routes/helpers'
|
import {getCurrentRoute} from '#/lib/routes/helpers'
|
||||||
import {type NavigationProp} from '#/lib/routes/types'
|
import {type NavigationProp} from '#/lib/routes/types'
|
||||||
|
import {getLocalizedFeedName} from '#/lib/strings/feed-names'
|
||||||
import {emitSoftReset} from '#/state/events'
|
import {emitSoftReset} from '#/state/events'
|
||||||
import {
|
import {
|
||||||
type SavedFeedSourceInfo,
|
type SavedFeedSourceInfo,
|
||||||
@@ -22,7 +22,7 @@ import {useAnalytics} from '#/analytics'
|
|||||||
|
|
||||||
export function DesktopFeeds() {
|
export function DesktopFeeds() {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {_} = useLingui()
|
const {t: l} = useLingui()
|
||||||
const ax = useAnalytics()
|
const ax = useAnalytics()
|
||||||
const {data: pinnedFeedInfos, error, isLoading} = usePinnedFeedsInfos()
|
const {data: pinnedFeedInfos, error, isLoading} = usePinnedFeedsInfos()
|
||||||
const selectedFeed = useSelectedFeed()
|
const selectedFeed = useSelectedFeed()
|
||||||
@@ -100,10 +100,9 @@ export function DesktopFeeds() {
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
to="/feeds"
|
to="/feeds"
|
||||||
label={_(msg`More feeds`)}
|
label={l`More feeds`}
|
||||||
style={[
|
style={[
|
||||||
a.flex_row,
|
a.flex_row,
|
||||||
a.align_center,
|
a.align_center,
|
||||||
@@ -150,7 +149,7 @@ export function DesktopFeeds() {
|
|||||||
: t.atoms.text_contrast_medium,
|
: t.atoms.text_contrast_medium,
|
||||||
]}
|
]}
|
||||||
numberOfLines={1}>
|
numberOfLines={1}>
|
||||||
{_(msg`More feeds`)}
|
{l`More feeds`}
|
||||||
</Text>
|
</Text>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
@@ -170,19 +169,20 @@ function FeedItem({
|
|||||||
onPress: () => void
|
onPress: () => void
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {_} = useLingui()
|
const {t: l, i18n} = useLingui()
|
||||||
const {
|
const {
|
||||||
state: hovered,
|
state: hovered,
|
||||||
onIn: onHoverIn,
|
onIn: onHoverIn,
|
||||||
onOut: onHoverOut,
|
onOut: onHoverOut,
|
||||||
} = useInteractionState()
|
} = useInteractionState()
|
||||||
const isFollowing = feedInfo.feedDescriptor === 'following'
|
const isFollowing = feedInfo.feedDescriptor === 'following'
|
||||||
|
const displayName = getLocalizedFeedName(feedInfo, i18n)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Pressable
|
<Pressable
|
||||||
accessibilityRole="link"
|
accessibilityRole="link"
|
||||||
accessibilityLabel={feedInfo.displayName}
|
accessibilityLabel={displayName}
|
||||||
accessibilityHint={_(msg`Opens ${feedInfo.displayName} feed`)}
|
accessibilityHint={l`Opens ${displayName} feed`}
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
onHoverIn={onHoverIn}
|
onHoverIn={onHoverIn}
|
||||||
onHoverOut={onHoverOut}
|
onHoverOut={onHoverOut}
|
||||||
@@ -231,7 +231,7 @@ function FeedItem({
|
|||||||
: t.atoms.text_contrast_medium,
|
: t.atoms.text_contrast_medium,
|
||||||
]}
|
]}
|
||||||
numberOfLines={1}>
|
numberOfLines={1}>
|
||||||
{feedInfo.displayName}
|
{displayName}
|
||||||
</Text>
|
</Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user