Add language selector in production (#6317)

* Add language selector in PRODUCTIN

* Fix wrong i18n keys

* Update the default i18n files
This commit is contained in:
Nicolas Gotchac 2017-09-05 13:26:29 +02:00 committed by Gav Wood
parent 7462a69583
commit a62238c19d
31 changed files with 301 additions and 123 deletions

View File

@ -20,34 +20,57 @@ import * as defaults from '../src/i18n/_default';
import { LANGUAGES, MESSAGES } from '../src/i18n/store';
const SKIP_LANG = ['en'];
const defaultKeys = Object.keys(flatten(Object.assign({}, defaults, LANGUAGES)));
const defaultValues = flatten(Object.assign({}, defaults, LANGUAGES));
const defaultKeys = Object.keys(defaultValues);
const results = {};
Object
.keys(MESSAGES)
.filter((lang) => !SKIP_LANG.includes(lang))
.forEach((lang) => {
const messageKeys = Object.keys(MESSAGES[lang]);
let extra = 0;
let found = 0;
let missing = 0;
const langResults = { found: [], missing: [], extras: [] };
console.log(`*** Checking translations for ${lang}`);
console.warn(`*** Checking translations for ${lang}`);
defaultKeys.forEach((key) => {
if (messageKeys.includes(key)) {
found++;
langResults.found.push(key);
} else {
missing++;
console.log(` Missing ${key}`);
langResults.missing.push(key);
}
});
messageKeys.forEach((key) => {
if (!defaultKeys.includes(key)) {
extra++;
console.log(` Extra ${key}`);
langResults.extras.push(key);
}
});
console.log(`Found ${found} keys, missing ${missing} keys, ${extra} extraneous keys\n`);
// Sort keys
langResults.extras.sort((kA, kB) => kA.localeCompare(kB));
langResults.found.sort((kA, kB) => kA.localeCompare(kB));
langResults.missing.sort((kA, kB) => kA.localeCompare(kB));
// Print to stderr the missing and extra keys
langResults.missing.forEach((key) => console.warn(` Missing ${key}`));
langResults.extras.forEach((key) => console.warn(` Extra ${key}`));
results[lang] = langResults;
console.warn(`Found ${langResults.found.length} keys, missing ${langResults.missing.length} keys, ${langResults.extras.length} extraneous keys\n`);
});
const formattedResults = Object.keys(results)
.reduce((res, lang) => {
const { missing } = results[lang];
res[lang] = missing.map((key) => ({
key,
default: defaultValues[key]
}));
return res;
}, {});
process.stdout.write(JSON.stringify(formattedResults, null, 2) + '\n');

View File

@ -18,12 +18,29 @@ export default {
button: {
delete: `delete`,
edit: `edit`,
export: `export`,
faucet: `Kovan ETH`,
forget: `forget`,
password: `password`,
shapeshift: `shapeshift`,
transfer: `transfer`,
verify: `verify`
},
export: {
info: `Export your account as a JSON file. Please enter the password linked with this account.`,
password: {
hint: `The password specified when creating this account`,
label: `Account password`
},
setPassword: {
hint: `Enter password Here`,
label: `Password`
},
title: `Export Account`
},
external: {
confirmDelete: `Are you sure you want to remove the following external address from your account list?`
},
hardware: {
confirmDelete: `Are you sure you want to remove the following hardware address from your account list?`
},

View File

@ -16,10 +16,19 @@
export default {
button: {
export: `export`,
newAccount: `account`,
newWallet: `wallet`,
restoreAccount: `restore`,
vaults: `vaults`
},
export: {
button: {
cancel: `Cancel`,
export: `Export`
},
title: `Export an Account`
},
summary: {
minedBlock: `Mined at block #{blockNumber}`
},

View File

@ -22,8 +22,7 @@ export default {
consensus: {
capable: `Upgrade not required.`,
capableUntil: `Upgrade required before #{blockNumber}`,
incapableSince: `Upgrade required since #{blockNumber}`,
unknown: `Upgrade status is unknown.`
incapableSince: `Upgrade required since #{blockNumber}`
},
upgrade: `Upgrade`
}

View File

@ -19,6 +19,7 @@ export default {
connectingNode: `Connecting to the Parity Node. If this informational message persists, please ensure that your Parity node is running and reachable on the network.`,
invalidToken: `invalid signer token`,
noConnection: `Unable to make a connection to the Parity Secure API. To update your secure token or to generate a new one, run {newToken} and paste the generated token into the space below.`,
timestamp: `Ensure that both the Parity node and this machine connecting have computer clocks in-sync with each other and with a timestamp server, ensuring both successful token validation and block operations.`,
token: {
hint: `a generated token from Parity`,
label: `secure token`

View File

@ -21,8 +21,11 @@ export default {
label: `address`
},
phrase: {
backedUp: `Type "I have written down the phrase" below to confirm it is backed up.`,
backup: `Please back up the recovery phrase now. Make sure to keep it private and secure, it allows full and unlimited access to the account.`,
backupConfirm: `Type your recovery phrase now.`,
hint: `the account recovery phrase`,
label: `owner recovery phrase (keep private and secure, it allows full and unlimited access to the account)`
label: `owner recovery phrase`
}
},
accountDetailsGeth: {
@ -50,14 +53,14 @@ export default {
description: `Selecting your identity icon and specifying the password`,
label: `New Account`
},
fromPhrase: {
description: `Recover using a previously stored recovery phrase and new password`,
label: `Recovery phrase`
},
fromPresale: {
description: `Import an Ethereum presale wallet file with the original password`,
label: `Presale wallet`
},
fromQr: {
description: `Attach an externally managed account via QR code`,
label: `External Account`
},
fromRaw: {
description: `Enter a previously created raw private key with a new password`,
label: `Private key`
@ -104,6 +107,21 @@ export default {
label: `password`
}
},
newQr: {
address: {
hint: `the network address for the account`,
label: `address`
},
description: {
hint: `a description for the account`,
label: `account description`
},
name: {
hint: `a descriptive name for the account`,
label: `account name`
},
summary: `Use the built-in machine camera to scan to QR code of the account you wish to attach as an external account. External accounts are signed on the external device.`
},
rawKey: {
hint: {
hint: `(optional) a hint to help with remembering the password`,
@ -135,6 +153,9 @@ export default {
hint: `a descriptive name for the account`,
label: `account name`
},
passPhrase: {
error: `enter a recovery phrase`
},
password: {
hint: `a strong, unique password`,
label: `password`
@ -147,14 +168,27 @@ export default {
hint: `the account recovery phrase`,
label: `account recovery phrase`
},
warning: {
emptyPhrase: `The recovery phrase is empty.
This account can be recovered by anyone.`,
shortPhrase: `The recovery phrase is less than 11 words.
This account has not been generated by Parity and might be insecure.
Proceed with caution.`,
testnetEmptyPhrase: `The recovery phrase is empty.
This account can be recovered by anyone.
Proceed with caution.`
},
windowsKey: {
label: `Key was created with Parity <1.4.5 on Windows`
}
},
title: {
accountInfo: `account information`,
backupPhrase: `confirm recovery phrase`,
createAccount: `create account`,
createType: `creation type`,
importWallet: `import wallet`
importAccount: `import account`,
qr: `external account`,
restoreAccount: `restore account`
}
};

View File

@ -18,14 +18,9 @@ export default {
button: {
add: `Add`,
cancel: `Cancel`,
close: `Close`,
create: `Create`,
done: `Done`,
next: `Next`,
sending: `Sending...`
},
deployment: {
message: `The deployment is currently in progress`
next: `Next`
},
details: {
address: {
@ -73,21 +68,7 @@ export default {
numOwners: `{numOwners} owners are required to confirm a transaction.`,
owners: `The following are wallet owners`
},
rejected: {
message: `The deployment has been rejected`,
state: `The wallet will not be created. You can safely close this window.`,
title: `rejected`
},
states: {
completed: `The contract deployment has been completed`,
confirmationNeeded: `The contract deployment needs confirmations from other owners of the Wallet`,
preparing: `Preparing transaction for network transmission`,
validatingCode: `Validating the deployed contract code`,
waitingConfirm: `Waiting for confirmation of the transaction in the Parity Secure Signer`,
waitingReceipt: `Waiting for the contract deployment transaction receipt`
},
steps: {
deployment: `wallet deployment`,
details: `wallet details`,
info: `wallet informaton`,
type: `wallet type`

View File

@ -31,6 +31,9 @@ export default {
}
},
button: {
dapp: {
refresh: `refresh`
},
edit: `edit`,
permissions: `permissions`
},

View File

@ -15,19 +15,12 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default {
busy: {
title: `The deployment is currently in progress`
},
button: {
cancel: `Cancel`,
close: `Close`,
create: `Create`,
done: `Done`,
next: `Next`
},
completed: {
description: `Your contract has been deployed at`
},
details: {
abi: {
hint: `the abi of the contract to deploy or solc combined-output`,
@ -66,25 +59,9 @@ export default {
parameters: {
choose: `Choose the contract parameters`
},
rejected: {
description: `You can safely close this window, the contract deployment will not occur.`,
title: `The deployment has been rejected`
},
state: {
completed: `The contract deployment has been completed`,
confirmationNeeded: `The operation needs confirmations from the other owners of the contract`,
preparing: `Preparing transaction for network transmission`,
validatingCode: `Validating the deployed contract code`,
waitReceipt: `Waiting for the contract deployment transaction receipt`,
waitSigner: `Waiting for confirmation of the transaction in the Parity Secure Signer`
},
title: {
completed: `completed`,
deployment: `deployment`,
details: `contract details`,
extras: `extra information`,
failed: `deployment failed`,
parameters: `contract parameters`,
rejected: `rejected`
parameters: `contract parameters`
}
};

View File

@ -19,6 +19,8 @@ export default {
invalidKey: `the raw key needs to be hex, 64 characters in length and contain the prefix "0x"`,
noFile: `select a valid wallet file to import`,
noKey: `you need to provide the raw private key`,
noMatchBackupPhrase: `the supplied recovery phrase does not match`,
noMatchPassword: `the supplied passwords does not match`,
noMatchPhraseBackedUp: `type "I have written down the phrase"`,
noName: `you need to specify a valid name`
};

View File

@ -15,14 +15,8 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default {
busy: {
posted: `Your transaction has been posted to the network`,
title: `The function execution is in progress`,
waitAuth: `Waiting for authorization in the Parity Signer`
},
button: {
cancel: `cancel`,
done: `done`,
next: `next`,
post: `post transaction`,
prev: `prev`
@ -44,15 +38,8 @@ export default {
label: `function to execute`
}
},
rejected: {
state: `You can safely close this window, the function execution will not occur.`,
title: `The execution has been rejected`
},
steps: {
advanced: `advanced options`,
complete: `complete`,
rejected: `rejected`,
sending: `sending`,
transfer: `function details`
}
};

View File

@ -20,6 +20,7 @@ export default {
create: `Create`,
next: `Next`,
print: `Print Phrase`,
restart: `Start Over`,
skip: `Skip`
},
completed: {
@ -28,6 +29,7 @@ export default {
},
title: {
completed: `completed`,
confirmation: `confirmation`,
newAccount: `new account`,
recovery: `recovery`,
terms: `terms`,

View File

@ -41,11 +41,14 @@ export home from './home';
export loadContract from './loadContract';
export parityBar from './parityBar';
export passwordChange from './passwordChange';
export peers from './peers';
export requests from './requests';
export saveContract from './saveContract';
export settings from './settings';
export shapeshift from './shapeshift';
export signer from './signer';
export status from './status';
export syncWarning from './syncWarning';
export tabBar from './tabBar';
export transfer from './transfer';
export txEditor from './txEditor';

View File

@ -0,0 +1,46 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default {
acceptNonReserved: {
label: `Accept non-reserved`
},
acceptNonReservedPeers: {
success: `Accepting non-reserved peers`
},
addReserved: {
label: `Add reserved`
},
dropNonReserved: {
label: `Drop non-reserved`
},
dropNonReservedPeers: {
success: `Dropping non-reserved peers`
},
form: {
action: {
label: `{add, select, true {Add} false {}}{remove, select, true {Remove} false {}}`,
success: `Successfully {add, select, true {added} false {}}{remove, select, true {removed} false {}} a reserved peer`
},
cancel: {
label: `Cancel`
},
label: `Peer enode URL`
},
removeReserved: {
label: `Remove reserved`
}
};

View File

@ -0,0 +1,24 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default {
status: {
error: `An error occured:`,
transactionMined: `Transaction mined at block #{blockNumber} ({blockHeight} blocks ago)`,
transactionSent: `Transaction sent to network with hash`,
waitingForSigner: `Waiting for authorization in the Parity Signer`
}
};

View File

@ -36,7 +36,7 @@ export default {
},
languages: {
hint: `the language this interface is displayed with`,
label: `UI language`
label: `language`
},
loglevels: `Choose the different logs level.`,
modes: {
@ -51,7 +51,7 @@ export default {
label: `parity`
},
proxy: {
details_0: `Instead of accessing Parity via the IP address and port, you will be able to access it via the .parity subdomain, by visiting {homeProxy}. To setup subdomain-based routing, you need to add the relevant proxy entries to your browser,`,
details_0: `Instead of accessing Parity via the IP address and port, you will be able to access it via the .web3.site subdomain, by visiting {homeProxy}. To setup subdomain-based routing, you need to add the relevant proxy entries to your browser,`,
details_1: `To learn how to configure the proxy, instructions are provided for {windowsLink}, {macOSLink} or {ubuntuLink}.`,
details_macos: `macOS`,
details_ubuntu: `Ubuntu`,
@ -88,13 +88,12 @@ export default {
description: `The secure transaction management area of the application where you can approve any outgoing transactions made from the application as well as those placed into the queue by decentralized applications.`,
label: `Signer`
},
status: {
description: `See how the Parity node is performing in terms of connections to the network, logs from the actual running instance and details of mining (if enabled and configured).`,
label: `Status`
},
label: `views`,
home: {
label: `Home`
},
status: {
label: `Status`
}
},
label: `settings`

View File

@ -15,6 +15,13 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default {
decryptRequest: {
request: `A request to decrypt data using your account:`,
state: {
confirmed: `Confirmed`,
rejected: `Rejected`
}
},
embedded: {
noPending: `There are currently no pending requests awaiting your confirmation`
},
@ -29,7 +36,7 @@ export default {
requestOrigin: {
dapp: `by a dapp at {url}`,
ipc: `via IPC session`,
rpc: `via RPC {rpc}`,
rpc: `via RPC {url}`,
signerCurrent: `via current tab`,
signerUI: `via UI session`,
unknownInterface: `via unknown interface`,
@ -38,10 +45,14 @@ export default {
},
requestsPage: {
noPending: `There are no requests requiring your confirmation.`,
pendingTitle: `Pending Requests`,
pendingTitle: `Pending Signature Authorization`,
queueTitle: `Local Transactions`
},
sending: {
external: {
scanSigned: `Scan the QR code of the signed transaction from your external device`,
scanTx: `Please scan the transaction QR on your external device`
},
hardware: {
confirm: `Please confirm the transaction on your attached hardware device`,
connect: `Please attach your hardware device before confirming the transaction`
@ -53,6 +64,10 @@ export default {
confirmed: `Confirmed`,
rejected: `Rejected`
},
tooltip: {
data: `Data: {data}`,
hash: `Hash to be signed: {hashToSign}`
},
unknownBinary: `(Unknown binary data)`,
warning: `WARNING: This consequences of doing this may be grave. Confirm the request only if you are sure.`
},
@ -65,7 +80,8 @@ export default {
txPendingConfirm: {
buttons: {
confirmBusy: `Confirming...`,
confirmRequest: `Confirm Request`
confirmRequest: `Confirm Request`,
scanSigned: `Scan Signed QR`
},
errors: {
invalidWallet: `Given wallet file is invalid.`

View File

@ -20,6 +20,14 @@ export default {
stopped: `Refresh and display of logs from Parity is currently stopped via the UI, start it to see the latest updates.`,
title: `Node Logs`
},
health: {
no: `no`,
peers: `Connected Peers`,
sync: `Chain Synchronized`,
time: `Time Synchronized`,
title: `Node Health`,
yes: `yes`
},
miningSettings: {
input: {
author: {
@ -41,13 +49,25 @@ export default {
},
title: `mining settings`
},
peers: {
table: {
header: {
caps: `Capabilities`,
ethDiff: `Difficulty (ETH)`,
ethHeader: `Header (ETH)`,
id: `ID`,
name: `Name`,
remoteAddress: `Remote Address`
}
},
title: `network peers`
},
status: {
hashrate: `{hashrate} H/s`,
input: {
chain: `chain`,
enode: `enode`,
no: `no`,
peers: `peers`,
port: `network port`,
rpcEnabled: `rpc enabled`,
rpcInterface: `rpc interface`,

View File

@ -14,4 +14,11 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default `Windows`;
export default {
dontShowAgain: {
label: `Do not show this warning again`
},
understandBtn: {
label: `I understand`
}
};

View File

@ -24,7 +24,6 @@ export default {
buttons: {
back: `Back`,
cancel: `Cancel`,
close: `Close`,
next: `Next`,
send: `Send`
},
@ -51,10 +50,6 @@ export default {
label: `total transaction amount`
}
},
wallet: {
confirmation: `This transaction needs confirmation from other owners.`,
operationHash: `operation hash`
},
warning: {
wallet_spent_limit: `This transaction value is above the remaining daily limit. It will need to be confirmed by other owners.`
}

View File

@ -66,6 +66,18 @@ export default {
errors: {
close: `close`
},
features: {
defaults: {
i18n: {
desc: `Allows changing the default interface language`,
name: `Language Selection`
},
logging: {
desc: `Allows changing of the log levels for various components`,
name: `Logging Level Selection`
}
}
},
fileSelect: {
defaultLabel: `Drop a file here, or click to select a file to upload`
},
@ -80,8 +92,8 @@ export default {
},
methodDecoding: {
condition: {
block: `, {historic, select, true {Submitted} false {Submission}} at block {blockNumber}`,
time: `, {historic, select, true {Submitted} false {Submission}} at {timestamp}`
block: `{historic, select, true {Will be submitted} false {To be submitted}} at block {blockNumber}`,
time: `{historic, select, true {Will be submitted} false {To be submitted}} {timestamp}`
},
deploy: {
address: `Deployed a contract at address`,
@ -101,7 +113,7 @@ export default {
info: `{historic, select, true {Received} false {Will receive}} {valueEth} from {aContract}{address}`
},
signature: {
info: `{historic, select, true {Executed} false {Will execute}} the {method} function on the contract {address} trsansferring {ethValue}{inputLength, plural, zero {,} other {passing the following {inputLength, plural, one {parameter} other {parameters}}}}`
info: `{historic, select, true {Executed} false {Will execute}} the {method} function on the contract {address} {showEth, select, true {transferring {ethValue}} false {}} {showInputs, select, false {} true {passing the following {inputLength, plural, one {parameter} other {parameters}}}}`
},
token: {
transfer: `{historic, select, true {Transferred} false {Will transfer}} {value} to {address}`
@ -131,6 +143,27 @@ export default {
posted: `The transaction has been posted to the network with a hash of {hashLink}`,
waiting: `waiting for confirmations`
},
txList: {
txRow: {
cancel: `Cancel`,
cancelWarning: `Warning: Editing or Canceling the transaction may not succeed!`,
canceled: `Canceled`,
edit: `Edit`,
editing: `Editing`,
pendingStatus: {
blocksLeft: `{blockNumber} blocks left`,
time: `{time} left`
},
scheduled: `Scheduled`,
submitting: `Pending`,
verify: {
cancelEditCancel: `Cancel`,
cancelEditEdit: `Edit`,
confirm: `Are you sure?`,
nevermind: `Nevermind`
}
}
},
vaultSelect: {
hint: `the vault this account is attached to`,
label: `associated vault`

View File

@ -22,8 +22,12 @@ export default {
cancel: `Cancel`,
close: `Close`,
next: `Next`,
send: `Send`,
sending: `Sending...`
send: `Send`
},
changeOwner: {
labelFrom: `From`,
labelTo: `To`,
title: `Change Owner`
},
changes: {
modificationString: `For your modifications to be taken into account,
@ -62,7 +66,6 @@ export default {
details: `from {from} to {to}`,
title: `Change Required Owners`
},
rejected: `The transaction #{txid} has been rejected`,
removeOwner: {
title: `Remove Owner`
}

View File

@ -37,7 +37,7 @@ export default {
params: `An error occurred with the following description`
},
input: {
abi: `ABI Interface`,
abi: `ABI Definition`,
code: `Bytecode`,
metadata: `Metadata`,
swarm: `Swarm Metadata Hash`

View File

@ -33,8 +33,8 @@ import zhHantTWMessages from './zh-Hant-TW';
let instance = null;
const LANGUAGES = flatten({ languages });
const MESSAGES = {
export const LANGUAGES = flatten({ languages });
export const MESSAGES = {
de: Object.assign(flatten(deMessages), LANGUAGES),
en: Object.assign(flatten(enMessages), LANGUAGES),
nl: Object.assign(flatten(nlMessages), LANGUAGES),
@ -75,8 +75,3 @@ export default class Store {
return instance;
}
}
export {
LANGUAGES,
MESSAGES
};

View File

@ -58,7 +58,7 @@ class ExportAccount extends Component {
key='cancel'
label={
<FormattedMessage
id='export.accounts.button.cancel'
id='accounts.export.button.cancel'
defaultMessage='Cancel'
/>
}
@ -70,7 +70,7 @@ class ExportAccount extends Component {
key='execute'
label={
<FormattedMessage
id='export.accounts.button.export'
id='accounts.export.button.export'
defaultMessage='Export'
/>
}
@ -81,7 +81,7 @@ class ExportAccount extends Component {
open
title={
<FormattedMessage
id='export.accounts.title'
id='accounts.export.title'
defaultMessage='Export an Account'
/>
}

View File

@ -34,13 +34,13 @@ export default class ExportInput extends Component {
type='password'
label={
<FormattedMessage
id='export.setPassword.label'
id='account.export.setPassword.label'
defaultMessage='Password'
/>
}
hint={
<FormattedMessage
id='export.setPassword.hint'
id='account.export.setPassword.hint'
defaultMessage='Enter password Here'
/>
}

View File

@ -30,17 +30,17 @@ const FEATURES = {
const DEFAULTS = {
[FEATURES.LANGUAGE]: {
mode: MODES.TESTING,
mode: MODES.PRODUCTION,
name: (
<FormattedMessage
id='ui.features.defaults.i18n.name'
defaultMssage='Language Selection'
defaultMessage='Language Selection'
/>
),
description: (
<FormattedMessage
id='ui.features.defaults.i18n.desc'
defaultMssage='Allows changing the default interface language'
defaultMessage='Allows changing the default interface language'
/>
)
},
@ -49,13 +49,13 @@ const DEFAULTS = {
name: (
<FormattedMessage
id='ui.features.defaults.logging.name'
defaultMssage='Logging Level Selection'
defaultMessage='Logging Level Selection'
/>
),
description: (
<FormattedMessage
id='ui.features.defaults.logging.desc'
defaultMssage='Allows changing of the log levels for various components'
defaultMessage='Allows changing of the log levels for various components'
/>
)
}

View File

@ -45,7 +45,7 @@ export default class LanguageSelector extends Component {
label={
<FormattedMessage
id='settings.parity.languages.label'
defaultMessage='UI language'
defaultMessage='language'
/>
}
value={ this.store.locale }

View File

@ -291,7 +291,7 @@ class TxRow extends Component {
<div />
<div className={ styles.uppercase }>
<FormattedMessage
id='ui.txList.txRow.verify'
id='ui.txList.txRow.verify.confirm'
defaultMessage='Are you sure?'
/>
</div>

View File

@ -370,14 +370,14 @@ class Account extends Component {
onDeny={ this.exportClose }
title={
<FormattedMessage
id='export.account.title'
id='account.export.title'
defaultMessage='Export Account'
/>
}
>
<div className={ styles.textbox }>
<FormattedMessage
id='export.account.info'
id='account.export.info'
defaultMessage='Export your account as a JSON file. Please enter the password linked with this account.'
/>
</div>
@ -388,13 +388,13 @@ class Account extends Component {
type='password'
hint={
<FormattedMessage
id='export.account.password.hint'
id='account.export.password.hint'
defaultMessage='The password specified when creating this account'
/>
}
label={
<FormattedMessage
id='export.account.password.label'
id='account.export.password.label'
defaultMessage='Account password'
/>
}

View File

@ -46,6 +46,8 @@ export default class Parity extends Component {
<FormattedMessage id='settings.parity.label' />
}
>
<Features />
<div className={ layout.layout }>
<div className={ layout.overview }>
<div>
@ -58,10 +60,10 @@ export default class Parity extends Component {
<div className={ layout.details }>
{ this.renderChains() }
{ this.renderModes() }
<Features />
<LanguageSelector />
</div>
</div>
{ this.renderLogsConfig() }
</Container>
);