Skip to content

Commit 92c4e25

Browse files
committed
frontend: migrate to latest i18next and react-i18next
i18next rewrote its types in latest versions, but defining i18n returnObjects: true does not return the correct type when only specifying a key to an object of translations. This was used for guide entry component to point to an object that contains title and text for the guide entry. It is possible to define a CustomTypeOptions with i18next.d.ts to globally returnObjects: true, but this breaks all regular uses of the t function that should return a string. https://www.i18next.com/overview/typescript#custom-type-options Added local option for each t function that is used for guide entries and remove the global option. Pluralization is used for native notification of newly detected transactions. Other changes: - added condition for i18n.resolvedLanguage as it can be undefined - rewrote unknownError that optionally receives errorMessage - remove type casting for account.syncedAddressesCount - rewrote component that passed t function Tested: - only use of pluralisation (notification.newTxs) works - feetarget customLabel_eth - BB01 unlock.error.e<n> returns correct error message with fallback - render correct translation with context (bb02Bootloader.success or bb02Bootloader.abort) - process parameter works in context (bootloader.progress) - keys using underscore (buy.info.disclaimer.payment.table.2_method)
1 parent 8f18186 commit 92c4e25

File tree

23 files changed

+1111
-1219
lines changed

23 files changed

+1111
-1219
lines changed

frontends/web/package-lock.json

Lines changed: 1013 additions & 1127 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontends/web/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525
"@walletconnect/types": "^2.10.4",
2626
"@walletconnect/web3wallet": "^1.9.3",
2727
"flag-icons": "7.2.3",
28-
"i18next": "21.6.16",
28+
"i18next": "23.11.5",
2929
"lightweight-charts": "4.1.4",
3030
"qr-scanner": "1.4.2",
3131
"react": "18.2.0",
3232
"react-dom": "18.2.0",
33-
"react-i18next": "11.16.8",
33+
"react-i18next": "14.1.2",
3434
"react-router-dom": "6.4.3",
3535
"react-select": "5.8.0",
3636
"request-address": "0.0.6"

frontends/web/src/components/banner/banner.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ export const Banner = ({ msgKey }: TBannerProps) => {
3535
syncBanner(msgKey, setBanner);
3636
}, [msgKey]);
3737

38-
if (!banner || !i18n.options.fallbackLng) {
38+
if (
39+
!banner
40+
|| !i18n.options.fallbackLng
41+
|| !i18n.resolvedLanguage
42+
) {
3943
return null;
4044
}
4145
const { message, link } = banner;

frontends/web/src/i18n/i18n.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ i18Init.init({
5353
defaultNS: 'app',
5454

5555
debug: false,
56-
returnObjects: true,
5756

5857
interpolation: {
5958
escapeValue: false // not needed for react

frontends/web/src/routes/account/add/add-account-guide.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ export const AddAccountGuide = ({ accounts }: TAddAccountGuide) => {
4141
const hasOnlyBTCAccounts = accounts.every(({ coinCode }) => isBitcoinOnly(coinCode));
4242
return (
4343
<Guide>
44-
<Entry key="whatAreAccounts" entry={t('guide.accounts.whatAreAccounts')} />
45-
<Entry key="whyIsThisUseful" entry={t('guide.accounts.whyIsThisUseful')} />
46-
<Entry key="recoverAccounts" entry={t('guide.accounts.recoverAccounts')} />
47-
<Entry key="moveFunds" entry={t('guide.accounts.moveFunds')} />
44+
<Entry key="whatAreAccounts" entry={t('guide.accounts.whatAreAccounts', { returnObjects: true })} />
45+
<Entry key="whyIsThisUseful" entry={t('guide.accounts.whyIsThisUseful', { returnObjects: true })} />
46+
<Entry key="recoverAccounts" entry={t('guide.accounts.recoverAccounts', { returnObjects: true })} />
47+
<Entry key="moveFunds" entry={t('guide.accounts.moveFunds', { returnObjects: true })} />
4848
{ !hasOnlyBTCAccounts && (
4949
<>
5050
<Entry key="supportedCoins" entry={{
@@ -55,10 +55,10 @@ export const AddAccountGuide = ({ accounts }: TAddAccountGuide) => {
5555
text: t('guide.accounts.supportedCoins.text'),
5656
title: t('guide.accounts.supportedCoins.title'),
5757
}} />
58-
<Entry key="howtoAddTokens" entry={t('guide.accounts.howtoAddTokens')} />
58+
<Entry key="howtoAddTokens" entry={t('guide.accounts.howtoAddTokens', { returnObjects: true })} />
5959
</>
6060
)}
61-
<Entry key="howManyAccounts" entry={t('guide.accounts.howManyAccounts')} />
61+
<Entry key="howManyAccounts" entry={t('guide.accounts.howManyAccounts', { returnObjects: true })} />
6262
</Guide>
6363
);
6464
};

frontends/web/src/routes/account/guide.tsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,30 +39,31 @@ export const AccountGuide = ({
3939
const { t } = useTranslation();
4040
return (
4141
<Guide title={t('guide.guideTitle.account')}>
42-
<Entry key="accountDescription" entry={t('guide.accountDescription')} />
42+
<Entry key="accountDescription" entry={t('guide.accountDescription', { returnObjects: true })} />
4343
{hasNoBalance && (
4444
<Entry key="accountSendDisabled" entry={t('guide.accountSendDisabled', {
45-
unit
45+
unit,
46+
returnObjects: true
4647
})} />
4748
)}
48-
<Entry key="accountReload" entry={t('guide.accountReload')} />
49+
<Entry key="accountReload" entry={t('guide.accountReload', { returnObjects: true })} />
4950
{hasTransactions && (
50-
<Entry key="accountTransactionLabel" entry={t('guide.accountTransactionLabel')} />
51+
<Entry key="accountTransactionLabel" entry={t('guide.accountTransactionLabel', { returnObjects: true })} />
5152
)}
5253
{hasTransactions && (
53-
<Entry key="accountTransactionTime" entry={t('guide.accountTransactionTime')} />
54+
<Entry key="accountTransactionTime" entry={t('guide.accountTransactionTime', { returnObjects: true })} />
5455
)}
5556
{hasTransactions && (
56-
<Entry key="accountTransactionAttributesGeneric" entry={t('guide.accountTransactionAttributesGeneric')} />
57+
<Entry key="accountTransactionAttributesGeneric" entry={t('guide.accountTransactionAttributesGeneric', { returnObjects: true })} />
5758
)}
5859
{hasTransactions && isBitcoinBased(account.coinCode) && (
59-
<Entry key="accountTransactionAttributesBTC" entry={t('guide.accountTransactionAttributesBTC')} />
60+
<Entry key="accountTransactionAttributesBTC" entry={t('guide.accountTransactionAttributesBTC', { returnObjects: true })} />
6061
)}
6162
{hasIncomingBalance && (
62-
<Entry key="accountIncomingBalance" entry={t('guide.accountIncomingBalance')} />
63+
<Entry key="accountIncomingBalance" entry={t('guide.accountIncomingBalance', { returnObjects: true })} />
6364
)}
64-
<Entry key="accountTransactionConfirmation" entry={t('guide.accountTransactionConfirmation')} />
65-
<Entry key="accountFiat" entry={t('guide.accountFiat')} />
65+
<Entry key="accountTransactionConfirmation" entry={t('guide.accountTransactionConfirmation', { returnObjects: true })} />
66+
<Entry key="accountFiat" entry={t('guide.accountFiat', { returnObjects: true })} />
6667

6768
{ /* careful, also used in Settings */ }
6869
<Entry key="accountRates" entry={{

frontends/web/src/routes/account/info/guide.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ export const BitcoinBasedAccountInfoGuide = ({
2828
const { t } = useTranslation();
2929
return (
3030
<Guide title={t('guide.guideTitle.accountInformation')}>
31-
<Entry key="guide.accountInfo.xpub" entry={t('guide.accountInfo.xpub')} shown={true} />
31+
<Entry key="guide.accountInfo.xpub" entry={t('guide.accountInfo.xpub', { returnObjects: true })} shown={true} />
3232
<Entry key="guide.accountInfo.multipleXPubs" entry={{
3333
text: t('guide.accountInfo.multipleXPubs.text', { coinName }),
3434
title: t('guide.accountInfo.multipleXPubs.title'),
3535
}} />
36-
<Entry key="guide.accountInfo.privacy" entry={t('guide.accountInfo.privacy')} />
37-
<Entry key="guide.accountInfo.verify" entry={t('guide.accountInfo.verify')} />
36+
<Entry key="guide.accountInfo.privacy" entry={t('guide.accountInfo.privacy', { returnObjects: true })} />
37+
<Entry key="guide.accountInfo.verify" entry={t('guide.accountInfo.verify', { returnObjects: true })} />
3838
</Guide>
3939
);
4040
};

frontends/web/src/routes/account/receive/components/guide.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,17 @@ export const ReceiveGuide = ({
3030
const { t } = useTranslation();
3131
return (
3232
<Guide title={t('guide.guideTitle.receive')}>
33-
<Entry key="guide.receive.address" entry={t('guide.receive.address')} />
34-
<Entry key="guide.receive.whyVerify" entry={t('guide.receive.whyVerify')} />
35-
<Entry key="guide.receive.howVerify" entry={t('guide.receive.howVerify')} />
36-
<Entry key="guide.receive.plugout" entry={t('guide.receive.plugout')} />
33+
<Entry key="guide.receive.address" entry={t('guide.receive.address', { returnObjects: true })} />
34+
<Entry key="guide.receive.whyVerify" entry={t('guide.receive.whyVerify', { returnObjects: true })} />
35+
<Entry key="guide.receive.howVerify" entry={t('guide.receive.howVerify', { returnObjects: true })} />
36+
<Entry key="guide.receive.plugout" entry={t('guide.receive.plugout', { returnObjects: true })} />
3737
{hasMultipleAddresses && (
3838
<>
39-
<Entry key="guide.receive.whyMany" entry={t('guide.receive.whyMany')} />
40-
<Entry key="guide.receive.why20" entry={t('guide.receive.why20')} />
41-
<Entry key="guide.receive.addressChange" entry={t('guide.receive.addressChange')} />
39+
<Entry key="guide.receive.whyMany" entry={t('guide.receive.whyMany', { returnObjects: true })} />
40+
<Entry key="guide.receive.why20" entry={t('guide.receive.why20', { returnObjects: true })} />
41+
<Entry key="guide.receive.addressChange" entry={t('guide.receive.addressChange', { returnObjects: true })} />
4242
{hasDifferentFormats && (
43-
<Entry key="guide.receive.addressFormats" entry={t('guide.receive.addressFormats')} />
43+
<Entry key="guide.receive.addressFormats" entry={t('guide.receive.addressFormats', { returnObjects: true })} />
4444
)}
4545
</>
4646
)}

frontends/web/src/routes/account/send/send-guide.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,18 @@ export const SendGuide = ({ coinCode }: TProps) => {
1212
const { t } = useTranslation();
1313
return (
1414
<Guide title={t('guide.guideTitle.send')}>
15-
<Entry key="guide.send.whyFee" entry={t('guide.send.whyFee')} />
15+
<Entry key="guide.send.whyFee" entry={t('guide.send.whyFee', { returnObjects: true })} />
1616
{ isBitcoinBased(coinCode) && (
17-
<Entry key="guide.send.priority" entry={t('guide.send.priority')} />
17+
<Entry key="guide.send.priority" entry={t('guide.send.priority', { returnObjects: true })} />
1818
)}
1919
{ isBitcoinBased(coinCode) && (
20-
<Entry key="guide.send.fee" entry={t('guide.send.fee')} />
20+
<Entry key="guide.send.fee" entry={t('guide.send.fee', { returnObjects: true })} />
2121
)}
2222
{ isBitcoinOnly(coinCode) && (
23-
<Entry key="guide.send.change" entry={t('guide.send.change')} />
23+
<Entry key="guide.send.change" entry={t('guide.send.change', { returnObjects: true })} />
2424
)}
25-
<Entry key="guide.send.revert" entry={t('guide.send.revert')} />
26-
<Entry key="guide.send.plugout" entry={t('guide.send.plugout')} />
25+
<Entry key="guide.send.revert" entry={t('guide.send.revert', { returnObjects: true })} />
26+
<Entry key="guide.send.plugout" entry={t('guide.send.plugout', { returnObjects: true })} />
2727
</Guide>
2828
);
2929
};

frontends/web/src/routes/account/send/send.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,11 @@ class Send extends Component<Props, State> {
229229
break;
230230
default:
231231
const { errorMessage } = result;
232-
alertUser(this.props.t('unknownError', errorMessage && { errorMessage }));
232+
if (errorMessage) {
233+
alertUser(this.props.t('unknownError', { errorMessage }));
234+
} else {
235+
alertUser(this.props.t('unknownError'));
236+
}
233237
}
234238
}
235239
} catch (err) {

0 commit comments

Comments
 (0)