Bluesky app fork with some witchin' additions 💫 witchsky.app
bluesky fork client
117
fork

Configure Feed

Select the types of activity you want to include in your feed.

Handle more translation errors (#10160)

authored by

DS Boyce and committed by
GitHub
5a213573 69164c64

+40 -10
+8
src/env/index.ts
··· 10 10 Platform.OS === 'ios' && typeof Platform.Version === 'string' 11 11 ? parseInt(Platform.Version.split('.')[0], 10) 12 12 : 0 13 + const androidPlatformVersion = 14 + Platform.OS === 'android' && typeof Platform.Version === 'number' 15 + ? Platform.Version 16 + : 0 13 17 14 18 /** 15 19 * The semver version of the app, specified in our `package.json`.file. On ··· 49 53 export const IS_HIGH_DPI: boolean = true 50 54 // ideally we'd use isLiquidGlassAvailable() from expo-glass-effect but checking iOS version is good enough for now 51 55 export const IS_LIQUID_GLASS: boolean = iOSMajorVersion >= 26 56 + // So we can avoid attempting on-device translation when we know it's unsupported. 57 + export const IS_TRANSLATION_SUPPORTED: boolean = 58 + (IS_IOS && iOSMajorVersion >= 18) || 59 + (IS_ANDROID && androidPlatformVersion > 22)
+1
src/env/index.web.ts
··· 48 48 '(min-resolution: 2dppx)', 49 49 ).matches 50 50 export const IS_LIQUID_GLASS: boolean = false 51 + export const IS_TRANSLATION_SUPPORTED: boolean = false
+31 -10
src/lib/translation/index.tsx
··· 1 1 import {useCallback, useContext, useEffect, useMemo, useState} from 'react' 2 2 import {LayoutAnimation, Platform} from 'react-native' 3 3 import {getLocales} from 'expo-localization' 4 - import { 5 - isTranslationSupported, 6 - onTranslateTask, 7 - } from '@bsky.app/expo-translate-text' 4 + import {onTranslateTask} from '@bsky.app/expo-translate-text' 8 5 import {type TranslationTaskResult} from '@bsky.app/expo-translate-text/build/ExpoTranslateText.types' 9 6 import {useLingui} from '@lingui/react/macro' 10 7 import {useFocusEffect} from '@react-navigation/native' 11 8 12 9 import {useGoogleTranslate} from '#/lib/hooks/useGoogleTranslate' 10 + import {codeToLanguageName} from '#/locale/helpers' 13 11 import {logger} from '#/logger' 12 + import {useLanguagePrefs} from '#/state/preferences' 14 13 import {useAnalytics} from '#/analytics' 15 - import {IS_ANDROID, IS_IOS} from '#/env' 14 + import {IS_ANDROID, IS_IOS, IS_TRANSLATION_SUPPORTED} from '#/env' 16 15 import {Context} from './context' 17 16 import { 18 17 type ContextType, ··· 25 24 export * from './types' 26 25 export * from './utils' 27 26 27 + const E_SAME_AS_SOURCE_LANGUAGE = 28 + 'Translation result is the same as the source text.' 29 + const E_EMPTY_RESULT = 'Translation result is empty.' 30 + const E_INVALID_SOURCE_LANGUAGE = 'Invalid source language' 31 + 28 32 /** 29 33 * Attempts on-device translation via @bsky.app/expo-translate-text. 30 34 * Uses a lazy import to avoid crashing if the native module isn't linked into ··· 80 84 typeof result.translatedTexts === 'string' ? result.translatedTexts : '' 81 85 82 86 if (translatedText === input) { 83 - throw new Error('Translation result is the same as the source text.') 87 + throw new Error(E_SAME_AS_SOURCE_LANGUAGE) 84 88 } 85 89 86 90 if (translatedText === '') { 87 - throw new Error('Translation result is empty.') 91 + throw new Error(E_EMPTY_RESULT) 88 92 } 89 93 90 94 return { ··· 159 163 >({}) 160 164 const [refCounts, setRefCounts] = useState<Record<string, number>>({}) 161 165 const ax = useAnalytics() 166 + const langPrefs = useLanguagePrefs() 162 167 const {t: l} = useLingui() 163 168 const googleTranslate = useGoogleTranslate() 164 169 ··· 235 240 googleTranslate: shouldForceGoogleTranslate, 236 241 }) 237 242 238 - if (shouldForceGoogleTranslate || !isTranslationSupported()) { 243 + if (shouldForceGoogleTranslate || !IS_TRANSLATION_SUPPORTED) { 239 244 await googleTranslate( 240 245 text, 241 246 expectedTargetLanguage, ··· 280 285 postLanguages: possibleSourceLanguages, 281 286 }, 282 287 })) 283 - } catch (e) { 288 + } catch (err) { 289 + const e = err as Error 284 290 logger.error('Failed to translate text on device', {safeMessage: e}) 285 291 // On-device translation failed (language pack missing or user 286 292 // dismissed the download prompt). ··· 295 301 textLength: text.length, 296 302 }) 297 303 let errorMessage = l`Device failed to translate :(` 304 + if (e.message === E_SAME_AS_SOURCE_LANGUAGE) { 305 + errorMessage = l`Translation to the same language is unavailable on your device.` 306 + } 307 + if (e.message === E_EMPTY_RESULT) { 308 + errorMessage = l`No translation received from your device.` 309 + } 310 + if ( 311 + expectedSourceLanguage && 312 + e.message.includes(E_INVALID_SOURCE_LANGUAGE) 313 + ) { 314 + errorMessage = l`${codeToLanguageName( 315 + expectedSourceLanguage, 316 + langPrefs.appLanguage, 317 + )} is not supported by your device.` 318 + } 298 319 if (!IS_ANDROID) { 299 320 LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut) 300 321 } ··· 304 325 })) 305 326 } 306 327 }, 307 - [ax, googleTranslate, l], 328 + [ax, googleTranslate, l, langPrefs.appLanguage], 308 329 ) 309 330 310 331 const ctx = useMemo(