Bluesky app fork with some witchin' additions 馃挮
witchsky.app
bluesky
fork
client
1import {useCallback, useContext, useMemo} from 'react'
2
3import {useGoogleTranslate} from '#/lib/hooks/useGoogleTranslate'
4import {useAnalytics} from '#/analytics'
5import {Context} from './context'
6import {type TranslationFunctionParams, type TranslationState} from './types'
7
8export * from './types'
9export * from './utils'
10
11const translationState: Record<string, TranslationState> = {}
12const acquireTranslation = (_key: string) => {
13 return () => {}
14}
15const clearTranslation = (_key: string) => {}
16
17/**
18 * Web always opens Google Translate.
19 */
20export function useTranslate({
21 key,
22}: {
23 key: string
24 forceGoogleTranslate?: boolean
25}) {
26 const context = useContext(Context)
27 if (!context) {
28 throw new Error(
29 'useTranslate must be used within a TranslateOnDeviceProvider',
30 )
31 }
32
33 // Always call hooks in consistent order
34 const translate = useCallback(
35 async (params: TranslationFunctionParams) => {
36 return context.translate({...params, key, forceGoogleTranslate: true})
37 },
38 [key, context],
39 )
40
41 const clearTranslation = useCallback(() => {
42 return context.clearTranslation(key)
43 }, [key, context])
44
45 return {
46 translationState: context.translationState[key] ?? {
47 status: 'idle' as const,
48 },
49 translate,
50 clearTranslation,
51 }
52}
53
54export function Provider({children}: React.PropsWithChildren<unknown>) {
55 const ax = useAnalytics()
56 const googleTranslate = useGoogleTranslate()
57
58 const translate = useCallback(
59 async ({
60 text,
61 targetLangCode,
62 sourceLangCode,
63 }: {
64 key: string
65 text: string
66 targetLangCode: string
67 sourceLangCode?: string
68 }) => {
69 ax.metric('translate:result', {
70 method: 'google-translate',
71 os: 'web',
72 sourceLanguage: sourceLangCode ?? null,
73 targetLanguage: targetLangCode,
74 })
75 await googleTranslate(text, targetLangCode, sourceLangCode)
76 },
77 [ax, googleTranslate],
78 )
79
80 const ctx = useMemo(
81 () => ({acquireTranslation, clearTranslation, translate, translationState}),
82 [translate],
83 )
84
85 return <Context.Provider value={ctx}>{children}</Context.Provider>
86}