Skip to content

Commit

Permalink
Fix spanish language detection not working
Browse files Browse the repository at this point in the history
  • Loading branch information
chriselly authored and sjmcnamara committed Nov 30, 2023
1 parent aed4206 commit d361949
Show file tree
Hide file tree
Showing 13 changed files with 203 additions and 416 deletions.
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@
"copy-webpack-plugin": "11.0.0",
"create-file-plugin-webpack": "1.0.1",
"cypress-real-events": "1.10.3",
"dayjs": "1.10.7",
"dayjs-business-days": "1.0.4",
"history": "4.10.1",
"html-webpack-plugin": "5.5.0",
"lodash": "4.17.21",
Expand Down
6 changes: 3 additions & 3 deletions src/forms/schemas/addressSchema.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { I18n } from '../../lib/i18n/provider';
import { getCurrency } from '../../lib/vault';
import { isValidAddress } from '../validations/isValidAddress';
import { translate } from '../../lib/i18n';
import { yup } from '../index';

export const addressSchema = selectedNetwork =>
yup.object().shape({
address: yup
.string()
.required(I18n.t('access.fields.address.errors.required', { currency: getCurrency(selectedNetwork) }))
.required(translate('access.fields.address.errors.required', { currency: getCurrency(selectedNetwork) }))
.test(
'validation',
I18n.t('access.fields.address.errors.invalid', { currency: getCurrency(selectedNetwork) }),
translate('access.fields.address.errors.invalid', { currency: getCurrency(selectedNetwork) }),
val => isValidAddress(selectedNetwork, val)
)
});
8 changes: 4 additions & 4 deletions src/forms/schemas/destinationSchema.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { Blockchain } from '../../lib/vault';
import { I18n } from '../../lib/i18n/provider';
import { isValidAddress } from '../validations/isValidAddress';
import { translate } from '../../lib/i18n';
import { yup } from '../index';

export const destinationSchema = sourceAddress =>
yup.object().shape({
address: yup
.string()
.required(I18n.t('withdraw.xrp.destination.fields.address.errors.required'))
.required(translate('withdraw.xrp.destination.fields.address.errors.required'))
.test(
'validation',
I18n.t('withdraw.xrp.destination.fields.address.errors.invalid.xrp'),
translate('withdraw.xrp.destination.fields.address.errors.invalid.xrp'),
val => isValidAddress(Blockchain.XRPL, val) && val !== sourceAddress
),
destinationTag: yup
.string()
.test(
'validation',
I18n.t('withdraw.xrp.destination.fields.destination.tag.errors.invalid'),
translate('withdraw.xrp.destination.fields.destination.tag.errors.invalid'),
val => !val.includes('-') && !val.includes('.') && !isNaN(Number(val))
)
});
10 changes: 5 additions & 5 deletions src/forms/schemas/signingKeysSchema.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { I18n } from '../../lib/i18n/provider';
import { isKeySigner } from '../../lib/vault';
import { isValidMnemonic } from '../validations/isValidMnemonic';
import { translate } from '../../lib/i18n';
import { yup } from '../index';

export const signingKeysSchema = (network, signers) =>
yup.object().shape({
backupKey: yup
.string()
.required(I18n.t('withdraw.xrp.confirm.fields.backup.key.errors.required'))
.required(translate('withdraw.xrp.confirm.fields.backup.key.errors.required'))
.test(
'validation',
I18n.t('withdraw.xrp.confirm.fields.backup.key.errors.invalid'),
translate('withdraw.xrp.confirm.fields.backup.key.errors.invalid'),
val => isValidMnemonic(val) && isKeySigner(network, val, signers)
),
vaultKey: yup
.string()
.required(I18n.t('withdraw.xrp.confirm.fields.vault.key.errors.required'))
.required(translate('withdraw.xrp.confirm.fields.vault.key.errors.required'))
.test(
'validation',
I18n.t('withdraw.xrp.confirm.fields.vault.key.errors.invalid'),
translate('withdraw.xrp.confirm.fields.vault.key.errors.invalid'),
val => isValidMnemonic(val) && isKeySigner(network, val, signers)
)
});
4 changes: 2 additions & 2 deletions src/hooks/useErrors.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { I18n } from '../lib/i18n/provider';
import { Toaster } from '../components/Toaster';
import { translate } from '../lib/i18n';
import { useEffect, useRef } from 'react';
import { useWatch } from 'react-hook-form';
import get from 'lodash/get';
Expand Down Expand Up @@ -57,7 +57,7 @@ export const useErrors = (
}

if (!Object.keys(errorsRef.current).some(field => field in previousRef.current) && showGenericError) {
Toaster.showError(I18n.t('messages.error.default'));
Toaster.showError(translate('messages.error.default'));

return;
}
Expand Down
8 changes: 3 additions & 5 deletions src/hooks/useTranslation.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { I18n } from '../lib/i18n/provider';
import { translate } from '../lib/i18n';
import i18next from 'react-i18next';

export const useTranslation = () => {
const exists = I18n.exists.bind(I18n);
const translate = I18n.t.bind(I18n);

return { exists, t: translate };
return { I18n: i18next, t: translate };
};
40 changes: 0 additions & 40 deletions src/lib/i18n/dayjs.js

This file was deleted.

106 changes: 0 additions & 106 deletions src/lib/i18n/fromNowFormatted.js

This file was deleted.

76 changes: 66 additions & 10 deletions src/lib/i18n/i18n.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,73 @@
import * as locales from '../../assets/locales';
import { I18n } from './provider';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import dayjs from './dayjs';
import React, { Fragment } from 'react';
import i18next from 'i18next';

const languageDetector = new LanguageDetector(null, {
order: ['navigator', 'querystring', 'cookie', 'sessionStorage', 'localStorage']
export const languageCodes = Object.freeze({
EN: 'en',
ES: 'es'
});

languageDetector.addDetector({
cacheUserLanguage: language => dayjs.locale(language),
name: 'dayjs'
});
languageDetector.options.caches.push('dayjs');
const interpolationMatch = /({{[^}]*}})/gm;

const hasComponent = options => {
try {
return Object.values(options).some(React.isValidElement);
} catch (error) {
return false;
}
};

const renderNestedComponents = (key, options) => {
const rawValue = i18next.t(key, { skipInterpolation: true });

return (
<Fragment>
{rawValue.split(interpolationMatch).map((value, index) => {
if (!interpolationMatch.test(value)) {
return value;
}

const interpolationKey = value.replace(/{|}/g, '');
const optionValue = options?.[interpolationKey];

if (optionValue) {
return <Fragment key={index}>{optionValue}</Fragment>;
}
})}
</Fragment>
);
};

export const setLocales = (locales = {}) => {
Object.entries(locales).forEach(([lang, locale = {}]) =>
Object.entries(locale).forEach(([ns, values]) => i18next.addResourceBundle(lang, ns, values, true, true))
);
};

export const translate = (key, options) => {
if (hasComponent(options)) {
return renderNestedComponents(key, options);
}

return i18next.t(key, options);
};

I18n.init([languageDetector, initReactI18next], locales);
i18next
.use(LanguageDetector)
.use(initReactI18next)
.init({
compatibilityJSON: 'v3',
detection: {
order: ['querystring', 'cookie', 'localStorage', 'sessionStorage', 'navigator', 'htmlTag', 'path', 'subdomain']
},
fallbackLng: languageCodes.EN,
interpolation: {
escapeValue: false,
skipOnVariables: false
},
keySeparator: ' ',
resources: Object.fromEntries(Object.entries(locales).map(([lang, locale = {}]) => [lang, locale])),
supportedLngs: Object.values(languageCodes)
});
Loading

0 comments on commit d361949

Please sign in to comment.