Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/lib/hooks/useTranslate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as IntentLauncher from 'expo-intent-launcher'

import {getTranslatorLink} from '#/locale/helpers'
import {isAndroid} from '#/platform/detection'
import * as persisted from '#/state/persisted'
import {useOpenLink} from './useOpenLink'

export function useTranslate() {
Expand All @@ -11,7 +12,18 @@ export function useTranslate() {
return useCallback(
async (text: string, language: string) => {
const translateUrl = getTranslatorLink(text, language)
if (isAndroid) {
let is_google_translate = true
// Put URL() logic inside a try/catch, because if the URL corrupts, the app will crash.
try {
is_google_translate =
new URL(
persisted.get('translationService') ||
'https://translate.google.com',
).hostname === 'translate.google.com'
} catch {}

// Check device is Android and user's preference is Google translate.
if (isAndroid && is_google_translate) {
try {
// use getApplicationIconAsync to determine if the translate app is installed
if (
Expand Down
10 changes: 7 additions & 3 deletions src/locale/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as bcp47Match from 'bcp-47-match'
import lande from 'lande'

import {hasProp} from '#/lib/type-guards'
import * as persisted from '#/state/persisted'
import {
AppLanguage,
type Language,
Expand Down Expand Up @@ -128,9 +129,12 @@ export function isPostInLanguage(
}

export function getTranslatorLink(text: string, lang: string): string {
return `https://translate.google.com/?sl=auto&tl=${lang}&text=${encodeURIComponent(
text,
)}`
return (
persisted.get('translationService') ||
'https://translate.google.com/?sl=auto&tl=%lang%&text=%text%'
)
.replaceAll('%lang%', lang)
.replaceAll('%text%', encodeURIComponent(text))
}

/**
Expand Down
34 changes: 23 additions & 11 deletions src/locale/locales/en/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ msgstr ""
msgid "App Icon"
msgstr ""

#: src/screens/Settings/LanguageSettings.tsx:87
#: src/screens/Settings/LanguageSettings.tsx:103
msgid "App Language"
msgstr ""

Expand Down Expand Up @@ -2181,7 +2181,7 @@ msgstr ""
msgid "Content from across the network we think you might like."
msgstr ""

#: src/screens/Settings/LanguageSettings.tsx:153
#: src/screens/Settings/LanguageSettings.tsx:169
#: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:76
msgid "Content Languages"
msgstr ""
Expand Down Expand Up @@ -4672,7 +4672,7 @@ msgstr ""
msgid "Language Settings"
msgstr ""

#: src/screens/Settings/LanguageSettings.tsx:78
#: src/screens/Settings/LanguageSettings.tsx:94
#: src/screens/Settings/Settings.tsx:228
#: src/screens/Settings/Settings.tsx:231
msgid "Languages"
Expand Down Expand Up @@ -6596,7 +6596,7 @@ msgstr ""
msgid "Previous image"
msgstr ""

#: src/screens/Settings/LanguageSettings.tsx:120
#: src/screens/Settings/LanguageSettings.tsx:136
msgid "Primary Language"
msgstr ""

Expand Down Expand Up @@ -7667,11 +7667,15 @@ msgstr ""
msgid "Select an option"
msgstr ""

#: src/screens/Settings/LanguageSettings.tsx:98
#: src/screens/Settings/LanguageSettings.tsx:114
msgid "Select app language"
msgstr ""

#: src/screens/Settings/LanguageSettings.tsx:164
#: src/screens/Settings/LanguageSettings.tsx:215
msgid "Select app translation service"
msgstr ""

#: src/screens/Settings/LanguageSettings.tsx:180
msgid "Select content languages"
msgstr ""

Expand Down Expand Up @@ -7704,7 +7708,7 @@ msgstr ""
msgid "Select language..."
msgstr ""

#: src/screens/Settings/LanguageSettings.tsx:178
#: src/screens/Settings/LanguageSettings.tsx:194
#: src/view/com/composer/select-language/PostLanguageSelectDialog.tsx:226
msgid "Select languages"
msgstr ""
Expand All @@ -7721,7 +7725,7 @@ msgstr ""
msgid "Select post language"
msgstr ""

#: src/screens/Settings/LanguageSettings.tsx:131
#: src/screens/Settings/LanguageSettings.tsx:147
msgid "Select primary language"
msgstr ""

Expand All @@ -7746,11 +7750,11 @@ msgstr ""
msgid "Select what content this mute word should apply to."
msgstr ""

#: src/screens/Settings/LanguageSettings.tsx:91
#: src/screens/Settings/LanguageSettings.tsx:107
msgid "Select which language to use for the app's user interface."
msgstr ""

#: src/screens/Settings/LanguageSettings.tsx:157
#: src/screens/Settings/LanguageSettings.tsx:173
msgid "Select which languages you want your subscribed feeds to include. If none are selected, all languages will be shown."
msgstr ""

Expand All @@ -7763,14 +7767,18 @@ msgstr ""
msgid "Select your interests from the options below"
msgstr ""

#: src/screens/Settings/LanguageSettings.tsx:124
#: src/screens/Settings/LanguageSettings.tsx:140
msgid "Select your preferred language for translations in your feed."
msgstr ""

#: src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx:110
msgid "Select your preferred notification channels"
msgstr ""

#: src/screens/Settings/LanguageSettings.tsx:206
msgid "Select your preferred service for translations."
msgstr ""

#: src/view/com/composer/SelectMediaButton.tsx:390
msgid "Selecting multiple media types is not supported."
msgstr ""
Expand Down Expand Up @@ -9214,6 +9222,10 @@ msgstr ""
msgid "Translate"
msgstr ""

#: src/screens/Settings/LanguageSettings.tsx:202
msgid "Translation Service"
msgstr ""

#: src/screens/Settings/ThreadPreferences.tsx:115
#: src/screens/Settings/ThreadPreferences.tsx:120
msgid "Tree view"
Expand Down
55 changes: 54 additions & 1 deletion src/screens/Settings/LanguageSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useCallback, useMemo} from 'react'
import {useCallback, useMemo, useState} from 'react'
import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
Expand All @@ -10,6 +10,7 @@ import {
} from '#/lib/routes/types'
import {languageName, sanitizeAppLanguageSetting} from '#/locale/helpers'
import {useModalControls} from '#/state/modals'
import * as persisted from '#/state/persisted'
import {useLanguagePrefs, useLanguagePrefsApi} from '#/state/preferences'
import {atoms as a, useTheme, web} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
Expand Down Expand Up @@ -69,6 +70,21 @@ export function LanguageSettingsScreen({}: Props) {
)
}, [langPrefs.appLanguage, langPrefs.contentLanguages])

const translation_services = [
{
label: 'Google',
value: 'https://translate.google.com/?sl=auto&tl=%lang%&text=%text%',
},
{
label: 'Kagi',
value: 'https://translate.kagi.com/?from=auto&to=%lang%&text=%text%',
},
]

const [translation_service, set_translation_service] = useState(
persisted.get('translationService'),
)

return (
<Layout.Screen testID="PreferencesLanguagesScreen">
<Layout.Header.Outer>
Expand Down Expand Up @@ -180,6 +196,43 @@ export function LanguageSettingsScreen({}: Props) {
</Button>
</View>
</SettingsList.Group>
<SettingsList.Divider />
<SettingsList.Group iconInset={false}>
<SettingsList.ItemText>
<Trans>Translation Service</Trans>
</SettingsList.ItemText>
<View style={[a.gap_md]}>
<Text style={[a.leading_snug]}>
<Trans>Select your preferred service for translations.</Trans>
</Text>

<Select.Root
value={translation_service}
onValueChange={e => {
set_translation_service(e)
persisted.write('translationService', e)
}}>
<Select.Trigger label={_(msg`Select app translation service`)}>
<Select.ValueText />
<Select.Icon />
</Select.Trigger>
<Select.Content
renderItem={({label, value}) => (
<Select.Item value={value} label={label}>
<Select.ItemIndicator />
<Select.ItemText>
{label}{' '}
<Text style={{color: 'gray'}}>
({new URL(value).hostname})
</Text>
</Select.ItemText>
</Select.Item>
)}
items={translation_services}
/>
</Select.Root>
</View>
</SettingsList.Group>
</SettingsList.Container>
</Layout.Content>
</Layout.Screen>
Expand Down
4 changes: 4 additions & 0 deletions src/state/persisted/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ const schema = z.object({
mutedThreads: z.array(z.string()),
trendingDisabled: z.boolean().optional(),
trendingVideoDisabled: z.boolean().optional(),
translationService: z.string().optional(),
})

export type Schema = z.infer<typeof schema>

export const defaults: Schema = {
Expand Down Expand Up @@ -174,6 +176,8 @@ export const defaults: Schema = {
subtitlesEnabled: true,
trendingDisabled: false,
trendingVideoDisabled: false,
translationService:
'https://translate.google.com/?sl=auto&tl=%lang%&text=%text%',
}

export function tryParse(rawData: string): Schema | undefined {
Expand Down