about summary refs log tree commit diff
path: root/src/view/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com')
-rw-r--r--src/view/com/auth/onboarding/RecommendedFeeds.tsx79
-rw-r--r--src/view/com/auth/onboarding/RecommendedFollows.tsx71
-rw-r--r--src/view/com/auth/onboarding/WelcomeMobile.tsx8
-rw-r--r--src/view/com/composer/Composer.tsx8
-rw-r--r--src/view/com/feeds/FeedSourceCard.tsx9
-rw-r--r--src/view/com/modals/SwitchAccount.tsx2
-rw-r--r--src/view/com/notifications/FeedItem.tsx3
-rw-r--r--src/view/com/post-thread/PostThread.tsx2
-rw-r--r--src/view/com/post-thread/PostThreadItem.tsx6
-rw-r--r--src/view/com/posts/FeedErrorMessage.tsx9
-rw-r--r--src/view/com/profile/ProfileHeader.tsx33
-rw-r--r--src/view/com/util/AccountDropdownBtn.tsx2
-rw-r--r--src/view/com/util/ErrorBoundary.tsx5
-rw-r--r--src/view/com/util/TimeElapsed.tsx1
-rw-r--r--src/view/com/util/UserAvatar.tsx7
-rw-r--r--src/view/com/util/UserBanner.tsx7
-rw-r--r--src/view/com/util/forms/PostDropdownBtn.tsx19
-rw-r--r--src/view/com/util/post-ctrls/RepostButton.web.tsx4
18 files changed, 158 insertions, 117 deletions
diff --git a/src/view/com/auth/onboarding/RecommendedFeeds.tsx b/src/view/com/auth/onboarding/RecommendedFeeds.tsx
index 941671bf8..d3318bffd 100644
--- a/src/view/com/auth/onboarding/RecommendedFeeds.tsx
+++ b/src/view/com/auth/onboarding/RecommendedFeeds.tsx
@@ -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}
diff --git a/src/view/com/auth/onboarding/RecommendedFollows.tsx b/src/view/com/auth/onboarding/RecommendedFollows.tsx
index c327a7168..7bf8c97e4 100644
--- a/src/view/com/auth/onboarding/RecommendedFollows.tsx
+++ b/src/view/com/auth/onboarding/RecommendedFollows.tsx
@@ -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}
diff --git a/src/view/com/auth/onboarding/WelcomeMobile.tsx b/src/view/com/auth/onboarding/WelcomeMobile.tsx
index 2717bff3f..5de1a7817 100644
--- a/src/view/com/auth/onboarding/WelcomeMobile.tsx
+++ b/src/view/com/auth/onboarding/WelcomeMobile.tsx
@@ -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]}>
diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx
index 50728cba8..6f058d39e 100644
--- a/src/view/com/composer/Composer.tsx
+++ b/src/view/com/composer/Composer.tsx
@@ -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) {
diff --git a/src/view/com/feeds/FeedSourceCard.tsx b/src/view/com/feeds/FeedSourceCard.tsx
index 4e461e4f6..d8b67767b 100644
--- a/src/view/com/feeds/FeedSourceCard.tsx
+++ b/src/view/com/feeds/FeedSourceCard.tsx
@@ -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
 
diff --git a/src/view/com/modals/SwitchAccount.tsx b/src/view/com/modals/SwitchAccount.tsx
index 3481b861c..dab0127cc 100644
--- a/src/view/com/modals/SwitchAccount.tsx
+++ b/src/view/com/modals/SwitchAccount.tsx
@@ -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>
diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx
index 94fe7ff2d..75d44a2fc 100644
--- a/src/view/com/notifications/FeedItem.tsx
+++ b/src/view/com/notifications/FeedItem.tsx
@@ -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)}{' '}
diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx
index b5347fc84..1c9f2c16f 100644
--- a/src/view/com/post-thread/PostThread.tsx
+++ b/src/view/com/post-thread/PostThread.tsx
@@ -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}>
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx
index f66c01d85..a4534b887 100644
--- a/src/view/com/post-thread/PostThreadItem.tsx
+++ b/src/view/com/post-thread/PostThreadItem.tsx
@@ -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>
diff --git a/src/view/com/posts/FeedErrorMessage.tsx b/src/view/com/posts/FeedErrorMessage.tsx
index 0ace06e9a..5a9290f66 100644
--- a/src/view/com/posts/FeedErrorMessage.tsx
+++ b/src/view/com/posts/FeedErrorMessage.tsx
@@ -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
diff --git a/src/view/com/profile/ProfileHeader.tsx b/src/view/com/profile/ProfileHeader.tsx
index ab6667816..45998406c 100644
--- a/src/view/com/profile/ProfileHeader.tsx
+++ b/src/view/com/profile/ProfileHeader.tsx
@@ -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 =
diff --git a/src/view/com/util/AccountDropdownBtn.tsx b/src/view/com/util/AccountDropdownBtn.tsx
index 96ce678ff..76d493886 100644
--- a/src/view/com/util/AccountDropdownBtn.tsx
+++ b/src/view/com/util/AccountDropdownBtn.tsx
@@ -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')
diff --git a/src/view/com/util/ErrorBoundary.tsx b/src/view/com/util/ErrorBoundary.tsx
index 529435cf1..397588cfb 100644
--- a/src/view/com/util/ErrorBoundary.tsx
+++ b/src/view/com/util/ErrorBoundary.tsx
@@ -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>
diff --git a/src/view/com/util/TimeElapsed.tsx b/src/view/com/util/TimeElapsed.tsx
index dad46448c..aa3a09223 100644
--- a/src/view/com/util/TimeElapsed.tsx
+++ b/src/view/com/util/TimeElapsed.tsx
@@ -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,
diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx
index 0ad2c23e7..2012f5828 100644
--- a/src/view/com/util/UserAvatar.tsx
+++ b/src/view/com/util/UserAvatar.tsx
@@ -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,
+      _,
     ],
   )
 
diff --git a/src/view/com/util/UserBanner.tsx b/src/view/com/util/UserBanner.tsx
index 2b7915527..b31d7e551 100644
--- a/src/view/com/util/UserBanner.tsx
+++ b/src/view/com/util/UserBanner.tsx
@@ -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,
+      _,
     ],
   )
 
diff --git a/src/view/com/util/forms/PostDropdownBtn.tsx b/src/view/com/util/forms/PostDropdownBtn.tsx
index 90a165ce7..889839d07 100644
--- a/src/view/com/util/forms/PostDropdownBtn.tsx
+++ b/src/view/com/util/forms/PostDropdownBtn.tsx
@@ -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,
         })
       },
diff --git a/src/view/com/util/post-ctrls/RepostButton.web.tsx b/src/view/com/util/post-ctrls/RepostButton.web.tsx
index 70f7229d4..6c5f816aa 100644
--- a/src/view/com/util/post-ctrls/RepostButton.web.tsx
+++ b/src/view/com/util/post-ctrls/RepostButton.web.tsx
@@ -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'},