add on-device translation to post feed item
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
import {useMemo} from 'react'
|
||||
import {Platform, View} from 'react-native'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {HITSLOP_30} from '#/lib/constants'
|
||||
import {codeToLanguageName, languageName} from '#/locale/helpers'
|
||||
import {LANGUAGES} from '#/locale/languages'
|
||||
import {useLanguagePrefs} from '#/state/preferences'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {atoms as a, native, useTheme} from '#/alf'
|
||||
import {Button} from '#/components/Button'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import * as Select from '#/components/Select'
|
||||
import {Text} from '#/components/Typography'
|
||||
@@ -16,24 +17,43 @@ import {useTranslateOnDevice} from '#/translation'
|
||||
|
||||
export function TranslatedPost({
|
||||
postText,
|
||||
hideLoading = false,
|
||||
standalone = false,
|
||||
}: {
|
||||
postText: string
|
||||
hideLoading: boolean
|
||||
/**
|
||||
* Hides the loading state, and adds its own "hide translation button"
|
||||
*/
|
||||
standalone?: boolean
|
||||
}) {
|
||||
const {translationState} = useTranslateOnDevice()
|
||||
const {translationState, clearTranslation} = useTranslateOnDevice()
|
||||
const {t: l} = useLingui()
|
||||
const t = useTheme()
|
||||
|
||||
if (translationState.status === 'loading' && !hideLoading) {
|
||||
if (translationState.status === 'loading' && standalone) {
|
||||
return <TranslationLoading />
|
||||
}
|
||||
|
||||
if (translationState.status === 'success') {
|
||||
return (
|
||||
<TranslationResult
|
||||
postText={postText}
|
||||
sourceLanguage={translationState.sourceLanguage}
|
||||
translatedText={translationState.translatedText}
|
||||
/>
|
||||
<>
|
||||
<TranslationResult
|
||||
postText={postText}
|
||||
sourceLanguage={translationState.sourceLanguage}
|
||||
translatedText={translationState.translatedText}
|
||||
/>
|
||||
{standalone && (
|
||||
<Button
|
||||
label={l`Hide translation`}
|
||||
onPress={clearTranslation}
|
||||
style={[a.self_start, a.mt_sm]}
|
||||
hoverStyle={native({opacity: 0.5})}
|
||||
hitSlop={HITSLOP_30}>
|
||||
<Text style={[a.text_sm, {color: t.palette.primary_500}]}>
|
||||
<Trans>Hide translation</Trans>
|
||||
</Text>
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -45,7 +65,7 @@ function TranslationLoading() {
|
||||
|
||||
return (
|
||||
<View style={[a.flex_row, a.align_center, a.gap_sm, a.py_xs]}>
|
||||
<Loader size="sm" />
|
||||
<Loader size="xs" />
|
||||
<Text style={[a.text_sm, t.atoms.text_contrast_medium]}>
|
||||
<Trans>Translating…</Trans>
|
||||
</Text>
|
||||
|
||||
@@ -420,7 +420,7 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
|
||||
shouldProxyLinks={true}
|
||||
/>
|
||||
) : undefined}
|
||||
<TranslatedPost postText={record.text} hideLoading />
|
||||
<TranslatedPost postText={record.text} />
|
||||
<TranslateLink post={item.value.post} />
|
||||
{post.embed && (
|
||||
<View style={[a.py_xs]}>
|
||||
@@ -617,7 +617,7 @@ function TranslateLink({
|
||||
)
|
||||
|
||||
return (
|
||||
needsTranslation && (
|
||||
(needsTranslation || translationState.status !== 'idle') && (
|
||||
<View style={[a.gap_md, a.pt_md, a.align_start]}>
|
||||
{translationState.status === 'loading' ? (
|
||||
<View style={[a.flex_row, a.align_center, a.gap_xs]}>
|
||||
|
||||
@@ -42,12 +42,14 @@ import {Embed} from '#/components/Post/Embed'
|
||||
import {PostEmbedViewContext} from '#/components/Post/Embed/types'
|
||||
import {PostRepliedTo} from '#/components/Post/PostRepliedTo'
|
||||
import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton'
|
||||
import {TranslatedPost} from '#/components/Post/Translated'
|
||||
import {PostControls} from '#/components/PostControls'
|
||||
import {DiscoverDebug} from '#/components/PostControls/DiscoverDebug'
|
||||
import {RichText} from '#/components/RichText'
|
||||
import {SubtleHover} from '#/components/SubtleHover'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {useActorStatus} from '#/features/liveNow'
|
||||
import {Provider as OnDeviceTranslationProvider} from '#/translation'
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {PostFeedReason} from './PostFeedReason'
|
||||
|
||||
@@ -108,27 +110,29 @@ export function PostFeedItem({
|
||||
}
|
||||
if (richText && moderation) {
|
||||
return (
|
||||
<FeedItemInner
|
||||
// Safeguard from clobbering per-post state below:
|
||||
key={postShadowed.uri}
|
||||
post={postShadowed}
|
||||
record={record}
|
||||
reason={reason}
|
||||
feedContext={feedContext}
|
||||
reqId={reqId}
|
||||
richText={richText}
|
||||
parentAuthor={parentAuthor}
|
||||
showReplyTo={showReplyTo}
|
||||
moderation={moderation}
|
||||
isThreadChild={isThreadChild}
|
||||
isThreadLastChild={isThreadLastChild}
|
||||
isThreadParent={isThreadParent}
|
||||
hideTopBorder={hideTopBorder}
|
||||
isParentBlocked={isParentBlocked}
|
||||
isParentNotFound={isParentNotFound}
|
||||
rootPost={rootPost}
|
||||
onShowLess={onShowLess}
|
||||
/>
|
||||
<OnDeviceTranslationProvider>
|
||||
<FeedItemInner
|
||||
// Safeguard from clobbering per-post state below:
|
||||
key={postShadowed.uri}
|
||||
post={postShadowed}
|
||||
record={record}
|
||||
reason={reason}
|
||||
feedContext={feedContext}
|
||||
reqId={reqId}
|
||||
richText={richText}
|
||||
parentAuthor={parentAuthor}
|
||||
showReplyTo={showReplyTo}
|
||||
moderation={moderation}
|
||||
isThreadChild={isThreadChild}
|
||||
isThreadLastChild={isThreadLastChild}
|
||||
isThreadParent={isThreadParent}
|
||||
hideTopBorder={hideTopBorder}
|
||||
isParentBlocked={isParentBlocked}
|
||||
isParentNotFound={isParentNotFound}
|
||||
rootPost={rootPost}
|
||||
onShowLess={onShowLess}
|
||||
/>
|
||||
</OnDeviceTranslationProvider>
|
||||
)
|
||||
}
|
||||
return null
|
||||
@@ -479,6 +483,7 @@ let PostContent = ({
|
||||
{limitLines && (
|
||||
<ShowMoreTextButton style={[a.text_md]} onPress={onPressShowMore} />
|
||||
)}
|
||||
<TranslatedPost postText={richText.text} standalone />
|
||||
</View>
|
||||
) : undefined}
|
||||
{postEmbed ? (
|
||||
|
||||
Reference in New Issue
Block a user