···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()
10111212+ const translationServicePreference = useTranslationServicePreference()
1313+1114 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 translateUrl = getTranslatorLink(text, language)
2323+2424+ if (IS_ANDROID && translationServicePreference == 'google') {
1525 try {
1626 // use getApplicationIconAsync to determine if the translate app is installed
1727 if (
···4959 await openLink(translateUrl)
5060 }
5161 },
5252- [openLink],
6262+ [openLink, translationServicePreference],
5363 )
5464}
+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 {logger} from '#/logger'
2226import {
2327 POST_TOMBSTONE,
···3236import {useDisableRepostsMetrics} from '#/state/preferences/disable-reposts-metrics'
3337import {useDisableSavesMetrics} from '#/state/preferences/disable-saves-metrics'
3438import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons'
3939+import {useTranslationServicePreference} from '#/state/preferences/translation-service-preference'
3540import {type ThreadItem} from '#/state/queries/usePostThread/types'
3641import {useSession} from '#/state/session'
3742import {type OnPostSuccessData} from '#/state/shell/composer'
···563568 const isRootPost = !('reply' in post.record)
564569 const langPrefs = useLanguagePrefs()
565570571571+ const translationServicePreference = useTranslationServicePreference()
572572+566573 const needsTranslation = useMemo(
567574 () =>
568575 Boolean(
···614621 <InlineLinkText
615622 // overridden to open an intent on android, but keep
616623 // as anchor tag for accessibility
617617- to={getTranslatorLink(
618618- post.record.text,
619619- langPrefs.primaryLanguage,
620620- )}
624624+ to={
625625+ translationServicePreference === 'kagi'
626626+ ? getTranslatorLinkKagi(
627627+ post.record.text,
628628+ langPrefs.primaryLanguage,
629629+ )
630630+ : // in case u want to expand this to allow other services to be u would do this
631631+ // : translationServicePreference === "insert service name"
632632+ // ? getTranslatorLink(post.record.text, langPrefs.primaryLanguage, "insert service name")
633633+ // atm i cant really think of another service that lets u easily do this so its only kagi for now
634634+ // the default itll use if its not any of the checks is google!!
635635+ getTranslatorLink(
636636+ post.record.text,
637637+ langPrefs.primaryLanguage,
638638+ )
639639+ }
621640 label={_(msg`Translate`)}
622641 style={[a.text_sm]}
623642 onPress={onTranslatePress}>
+43
src/screens/Settings/DeerSettings.tsx
···109109 useSetShowLinkInHandle,
110110 useShowLinkInHandle,
111111} from '#/state/preferences/show-link-in-handle.tsx'
112112+import {
113113+ useSetTranslationServicePreference,
114114+ useTranslationServicePreference,
115115+} from '#/state/preferences/translation-service-preference'
112116import {useProfilesQuery} from '#/state/queries/profile'
113117import * as SettingsList from '#/screens/Settings/components/SettingsList'
114118import {atoms as a, useBreakpoints} from '#/alf'
···119123import {Atom_Stroke2_Corner0_Rounded as DeerIcon} from '#/components/icons/Atom'
120124import {ChainLink_Stroke2_Corner0_Rounded as ChainLinkIcon} from '#/components/icons/ChainLink'
121125import {Eye_Stroke2_Corner0_Rounded as VisibilityIcon} from '#/components/icons/Eye'
126126+import {Earth_Stroke2_Corner2_Rounded as EarthIcon} from '#/components/icons/Globe'
122127import {Lab_Stroke2_Corner0_Rounded as BeakerIcon} from '#/components/icons/Lab'
123128import {PaintRoller_Stroke2_Corner2_Rounded as PaintRollerIcon} from '#/components/icons/PaintRoller'
124129import {RaisingHand4Finger_Stroke2_Corner0_Rounded as RaisingHandIcon} from '#/components/icons/RaisingHand'
···352357353358 const showLinkInHandle = useShowLinkInHandle()
354359 const setShowLinkInHandle = useSetShowLinkInHandle()
360360+361361+ const translationServicePreference = useTranslationServicePreference()
362362+ const setTranslationServicePreference = useSetTranslationServicePreference()
355363356364 const [gates, setGatesView] = useState(
357365 Object.assign(defaultGateValues, Object.fromEntries(useGatesCache())),
···652660 access to features locked behind email verification.
653661 </Trans>
654662 </Admonition>
663663+ </SettingsList.Group>
664664+665665+ <SettingsList.Group contentContainerStyle={[a.gap_sm]}>
666666+ <SettingsList.ItemIcon icon={EarthIcon} />
667667+ <SettingsList.ItemText>
668668+ <Trans>Translation Engine</Trans>
669669+ </SettingsList.ItemText>
670670+671671+ <Admonition type="info" style={[a.flex_1]}>
672672+ <Trans>Choose the engine to use when translating posts.</Trans>
673673+ </Admonition>
674674+675675+ <Toggle.Item
676676+ name="service_google"
677677+ label={_(msg`Use Google Translate`)}
678678+ value={translationServicePreference === 'google'}
679679+ onChange={() => setTranslationServicePreference('google')}
680680+ style={[a.w_full]}>
681681+ <Toggle.LabelText style={[a.flex_1]}>
682682+ <Trans>Use Google Translate</Trans>
683683+ </Toggle.LabelText>
684684+ <Toggle.Radio />
685685+ </Toggle.Item>
686686+687687+ <Toggle.Item
688688+ name="service_kagi"
689689+ label={_(msg`Use Kagi Translate`)}
690690+ value={translationServicePreference === 'kagi'}
691691+ onChange={() => setTranslationServicePreference('kagi')}
692692+ style={[a.w_full]}>
693693+ <Toggle.LabelText style={[a.flex_1]}>
694694+ <Trans>Use Kagi Translate</Trans>
695695+ </Toggle.LabelText>
696696+ <Toggle.Radio />
697697+ </Toggle.Item>
655698 </SettingsList.Group>
656699657700 <SettingsList.Group contentContainerStyle={[a.gap_sm]}>