Native translation expo module (#4098)

* translation expo module

* add `onClose` and `onReplacementAction`

* rm onReplacementAction

* make all props published

* make translation api available globally w/o wrapper (#4110)

* conditionally import the translation module

* only use native translation if language is probably supported

* open native translation via dropdown menu

---------

Co-authored-by: Hailey <me@haileyok.com>
Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
This commit is contained in:
Samuel Newman 2024-05-29 07:08:46 +03:00 committed by GitHub
parent a60f9933d8
commit b59c8e22af
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 232 additions and 8 deletions

View file

@ -30,6 +30,11 @@ import {useSession} from 'state/session'
import {PostThreadFollowBtn} from 'view/com/post-thread/PostThreadFollowBtn'
import {atoms as a} from '#/alf'
import {RichText} from '#/components/RichText'
import {
isAvailable as isNativeTranslationAvailable,
isLanguageSupported,
NativeTranslationModule,
} from '../../../../modules/expo-bluesky-translate'
import {ContentHider} from '../../../components/moderation/ContentHider'
import {LabelsOnMyPost} from '../../../components/moderation/LabelsOnMe'
import {PostAlerts} from '../../../components/moderation/PostAlerts'
@ -317,6 +322,7 @@ let PostThreadItemLoaded = ({
</ContentHider>
<ExpandedPostDetails
post={post}
record={record}
translatorUrl={translatorUrl}
needsTranslation={needsTranslation}
/>
@ -620,26 +626,39 @@ function PostOuterWrapper({
function ExpandedPostDetails({
post,
record,
needsTranslation,
translatorUrl,
}: {
post: AppBskyFeedDefs.PostView
record?: AppBskyFeedPost.Record
needsTranslation: boolean
translatorUrl: string
}) {
const pal = usePalette('default')
const {_} = useLingui()
const openLink = useOpenLink()
const onTranslatePress = React.useCallback(
() => openLink(translatorUrl),
[openLink, translatorUrl],
)
const text = record?.text || ''
const onTranslatePress = React.useCallback(() => {
if (
isNativeTranslationAvailable &&
isLanguageSupported(record?.langs?.at(0))
) {
NativeTranslationModule.presentAsync(text)
} else {
openLink(translatorUrl)
}
}, [openLink, text, translatorUrl, record])
return (
<View style={[s.flexRow, s.mt2, s.mb10]}>
<Text style={pal.textLight}>{niceDate(post.indexedAt)}</Text>
{needsTranslation && (
<>
<Text style={pal.textLight}> &middot; </Text>
<Text
style={pal.link}
title={_(msg`Translate`)}

View file

@ -50,6 +50,11 @@ import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/War
import * as Menu from '#/components/Menu'
import * as Prompt from '#/components/Prompt'
import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog'
import {
isAvailable as isNativeTranslationAvailable,
isLanguageSupported,
NativeTranslationModule,
} from '../../../../../modules/expo-bluesky-translate'
import {EventStopper} from '../EventStopper'
import * as Toast from '../Toast'
@ -172,9 +177,17 @@ let PostDropdownBtn = ({
Toast.show(_(msg`Copied to clipboard`))
}, [_, richText])
const onOpenTranslate = React.useCallback(() => {
openLink(translatorUrl)
}, [openLink, translatorUrl])
const onPressTranslate = React.useCallback(() => {
if (
isNativeTranslationAvailable &&
isLanguageSupported(record?.langs?.at(0))
) {
const text = richTextToString(richText, true)
NativeTranslationModule.presentAsync(text)
} else {
openLink(translatorUrl)
}
}, [openLink, record?.langs, richText, translatorUrl])
const onHidePost = React.useCallback(() => {
hidePost({uri: postUri})
@ -246,7 +259,7 @@ let PostDropdownBtn = ({
<Menu.Item
testID="postDropdownTranslateBtn"
label={_(msg`Translate`)}
onPress={onOpenTranslate}>
onPress={onPressTranslate}>
<Menu.ItemText>{_(msg`Translate`)}</Menu.ItemText>
<Menu.ItemIcon icon={Translate} position="right" />
</Menu.Item>

View file

@ -33,6 +33,7 @@ import {ErrorBoundary} from 'view/com/util/ErrorBoundary'
import {MutedWordsDialog} from '#/components/dialogs/MutedWords'
import {SigninDialog} from '#/components/dialogs/Signin'
import {Outlet as PortalOutlet} from '#/components/Portal'
import {NativeTranslationView} from '../../../modules/expo-bluesky-translate'
import {RoutesContainer, TabsNavigator} from '../../Navigation'
import {Composer} from './Composer'
import {DrawerContent} from './Drawer'
@ -93,6 +94,7 @@ function ShellInner() {
</Drawer>
</ErrorBoundary>
</Animated.View>
<NativeTranslationView />
<Composer winHeight={winDim.height} />
<ModalsContainer />
<MutedWordsDialog />