Last active
March 24, 2022 14:35
-
-
Save rvision/374faee770723d41f5cc376f03c953d5 to your computer and use it in GitHub Desktop.
Translation helper for talkr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable no-underscore-dangle */ | |
import { useState } from 'react'; | |
import { useT } from 'talkr'; | |
import languages, { defaultLanguage } from './languages'; | |
const _extractPath = string => { | |
if (!string) { | |
return []; | |
} | |
const splitRegEx = /\[([^\]]+)\]/g; | |
const split = string.replace(splitRegEx, '.$1').split('.'); | |
return split; | |
}; | |
const _getNested = (fullPath, source) => { | |
if (!Array.isArray(fullPath)) { | |
return _getNested(_extractPath(fullPath), source); | |
} | |
if (source === undefined) { | |
return undefined; | |
} | |
if (fullPath.length === 0) { | |
return source; | |
} | |
const path = fullPath[0]; | |
if (fullPath.length === 1) { | |
return source[path]; | |
} | |
if (source[path] === undefined) { | |
return undefined; | |
} | |
return _getNested(fullPath.slice(1), source[path]); | |
}; | |
const _setNested = (fullPath, target, value) => { | |
if (!Array.isArray(fullPath)) { | |
_setNested(_extractPath(fullPath), target, value); | |
return; | |
} | |
if (fullPath.length === 0) { | |
return; | |
} | |
const path = fullPath[0]; | |
if (fullPath.length === 1) { | |
target[path] = value; | |
return; | |
} | |
_setNested(fullPath.slice(1), target[path], value); | |
}; | |
let currentLocale = null; | |
const translated = new Map(); | |
const Translatable = ({ tKey }) => { | |
const { T, locale } = useT(); | |
const [, reRender] = useState(null); | |
const alreadyTranslated = translated.has(tKey); | |
const style = alreadyTranslated ? undefined : { background: 'red', color: '#fff' }; | |
let value = alreadyTranslated ? translated.get(tKey) : T(tKey); | |
if (currentLocale === null) { | |
currentLocale = JSON.parse(JSON.stringify(languages[locale])); | |
} | |
const currentTranslation = _getNested(tKey, currentLocale); | |
if (currentLocale !== null) { | |
const defaultLocale = languages[defaultLanguage]; | |
const defaultTranslation = _getNested(tKey, defaultLocale); | |
if (defaultTranslation === currentTranslation || currentTranslation === tKey) { | |
console.log(`%cPossibly not translated/missing:\nT('${tKey}') = '${defaultTranslation}'`, 'background:#ff9800;color:#fff;padding:1px 2px'); | |
} | |
} | |
const missing = '*** missing ***'; | |
if (currentTranslation === undefined) { | |
_setNested(tKey, currentLocale, missing); | |
} | |
if (value === null) { | |
value = missing; | |
} | |
return ( | |
<span | |
onClick={() => { | |
// e.stopPropagation(); | |
// e.preventDefault(); | |
// eslint-disable-next-line no-alert | |
const translation = window.prompt(tKey, value); | |
if (translation !== null) { | |
_setNested(tKey, currentLocale, translation); | |
translated.set(tKey, translation); | |
const json = JSON.stringify(currentLocale, null, '\t'); | |
document.activeElement.blur(); | |
navigator.clipboard.writeText(json); | |
reRender(Date.now()); | |
} | |
}} | |
style={style} | |
> | |
{value} | |
</span> | |
); | |
}; | |
const makeTranslatable = key => { | |
return <Translatable tKey={key} />; | |
}; | |
// wrapper around talkr's hook | |
const useTranslation = () => { | |
const { T } = useT(); | |
// return T; // normal behaviour | |
return makeTranslatable; // helper | |
}; | |
export default useTranslation; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment