From 44a53ea66d633cc0cb7c3066a44718e0682e659b Mon Sep 17 00:00:00 2001 From: DS Boyce <260543580+ds-boyce@users.noreply.github.com> Date: Tue, 3 Mar 2026 14:47:10 -0800 Subject: [PATCH] Update presentation based on latest design --- src/components/Post/Translated/index.tsx | 198 +++++++++++++++--- .../components/ThreadItemAnchor.tsx | 2 +- src/view/com/post/Post.tsx | 5 +- src/view/com/posts/PostFeedItem.tsx | 4 +- 4 files changed, 170 insertions(+), 39 deletions(-) diff --git a/src/components/Post/Translated/index.tsx b/src/components/Post/Translated/index.tsx index 069f5e80d8..112a65eb59 100644 --- a/src/components/Post/Translated/index.tsx +++ b/src/components/Post/Translated/index.tsx @@ -1,28 +1,49 @@ -import {useMemo} from 'react' -import {Platform, View} from 'react-native' +import {useCallback, useMemo} from 'react' +import {type GestureResponderEvent, Platform, View} from 'react-native' +import {type AppBskyFeedDefs} from '@atproto/api' import {Trans, useLingui} from '@lingui/react/macro' import {HITSLOP_30} from '#/lib/constants' import {useTranslate} from '#/lib/translation' import {type TranslationFunction} from '#/lib/translation/types' -import {codeToLanguageName, languageName} from '#/locale/helpers' +import { + codeToLanguageName, + getTranslatorLink, + isPostInLanguage, + languageName, +} from '#/locale/helpers' import {LANGUAGES} from '#/locale/languages' import {useLanguagePrefs} from '#/state/preferences' import {atoms as a, native, useTheme} from '#/alf' import {Button} from '#/components/Button' +import {ArrowRight_Stroke2_Corner0_Rounded as ArrowRight} from '#/components/icons/Arrow' +import {TimesLarge_Stroke2_Corner0_Rounded as Times} from '#/components/icons/Times' +import {InlineLinkText} from '#/components/Link' import {Loader} from '#/components/Loader' import * as Select from '#/components/Select' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' export function TranslatedPost({ - translationKey, + post, postText, }: { - translationKey: string + post: AppBskyFeedDefs.PostView postText: string }) { - const {translate, translationState} = useTranslate({key: translationKey}) + const langPrefs = useLanguagePrefs() + const {clearTranslation, translate, translationState} = useTranslate({ + key: post.uri, + }) + + const needsTranslation = useMemo( + () => + Boolean( + langPrefs.primaryLanguage && + !isPostInLanguage(post, [langPrefs.primaryLanguage]), + ), + [post, langPrefs.primaryLanguage], + ) if (translationState.status === 'loading') { return @@ -31,6 +52,7 @@ export function TranslatedPost({ if (translationState.status === 'success') { return ( + ) + ) } function TranslationLoading() { @@ -57,51 +87,157 @@ function TranslationLoading() { ) } +function TranslationLink({ + postText, + primaryLanguage, + translate, +}: { + postText: string + primaryLanguage: string + translate: TranslationFunction +}) { + const t = useTheme() + const {t: l} = useLingui() + const ax = useAnalytics() + + const handleTranslate = useCallback( + (e: GestureResponderEvent) => { + e.preventDefault() + void translate({ + text: postText, + targetLangCode: primaryLanguage, + }) + + ax.metric('translate', { + sourceLanguages: [], + targetLanguage: primaryLanguage, + textLength: postText.length, + }) + + return false + }, + [ax, postText, primaryLanguage, translate], + ) + + return ( + + + + + Translate + + + + + ) +} + function TranslationResult({ + clearTranslation, translate, postText, sourceLanguage, translatedText, }: { + clearTranslation: () => void translate: TranslationFunction postText: string sourceLanguage: string | null translatedText: string }) { const t = useTheme() - const {i18n} = useLingui() + const langPrefs = useLanguagePrefs() + const {i18n, t: l} = useLingui() const langName = sourceLanguage ? codeToLanguageName(sourceLanguage, i18n.locale) : undefined return ( - - - + + + {langName ? ( - Translated from {langName} + + + {langName}{' '} + + + + + + {' '} + {codeToLanguageName( + langPrefs.primaryLanguage, + langPrefs.appLanguage, + )} + + ) : ( - Translated - )} - - {sourceLanguage != null && ( - <> - - {' '} - ·{' '} + + Translated - - - )} + )} + {sourceLanguage != null && ( + <> + + {' '} + ·{' '} + + + + )} + + + {translatedText} + + - - {translatedText} - ) } @@ -165,7 +301,7 @@ function TranslationLanguageSelect({ {...props} hitSlop={HITSLOP_30} hoverStyle={native({opacity: 0.5})}> - + Change diff --git a/src/screens/PostThread/components/ThreadItemAnchor.tsx b/src/screens/PostThread/components/ThreadItemAnchor.tsx index 9b05cf345f..1531784aee 100644 --- a/src/screens/PostThread/components/ThreadItemAnchor.tsx +++ b/src/screens/PostThread/components/ThreadItemAnchor.tsx @@ -407,7 +407,7 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({ shouldProxyLinks={true} /> ) : undefined} - + {post.embed && ( )} - + ) : undefined} {post.embed ? ( diff --git a/src/view/com/posts/PostFeedItem.tsx b/src/view/com/posts/PostFeedItem.tsx index 2279894a60..88e1c8bbe6 100644 --- a/src/view/com/posts/PostFeedItem.tsx +++ b/src/view/com/posts/PostFeedItem.tsx @@ -493,9 +493,7 @@ let PostContent = ({ /> )} - {record && ( - - )} + {record && } ) : undefined} {postEmbed ? (