Skip to content

Instantly share code, notes, and snippets.

@rvision
Last active March 24, 2022 14:35
Show Gist options
  • Save rvision/374faee770723d41f5cc376f03c953d5 to your computer and use it in GitHub Desktop.
Save rvision/374faee770723d41f5cc376f03c953d5 to your computer and use it in GitHub Desktop.
Translation helper for talkr
/* 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