···11import {useCallback} from 'react'
22import * as IntentLauncher from 'expo-intent-launcher'
3344-import {getTranslatorLink} from '#/locale/helpers'
44+import {getTranslatorLink, getTranslatorLinkKagi} from '#/locale/helpers'
55+import {useTranslationServicePreference} from '#/state/preferences/translation-service-preference'
56import {IS_ANDROID} from '#/env'
67import {useOpenLink} from './useOpenLink'
7889export function useTranslate() {
910 const openLink = useOpenLink()
1111+1212+ const translationServicePreference = useTranslationServicePreference()
10131114 return useCallback(
1215 async (text: string, language: string) => {
1313- const translateUrl = getTranslatorLink(text, language)
1414- if (IS_ANDROID) {
1616+ let translateUrl
1717+1818+ // if ur curious why this isnt a switch case, good question, for some reason making this a switch case breaks the functionality
1919+ // it is a mystery https://www.youtube.com/watch?v=fq3abPnEEGE
2020+ if (translationServicePreference == 'kagi') {
2121+ translateUrl = getTranslatorLinkKagi(text, language)
2222+ } else {
2323+ translateUrl = getTranslatorLink(text, language)
2424+ }
2525+2626+ if (IS_ANDROID && translationServicePreference == 'google') {
1527 try {
1628 // use getApplicationIconAsync to determine if the translate app is installed
1729 if (
···4961 await openLink(translateUrl)
5062 }
5163 },
5252- [openLink],
6464+ [openLink, translationServicePreference],
5365 )
5466}
+7
src/locale/helpers.ts
···127127 return bcp47Match.basicFilter(lang, targetLangs).length > 0
128128}
129129130130+// we cant hook into functions like this, so we will make other translator functions n swap between em
130131export function getTranslatorLink(text: string, lang: string): string {
131132 return `https://translate.google.com/?sl=auto&tl=${lang}&text=${encodeURIComponent(
133133+ text,
134134+ )}`
135135+}
136136+137137+export function getTranslatorLinkKagi(text: string, lang: string): string {
138138+ return `https://translate.kagi.com/?from=auto&to=${lang}&text=${encodeURIComponent(
132139 text,
133140 )}`
134141}
···1717import {sanitizeDisplayName} from '#/lib/strings/display-names'
1818import {sanitizeHandle} from '#/lib/strings/handles'
1919import {niceDate} from '#/lib/strings/time'
2020-import {getTranslatorLink, isPostInLanguage} from '#/locale/helpers'
2020+import {
2121+ getTranslatorLink,
2222+ getTranslatorLinkKagi,
2323+ isPostInLanguage,
2424+} from '#/locale/helpers'
2125import {
2226 POST_TOMBSTONE,
2327 type Shadow,
···3135import {useDisableRepostsMetrics} from '#/state/preferences/disable-reposts-metrics'
3236import {useDisableSavesMetrics} from '#/state/preferences/disable-saves-metrics'
3337import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons'
3838+import {useTranslationServicePreference} from '#/state/preferences/translation-service-preference'
3439import {type ThreadItem} from '#/state/queries/usePostThread/types'
3540import {useSession} from '#/state/session'
3641import {type OnPostSuccessData} from '#/state/shell/composer'
···566571 const isRootPost = !('reply' in post.record)
567572 const langPrefs = useLanguagePrefs()
568573574574+ const translationServicePreference = useTranslationServicePreference()
575575+569576 const needsTranslation = useMemo(
570577 () =>
571578 Boolean(
···617624 <InlineLinkText
618625 // overridden to open an intent on android, but keep
619626 // as anchor tag for accessibility
620620- to={getTranslatorLink(
621621- post.record.text,
622622- langPrefs.primaryLanguage,
623623- )}
627627+ to={
628628+ // in case u want to expand this to allow other services to be u would do this after the kagi one
629629+ // : translationServicePreference === "insert service name"
630630+ // ? getTranslatorLink(post.record.text, langPrefs.primaryLanguage, "insert service name")
631631+ // atm i cant really think of another service that lets u easily do this so its only kagi for now
632632+ // the default itll use if its not any of the checks is google!!
633633+ translationServicePreference === 'kagi'
634634+ ? getTranslatorLinkKagi(
635635+ post.record.text,
636636+ langPrefs.primaryLanguage,
637637+ )
638638+ : getTranslatorLink(
639639+ post.record.text,
640640+ langPrefs.primaryLanguage,
641641+ )
642642+ }
624643 label={_(msg`Translate`)}
625644 style={[a.text_sm]}
626645 onPress={onTranslatePress}>
+43
src/screens/Settings/DeerSettings.tsx
···103103 useSetShowLinkInHandle,
104104 useShowLinkInHandle,
105105} from '#/state/preferences/show-link-in-handle.tsx'
106106+import {
107107+ useSetTranslationServicePreference,
108108+ useTranslationServicePreference,
109109+} from '#/state/preferences/translation-service-preference'
106110import {useProfilesQuery} from '#/state/queries/profile'
107111import * as SettingsList from '#/screens/Settings/components/SettingsList'
108112import {atoms as a, useBreakpoints} from '#/alf'
···113117import {Atom_Stroke2_Corner0_Rounded as DeerIcon} from '#/components/icons/Atom'
114118import {ChainLink_Stroke2_Corner0_Rounded as ChainLinkIcon} from '#/components/icons/ChainLink'
115119import {Eye_Stroke2_Corner0_Rounded as VisibilityIcon} from '#/components/icons/Eye'
120120+import {Earth_Stroke2_Corner2_Rounded as EarthIcon} from '#/components/icons/Globe'
116121import {Lab_Stroke2_Corner0_Rounded as _BeakerIcon} from '#/components/icons/Lab'
117122import {PaintRoller_Stroke2_Corner2_Rounded as PaintRollerIcon} from '#/components/icons/PaintRoller'
118123import {RaisingHand4Finger_Stroke2_Corner0_Rounded as RaisingHandIcon} from '#/components/icons/RaisingHand'
···326331327332 const showLinkInHandle = useShowLinkInHandle()
328333 const setShowLinkInHandle = useSetShowLinkInHandle()
334334+335335+ const translationServicePreference = useTranslationServicePreference()
336336+ const setTranslationServicePreference = useSetTranslationServicePreference()
329337330338 return (
331339 <Layout.Screen>
···614622 access to features locked behind email verification.
615623 </Trans>
616624 </Admonition>
625625+ </SettingsList.Group>
626626+627627+ <SettingsList.Group contentContainerStyle={[a.gap_sm]}>
628628+ <SettingsList.ItemIcon icon={EarthIcon} />
629629+ <SettingsList.ItemText>
630630+ <Trans>Translation Engine</Trans>
631631+ </SettingsList.ItemText>
632632+633633+ <Admonition type="info" style={[a.flex_1]}>
634634+ <Trans>Choose the engine to use when translating posts.</Trans>
635635+ </Admonition>
636636+637637+ <Toggle.Item
638638+ name="service_google"
639639+ label={_(msg`Use Google Translate`)}
640640+ value={translationServicePreference === 'google'}
641641+ onChange={() => setTranslationServicePreference('google')}
642642+ style={[a.w_full]}>
643643+ <Toggle.LabelText style={[a.flex_1]}>
644644+ <Trans>Use Google Translate</Trans>
645645+ </Toggle.LabelText>
646646+ <Toggle.Radio />
647647+ </Toggle.Item>
648648+649649+ <Toggle.Item
650650+ name="service_kagi"
651651+ label={_(msg`Use Kagi Translate`)}
652652+ value={translationServicePreference === 'kagi'}
653653+ onChange={() => setTranslationServicePreference('kagi')}
654654+ style={[a.w_full]}>
655655+ <Toggle.LabelText style={[a.flex_1]}>
656656+ <Trans>Use Kagi Translate</Trans>
657657+ </Toggle.LabelText>
658658+ <Toggle.Radio />
659659+ </Toggle.Item>
617660 </SettingsList.Group>
618661619662 <SettingsList.Group contentContainerStyle={[a.gap_sm]}>