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
|
@ -10,6 +10,8 @@ import {RecommendedFeedsItem} from './RecommendedFeedsItem'
|
|||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {ErrorMessage} from 'view/com/util/error/ErrorMessage'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useSuggestedFeedsQuery} from '#/state/queries/suggested-feeds'
|
||||
|
||||
type Props = {
|
||||
|
@ -17,40 +19,45 @@ type Props = {
|
|||
}
|
||||
export function RecommendedFeeds({next}: Props) {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const {isTabletOrMobile} = useWebMediaQueries()
|
||||
const {isLoading, data} = useSuggestedFeedsQuery()
|
||||
|
||||
const hasFeeds = data && data?.pages?.[0]?.feeds?.length
|
||||
const hasFeeds = data && data.pages[0].feeds.length
|
||||
|
||||
const title = (
|
||||
<>
|
||||
<Text
|
||||
style={[
|
||||
pal.textLight,
|
||||
tdStyles.title1,
|
||||
isTabletOrMobile && tdStyles.title1Small,
|
||||
]}>
|
||||
Choose your
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
pal.link,
|
||||
tdStyles.title2,
|
||||
isTabletOrMobile && tdStyles.title2Small,
|
||||
]}>
|
||||
Recommended
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
pal.link,
|
||||
tdStyles.title2,
|
||||
isTabletOrMobile && tdStyles.title2Small,
|
||||
]}>
|
||||
Feeds
|
||||
</Text>
|
||||
<Trans>
|
||||
<Text
|
||||
style={[
|
||||
pal.textLight,
|
||||
tdStyles.title1,
|
||||
isTabletOrMobile && tdStyles.title1Small,
|
||||
]}>
|
||||
Choose your
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
pal.link,
|
||||
tdStyles.title2,
|
||||
isTabletOrMobile && tdStyles.title2Small,
|
||||
]}>
|
||||
Recommended
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
pal.link,
|
||||
tdStyles.title2,
|
||||
isTabletOrMobile && tdStyles.title2Small,
|
||||
]}>
|
||||
Feeds
|
||||
</Text>
|
||||
</Trans>
|
||||
<Text type="2xl-medium" style={[pal.textLight, tdStyles.description]}>
|
||||
Feeds are created by users to curate content. Choose some feeds that you
|
||||
find interesting.
|
||||
<Trans>
|
||||
Feeds are created by users to curate content. Choose some feeds that
|
||||
you find interesting.
|
||||
</Trans>
|
||||
</Text>
|
||||
<View
|
||||
style={{
|
||||
|
@ -69,7 +76,7 @@ export function RecommendedFeeds({next}: Props) {
|
|||
<Text
|
||||
type="2xl-medium"
|
||||
style={{color: '#fff', position: 'relative', top: -1}}>
|
||||
Next
|
||||
<Trans>Next</Trans>
|
||||
</Text>
|
||||
<FontAwesomeIcon icon="angle-right" color="#fff" size={14} />
|
||||
</View>
|
||||
|
@ -99,20 +106,22 @@ export function RecommendedFeeds({next}: Props) {
|
|||
<ActivityIndicator size="large" />
|
||||
</View>
|
||||
) : (
|
||||
<ErrorMessage message="Failed to load recommended feeds" />
|
||||
<ErrorMessage message={_(msg`Failed to load recommended feeds`)} />
|
||||
)}
|
||||
</TitleColumnLayout>
|
||||
</TabletOrDesktop>
|
||||
<Mobile>
|
||||
<View style={[mStyles.container]} testID="recommendedFeedsOnboarding">
|
||||
<ViewHeader
|
||||
title="Recommended Feeds"
|
||||
title={_(msg`Recommended Feeds`)}
|
||||
showBackButton={false}
|
||||
showOnDesktop
|
||||
/>
|
||||
<Text type="lg-medium" style={[pal.text, mStyles.header]}>
|
||||
Check out some recommended feeds. Tap + to add them to your list of
|
||||
pinned feeds.
|
||||
<Trans>
|
||||
Check out some recommended feeds. Tap + to add them to your list
|
||||
of pinned feeds.
|
||||
</Trans>
|
||||
</Text>
|
||||
|
||||
{hasFeeds ? (
|
||||
|
@ -128,13 +137,15 @@ export function RecommendedFeeds({next}: Props) {
|
|||
</View>
|
||||
) : (
|
||||
<View style={{flex: 1}}>
|
||||
<ErrorMessage message="Failed to load recommended feeds" />
|
||||
<ErrorMessage
|
||||
message={_(msg`Failed to load recommended feeds`)}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<Button
|
||||
onPress={next}
|
||||
label="Continue"
|
||||
label={_(msg`Continue`)}
|
||||
testID="continueBtn"
|
||||
style={mStyles.button}
|
||||
labelStyle={mStyles.buttonText}
|
||||
|
|
|
@ -14,12 +14,15 @@ import {useSuggestedFollowsQuery} from '#/state/queries/suggested-follows'
|
|||
import {useGetSuggestedFollowersByActor} from '#/state/queries/suggested-follows'
|
||||
import {useModerationOpts} from '#/state/queries/preferences'
|
||||
import {logger} from '#/logger'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
type Props = {
|
||||
next: () => void
|
||||
}
|
||||
export function RecommendedFollows({next}: Props) {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const {isTabletOrMobile} = useWebMediaQueries()
|
||||
const {data: suggestedFollows, dataUpdatedAt} = useSuggestedFollowsQuery()
|
||||
const getSuggestedFollowsByActor = useGetSuggestedFollowersByActor()
|
||||
|
@ -31,33 +34,37 @@ export function RecommendedFollows({next}: Props) {
|
|||
|
||||
const title = (
|
||||
<>
|
||||
<Text
|
||||
style={[
|
||||
pal.textLight,
|
||||
tdStyles.title1,
|
||||
isTabletOrMobile && tdStyles.title1Small,
|
||||
]}>
|
||||
Follow some
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
pal.link,
|
||||
tdStyles.title2,
|
||||
isTabletOrMobile && tdStyles.title2Small,
|
||||
]}>
|
||||
Recommended
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
pal.link,
|
||||
tdStyles.title2,
|
||||
isTabletOrMobile && tdStyles.title2Small,
|
||||
]}>
|
||||
Users
|
||||
</Text>
|
||||
<Trans>
|
||||
<Text
|
||||
style={[
|
||||
pal.textLight,
|
||||
tdStyles.title1,
|
||||
isTabletOrMobile && tdStyles.title1Small,
|
||||
]}>
|
||||
Follow some
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
pal.link,
|
||||
tdStyles.title2,
|
||||
isTabletOrMobile && tdStyles.title2Small,
|
||||
]}>
|
||||
Recommended
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
pal.link,
|
||||
tdStyles.title2,
|
||||
isTabletOrMobile && tdStyles.title2Small,
|
||||
]}>
|
||||
Users
|
||||
</Text>
|
||||
</Trans>
|
||||
<Text type="2xl-medium" style={[pal.textLight, tdStyles.description]}>
|
||||
Follow some users to get started. We can recommend you more users based
|
||||
on who you find interesting.
|
||||
<Trans>
|
||||
Follow some users to get started. We can recommend you more users
|
||||
based on who you find interesting.
|
||||
</Trans>
|
||||
</Text>
|
||||
<View
|
||||
style={{
|
||||
|
@ -76,7 +83,7 @@ export function RecommendedFollows({next}: Props) {
|
|||
<Text
|
||||
type="2xl-medium"
|
||||
style={{color: '#fff', position: 'relative', top: -1}}>
|
||||
Done
|
||||
<Trans>Done</Trans>
|
||||
</Text>
|
||||
<FontAwesomeIcon icon="angle-right" color="#fff" size={14} />
|
||||
</View>
|
||||
|
@ -171,13 +178,15 @@ export function RecommendedFollows({next}: Props) {
|
|||
<View style={[mStyles.container]} testID="recommendedFollowsOnboarding">
|
||||
<View>
|
||||
<ViewHeader
|
||||
title="Recommended Follows"
|
||||
title={_(msg`Recommended Users`)}
|
||||
showBackButton={false}
|
||||
showOnDesktop
|
||||
/>
|
||||
<Text type="lg-medium" style={[pal.text, mStyles.header]}>
|
||||
Check out some recommended users. Follow them to see similar
|
||||
users.
|
||||
<Trans>
|
||||
Check out some recommended users. Follow them to see similar
|
||||
users.
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
{!suggestedFollows || !moderationOpts ? (
|
||||
|
@ -199,7 +208,7 @@ export function RecommendedFollows({next}: Props) {
|
|||
)}
|
||||
<Button
|
||||
onPress={next}
|
||||
label="Continue"
|
||||
label={_(msg`Continue`)}
|
||||
testID="continueBtn"
|
||||
style={mStyles.button}
|
||||
labelStyle={mStyles.buttonText}
|
||||
|
|
|
@ -43,10 +43,10 @@ export function WelcomeMobile({next, skip}: Props) {
|
|||
/>
|
||||
<View>
|
||||
<Text style={[pal.text, styles.title]}>
|
||||
Welcome to{' '}
|
||||
<Text style={[pal.text, pal.link, styles.title]}>
|
||||
<Trans>Bluesky</Trans>
|
||||
</Text>
|
||||
<Trans>
|
||||
Welcome to{' '}
|
||||
<Text style={[pal.text, pal.link, styles.title]}>Bluesky</Text>
|
||||
</Trans>
|
||||
</Text>
|
||||
<View style={styles.spacer} />
|
||||
<View style={[styles.row]}>
|
||||
|
|
|
@ -129,19 +129,19 @@ export const ComposePost = observer(function ComposePost({
|
|||
}
|
||||
openModal({
|
||||
name: 'confirm',
|
||||
title: 'Discard draft',
|
||||
title: _(msg`Discard draft`),
|
||||
onPressConfirm: onClose,
|
||||
onPressCancel: () => {
|
||||
closeModal()
|
||||
},
|
||||
message: "Are you sure you'd like to discard this draft?",
|
||||
confirmBtnText: 'Discard',
|
||||
message: _(msg`Are you sure you'd like to discard this draft?`),
|
||||
confirmBtnText: _(msg`Discard`),
|
||||
confirmBtnStyle: {backgroundColor: colors.red4},
|
||||
})
|
||||
} else {
|
||||
onClose()
|
||||
}
|
||||
}, [openModal, closeModal, activeModals, onClose, graphemeLength, gallery])
|
||||
}, [openModal, closeModal, activeModals, onClose, graphemeLength, gallery, _])
|
||||
// android back button
|
||||
useEffect(() => {
|
||||
if (!isAndroid) {
|
||||
|
|
|
@ -14,6 +14,8 @@ import * as Toast from 'view/com/util/Toast'
|
|||
import {sanitizeHandle} from 'lib/strings/handles'
|
||||
import {logger} from '#/logger'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {
|
||||
UsePreferencesQueryResponse,
|
||||
usePreferencesQuery,
|
||||
|
@ -68,6 +70,7 @@ export function FeedSourceCardLoaded({
|
|||
showLikes?: boolean
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const navigation = useNavigation<NavigationProp>()
|
||||
const {openModal} = useModalControls()
|
||||
|
||||
|
@ -85,8 +88,8 @@ export function FeedSourceCardLoaded({
|
|||
if (isSaved) {
|
||||
openModal({
|
||||
name: 'confirm',
|
||||
title: 'Remove from my feeds',
|
||||
message: `Remove ${feed?.displayName} from my feeds?`,
|
||||
title: _(msg`Remove from my feeds`),
|
||||
message: _(msg`Remove ${feed.displayName} from my feeds?`),
|
||||
onPressConfirm: async () => {
|
||||
try {
|
||||
await removeFeed({uri: feed.uri})
|
||||
|
@ -107,7 +110,7 @@ export function FeedSourceCardLoaded({
|
|||
logger.error('Failed to save feed', {error: e})
|
||||
}
|
||||
}
|
||||
}, [isSaved, openModal, feed, removeFeed, saveFeed])
|
||||
}, [isSaved, openModal, feed, removeFeed, saveFeed, _])
|
||||
|
||||
if (!feed || !preferences) return null
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ function SwitchAccountCard({account}: {account: SessionAccount}) {
|
|||
did: currentAccount.did,
|
||||
handle: currentAccount.handle,
|
||||
})}
|
||||
title="Your profile"
|
||||
title={_(msg`Your profile`)}
|
||||
noFeedback>
|
||||
{contents}
|
||||
</Link>
|
||||
|
|
|
@ -235,7 +235,8 @@ let FeedItem = ({
|
|||
{authors.length > 1 ? (
|
||||
<>
|
||||
<Text style={[pal.text, s.mr5, s.ml5]}>
|
||||
<Trans>and</Trans>
|
||||
{' '}
|
||||
<Trans>and</Trans>{' '}
|
||||
</Text>
|
||||
<Text style={[pal.text, s.bold]}>
|
||||
{formatCount(authors.length - 1)}{' '}
|
||||
|
|
|
@ -220,7 +220,7 @@ function PostThreadLoaded({
|
|||
const renderItem = React.useCallback(
|
||||
({item, index}: {item: YieldedItem; index: number}) => {
|
||||
if (item === TOP_COMPONENT) {
|
||||
return isTablet ? <ViewHeader title="Post" /> : null
|
||||
return isTablet ? <ViewHeader title={_(msg`Post`)} /> : null
|
||||
} else if (item === PARENT_SPINNER) {
|
||||
return (
|
||||
<View style={styles.parentSpinner}>
|
||||
|
|
|
@ -35,7 +35,8 @@ import {TimeElapsed} from 'view/com/util/TimeElapsed'
|
|||
import {makeProfileLink} from 'lib/routes/links'
|
||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {MAX_POST_LINES} from 'lib/constants'
|
||||
import {Trans} from '@lingui/macro'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useLanguagePrefs} from '#/state/preferences'
|
||||
import {useComposerControls} from '#/state/shell/composer'
|
||||
import {useModerationOpts} from '#/state/queries/preferences'
|
||||
|
@ -637,13 +638,14 @@ function ExpandedPostDetails({
|
|||
translatorUrl: string
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
return (
|
||||
<View style={[s.flexRow, s.mt2, s.mb10]}>
|
||||
<Text style={pal.textLight}>{niceDate(post.indexedAt)}</Text>
|
||||
{needsTranslation && (
|
||||
<>
|
||||
<Text style={[pal.textLight, s.ml5, s.mr5]}>•</Text>
|
||||
<Link href={translatorUrl} title="Translate">
|
||||
<Link href={translatorUrl} title={_(msg`Translate`)}>
|
||||
<Text style={pal.link}>
|
||||
<Trans>Translate</Trans>
|
||||
</Text>
|
||||
|
|
|
@ -10,6 +10,8 @@ import {useNavigation} from '@react-navigation/native'
|
|||
import {NavigationProp} from 'lib/routes/types'
|
||||
import {logger} from '#/logger'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {msg as msgLingui} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {FeedDescriptor} from '#/state/queries/post-feed'
|
||||
import {EmptyState} from '../util/EmptyState'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
|
@ -86,6 +88,7 @@ function FeedgenErrorMessage({
|
|||
knownError: KnownError
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const {_: _l} = useLingui()
|
||||
const navigation = useNavigation<NavigationProp>()
|
||||
const msg = MESSAGES[knownError]
|
||||
const [_, uri] = feedDesc.split('|')
|
||||
|
@ -100,8 +103,8 @@ function FeedgenErrorMessage({
|
|||
const onRemoveFeed = React.useCallback(async () => {
|
||||
openModal({
|
||||
name: 'confirm',
|
||||
title: 'Remove feed',
|
||||
message: 'Remove this feed from your saved feeds?',
|
||||
title: _l(msgLingui`Remove feed`),
|
||||
message: _l(msgLingui`Remove this feed from your saved feeds?`),
|
||||
async onPressConfirm() {
|
||||
try {
|
||||
await removeFeed({uri})
|
||||
|
@ -116,7 +119,7 @@ function FeedgenErrorMessage({
|
|||
closeModal()
|
||||
},
|
||||
})
|
||||
}, [openModal, closeModal, uri, removeFeed])
|
||||
}, [openModal, closeModal, uri, removeFeed, _l])
|
||||
|
||||
return (
|
||||
<View
|
||||
|
|
|
@ -236,9 +236,10 @@ let ProfileHeaderLoaded = ({
|
|||
track('ProfileHeader:BlockAccountButtonClicked')
|
||||
openModal({
|
||||
name: 'confirm',
|
||||
title: 'Block Account',
|
||||
message:
|
||||
'Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you.',
|
||||
title: _(msg`Block Account`),
|
||||
message: _(
|
||||
msg`Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you.`,
|
||||
),
|
||||
onPressConfirm: async () => {
|
||||
try {
|
||||
await queueBlock()
|
||||
|
@ -251,15 +252,16 @@ let ProfileHeaderLoaded = ({
|
|||
}
|
||||
},
|
||||
})
|
||||
}, [track, queueBlock, openModal])
|
||||
}, [track, queueBlock, openModal, _])
|
||||
|
||||
const onPressUnblockAccount = React.useCallback(async () => {
|
||||
track('ProfileHeader:UnblockAccountButtonClicked')
|
||||
openModal({
|
||||
name: 'confirm',
|
||||
title: 'Unblock Account',
|
||||
message:
|
||||
'The account will be able to interact with you after unblocking.',
|
||||
title: _(msg`Unblock Account`),
|
||||
message: _(
|
||||
msg`The account will be able to interact with you after unblocking.`,
|
||||
),
|
||||
onPressConfirm: async () => {
|
||||
try {
|
||||
await queueUnblock()
|
||||
|
@ -272,7 +274,7 @@ let ProfileHeaderLoaded = ({
|
|||
}
|
||||
},
|
||||
})
|
||||
}, [track, queueUnblock, openModal])
|
||||
}, [track, queueUnblock, openModal, _])
|
||||
|
||||
const onPressReportAccount = React.useCallback(() => {
|
||||
track('ProfileHeader:ReportAccountButtonClicked')
|
||||
|
@ -290,7 +292,7 @@ let ProfileHeaderLoaded = ({
|
|||
let items: DropdownItem[] = [
|
||||
{
|
||||
testID: 'profileHeaderDropdownShareBtn',
|
||||
label: 'Share',
|
||||
label: _(msg`Share`),
|
||||
onPress: onPressShare,
|
||||
icon: {
|
||||
ios: {
|
||||
|
@ -304,7 +306,7 @@ let ProfileHeaderLoaded = ({
|
|||
items.push({label: 'separator'})
|
||||
items.push({
|
||||
testID: 'profileHeaderDropdownListAddRemoveBtn',
|
||||
label: 'Add to Lists',
|
||||
label: _(msg`Add to Lists`),
|
||||
onPress: onPressAddRemoveLists,
|
||||
icon: {
|
||||
ios: {
|
||||
|
@ -318,7 +320,9 @@ let ProfileHeaderLoaded = ({
|
|||
if (!profile.viewer?.blocking) {
|
||||
items.push({
|
||||
testID: 'profileHeaderDropdownMuteBtn',
|
||||
label: profile.viewer?.muted ? 'Unmute Account' : 'Mute Account',
|
||||
label: profile.viewer?.muted
|
||||
? _(msg`Unmute Account`)
|
||||
: _(msg`Mute Account`),
|
||||
onPress: profile.viewer?.muted
|
||||
? onPressUnmuteAccount
|
||||
: onPressMuteAccount,
|
||||
|
@ -334,7 +338,9 @@ let ProfileHeaderLoaded = ({
|
|||
if (!profile.viewer?.blockingByList) {
|
||||
items.push({
|
||||
testID: 'profileHeaderDropdownBlockBtn',
|
||||
label: profile.viewer?.blocking ? 'Unblock Account' : 'Block Account',
|
||||
label: profile.viewer?.blocking
|
||||
? _(msg`Unblock Account`)
|
||||
: _(msg`Block Account`),
|
||||
onPress: profile.viewer?.blocking
|
||||
? onPressUnblockAccount
|
||||
: onPressBlockAccount,
|
||||
|
@ -349,7 +355,7 @@ let ProfileHeaderLoaded = ({
|
|||
}
|
||||
items.push({
|
||||
testID: 'profileHeaderDropdownReportBtn',
|
||||
label: 'Report Account',
|
||||
label: _(msg`Report Account`),
|
||||
onPress: onPressReportAccount,
|
||||
icon: {
|
||||
ios: {
|
||||
|
@ -373,6 +379,7 @@ let ProfileHeaderLoaded = ({
|
|||
onPressBlockAccount,
|
||||
onPressReportAccount,
|
||||
onPressAddRemoveLists,
|
||||
_,
|
||||
])
|
||||
|
||||
const blockHide =
|
||||
|
|
|
@ -19,7 +19,7 @@ export function AccountDropdownBtn({account}: {account: SessionAccount}) {
|
|||
|
||||
const items: DropdownItem[] = [
|
||||
{
|
||||
label: 'Remove account',
|
||||
label: _(msg`Remove account`),
|
||||
onPress: () => {
|
||||
removeAccount(account)
|
||||
Toast.show('Account removed from quick access')
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React, {Component, ErrorInfo, ReactNode} from 'react'
|
||||
import {ErrorScreen} from './error/ErrorScreen'
|
||||
import {CenteredView} from './Views'
|
||||
import {t} from '@lingui/macro'
|
||||
|
||||
interface Props {
|
||||
children?: ReactNode
|
||||
|
@ -30,8 +31,8 @@ export class ErrorBoundary extends Component<Props, State> {
|
|||
return (
|
||||
<CenteredView style={{height: '100%', flex: 1}}>
|
||||
<ErrorScreen
|
||||
title="Oh no!"
|
||||
message="There was an unexpected issue in the application. Please let us know if this happened to you!"
|
||||
title={t`Oh no!`}
|
||||
message={t`There was an unexpected issue in the application. Please let us know if this happened to you!`}
|
||||
details={this.state.error.toString()}
|
||||
/>
|
||||
</CenteredView>
|
||||
|
|
|
@ -3,7 +3,6 @@ import {ago} from 'lib/strings/time'
|
|||
import {useTickEveryMinute} from '#/state/shell'
|
||||
|
||||
// FIXME(dan): Figure out why the false positives
|
||||
/* eslint-disable react/prop-types */
|
||||
|
||||
export function TimeElapsed({
|
||||
timestamp,
|
||||
|
|
|
@ -208,7 +208,7 @@ export function EditableUserAvatar({
|
|||
[
|
||||
!isWeb && {
|
||||
testID: 'changeAvatarCameraBtn',
|
||||
label: 'Camera',
|
||||
label: _(msg`Camera`),
|
||||
icon: {
|
||||
ios: {
|
||||
name: 'camera',
|
||||
|
@ -232,7 +232,7 @@ export function EditableUserAvatar({
|
|||
},
|
||||
{
|
||||
testID: 'changeAvatarLibraryBtn',
|
||||
label: 'Library',
|
||||
label: _(msg`Library`),
|
||||
icon: {
|
||||
ios: {
|
||||
name: 'photo.on.rectangle.angled',
|
||||
|
@ -269,7 +269,7 @@ export function EditableUserAvatar({
|
|||
},
|
||||
!!avatar && {
|
||||
testID: 'changeAvatarRemoveBtn',
|
||||
label: 'Remove',
|
||||
label: _(msg`Remove`),
|
||||
icon: {
|
||||
ios: {
|
||||
name: 'trash',
|
||||
|
@ -287,6 +287,7 @@ export function EditableUserAvatar({
|
|||
onSelectNewAvatar,
|
||||
requestCameraAccessIfNeeded,
|
||||
requestPhotoAccessIfNeeded,
|
||||
_,
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ export function UserBanner({
|
|||
[
|
||||
!isWeb && {
|
||||
testID: 'changeBannerCameraBtn',
|
||||
label: 'Camera',
|
||||
label: _(msg`Camera`),
|
||||
icon: {
|
||||
ios: {
|
||||
name: 'camera',
|
||||
|
@ -57,7 +57,7 @@ export function UserBanner({
|
|||
},
|
||||
{
|
||||
testID: 'changeBannerLibraryBtn',
|
||||
label: 'Library',
|
||||
label: _(msg`Library`),
|
||||
icon: {
|
||||
ios: {
|
||||
name: 'photo.on.rectangle.angled',
|
||||
|
@ -86,7 +86,7 @@ export function UserBanner({
|
|||
},
|
||||
!!banner && {
|
||||
testID: 'changeBannerRemoveBtn',
|
||||
label: 'Remove',
|
||||
label: _(msg`Remove`),
|
||||
icon: {
|
||||
ios: {
|
||||
name: 'trash',
|
||||
|
@ -104,6 +104,7 @@ export function UserBanner({
|
|||
onSelectNewBanner,
|
||||
requestCameraAccessIfNeeded,
|
||||
requestPhotoAccessIfNeeded,
|
||||
_,
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ import {useMutedThreads, useToggleThreadMute} from '#/state/muted-threads'
|
|||
import {useLanguagePrefs} from '#/state/preferences'
|
||||
import {logger} from '#/logger'
|
||||
import {Shadow} from '#/state/cache/types'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useSession} from '#/state/session'
|
||||
|
||||
export function PostDropdownBtn({
|
||||
|
@ -35,6 +37,7 @@ export function PostDropdownBtn({
|
|||
}) {
|
||||
const {currentAccount} = useSession()
|
||||
const theme = useTheme()
|
||||
const {_} = useLingui()
|
||||
const defaultCtrlColor = theme.palette.default.postCtrl
|
||||
const {openModal} = useModalControls()
|
||||
const langPrefs = useLanguagePrefs()
|
||||
|
@ -91,7 +94,7 @@ export function PostDropdownBtn({
|
|||
|
||||
const dropdownItems: NativeDropdownItem[] = [
|
||||
{
|
||||
label: 'Translate',
|
||||
label: _(msg`Translate`),
|
||||
onPress() {
|
||||
onOpenTranslate()
|
||||
},
|
||||
|
@ -105,7 +108,7 @@ export function PostDropdownBtn({
|
|||
},
|
||||
},
|
||||
{
|
||||
label: 'Copy post text',
|
||||
label: _(msg`Copy post text`),
|
||||
onPress() {
|
||||
onCopyPostText()
|
||||
},
|
||||
|
@ -119,7 +122,7 @@ export function PostDropdownBtn({
|
|||
},
|
||||
},
|
||||
{
|
||||
label: 'Share',
|
||||
label: _(msg`Share`),
|
||||
onPress() {
|
||||
const url = toShareUrl(href)
|
||||
shareUrl(url)
|
||||
|
@ -137,7 +140,7 @@ export function PostDropdownBtn({
|
|||
label: 'separator',
|
||||
},
|
||||
{
|
||||
label: isThreadMuted ? 'Unmute thread' : 'Mute thread',
|
||||
label: isThreadMuted ? _(msg`Unmute thread`) : _(msg`Mute thread`),
|
||||
onPress() {
|
||||
onToggleThreadMute()
|
||||
},
|
||||
|
@ -154,7 +157,7 @@ export function PostDropdownBtn({
|
|||
label: 'separator',
|
||||
},
|
||||
!isAuthor && {
|
||||
label: 'Report post',
|
||||
label: _(msg`Report post`),
|
||||
onPress() {
|
||||
openModal({
|
||||
name: 'report',
|
||||
|
@ -175,12 +178,12 @@ export function PostDropdownBtn({
|
|||
label: 'separator',
|
||||
},
|
||||
isAuthor && {
|
||||
label: 'Delete post',
|
||||
label: _(msg`Delete post`),
|
||||
onPress() {
|
||||
openModal({
|
||||
name: 'confirm',
|
||||
title: 'Delete this post?',
|
||||
message: 'Are you sure? This can not be undone.',
|
||||
title: _(msg`Delete this post?`),
|
||||
message: _(msg`Are you sure? This cannot be undone.`),
|
||||
onPressConfirm: onDeletePost,
|
||||
})
|
||||
},
|
||||
|
|
|
@ -41,7 +41,7 @@ export const RepostButton = ({
|
|||
|
||||
const dropdownItems: NativeDropdownItem[] = [
|
||||
{
|
||||
label: isReposted ? 'Undo repost' : 'Repost',
|
||||
label: isReposted ? _(msg`Undo repost`) : _(msg`Repost`),
|
||||
testID: 'repostDropdownRepostBtn',
|
||||
icon: {
|
||||
ios: {name: 'repeat'},
|
||||
|
@ -51,7 +51,7 @@ export const RepostButton = ({
|
|||
onPress: onRepost,
|
||||
},
|
||||
{
|
||||
label: 'Quote post',
|
||||
label: _(msg`Quote post`),
|
||||
testID: 'repostDropdownQuoteBtn',
|
||||
icon: {
|
||||
ios: {name: 'quote.bubble'},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue