diff --git a/src/actions/DiscoveryActions.js b/src/actions/DiscoveryActions.js
index 154de83c..c3734327 100644
--- a/src/actions/DiscoveryActions.js
+++ b/src/actions/DiscoveryActions.js
@@ -1,5 +1,6 @@
/* @flow */
-
+import React from 'react';
+import { FormattedMessage } from 'react-intl';
import TrezorConnect, { UI } from 'trezor-connect';
import * as BLOCKCHAIN_ACTION from 'actions/constants/blockchain';
import * as DISCOVERY from 'actions/constants/discovery';
@@ -17,6 +18,8 @@ import type {
Account,
} from 'flowtype';
import type { Discovery, State } from 'reducers/DiscoveryReducer';
+import l10nMessages from 'components/notifications/Context/actions.messages';
+import l10nCommonMessages from 'views/common.messages';
import * as BlockchainActions from './BlockchainActions';
import * as EthereumDiscoveryActions from './ethereum/DiscoveryActions';
import * as RippleDiscoveryActions from './ripple/DiscoveryActions';
@@ -176,12 +179,12 @@ const begin = (device: TrezorDevice, networkName: string): AsyncAction => async
type: NOTIFICATION.ADD,
payload: {
variant: 'error',
- title: 'Discovery error',
+ title: ,
message: error.message,
cancelable: true,
actions: [
{
- label: 'Try again',
+ label: ,
callback: () => {
dispatch(start(device, networkName));
},
@@ -264,12 +267,12 @@ const discoverAccount = (device: TrezorDevice, discoveryProcess: Discovery): Asy
type: NOTIFICATION.ADD,
payload: {
variant: 'error',
- title: 'Account discovery error',
+ title: ,
message: error.message,
cancelable: true,
actions: [
{
- label: 'Try again',
+ label: ,
callback: () => {
dispatch(start(device, discoveryProcess.network));
},
diff --git a/src/actions/NotificationActions.js b/src/actions/NotificationActions.js
index 35ea0c18..9d9af9c2 100644
--- a/src/actions/NotificationActions.js
+++ b/src/actions/NotificationActions.js
@@ -2,7 +2,14 @@
import * as React from 'react';
import * as NOTIFICATION from 'actions/constants/notification';
-import type { Action, AsyncAction, GetState, Dispatch, RouterLocationState } from 'flowtype';
+import type {
+ Action,
+ AsyncAction,
+ GetState,
+ Dispatch,
+ RouterLocationState,
+ MessageDescriptor,
+} from 'flowtype';
import type { CallbackAction } from 'reducers/NotificationReducer';
export type NotificationAction =
@@ -10,7 +17,7 @@ export type NotificationAction =
type: typeof NOTIFICATION.ADD,
payload: {
+variant: string,
- +title: React.Node | string,
+ +title: React.Node | MessageDescriptor | string,
+message?: ?(React.Node | string),
+cancelable: boolean,
actions?: Array,
diff --git a/src/actions/ReceiveActions.js b/src/actions/ReceiveActions.js
index bbb5d247..7516d195 100644
--- a/src/actions/ReceiveActions.js
+++ b/src/actions/ReceiveActions.js
@@ -1,5 +1,6 @@
/* @flow */
-
+import React from 'react';
+import { FormattedMessage } from 'react-intl';
import TrezorConnect from 'trezor-connect';
import * as RECEIVE from 'actions/constants/receive';
import * as NOTIFICATION from 'actions/constants/notification';
@@ -8,6 +9,8 @@ import { initialState } from 'reducers/ReceiveReducer';
import type { State } from 'reducers/ReceiveReducer';
import type { TrezorDevice, ThunkAction, AsyncAction, Action, GetState, Dispatch } from 'flowtype';
+import l10nMessages from 'components/notifications/Context/actions.messages';
+import l10nCommonMessages from 'views/common.messages';
export type ReceiveAction =
| {
@@ -112,12 +115,12 @@ export const showAddress = (path: Array): AsyncAction => async (
type: NOTIFICATION.ADD,
payload: {
variant: 'error',
- title: 'Verifying address error',
+ title: ,
message: response.payload.error,
cancelable: true,
actions: [
{
- label: 'Try again',
+ label: ,
callback: () => {
dispatch(showAddress(path));
},
diff --git a/src/actions/SignVerifyActions.js b/src/actions/SignVerifyActions.js
index ecfe784b..a0722196 100644
--- a/src/actions/SignVerifyActions.js
+++ b/src/actions/SignVerifyActions.js
@@ -1,8 +1,11 @@
/* @flow */
+import React from 'react';
+import { FormattedMessage } from 'react-intl';
import TrezorConnect from 'trezor-connect';
import type { GetState, Dispatch, ThunkAction, AsyncAction } from 'flowtype';
import { validateAddress } from 'utils/ethUtils';
import * as NOTIFICATION from 'actions/constants/notification';
+import l10nMessages from 'components/notifications/Context/actions.messages';
import * as SIGN_VERIFY from './constants/signVerify';
export type SignVerifyAction =
@@ -65,7 +68,7 @@ const sign = (path: Array, message: string, hex: boolean = false): Async
type: NOTIFICATION.ADD,
payload: {
variant: 'error',
- title: 'Sign error',
+ title: ,
message: response.payload.error,
cancelable: true,
},
@@ -110,8 +113,8 @@ const verify = (
type: NOTIFICATION.ADD,
payload: {
variant: 'success',
- title: 'Verify success',
- message: 'signature is valid',
+ title: ,
+ message: ,
cancelable: true,
},
});
@@ -120,7 +123,7 @@ const verify = (
type: NOTIFICATION.ADD,
payload: {
variant: 'error',
- title: 'Verify error',
+ title: ,
message: response.payload.error,
cancelable: true,
},
diff --git a/src/actions/TrezorConnectActions.js b/src/actions/TrezorConnectActions.js
index bfa52881..e60931ab 100644
--- a/src/actions/TrezorConnectActions.js
+++ b/src/actions/TrezorConnectActions.js
@@ -6,6 +6,8 @@ import TrezorConnect, {
TRANSPORT_EVENT,
BLOCKCHAIN_EVENT,
} from 'trezor-connect';
+import React from 'react';
+import { FormattedMessage } from 'react-intl';
import { CONTEXT_NONE } from 'actions/constants/modal';
import urlConstants from 'constants/urls';
import * as CONNECT from 'actions/constants/TrezorConnect';
@@ -35,6 +37,9 @@ import type {
TrezorDevice,
} from 'flowtype';
+import l10nCommonMessages from 'views/common.messages';
+import l10nMessages from 'components/notifications/Context/actions.messages';
+
export type TrezorConnectAction =
| {
type: typeof CONNECT.INITIALIZATION_ERROR,
@@ -264,12 +269,12 @@ export const authorizeDevice = (): AsyncAction => async (
payload: {
devicePath: selected.path,
variant: 'error',
- title: 'Authentication error',
+ title: ,
message: response.payload.error,
cancelable: false,
actions: [
{
- label: 'Try again',
+ label: ,
callback: () => {
dispatch({
type: NOTIFICATION.CLOSE,
@@ -351,7 +356,7 @@ export function acquire(): AsyncAction {
payload: {
type: 'error',
variant: 'error',
- title: 'Acquire device error',
+ title: ,
message: response.payload.error,
cancelable: true,
// actions: [
diff --git a/src/actions/ethereum/SendFormActions.js b/src/actions/ethereum/SendFormActions.js
index 094a9158..92877a12 100644
--- a/src/actions/ethereum/SendFormActions.js
+++ b/src/actions/ethereum/SendFormActions.js
@@ -1,5 +1,6 @@
/* @flow */
import React from 'react';
+import { FormattedMessage } from 'react-intl';
import { Link } from 'trezor-ui-components';
import TrezorConnect from 'trezor-connect';
import BigNumber from 'bignumber.js';
@@ -23,10 +24,10 @@ import type {
TrezorDevice,
} from 'flowtype';
import type { State, FeeLevel } from 'reducers/SendFormEthereumReducer';
+import l10nMessages from 'components/notifications/Context/actions.messages';
import * as SessionStorageActions from '../SessionStorageActions';
import { prepareEthereumTx, serializeEthereumTx } from '../TxActions';
import * as BlockchainActions from './BlockchainActions';
-
import * as ValidationActions from './SendFormValidationActions';
// list of all actions which has influence on "sendFormEthereum" reducer
@@ -717,7 +718,7 @@ export const onSend = (): AsyncAction => async (
type: NOTIFICATION.ADD,
payload: {
variant: 'error',
- title: 'Transaction error',
+ title: ,
message: signedTransaction.payload.error,
cancelable: true,
actions: [],
@@ -807,10 +808,10 @@ export const onSend = (): AsyncAction => async (
type: NOTIFICATION.ADD,
payload: {
variant: 'success',
- title: 'Transaction success',
+ title: ,
message: (
- See transaction detail
+
),
cancelable: true,
@@ -822,7 +823,7 @@ export const onSend = (): AsyncAction => async (
type: NOTIFICATION.ADD,
payload: {
variant: 'error',
- title: 'Transaction error',
+ title: ,
message: error.message || error,
cancelable: true,
actions: [],
diff --git a/src/actions/ethereum/SendFormValidationActions.js b/src/actions/ethereum/SendFormValidationActions.js
index c213710d..33aa0ec6 100644
--- a/src/actions/ethereum/SendFormValidationActions.js
+++ b/src/actions/ethereum/SendFormValidationActions.js
@@ -11,6 +11,8 @@ import * as validators from 'utils/validators';
import type { Dispatch, GetState, PayloadAction } from 'flowtype';
import type { State, FeeLevel } from 'reducers/SendFormEthereumReducer';
+import l10nMessages from 'views/Wallet/views/Account/Send/validation.messages';
+import l10nCommonMessages from 'views/common.messages';
/*
* Called from SendFormActions.observe
@@ -150,14 +152,14 @@ export const addressValidation = ($state: State): PayloadAction => (): St
const { address } = state;
if (address.length < 1) {
- state.errors.address = 'Address is not set';
+ state.errors.address = l10nMessages.TR_ADDRESS_IS_NOT_SET;
} else if (!EthereumjsUtil.isValidAddress(address)) {
- state.errors.address = 'Address is not valid';
+ state.errors.address = l10nMessages.TR_ADDRESS_IS_NOT_VALID;
} else if (
validators.hasUppercase(address) &&
!EthereumjsUtil.isValidChecksumAddress(address)
) {
- state.errors.address = 'Address is not a valid checksum';
+ state.errors.address = l10nMessages.TR_ADDRESS_CHECKSUM_IS_NOT_VALID;
}
return state;
};
@@ -189,9 +191,13 @@ export const addressLabel = ($state: State): PayloadAction => (
currentNetworkAccount.deviceState
);
if (device) {
- state.infos.address = `${
- device.instanceLabel
- } Account #${currentNetworkAccount.index + 1}`;
+ state.infos.address = {
+ ...l10nCommonMessages.TR_DEVICE_LABEL_ACCOUNT_HASH,
+ values: {
+ deviceLabel: device.instanceLabel,
+ number: currentNetworkAccount.index + 1,
+ },
+ };
}
} else {
// corner-case: the same derivation path is used on different networks
@@ -204,11 +210,14 @@ export const addressLabel = ($state: State): PayloadAction => (
const { networks } = getState().localStorage.config;
const otherNetwork = networks.find(c => c.shortcut === otherNetworkAccount.network);
if (device && otherNetwork) {
- state.warnings.address = `Looks like it's ${
- device.instanceLabel
- } Account #${otherNetworkAccount.index + 1} address of ${
- otherNetwork.name
- } network`;
+ state.warnings.address = {
+ ...l10nCommonMessages.TR_LOOKS_LIKE_IT_IS_DEVICE_LABEL,
+ values: {
+ deviceLabel: device.instanceLabel,
+ number: otherNetworkAccount.index + 1,
+ network: otherNetwork.name,
+ },
+ };
}
}
}
@@ -231,9 +240,9 @@ export const amountValidation = ($state: State): PayloadAction => (
const { amount } = state;
if (amount.length < 1) {
- state.errors.amount = 'Amount is not set';
+ state.errors.amount = l10nMessages.TR_AMOUNT_IS_NOT_SET;
} else if (amount.length > 0 && !validators.isNumber(amount)) {
- state.errors.amount = 'Amount is not a number';
+ state.errors.amount = l10nMessages.TR_AMOUNT_IS_NOT_A_NUMBER;
} else {
const isToken: boolean = state.currency !== state.networkSymbol;
const pendingAmount: BigNumber = getPendingAmount(pending, state.currency, isToken);
@@ -248,26 +257,40 @@ export const amountValidation = ($state: State): PayloadAction => (
if (!token) return state;
if (!validators.hasDecimals(state.amount, parseInt(token.decimals, 0))) {
- state.errors.amount = `Maximum ${token.decimals} decimals allowed`;
+ state.errors.amount = {
+ ...l10nMessages.TR_MAXIMUM_DECIMALS_ALLOWED,
+ values: { decimals: token.decimals },
+ };
} else if (new BigNumber(state.total).isGreaterThan(account.balance)) {
- state.errors.amount = `Not enough ${state.networkSymbol} to cover transaction fee`;
+ state.errors.amount = {
+ ...l10nMessages.TR_NOT_ENOUGH_FUNDS_TO_COVER_TRANSACTION,
+ values: {
+ networkSymbol: state.networkSymbol,
+ },
+ };
} else if (
new BigNumber(state.amount).isGreaterThan(
new BigNumber(token.balance).minus(pendingAmount)
)
) {
- state.errors.amount = 'Not enough funds';
+ state.errors.amount = l10nMessages.TR_NOT_ENOUGH_FUNDS;
} else if (new BigNumber(state.amount).isLessThanOrEqualTo('0')) {
- state.errors.amount = 'Amount is too low';
+ // TODO: this is never gonna happen! It will fail in second if condiftion (isNumber validation)
+ state.errors.amount = l10nMessages.TR_AMOUNT_IS_TOO_LOW;
}
} else if (!validators.hasDecimals(state.amount, 18)) {
- state.errors.amount = 'Maximum 18 decimals allowed';
+ state.errors.amount = {
+ ...l10nMessages.TR_MAXIMUM_DECIMALS_ALLOWED,
+ values: {
+ decimals: 18,
+ },
+ };
} else if (
new BigNumber(state.total).isGreaterThan(
new BigNumber(account.balance).minus(pendingAmount)
)
) {
- state.errors.amount = 'Not enough funds';
+ state.errors.amount = l10nMessages.TR_NOT_ENOUGH_FUNDS;
}
}
return state;
@@ -288,13 +311,13 @@ export const gasLimitValidation = ($state: State): PayloadAction => (
const { gasLimit } = state;
if (gasLimit.length < 1) {
- state.errors.gasLimit = 'Gas limit is not set';
+ state.errors.gasLimit = l10nMessages.TR_GAS_LIMIT_IS_NOT_SET;
} else if (gasLimit.length > 0 && !validators.isNumber(gasLimit)) {
- state.errors.gasLimit = 'Gas limit is not a number';
+ state.errors.gasLimit = l10nMessages.TR_GAS_LIMIT_IS_NOT_A_NUMBER;
} else {
const gl: BigNumber = new BigNumber(gasLimit);
if (gl.isLessThan(1)) {
- state.errors.gasLimit = 'Gas limit is too low';
+ state.errors.gasLimit = l10nMessages.TR_GAS_LIMIT_IS_TOO_LOW;
} else if (
gl.isLessThan(
state.currency !== state.networkSymbol
@@ -302,7 +325,7 @@ export const gasLimitValidation = ($state: State): PayloadAction => (
: network.defaultGasLimit
)
) {
- state.warnings.gasLimit = 'Gas limit is below recommended';
+ state.warnings.gasLimit = l10nMessages.TR_GAS_LIMIT_IS_BELOW_RECOMMENDED;
}
}
return state;
@@ -317,15 +340,15 @@ export const gasPriceValidation = ($state: State): PayloadAction => (): S
const { gasPrice } = state;
if (gasPrice.length < 1) {
- state.errors.gasPrice = 'Gas price is not set';
+ state.errors.gasPrice = l10nMessages.TR_GAS_PRICE_IS_NOT_SET;
} else if (gasPrice.length > 0 && !validators.isNumber(gasPrice)) {
- state.errors.gasPrice = 'Gas price is not a number';
+ state.errors.gasPrice = l10nMessages.TR_GAS_PRICE_IS_NOT_A_NUMBER;
} else {
const gp: BigNumber = new BigNumber(gasPrice);
if (gp.isGreaterThan(1000)) {
- state.warnings.gasPrice = 'Gas price is too high';
+ state.warnings.gasPrice = l10nMessages.TR_GAS_PRICE_IS_TOO_HIGH;
} else if (gp.isLessThanOrEqualTo('0')) {
- state.errors.gasPrice = 'Gas price is too low';
+ state.errors.gasPrice = l10nMessages.TR_GAS_PRICE_IS_TOO_LOW;
}
}
return state;
@@ -346,28 +369,29 @@ export const nonceValidation = ($state: State): PayloadAction => (
const { nonce } = state;
if (nonce.length < 1) {
- state.errors.nonce = 'Nonce is not set';
+ state.errors.nonce = l10nMessages.TR_NONCE_IS_NOT_SET;
} else if (!validators.isAbs(nonce)) {
- state.errors.nonce = 'Nonce is not a valid number';
+ state.errors.nonce = l10nMessages.TR_NONCE_IS_NOT_A_NUMBER;
} else {
const n: BigNumber = new BigNumber(nonce);
if (n.isLessThan(account.nonce)) {
- state.warnings.nonce = 'Nonce is lower than recommended';
+ state.warnings.nonce = l10nMessages.TR_NONCE_IS_LOWER_THAN_RECOMMENDED;
} else if (n.isGreaterThan(account.nonce)) {
- state.warnings.nonce = 'Nonce is greater than recommended';
+ state.warnings.nonce = l10nMessages.TR_NONCE_IS_GREATER_THAN_RECOMMENDED;
}
}
return state;
};
/*
- * Gas price value validation
+ * Data validation
*/
export const dataValidation = ($state: State): PayloadAction => (): State => {
const state = { ...$state };
if (!state.touched.data || state.data.length === 0) return state;
+
if (!ethUtils.isHex(state.data)) {
- state.errors.data = 'Data is not valid hexadecimal';
+ state.errors.data = l10nMessages.TR_DATA_IS_NOT_VALID_HEX;
}
return state;
};
@@ -432,12 +456,13 @@ export const getFeeLevels = (
selected && selected.value === 'Custom'
? {
value: 'Custom',
+ localizedValue: l10nCommonMessages.TR_CUSTOM_FEE,
gasPrice: selected.gasPrice,
- // label: `${ calculateFee(gasPrice, gasLimit) } ${ symbol }`
label: `${calculateFee(selected.gasPrice, gasLimit)} ${symbol}`,
}
: {
value: 'Custom',
+ localizedValue: l10nCommonMessages.TR_CUSTOM_FEE,
gasPrice: low,
label: '',
};
@@ -445,16 +470,19 @@ export const getFeeLevels = (
return [
{
value: 'High',
+ localizedValue: l10nCommonMessages.TR_HIGH_FEE,
gasPrice: high,
label: `${calculateFee(high, gasLimit)} ${symbol}`,
},
{
value: 'Normal',
+ localizedValue: l10nCommonMessages.TR_NORMAL_FEE,
gasPrice: gasPrice.toString(),
label: `${calculateFee(price.toFixed(), gasLimit)} ${symbol}`,
},
{
value: 'Low',
+ localizedValue: l10nCommonMessages.TR_LOW_FEE,
gasPrice: low,
label: `${calculateFee(low, gasLimit)} ${symbol}`,
},
diff --git a/src/actions/ripple/SendFormActions.js b/src/actions/ripple/SendFormActions.js
index 302d0051..fce5ef8b 100644
--- a/src/actions/ripple/SendFormActions.js
+++ b/src/actions/ripple/SendFormActions.js
@@ -1,4 +1,6 @@
/* @flow */
+import React from 'react';
+import { FormattedMessage } from 'react-intl';
import TrezorConnect from 'trezor-connect';
import * as NOTIFICATION from 'actions/constants/notification';
import * as SEND from 'actions/constants/send';
@@ -19,6 +21,7 @@ import type {
TrezorDevice,
} from 'flowtype';
import type { State, FeeLevel } from 'reducers/SendFormRippleReducer';
+import l10nMessages from 'components/notifications/Context/actions.messages';
import * as SessionStorageActions from '../SessionStorageActions';
import * as BlockchainActions from './BlockchainActions';
@@ -455,7 +458,7 @@ export const onSend = (): AsyncAction => async (
type: NOTIFICATION.ADD,
payload: {
variant: 'error',
- title: 'Transaction error',
+ title: ,
message: signedTransaction.payload.error,
cancelable: true,
actions: [],
@@ -474,7 +477,7 @@ export const onSend = (): AsyncAction => async (
type: NOTIFICATION.ADD,
payload: {
variant: 'error',
- title: 'Transaction error',
+ title: ,
message: push.payload.error,
cancelable: true,
actions: [],
@@ -497,7 +500,7 @@ export const onSend = (): AsyncAction => async (
type: NOTIFICATION.ADD,
payload: {
variant: 'success',
- title: 'Transaction success',
+ title: ,
message: txid,
cancelable: true,
actions: [],
diff --git a/src/actions/ripple/SendFormValidationActions.js b/src/actions/ripple/SendFormValidationActions.js
index d24ff34c..cf400427 100644
--- a/src/actions/ripple/SendFormValidationActions.js
+++ b/src/actions/ripple/SendFormValidationActions.js
@@ -6,6 +6,8 @@ import { findDevice, getPendingAmount } from 'reducers/utils';
import { toDecimalAmount } from 'utils/formatUtils';
import { toFiatCurrency } from 'utils/fiatConverter';
import * as validators from 'utils/validators';
+import l10nMessages from 'views/Wallet/views/Account/Send/validation.messages';
+import l10nCommonMessages from 'views/common.messages';
import type {
Dispatch,
@@ -150,11 +152,11 @@ const addressValidation = ($state: State): PayloadAction => (
const { address } = state;
if (address.length < 1) {
- state.errors.address = 'Address is not set';
+ state.errors.address = l10nMessages.TR_ADDRESS_IS_NOT_SET;
} else if (!AddressValidator.validate(address, 'XRP')) {
- state.errors.address = 'Address is not valid';
+ state.errors.address = l10nMessages.TR_ADDRESS_IS_NOT_VALID;
} else if (address.toLowerCase() === account.descriptor.toLowerCase()) {
- state.errors.address = 'Cannot send to myself';
+ state.errors.address = l10nMessages.TR_CANNOT_SEND_TO_MYSELF;
}
return state;
};
@@ -226,9 +228,13 @@ const addressLabel = ($state: State): PayloadAction => (
currentNetworkAccount.deviceState
);
if (device) {
- state.infos.address = `${
- device.instanceLabel
- } Account #${currentNetworkAccount.index + 1}`;
+ state.infos.address = {
+ ...l10nCommonMessages.TR_DEVICE_LABEL_ACCOUNT_HASH,
+ values: {
+ deviceLabel: device.instanceLabel,
+ number: currentNetworkAccount.index + 1,
+ },
+ };
}
} else {
// corner-case: the same derivation path is used on different networks
@@ -241,11 +247,14 @@ const addressLabel = ($state: State): PayloadAction => (
const { networks } = getState().localStorage.config;
const otherNetwork = networks.find(c => c.shortcut === otherNetworkAccount.network);
if (device && otherNetwork) {
- state.warnings.address = `Looks like it's ${
- device.instanceLabel
- } Account #${otherNetworkAccount.index + 1} address of ${
- otherNetwork.name
- } network`;
+ state.warnings.address = {
+ ...l10nCommonMessages.TR_LOOKS_LIKE_IT_IS_DEVICE_LABEL,
+ values: {
+ deviceLabel: device.instanceLabel,
+ number: otherNetworkAccount.index + 1,
+ network: otherNetwork.name,
+ },
+ };
}
}
}
@@ -268,19 +277,22 @@ const amountValidation = ($state: State): PayloadAction => (
const { amount } = state;
if (amount.length < 1) {
- state.errors.amount = 'Amount is not set';
+ state.errors.amount = l10nMessages.TR_AMOUNT_IS_NOT_SET;
} else if (amount.length > 0 && !validators.isNumber(amount)) {
- state.errors.amount = 'Amount is not a number';
+ state.errors.amount = l10nMessages.TR_AMOUNT_IS_NOT_A_NUMBER;
} else {
const pendingAmount: BigNumber = getPendingAmount(pending, state.networkSymbol);
if (!validators.hasDecimals(state.amount, 6)) {
- state.errors.amount = 'Maximum 6 decimals allowed';
+ state.errors.amount = {
+ ...l10nMessages.TR_MAXIMUM_DECIMALS_ALLOWED,
+ values: { decimals: 6 },
+ };
} else if (
new BigNumber(state.total).isGreaterThan(
new BigNumber(account.balance).minus(pendingAmount)
)
) {
- state.errors.amount = 'Not enough funds';
+ state.errors.amount = l10nMessages.TR_NOT_ENOUGH_FUNDS;
}
}
@@ -288,15 +300,23 @@ const amountValidation = ($state: State): PayloadAction => (
!state.errors.amount &&
new BigNumber(account.balance).minus(state.total).lt(account.reserve)
) {
- state.errors.amount = `Not enough funds. Reserved amount for this account is ${
- account.reserve
- } ${state.networkSymbol}`;
+ state.errors.amount = {
+ ...l10nMessages.TR_NOT_ENOUGH_FUNDS_RESERVED_AMOUNT,
+ values: {
+ reservedAmount: account.reserve,
+ networkSymbol: state.networkSymbol,
+ },
+ };
}
if (!state.errors.amount && new BigNumber(state.amount).lt(state.minAmount)) {
- state.errors.amount = `Amount is too low. Minimum amount for creating a new account is ${
- state.minAmount
- } ${state.networkSymbol}`;
+ state.errors.amount = {
+ ...l10nMessages.TR_AMOUNT_IS_TOO_LOW_MINIMUM_AMOUNT_FOR_CREATING,
+ values: {
+ reservedAmount: state.minAmount,
+ networkSymbol: state.networkSymbol,
+ },
+ };
}
return state;
@@ -317,15 +337,15 @@ export const feeValidation = ($state: State): PayloadAction => (
const { fee } = state;
if (fee.length < 1) {
- state.errors.fee = 'Fee is not set';
+ state.errors.fee = l10nMessages.TR_FEE_IS_NOT_SET;
} else if (fee.length > 0 && !validators.isAbs(fee)) {
- state.errors.fee = 'Fee must be an absolute number';
+ state.errors.fee = l10nMessages.TR_FEE_MUST_ME_AN_ABSOLUT_NUMBER;
} else {
const gl: BigNumber = new BigNumber(fee);
if (gl.isLessThan(network.fee.minFee)) {
- state.errors.fee = 'Fee is below recommended';
+ state.errors.fee = l10nMessages.TR_FEE_IS_BELOW_RECOMMENDED;
} else if (gl.isGreaterThan(network.fee.maxFee)) {
- state.errors.fee = 'Fee is above recommended';
+ state.errors.fee = l10nMessages.TR_FEE_IS_ABOVE_RECOMMENDED;
}
}
return state;
@@ -340,11 +360,11 @@ export const destinationTagValidation = ($state: State): PayloadAction =>
const { destinationTag } = state;
if (destinationTag.length > 0 && !validators.isAbs(destinationTag)) {
- state.errors.destinationTag = 'Destination tag must be an absolute number';
+ state.errors.destinationTag = l10nMessages.TR_DESTINATION_TAG_MUST_BE_AN_ABSOLUTE;
}
if (parseInt(destinationTag, 10) > U_INT_32) {
- state.errors.destinationTag = 'Number is too big';
+ state.errors.destinationTag = l10nMessages.TR_DESTINATION_TAG_IS_NOT_VALID;
}
return state;
@@ -386,9 +406,16 @@ export const getFeeLevels = (
const { network } = getState().selectedAccount;
if (!network) return []; // flowtype fallback
+ const l10nFeeMap = {
+ Low: l10nCommonMessages.TR_LOW_FEE,
+ Normal: l10nCommonMessages.TR_NORMAL_FEE,
+ High: l10nCommonMessages.TR_HIGH_FEE,
+ };
+
// map BlockchainFeeLevel to SendFormReducer FeeLevel
const levels = feeLevels.map(level => ({
value: level.name,
+ localizedValue: l10nFeeMap[level.value],
fee: level.value,
label: `${toDecimalAmount(level.value, network.decimals)} ${network.symbol}`,
}));
@@ -398,11 +425,13 @@ export const getFeeLevels = (
selected && selected.value === 'Custom'
? {
value: 'Custom',
+ localizedValue: l10nCommonMessages.TR_CUSTOM_FEE,
fee: selected.fee,
label: `${toDecimalAmount(selected.fee, network.decimals)} ${network.symbol}`,
}
: {
value: 'Custom',
+ localizedValue: l10nCommonMessages.TR_CUSTOM_FEE,
fee: '0',
label: '',
};
diff --git a/src/components/DeviceHeader/index.js b/src/components/DeviceHeader/index.js
index 3f3a7350..ce10788c 100644
--- a/src/components/DeviceHeader/index.js
+++ b/src/components/DeviceHeader/index.js
@@ -1,9 +1,9 @@
-// TODO: l10n for device status
import React from 'react';
import styled, { css } from 'styled-components';
import PropTypes from 'prop-types';
import { getStatusColor, getStatusName, getStatus } from 'utils/device';
import { TrezorImage, colors } from 'trezor-ui-components';
+import { injectIntl } from 'react-intl';
import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
@@ -102,6 +102,7 @@ const DeviceHeader = ({
isSelected = false,
className,
testId,
+ intl,
}) => {
const status = getStatus(device);
return (
@@ -123,7 +124,7 @@ const DeviceHeader = ({
{device.instanceLabel}
- {getStatusName(status)}
+ {getStatusName(status, intl)}
{icon && !disabled && isAccessible && icon}
@@ -141,6 +142,7 @@ DeviceHeader.propTypes = {
onClickWrapper: PropTypes.func.isRequired,
className: PropTypes.string,
testId: PropTypes.string,
+ intl: PropTypes.any,
};
-export default DeviceHeader;
+export default injectIntl(DeviceHeader);
diff --git a/src/components/DeviceHeader/index.messages.js b/src/components/DeviceHeader/index.messages.js
new file mode 100644
index 00000000..329f1277
--- /dev/null
+++ b/src/components/DeviceHeader/index.messages.js
@@ -0,0 +1,63 @@
+/* @flow */
+import { defineMessages } from 'react-intl';
+import type { Messages } from 'flowtype';
+
+const definedMessages: Messages = defineMessages({
+ TR_CONNECTED: {
+ id: 'TR_CONNECTED',
+ defaultMessage: 'Connected',
+ description: 'Device status',
+ },
+ TR_CONNECTED_BOOTLOADER: {
+ id: 'TR_CONNECTED_BOOTLOADER',
+ defaultMessage: 'Connected (bootloader mode)',
+ description: 'Device status',
+ },
+ TR_CONNECTED_NOT_INITIALIZED: {
+ id: 'TR_CONNECTED_NOT_INITIALIZED',
+ defaultMessage: 'Connected (not initialized)',
+ description: 'Device status',
+ },
+ TR_CONNECTED_SEEDLESS: {
+ id: 'TR_CONNECTED_SEEDLESS',
+ defaultMessage: 'Connected (seedless mode)',
+ description: 'Device status',
+ },
+ TR_CONNECTED_UPDATE_REQUIRED: {
+ id: 'TR_CONNECTED_UPDATE_REQUIRED',
+ defaultMessage: 'Connected (update required)',
+ description: 'Device status',
+ },
+ TR_CONNECTED_UPDATE_RECOMMENDED: {
+ id: 'TR_CONNECTED_UPDATE_RECOMMENDED',
+ defaultMessage: 'Connected (update recommended)',
+ description: 'Device status',
+ },
+ TR_USED_IN_ANOTHER_WINDOW: {
+ id: 'TR_USED_IN_ANOTHER_WINDOW',
+ defaultMessage: 'Used in other window',
+ description: 'Device status',
+ },
+ TR_UNAVAILABLE: {
+ id: 'TR_UNAVAILABLE',
+ defaultMessage: 'Unavailable',
+ description: 'Device status',
+ },
+ TR_UNREADABLE: {
+ id: 'TR_UNREADABLE',
+ defaultMessage: 'Unreadable',
+ description: 'Device status',
+ },
+ TR_DISCONNECTED: {
+ id: 'TR_DISCONNECTED',
+ defaultMessage: 'Disconnected',
+ description: 'Device status',
+ },
+ TR_STATUS_UNKNOWN: {
+ id: 'TR_STATUS_UNKNOWN',
+ defaultMessage: 'Status unknown',
+ description: 'Device status',
+ },
+});
+
+export default definedMessages;
diff --git a/src/components/Footer/index.messages.js b/src/components/Footer/index.messages.js
index f5e1efb8..19542e56 100644
--- a/src/components/Footer/index.messages.js
+++ b/src/components/Footer/index.messages.js
@@ -1,6 +1,6 @@
/* @flow */
import { defineMessages } from 'react-intl';
-import type { Messages } from 'flowtype/npm/react-intl';
+import type { Messages } from 'flowtype';
const definedMessages: Messages = defineMessages({
TR_TERMS: {
diff --git a/src/components/Header/index.messages.js b/src/components/Header/index.messages.js
index d9f5f048..1e4adb0a 100644
--- a/src/components/Header/index.messages.js
+++ b/src/components/Header/index.messages.js
@@ -1,6 +1,6 @@
/* @flow */
import { defineMessages } from 'react-intl';
-import type { Messages } from 'flowtype/npm/react-intl';
+import type { Messages } from 'flowtype';
const definedMessages: Messages = defineMessages({
TR_MENU: {
diff --git a/src/components/Log/index.messages.js b/src/components/Log/index.messages.js
index 702d677c..11e6711b 100644
--- a/src/components/Log/index.messages.js
+++ b/src/components/Log/index.messages.js
@@ -1,6 +1,6 @@
/* @flow */
import { defineMessages } from 'react-intl';
-import type { Messages } from 'flowtype/npm/react-intl';
+import type { Messages } from 'flowtype';
const definedMessages: Messages = defineMessages({
TR_ATTENTION_COLON_THE_LOG_CONTAINS: {
diff --git a/src/components/modals/QrModal/index.messages.js b/src/components/modals/QrModal/index.messages.js
index 2b188323..99582c0a 100644
--- a/src/components/modals/QrModal/index.messages.js
+++ b/src/components/modals/QrModal/index.messages.js
@@ -1,6 +1,6 @@
/* @flow */
import { defineMessages } from 'react-intl';
-import type { Messages } from 'flowtype/npm/react-intl';
+import type { Messages } from 'flowtype';
const definedMessages: Messages = defineMessages({
TR_SCAN_QR_CODE: {
diff --git a/src/components/modals/confirm/Action/index.messages.js b/src/components/modals/confirm/Action/index.messages.js
index d98eed09..0d675228 100644
--- a/src/components/modals/confirm/Action/index.messages.js
+++ b/src/components/modals/confirm/Action/index.messages.js
@@ -1,6 +1,6 @@
/* @flow */
import { defineMessages } from 'react-intl';
-import type { Messages } from 'flowtype/npm/react-intl';
+import type { Messages } from 'flowtype';
const definedMessages: Messages = defineMessages({
TR_CONFIRM_ACTION_ON_YOUR: {
diff --git a/src/components/modals/confirm/Address/index.messages.js b/src/components/modals/confirm/Address/index.messages.js
index c1d0f4b3..854523ee 100644
--- a/src/components/modals/confirm/Address/index.messages.js
+++ b/src/components/modals/confirm/Address/index.messages.js
@@ -1,6 +1,6 @@
/* @flow */
import { defineMessages } from 'react-intl';
-import type { Messages } from 'flowtype/npm/react-intl';
+import type { Messages } from 'flowtype';
const definedMessages: Messages = defineMessages({
TR_CONFIRM_ADDRESS_ON_TREZOR: {
diff --git a/src/components/modals/confirm/SignTx/index.messages.js b/src/components/modals/confirm/SignTx/index.messages.js
index a712178e..8c402546 100644
--- a/src/components/modals/confirm/SignTx/index.messages.js
+++ b/src/components/modals/confirm/SignTx/index.messages.js
@@ -1,6 +1,6 @@
/* @flow */
import { defineMessages } from 'react-intl';
-import type { Messages } from 'flowtype/npm/react-intl';
+import type { Messages } from 'flowtype';
const definedMessages: Messages = defineMessages({
TR_CONFIRM_TRANSACTION_ON: {
diff --git a/src/components/modals/confirm/UnverifiedAddress/index.js b/src/components/modals/confirm/UnverifiedAddress/index.js
index 09256c97..790a6406 100644
--- a/src/components/modals/confirm/UnverifiedAddress/index.js
+++ b/src/components/modals/confirm/UnverifiedAddress/index.js
@@ -145,7 +145,7 @@ class ConfirmUnverifiedAddress extends PureComponent {