diff --git a/packages/extension-ui/src/Popup/Accounts/Account.tsx b/packages/extension-ui/src/Popup/Accounts/Account.tsx index c08446e5..9b844d5e 100644 --- a/packages/extension-ui/src/Popup/Accounts/Account.tsx +++ b/packages/extension-ui/src/Popup/Accounts/Account.tsx @@ -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('Rename')} + {t('Rename')} {!isExternal && canDerive(type) && ( - {t('Derive New Account')} + {t('Derive New Account')} )} @@ -97,7 +96,7 @@ function Account ({ address, className, genesisHash, isExternal, isHardware, isH isDanger to={`/account/export/${address}`} > - {t('Export Account')} + {t('Export Account')} )} - {t('Forget Account')} + {t('Forget Account')} {!isHardware && ( <> diff --git a/packages/extension-ui/src/Popup/Accounts/AddAccount.tsx b/packages/extension-ui/src/Popup/Accounts/AddAccount.tsx index 0484384f..146df7a5 100644 --- a/packages/extension-ui/src/Popup/Accounts/AddAccount.tsx +++ b/packages/extension-ui/src/Popup/Accounts/AddAccount.tsx @@ -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 {
('Add Account')} + text={t('Add Account')} />
-

{t("You currently don't have any accounts. Create your first account to get started.")}

+

{t("You currently don't have any accounts. Create your first account to get started.")}

diff --git a/packages/extension-ui/src/Popup/Accounts/index.tsx b/packages/extension-ui/src/Popup/Accounts/index.tsx index 07649889..1b96a10b 100644 --- a/packages/extension-ui/src/Popup/Accounts/index.tsx +++ b/packages/extension-ui/src/Popup/Accounts/index.tsx @@ -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('Accounts')} + text={t('Accounts')} />
{filteredAccount.map((json, index): React.ReactNode => ( diff --git a/packages/extension-ui/src/Popup/AuthManagement/AccountManagement.tsx b/packages/extension-ui/src/Popup/AuthManagement/AccountManagement.tsx index 9cd0666b..f2b4a6c6 100644 --- a/packages/extension-ui/src/Popup/AuthManagement/AccountManagement.tsx +++ b/packages/extension-ui/src/Popup/AuthManagement/AccountManagement.tsx @@ -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 {
('Accounts connected to {{url}}', { replace: { url } })} + text={t('Accounts connected to {{url}}', { replace: { url } })} />
{ className='acceptButton' onClick={_onApprove} > - {t('Connect {{total}} account(s)', { replace: { + {t('Connect {{total}} account(s)', { replace: { total: selectedAccounts.length } })} diff --git a/packages/extension-ui/src/Popup/AuthManagement/WebsiteEntry.tsx b/packages/extension-ui/src/Popup/AuthManagement/WebsiteEntry.tsx index 5b56c527..a8f09616 100644 --- a/packages/extension-ui/src/Popup/AuthManagement/WebsiteEntry.tsx +++ b/packages/extension-ui/src/Popup/AuthManagement/WebsiteEntry.tsx @@ -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('{{total}} accounts', { + ? t('{{total}} accounts', { replace: { total: authorizedAccounts.length } }) : isAllowed - ? t('all accounts') - : t('no accounts') + ? t('all accounts') + : t('no accounts') }
); diff --git a/packages/extension-ui/src/Popup/AuthManagement/index.tsx b/packages/extension-ui/src/Popup/AuthManagement/index.tsx index 42def8c0..2bf400fe 100644 --- a/packages/extension-ui/src/Popup/AuthManagement/index.tsx +++ b/packages/extension-ui/src/Popup/AuthManagement/index.tsx @@ -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 {
('Manage Website Access')} + text={t('Manage Website Access')} />
('example.com')} + placeholder={t('example.com')} value={filter} withReset /> { !authList || !hasAuthList - ?
{t('No website request yet!')}
+ ?
{t('No website request yet!')}
: ( <>
diff --git a/packages/extension-ui/src/Popup/Authorize/NoAccount.tsx b/packages/extension-ui/src/Popup/Authorize/NoAccount.tsx index de852f0d..f09fab9b 100644 --- a/packages/extension-ui/src/Popup/Authorize/NoAccount.tsx +++ b/packages/extension-ui/src/Popup/Authorize/NoAccount.tsx @@ -31,7 +31,7 @@ function NoAccount ({ authId, className }: Props): React.ReactElement { className='acceptButton' onClick={_onClick} > - {t('Understood')} + {t('Understood')}
); diff --git a/packages/extension-ui/src/Popup/Authorize/Request.tsx b/packages/extension-ui/src/Popup/Authorize/Request.tsx index 2c3620d4..2381ec13 100644 --- a/packages/extension-ui/src/Popup/Authorize/Request.tsx +++ b/packages/extension-ui/src/Popup/Authorize/Request.tsx @@ -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('Connect {{total}} account(s)', { replace: { + {t('Connect {{total}} account(s)', { replace: { total: selectedAccounts.length } })} @@ -78,7 +78,7 @@ function Request ({ authId, className, isFirst, request: { origin }, url }: Prop isDanger onClick={_onClose} > - {t('Ask again later')} + {t('Ask again later')}
diff --git a/packages/extension-ui/src/Popup/Authorize/index.tsx b/packages/extension-ui/src/Popup/Authorize/index.tsx index d2598b66..2813f3aa 100644 --- a/packages/extension-ui/src/Popup/Authorize/index.tsx +++ b/packages/extension-ui/src/Popup/Authorize/index.tsx @@ -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 {
('Account connection request')} + text={t('Account connection request')} /> {requests.map(({ id, request, url }, index): React.ReactNode => ( void; @@ -18,7 +17,7 @@ function Mnemonic ({ onNextStep, seed }: Props): React.ReactElement { const { show } = useToast(); const _onCopy = useCallback((): void => { - show(t('Copied')); + show(t('Copied')); }, [show, t]); return ( @@ -28,12 +27,12 @@ function Mnemonic ({ onNextStep, seed }: Props): React.ReactElement { seed={seed} /> - {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.")} + {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.")} ('I have saved my mnemonic seed safely.')} + label={t('I have saved my mnemonic seed safely.')} onChange={setIsMnemonicSaved} /> @@ -41,7 +40,7 @@ function Mnemonic ({ onNextStep, seed }: Props): React.ReactElement { isDisabled={!isMnemonicSaved} onClick={onNextStep} > - {t('Next step')} + {t('Next step')} diff --git a/packages/extension-ui/src/Popup/CreateAccount/index.tsx b/packages/extension-ui/src/Popup/CreateAccount/index.tsx index 74e09148..04c13dc6 100644 --- a/packages/extension-ui/src/Popup/CreateAccount/index.tsx +++ b/packages/extension-ui/src/Popup/CreateAccount/index.tsx @@ -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 { <> ('Create an account')} + text={t('Create an account')} />
@@ -114,13 +112,13 @@ function CreateAccount ({ className }: Props): React.ReactElement { <> ('Network')} + label={t('Network')} onChange={_onChangeNetwork} options={options} value={genesisHash} /> ('Add the account with the generated seed')} + buttonLabel={t('Add the account with the generated seed')} isBusy={isBusy} onBackClick={_onPreviousStep} onCreate={_onCreate} diff --git a/packages/extension-ui/src/Popup/Derive/AddressDropdown.tsx b/packages/extension-ui/src/Popup/Derive/AddressDropdown.tsx index fe166c45..e8155b3d 100644 --- a/packages/extension-ui/src/Popup/Derive/AddressDropdown.tsx +++ b/packages/extension-ui/src/Popup/Derive/AddressDropdown.tsx @@ -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 { diff --git a/packages/extension-ui/src/Popup/Derive/DerivationPath.tsx b/packages/extension-ui/src/Popup/Derive/DerivationPath.tsx index 2e4a259a..b02db1ac 100644 --- a/packages/extension-ui/src/Popup/Derive/DerivationPath.tsx +++ b/packages/extension-ui/src/Popup/Derive/DerivationPath.tsx @@ -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('Derivation Path (unlock to edit)') - : t('Derivation Path') + ? t('Derivation Path (unlock to edit)') + : t('Derivation Path') } onChange={_onChange} placeholder={withSoftPath - ? t('//hard/soft') - : t('//hard') + ? t('//hard/soft') + : t('//hard') } value={path} /> diff --git a/packages/extension-ui/src/Popup/Derive/SelectParent.tsx b/packages/extension-ui/src/Popup/Derive/SelectParent.tsx index 0c98add3..b04a7b3c 100644 --- a/packages/extension-ui/src/Popup/Derive/SelectParent.tsx +++ b/packages/extension-ui/src/Popup/Derive/SelectParent.tsx @@ -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('`///password` not supported for derivation')); + setPathError(t('`///password` not supported for derivation')); } if (!allowSoftDerivation && suriPath && singleSlashRegex.test(suriPath)) { - setPathError(t('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('Invalid derivation path')); + setPathError(t('Invalid derivation path')); console.error(error); } } else { @@ -129,7 +129,7 @@ export default function SelectParent ({ className, isLocked, onDerivationConfirm /> ) : ( -
@@ -187,7 +187,7 @@ export default function SelectParent ({ className, isLocked, onDerivationConfirm isDisabled={!isProperParentPassword || !!pathError} onClick={_onSubmit} > - {t('Create a derived account')} + {t('Create a derived account')} diff --git a/packages/extension-ui/src/Popup/Derive/index.tsx b/packages/extension-ui/src/Popup/Derive/index.tsx index fe7574d7..4bfc8e69 100644 --- a/packages/extension-ui/src/Popup/Derive/index.tsx +++ b/packages/extension-ui/src/Popup/Derive/index.tsx @@ -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 { <> ('Add new account')} + text={t('Add new account')} /> {!account && ( { />
('Create derived account')} + buttonLabel={t('Create derived account')} isBusy={isBusy} onBackClick={_onBackClick} onCreate={_onCreate} diff --git a/packages/extension-ui/src/Popup/Export.tsx b/packages/extension-ui/src/Popup/Export.tsx index 63ae32d0..72d796e9 100644 --- a/packages/extension-ui/src/Popup/Export.tsx +++ b/packages/extension-ui/src/Popup/Export.tsx @@ -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 <>
('Export account')} + text={t('Export account')} />
- {t("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.")}
('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('I want to export this account')} + {t('I want to export this account')} ('Cancel')} + text={t('Cancel')} />
diff --git a/packages/extension-ui/src/Popup/ExportAll.tsx b/packages/extension-ui/src/Popup/ExportAll.tsx index 38f195cc..1e4afc3d 100644 --- a/packages/extension-ui/src/Popup/ExportAll.tsx +++ b/packages/extension-ui/src/Popup/ExportAll.tsx @@ -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 { <>
('All account')} + text={t('All account')} />
@@ -74,7 +74,7 @@ function ExportAll ({ className }: Props): React.ReactElement { data-export-all-password disabled={isBusy} isError={pass.length < MIN_LENGTH || !!error} - label={t('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 { isDisabled={pass.length === 0 || !!error} onClick={_onExportAllButtonClick} > - {t('I want to export all my accounts')} + {t('I want to export all my accounts')} ('Cancel')} + text={t('Cancel')} />
diff --git a/packages/extension-ui/src/Popup/Forget.tsx b/packages/extension-ui/src/Popup/Forget.tsx index cfa10154..2730ebf5 100644 --- a/packages/extension-ui/src/Popup/Forget.tsx +++ b/packages/extension-ui/src/Popup/Forget.tsx @@ -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 <>
('Forget account')} + text={t('Forget account')} />
- {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.')} + {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.')}
('Cancel')} + text={t('Cancel')} />
diff --git a/packages/extension-ui/src/Popup/ImportLedger.tsx b/packages/extension-ui/src/Popup/ImportLedger.tsx index 1cb8962d..8ef3ebe4 100644 --- a/packages/extension-ui/src/Popup/ImportLedger.tsx +++ b/packages/extension-ui/src/Popup/ImportLedger.tsx @@ -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('Account type {{index}}', { replace: { index: value } }), + text: t('Account type {{index}}', { replace: { index: value } }), value }))); const addOps = useRef(AVAIL.map((value): AccOption => ({ - text: t('Address index {{index}}', { replace: { index: value } }), + text: t('Address index {{index}}', { replace: { index: value } }), value }))); const networkOps = useRef( [{ - text: t('Select network'), + text: t('Select network'), value: '' }, ...ledgerChains.map(({ displayName, genesisHash }): NetworkOption => ({ @@ -98,7 +97,7 @@ function ImportLedger ({ className }: Props): React.ReactElement { <>
('Import Ledger Account')} + text={t('Import Ledger Account')} />
('Network')} + label={t('Network')} onChange={setGenesis} options={networkOps.current} value={genesis} @@ -126,7 +125,7 @@ function ImportLedger ({ className }: Props): React.ReactElement { ('account type')} + label={t('account type')} onChange={_onSetAccountIndex} options={accOps.current} value={accountIndex} @@ -134,7 +133,7 @@ function ImportLedger ({ className }: Props): React.ReactElement { ('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} > - {t('Refresh')} + {t('Refresh')} ) : ( @@ -172,7 +171,7 @@ function ImportLedger ({ className }: Props): React.ReactElement { isDisabled={!!error || !!ledgerError || !address || !genesis} onClick={_onSave} > - {t('Import Account')} + {t('Import Account')} ) } diff --git a/packages/extension-ui/src/Popup/ImportQr.tsx b/packages/extension-ui/src/Popup/ImportQr.tsx index fcaca900..450c4731 100644 --- a/packages/extension-ui/src/Popup/ImportQr.tsx +++ b/packages/extension-ui/src/Popup/ImportQr.tsx @@ -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 { <>
('Scan Address Qr')} + text={t('Scan Address Qr')} /> {!account && (
@@ -105,7 +105,7 @@ export default function ImportQr (): React.ReactElement { isDisabled={!name || (!account.isAddress && !password)} onClick={_onCreate} > - {t('Add the account with identified address')} + {t('Add the account with identified address')} diff --git a/packages/extension-ui/src/Popup/ImportSeed/SeedAndPath.tsx b/packages/extension-ui/src/Popup/ImportSeed/SeedAndPath.tsx index 75f399d0..85c2cd07 100644 --- a/packages/extension-ui/src/Popup/ImportSeed/SeedAndPath.tsx +++ b/packages/extension-ui/src/Popup/ImportSeed/SeedAndPath.tsx @@ -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('Invalid mnemonic seed or derivation path') - : t('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('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('Mnemonic needs to contain 12, 15, 18, 21, 24 words')} + {t('Mnemonic needs to contain 12, 15, 18, 21, 24 words')} )} ('Network')} + label={t('Network')} onChange={setGenesis} options={genesisOptions} value={genesis} @@ -100,13 +99,13 @@ function SeedAndPath ({ className, onAccountChange, onNextStep, type }: Props): onClick={_onToggleAdvanced} > - {t('advanced')} + {t('advanced')}
{ advanced && ( ('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('Next')} + {t('Next')} diff --git a/packages/extension-ui/src/Popup/ImportSeed/index.tsx b/packages/extension-ui/src/Popup/ImportSeed/index.tsx index 2d0d74a1..5362118e 100644 --- a/packages/extension-ui/src/Popup/ImportSeed/index.tsx +++ b/packages/extension-ui/src/Popup/ImportSeed/index.tsx @@ -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 { <> ('Import account')} + text={t('Import account')} />
('Add the account with the supplied seed')} + buttonLabel={t('Add the account with the supplied seed')} isBusy={isBusy} onBackClick={_onBackClick} onCreate={_onCreate} diff --git a/packages/extension-ui/src/Popup/Metadata/Request.tsx b/packages/extension-ui/src/Popup/Metadata/Request.tsx index e2f650e0..2359eb68 100644 --- a/packages/extension-ui/src/Popup/Metadata/Request.tsx +++ b/packages/extension-ui/src/Popup/Metadata/Request.tsx @@ -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
- + - + - + - + - + - - + +
{t('from')}{t('from')} {url}
{t('chain')}{t('chain')} {request.chain}
{t('icon')}{t('icon')} {request.icon}
{t('decimals')}{t('decimals')} {request.tokenDecimals}
{t('symbol')}{t('symbol')} {request.tokenSymbol}
{t('upgrade')}{chain ? chain.specVersion : t('')} -> {request.specVersion}{t('upgrade')}{chain ? chain.specVersion : t('')} -> {request.specVersion}
- {t('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.')} - {t('Reject')} + {t('Reject')}
diff --git a/packages/extension-ui/src/Popup/Metadata/index.tsx b/packages/extension-ui/src/Popup/Metadata/index.tsx index 3bb794b8..b9e167f6 100644 --- a/packages/extension-ui/src/Popup/Metadata/index.tsx +++ b/packages/extension-ui/src/Popup/Metadata/index.tsx @@ -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 ( <> -
('Metadata')} /> +
{requests[0] ? ( { return ( <> -
('Phishing detected')} /> +

- {t('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.')}

{decodedWebsite} diff --git a/packages/extension-ui/src/Popup/RestoreJson.tsx b/packages/extension-ui/src/Popup/RestoreJson.tsx index a600a17b..ad66a5ad 100644 --- a/packages/extension-ui/src/Popup/RestoreJson.tsx +++ b/packages/extension-ui/src/Popup/RestoreJson.tsx @@ -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 {

('Restore from JSON')} + text={t('Restore from JSON')} />
{accountsInfo.map(({ address, genesisHash, name, type = DEFAULT_TYPE }, index) => ( @@ -132,7 +132,7 @@ function Upload ({ className }: Props): React.ReactElement { ('backup file')} + label={t('backup file')} onChange={_onChangeFile} withLabel /> @@ -140,14 +140,14 @@ function Upload ({ className }: Props): React.ReactElement { - {t('Invalid Json file')} + {t('Invalid Json file')} )} {requirePassword && (
('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('Unable to decode using the supplied passphrase')} + {t('Unable to decode using the supplied passphrase')} )}
@@ -167,7 +167,7 @@ function Upload ({ className }: Props): React.ReactElement { isDisabled={isFileError || isPasswordError} onClick={_onRestore} > - {t('Restore')} + {t('Restore')}
diff --git a/packages/extension-ui/src/Popup/Signing/Bytes.tsx b/packages/extension-ui/src/Popup/Signing/Bytes.tsx index d4f0294a..1cdecf73 100644 --- a/packages/extension-ui/src/Popup/Signing/Bytes.tsx +++ b/packages/extension-ui/src/Popup/Signing/Bytes.tsx @@ -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 { - + - + diff --git a/packages/extension-ui/src/Popup/Signing/Extrinsic.tsx b/packages/extension-ui/src/Popup/Signing/Extrinsic.tsx index 78b62983..f822ab17 100644 --- a/packages/extension-ui/src/Popup/Signing/Extrinsic.tsx +++ b/packages/extension-ui/src/Popup/Signing/Extrinsic.tsx @@ -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 ( - + ); @@ -65,7 +64,7 @@ function renderMethod (data: string, { args, method }: Decoded, t: TFunction): R return ( <> - + {method.meta && ( - + - + - + - + - + {!tip.isEmpty && ( - + )} {renderMethod(method, decoded, t)} - +
{t('from')}{t('from')} {url}
{t('bytes')}{t('bytes')}
{text}
{t('method data')}{t('method data')} {data}
{t('method')}{t('method')}
{method.section}.{method.method}{ @@ -79,7 +78,7 @@ function renderMethod (data: string, { args, method }: Decoded, t: TFunction): R
{t('info')}{t('info')}
{method.meta.docs.map((d) => d.toString().trim()).join(' ')} @@ -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('immortal'); + return t('immortal'); } const blockNumber = bnToBn(hexBlockNumber); const mortal = era.asMortalEra; - return t('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 >
{t('from')}{t('from')} {url}
{chain ? t('chain') : t('genesis')}{chain ? t('chain') : t('genesis')} {chain ? chain.name : genesisHash}
{t('version')}{t('version')} {specVersion.toNumber()}
{t('nonce')}{t('nonce')} {formatNumber(nonce)}
{t('tip')}{t('tip')} {formatNumber(tip)}
{t('lifetime')}{t('lifetime')} {mortalityAsString(era, blockNumber, t)}
diff --git a/packages/extension-ui/src/Popup/Signing/LedgerSign.tsx b/packages/extension-ui/src/Popup/Signing/LedgerSign.tsx index 5ed8bc9a..c280240d 100644 --- a/packages/extension-ui/src/Popup/Signing/LedgerSign.tsx +++ b/packages/extension-ui/src/Popup/Signing/LedgerSign.tsx @@ -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} > - {t('Refresh')} + {t('Refresh')} ) : ( @@ -86,7 +85,7 @@ function LedgerSign ({ accountIndex, addressOffset, className, error, genesisHas isBusy={isBusy || ledgerLoading} onClick={_onSignLedger} > - {t('Sign on Ledger')} + {t('Sign on Ledger')} ) } diff --git a/packages/extension-ui/src/Popup/Signing/Qr.tsx b/packages/extension-ui/src/Popup/Signing/Qr.tsx index f426341f..591ba03b 100644 --- a/packages/extension-ui/src/Popup/Signing/Qr.tsx +++ b/packages/extension-ui/src/Popup/Signing/Qr.tsx @@ -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('Scan signature via camera')} + {t('Scan signature via camera')} )}
diff --git a/packages/extension-ui/src/Popup/Signing/Request/SignArea.tsx b/packages/extension-ui/src/Popup/Signing/Request/SignArea.tsx index 5964e25e..ac27b72c 100644 --- a/packages/extension-ui/src/Popup/Signing/Request/SignArea.tsx +++ b/packages/extension-ui/src/Popup/Signing/Request/SignArea.tsx @@ -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 ( + ? t( 'Remember my password for the next {{expiration}} minutes', { replace: { expiration: PASSWORD_EXPIRY_MIN } } ) - : t( + : 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('Cancel')} + {t('Cancel')} diff --git a/packages/extension-ui/src/Popup/Signing/Request/index.tsx b/packages/extension-ui/src/Popup/Signing/Request/index.tsx index 3d8b4b2d..a8431aeb 100644 --- a/packages/extension-ui/src/Popup/Signing/Request/index.tsx +++ b/packages/extension-ui/src/Popup/Signing/Request/index.tsx @@ -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 {isExternal && !isHardware && !genesisHash && ( <> - {t('"Allow use on any network" is not supported to show a QR code. You must associate this account with a network.')} + {t('"Allow use on any network" is not supported to show a QR code. You must associate this account with a network.')} )} {isHardware && <> - {t('Message signing is not supported for hardware wallets.')} + {t('Message signing is not supported for hardware wallets.')} } ('Password for this account')} + label={t('Password for this account')} onChange={_onChangePassword} onEnter={onSign} type='password' diff --git a/packages/extension-ui/src/Popup/Signing/index.tsx b/packages/extension-ui/src/Popup/Signing/index.tsx index 846fd67b..feacec7f 100644 --- a/packages/extension-ui/src/Popup/Signing/index.tsx +++ b/packages/extension-ui/src/Popup/Signing/index.tsx @@ -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 ? ( <> -
('Transaction') : t('Sign message')}> +
{requests.length > 1 && ( ('Sign the transaction') : t('Sign the message')} + buttonText={isTransaction ? t('Sign the transaction') : t('Sign the message')} isFirst={requestIndex === 0} request={request.request} signId={request.id} diff --git a/packages/extension-ui/src/Popup/Welcome.tsx b/packages/extension-ui/src/Popup/Welcome.tsx index 89d51fea..5d3d6d32 100644 --- a/packages/extension-ui/src/Popup/Welcome.tsx +++ b/packages/extension-ui/src/Popup/Welcome.tsx @@ -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 { return ( <> -
('Welcome')} /> +
-

{t('Before we start, just a couple of notes regarding use:')}

+

{t('Before we start, just a couple of notes regarding use:')}

-
  • {t('We do not send any clicks, pageviews or events to a central server')}
  • -
  • {t('We do not use any trackers or analytics')}
  • -
  • {t("We don't collect keys, addresses or any information - your information never leaves this machine")}
  • +
  • {t('We do not send any clicks, pageviews or events to a central server')}
  • +
  • {t('We do not use any trackers or analytics')}
  • +
  • {t("We don't collect keys, addresses or any information - your information never leaves this machine")}
  • -

    {t('... we are not in the information collection business (even anonymized).')}

    +

    {t('... we are not in the information collection business (even anonymized).')}

    - + ); diff --git a/packages/extension-ui/src/components/Address.tsx b/packages/extension-ui/src/components/Address.tsx index f0e075e3..ca454da7 100644 --- a/packages/extension-ui/src/components/Address.tsx +++ b/packages/extension-ui/src/components/Address.tsx @@ -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('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(''); + const displayName = accountName || t(''); return ( <> @@ -181,14 +178,14 @@ function Address ({ actions, address, children, className, genesisHash, isExtern className='hardwareIcon' icon={faUsb} rotation={270} - title={t('hardware wallet account')} + title={t('hardware wallet account')} /> ) : ( ('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('')} + {formatted || address || t('')}
    ('copy address')} + title={t('copy address')} /> {(actions || showVisibilityAction) && ( @@ -275,7 +272,7 @@ function Address ({ actions, address, children, className, genesisHash, isExtern icon={isHidden ? faEyeSlash : faEye} onClick={_toggleVisibility} size='sm' - title={t('account visibility')} + title={t('account visibility')} /> )}
    diff --git a/packages/extension-ui/src/components/ErrorBoundary.tsx b/packages/extension-ui/src/components/ErrorBoundary.tsx index 1bdb784c..0d483f60 100644 --- a/packages/extension-ui/src/components/ErrorBoundary.tsx +++ b/packages/extension-ui/src/components/ErrorBoundary.tsx @@ -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 { public override state: State = { error: null }; @@ -51,9 +53,9 @@ class ErrorBoundary extends React.Component { return error ? ( <> -
    ('An error occurred')} /> +
    >('An error occurred')} />
    - {t('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 } })}
    @@ -62,7 +64,7 @@ class ErrorBoundary extends React.Component { diff --git a/packages/extension-ui/src/components/InputFileWithLabel.tsx b/packages/extension-ui/src/components/InputFileWithLabel.tsx index c451ca65..272bc637 100644 --- a/packages/extension-ui/src/components/InputFileWithLabel.tsx +++ b/packages/extension-ui/src/components/InputFileWithLabel.tsx @@ -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 { !file || clearContent - ? placeholder || t('click to select or drag and drop the file here') - : placeholder || t('{{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) diff --git a/packages/extension-ui/src/components/InputWithLabel.tsx b/packages/extension-ui/src/components/InputWithLabel.tsx index 6cde6db1..aa720c75 100644 --- a/packages/extension-ui/src/components/InputWithLabel.tsx +++ b/packages/extension-ui/src/components/InputWithLabel.tsx @@ -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 && ( - {t('Warning: Caps lock is on')} + {t('Warning: Caps lock is on')} )} ); diff --git a/packages/extension-ui/src/components/Loading.tsx b/packages/extension-ui/src/components/Loading.tsx index 2b4b8b58..6cd3acd0 100644 --- a/packages/extension-ui/src/components/Loading.tsx +++ b/packages/extension-ui/src/components/Loading.tsx @@ -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 if (!children) { return ( -
    {t('... loading ...')}
    +
    {t('... loading ...')}
    ); } diff --git a/packages/extension-ui/src/components/MnemonicSeed.tsx b/packages/extension-ui/src/components/MnemonicSeed.tsx index 5eb92ded..876baea9 100644 --- a/packages/extension-ui/src/components/MnemonicSeed.tsx +++ b/packages/extension-ui/src/components/MnemonicSeed.tsx @@ -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

    ('Generated 12-word mnemonic seed:')} + label={t('Generated 12-word mnemonic seed:')} value={seed} />

    @@ -36,7 +36,7 @@ function MnemonicSeed ({ className, onCopy, seed }: Props): React.ReactElement

    ('Copy to clipboard')} + text={t('Copy to clipboard')} />

    diff --git a/packages/extension-ui/src/components/ValidatedInput.tsx b/packages/extension-ui/src/components/ValidatedInput.tsx index 77d21f92..76ebc46b 100644 --- a/packages/extension-ui/src/components/ValidatedInput.tsx +++ b/packages/extension-ui/src/components/ValidatedInput.tsx @@ -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'; diff --git a/packages/extension-ui/src/hooks/index.js b/packages/extension-ui/src/hooks/index.js new file mode 100644 index 00000000..5a758876 --- /dev/null +++ b/packages/extension-ui/src/hooks/index.js @@ -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'; diff --git a/packages/extension-ui/src/hooks/useGenesisHashOptions.ts b/packages/extension-ui/src/hooks/useGenesisHashOptions.ts index 83e6902d..7e86ed8f 100644 --- a/packages/extension-ui/src/hooks/useGenesisHashOptions.ts +++ b/packages/extension-ui/src/hooks/useGenesisHashOptions.ts @@ -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([]); @@ -30,7 +30,7 @@ export default function (): Option[] { const hashes = useMemo(() => [ { - text: t('Allow use on any chain'), + text: t('Allow use on any chain'), value: '' as HexString }, // put the relay chains at the top diff --git a/packages/extension-ui/src/hooks/useLedger.ts b/packages/extension-ui/src/hooks/useLedger.ts index da707d46..683272c0 100644 --- a/packages/extension-ui/src/hooks/useLedger.ts +++ b/packages/extension-ui/src/hooks/useLedger.ts @@ -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('Is your ledger locked?') + ? t('Is your ledger locked?') : null; const errorMessage = e.message.includes('App does not seem to be open') - ? t('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( + setError(t( 'Ledger error: {{errorMessage}}', { replace: { errorMessage } } )); diff --git a/packages/extension-ui/src/hooks/useTranslation.ts b/packages/extension-ui/src/hooks/useTranslation.ts index 13aa6dfc..95a817c7 100644 --- a/packages/extension-ui/src/hooks/useTranslation.ts +++ b/packages/extension-ui/src/hooks/useTranslation.ts @@ -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; + +interface UseTranslation { + t: TFunction +} + +export default function useTranslation (): UseTranslation { + return useTranslationBase(); +} diff --git a/packages/extension-ui/src/partials/AccountSelection.tsx b/packages/extension-ui/src/partials/AccountSelection.tsx index bb7095da..b3eebef7 100644 --- a/packages/extension-ui/src/partials/AccountSelection.tsx +++ b/packages/extension-ui/src/partials/AccountSelection.tsx @@ -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('Select all')} + label={t('Select all')} onChange={_onSelectAllToggle} />
    diff --git a/packages/extension-ui/src/partials/Header.tsx b/packages/extension-ui/src/partials/Header.tsx index a54cbd3c..34bf77c2 100644 --- a/packages/extension-ui/src/partials/Header.tsx +++ b/packages/extension-ui/src/partials/Header.tsx @@ -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 ('Search by name or network...')} + placeholder={t('Search by name or network...')} value={filter} withReset /> diff --git a/packages/extension-ui/src/partials/MenuAdd.tsx b/packages/extension-ui/src/partials/MenuAdd.tsx index 4121a5fa..42387ea9 100644 --- a/packages/extension-ui/src/partials/MenuAdd.tsx +++ b/packages/extension-ui/src/partials/MenuAdd.tsx @@ -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 { - { t('Create new account')} + { t('Create new account')} @@ -59,7 +57,7 @@ function MenuAdd ({ className, reference }: Props): React.ReactElement { - {t('Derive from an account')} + {t('Derive from an account')} @@ -68,13 +66,13 @@ function MenuAdd ({ className, reference }: Props): React.ReactElement { - {t('Export all accounts')} + {t('Export all accounts')} - {t('Import account from pre-existing seed')} + {t('Import account from pre-existing seed')} @@ -83,7 +81,7 @@ function MenuAdd ({ className, reference }: Props): React.ReactElement { to={isPopup ? undefined : jsonPath} > - {t('Restore account from backup JSON file')} + {t('Restore account from backup JSON file')} @@ -91,13 +89,13 @@ function MenuAdd ({ className, reference }: Props): React.ReactElement { ('Camera access must be first enabled in the settings') + ? t('Camera access must be first enabled in the settings') : '' } to='/account/import-qr' > - {t('Attach external QR-signer account')} + {t('Attach external QR-signer account')} @@ -105,14 +103,14 @@ function MenuAdd ({ className, reference }: Props): React.ReactElement { ? ( ('Ledger devices can only be connected with Chrome browser')) || ''} + title={ (!isLedgerCapable && t('Ledger devices can only be connected with Chrome browser')) || ''} to={ledgerPath} > - { t('Attach ledger account')} + { t('Attach ledger account')} ) : ( @@ -121,7 +119,7 @@ function MenuAdd ({ className, reference }: Props): React.ReactElement { icon={faUsb} rotation={270} /> - { t('Connect Ledger device')} + { t('Connect Ledger device')} ) } diff --git a/packages/extension-ui/src/partials/MenuSettings.tsx b/packages/extension-ui/src/partials/MenuSettings.tsx index bc6eba4f..8cc86f5d 100644 --- a/packages/extension-ui/src/partials/MenuSettings.tsx +++ b/packages/extension-ui/src/partials/MenuSettings.tsx @@ -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 ('Dark')} + checkedLabel={t('Dark')} onChange={_onChangeTheme} - uncheckedLabel={t('Light')} + uncheckedLabel={t('Light')} /> ('Display address format for')} + title={t('Display address format for')} > ('Language')} + title={t('Language')} > ('Notifications')} + title={t('Notifications')} > ('External accounts and Access')} + title={t('External accounts and Access')} > ('Allow QR Camera Access')} + label={t('Allow QR Camera Access')} onChange={setCamera} /> @@ -156,7 +155,7 @@ function MenuSettings ({ className, reference }: Props): React.ReactElement('Manage Website Access')} + text={t('Manage Website Access')} /> {isPopup && ( @@ -165,7 +164,7 @@ function MenuSettings ({ className, reference }: Props): React.ReactElement('Open extension in new window')} + text={t('Open extension in new window')} /> )} diff --git a/packages/extension-ui/src/partials/Name.tsx b/packages/extension-ui/src/partials/Name.tsx index 817263e6..3e1c2d9a 100644 --- a/packages/extension-ui/src/partials/Name.tsx +++ b/packages/extension-ui/src/partials/Name.tsx @@ -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 { const { t } = useTranslation(); const { accounts } = useContext(AccountContext); - const isNameValid = useMemo(() => isNotShorterThan(3, t('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('A descriptive name for your account')} + label={label || t('A descriptive name for your account')} onBlur={onBlur} onEnter={onBlur} onValidatedChange={onChange} diff --git a/packages/extension-ui/src/partials/Password.tsx b/packages/extension-ui/src/partials/Password.tsx index b3b50b8f..6766d8c9 100644 --- a/packages/extension-ui/src/partials/Password.tsx +++ b/packages/extension-ui/src/partials/Password.tsx @@ -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(null); const [pass2, setPass2] = useState(null); - const isFirstPasswordValid = useMemo(() => isNotShorterThan(MIN_LENGTH, t('Password is too short')), [t]); + const isFirstPasswordValid = useMemo(() => isNotShorterThan(MIN_LENGTH, t('Password is too short')), [t]); const isSecondPasswordValid = useCallback((firstPassword: string): Validator => allOf( - isNotShorterThan(MIN_LENGTH, t('Password is too short')), - isSameAs(firstPassword, t('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('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 ('Repeat password for verification')} + label={t('Repeat password for verification')} onValidatedChange={setPass2} type='password' validator={isSecondPasswordValid(pass1)} diff --git a/packages/extension-ui/src/translate.ts b/packages/extension-ui/src/translate.ts deleted file mode 100644 index a095dcb8..00000000 --- a/packages/extension-ui/src/translate.ts +++ /dev/null @@ -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 { - return useTranslationBase(); -} - -export default withTranslation(); diff --git a/packages/extension/public/locales/en/translation.json b/packages/extension/public/locales/en/translation.json index c3f46abc..6615752f 100644 --- a/packages/extension/public/locales/en/translation.json +++ b/packages/extension/public/locales/en/translation.json @@ -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}}": "" }