Hindi Internationalization (#1914)
* get basic hindi support to work * get web app language switcher in * Refactor i18n implementation and remove unused code * add missing strings * add dropdowns and modals missing strings * complete all hindi translations * fix merge conflicts * fix legeacy persisted state * fix data in RecommendedFeeds * fix lint
This commit is contained in:
parent
019aae5f01
commit
c5b6f88e9a
68 changed files with 5121 additions and 2058 deletions
|
@ -183,9 +183,10 @@ export const AppPasswords = withAuthRequired(
|
|||
function AppPasswordsHeader() {
|
||||
const {isTabletOrDesktop} = useWebMediaQueries()
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
return (
|
||||
<>
|
||||
<ViewHeader title="App Passwords" showOnDesktop />
|
||||
<ViewHeader title={_(msg`App Passwords`)} showOnDesktop />
|
||||
<Text
|
||||
type="sm"
|
||||
style={[
|
||||
|
@ -220,14 +221,16 @@ function AppPassword({
|
|||
const onDelete = React.useCallback(async () => {
|
||||
openModal({
|
||||
name: 'confirm',
|
||||
title: 'Delete App Password',
|
||||
message: `Are you sure you want to delete the app password "${name}"?`,
|
||||
title: _(msg`Delete app password`),
|
||||
message: _(
|
||||
msg`Are you sure you want to delete the app password "${name}"?`,
|
||||
),
|
||||
async onPressConfirm() {
|
||||
await deleteMutation.mutateAsync({name})
|
||||
Toast.show('App password deleted')
|
||||
},
|
||||
})
|
||||
}, [deleteMutation, openModal, name])
|
||||
}, [deleteMutation, openModal, name, _])
|
||||
|
||||
const primaryLocale =
|
||||
contentLanguages.length > 0 ? contentLanguages[0] : 'en-US'
|
||||
|
@ -245,15 +248,17 @@ function AppPassword({
|
|||
{name}
|
||||
</Text>
|
||||
<Text type="md" style={[pal.text, styles.pr10]} numberOfLines={1}>
|
||||
Created{' '}
|
||||
{Intl.DateTimeFormat(primaryLocale, {
|
||||
year: 'numeric',
|
||||
month: 'numeric',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
}).format(new Date(createdAt))}
|
||||
<Trans>
|
||||
Created{' '}
|
||||
{Intl.DateTimeFormat(primaryLocale, {
|
||||
year: 'numeric',
|
||||
month: 'numeric',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
}).format(new Date(createdAt))}
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
<FontAwesomeIcon icon={['far', 'trash-can']} style={styles.trashIcon} />
|
||||
|
|
|
@ -9,6 +9,8 @@ import {ScrollView} from 'view/com/util/Views'
|
|||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {s} from 'lib/styles'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
type Props = NativeStackScreenProps<
|
||||
CommonNavigatorParams,
|
||||
|
@ -16,6 +18,7 @@ type Props = NativeStackScreenProps<
|
|||
>
|
||||
export const CommunityGuidelinesScreen = (_props: Props) => {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
|
||||
useFocusEffect(
|
||||
|
@ -26,16 +29,18 @@ export const CommunityGuidelinesScreen = (_props: Props) => {
|
|||
|
||||
return (
|
||||
<View>
|
||||
<ViewHeader title="Community Guidelines" />
|
||||
<ViewHeader title={_(msg`Community Guidelines`)} />
|
||||
<ScrollView style={[s.hContentRegion, pal.view]}>
|
||||
<View style={[s.p20]}>
|
||||
<Text style={pal.text}>
|
||||
The Community Guidelines have been moved to{' '}
|
||||
<TextLink
|
||||
style={pal.link}
|
||||
href="https://blueskyweb.xyz/support/community-guidelines"
|
||||
text="blueskyweb.xyz/support/community-guidelines"
|
||||
/>
|
||||
<Trans>
|
||||
The Community Guidelines have been moved to{' '}
|
||||
<TextLink
|
||||
style={pal.link}
|
||||
href="https://blueskyweb.xyz/support/community-guidelines"
|
||||
text="blueskyweb.xyz/support/community-guidelines"
|
||||
/>
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
<View style={s.footerSpacer} />
|
||||
|
|
|
@ -9,10 +9,13 @@ import {ScrollView} from 'view/com/util/Views'
|
|||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {s} from 'lib/styles'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'CopyrightPolicy'>
|
||||
export const CopyrightPolicyScreen = (_props: Props) => {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
|
||||
useFocusEffect(
|
||||
|
@ -23,16 +26,18 @@ export const CopyrightPolicyScreen = (_props: Props) => {
|
|||
|
||||
return (
|
||||
<View>
|
||||
<ViewHeader title="Copyright Policy" />
|
||||
<ViewHeader title={_(msg`Copyright Policy`)} />
|
||||
<ScrollView style={[s.hContentRegion, pal.view]}>
|
||||
<View style={[s.p20]}>
|
||||
<Text style={pal.text}>
|
||||
The Copyright Policy has been moved to{' '}
|
||||
<TextLink
|
||||
style={pal.link}
|
||||
href="https://blueskyweb.xyz/support/community-guidelines"
|
||||
text="blueskyweb.xyz/support/community-guidelines"
|
||||
/>
|
||||
<Trans>
|
||||
The Copyright Policy has been moved to{' '}
|
||||
<TextLink
|
||||
style={pal.link}
|
||||
href="https://blueskyweb.xyz/support/community-guidelines"
|
||||
text="blueskyweb.xyz/support/community-guidelines"
|
||||
/>
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
<View style={s.footerSpacer} />
|
||||
|
|
|
@ -467,7 +467,7 @@ export const FeedsScreen = withAuthRequired(function FeedsScreenImpl(
|
|||
<View style={[pal.view, styles.container]}>
|
||||
{isMobile && (
|
||||
<ViewHeader
|
||||
title="Feeds"
|
||||
title={_(msg`Feeds`)}
|
||||
canGoBack={false}
|
||||
renderButton={renderHeaderBtn}
|
||||
showBorder
|
||||
|
|
|
@ -14,16 +14,19 @@ import {
|
|||
} from '@fortawesome/react-native-fontawesome'
|
||||
import {useAnalytics} from 'lib/analytics/analytics'
|
||||
import {useFocusEffect} from '@react-navigation/native'
|
||||
import {LANGUAGES} from 'lib/../locale/languages'
|
||||
import {APP_LANGUAGES, LANGUAGES} from 'lib/../locale/languages'
|
||||
import RNPickerSelect, {PickerSelectProps} from 'react-native-picker-select'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {useLanguagePrefs, useLanguagePrefsApi} from '#/state/preferences'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'LanguageSettings'>
|
||||
|
||||
export function LanguageSettingsScreen(_: Props) {
|
||||
export function LanguageSettingsScreen(_props: Props) {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const langPrefs = useLanguagePrefs()
|
||||
const setLangPrefs = useLanguagePrefsApi()
|
||||
const {isTabletOrDesktop} = useWebMediaQueries()
|
||||
|
@ -52,6 +55,15 @@ export function LanguageSettingsScreen(_: Props) {
|
|||
[langPrefs, setLangPrefs],
|
||||
)
|
||||
|
||||
const onChangeAppLanguage = React.useCallback(
|
||||
(value: Parameters<PickerSelectProps['onValueChange']>[0]) => {
|
||||
if (langPrefs.appLanguage !== value) {
|
||||
setLangPrefs.setAppLanguage(value)
|
||||
}
|
||||
},
|
||||
[langPrefs, setLangPrefs],
|
||||
)
|
||||
|
||||
const myLanguages = React.useMemo(() => {
|
||||
return (
|
||||
langPrefs.contentLanguages
|
||||
|
@ -71,15 +83,109 @@ export function LanguageSettingsScreen(_: Props) {
|
|||
styles.container,
|
||||
isTabletOrDesktop && styles.desktopContainer,
|
||||
]}>
|
||||
<ViewHeader title="Language Settings" showOnDesktop />
|
||||
<ViewHeader title={_(msg`Language Settings`)} showOnDesktop />
|
||||
|
||||
<View style={{paddingTop: 20, paddingHorizontal: 20}}>
|
||||
{/* APP LANGUAGE */}
|
||||
<View style={{paddingBottom: 20}}>
|
||||
<Text type="title-sm" style={[pal.text, s.pb5]}>
|
||||
Primary Language
|
||||
<Trans>App Language</Trans>
|
||||
</Text>
|
||||
<Text style={[pal.text, s.pb10]}>
|
||||
Select your preferred language for translations in your feed.
|
||||
<Trans>
|
||||
Select your app language for the default text to display in the
|
||||
app
|
||||
</Trans>
|
||||
</Text>
|
||||
|
||||
<View style={{position: 'relative'}}>
|
||||
<RNPickerSelect
|
||||
value={langPrefs.appLanguage}
|
||||
onValueChange={onChangeAppLanguage}
|
||||
items={APP_LANGUAGES.filter(l => Boolean(l.code2)).map(l => ({
|
||||
label: l.name,
|
||||
value: l.code2,
|
||||
key: l.code2,
|
||||
}))}
|
||||
style={{
|
||||
inputAndroid: {
|
||||
backgroundColor: pal.viewLight.backgroundColor,
|
||||
color: pal.text.color,
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: '500',
|
||||
paddingHorizontal: 14,
|
||||
paddingVertical: 8,
|
||||
borderRadius: 24,
|
||||
},
|
||||
inputIOS: {
|
||||
backgroundColor: pal.viewLight.backgroundColor,
|
||||
color: pal.text.color,
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: '500',
|
||||
paddingHorizontal: 14,
|
||||
paddingVertical: 8,
|
||||
borderRadius: 24,
|
||||
},
|
||||
inputWeb: {
|
||||
// @ts-ignore web only
|
||||
cursor: 'pointer',
|
||||
'-moz-appearance': 'none',
|
||||
'-webkit-appearance': 'none',
|
||||
appearance: 'none',
|
||||
outline: 0,
|
||||
borderWidth: 0,
|
||||
backgroundColor: pal.viewLight.backgroundColor,
|
||||
color: pal.text.color,
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: '500',
|
||||
paddingHorizontal: 14,
|
||||
paddingVertical: 8,
|
||||
borderRadius: 24,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 1,
|
||||
right: 1,
|
||||
bottom: 1,
|
||||
width: 40,
|
||||
backgroundColor: pal.viewLight.backgroundColor,
|
||||
borderRadius: 24,
|
||||
pointerEvents: 'none',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}>
|
||||
<FontAwesomeIcon
|
||||
icon="chevron-down"
|
||||
style={pal.text as FontAwesomeIconStyle}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={{
|
||||
height: 1,
|
||||
backgroundColor: pal.border.borderColor,
|
||||
marginBottom: 20,
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* PRIMARY LANGUAGE */}
|
||||
<View style={{paddingBottom: 20}}>
|
||||
<Text type="title-sm" style={[pal.text, s.pb5]}>
|
||||
<Trans>Primary Language</Trans>
|
||||
</Text>
|
||||
<Text style={[pal.text, s.pb10]}>
|
||||
<Trans>
|
||||
Select your preferred language for translations in your feed.
|
||||
</Trans>
|
||||
</Text>
|
||||
|
||||
<View style={{position: 'relative'}}>
|
||||
|
@ -161,13 +267,16 @@ export function LanguageSettingsScreen(_: Props) {
|
|||
}}
|
||||
/>
|
||||
|
||||
{/* CONTENT LANGUAGES */}
|
||||
<View style={{paddingBottom: 20}}>
|
||||
<Text type="title-sm" style={[pal.text, s.pb5]}>
|
||||
Content Languages
|
||||
<Trans>Content Languages</Trans>
|
||||
</Text>
|
||||
<Text style={[pal.text, s.pb10]}>
|
||||
Select which languages you want your subscribed feeds to include. If
|
||||
none are selected, all languages will be shown.
|
||||
<Trans>
|
||||
Select which languages you want your subscribed feeds to include.
|
||||
If none are selected, all languages will be shown.
|
||||
</Trans>
|
||||
</Text>
|
||||
|
||||
<Button
|
||||
|
|
|
@ -15,6 +15,7 @@ import {SimpleViewHeader} from 'view/com/util/SimpleViewHeader'
|
|||
import {s} from 'lib/styles'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {Trans} from '@lingui/macro'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Lists'>
|
||||
export const ListsScreen = withAuthRequired(
|
||||
|
@ -56,10 +57,10 @@ export const ListsScreen = withAuthRequired(
|
|||
}>
|
||||
<View style={{flex: 1}}>
|
||||
<Text type="title-lg" style={[pal.text, {fontWeight: 'bold'}]}>
|
||||
User Lists
|
||||
<Trans>User Lists</Trans>
|
||||
</Text>
|
||||
<Text style={pal.textLight}>
|
||||
Public, shareable lists which can drive feeds.
|
||||
<Trans>Public, shareable lists which can drive feeds.</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
<View>
|
||||
|
@ -74,7 +75,7 @@ export const ListsScreen = withAuthRequired(
|
|||
}}>
|
||||
<FontAwesomeIcon icon="plus" color={pal.colors.text} />
|
||||
<Text type="button" style={pal.text}>
|
||||
New
|
||||
<Trans>New</Trans>
|
||||
</Text>
|
||||
</Button>
|
||||
</View>
|
||||
|
|
|
@ -17,11 +17,14 @@ import {useAnalytics} from 'lib/analytics/analytics'
|
|||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Moderation'>
|
||||
export const ModerationScreen = withAuthRequired(
|
||||
function Moderation({}: Props) {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const {screen, track} = useAnalytics()
|
||||
const {isTabletOrDesktop} = useWebMediaQueries()
|
||||
|
@ -47,7 +50,7 @@ export const ModerationScreen = withAuthRequired(
|
|||
isTabletOrDesktop ? styles.desktopContainer : pal.viewLight,
|
||||
]}
|
||||
testID="moderationScreen">
|
||||
<ViewHeader title="Moderation" showOnDesktop />
|
||||
<ViewHeader title={_(msg`Moderation`)} showOnDesktop />
|
||||
<View style={styles.spacer} />
|
||||
<TouchableOpacity
|
||||
testID="contentFilteringBtn"
|
||||
|
@ -63,7 +66,7 @@ export const ModerationScreen = withAuthRequired(
|
|||
/>
|
||||
</View>
|
||||
<Text type="lg" style={pal.text}>
|
||||
Content filtering
|
||||
<Trans>Content filtering</Trans>
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<Link
|
||||
|
@ -77,7 +80,7 @@ export const ModerationScreen = withAuthRequired(
|
|||
/>
|
||||
</View>
|
||||
<Text type="lg" style={pal.text}>
|
||||
Moderation lists
|
||||
<Trans>Moderation lists</Trans>
|
||||
</Text>
|
||||
</Link>
|
||||
<Link
|
||||
|
@ -91,7 +94,7 @@ export const ModerationScreen = withAuthRequired(
|
|||
/>
|
||||
</View>
|
||||
<Text type="lg" style={pal.text}>
|
||||
Muted accounts
|
||||
<Trans>Muted accounts</Trans>
|
||||
</Text>
|
||||
</Link>
|
||||
<Link
|
||||
|
@ -105,7 +108,7 @@ export const ModerationScreen = withAuthRequired(
|
|||
/>
|
||||
</View>
|
||||
<Text type="lg" style={pal.text}>
|
||||
Blocked accounts
|
||||
<Trans>Blocked accounts</Trans>
|
||||
</Text>
|
||||
</Link>
|
||||
</CenteredView>
|
||||
|
|
|
@ -21,6 +21,8 @@ import {ErrorScreen} from '../com/util/error/ErrorScreen'
|
|||
import {ProfileCard} from 'view/com/profile/ProfileCard'
|
||||
import {logger} from '#/logger'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useMyBlockedAccountsQuery} from '#/state/queries/my-blocked-accounts'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
|
||||
|
@ -31,6 +33,7 @@ type Props = NativeStackScreenProps<
|
|||
export const ModerationBlockedAccounts = withAuthRequired(
|
||||
function ModerationBlockedAccountsImpl({}: Props) {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const {isTabletOrDesktop} = useWebMediaQueries()
|
||||
const {screen} = useAnalytics()
|
||||
|
@ -104,7 +107,7 @@ export const ModerationBlockedAccounts = withAuthRequired(
|
|||
pal.border,
|
||||
]}
|
||||
testID="blockedAccountsScreen">
|
||||
<ViewHeader title="Blocked Accounts" showOnDesktop />
|
||||
<ViewHeader title={_(msg`Blocked Accounts`)} showOnDesktop />
|
||||
<Text
|
||||
type="sm"
|
||||
style={[
|
||||
|
@ -112,9 +115,11 @@ export const ModerationBlockedAccounts = withAuthRequired(
|
|||
pal.text,
|
||||
isTabletOrDesktop && styles.descriptionDesktop,
|
||||
]}>
|
||||
Blocked accounts cannot reply in your threads, mention you, or
|
||||
otherwise interact with you. You will not see their content and they
|
||||
will be prevented from seeing yours.
|
||||
<Trans>
|
||||
Blocked accounts cannot reply in your threads, mention you, or
|
||||
otherwise interact with you. You will not see their content and they
|
||||
will be prevented from seeing yours.
|
||||
</Trans>
|
||||
</Text>
|
||||
{isEmpty ? (
|
||||
<View style={[pal.border, !isTabletOrDesktop && styles.flex1]}>
|
||||
|
@ -127,9 +132,11 @@ export const ModerationBlockedAccounts = withAuthRequired(
|
|||
) : (
|
||||
<View style={[styles.empty, pal.viewLight]}>
|
||||
<Text type="lg" style={[pal.text, styles.emptyText]}>
|
||||
You have not blocked any accounts yet. To block an account, go
|
||||
to their profile and selected "Block account" from the menu on
|
||||
their account.
|
||||
<Trans>
|
||||
You have not blocked any accounts yet. To block an account,
|
||||
go to their profile and selected "Block account" from the
|
||||
menu on their account.
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
|
|
|
@ -21,6 +21,8 @@ import {ErrorScreen} from '../com/util/error/ErrorScreen'
|
|||
import {ProfileCard} from 'view/com/profile/ProfileCard'
|
||||
import {logger} from '#/logger'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useMyMutedAccountsQuery} from '#/state/queries/my-muted-accounts'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
|
||||
|
@ -31,6 +33,7 @@ type Props = NativeStackScreenProps<
|
|||
export const ModerationMutedAccounts = withAuthRequired(
|
||||
function ModerationMutedAccountsImpl({}: Props) {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const {isTabletOrDesktop} = useWebMediaQueries()
|
||||
const {screen} = useAnalytics()
|
||||
|
@ -104,7 +107,7 @@ export const ModerationMutedAccounts = withAuthRequired(
|
|||
pal.border,
|
||||
]}
|
||||
testID="mutedAccountsScreen">
|
||||
<ViewHeader title="Muted Accounts" showOnDesktop />
|
||||
<ViewHeader title={_(msg`Muted Accounts`)} showOnDesktop />
|
||||
<Text
|
||||
type="sm"
|
||||
style={[
|
||||
|
@ -112,8 +115,10 @@ export const ModerationMutedAccounts = withAuthRequired(
|
|||
pal.text,
|
||||
isTabletOrDesktop && styles.descriptionDesktop,
|
||||
]}>
|
||||
Muted accounts have their posts removed from your feed and from your
|
||||
notifications. Mutes are completely private.
|
||||
<Trans>
|
||||
Muted accounts have their posts removed from your feed and from your
|
||||
notifications. Mutes are completely private.
|
||||
</Trans>
|
||||
</Text>
|
||||
{isEmpty ? (
|
||||
<View style={[pal.border, !isTabletOrDesktop && styles.flex1]}>
|
||||
|
@ -126,9 +131,11 @@ export const ModerationMutedAccounts = withAuthRequired(
|
|||
) : (
|
||||
<View style={[styles.empty, pal.viewLight]}>
|
||||
<Text type="lg" style={[pal.text, styles.emptyText]}>
|
||||
You have not muted any accounts yet. To mute an account, go to
|
||||
their profile and selected "Mute account" from the menu on
|
||||
their account.
|
||||
<Trans>
|
||||
You have not muted any accounts yet. To mute an account, go
|
||||
to their profile and selected "Mute account" from the menu
|
||||
on their account.
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
|
|
|
@ -12,9 +12,12 @@ import {NavigationProp} from 'lib/routes/types'
|
|||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {s} from 'lib/styles'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
export const NotFoundScreen = () => {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const navigation = useNavigation<NavigationProp>()
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
|
||||
|
@ -36,13 +39,15 @@ export const NotFoundScreen = () => {
|
|||
|
||||
return (
|
||||
<View testID="notFoundView" style={pal.view}>
|
||||
<ViewHeader title="Page not found" />
|
||||
<ViewHeader title={_(msg`Page not found`)} />
|
||||
<View style={styles.container}>
|
||||
<Text type="title-2xl" style={[pal.text, s.mb10]}>
|
||||
Page not found
|
||||
<Trans>Page not found</Trans>
|
||||
</Text>
|
||||
<Text type="md" style={[pal.text, s.mb10]}>
|
||||
We're sorry! We can't find the page you were looking for.
|
||||
<Trans>
|
||||
We're sorry! We can't find the page you were looking for.
|
||||
</Trans>
|
||||
</Text>
|
||||
<Button
|
||||
type="primary"
|
||||
|
|
|
@ -18,6 +18,8 @@ import {s, colors} from 'lib/styles'
|
|||
import {useAnalytics} from 'lib/analytics/analytics'
|
||||
import {logger} from '#/logger'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useUnreadNotifications} from '#/state/queries/notifications/unread'
|
||||
import {RQKEY as NOTIFS_RQKEY} from '#/state/queries/notifications/feed'
|
||||
import {listenSoftReset, emitSoftReset} from '#/state/events'
|
||||
|
@ -28,6 +30,7 @@ type Props = NativeStackScreenProps<
|
|||
>
|
||||
export const NotificationsScreen = withAuthRequired(
|
||||
function NotificationsScreenImpl({}: Props) {
|
||||
const {_} = useLingui()
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const [onMainScroll, isScrolledDown, resetMainScroll] = useOnMainScroll()
|
||||
const scrollElRef = React.useRef<FlatList>(null)
|
||||
|
@ -83,7 +86,7 @@ export const NotificationsScreen = withAuthRequired(
|
|||
style={[pal.text, {fontWeight: 'bold'}]}
|
||||
text={
|
||||
<>
|
||||
Notifications{' '}
|
||||
<Trans>Notifications</Trans>{' '}
|
||||
{hasNew && (
|
||||
<View
|
||||
style={{
|
||||
|
@ -107,7 +110,7 @@ export const NotificationsScreen = withAuthRequired(
|
|||
|
||||
return (
|
||||
<View testID="notificationsScreen" style={s.hContentRegion}>
|
||||
<ViewHeader title="Notifications" canGoBack={false} />
|
||||
<ViewHeader title={_(msg`Notifications`)} canGoBack={false} />
|
||||
<Feed
|
||||
onScroll={onMainScroll}
|
||||
scrollElRef={scrollElRef}
|
||||
|
@ -116,7 +119,7 @@ export const NotificationsScreen = withAuthRequired(
|
|||
{(isScrolledDown || hasNew) && (
|
||||
<LoadLatestBtn
|
||||
onPress={onPressLoadLatest}
|
||||
label="Load new notifications"
|
||||
label={_(msg`Load new notifications`)}
|
||||
showIndicator={hasNew}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -7,12 +7,15 @@ import {ViewHeader} from '../com/util/ViewHeader'
|
|||
import {PostLikedBy as PostLikedByComponent} from '../com/post-thread/PostLikedBy'
|
||||
import {makeRecordUri} from 'lib/strings/url-helpers'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostLikedBy'>
|
||||
export const PostLikedByScreen = withAuthRequired(({route}: Props) => {
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const {name, rkey} = route.params
|
||||
const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
|
||||
const {_} = useLingui()
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
|
@ -22,7 +25,7 @@ export const PostLikedByScreen = withAuthRequired(({route}: Props) => {
|
|||
|
||||
return (
|
||||
<View>
|
||||
<ViewHeader title="Liked by" />
|
||||
<ViewHeader title={_(msg`Liked by`)} />
|
||||
<PostLikedByComponent uri={uri} />
|
||||
</View>
|
||||
)
|
||||
|
|
|
@ -7,12 +7,15 @@ import {ViewHeader} from '../com/util/ViewHeader'
|
|||
import {PostRepostedBy as PostRepostedByComponent} from '../com/post-thread/PostRepostedBy'
|
||||
import {makeRecordUri} from 'lib/strings/url-helpers'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {msg} from '@lingui/macro'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostRepostedBy'>
|
||||
export const PostRepostedByScreen = withAuthRequired(({route}: Props) => {
|
||||
const {name, rkey} = route.params
|
||||
const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const {_} = useLingui()
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
|
@ -22,7 +25,7 @@ export const PostRepostedByScreen = withAuthRequired(({route}: Props) => {
|
|||
|
||||
return (
|
||||
<View>
|
||||
<ViewHeader title="Reposted by" />
|
||||
<ViewHeader title={_(msg`Reposted by`)} />
|
||||
<PostRepostedByComponent uri={uri} />
|
||||
</View>
|
||||
)
|
||||
|
|
|
@ -19,6 +19,8 @@ import {clamp} from 'lodash'
|
|||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useResolveUriQuery} from '#/state/queries/resolve-uri'
|
||||
import {ErrorMessage} from '../com/util/error/ErrorMessage'
|
||||
import {CenteredView} from '../com/util/Views'
|
||||
|
@ -29,6 +31,7 @@ export const PostThreadScreen = withAuthRequired(function PostThreadScreenImpl({
|
|||
route,
|
||||
}: Props) {
|
||||
const queryClient = useQueryClient()
|
||||
const {_} = useLingui()
|
||||
const {fabMinimalShellTransform} = useMinimalShellMode()
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const {openComposer} = useComposerControls()
|
||||
|
@ -74,7 +77,7 @@ export const PostThreadScreen = withAuthRequired(function PostThreadScreenImpl({
|
|||
|
||||
return (
|
||||
<View style={s.hContentRegion}>
|
||||
{isMobile && <ViewHeader title="Post" />}
|
||||
{isMobile && <ViewHeader title={_(msg`Post`)} />}
|
||||
<View style={s.flex1}>
|
||||
{uriError ? (
|
||||
<CenteredView>
|
||||
|
|
|
@ -92,7 +92,7 @@ export function PreferencesHomeFeed({navigation}: Props) {
|
|||
styles.container,
|
||||
isTabletOrDesktop && styles.desktopContainer,
|
||||
]}>
|
||||
<ViewHeader title="Home Feed Preferences" showOnDesktop />
|
||||
<ViewHeader title={_(msg`Home Feed Preferences`)} showOnDesktop />
|
||||
<View
|
||||
style={[
|
||||
styles.titleSection,
|
||||
|
@ -142,7 +142,7 @@ export function PreferencesHomeFeed({navigation}: Props) {
|
|||
</Text>
|
||||
<ToggleButton
|
||||
type="default-light"
|
||||
label="Followed users only"
|
||||
label={_(msg`Followed users only`)}
|
||||
isSelected={Boolean(
|
||||
variables?.hideRepliesByUnfollowed ??
|
||||
preferences?.feedViewPrefs?.hideRepliesByUnfollowed,
|
||||
|
@ -188,8 +188,8 @@ export function PreferencesHomeFeed({navigation}: Props) {
|
|||
label={
|
||||
variables?.hideReposts ??
|
||||
preferences?.feedViewPrefs?.hideReposts
|
||||
? 'No'
|
||||
: 'Yes'
|
||||
? _(msg`No`)
|
||||
: _(msg`Yes`)
|
||||
}
|
||||
isSelected={
|
||||
!(
|
||||
|
@ -223,8 +223,8 @@ export function PreferencesHomeFeed({navigation}: Props) {
|
|||
label={
|
||||
variables?.hideQuotePosts ??
|
||||
preferences?.feedViewPrefs?.hideQuotePosts
|
||||
? 'No'
|
||||
: 'Yes'
|
||||
? _(msg`No`)
|
||||
: _(msg`Yes`)
|
||||
}
|
||||
isSelected={
|
||||
!(
|
||||
|
@ -259,8 +259,8 @@ export function PreferencesHomeFeed({navigation}: Props) {
|
|||
label={
|
||||
variables?.lab_mergeFeedEnabled ??
|
||||
preferences?.feedViewPrefs?.lab_mergeFeedEnabled
|
||||
? 'Yes'
|
||||
: 'No'
|
||||
? _(msg`Yes`)
|
||||
: _(msg`No`)
|
||||
}
|
||||
isSelected={
|
||||
!!(
|
||||
|
|
|
@ -50,7 +50,7 @@ export function PreferencesThreads({navigation}: Props) {
|
|||
styles.container,
|
||||
isTabletOrDesktop && styles.desktopContainer,
|
||||
]}>
|
||||
<ViewHeader title="Thread Preferences" showOnDesktop />
|
||||
<ViewHeader title={_(msg`Thread Preferences`)} showOnDesktop />
|
||||
<View
|
||||
style={[
|
||||
styles.titleSection,
|
||||
|
|
|
@ -9,10 +9,13 @@ import {ScrollView} from 'view/com/util/Views'
|
|||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {s} from 'lib/styles'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'PrivacyPolicy'>
|
||||
export const PrivacyPolicyScreen = (_props: Props) => {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
|
||||
useFocusEffect(
|
||||
|
@ -23,16 +26,18 @@ export const PrivacyPolicyScreen = (_props: Props) => {
|
|||
|
||||
return (
|
||||
<View>
|
||||
<ViewHeader title="Privacy Policy" />
|
||||
<ViewHeader title={_(msg`Privacy Policy`)} />
|
||||
<ScrollView style={[s.hContentRegion, pal.view]}>
|
||||
<View style={[s.p20]}>
|
||||
<Text style={pal.text}>
|
||||
The Privacy Policy has been moved to{' '}
|
||||
<TextLink
|
||||
style={pal.link}
|
||||
href="https://blueskyweb.xyz/support/privacy-policy"
|
||||
text="blueskyweb.xyz/support/privacy-policy"
|
||||
/>
|
||||
<Trans>
|
||||
The Privacy Policy has been moved to{' '}
|
||||
<TextLink
|
||||
style={pal.link}
|
||||
href="https://blueskyweb.xyz/support/privacy-policy"
|
||||
text="blueskyweb.xyz/support/privacy-policy"
|
||||
/>
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
<View style={s.footerSpacer} />
|
||||
|
|
|
@ -269,7 +269,7 @@ export function ProfileFeedScreenInner({
|
|||
return [
|
||||
{
|
||||
testID: 'feedHeaderDropdownToggleSavedBtn',
|
||||
label: isSaved ? 'Remove from my feeds' : 'Add to my feeds',
|
||||
label: isSaved ? _(msg`Remove from my feeds`) : _(msg`Add to my feeds`),
|
||||
onPress: isSavePending || isRemovePending ? undefined : onToggleSaved,
|
||||
icon: isSaved
|
||||
? {
|
||||
|
@ -289,7 +289,7 @@ export function ProfileFeedScreenInner({
|
|||
},
|
||||
{
|
||||
testID: 'feedHeaderDropdownReportBtn',
|
||||
label: 'Report feed',
|
||||
label: _(msg`Report feed`),
|
||||
onPress: onPressReport,
|
||||
icon: {
|
||||
ios: {
|
||||
|
@ -301,7 +301,7 @@ export function ProfileFeedScreenInner({
|
|||
},
|
||||
{
|
||||
testID: 'feedHeaderDropdownShareBtn',
|
||||
label: 'Share link',
|
||||
label: _(msg`Share feed`),
|
||||
onPress: onPressShare,
|
||||
icon: {
|
||||
ios: {
|
||||
|
@ -319,6 +319,7 @@ export function ProfileFeedScreenInner({
|
|||
isSaved,
|
||||
isSavePending,
|
||||
isRemovePending,
|
||||
_,
|
||||
])
|
||||
|
||||
const renderHeader = useCallback(() => {
|
||||
|
|
|
@ -7,12 +7,15 @@ import {ViewHeader} from '../com/util/ViewHeader'
|
|||
import {PostLikedBy as PostLikedByComponent} from '../com/post-thread/PostLikedBy'
|
||||
import {makeRecordUri} from 'lib/strings/url-helpers'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {msg} from '@lingui/macro'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileFeedLikedBy'>
|
||||
export const ProfileFeedLikedByScreen = withAuthRequired(({route}: Props) => {
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const {name, rkey} = route.params
|
||||
const uri = makeRecordUri(name, 'app.bsky.feed.generator', rkey)
|
||||
const {_} = useLingui()
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
|
@ -22,7 +25,7 @@ export const ProfileFeedLikedByScreen = withAuthRequired(({route}: Props) => {
|
|||
|
||||
return (
|
||||
<View>
|
||||
<ViewHeader title="Liked by" />
|
||||
<ViewHeader title={_(msg`Liked by`)} />
|
||||
<PostLikedByComponent uri={uri} />
|
||||
</View>
|
||||
)
|
||||
|
|
|
@ -6,11 +6,14 @@ import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
|||
import {ViewHeader} from '../com/util/ViewHeader'
|
||||
import {ProfileFollowers as ProfileFollowersComponent} from '../com/profile/ProfileFollowers'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {msg} from '@lingui/macro'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileFollowers'>
|
||||
export const ProfileFollowersScreen = withAuthRequired(({route}: Props) => {
|
||||
const {name} = route.params
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const {_} = useLingui()
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
|
@ -20,7 +23,7 @@ export const ProfileFollowersScreen = withAuthRequired(({route}: Props) => {
|
|||
|
||||
return (
|
||||
<View>
|
||||
<ViewHeader title="Followers" />
|
||||
<ViewHeader title={_(msg`Followers`)} />
|
||||
<ProfileFollowersComponent name={name} />
|
||||
</View>
|
||||
)
|
||||
|
|
|
@ -6,11 +6,14 @@ import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
|||
import {ViewHeader} from '../com/util/ViewHeader'
|
||||
import {ProfileFollows as ProfileFollowsComponent} from '../com/profile/ProfileFollows'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {msg} from '@lingui/macro'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileFollows'>
|
||||
export const ProfileFollowsScreen = withAuthRequired(({route}: Props) => {
|
||||
const {name} = route.params
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const {_} = useLingui()
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
|
@ -20,7 +23,7 @@ export const ProfileFollowsScreen = withAuthRequired(({route}: Props) => {
|
|||
|
||||
return (
|
||||
<View>
|
||||
<ViewHeader title="Following" />
|
||||
<ViewHeader title={_(msg`Following`)} />
|
||||
<ProfileFollowsComponent name={name} />
|
||||
</View>
|
||||
)
|
||||
|
|
|
@ -268,9 +268,10 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
const onSubscribeMute = useCallback(() => {
|
||||
openModal({
|
||||
name: 'confirm',
|
||||
title: 'Mute these accounts?',
|
||||
message:
|
||||
'Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them.',
|
||||
title: _(msg`Mute these accounts?`),
|
||||
message: _(
|
||||
msg`Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them.`,
|
||||
),
|
||||
confirmBtnText: 'Mute this List',
|
||||
async onPressConfirm() {
|
||||
try {
|
||||
|
@ -286,7 +287,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
closeModal()
|
||||
},
|
||||
})
|
||||
}, [openModal, closeModal, list, listMuteMutation])
|
||||
}, [openModal, closeModal, list, listMuteMutation, _])
|
||||
|
||||
const onUnsubscribeMute = useCallback(async () => {
|
||||
try {
|
||||
|
@ -302,9 +303,10 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
const onSubscribeBlock = useCallback(() => {
|
||||
openModal({
|
||||
name: 'confirm',
|
||||
title: 'Block these accounts?',
|
||||
message:
|
||||
'Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you.',
|
||||
title: _(msg`Block these accounts?`),
|
||||
message: _(
|
||||
msg`Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you.`,
|
||||
),
|
||||
confirmBtnText: 'Block this List',
|
||||
async onPressConfirm() {
|
||||
try {
|
||||
|
@ -320,7 +322,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
closeModal()
|
||||
},
|
||||
})
|
||||
}, [openModal, closeModal, list, listBlockMutation])
|
||||
}, [openModal, closeModal, list, listBlockMutation, _])
|
||||
|
||||
const onUnsubscribeBlock = useCallback(async () => {
|
||||
try {
|
||||
|
@ -343,8 +345,8 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
const onPressDelete = useCallback(() => {
|
||||
openModal({
|
||||
name: 'confirm',
|
||||
title: 'Delete List',
|
||||
message: 'Are you sure?',
|
||||
title: _(msg`Delete List`),
|
||||
message: _(msg`Are you sure?`),
|
||||
async onPressConfirm() {
|
||||
await listDeleteMutation.mutateAsync({uri: list.uri})
|
||||
Toast.show('List deleted')
|
||||
|
@ -355,7 +357,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
}
|
||||
},
|
||||
})
|
||||
}, [openModal, list, listDeleteMutation, navigation])
|
||||
}, [openModal, list, listDeleteMutation, navigation, _])
|
||||
|
||||
const onPressReport = useCallback(() => {
|
||||
openModal({
|
||||
|
@ -374,7 +376,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
let items: DropdownItem[] = [
|
||||
{
|
||||
testID: 'listHeaderDropdownShareBtn',
|
||||
label: 'Share',
|
||||
label: _(msg`Share`),
|
||||
onPress: onPressShare,
|
||||
icon: {
|
||||
ios: {
|
||||
|
@ -389,7 +391,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
items.push({label: 'separator'})
|
||||
items.push({
|
||||
testID: 'listHeaderDropdownEditBtn',
|
||||
label: 'Edit List Details',
|
||||
label: _(msg`Edit list details`),
|
||||
onPress: onPressEdit,
|
||||
icon: {
|
||||
ios: {
|
||||
|
@ -401,7 +403,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
})
|
||||
items.push({
|
||||
testID: 'listHeaderDropdownDeleteBtn',
|
||||
label: 'Delete List',
|
||||
label: _(msg`Delete List`),
|
||||
onPress: onPressDelete,
|
||||
icon: {
|
||||
ios: {
|
||||
|
@ -415,7 +417,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
items.push({label: 'separator'})
|
||||
items.push({
|
||||
testID: 'listHeaderDropdownReportBtn',
|
||||
label: 'Report List',
|
||||
label: _(msg`Report List`),
|
||||
onPress: onPressReport,
|
||||
icon: {
|
||||
ios: {
|
||||
|
@ -427,13 +429,13 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
})
|
||||
}
|
||||
return items
|
||||
}, [isOwner, onPressShare, onPressEdit, onPressDelete, onPressReport])
|
||||
}, [isOwner, onPressShare, onPressEdit, onPressDelete, onPressReport, _])
|
||||
|
||||
const subscribeDropdownItems: DropdownItem[] = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
testID: 'subscribeDropdownMuteBtn',
|
||||
label: 'Mute accounts',
|
||||
label: _(msg`Mute accounts`),
|
||||
onPress: onSubscribeMute,
|
||||
icon: {
|
||||
ios: {
|
||||
|
@ -445,7 +447,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
},
|
||||
{
|
||||
testID: 'subscribeDropdownBlockBtn',
|
||||
label: 'Block accounts',
|
||||
label: _(msg`Block accounts`),
|
||||
onPress: onSubscribeBlock,
|
||||
icon: {
|
||||
ios: {
|
||||
|
@ -456,7 +458,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
},
|
||||
},
|
||||
]
|
||||
}, [onSubscribeMute, onSubscribeBlock])
|
||||
}, [onSubscribeMute, onSubscribeBlock, _])
|
||||
|
||||
return (
|
||||
<ProfileSubpageHeader
|
||||
|
|
|
@ -9,7 +9,6 @@ import {
|
|||
import {useFocusEffect} from '@react-navigation/native'
|
||||
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {track} from '#/lib/analytics/analytics'
|
||||
import {useAnalytics} from 'lib/analytics/analytics'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
|
@ -27,6 +26,8 @@ import {Haptics} from 'lib/haptics'
|
|||
import {TextLink} from 'view/com/util/Link'
|
||||
import {logger} from '#/logger'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {
|
||||
usePreferencesQuery,
|
||||
usePinFeedMutation,
|
||||
|
@ -52,6 +53,7 @@ const HITSLOP_BOTTOM = {
|
|||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'SavedFeeds'>
|
||||
export const SavedFeeds = withAuthRequired(function SavedFeedsImpl({}: Props) {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const {isMobile, isTabletOrDesktop} = useWebMediaQueries()
|
||||
const {screen} = useAnalytics()
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
|
@ -71,11 +73,11 @@ export const SavedFeeds = withAuthRequired(function SavedFeedsImpl({}: Props) {
|
|||
pal.border,
|
||||
isTabletOrDesktop && styles.desktopContainer,
|
||||
]}>
|
||||
<ViewHeader title="Edit My Feeds" showOnDesktop showBorder />
|
||||
<ViewHeader title={_(msg`Edit My Feeds`)} showOnDesktop showBorder />
|
||||
<ScrollView style={s.flex1}>
|
||||
<View style={[pal.text, pal.border, styles.title]}>
|
||||
<Text type="title" style={pal.text}>
|
||||
Pinned Feeds
|
||||
<Trans>Pinned Feeds</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
{preferences?.feeds ? (
|
||||
|
@ -88,7 +90,7 @@ export const SavedFeeds = withAuthRequired(function SavedFeedsImpl({}: Props) {
|
|||
styles.empty,
|
||||
]}>
|
||||
<Text type="lg" style={[pal.text]}>
|
||||
You don't have any pinned feeds.
|
||||
<Trans>You don't have any pinned feeds.</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
|
@ -101,7 +103,7 @@ export const SavedFeeds = withAuthRequired(function SavedFeedsImpl({}: Props) {
|
|||
)}
|
||||
<View style={[pal.text, pal.border, styles.title]}>
|
||||
<Text type="title" style={pal.text}>
|
||||
Saved Feeds
|
||||
<Trans>Saved Feeds</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
{preferences?.feeds ? (
|
||||
|
@ -114,7 +116,7 @@ export const SavedFeeds = withAuthRequired(function SavedFeedsImpl({}: Props) {
|
|||
styles.empty,
|
||||
]}>
|
||||
<Text type="lg" style={[pal.text]}>
|
||||
You don't have any saved feeds.
|
||||
<Trans>You don't have any saved feeds.</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
|
@ -128,15 +130,17 @@ export const SavedFeeds = withAuthRequired(function SavedFeedsImpl({}: Props) {
|
|||
|
||||
<View style={styles.footerText}>
|
||||
<Text type="sm" style={pal.textLight}>
|
||||
Feeds are custom algorithms that users build with a little coding
|
||||
expertise.{' '}
|
||||
<TextLink
|
||||
type="sm"
|
||||
style={pal.link}
|
||||
href="https://github.com/bluesky-social/feed-generator"
|
||||
text="See this guide"
|
||||
/>{' '}
|
||||
for more information.
|
||||
<Trans>
|
||||
Feeds are custom algorithms that users build with a little coding
|
||||
expertise.{' '}
|
||||
<TextLink
|
||||
type="sm"
|
||||
style={pal.link}
|
||||
href="https://github.com/bluesky-social/feed-generator"
|
||||
text="See this guide"
|
||||
/>{' '}
|
||||
for more information.
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{height: 100}} />
|
||||
|
|
|
@ -222,10 +222,10 @@ function SearchScreenPostResults({query}: {query: string}) {
|
|||
return results?.pages.flatMap(page => page.posts) || []
|
||||
}, [results])
|
||||
const items = React.useMemo(() => {
|
||||
let items: SearchResultSlice[] = []
|
||||
let temp: SearchResultSlice[] = []
|
||||
|
||||
for (const post of posts) {
|
||||
items.push({
|
||||
temp.push({
|
||||
type: 'post',
|
||||
key: post.uri,
|
||||
post,
|
||||
|
@ -233,13 +233,13 @@ function SearchScreenPostResults({query}: {query: string}) {
|
|||
}
|
||||
|
||||
if (isFetchingNextPage) {
|
||||
items.push({
|
||||
temp.push({
|
||||
type: 'loadingMore',
|
||||
key: 'loadingMore',
|
||||
})
|
||||
}
|
||||
|
||||
return items
|
||||
return temp
|
||||
}, [posts, isFetchingNextPage])
|
||||
|
||||
return error ? (
|
||||
|
@ -299,9 +299,9 @@ function SearchScreenUserResults({query}: {query: string}) {
|
|||
|
||||
React.useEffect(() => {
|
||||
async function getResults() {
|
||||
const results = await search({query, limit: 30})
|
||||
const searchResults = await search({query, limit: 30})
|
||||
|
||||
if (results) {
|
||||
if (searchResults) {
|
||||
setDataUpdatedAt(Date.now())
|
||||
setResults(results)
|
||||
setIsFetched(true)
|
||||
|
@ -314,7 +314,7 @@ function SearchScreenUserResults({query}: {query: string}) {
|
|||
setResults([])
|
||||
setIsFetched(false)
|
||||
}
|
||||
}, [query, setDataUpdatedAt, search])
|
||||
}, [query, setDataUpdatedAt, search, results])
|
||||
|
||||
return isFetched ? (
|
||||
<>
|
||||
|
|
|
@ -268,7 +268,7 @@ export const SettingsScreen = withAuthRequired(function Settings({}: Props) {
|
|||
|
||||
return (
|
||||
<View style={[s.hContentRegion]} testID="settingsScreen">
|
||||
<ViewHeader title="Settings" />
|
||||
<ViewHeader title={_(msg`Settings`)} />
|
||||
<ScrollView
|
||||
style={[s.hContentRegion]}
|
||||
contentContainerStyle={isMobile && pal.viewLight}
|
||||
|
@ -281,7 +281,7 @@ export const SettingsScreen = withAuthRequired(function Settings({}: Props) {
|
|||
</Text>
|
||||
<View style={[styles.infoLine]}>
|
||||
<Text type="lg-medium" style={pal.text}>
|
||||
Email:{' '}
|
||||
<Trans>Email:</Trans>{' '}
|
||||
</Text>
|
||||
{currentAccount.emailConfirmed && (
|
||||
<>
|
||||
|
|
|
@ -10,11 +10,14 @@ import {usePalette} from 'lib/hooks/usePalette'
|
|||
import {s} from 'lib/styles'
|
||||
import {HELP_DESK_URL} from 'lib/constants'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Support'>
|
||||
export const SupportScreen = (_props: Props) => {
|
||||
const pal = usePalette('default')
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const {_} = useLingui()
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
|
@ -24,19 +27,21 @@ export const SupportScreen = (_props: Props) => {
|
|||
|
||||
return (
|
||||
<View>
|
||||
<ViewHeader title="Support" />
|
||||
<ViewHeader title={_(msg`Support`)} />
|
||||
<CenteredView>
|
||||
<Text type="title-xl" style={[pal.text, s.p20, s.pb5]}>
|
||||
Support
|
||||
<Trans>Support</Trans>
|
||||
</Text>
|
||||
<Text style={[pal.text, s.p20]}>
|
||||
The support form has been moved. If you need help, please
|
||||
<TextLink
|
||||
href={HELP_DESK_URL}
|
||||
text=" click here"
|
||||
style={pal.link}
|
||||
/>{' '}
|
||||
or visit {HELP_DESK_URL} to get in touch with us.
|
||||
<Trans>
|
||||
The support form has been moved. If you need help, please
|
||||
<TextLink
|
||||
href={HELP_DESK_URL}
|
||||
text=" click here"
|
||||
style={pal.link}
|
||||
/>{' '}
|
||||
or visit {HELP_DESK_URL} to get in touch with us.
|
||||
</Trans>
|
||||
</Text>
|
||||
</CenteredView>
|
||||
</View>
|
||||
|
|
|
@ -9,11 +9,14 @@ import {ScrollView} from 'view/com/util/Views'
|
|||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {s} from 'lib/styles'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'TermsOfService'>
|
||||
export const TermsOfServiceScreen = (_props: Props) => {
|
||||
const pal = usePalette('default')
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const {_} = useLingui()
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
|
@ -23,11 +26,11 @@ export const TermsOfServiceScreen = (_props: Props) => {
|
|||
|
||||
return (
|
||||
<View>
|
||||
<ViewHeader title="Terms of Service" />
|
||||
<ViewHeader title={_(msg`Terms of Service`)} />
|
||||
<ScrollView style={[s.hContentRegion, pal.view]}>
|
||||
<View style={[s.p20]}>
|
||||
<Text style={pal.text}>
|
||||
The Terms of Service have been moved to{' '}
|
||||
<Trans>The Terms of Service have been moved to</Trans>{' '}
|
||||
<TextLink
|
||||
style={pal.link}
|
||||
href="https://blueskyweb.xyz/support/tos"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue