Adjust hooks for index import (#1271)

This commit is contained in:
Jaco
2023-07-11 11:07:38 +03:00
committed by GitHub
parent c654f9a670
commit c7dac675e0
54 changed files with 248 additions and 254 deletions
@@ -10,8 +10,7 @@ import React, { useCallback, useContext, useEffect, useMemo, useState } from 're
import { canDerive } from '@polkadot/extension-base/utils';
import { AccountContext, Address, Checkbox, Dropdown, Link, MenuDivider } from '../../components/index.js';
import useGenesisHashOptions from '../../hooks/useGenesisHashOptions.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useGenesisHashOptions, useTranslation } from '../../hooks/index.js';
import { editAccount, tieAccount } from '../../messaging.js';
import { Name } from '../../partials/index.js';
import { styled } from '../../styled.js';
@@ -80,14 +79,14 @@ function Account ({ address, className, genesisHash, isExternal, isHardware, isH
className='menuItem'
onClick={_toggleEdit}
>
{t<string>('Rename')}
{t('Rename')}
</Link>
{!isExternal && canDerive(type) && (
<Link
className='menuItem'
to={`/account/derive/${address}/locked`}
>
{t<string>('Derive New Account')}
{t('Derive New Account')}
</Link>
)}
<MenuDivider />
@@ -97,7 +96,7 @@ function Account ({ address, className, genesisHash, isExternal, isHardware, isH
isDanger
to={`/account/export/${address}`}
>
{t<string>('Export Account')}
{t('Export Account')}
</Link>
)}
<Link
@@ -105,7 +104,7 @@ function Account ({ address, className, genesisHash, isExternal, isHardware, isH
isDanger
to={`/account/forget/${address}`}
>
{t<string>('Forget Account')}
{t('Forget Account')}
</Link>
{!isHardware && (
<>
@@ -6,7 +6,7 @@ import type { ThemeProps } from '../../types.js';
import React, { useCallback, useContext } from 'react';
import { ActionContext } from '../../components/index.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useTranslation } from '../../hooks/index.js';
import Header from '../../partials/Header.js';
import { styled } from '../../styled.js';
import AddAccountImage from './AddAccountImage.js';
@@ -28,14 +28,14 @@ function AddAccount ({ className }: Props): React.ReactElement<Props> {
<Header
showAdd
showSettings
text={t<string>('Add Account')}
text={t('Add Account')}
/>
<div className={className}>
<div className='image'>
<AddAccountImage onClick={_onClick} />
</div>
<div className='no-accounts'>
<p>{t<string>("You currently don't have any accounts. Create your first account to get started.")}</p>
<p>{t("You currently don't have any accounts. Create your first account to get started.")}</p>
</div>
</div>
</>
@@ -9,7 +9,7 @@ import React, { useCallback, useContext, useEffect, useMemo, useState } from 're
import getNetworkMap from '@polkadot/extension-ui/util/getNetworkMap';
import { AccountContext } from '../../components/index.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useTranslation } from '../../hooks/index.js';
import { Header } from '../../partials/index.js';
import { styled } from '../../styled.js';
import AccountsTree from './AccountsTree.js';
@@ -54,7 +54,7 @@ function Accounts ({ className }: Props): React.ReactElement {
showConnectedAccounts
showSearch
showSettings
text={t<string>('Accounts')}
text={t('Accounts')}
/>
<div className={className}>
{filteredAccount.map((json, index): React.ReactNode => (
@@ -7,7 +7,7 @@ import React, { useCallback, useContext, useEffect } from 'react';
import { useParams } from 'react-router';
import { AccountContext, ActionContext, Button } from '../../components/index.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useTranslation } from '../../hooks/index.js';
import { getAuthList, updateAuthorization } from '../../messaging.js';
import { AccountSelection, Header } from '../../partials/index.js';
import { styled } from '../../styled.js';
@@ -48,7 +48,7 @@ function AccountManagement ({ className }: Props): React.ReactElement<Props> {
<Header
showBackArrow
smallMargin={true}
text={t<string>('Accounts connected to {{url}}', { replace: { url } })}
text={t('Accounts connected to {{url}}', { replace: { url } })}
/>
<div className={className}>
<AccountSelection
@@ -62,7 +62,7 @@ function AccountManagement ({ className }: Props): React.ReactElement<Props> {
className='acceptButton'
onClick={_onApprove}
>
{t<string>('Connect {{total}} account(s)', { replace: {
{t('Connect {{total}} account(s)', { replace: {
total: selectedAccounts.length
} })}
</Button>
@@ -7,9 +7,8 @@ import type { ThemeProps } from '../../types.js';
import React, { useCallback } from 'react';
import { Link } from 'react-router-dom';
import { useTranslation } from '@polkadot/extension-ui/translate';
import RemoveAuth from '../../components/RemoveAuth.js';
import { useTranslation } from '../../hooks/index.js';
import { styled } from '../../styled.js';
interface Props extends ThemeProps {
@@ -38,14 +37,14 @@ function WebsiteEntry ({ className = '', info: { authorizedAccounts, isAllowed }
to={`/url/manage/${url}`}
>{
authorizedAccounts && authorizedAccounts.length
? t<string>('{{total}} accounts', {
? t('{{total}} accounts', {
replace: {
total: authorizedAccounts.length
}
})
: isAllowed
? t<string>('all accounts')
: t<string>('no accounts')
? t('all accounts')
: t('no accounts')
}</Link>
</div>
);
@@ -7,7 +7,7 @@ import type { ThemeProps } from '../../types.js';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import InputFilter from '../../components/InputFilter.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useTranslation } from '../../hooks/index.js';
import { getAuthList, removeAuthorization } from '../../messaging.js';
import { Header } from '../../partials/index.js';
import { styled } from '../../styled.js';
@@ -48,19 +48,19 @@ function AuthManagement ({ className }: Props): React.ReactElement<Props> {
<Header
showBackArrow
smallMargin
text={t<string>('Manage Website Access')}
text={t('Manage Website Access')}
/>
<div className={className}>
<InputFilter
className='inputFilter'
onChange={_onChangeFilter}
placeholder={t<string>('example.com')}
placeholder={t('example.com')}
value={filter}
withReset
/>
{
!authList || !hasAuthList
? <div className='empty-list'>{t<string>('No website request yet!')}</div>
? <div className='empty-list'>{t('No website request yet!')}</div>
: (
<>
<div className='website-list'>
@@ -31,7 +31,7 @@ function NoAccount ({ authId, className }: Props): React.ReactElement<Props> {
className='acceptButton'
onClick={_onClick}
>
{t<string>('Understood')}
{t('Understood')}
</Button>
</div>
);
@@ -7,7 +7,7 @@ import type { ThemeProps } from '../../types.js';
import React, { useCallback, useContext, useEffect } from 'react';
import { AccountContext, ActionBar, ActionContext, Button, Link } from '../../components/index.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useTranslation } from '../../hooks/index.js';
import { approveAuthRequest, deleteAuthRequest } from '../../messaging.js';
import { AccountSelection } from '../../partials/index.js';
import { styled } from '../../styled.js';
@@ -67,7 +67,7 @@ function Request ({ authId, className, isFirst, request: { origin }, url }: Prop
className='acceptButton'
onClick={_onApprove}
>
{t<string>('Connect {{total}} account(s)', { replace: {
{t('Connect {{total}} account(s)', { replace: {
total: selectedAccounts.length
} })}
</Button>
@@ -78,7 +78,7 @@ function Request ({ authId, className, isFirst, request: { origin }, url }: Prop
isDanger
onClick={_onClose}
>
{t<string>('Ask again later')}
{t('Ask again later')}
</Link>
</ActionBar>
</div>
@@ -6,7 +6,7 @@ import type { ThemeProps } from '../../types.js';
import React, { useContext } from 'react';
import { AuthorizeReqContext } from '../../components/index.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useTranslation } from '../../hooks/index.js';
import { Header } from '../../partials/index.js';
import { styled } from '../../styled.js';
import Request from './Request.js';
@@ -24,7 +24,7 @@ function Authorize ({ className = '' }: Props): React.ReactElement {
<div className={`${className} ${requests.length === 1 ? 'lastRequest' : ''}`}>
<Header
smallMargin={true}
text={t<string>('Account connection request')}
text={t('Account connection request')}
/>
{requests.map(({ id, request, url }, index): React.ReactNode => (
<Request
@@ -4,8 +4,7 @@
import React, { useCallback, useState } from 'react';
import { ButtonArea, Checkbox, MnemonicSeed, NextStepButton, VerticalSpace, Warning } from '../../components/index.js';
import useToast from '../../hooks/useToast.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useToast, useTranslation } from '../../hooks/index.js';
interface Props {
onNextStep: () => void;
@@ -18,7 +17,7 @@ function Mnemonic ({ onNextStep, seed }: Props): React.ReactElement<Props> {
const { show } = useToast();
const _onCopy = useCallback((): void => {
show(t<string>('Copied'));
show(t('Copied'));
}, [show, t]);
return (
@@ -28,12 +27,12 @@ function Mnemonic ({ onNextStep, seed }: Props): React.ReactElement<Props> {
seed={seed}
/>
<Warning>
{t<string>("Please write down your wallet's mnemonic seed and keep it in a safe place. The mnemonic can be used to restore your wallet. Keep it carefully to not lose your assets.")}
{t("Please write down your wallet's mnemonic seed and keep it in a safe place. The mnemonic can be used to restore your wallet. Keep it carefully to not lose your assets.")}
</Warning>
<VerticalSpace />
<Checkbox
checked={isMnemonicSaved}
label={t<string>('I have saved my mnemonic seed safely.')}
label={t('I have saved my mnemonic seed safely.')}
onChange={setIsMnemonicSaved}
/>
<ButtonArea>
@@ -41,7 +40,7 @@ function Mnemonic ({ onNextStep, seed }: Props): React.ReactElement<Props> {
isDisabled={!isMnemonicSaved}
onClick={onNextStep}
>
{t<string>('Next step')}
{t('Next step')}
</NextStepButton>
</ButtonArea>
</>
@@ -7,9 +7,7 @@ import React, { useCallback, useContext, useEffect, useState } from 'react';
import AccountNamePasswordCreation from '../../components/AccountNamePasswordCreation.js';
import { ActionContext, Address, Dropdown, Loading } from '../../components/index.js';
import useGenesisHashOptions from '../../hooks/useGenesisHashOptions.js';
import useMetadata from '../../hooks/useMetadata.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useGenesisHashOptions, useMetadata, useTranslation } from '../../hooks/index.js';
import { createAccountSuri, createSeed, validateSeed } from '../../messaging.js';
import { HeaderWithSteps } from '../../partials/index.js';
import { styled } from '../../styled.js';
@@ -92,7 +90,7 @@ function CreateAccount ({ className }: Props): React.ReactElement {
<>
<HeaderWithSteps
step={step}
text={t<string>('Create an account')}
text={t('Create an account')}
/>
<Loading>
<div>
@@ -114,13 +112,13 @@ function CreateAccount ({ className }: Props): React.ReactElement {
<>
<Dropdown
className={className}
label={t<string>('Network')}
label={t('Network')}
onChange={_onChangeNetwork}
options={options}
value={genesisHash}
/>
<AccountNamePasswordCreation
buttonLabel={t<string>('Add the account with the generated seed')}
buttonLabel={t('Add the account with the generated seed')}
isBusy={isBusy}
onBackClick={_onPreviousStep}
onCreate={_onCreate}
@@ -7,7 +7,7 @@ import React, { useCallback, useRef, useState } from 'react';
import arrow from '../../assets/arrow-down.svg';
import { Address } from '../../components/index.js';
import useOutsideClick from '../../hooks/useOutsideClick.js';
import { useOutsideClick } from '../../hooks/index.js';
import { styled } from '../../styled.js';
interface Props {
@@ -8,7 +8,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React, { useCallback, useEffect, useState } from 'react';
import { Button, InputWithLabel } from '../../components/index.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useTranslation } from '../../hooks/index.js';
import { styled } from '../../styled.js';
interface Props extends ThemeProps{
@@ -47,13 +47,13 @@ function DerivationPath ({ className, defaultPath, isError, onChange, withSoftPa
isError={isError || !path}
label={
isDisabled
? t<string>('Derivation Path (unlock to edit)')
: t<string>('Derivation Path')
? t('Derivation Path (unlock to edit)')
: t('Derivation Path')
}
onChange={_onChange}
placeholder={withSoftPath
? t<string>('//hard/soft')
: t<string>('//hard')
? t('//hard/soft')
: t('//hard')
}
value={path}
/>
@@ -6,7 +6,7 @@ import React, { useCallback, useContext, useEffect, useMemo, useRef, useState }
import { canDerive } from '@polkadot/extension-base/utils';
import { AccountContext, ActionContext, Address, ButtonArea, InputWithLabel, Label, NextStepButton, VerticalSpace, Warning } from '../../components/index.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useTranslation } from '../../hooks/index.js';
import { validateAccount, validateDerivationPath } from '../../messaging.js';
import { nextDerivationPath } from '../../util/nextDerivationPath.js';
import AddressDropdown from './AddressDropdown.js';
@@ -48,11 +48,11 @@ export default function SelectParent ({ className, isLocked, onDerivationConfirm
useEffect(() => {
// forbid the use of password since Keyring ignores it
if (suriPath?.includes('///')) {
setPathError(t<string>('`///password` not supported for derivation'));
setPathError(t('`///password` not supported for derivation'));
}
if (!allowSoftDerivation && suriPath && singleSlashRegex.test(suriPath)) {
setPathError(t<string>('Soft derivation is only allowed for sr25519 accounts'));
setPathError(t('Soft derivation is only allowed for sr25519 accounts'));
}
}, [allowSoftDerivation, suriPath, t]);
@@ -99,7 +99,7 @@ export default function SelectParent ({ className, isLocked, onDerivationConfirm
onDerivationConfirmed({ account, parentPassword });
} catch (error) {
setIsBusy(false);
setPathError(t<string>('Invalid derivation path'));
setPathError(t('Invalid derivation path'));
console.error(error);
}
} else {
@@ -129,7 +129,7 @@ export default function SelectParent ({ className, isLocked, onDerivationConfirm
/>
)
: (
<Label label={t<string>('Choose Parent Account:')}>
<Label label={t('Choose Parent Account:')}>
<AddressDropdown
allAddresses={allAddresses}
onSelect={_onParentChange}
@@ -144,7 +144,7 @@ export default function SelectParent ({ className, isLocked, onDerivationConfirm
data-input-password
isError={!!parentPassword && !isProperParentPassword}
isFocused
label={t<string>('enter the password for the account you want to derive from')}
label={t('enter the password for the account you want to derive from')}
onChange={_onParentPasswordEnter}
type='password'
value={parentPassword}
@@ -154,7 +154,7 @@ export default function SelectParent ({ className, isLocked, onDerivationConfirm
isBelowInput
isDanger
>
{t<string>('Wrong password')}
{t('Wrong password')}
</Warning>
)}
</div>
@@ -187,7 +187,7 @@ export default function SelectParent ({ className, isLocked, onDerivationConfirm
isDisabled={!isProperParentPassword || !!pathError}
onClick={_onSubmit}
>
{t<string>('Create a derived account')}
{t('Create a derived account')}
</NextStepButton>
</ButtonArea>
</>
@@ -5,7 +5,7 @@ import React, { useCallback, useContext, useMemo, useState } from 'react';
import { useParams } from 'react-router';
import { AccountContext, AccountNamePasswordCreation, ActionContext, Address } from '../../components/index.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useTranslation } from '../../hooks/index.js';
import { deriveAccount } from '../../messaging.js';
import { HeaderWithSteps } from '../../partials/index.js';
import SelectParent from './SelectParent.js';
@@ -69,7 +69,7 @@ function Derive ({ isLocked }: Props): React.ReactElement<Props> {
<>
<HeaderWithSteps
step={account ? 2 : 1}
text={t<string>('Add new account')}
text={t('Add new account')}
/>
{!account && (
<SelectParent
@@ -89,7 +89,7 @@ function Derive ({ isLocked }: Props): React.ReactElement<Props> {
/>
</div>
<AccountNamePasswordCreation
buttonLabel={t<string>('Create derived account')}
buttonLabel={t('Create derived account')}
isBusy={isBusy}
onBackClick={_onBackClick}
onCreate={_onCreate}
+6 -6
View File
@@ -9,7 +9,7 @@ import React, { useCallback, useContext, useState } from 'react';
import { withRouter } from 'react-router';
import { ActionBar, ActionContext, ActionText, Address, Button, InputWithLabel, Warning } from '../components/index.js';
import useTranslation from '../hooks/useTranslation.js';
import { useTranslation } from '../hooks/index.js';
import { exportAccount } from '../messaging.js';
import { Header } from '../partials/index.js';
import { styled } from '../styled.js';
@@ -65,19 +65,19 @@ function Export ({ className, match: { params: { address } } }: Props): React.Re
<>
<Header
showBackArrow
text={t<string>('Export account')}
text={t('Export account')}
/>
<div className={className}>
<Address address={address}>
<Warning className='movedWarning'>
{t<string>("You are exporting your account. Keep it safe and don't share it with anyone.")}
{t("You are exporting your account. Keep it safe and don't share it with anyone.")}
</Warning>
<div className='actionArea'>
<InputWithLabel
data-export-password
disabled={isBusy}
isError={pass.length < MIN_LENGTH || !!error}
label={t<string>('password for this account')}
label={t('password for this account')}
onChange={onPassChange}
type='password'
/>
@@ -97,13 +97,13 @@ function Export ({ className, match: { params: { address } } }: Props): React.Re
isDisabled={pass.length === 0 || !!error}
onClick={_onExportButtonClick}
>
{t<string>('I want to export this account')}
{t('I want to export this account')}
</Button>
<ActionBar className='withMarginTop'>
<ActionText
className='center'
onClick={_goHome}
text={t<string>('Cancel')}
text={t('Cancel')}
/>
</ActionBar>
</div>
@@ -9,7 +9,7 @@ import React, { useCallback, useContext, useState } from 'react';
import { withRouter } from 'react-router';
import { AccountContext, ActionBar, ActionContext, ActionText, Button, InputWithLabel, Warning } from '../components/index.js';
import useTranslation from '../hooks/useTranslation.js';
import { useTranslation } from '../hooks/index.js';
import { exportAccounts } from '../messaging.js';
import { Header } from '../partials/index.js';
import { styled } from '../styled.js';
@@ -66,7 +66,7 @@ function ExportAll ({ className }: Props): React.ReactElement<Props> {
<>
<Header
showBackArrow
text={t<string>('All account')}
text={t('All account')}
/>
<div className={className}>
<div className='actionArea'>
@@ -74,7 +74,7 @@ function ExportAll ({ className }: Props): React.ReactElement<Props> {
data-export-all-password
disabled={isBusy}
isError={pass.length < MIN_LENGTH || !!error}
label={t<string>('password for encrypting all accounts')}
label={t('password for encrypting all accounts')}
onChange={onPassChange}
type='password'
/>
@@ -94,13 +94,13 @@ function ExportAll ({ className }: Props): React.ReactElement<Props> {
isDisabled={pass.length === 0 || !!error}
onClick={_onExportAllButtonClick}
>
{t<string>('I want to export all my accounts')}
{t('I want to export all my accounts')}
</Button>
<ActionBar className='withMarginTop'>
<ActionText
className='center'
onClick={_goHome}
text={t<string>('Cancel')}
text={t('Cancel')}
/>
</ActionBar>
</div>
+5 -5
View File
@@ -8,7 +8,7 @@ import React, { useCallback, useContext, useState } from 'react';
import { withRouter } from 'react-router';
import { ActionBar, ActionContext, ActionText, Address, Button, Warning } from '../components/index.js';
import useTranslation from '../hooks/useTranslation.js';
import { useTranslation } from '../hooks/index.js';
import { forgetAccount } from '../messaging.js';
import { Header } from '../partials/index.js';
import { styled } from '../styled.js';
@@ -47,12 +47,12 @@ function Forget ({ className, match: { params: { address } } }: Props): React.Re
<>
<Header
showBackArrow
text={t<string>('Forget account')}
text={t('Forget account')}
/>
<div className={className}>
<Address address={address}>
<Warning className='movedWarning'>
{t<string>('You are about to remove the account. This means that you will not be able to access it via this extension anymore. If you wish to recover it, you would need to use the seed.')}
{t('You are about to remove the account. This means that you will not be able to access it via this extension anymore. If you wish to recover it, you would need to use the seed.')}
</Warning>
<div className='actionArea'>
<Button
@@ -60,13 +60,13 @@ function Forget ({ className, match: { params: { address } } }: Props): React.Re
isDanger
onClick={_onClick}
>
{t<string>('I want to forget this account')}
{t('I want to forget this account')}
</Button>
<ActionBar className='withMarginTop'>
<ActionText
className='center'
onClick={_goHome}
text={t<string>('Cancel')}
text={t('Cancel')}
/>
</ActionBar>
</div>
@@ -11,8 +11,7 @@ import React, { useCallback, useContext, useEffect, useRef, useState } from 'rea
import settings from '@polkadot/ui-settings';
import { ActionContext, Address, Button, ButtonArea, Dropdown, VerticalSpace, Warning } from '../components/index.js';
import { useLedger } from '../hooks/useLedger.js';
import useTranslation from '../hooks/useTranslation.js';
import { useLedger, useTranslation } from '../hooks/index.js';
import { createAccountHardware } from '../messaging.js';
import { Header, Name } from '../partials/index.js';
import { styled } from '../styled.js';
@@ -52,18 +51,18 @@ function ImportLedger ({ className }: Props): React.ReactElement {
}, [address]);
const accOps = useRef(AVAIL.map((value): AccOption => ({
text: t<string>('Account type {{index}}', { replace: { index: value } }),
text: t('Account type {{index}}', { replace: { index: value } }),
value
})));
const addOps = useRef(AVAIL.map((value): AccOption => ({
text: t<string>('Address index {{index}}', { replace: { index: value } }),
text: t('Address index {{index}}', { replace: { index: value } }),
value
})));
const networkOps = useRef(
[{
text: t<string>('Select network'),
text: t('Select network'),
value: ''
},
...ledgerChains.map(({ displayName, genesisHash }): NetworkOption => ({
@@ -98,7 +97,7 @@ function ImportLedger ({ className }: Props): React.ReactElement {
<>
<Header
showBackArrow
text={t<string>('Import Ledger Account')}
text={t('Import Ledger Account')}
/>
<div className={className}>
<Address
@@ -110,7 +109,7 @@ function ImportLedger ({ className }: Props): React.ReactElement {
/>
<Dropdown
className='network'
label={t<string>('Network')}
label={t('Network')}
onChange={setGenesis}
options={networkOps.current}
value={genesis}
@@ -126,7 +125,7 @@ function ImportLedger ({ className }: Props): React.ReactElement {
<Dropdown
className='accountType'
isDisabled={ledgerLoading}
label={t<string>('account type')}
label={t('account type')}
onChange={_onSetAccountIndex}
options={accOps.current}
value={accountIndex}
@@ -134,7 +133,7 @@ function ImportLedger ({ className }: Props): React.ReactElement {
<Dropdown
className='accountIndex'
isDisabled={ledgerLoading}
label={t<string>('address index')}
label={t('address index')}
onChange={_onSetAddressOffset}
options={addOps.current}
value={addressOffset}
@@ -163,7 +162,7 @@ function ImportLedger ({ className }: Props): React.ReactElement {
onClick={refresh}
>
<FontAwesomeIcon icon={faSync} />
{t<string>('Refresh')}
{t('Refresh')}
</Button>
)
: (
@@ -172,7 +171,7 @@ function ImportLedger ({ className }: Props): React.ReactElement {
isDisabled={!!error || !!ledgerError || !address || !genesis}
onClick={_onSave}
>
{t<string>('Import Account')}
{t('Import Account')}
</Button>
)
}
+3 -3
View File
@@ -9,7 +9,7 @@ import { QrScanAddress } from '@polkadot/react-qr';
import AccountNamePasswordCreation from '../components/AccountNamePasswordCreation.js';
import { ActionContext, Address, ButtonArea, NextStepButton, VerticalSpace } from '../components/index.js';
import useTranslation from '../hooks/useTranslation.js';
import { useTranslation } from '../hooks/index.js';
import { createAccountExternal, createAccountSuri, createSeed } from '../messaging.js';
import { Header, Name } from '../partials/index.js';
@@ -65,7 +65,7 @@ export default function ImportQr (): React.ReactElement {
<>
<Header
showBackArrow
text={t<string>('Scan Address Qr')}
text={t('Scan Address Qr')}
/>
{!account && (
<div>
@@ -105,7 +105,7 @@ export default function ImportQr (): React.ReactElement {
isDisabled={!name || (!account.isAddress && !password)}
onClick={_onCreate}
>
{t<string>('Add the account with identified address')}
{t('Add the account with identified address')}
</NextStepButton>
</ButtonArea>
</>
@@ -13,8 +13,7 @@ import { validateSeed } from '@polkadot/extension-ui/messaging';
import { objectSpread } from '@polkadot/util';
import { ButtonArea, Dropdown, InputWithLabel, NextStepButton, TextAreaWithLabel, VerticalSpace, Warning } from '../../components/index.js';
import useGenesisHashOptions from '../../hooks/useGenesisHashOptions.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useGenesisHashOptions, useTranslation } from '../../hooks/index.js';
import { styled } from '../../styled.js';
interface Props {
@@ -57,8 +56,8 @@ function SeedAndPath ({ className, onAccountChange, onNextStep, type }: Props):
setAddress('');
onAccountChange(null);
setError(path
? t<string>('Invalid mnemonic seed or derivation path')
: t<string>('Invalid mnemonic seed')
? t('Invalid mnemonic seed or derivation path')
: t('Invalid mnemonic seed')
);
});
}, [t, genesis, seed, path, onAccountChange, type]);
@@ -74,7 +73,7 @@ function SeedAndPath ({ className, onAccountChange, onNextStep, type }: Props):
className='seedInput'
isError={!!error}
isFocused
label={t<string>('existing 12 or 24-word mnemonic seed')}
label={t('existing 12 or 24-word mnemonic seed')}
onChange={setSeed}
rowsCount={2}
value={seed || ''}
@@ -85,12 +84,12 @@ function SeedAndPath ({ className, onAccountChange, onNextStep, type }: Props):
isBelowInput
isDanger
>
{t<string>('Mnemonic needs to contain 12, 15, 18, 21, 24 words')}
{t('Mnemonic needs to contain 12, 15, 18, 21, 24 words')}
</Warning>
)}
<Dropdown
className='genesisSelection'
label={t<string>('Network')}
label={t('Network')}
onChange={setGenesis}
options={genesisOptions}
value={genesis}
@@ -100,13 +99,13 @@ function SeedAndPath ({ className, onAccountChange, onNextStep, type }: Props):
onClick={_onToggleAdvanced}
>
<FontAwesomeIcon icon={advanced ? faCaretDown : faCaretRight} />
<span>{t<string>('advanced')}</span>
<span>{t('advanced')}</span>
</div>
{ advanced && (
<InputWithLabel
className='derivationPath'
isError={!!path && !!error}
label={t<string>('derivation path')}
label={t('derivation path')}
onChange={setPath}
value={path || ''}
/>
@@ -125,7 +124,7 @@ function SeedAndPath ({ className, onAccountChange, onNextStep, type }: Props):
isDisabled={!address || !!error}
onClick={onNextStep}
>
{t<string>('Next')}
{t('Next')}
</NextStepButton>
</ButtonArea>
</>
@@ -7,8 +7,7 @@ import React, { useCallback, useContext, useEffect, useState } from 'react';
import AccountNamePasswordCreation from '../../components/AccountNamePasswordCreation.js';
import { AccountContext, ActionContext, Address } from '../../components/index.js';
import useMetadata from '../../hooks/useMetadata.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useMetadata, useTranslation } from '../../hooks/index.js';
import { createAccountSuri } from '../../messaging.js';
import { HeaderWithSteps } from '../../partials/index.js';
import { DEFAULT_TYPE } from '../../util/defaultType.js';
@@ -71,7 +70,7 @@ function ImportSeed (): React.ReactElement {
<>
<HeaderWithSteps
step={step1 ? 1 : 2}
text={t<string>('Import account')}
text={t('Import account')}
/>
<div>
<Address
@@ -90,7 +89,7 @@ function ImportSeed (): React.ReactElement {
)
: (
<AccountNamePasswordCreation
buttonLabel={t<string>('Add the account with the supplied seed')}
buttonLabel={t('Add the account with the supplied seed')}
isBusy={isBusy}
onBackClick={_onBackClick}
onCreate={_onCreate}
@@ -7,8 +7,7 @@ import type { ThemeProps } from '../../types.js';
import React, { useCallback, useContext } from 'react';
import { ActionBar, ActionContext, Button, Link, Table, Warning } from '../../components/index.js';
import useMetadata from '../../hooks/useMetadata.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useMetadata, useTranslation } from '../../hooks/index.js';
import { approveMetaRequest, rejectMetaRequest } from '../../messaging.js';
import { styled } from '../../styled.js';
@@ -46,46 +45,46 @@ function Request ({ className, metaId, request, url }: Props): React.ReactElemen
<div className={className}>
<Table>
<tr>
<td className='label'>{t<string>('from')}</td>
<td className='label'>{t('from')}</td>
<td className='data'>{url}</td>
</tr>
<tr>
<td className='label'>{t<string>('chain')}</td>
<td className='label'>{t('chain')}</td>
<td className='data'>{request.chain}</td>
</tr>
<tr>
<td className='label'>{t<string>('icon')}</td>
<td className='label'>{t('icon')}</td>
<td className='data'>{request.icon}</td>
</tr>
<tr>
<td className='label'>{t<string>('decimals')}</td>
<td className='label'>{t('decimals')}</td>
<td className='data'>{request.tokenDecimals}</td>
</tr>
<tr>
<td className='label'>{t<string>('symbol')}</td>
<td className='label'>{t('symbol')}</td>
<td className='data'>{request.tokenSymbol}</td>
</tr>
<tr>
<td className='label'>{t<string>('upgrade')}</td>
<td className='data'>{chain ? chain.specVersion : t<string>('<unknown>')} -&gt; {request.specVersion}</td>
<td className='label'>{t('upgrade')}</td>
<td className='data'>{chain ? chain.specVersion : t('<unknown>')} -&gt; {request.specVersion}</td>
</tr>
</Table>
<div className='requestInfo'>
<Warning className='requestWarning'>
{t<string>('This approval will add the metadata to your extension instance, allowing future requests to be decoded using this metadata.')}
{t('This approval will add the metadata to your extension instance, allowing future requests to be decoded using this metadata.')}
</Warning>
<Button
className='btnAccept'
onClick={_onApprove}
>
{t<string>('Yes, do this metadata update')}
{t('Yes, do this metadata update')}
</Button>
<ActionBar className='btnReject'>
<Link
isDanger
onClick={_onReject}
>
{t<string>('Reject')}
{t('Reject')}
</Link>
</ActionBar>
</div>
@@ -4,7 +4,7 @@
import React, { useContext } from 'react';
import { Loading, MetadataReqContext } from '../../components/index.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useTranslation } from '../../hooks/index.js';
import { Header } from '../../partials/index.js';
import Request from './Request.js';
@@ -14,7 +14,7 @@ export default function Metadata (): React.ReactElement {
return (
<>
<Header text={t<string>('Metadata')} />
<Header text={t('Metadata')} />
{requests[0]
? (
<Request
@@ -7,7 +7,7 @@ import React from 'react';
import { Trans } from 'react-i18next';
import { useParams } from 'react-router';
import useTranslation from '../hooks/useTranslation.js';
import { useTranslation } from '../hooks/index.js';
import { Header } from '../partials/index.js';
import { styled } from '../styled.js';
@@ -26,10 +26,10 @@ function PhishingDetected ({ className }: Props): React.ReactElement<Props> {
return (
<>
<Header text={t<string>('Phishing detected')} />
<Header text={t('Phishing detected')} />
<div className={className}>
<p>
{t<string>('You have been redirected because the Polkadot{.js} extension believes that this website could compromise the security of your accounts and your tokens.')}
{t('You have been redirected because the Polkadot{.js} extension believes that this website could compromise the security of your accounts and your tokens.')}
</p>
<p className='websiteAddress'>
{decodedWebsite}
@@ -10,7 +10,7 @@ import React, { useCallback, useContext, useEffect, useState } from 'react';
import { u8aToString } from '@polkadot/util';
import { AccountContext, ActionContext, Address, Button, InputFileWithLabel, InputWithLabel, Warning } from '../components/index.js';
import useTranslation from '../hooks/useTranslation.js';
import { useTranslation } from '../hooks/index.js';
import { batchRestore, jsonGetAccountInfo, jsonRestore } from '../messaging.js';
import { Header } from '../partials/index.js';
import { styled } from '../styled.js';
@@ -117,7 +117,7 @@ function Upload ({ className }: Props): React.ReactElement {
<Header
showBackArrow
smallMargin
text={t<string>('Restore from JSON')}
text={t('Restore from JSON')}
/>
<div className={className}>
{accountsInfo.map(({ address, genesisHash, name, type = DEFAULT_TYPE }, index) => (
@@ -132,7 +132,7 @@ function Upload ({ className }: Props): React.ReactElement {
<InputFileWithLabel
accept={acceptedFormats}
isError={isFileError}
label={t<string>('backup file')}
label={t('backup file')}
onChange={_onChangeFile}
withLabel
/>
@@ -140,14 +140,14 @@ function Upload ({ className }: Props): React.ReactElement {
<Warning
isDanger
>
{t<string>('Invalid Json file')}
{t('Invalid Json file')}
</Warning>
)}
{requirePassword && (
<div>
<InputWithLabel
isError={isPasswordError}
label={t<string>('Password for this file')}
label={t('Password for this file')}
onChange={_onChangePass}
type='password'
/>
@@ -156,7 +156,7 @@ function Upload ({ className }: Props): React.ReactElement {
isBelowInput
isDanger
>
{t<string>('Unable to decode using the supplied passphrase')}
{t('Unable to decode using the supplied passphrase')}
</Warning>
)}
</div>
@@ -167,7 +167,7 @@ function Upload ({ className }: Props): React.ReactElement {
isDisabled={isFileError || isPasswordError}
onClick={_onRestore}
>
{t<string>('Restore')}
{t('Restore')}
</Button>
</div>
</>
@@ -7,7 +7,7 @@ import React, { useMemo } from 'react';
import { isAscii, u8aToString, u8aUnwrapBytes } from '@polkadot/util';
import useTranslation from '../../hooks/useTranslation.js';
import { useTranslation } from '../../hooks/index.js';
import { styled } from '../../styled.js';
interface Props {
@@ -30,11 +30,11 @@ function Bytes ({ bytes, className, url }: Props): React.ReactElement<Props> {
<table className={className}>
<tbody>
<tr>
<td className='label'>{t<string>('from')}</td>
<td className='label'>{t('from')}</td>
<td className='data'>{url}</td>
</tr>
<tr>
<td className='label'>{t<string>('bytes')}</td>
<td className='label'>{t('bytes')}</td>
<td className='data pre'><div>{text}</div></td>
</tr>
</tbody>
@@ -1,19 +1,18 @@
// Copyright 2019-2023 @polkadot/extension-ui authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { TFunction } from 'i18next';
import type { Chain } from '@polkadot/extension-chains/types';
import type { Call, ExtrinsicEra, ExtrinsicPayload } from '@polkadot/types/interfaces';
import type { AnyJson, SignerPayloadJSON } from '@polkadot/types/types';
import type { BN } from '@polkadot/util';
import type { TFunction } from '../../hooks/useTranslation.js';
import React, { useMemo, useRef } from 'react';
import { bnToBn, formatNumber } from '@polkadot/util';
import { Table } from '../../components/index.js';
import useMetadata from '../../hooks/useMetadata.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useMetadata, useTranslation } from '../../hooks/index.js';
interface Decoded {
args: AnyJson | null;
@@ -56,7 +55,7 @@ function renderMethod (data: string, { args, method }: Decoded, t: TFunction): R
if (!args || !method) {
return (
<tr>
<td className='label'>{t<string>('method data')}</td>
<td className='label'>{t('method data')}</td>
<td className='data'>{data}</td>
</tr>
);
@@ -65,7 +64,7 @@ function renderMethod (data: string, { args, method }: Decoded, t: TFunction): R
return (
<>
<tr>
<td className='label'>{t<string>('method')}</td>
<td className='label'>{t('method')}</td>
<td className='data'>
<details>
<summary>{method.section}.{method.method}{
@@ -79,7 +78,7 @@ function renderMethod (data: string, { args, method }: Decoded, t: TFunction): R
</tr>
{method.meta && (
<tr>
<td className='label'>{t<string>('info')}</td>
<td className='label'>{t('info')}</td>
<td className='data'>
<details>
<summary>{method.meta.docs.map((d) => d.toString().trim()).join(' ')}</summary>
@@ -93,13 +92,13 @@ function renderMethod (data: string, { args, method }: Decoded, t: TFunction): R
function mortalityAsString (era: ExtrinsicEra, hexBlockNumber: string, t: TFunction): string {
if (era.isImmortalEra) {
return t<string>('immortal');
return t('immortal');
}
const blockNumber = bnToBn(hexBlockNumber);
const mortal = era.asMortalEra;
return t<string>('mortal, valid from {{birth}} to {{death}}', {
return t('mortal, valid from {{birth}} to {{death}}', {
replace: {
birth: formatNumber(mortal.birth(blockNumber)),
death: formatNumber(mortal.death(blockNumber))
@@ -124,30 +123,30 @@ function Extrinsic ({ className, payload: { era, nonce, tip }, request: { blockN
isFull
>
<tr>
<td className='label'>{t<string>('from')}</td>
<td className='label'>{t('from')}</td>
<td className='data'>{url}</td>
</tr>
<tr>
<td className='label'>{chain ? t<string>('chain') : t<string>('genesis')}</td>
<td className='label'>{chain ? t('chain') : t('genesis')}</td>
<td className='data'>{chain ? chain.name : genesisHash}</td>
</tr>
<tr>
<td className='label'>{t<string>('version')}</td>
<td className='label'>{t('version')}</td>
<td className='data'>{specVersion.toNumber()}</td>
</tr>
<tr>
<td className='label'>{t<string>('nonce')}</td>
<td className='label'>{t('nonce')}</td>
<td className='data'>{formatNumber(nonce)}</td>
</tr>
{!tip.isEmpty && (
<tr>
<td className='label'>{t<string>('tip')}</td>
<td className='label'>{t('tip')}</td>
<td className='data'>{formatNumber(tip)}</td>
</tr>
)}
{renderMethod(method, decoded, t)}
<tr>
<td className='label'>{t<string>('lifetime')}</td>
<td className='label'>{t('lifetime')}</td>
<td className='data'>{mortalityAsString(era, blockNumber, t)}</td>
</tr>
</Table>
@@ -9,8 +9,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React, { useCallback, useEffect, useState } from 'react';
import { Button, Warning } from '../../components/index.js';
import { useLedger } from '../../hooks/useLedger.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useLedger, useTranslation } from '../../hooks/index.js';
import { styled } from '../../styled.js';
interface Props {
@@ -78,7 +77,7 @@ function LedgerSign ({ accountIndex, addressOffset, className, error, genesisHas
onClick={_onRefresh}
>
<FontAwesomeIcon icon={faSync} />
{t<string>('Refresh')}
{t('Refresh')}
</Button>
)
: (
@@ -86,7 +85,7 @@ function LedgerSign ({ accountIndex, addressOffset, className, error, genesisHas
isBusy={isBusy || ledgerLoading}
onClick={_onSignLedger}
>
{t<string>('Sign on Ledger')}
{t('Sign on Ledger')}
</Button>
)
}
@@ -10,7 +10,7 @@ import { QrDisplayPayload, QrScanSignature } from '@polkadot/react-qr';
import { u8aWrapBytes } from '@polkadot/util';
import { Button } from '../../components/index.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useTranslation } from '../../hooks/index.js';
import { styled } from '../../styled.js';
import { CMD_MORTAL, CMD_SIGN_MESSAGE } from './Request/index.js';
@@ -78,7 +78,7 @@ function Qr ({ address, className, cmd, genesisHash, onSignature, payload }: Pro
className='scanButton'
onClick={_onShowQr}
>
{t<string>('Scan signature via camera')}
{t('Scan signature via camera')}
</Button>
)}
</div>
@@ -6,7 +6,7 @@ import React, { useCallback, useContext, useEffect, useState } from 'react';
import { PASSWORD_EXPIRY_MIN } from '@polkadot/extension-base/defaults';
import { ActionBar, ActionContext, Button, ButtonArea, Checkbox, Link } from '../../../components/index.js';
import useTranslation from '../../../hooks/useTranslation.js';
import { useTranslation } from '../../../hooks/index.js';
import { approveSignPassword, cancelSignRequest, isSignLocked } from '../../../messaging.js';
import { styled } from '../../../styled.js';
import Unlock from '../Unlock.js';
@@ -81,11 +81,11 @@ function SignArea ({ buttonText, className, error, isExternal, isFirst, setError
<Checkbox
checked={savePass}
label={ isLocked
? t<string>(
? t(
'Remember my password for the next {{expiration}} minutes',
{ replace: { expiration: PASSWORD_EXPIRY_MIN } }
)
: t<string>(
: t(
'Extend the period without password by {{expiration}} minutes',
{ replace: { expiration: PASSWORD_EXPIRY_MIN } }
)
@@ -123,7 +123,7 @@ function SignArea ({ buttonText, className, error, isExternal, isFirst, setError
isDanger
onClick={_onCancel}
>
{t<string>('Cancel')}
{t('Cancel')}
</Link>
</ActionBar>
</ButtonArea>
@@ -11,8 +11,8 @@ import React, { useCallback, useContext, useEffect, useState } from 'react';
import { TypeRegistry } from '@polkadot/types';
import { ActionContext, Address, VerticalSpace, Warning } from '../../../components/index.js';
import { useTranslation } from '../../../hooks/index.js';
import { approveSignSignature } from '../../../messaging.js';
import { useTranslation } from '../../../translate.js';
import Bytes from '../Bytes.js';
import Extrinsic from '../Extrinsic.js';
import LedgerSign from '../LedgerSign.js';
@@ -162,12 +162,12 @@ export default function Request ({ account: { accountIndex, addressOffset, genes
<VerticalSpace />
{isExternal && !isHardware && !genesisHash && (
<>
<Warning isDanger>{t<string>('"Allow use on any network" is not supported to show a QR code. You must associate this account with a network.')}</Warning>
<Warning isDanger>{t('"Allow use on any network" is not supported to show a QR code. You must associate this account with a network.')}</Warning>
<VerticalSpace />
</>
)}
{isHardware && <>
<Warning>{t<string>('Message signing is not supported for hardware wallets.')}</Warning>
<Warning>{t('Message signing is not supported for hardware wallets.')}</Warning>
<VerticalSpace />
</>}
<SignArea
@@ -4,7 +4,7 @@
import React, { useCallback } from 'react';
import { InputWithLabel, Warning } from '../../components/index.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useTranslation } from '../../hooks/index.js';
interface Props {
className?: string;
@@ -33,7 +33,7 @@ function Unlock ({ className, error, isBusy, onSign, password, setError, setPass
disabled={isBusy}
isError={!password || !!error}
isFocused
label={t<string>('Password for this account')}
label={t('Password for this account')}
onChange={_onChangePassword}
onEnter={onSign}
type='password'
@@ -6,7 +6,7 @@ import type { SignerPayloadJSON } from '@polkadot/types/types';
import React, { useCallback, useContext, useEffect, useState } from 'react';
import { Loading, SigningReqContext } from '../../components/index.js';
import useTranslation from '../../hooks/useTranslation.js';
import { useTranslation } from '../../hooks/index.js';
import { Header } from '../../partials/index.js';
import Request from './Request/index.js';
import TransactionIndex from './TransactionIndex.js';
@@ -47,7 +47,7 @@ export default function Signing (): React.ReactElement {
return request
? (
<>
<Header text={isTransaction ? t<string>('Transaction') : t<string>('Sign message')}>
<Header text={isTransaction ? t('Transaction') : t('Sign message')}>
{requests.length > 1 && (
<TransactionIndex
index={requestIndex}
@@ -59,7 +59,7 @@ export default function Signing (): React.ReactElement {
</Header>
<Request
account={request.account}
buttonText={isTransaction ? t<string>('Sign the transaction') : t<string>('Sign the message')}
buttonText={isTransaction ? t('Sign the transaction') : t('Sign the message')}
isFirst={requestIndex === 0}
request={request.request}
signId={request.id}
+8 -8
View File
@@ -6,7 +6,7 @@ import type { ThemeProps } from '../types.js';
import React, { useCallback, useContext } from 'react';
import { ActionContext, Box, Button, ButtonArea, List, VerticalSpace } from '../components/index.js';
import useTranslation from '../hooks/useTranslation.js';
import { useTranslation } from '../hooks/index.js';
import { Header } from '../partials/index.js';
import { styled } from '../styled.js';
@@ -28,21 +28,21 @@ function Welcome ({ className }: Props): React.ReactElement<Props> {
return (
<>
<Header text={t<string>('Welcome')} />
<Header text={t('Welcome')} />
<div className={className}>
<p>{t<string>('Before we start, just a couple of notes regarding use:')}</p>
<p>{t('Before we start, just a couple of notes regarding use:')}</p>
<Box>
<List>
<li>{t<string>('We do not send any clicks, pageviews or events to a central server')}</li>
<li>{t<string>('We do not use any trackers or analytics')}</li>
<li>{t<string>("We don't collect keys, addresses or any information - your information never leaves this machine")}</li>
<li>{t('We do not send any clicks, pageviews or events to a central server')}</li>
<li>{t('We do not use any trackers or analytics')}</li>
<li>{t("We don't collect keys, addresses or any information - your information never leaves this machine")}</li>
</List>
</Box>
<p>{t<string>('... we are not in the information collection business (even anonymized).')}</p>
<p>{t('... we are not in the information collection business (even anonymized).')}</p>
</div>
<VerticalSpace />
<ButtonArea>
<Button onClick={_onClick}>{t<string>('Understood, let me continue')}</Button>
<Button onClick={_onClick}>{t('Understood, let me continue')}</Button>
</ButtonArea>
</>
);
@@ -18,10 +18,7 @@ import CopyToClipboard from 'react-copy-to-clipboard';
import { decodeAddress, encodeAddress } from '@polkadot/util-crypto';
import details from '../assets/details.svg';
import useMetadata from '../hooks/useMetadata.js';
import useOutsideClick from '../hooks/useOutsideClick.js';
import useToast from '../hooks/useToast.js';
import useTranslation from '../hooks/useTranslation.js';
import { useMetadata, useOutsideClick, useToast, useTranslation } from '../hooks/index.js';
import { showAccount } from '../messaging.js';
import { styled } from '../styled.js';
import { DEFAULT_TYPE } from '../util/defaultType.js';
@@ -157,7 +154,7 @@ function Address ({ actions, address, children, className, genesisHash, isExtern
);
const _onCopy = useCallback(
() => show(t<string>('Copied')),
() => show(t('Copied')),
[show, t]
);
@@ -170,7 +167,7 @@ function Address ({ actions, address, children, className, genesisHash, isExtern
const Name = () => {
const accountName = name || account?.name;
const displayName = accountName || t<string>('<unknown>');
const displayName = accountName || t('<unknown>');
return (
<>
@@ -181,14 +178,14 @@ function Address ({ actions, address, children, className, genesisHash, isExtern
className='hardwareIcon'
icon={faUsb}
rotation={270}
title={t<string>('hardware wallet account')}
title={t('hardware wallet account')}
/>
)
: (
<FontAwesomeIcon
className='externalIcon'
icon={faQrcode}
title={t<string>('external account')}
title={t('external account')}
/>
)
)}
@@ -258,7 +255,7 @@ function Address ({ actions, address, children, className, genesisHash, isExtern
className='fullAddress'
data-field='address'
>
{formatted || address || t<string>('<unknown>')}
{formatted || address || t('<unknown>')}
</div>
<CopyToClipboard text={(formatted && formatted) || ''}>
<FontAwesomeIcon
@@ -266,7 +263,7 @@ function Address ({ actions, address, children, className, genesisHash, isExtern
icon={faCopy}
onClick={_onCopy}
size='sm'
title={t<string>('copy address')}
title={t('copy address')}
/>
</CopyToClipboard>
{(actions || showVisibilityAction) && (
@@ -275,7 +272,7 @@ function Address ({ actions, address, children, className, genesisHash, isExtern
icon={isHidden ? faEyeSlash : faEye}
onClick={_toggleVisibility}
size='sm'
title={t<string>('account visibility')}
title={t('account visibility')}
/>
)}
</div>
@@ -4,9 +4,9 @@
import type { WithTranslation } from 'react-i18next';
import React from 'react';
import { withTranslation } from 'react-i18next';
import Header from '../partials/Header.js';
import translate from '../translate.js';
import Button from './Button.js';
import ButtonArea from './ButtonArea.js';
import VerticalSpace from './VerticalSpace.js';
@@ -22,6 +22,8 @@ interface State {
error: Error | null;
}
const translate = withTranslation();
// NOTE: This is the only way to do an error boundary, via extend
class ErrorBoundary extends React.Component<Props> {
public override state: State = { error: null };
@@ -51,9 +53,9 @@ class ErrorBoundary extends React.Component<Props> {
return error
? (
<>
<Header text={t<string>('An error occurred')} />
<Header text={t<string, string, Record<string, string>>('An error occurred')} />
<div>
{t<string>('Something went wrong with the query and rendering of this component. {{message}}', {
{t('Something went wrong with the query and rendering of this component. {{message}}', {
replace: { message: error.message }
})}
</div>
@@ -62,7 +64,7 @@ class ErrorBoundary extends React.Component<Props> {
<Button
onClick={this.#goHome}
>
{t<string>('Back to home')}
{t('Back to home')}
</Button>
</ButtonArea>
</>
@@ -9,7 +9,7 @@ import Dropzone from 'react-dropzone';
import { formatNumber, hexToU8a, isHex, u8aToString } from '@polkadot/util';
import useTranslation from '../hooks/useTranslation.js';
import { useTranslation } from '../hooks/index.js';
import { styled } from '../styled.js';
import Label from './Label.js';
@@ -106,8 +106,8 @@ function InputFile ({ accept, className = '', clearContent, convertHex, isDisabl
<em className='label'>
{
!file || clearContent
? placeholder || t<string>('click to select or drag and drop the file here')
: placeholder || t<string>('{{name}} ({{size}} bytes)', {
? placeholder || t('click to select or drag and drop the file here')
: placeholder || t('{{name}} ({{size}} bytes)', {
replace: {
name: file.name,
size: formatNumber(file.size)
@@ -3,7 +3,7 @@
import React, { useCallback, useState } from 'react';
import useTranslation from '../hooks/useTranslation.js';
import { useTranslation } from '../hooks/index.js';
import { styled } from '../styled.js';
import Label from './Label.js';
import { Input } from './TextInputs.js';
@@ -74,7 +74,7 @@ function InputWithLabel ({ className, defaultValue, disabled, isError, isFocused
withError={isError}
/>
{ isCapsLock && (
<Warning isBelowInput>{t<string>('Warning: Caps lock is on')}</Warning>
<Warning isBelowInput>{t('Warning: Caps lock is on')}</Warning>
)}
</Label>
);
@@ -3,7 +3,7 @@
import React from 'react';
import useTranslation from '../hooks/useTranslation.js';
import { useTranslation } from '../hooks/index.js';
interface Props {
children?: React.ReactNode;
@@ -14,7 +14,7 @@ export default function Loading ({ children }: Props): React.ReactElement<Props>
if (!children) {
return (
<div>{t<string>('... loading ...')}</div>
<div>{t('... loading ...')}</div>
);
}
@@ -8,7 +8,7 @@ import { faCopy } from '@fortawesome/free-regular-svg-icons';
import React from 'react';
import CopyToClipboard from 'react-copy-to-clipboard';
import useTranslation from '../hooks/useTranslation.js';
import { useTranslation } from '../hooks/index.js';
import { styled } from '../styled.js';
import ActionText from './ActionText.js';
import BoxWithLabel from './BoxWithLabel.js';
@@ -26,7 +26,7 @@ function MnemonicSeed ({ className, onCopy, seed }: Props): React.ReactElement<P
<div className={className}>
<BoxWithLabel
className='mnemonicDisplay'
label={t<string>('Generated 12-word mnemonic seed:')}
label={t('Generated 12-word mnemonic seed:')}
value={seed}
/>
<div className='buttonsRow'>
@@ -36,7 +36,7 @@ function MnemonicSeed ({ className, onCopy, seed }: Props): React.ReactElement<P
data-seed-action='copy'
icon={faCopy}
onClick={onCopy}
text={t<string>('Copy to clipboard')}
text={t('Copy to clipboard')}
/>
</CopyToClipboard>
</div>
@@ -5,7 +5,7 @@ import type { ResultType, Validator } from '../util/validators.js';
import React, { useEffect, useState } from 'react';
import useIsMounted from '../hooks/useIsMounted.js';
import { useIsMounted } from '../hooks/index.js';
import { Result } from '../util/validators.js';
import Warning from './Warning.js';
+11
View File
@@ -0,0 +1,11 @@
// Copyright 2019-2023 @polkadot/extension-ui authors & contributors
// SPDX-License-Identifier: Apache-2.0
export { default as useGenesisHashOptions } from './useGenesisHashOptions.js';
export { default as useIsMounted } from './useIsMounted.js';
export { default as useIsPopup } from './useIsPopup.js';
export { default as useLedger } from './useLedger.js';
export { default as useMetadata } from './useMetadata.js';
export { default as useOutsideClick } from './useOutsideClick.js';
export { default as useToast } from './useToast.js';
export { default as useTranslation } from './useTranslation.js';
@@ -16,7 +16,7 @@ interface Option {
const RELAY_CHAIN = 'Relay Chain';
export default function (): Option[] {
export default function useGenesisHashOptions (): Option[] {
const { t } = useTranslation();
const [metadataChains, setMetadatachains] = useState<Option[]>([]);
@@ -30,7 +30,7 @@ export default function (): Option[] {
const hashes = useMemo(() => [
{
text: t<string>('Allow use on any chain'),
text: t('Allow use on any chain'),
value: '' as HexString
},
// put the relay chains at the top
+4 -4
View File
@@ -56,7 +56,7 @@ function retrieveLedger (genesis: string): Ledger {
return ledger;
}
export function useLedger (genesis?: string | null, accountIndex = 0, addressOffset = 0): State {
export default function useLedger (genesis?: string | null, accountIndex = 0, addressOffset = 0): State {
const [isLoading, setIsLoading] = useState(false);
const [isLocked, setIsLocked] = useState(false);
const [refreshLock, setRefreshLock] = useState(false);
@@ -107,16 +107,16 @@ export function useLedger (genesis?: string | null, accountIndex = 0, addressOff
const { network } = getNetwork(genesis) || { network: 'unknown network' };
const warningMessage = e.message.includes('Code: 26628')
? t<string>('Is your ledger locked?')
? t('Is your ledger locked?')
: null;
const errorMessage = e.message.includes('App does not seem to be open')
? t<string>('App "{{network}}" does not seem to be open', { replace: { network } })
? t('App "{{network}}" does not seem to be open', { replace: { network } })
: e.message;
setIsLocked(true);
setWarning(warningMessage);
setError(t<string>(
setError(t(
'Ledger error: {{errorMessage}}',
{ replace: { errorMessage } }
));
@@ -1,6 +1,14 @@
// Copyright 2019-2023 @polkadot/extension-ui authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { useTranslation } from 'react-i18next';
import { useTranslation as useTranslationBase } from 'react-i18next';
export default useTranslation;
export type TFunction = (key: string, options?: { replace: Record<string, string | number> }) => string;
interface UseTranslation {
t: TFunction
}
export default function useTranslation (): UseTranslation {
return useTranslationBase();
}
@@ -7,7 +7,7 @@ import React, { useCallback, useContext, useEffect, useMemo, useState } from 're
import { Trans } from 'react-i18next';
import { AccountContext, Checkbox, Warning } from '../components/index.js';
import useTranslation from '../hooks/useTranslation.js';
import { useTranslation } from '../hooks/index.js';
import AccountsTree from '../Popup/Accounts/AccountsTree.js';
import { styled } from '../styled.js';
@@ -72,7 +72,7 @@ function AccounSelection ({ className, origin, showHidden = false, url, withWarn
checked={areAllAccountsSelected}
className='accountTree-checkbox'
indeterminate={isIndeterminate}
label={t<string>('Select all')}
label={t('Select all')}
onChange={_onSelectAllToggle}
/>
<div className='accountList'>
@@ -11,8 +11,7 @@ import logo from '../assets/pjs.svg';
import { ActionContext } from '../components/index.js';
import InputFilter from '../components/InputFilter.js';
import Link from '../components/Link.js';
import useOutsideClick from '../hooks/useOutsideClick.js';
import useTranslation from '../hooks/useTranslation.js';
import { useOutsideClick, useTranslation } from '../hooks/index.js';
import { getConnectedTabsUrl } from '../messaging.js';
import { styled } from '../styled.js';
import MenuAdd from './MenuAdd.js';
@@ -134,7 +133,7 @@ function Header ({ children, className = '', onFilter, showAdd, showBackArrow, s
<InputFilter
className='inputFilter'
onChange={_onChangeFilter}
placeholder={t<string>('Search by name or network...')}
placeholder={t('Search by name or network...')}
value={filter}
withReset
/>
+11 -13
View File
@@ -9,9 +9,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React, { useCallback, useContext } from 'react';
import { AccountContext, Link, MediaContext, Menu, MenuDivider, MenuItem } from '../components/index.js';
import useIsPopup from '../hooks/useIsPopup.js';
import { useLedger } from '../hooks/useLedger.js';
import useTranslation from '../hooks/useTranslation.js';
import { useIsPopup, useLedger, useTranslation } from '../hooks/index.js';
import { windowOpen } from '../messaging.js';
import { styled } from '../styled.js';
@@ -50,7 +48,7 @@ function MenuAdd ({ className, reference }: Props): React.ReactElement<Props> {
<MenuItem className='menuItem'>
<Link to={'/account/create'}>
<FontAwesomeIcon icon={faPlusCircle} />
<span>{ t<string>('Create new account')}</span>
<span>{ t('Create new account')}</span>
</Link>
</MenuItem>
<MenuDivider />
@@ -59,7 +57,7 @@ function MenuAdd ({ className, reference }: Props): React.ReactElement<Props> {
<MenuItem className='menuItem'>
<Link to={`/account/derive/${master.address}`}>
<FontAwesomeIcon icon={faCodeBranch} />
<span>{t<string>('Derive from an account')}</span>
<span>{t('Derive from an account')}</span>
</Link>
</MenuItem>
<MenuDivider />
@@ -68,13 +66,13 @@ function MenuAdd ({ className, reference }: Props): React.ReactElement<Props> {
<MenuItem className='menuItem'>
<Link to={'/account/export-all'}>
<FontAwesomeIcon icon={faFileExport} />
<span>{t<string>('Export all accounts')}</span>
<span>{t('Export all accounts')}</span>
</Link>
</MenuItem>
<MenuItem className='menuItem'>
<Link to='/account/import-seed'>
<FontAwesomeIcon icon={faKey} />
<span>{t<string>('Import account from pre-existing seed')}</span>
<span>{t('Import account from pre-existing seed')}</span>
</Link>
</MenuItem>
<MenuItem className='menuItem'>
@@ -83,7 +81,7 @@ function MenuAdd ({ className, reference }: Props): React.ReactElement<Props> {
to={isPopup ? undefined : jsonPath}
>
<FontAwesomeIcon icon={faFileUpload} />
<span>{t<string>('Restore account from backup JSON file')}</span>
<span>{t('Restore account from backup JSON file')}</span>
</Link>
</MenuItem>
<MenuDivider />
@@ -91,13 +89,13 @@ function MenuAdd ({ className, reference }: Props): React.ReactElement<Props> {
<Link
isDisabled={!mediaAllowed}
title={!mediaAllowed
? t<string>('Camera access must be first enabled in the settings')
? t('Camera access must be first enabled in the settings')
: ''
}
to='/account/import-qr'
>
<FontAwesomeIcon icon={faQrcode} />
<span>{t<string>('Attach external QR-signer account')}</span>
<span>{t('Attach external QR-signer account')}</span>
</Link>
</MenuItem>
<MenuItem className='menuItem ledger'>
@@ -105,14 +103,14 @@ function MenuAdd ({ className, reference }: Props): React.ReactElement<Props> {
? (
<Link
isDisabled={!isLedgerCapable}
title={ (!isLedgerCapable && t<string>('Ledger devices can only be connected with Chrome browser')) || ''}
title={ (!isLedgerCapable && t('Ledger devices can only be connected with Chrome browser')) || ''}
to={ledgerPath}
>
<FontAwesomeIcon
icon={faUsb}
rotation={270}
/>
<span>{ t<string>('Attach ledger account')}</span>
<span>{ t('Attach ledger account')}</span>
</Link>
)
: (
@@ -121,7 +119,7 @@ function MenuAdd ({ className, reference }: Props): React.ReactElement<Props> {
icon={faUsb}
rotation={270}
/>
<span>{ t<string>('Connect Ledger device')}</span>
<span>{ t('Connect Ledger device')}</span>
</Link>
)
}
@@ -10,8 +10,7 @@ import { ThemeContext } from 'styled-components';
import settings from '@polkadot/ui-settings';
import { ActionContext, ActionText, Checkbox, Dropdown, Menu, MenuDivider, MenuItem, Svg, Switch, themes, ThemeSwitchContext } from '../components/index.js';
import useIsPopup from '../hooks/useIsPopup.js';
import useTranslation from '../hooks/useTranslation.js';
import { useIsPopup, useTranslation } from '../hooks/index.js';
import { setNotification, windowOpen } from '../messaging.js';
import { styled } from '../styled.js';
import getLanguageOptions from '../util/getLanguageOptions.js';
@@ -98,14 +97,14 @@ function MenuSettings ({ className, reference }: Props): React.ReactElement<Prop
>
<Switch
checked={themeContext.id === themes.dark.id}
checkedLabel={t<string>('Dark')}
checkedLabel={t('Dark')}
onChange={_onChangeTheme}
uncheckedLabel={t<string>('Light')}
uncheckedLabel={t('Light')}
/>
</MenuItem>
<MenuItem
className='setting'
title={t<string>('Display address format for')}
title={t('Display address format for')}
>
<Dropdown
className='dropdown'
@@ -117,7 +116,7 @@ function MenuSettings ({ className, reference }: Props): React.ReactElement<Prop
</MenuItem>
<MenuItem
className='setting'
title={t<string>('Language')}
title={t('Language')}
>
<Dropdown
className='dropdown'
@@ -129,7 +128,7 @@ function MenuSettings ({ className, reference }: Props): React.ReactElement<Prop
</MenuItem>
<MenuItem
className='setting'
title={t<string>('Notifications')}
title={t('Notifications')}
>
<Dropdown
className='dropdown'
@@ -141,12 +140,12 @@ function MenuSettings ({ className, reference }: Props): React.ReactElement<Prop
</MenuItem>
<MenuItem
className='setting'
title={t<string>('External accounts and Access')}
title={t('External accounts and Access')}
>
<Checkbox
checked={camera}
className='checkbox camera'
label={t<string>('Allow QR Camera Access')}
label={t('Allow QR Camera Access')}
onChange={setCamera}
/>
</MenuItem>
@@ -156,7 +155,7 @@ function MenuSettings ({ className, reference }: Props): React.ReactElement<Prop
className='manageWebsiteAccess'
icon={faTasks}
onClick={_goToAuthList}
text={t<string>('Manage Website Access')}
text={t('Manage Website Access')}
/>
</MenuItem>
{isPopup && (
@@ -165,7 +164,7 @@ function MenuSettings ({ className, reference }: Props): React.ReactElement<Prop
className='openWindow'
icon={faExpand}
onClick={_onWindowOpen}
text={t<string>('Open extension in new window')}
text={t('Open extension in new window')}
/>
</MenuItem>
)}
+3 -3
View File
@@ -4,7 +4,7 @@
import React, { useContext, useMemo } from 'react';
import { AccountContext, InputWithLabel, ValidatedInput } from '../components/index.js';
import useTranslation from '../hooks/useTranslation.js';
import { useTranslation } from '../hooks/index.js';
import { isNotShorterThan } from '../util/validators.js';
interface Props {
@@ -20,7 +20,7 @@ interface Props {
export default function Name ({ address, className, isFocused, label, onBlur, onChange, value }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { accounts } = useContext(AccountContext);
const isNameValid = useMemo(() => isNotShorterThan(3, t<string>('Account name is too short')), [t]);
const isNameValid = useMemo(() => isNotShorterThan(3, t('Account name is too short')), [t]);
const account = accounts.find((account) => account.address === address);
const startValue = value || account?.name;
@@ -32,7 +32,7 @@ export default function Name ({ address, className, isFocused, label, onBlur, on
data-input-name
defaultValue={startValue}
isFocused={isFocused}
label={label || t<string>('A descriptive name for your account')}
label={label || t('A descriptive name for your account')}
onBlur={onBlur}
onEnter={onBlur}
onValidatedChange={onChange}
@@ -6,7 +6,7 @@ import type { Validator } from '../util/validators.js';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { InputWithLabel, ValidatedInput } from '../components/index.js';
import useTranslation from '../hooks/useTranslation.js';
import { useTranslation } from '../hooks/index.js';
import { allOf, isNotShorterThan, isSameAs } from '../util/validators.js';
interface Props {
@@ -20,10 +20,10 @@ export default function Password ({ isFocussed, onChange }: Props): React.ReactE
const { t } = useTranslation();
const [pass1, setPass1] = useState<string | null>(null);
const [pass2, setPass2] = useState<string | null>(null);
const isFirstPasswordValid = useMemo(() => isNotShorterThan(MIN_LENGTH, t<string>('Password is too short')), [t]);
const isFirstPasswordValid = useMemo(() => isNotShorterThan(MIN_LENGTH, t('Password is too short')), [t]);
const isSecondPasswordValid = useCallback((firstPassword: string): Validator<string> => allOf(
isNotShorterThan(MIN_LENGTH, t<string>('Password is too short')),
isSameAs(firstPassword, t<string>('Passwords do not match'))
isNotShorterThan(MIN_LENGTH, t('Password is too short')),
isSameAs(firstPassword, t('Passwords do not match'))
), [t]);
useEffect((): void => {
@@ -36,7 +36,7 @@ export default function Password ({ isFocussed, onChange }: Props): React.ReactE
component={InputWithLabel}
data-input-password
isFocused={isFocussed}
label={t<string>('A new password for this account')}
label={t('A new password for this account')}
onValidatedChange={setPass1}
type='password'
validator={isFirstPasswordValid}
@@ -45,7 +45,7 @@ export default function Password ({ isFocussed, onChange }: Props): React.ReactE
<ValidatedInput
component={InputWithLabel}
data-input-repeat-password
label={t<string>('Repeat password for verification')}
label={t('Repeat password for verification')}
onValidatedChange={setPass2}
type='password'
validator={isSecondPasswordValid(pass1)}
-12
View File
@@ -1,12 +0,0 @@
// Copyright 2019-2023 @polkadot/extension-ui authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { UseTranslationResponse } from 'react-i18next';
import { useTranslation as useTranslationBase, withTranslation } from 'react-i18next';
export function useTranslation (): UseTranslationResponse<string, undefined> {
return useTranslationBase();
}
export default withTranslation();
@@ -172,5 +172,8 @@
"all accounts": "",
"Message signing is not supported for hardware wallets.": "",
"\"Allow use on any network\" is not supported to show a QR code. You must associate this account with a network.": "",
"An error occurred": ""
"An error occurred": "",
"Is your ledger locked?": "",
"App \"{{network}}\" does not seem to be open": "",
"Ledger error: {{errorMessage}}": ""
}