Skip to content

Commit 94fc732

Browse files
committed
fix: address PR review comments
- Remove unused imports (hot-memo, react-icons, forEach) - Fix typos in comments (broswer -> browser, avaliable -> available) - Simplify JSX return structure in dt function - Improve code readability
1 parent ec38c55 commit 94fc732

File tree

2 files changed

+80
-63
lines changed

2 files changed

+80
-63
lines changed

components/nodes/NodeDetails.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { useDynamicTranslate, useNextTranslation } from '@/src/hooks/i18n'
1+
import {
2+
DynamicTranslateSwitcher,
3+
useDynamicTranslate,
4+
useNextTranslation,
5+
} from '@/src/hooks/i18n'
26
import { useQueryClient } from '@tanstack/react-query'
37
import download from 'downloadjs'
48
import { Button, Label, Spinner } from 'flowbite-react'
@@ -90,7 +94,7 @@ export function formatDownloadCount(count: number): string {
9094

9195
const NodeDetails = () => {
9296
const { t, i18n } = useNextTranslation()
93-
const { dt, Switcher } = useDynamicTranslate()
97+
const { dt } = useDynamicTranslate()
9498

9599
// state for drawer and modals
96100
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
@@ -479,7 +483,7 @@ const NodeDetails = () => {
479483
{t('Description')}
480484
</h2>
481485
<p className="text-base font-normal text-gray-200">
482-
<Switcher />
486+
<DynamicTranslateSwitcher />
483487
{dt(node.description)}
484488
</p>
485489
</div>

src/hooks/i18n/index.tsx

Lines changed: 73 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { LANGUAGE_STORAGE_KEY, SUPPORTED_LANGUAGES } from '@/src/constants'
2-
import hotMemo from 'hot-memo'
32
import i18next from 'i18next'
43
import I18nextBrowserLanguageDetector from 'i18next-browser-languagedetector'
54
import i18nextResourcesToBackend from 'i18next-resources-to-backend'
@@ -25,57 +24,69 @@ const i18n = i18next
2524
)
2625
)
2726
.use(initReactI18next)
28-
.init({
29-
fallbackLng: 'en',
30-
supportedLngs: SUPPORTED_LANGUAGES,
31-
defaultNS: 'common',
32-
fallbackNS: 'common',
33-
34-
// not needed for react as it escapes by default
35-
interpolation: { escapeValue: false },
36-
37-
// use ssr-side detection in middleware
38-
detection: {
39-
order: ['htmlTag'],
40-
caches: [],
41-
},
4227

43-
react: {
44-
bindI18nStore: 'added', // notify react to rerender when a new key is added
45-
},
28+
i18n.init({
29+
fallbackLng: 'en',
30+
supportedLngs: SUPPORTED_LANGUAGES,
31+
defaultNS: 'common',
32+
fallbackNS: 'common',
4633

47-
saveMissing: true,
48-
missingKeyNoValueFallbackToKey: true,
49-
missingKeyHandler: async (lngs, ns, key) => {
50-
const lng = i18next.language
51-
console.log(lngs, i18next.language, key)
52-
console.log(
53-
`Missing translation for key "${key}" in language "${lng}"`
54-
)
55-
// (Experimental) Try use broswer Translator API to handle missing keys
56-
// If the Translator API is not available, just return the key
57-
if (typeof globalThis.Translator === 'undefined') return
58-
59-
// Create a translator instance
60-
const Translator = globalThis.Translator as any
61-
const translator = await Translator.create({
62-
sourceLanguage: 'en',
63-
targetLanguage: lng,
64-
}).catch(() => null)
65-
if (!translator) return
66-
67-
// Translate the key
68-
let tr = ''
69-
for await (const chunk of translator.translateStreaming(key)) {
70-
tr += chunk
71-
}
72-
console.log(`Translated "${key}" to "${tr}" in language "${lng}"`)
73-
// add to i18next resources
74-
// how to trigger a re-render in components that use this key?
75-
i18next.addResource(lng, ns, key, tr)
76-
i18next.emit('added', lng, ns, key, tr)
77-
},
78-
})
34+
// not needed for react as it escapes by default
35+
interpolation: { escapeValue: false },
36+
37+
// use ssr-side detection in middleware
38+
detection: {
39+
order: ['htmlTag'],
40+
caches: [],
41+
},
42+
43+
react: {
44+
bindI18nStore: 'added', // notify react to rerender when a new key is added
45+
},
46+
47+
// Support dynamic translation
48+
saveMissing: true,
49+
missingKeyNoValueFallbackToKey: true,
50+
missingKeyHandler: async (lngs, ns, key) => {
51+
const lng = i18next.language
52+
console.log(lngs, i18next.language, key)
53+
console.log(`Missing translation for key "${key}" in language "${lng}"`)
54+
55+
// (Experimental) Try use browser Translator API to handle missing keys
56+
// If the Translator API is not available, just return the key
57+
if (typeof globalThis.Translator === 'undefined') return
58+
59+
// Create a translator instance
60+
const Translator = globalThis.Translator as any
61+
const translator = await Translator.create({
62+
sourceLanguage: 'en',
63+
targetLanguage: lng,
64+
}).catch(() => null)
65+
if (!translator) return
66+
67+
// Translate the key
68+
let tr = ''
69+
for await (const chunk of translator.translateStreaming(key)) {
70+
tr += chunk
71+
}
72+
console.log(`Translated "${key}" to "${tr}" in language "${lng}"`)
73+
// add to i18next resources
74+
// how to trigger a re-render in components that use this key?
75+
i18next.addResource(lng, ns, key, tr)
76+
i18next.emit('added', lng, ns, key, tr)
77+
78+
// TODO: use ChatGPT to handle missing keys if browser Translator API is not available
79+
//
80+
},
81+
})
82+
83+
export const useDynamicTranslateEnabled = () => {
84+
const [enabled, setEnabled] = useLocalStorage(
85+
'DynamicTranslate',
86+
false // default disabled, click the globe icon to enable across the site
87+
)
88+
return { enabled, setEnabled }
89+
}
7990

8091
export const useDynamicTranslate = () => {
8192
const { currentLanguage, t } = useNextTranslation('dynamic')
@@ -86,7 +97,7 @@ export const useDynamicTranslate = () => {
8697
// cons:
8798
// 1. requires network access to the browser's translation service
8899
// 2. not able to use in server-side rendering
89-
// 3. not avaliable in china
100+
// 3. not available in china
90101
//
91102
const [available, availableState] = useAsyncData(async () => {
92103
const Translator = globalThis.Translator as any
@@ -97,33 +108,35 @@ export const useDynamicTranslate = () => {
97108
return translator
98109
})
99110

100-
const [enabled, setEnabled] = useLocalStorage(
101-
'DynamicTranslate',
102-
false // default disabled, click the globe icon to enable across the site
103-
)
111+
const { enabled, setEnabled } = useDynamicTranslateEnabled()
104112
const dt = useCallback(
105113
(key?: string) => {
106114
if (!key) return key
107115
if (!available) return key
108-
return <>{enabled ? <>{t(key)}</> : <>{key}</>}</>
116+
return enabled ? t(key) : key
109117
},
110118
[enabled, available, t]
111119
)
112-
const Switcher = () => (
120+
121+
return { available, enabled, setEnabled, dt }
122+
}
123+
124+
export const DynamicTranslateSwitcher = () => {
125+
const { available, enabled, setEnabled } = useDynamicTranslate()
126+
if (!available) return null
127+
return (
113128
<span
114129
role="img"
115130
aria-label="translate"
116131
onClick={() => {
117-
setEnabled((e) => !e)
132+
setEnabled(!enabled) // toggle the translation statey
118133
}}
119134
>
120135
{
121136
enabled ? '🔄' : '🌐' // use a different icon to indicate translation is disabled
122137
}
123138
</span>
124139
)
125-
126-
return { available, Switcher, enabled, setEnabled, dt }
127140
}
128141
/**
129142
* Custom hook for translations in the Comfy Registry

0 commit comments

Comments
 (0)