From 160be3578fc9ba7f9f5421dcddcf1a7d678c5133 Mon Sep 17 00:00:00 2001 From: vetalcore Date: Fri, 17 May 2024 09:41:52 +0300 Subject: [PATCH] chore: [LW-10534] translation package (#1154) * chore(extension): add translation package * chore(extension): use translation package in browser-extension * chore(extension): use translation package in core * chore(extension): use translation package in staking * chore(extension): remove Language obj from common package * chore(extension): fix storybook in staking package * fix(extension): fix e2e * chore(extension): fix storybook in core package * chore(extension): add typings for core and cardano packages * test(extension): fix issue with missing translations in tests --------- Co-authored-by: wklos-iohk --- apps/browser-extension-wallet/package.json | 1 + .../components/ThemeSwitcher.tsx | 2 +- .../WalletStatus/WalletStatusContainer.tsx | 2 +- .../AddressDetailDrawer/types/index.ts | 2 +- .../components/__tests__/Connect.test.tsx | 2 +- .../confirm-transaction/testing.utils.tsx | 2 +- .../src/features/dapp/config/ViewsConfig.tsx | 2 +- .../components/__tests__/ReceiveInfo.test.tsx | 2 +- .../__tests__/UnlockWallet.test.tsx | 2 +- .../hooks/__tests__/useCollateral.test.tsx | 2 +- .../hooks/__tests__/useOnAddressSave.test.tsx | 2 +- .../src/hooks/useActionExecution.ts | 2 +- .../src/hooks/useInitializeTx.ts | 2 +- apps/browser-extension-wallet/src/lib/i18n.ts | 36 +- .../src/lib/storage/helpers/index.ts | 2 +- .../src/types/side-menu.ts | 2 +- .../src/typings/i18next.d.ts | 2 +- .../__tests__/PortfolioBalanceLabel.test.tsx | 2 +- .../SideMenu/__tests__/SideMenu.test.tsx | 2 +- .../WalletUsedAddressesDrawer.test.tsx | 2 +- .../activity/components/ActivityDetail.tsx | 2 +- .../__tests__/AddressBookEmpty.test.tsx | 2 +- .../__tests__/AddressForm.test.tsx | 2 +- .../__tests__/AssetDetails.test.tsx | 2 +- .../MultiAddressBalanceVisibleModal.tsx | 4 +- .../hardware-wallet/steps/Connect.tsx | 2 +- .../nfts/components/CreateFolder/NameForm.tsx | 2 +- .../__tests__/useSelectedCoins.test.ts | 2 +- .../Form/__tests__/MetadataInput.test.tsx | 2 +- .../SendTransactionDrawer/Footer.tsx | 20 +- .../SendTransactionDrawer/HeaderView.tsx | 2 +- .../__tests__/CollateralDrawer.test.tsx | 6 +- .../Collateral/hardware-wallet/FooterHW.tsx | 2 +- .../settings/components/TermsDrawer.tsx | 5 +- .../SettingsAnalyticsTracker.test.tsx | 2 +- .../__tests__/SettingsWallet.test.tsx | 4 +- .../StakePoolDetails/StakePoolDetail.tsx | 2 +- .../__tests__/StakingModal.test.tsx | 2 +- .../__tests__/StakingModals.test.tsx | 2 +- .../voting/components/VotingLayout.tsx | 2 +- .../HardwareWalletFlow/StepConnect.tsx | 2 +- .../HardwareWalletFlow/makeErrorDialog.tsx | 2 +- .../components/WalletSetupMainPage.tsx | 13 +- package.json | 6 +- packages/cardano/src/ui/typings/i18next.d.ts | 10 + packages/common/src/ui/lib/i18n.ts | 3 - packages/common/src/ui/lib/index.ts | 1 - packages/core/.storybook/preview.js | 1 + packages/core/package.json | 3 +- .../components/Activity/AssetActivityItem.tsx | 7 +- .../components/Activity/AssetActivityList.tsx | 4 +- .../components/ActivityDetail/Collateral.tsx | 4 +- .../ActivityDetail/RewardsDetails.tsx | 4 +- .../ActivityDetail/TransactionDetails.tsx | 11 +- .../ActivityDetail/TransactionFee.tsx | 4 +- .../ActivityDetail/TransactionInputOutput.tsx | 4 +- .../ui/components/AssetInput/AssetInput.tsx | 7 +- .../AssetSelector/AssetSelectorOverlay.tsx | 9 +- .../ui/components/AssetTable/AssetTable.tsx | 4 +- .../AuthorizeDapp/AuthorizeDapp.tsx | 4 +- .../DappAddressSection.tsx | 7 +- .../DappAddressSections.tsx | 5 +- .../DappTransaction/DappTransaction.tsx | 4 +- .../DappTransactionHeader.tsx | 4 +- .../OutputSummary/OutputSummary.tsx | 4 +- .../src/ui/components/Token/TokenItem.tsx | 4 +- .../WalletAddresses/WalletAddressItem.tsx | 4 +- .../AnalyticsConfirmationBanner.tsx | 4 +- .../WalletSetup/LegalTranslations.tsx | 77 ++- .../WalletSetup/WalletAnalyticsInfo.tsx | 4 +- .../WalletSetupConfirmationDialogProvider.tsx | 4 +- .../WalletSetupNamePasswordStep.tsx | 4 +- .../WalletSetupNamePasswordStep/utils.ts | 3 +- .../WalletSetupSelectAccountsStep.tsx | 4 +- .../WalletSetup/WalletSetupStepLayout.tsx | 6 +- .../WalletSetupNamePasswordStepRevamp.tsx | 4 +- .../WalletSetupSelectAccountsStepRevamp.tsx | 4 +- .../WalletSetupStepLayoutRevamp.tsx | 6 +- packages/core/src/ui/hooks/index.ts | 1 - packages/core/src/ui/hooks/useTranslate.tsx | 43 -- packages/core/src/ui/lib/en.ts | 3 - packages/core/src/ui/lib/i18n.ts | 28 -- packages/core/src/ui/lib/index.ts | 1 - packages/core/src/ui/typings/i18next.d.ts | 10 + .../core/src/ui/utils/render-address-tag.tsx | 4 +- .../e2e-tests/src/utils/translationService.ts | 7 +- packages/staking/.storybook/preview.tsx | 1 + packages/staking/package.json | 1 + .../BrowsePoolsPreferencesCardContainer.tsx | 3 +- .../DelegationCard/DelegationCard.tsx | 2 +- packages/staking/src/features/i18n/i18n.ts | 39 -- packages/staking/src/features/i18n/index.ts | 2 - .../StakingInfoCard/StakingInfoCard.tsx | 2 +- .../src/features/staking/Setup/Setup.tsx | 4 +- .../src/features/staking/Setup/SetupBase.tsx | 24 +- .../features/staking/Setup/useI18n.test.ts | 61 --- .../src/features/staking/Setup/useI18n.ts | 24 - .../staking/src/features/staking/types.ts | 2 +- packages/staking/src/typings/i18next.d.ts | 2 +- packages/translation/.eslintignore | 2 + packages/translation/.eslintrc.js | 226 +++++++++ packages/translation/.gitignore | 2 + packages/translation/.prettierrc.js | 6 + packages/translation/README.md | 53 +++ packages/translation/package.json | 50 ++ packages/translation/rollup.config.js | 30 ++ packages/translation/src/index.ts | 3 + packages/translation/src/lib/i18n.ts | 44 ++ .../cookie-policy.en.ts | 2 +- .../browser-extension-wallet}/en.json | 443 ------------------ .../browser-extension-wallet}/en.ts | 4 +- .../browser-extension-wallet}/index.ts | 0 .../browser-extension-wallet}/legal.en.ts | 2 +- .../src/lib/translations/cardano/en.json | 71 +++ .../src/lib/translations/cardano/en.ts | 5 + .../src/lib/translations/core}/en.json | 8 +- .../src/lib/translations/core/en.ts | 5 + .../translation/src/lib/translations/index.ts | 11 + .../src/lib/translations/staking/en.json | 205 ++++++++ .../src/lib/translations/staking/en.ts | 5 + .../src/lib/translations/staking}/index.ts | 0 packages/translation/src/types/index.ts | 1 + .../translation/src/types}/types.ts | 2 +- packages/translation/src/typings/i18next.d.ts | 10 + packages/translation/tsconfig.eslint.json | 4 + packages/translation/tsconfig.json | 24 + yarn.lock | 196 ++++++-- 127 files changed, 1149 insertions(+), 926 deletions(-) create mode 100644 packages/cardano/src/ui/typings/i18next.d.ts delete mode 100644 packages/common/src/ui/lib/i18n.ts delete mode 100644 packages/core/src/ui/hooks/useTranslate.tsx delete mode 100644 packages/core/src/ui/lib/en.ts delete mode 100644 packages/core/src/ui/lib/i18n.ts create mode 100644 packages/core/src/ui/typings/i18next.d.ts delete mode 100644 packages/staking/src/features/i18n/i18n.ts delete mode 100644 packages/staking/src/features/i18n/index.ts delete mode 100644 packages/staking/src/features/staking/Setup/useI18n.test.ts delete mode 100644 packages/staking/src/features/staking/Setup/useI18n.ts create mode 100644 packages/translation/.eslintignore create mode 100644 packages/translation/.eslintrc.js create mode 100644 packages/translation/.gitignore create mode 100644 packages/translation/.prettierrc.js create mode 100644 packages/translation/README.md create mode 100644 packages/translation/package.json create mode 100644 packages/translation/rollup.config.js create mode 100644 packages/translation/src/index.ts create mode 100644 packages/translation/src/lib/i18n.ts rename {apps/browser-extension-wallet/src/lib/translations => packages/translation/src/lib/translations/browser-extension-wallet}/cookie-policy.en.ts (99%) rename {apps/browser-extension-wallet/src/lib/translations => packages/translation/src/lib/translations/browser-extension-wallet}/en.json (61%) rename {apps/browser-extension-wallet/src/lib/translations => packages/translation/src/lib/translations/browser-extension-wallet}/en.ts (74%) rename {apps/browser-extension-wallet/src/lib/translations => packages/translation/src/lib/translations/browser-extension-wallet}/index.ts (100%) rename {apps/browser-extension-wallet/src/lib/translations => packages/translation/src/lib/translations/browser-extension-wallet}/legal.en.ts (99%) create mode 100644 packages/translation/src/lib/translations/cardano/en.json create mode 100644 packages/translation/src/lib/translations/cardano/en.ts rename packages/{core/src/ui/lib/translations => translation/src/lib/translations/core}/en.json (99%) create mode 100644 packages/translation/src/lib/translations/core/en.ts create mode 100644 packages/translation/src/lib/translations/index.ts create mode 100644 packages/translation/src/lib/translations/staking/en.json create mode 100644 packages/translation/src/lib/translations/staking/en.ts rename packages/{staking/src/features/i18n/translations => translation/src/lib/translations/staking}/index.ts (100%) create mode 100644 packages/translation/src/types/index.ts rename {apps/browser-extension-wallet/src/lib/translations => packages/translation/src/types}/types.ts (70%) create mode 100644 packages/translation/src/typings/i18next.d.ts create mode 100644 packages/translation/tsconfig.eslint.json create mode 100644 packages/translation/tsconfig.json diff --git a/apps/browser-extension-wallet/package.json b/apps/browser-extension-wallet/package.json index f2e7f1402..d585ddc9a 100644 --- a/apps/browser-extension-wallet/package.json +++ b/apps/browser-extension-wallet/package.json @@ -52,6 +52,7 @@ "@lace/common": "0.1.0", "@lace/core": "0.1.0", "@lace/staking": "0.1.0", + "@lace/translation": "0.1.0", "@lace/ui": "^0.1.0", "@react-rxjs/core": "^0.9.8", "@react-rxjs/utils": "^0.9.5", diff --git a/apps/browser-extension-wallet/src/components/MainMenu/DropdownMenuOverlay/components/ThemeSwitcher.tsx b/apps/browser-extension-wallet/src/components/MainMenu/DropdownMenuOverlay/components/ThemeSwitcher.tsx index f87b777e8..cb85e2013 100644 --- a/apps/browser-extension-wallet/src/components/MainMenu/DropdownMenuOverlay/components/ThemeSwitcher.tsx +++ b/apps/browser-extension-wallet/src/components/MainMenu/DropdownMenuOverlay/components/ThemeSwitcher.tsx @@ -9,7 +9,7 @@ import MoonIcon from '../../../../assets/icons/moon.component.svg'; import { useBackgroundServiceAPIContext } from '@providers/BackgroundServiceAPI'; import { themes, useAnalyticsContext } from '@providers'; import { PostHogAction } from '@providers/AnalyticsProvider/analyticsTracker'; -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; type ThemeAnalyticsEvents = Record; diff --git a/apps/browser-extension-wallet/src/components/WalletStatus/WalletStatusContainer.tsx b/apps/browser-extension-wallet/src/components/WalletStatus/WalletStatusContainer.tsx index 737a4e11b..a292329b6 100644 --- a/apps/browser-extension-wallet/src/components/WalletStatus/WalletStatusContainer.tsx +++ b/apps/browser-extension-wallet/src/components/WalletStatus/WalletStatusContainer.tsx @@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { useSyncStatus } from '@src/stores'; import { WalletStatus, Status } from './WalletStatus'; -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; const DEFAULT_WALLET_STATUS: { status: Status; text: TranslationKey } = { status: Status.SYNCING, diff --git a/apps/browser-extension-wallet/src/features/address-book/components/AddressDetailDrawer/types/index.ts b/apps/browser-extension-wallet/src/features/address-book/components/AddressDetailDrawer/types/index.ts index e32905a23..613ee8644 100644 --- a/apps/browser-extension-wallet/src/features/address-book/components/AddressDetailDrawer/types/index.ts +++ b/apps/browser-extension-wallet/src/features/address-book/components/AddressDetailDrawer/types/index.ts @@ -1,4 +1,4 @@ -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; export enum AddressDetailsSteps { DETAILS, diff --git a/apps/browser-extension-wallet/src/features/dapp/components/__tests__/Connect.test.tsx b/apps/browser-extension-wallet/src/features/dapp/components/__tests__/Connect.test.tsx index 188e24e0a..29de42004 100644 --- a/apps/browser-extension-wallet/src/features/dapp/components/__tests__/Connect.test.tsx +++ b/apps/browser-extension-wallet/src/features/dapp/components/__tests__/Connect.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import '@testing-library/jest-dom'; import { cleanup, render, screen, waitFor, within } from '@testing-library/react'; import { Connect } from '../Connect'; -import i18n from '@lib/i18n'; +import { i18n } from '@lace/translation'; import { I18nextProvider } from 'react-i18next'; jest.mock('react-router-dom', () => ({ diff --git a/apps/browser-extension-wallet/src/features/dapp/components/confirm-transaction/testing.utils.tsx b/apps/browser-extension-wallet/src/features/dapp/components/confirm-transaction/testing.utils.tsx index 3d36e6ec4..c7d258dbb 100644 --- a/apps/browser-extension-wallet/src/features/dapp/components/confirm-transaction/testing.utils.tsx +++ b/apps/browser-extension-wallet/src/features/dapp/components/confirm-transaction/testing.utils.tsx @@ -10,7 +10,7 @@ import { ViewFlowProvider } from '@src/providers'; import { APP_MODE_BROWSER } from '@src/utils/constants'; -import i18n from '@lib/i18n'; +import { i18n } from '@lace/translation'; import { PostHogClientProvider } from '@providers/PostHogClientProvider'; import { postHogClientMocks } from '@src/utils/mocks/test-helpers'; import React from 'react'; diff --git a/apps/browser-extension-wallet/src/features/dapp/config/ViewsConfig.tsx b/apps/browser-extension-wallet/src/features/dapp/config/ViewsConfig.tsx index 8cd94bd0a..1958b3b25 100644 --- a/apps/browser-extension-wallet/src/features/dapp/config/ViewsConfig.tsx +++ b/apps/browser-extension-wallet/src/features/dapp/config/ViewsConfig.tsx @@ -5,7 +5,7 @@ import { DappTransactionFail } from '../components/DappTransactionFail'; import { IViewAction, IViewState } from '../../../providers'; import { DappConfirmData as ConfirmData } from '../components/ConfirmData'; import { SignData } from '../components/SignData'; -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; export enum DAPP_VIEWS { CONNECT = 'connect', CONFIRM_TX = 'confirm-tx', diff --git a/apps/browser-extension-wallet/src/features/receive-info/components/__tests__/ReceiveInfo.test.tsx b/apps/browser-extension-wallet/src/features/receive-info/components/__tests__/ReceiveInfo.test.tsx index 8385fe82a..1ef780305 100644 --- a/apps/browser-extension-wallet/src/features/receive-info/components/__tests__/ReceiveInfo.test.tsx +++ b/apps/browser-extension-wallet/src/features/receive-info/components/__tests__/ReceiveInfo.test.tsx @@ -5,7 +5,7 @@ import { I18nextProvider } from 'react-i18next'; import { render } from '@testing-library/react'; import { ReceiveInfo, ReceiveInfoProps } from '../ReceiveInfo'; import '@testing-library/jest-dom'; -import i18n from '../../../../lib/i18n'; +import { i18n } from '../../../../lib/i18n'; import { mockWalletInfoTestnet } from '@src/utils/mocks/test-helpers'; import { ThemeProvider } from '@providers/ThemeProvider'; diff --git a/apps/browser-extension-wallet/src/features/unlock-wallet/components/__tests__/UnlockWallet.test.tsx b/apps/browser-extension-wallet/src/features/unlock-wallet/components/__tests__/UnlockWallet.test.tsx index 1e283d7ea..ec61201aa 100644 --- a/apps/browser-extension-wallet/src/features/unlock-wallet/components/__tests__/UnlockWallet.test.tsx +++ b/apps/browser-extension-wallet/src/features/unlock-wallet/components/__tests__/UnlockWallet.test.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { I18nextProvider } from 'react-i18next'; import { fireEvent, render } from '@testing-library/react'; import '@testing-library/jest-dom'; -import i18n from '../../../../lib/i18n'; +import { i18n } from '../../../../lib/i18n'; import { UnlockWallet, UnlockWalletProps } from '../UnlockWallet'; import { MemoryRouter } from 'react-router-dom'; diff --git a/apps/browser-extension-wallet/src/hooks/__tests__/useCollateral.test.tsx b/apps/browser-extension-wallet/src/hooks/__tests__/useCollateral.test.tsx index 3442a4d25..a8a603352 100644 --- a/apps/browser-extension-wallet/src/hooks/__tests__/useCollateral.test.tsx +++ b/apps/browser-extension-wallet/src/hooks/__tests__/useCollateral.test.tsx @@ -17,7 +17,7 @@ import { StoreProvider } from '@src/stores'; import { COLLATERAL_ADA_AMOUNT, COLLATERAL_AMOUNT_LOVELACES, useCollateral } from '@hooks'; import { APP_MODE_BROWSER } from '@src/utils/constants'; import { I18nextProvider } from 'react-i18next'; -import i18n from '@lib/i18n'; +import { i18n } from '@lace/translation'; import { Wallet } from '@lace/cardano'; import { act } from 'react-dom/test-utils'; import { waitFor } from '@testing-library/react'; diff --git a/apps/browser-extension-wallet/src/hooks/__tests__/useOnAddressSave.test.tsx b/apps/browser-extension-wallet/src/hooks/__tests__/useOnAddressSave.test.tsx index 53b293eb3..955306404 100644 --- a/apps/browser-extension-wallet/src/hooks/__tests__/useOnAddressSave.test.tsx +++ b/apps/browser-extension-wallet/src/hooks/__tests__/useOnAddressSave.test.tsx @@ -15,7 +15,7 @@ const mockSendEventToPostHog = jest.fn(); import { renderHook, act } from '@testing-library/react-hooks'; import { I18nextProvider } from 'react-i18next'; -import i18n from '@lib/i18n'; +import { i18n } from '@lace/translation'; import { useOnAddressSave } from '../useOnAddressSave'; import React from 'react'; import { PostHogAction } from '@providers/AnalyticsProvider/analyticsTracker'; diff --git a/apps/browser-extension-wallet/src/hooks/useActionExecution.ts b/apps/browser-extension-wallet/src/hooks/useActionExecution.ts index c47eaac34..b1cc106f7 100644 --- a/apps/browser-extension-wallet/src/hooks/useActionExecution.ts +++ b/apps/browser-extension-wallet/src/hooks/useActionExecution.ts @@ -1,7 +1,7 @@ import { useTranslation } from 'react-i18next'; import { toast, ToastProps } from '@lace/common'; import ErrorIcon from '../assets/icons/address-error-icon.component.svg'; -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; export const TOAST_DEFAULT_DURATION = 3; diff --git a/apps/browser-extension-wallet/src/hooks/useInitializeTx.ts b/apps/browser-extension-wallet/src/hooks/useInitializeTx.ts index ad3143036..ed914f614 100644 --- a/apps/browser-extension-wallet/src/hooks/useInitializeTx.ts +++ b/apps/browser-extension-wallet/src/hooks/useInitializeTx.ts @@ -7,7 +7,7 @@ import { getReachedMaxAmountList } from '@src/views/browser-view/features/send-t import { useWalletStore } from '@src/stores'; import { useMaxAda } from './useMaxAda'; import { UseTranslationResponse } from 'react-i18next'; -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; const { buildTransactionProps, setMissingCoins, getTotalMinimumCoins } = Wallet; diff --git a/apps/browser-extension-wallet/src/lib/i18n.ts b/apps/browser-extension-wallet/src/lib/i18n.ts index bed34a575..af3a65f54 100644 --- a/apps/browser-extension-wallet/src/lib/i18n.ts +++ b/apps/browser-extension-wallet/src/lib/i18n.ts @@ -1,35 +1 @@ -import { Language } from '@lace/common'; -import i18n from 'i18next'; -import { initReactI18next } from 'react-i18next'; -import * as translations from './translations'; - -type I18NextResources = Partial>; - -const DEFAULT_LANG = Language.en; - -const resources: I18NextResources = {}; -for (const lang of Object.values(Language)) { - Object.assign(resources, { - [lang]: { - translation: { - ...translations[lang] - } - } - }); -} - -i18n.use(initReactI18next).init({ - fallbackLng: DEFAULT_LANG, - interpolation: { - // not needed for react as it escapes by default - escapeValue: false - }, - lng: Language.en, - resources, - react: { - useSuspense: false, - transSupportBasicHtmlNodes: true - } -}); - -export default i18n; +export { i18n } from '@lace/translation'; diff --git a/apps/browser-extension-wallet/src/lib/storage/helpers/index.ts b/apps/browser-extension-wallet/src/lib/storage/helpers/index.ts index 740aad1ab..37a75b6f1 100644 --- a/apps/browser-extension-wallet/src/lib/storage/helpers/index.ts +++ b/apps/browser-extension-wallet/src/lib/storage/helpers/index.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; import Dexie from 'dexie'; const isAddressError = /address/i; diff --git a/apps/browser-extension-wallet/src/types/side-menu.ts b/apps/browser-extension-wallet/src/types/side-menu.ts index abaca5c6b..722adff51 100644 --- a/apps/browser-extension-wallet/src/types/side-menu.ts +++ b/apps/browser-extension-wallet/src/types/side-menu.ts @@ -1,4 +1,4 @@ -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; import { MenuItemList } from '@utils/constants'; import { FC, SVGProps } from 'react'; diff --git a/apps/browser-extension-wallet/src/typings/i18next.d.ts b/apps/browser-extension-wallet/src/typings/i18next.d.ts index 81e31e253..9504b1ac7 100644 --- a/apps/browser-extension-wallet/src/typings/i18next.d.ts +++ b/apps/browser-extension-wallet/src/typings/i18next.d.ts @@ -1,5 +1,5 @@ import 'i18next'; -import { Translations } from '../lib/translations/types'; +import type { Translations } from '@lace/translation'; declare module 'i18next' { interface CustomTypeOptions { diff --git a/apps/browser-extension-wallet/src/views/browser-view/components/PortfolioBalance/PortfolioBalanceLabel/__tests__/PortfolioBalanceLabel.test.tsx b/apps/browser-extension-wallet/src/views/browser-view/components/PortfolioBalance/PortfolioBalanceLabel/__tests__/PortfolioBalanceLabel.test.tsx index 45d58c8bb..dd3a7c3dd 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/components/PortfolioBalance/PortfolioBalanceLabel/__tests__/PortfolioBalanceLabel.test.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/components/PortfolioBalance/PortfolioBalanceLabel/__tests__/PortfolioBalanceLabel.test.tsx @@ -4,7 +4,7 @@ import { render } from '@testing-library/react'; import { I18nextProvider } from 'react-i18next'; import { PortfolioBalanceLabel, PortfolioBalanceLabelProps } from '../PortfolioBalanceLabel'; import * as Stores from '@src/stores'; -import i18n from '@lib/i18n'; +import { i18n } from '@lace/translation'; jest.mock('@src/stores', (): typeof Stores => ({ ...jest.requireActual('@src/stores'), diff --git a/apps/browser-extension-wallet/src/views/browser-view/components/SideMenu/__tests__/SideMenu.test.tsx b/apps/browser-extension-wallet/src/views/browser-view/components/SideMenu/__tests__/SideMenu.test.tsx index fc28bc60e..396414e78 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/components/SideMenu/__tests__/SideMenu.test.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/components/SideMenu/__tests__/SideMenu.test.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { Wallet } from '@lace/cardano'; import { render, queryByText } from '@testing-library/react'; import '@testing-library/jest-dom'; -import i18n from '../../../../../lib/i18n'; +import { i18n } from '../../../../../lib/i18n'; import { I18nextProvider } from 'react-i18next'; import { BrowserRouter, Switch, Route } from 'react-router-dom'; import { SideMenu } from '../SideMenu'; diff --git a/apps/browser-extension-wallet/src/views/browser-view/components/WalletUsedAddressesDrawer/__tests__/WalletUsedAddressesDrawer.test.tsx b/apps/browser-extension-wallet/src/views/browser-view/components/WalletUsedAddressesDrawer/__tests__/WalletUsedAddressesDrawer.test.tsx index 4d0325212..9d8862e51 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/components/WalletUsedAddressesDrawer/__tests__/WalletUsedAddressesDrawer.test.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/components/WalletUsedAddressesDrawer/__tests__/WalletUsedAddressesDrawer.test.tsx @@ -3,7 +3,7 @@ import { I18nextProvider } from 'react-i18next'; import { render } from '@testing-library/react'; import '@testing-library/jest-dom'; import { Wallet } from '@lace/cardano'; -import i18n from '../../../../../lib/i18n'; +import { i18n } from '../../../../../lib/i18n'; import { buildMockProviders } from '../../../../../utils/mocks/context-providers'; import { WalletUsedAddressesDrawer } from '../WalletUsedAddressesDrawer'; import { from } from 'rxjs'; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx index a59640ea7..488c9cd1d 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx @@ -19,7 +19,7 @@ import { ActivityDetail as ActivityDetailType } from '@src/types'; import { useCurrencyStore } from '@providers'; import { TransactionDetailsProxy } from './TransactionDetailsProxy'; import { useTranslation } from 'react-i18next'; -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; const MAX_SUMMARY_ADDRESSES = 5; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/adress-book/components/AddressBookEmpty/__tests__/AddressBookEmpty.test.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/adress-book/components/AddressBookEmpty/__tests__/AddressBookEmpty.test.tsx index 1c5939cac..f3eb93e74 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/adress-book/components/AddressBookEmpty/__tests__/AddressBookEmpty.test.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/adress-book/components/AddressBookEmpty/__tests__/AddressBookEmpty.test.tsx @@ -5,7 +5,7 @@ import { AddressBookEmpty } from '../AddressBookEmpty'; import '@testing-library/jest-dom'; import { I18nextProvider } from 'react-i18next'; -import i18n from '../../../../../../../lib/i18n'; +import { i18n } from '../../../../../../../lib/i18n'; jest.mock('react-router', () => ({ // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/adress-book/components/AddressForm/__tests__/AddressForm.test.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/adress-book/components/AddressForm/__tests__/AddressForm.test.tsx index b52503463..d862bcba5 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/adress-book/components/AddressForm/__tests__/AddressForm.test.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/adress-book/components/AddressForm/__tests__/AddressForm.test.tsx @@ -5,7 +5,7 @@ import { AddressForm, AddressFormProps } from '../AddressForm'; import '@testing-library/jest-dom'; import { I18nextProvider } from 'react-i18next'; -import i18n from '../../../../../../../lib/i18n'; +import { i18n } from '../../../../../../../lib/i18n'; import { buildMockProviders } from '@src/utils/mocks/context-providers'; jest.mock('react-router', () => ({ diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetDetailsDrawer/__tests__/AssetDetails.test.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetDetailsDrawer/__tests__/AssetDetails.test.tsx index 6ea8a26af..35e218f59 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetDetailsDrawer/__tests__/AssetDetails.test.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetDetailsDrawer/__tests__/AssetDetails.test.tsx @@ -5,7 +5,7 @@ import { queryByTestId as queryByTestIdInContainer, render } from '@testing-libr import { I18nextProvider } from 'react-i18next'; import { AssetDetails, AssetDetailsProps } from '../AssetDetails'; import { StateStatus } from '@src/stores/types'; -import i18n from '@lib/i18n'; +import { i18n } from '@lace/translation'; import * as Stores from '@src/stores'; import { ExternalLinkOpenerProvider } from '@providers'; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/multi-address/MultiAddressBalanceVisibleModal.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/multi-address/MultiAddressBalanceVisibleModal.tsx index 60757adc7..70a47b356 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/multi-address/MultiAddressBalanceVisibleModal.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/multi-address/MultiAddressBalanceVisibleModal.tsx @@ -1,10 +1,10 @@ import React, { ReactElement } from 'react'; import { WarningModal } from '@views/browser/components'; -import { useTranslate } from '@lace/core'; import { useLocalStorage } from '@hooks'; import { useWalletStore } from '@stores'; import { useAnalyticsContext } from '@providers'; import { PostHogAction } from '@lace/common'; +import { useTranslation } from 'react-i18next'; export const MultiAddressBalanceVisibleModal = (): ReactElement => { const { walletState } = useWalletStore(); @@ -13,7 +13,7 @@ export const MultiAddressBalanceVisibleModal = (): ReactElement => { 'showMultiAddressModal', walletState.addresses.length > 1 ); - const { t } = useTranslate(); + const { t } = useTranslation(); const handleCloseModal = () => { setShowMultiAddressModal(false); diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/multi-wallet/hardware-wallet/steps/Connect.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/multi-wallet/hardware-wallet/steps/Connect.tsx index da251d7d6..d9cfd847a 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/multi-wallet/hardware-wallet/steps/Connect.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/multi-wallet/hardware-wallet/steps/Connect.tsx @@ -1,7 +1,7 @@ /* eslint-disable unicorn/no-null */ import { Wallet } from '@lace/cardano'; import { WalletSetupConnectHardwareWalletStepRevamp } from '@lace/core'; -import { TranslationKey } from '@lib/translations/types'; +import { TranslationKey } from '@lace/translation'; import { TFunction } from 'i18next'; import React, { useCallback, useEffect, useState, VFC } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/nfts/components/CreateFolder/NameForm.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/nfts/components/CreateFolder/NameForm.tsx index e4ebb360b..6b4546550 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/nfts/components/CreateFolder/NameForm.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/nfts/components/CreateFolder/NameForm.tsx @@ -2,7 +2,7 @@ import React, { ChangeEvent, ReactElement, useEffect, useState } from 'react'; import { Input } from '@lace/common'; import { useTranslation } from 'react-i18next'; import styles from './NameForm.module.scss'; -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; interface GeneralSettingsDrawerProps { usedFolderNames: Array; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/Form/CoinInput/__tests__/useSelectedCoins.test.ts b/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/Form/CoinInput/__tests__/useSelectedCoins.test.ts index 33d5ad064..984d57d3e 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/Form/CoinInput/__tests__/useSelectedCoins.test.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/Form/CoinInput/__tests__/useSelectedCoins.test.ts @@ -21,7 +21,7 @@ const mockUseSpentBalances = jest.fn().mockReturnValue({}); /* eslint-disable import/imports-first */ import { renderHook } from '@testing-library/react-hooks'; import { I18nextProvider } from 'react-i18next'; -import i18n from '@lib/i18n'; +import { i18n } from '@lace/translation'; import { UseSelectedCoinsProps, useSelectedCoins } from '../useSelectedCoins'; import { COIN_SELECTION_ERRORS } from '@hooks/useInitializeTx'; import { mockAsset } from '@src/utils/mocks/test-helpers'; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/Form/__tests__/MetadataInput.test.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/Form/__tests__/MetadataInput.test.tsx index 849af03d0..df77483cf 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/Form/__tests__/MetadataInput.test.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/Form/__tests__/MetadataInput.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import '@testing-library/jest-dom'; import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'; import { MetadataInput } from '../MetadataInput'; -import i18n from '@lib/i18n'; +import { i18n } from '@lace/translation'; import { I18nextProvider } from 'react-i18next'; const WrappedMetadataInput = () => ( diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/SendTransactionDrawer/Footer.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/SendTransactionDrawer/Footer.tsx index b69574d0d..96c3beb5b 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/SendTransactionDrawer/Footer.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/SendTransactionDrawer/Footer.tsx @@ -38,7 +38,7 @@ import { getAddressToSave } from '@src/utils/validators'; import { useAnalyticsContext } from '@providers'; import { txSubmitted$ } from '@providers/AnalyticsProvider/onChain'; import { withSignTxConfirmation } from '@lib/wallet-api-ui'; -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; export const nextStepBtnLabels: Partial> = { [Sections.FORM]: 'browserView.transaction.send.footer.review', @@ -232,22 +232,28 @@ export const Footer = withAddressBookContext( } switch (true) { - case isReviewingAddress: + case isReviewingAddress: { return handleReviewAddress('UPDATE'); - case isSummaryStep && !isInMemoryWallet: + } + case isSummaryStep && !isInMemoryWallet: { if (isPopupView) { return openContinueDialog(); } return handleVerifyPass(); - case isConfirmPass: + } + case isConfirmPass: { return handleVerifyPass(); - case txHasSucceeded: + } + case txHasSucceeded: { return onCloseSubmitedTransaction(); - case txHasFailed: + } + case txHasFailed: { setSubmitingTxState({ isPasswordValid: true }); return setSection(sectionsConfig.form); - default: + } + default: { return setSection(); + } } }, [ currentSection.currentSection, diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/SendTransactionDrawer/HeaderView.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/SendTransactionDrawer/HeaderView.tsx index 63f8b4f4b..235d9928e 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/SendTransactionDrawer/HeaderView.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/send-transaction/components/SendTransactionDrawer/HeaderView.tsx @@ -36,7 +36,7 @@ import { SelectTokenButton } from '@components/AssetSelectionButton/SelectTokens import { AssetsCounter } from '@components/AssetSelectionButton/AssetCounter'; import { saveTemporaryTxDataInStorage } from '../../helpers'; import { useAddressBookStore } from '@src/features/address-book/store'; -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; export const useHandleClose = (): { onClose: () => void; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/settings/components/Collateral/__tests__/CollateralDrawer.test.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/settings/components/Collateral/__tests__/CollateralDrawer.test.tsx index c201956a0..0f3ca097f 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/settings/components/Collateral/__tests__/CollateralDrawer.test.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/settings/components/Collateral/__tests__/CollateralDrawer.test.tsx @@ -26,7 +26,7 @@ import '@testing-library/jest-dom'; import { I18nextProvider } from 'react-i18next'; import { StoreProvider, WalletStore } from '@src/stores'; import { APP_MODE_BROWSER } from '@src/utils/constants'; -import i18n from '@lib/i18n'; +import { i18n } from '@lace/translation'; import { AnalyticsProvider, AppSettingsProvider, @@ -654,7 +654,7 @@ describe('Testing CollateralDrawer component', () => { } }; mockGetBackgroundStorage.mockReturnValue({ message }); - const clearBackgroundStorageMock = jest.fn().mockImplementation(async () => await true); + const clearBackgroundStorageMock = jest.fn().mockImplementation(async () => true); render( { } }; mockGetBackgroundStorage.mockReturnValue({ message }); - const clearBackgroundStorageMock = jest.fn().mockImplementation(async () => await true); + const clearBackgroundStorageMock = jest.fn().mockImplementation(async () => true); render(, { wrapper: getWrapper({ diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/settings/components/Collateral/hardware-wallet/FooterHW.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/settings/components/Collateral/hardware-wallet/FooterHW.tsx index 80a6b8e00..81225e845 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/settings/components/Collateral/hardware-wallet/FooterHW.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/settings/components/Collateral/hardware-wallet/FooterHW.tsx @@ -9,7 +9,7 @@ import { useBackgroundServiceAPIContext } from '@providers'; import { BrowserViewSections, MessageTypes } from '@lib/scripts/types'; import { SectionConfig } from '@src/views/browser-view/stores'; import { useBuiltTxState } from '@src/views/browser-view/features/send-transaction'; -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; export const nextStepBtnLabels: Partial> = { [Sections.SUCCESS_TX]: 'browserView.transaction.send.footer.viewTransaction', diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/settings/components/TermsDrawer.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/settings/components/TermsDrawer.tsx index 45cddb138..b7832bdec 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/settings/components/TermsDrawer.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/settings/components/TermsDrawer.tsx @@ -1,8 +1,9 @@ import React from 'react'; import cn from 'classnames'; import { Drawer, DrawerHeader, DrawerNavigation } from '@lace/common'; -import { LegalTranslations, useTranslate } from '@lace/core'; +import { LegalTranslations } from '@lace/core'; import styles from './SettingsLayout.module.scss'; +import { useTranslation } from 'react-i18next'; interface GeneralSettingsDrawerProps { visible: boolean; @@ -16,7 +17,7 @@ export const TermsDrawer = ({ onClose, popupView = false }: GeneralSettingsDrawerProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); return ( { section: BrowserViewSections.COLLATERAL_SETTINGS } }; - const clearBackgroundStorageMock = jest.fn().mockImplementation(async () => await true); + const clearBackgroundStorageMock = jest.fn().mockImplementation(async () => true); mockGetBackgroundStorage.mockReturnValue({ message }); const redirectToSettingsMock = jest.fn(); diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakePoolDetails/StakePoolDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakePoolDetails/StakePoolDetail.tsx index 9fdb8f69c..636eff0ba 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakePoolDetails/StakePoolDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakePoolDetails/StakePoolDetail.tsx @@ -14,7 +14,7 @@ import { useWalletStore } from '@src/stores'; import { useAnalyticsContext } from '@providers'; import { PostHogAction } from '@providers/AnalyticsProvider/analyticsTracker'; import { isOversaturated, StakePoolCardProgressBar } from '@lace/staking'; -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; const listItem: TranslationKey[] = [ 'browserView.staking.details.clickOnAPoolFromTheListInTheMainPage', diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakingModals/__tests__/StakingModal.test.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakingModals/__tests__/StakingModal.test.tsx index 8c4454920..bdd735af0 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakingModals/__tests__/StakingModal.test.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakingModals/__tests__/StakingModal.test.tsx @@ -5,7 +5,7 @@ import { StakingModal, StakingModalProps } from '../StakingModal'; import '@testing-library/jest-dom'; import { I18nextProvider } from 'react-i18next'; -import i18n from '../../../../../../../lib/i18n'; +import { i18n } from '../../../../../../../lib/i18n'; jest.mock('react-router', () => ({ // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakingModals/__tests__/StakingModals.test.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakingModals/__tests__/StakingModals.test.tsx index 97edb7c56..c741cbe60 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakingModals/__tests__/StakingModals.test.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakingModals/__tests__/StakingModals.test.tsx @@ -9,7 +9,7 @@ import { StakingModals } from '../StakingModals'; import '@testing-library/jest-dom'; import { I18nextProvider } from 'react-i18next'; -import i18n from '../../../../../../../lib/i18n'; +import { i18n } from '../../../../../../../lib/i18n'; import { AnalyticsProvider, AppSettingsProvider, ThemeProvider } from '@providers'; import { StoreProvider } from '@src/stores'; import { APP_MODE_BROWSER } from '@src/utils/constants'; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/voting/components/VotingLayout.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/voting/components/VotingLayout.tsx index d2746e145..c01853aaf 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/voting/components/VotingLayout.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/voting/components/VotingLayout.tsx @@ -15,7 +15,7 @@ import { import { useWalletStore } from '@src/stores'; import { ActionableAlert, Button, MultiStepProgressLine, DrawerHeader, DrawerNavigation, Drawer } from '@lace/common'; import classnames from 'classnames'; -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; const votingPhases = ['registration', 'snapshot', 'voting'] as const; type VotingPhase = typeof votingPhases[number]; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/wallet-setup/components/HardwareWalletFlow/StepConnect.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/wallet-setup/components/HardwareWalletFlow/StepConnect.tsx index d852733eb..6f19a3634 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/wallet-setup/components/HardwareWalletFlow/StepConnect.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/wallet-setup/components/HardwareWalletFlow/StepConnect.tsx @@ -2,7 +2,7 @@ import { UseWalletManager, useWalletManager } from '@hooks'; import { Wallet } from '@lace/cardano'; import { WalletSetupConnectHardwareWalletStepRevamp } from '@lace/core'; -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; import { TFunction } from 'i18next'; import React, { useCallback, useEffect, useState, VFC } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/wallet-setup/components/HardwareWalletFlow/makeErrorDialog.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/wallet-setup/components/HardwareWalletFlow/makeErrorDialog.tsx index a27f4f9a6..46adbbb75 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/wallet-setup/components/HardwareWalletFlow/makeErrorDialog.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/wallet-setup/components/HardwareWalletFlow/makeErrorDialog.tsx @@ -1,4 +1,4 @@ -import { TranslationKey } from '@lib/translations/types'; +import type { TranslationKey } from '@lace/translation'; import React from 'react'; import { Modal, Typography } from 'antd'; import { Button } from '@lace/common'; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/wallet-setup/components/WalletSetupMainPage.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/wallet-setup/components/WalletSetupMainPage.tsx index b9bd84d4f..c8e0684b6 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/wallet-setup/components/WalletSetupMainPage.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/wallet-setup/components/WalletSetupMainPage.tsx @@ -1,12 +1,7 @@ import React, { ReactElement, useState } from 'react'; -import { Trans } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; import { WalletSetupLayout, WarningModal } from '@views/browser/components'; -import { - AnalyticsConfirmationBanner, - useTranslate, - WalletAnalyticsInfo, - WalletSetupOptionsStepRevamp -} from '@lace/core'; +import { AnalyticsConfirmationBanner, WalletAnalyticsInfo, WalletSetupOptionsStepRevamp } from '@lace/core'; import styles from '@views/browser/features/wallet-setup/components/WalletSetup.module.scss'; import { walletRoutePaths } from '@routes'; import { @@ -27,7 +22,7 @@ const TERMS_OF_USE_URL = process.env.TERMS_OF_USE_URL; export const WalletSetupMainPage = (): ReactElement => { const history = useHistory(); const [isAnalyticsModalOpen, setIsAnalyticsModalOpen] = useState(false); - const { t: translate } = useTranslate(); + const { t: translate } = useTranslation(); const analytics = useAnalyticsContext(); const [enhancedAnalyticsStatus, { updateLocalStorage: setDoesUserAllowAnalytics }] = useLocalStorage( @@ -63,6 +58,7 @@ export const WalletSetupMainPage = (): ReactElement => { target="_blank" className={styles.link} data-testid="agreement-terms-of-service-link" + rel="noreferrer" /> ), a2: ( @@ -71,6 +67,7 @@ export const WalletSetupMainPage = (): ReactElement => { target="_blank" className={styles.link} data-testid="agreement-privacy-policy-link" + rel="noreferrer" /> ) }} diff --git a/package.json b/package.json index be5ed906d..ae755d669 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "watch-deps": "EXCLUDE_APP=true yarn watch" }, "lint-staged": { - "*(apps/**/*.{js,ts,tsx}|packages/!(ui)/**/*.{js,ts,tsx}|stories/**/*.{js,ts,tsx})": [ + "*(apps/**/*.{js,ts,tsx}|packages/!(ui|translation)/**/*.{js,ts,tsx}|stories/**/*.{js,ts,tsx})": [ "eslint --cache --cache-location .cache/eslintcache --cache-strategy metadata --fix --ignore-path ./.eslintignore", "prettier --write" ], @@ -53,6 +53,10 @@ "yarn workspace @lace/ui lint --fix", "yarn workspace @lace/ui format" ], + "*(packages/translation/**/*.{js,ts,tsx})": [ + "yarn workspace @lace/translation lint --fix", + "yarn workspace @lace/translation format" + ], "*.json": "prettier --write", "{packages/!(ui),apps}/**/*.md": [ "prettier --write", diff --git a/packages/cardano/src/ui/typings/i18next.d.ts b/packages/cardano/src/ui/typings/i18next.d.ts new file mode 100644 index 000000000..9504b1ac7 --- /dev/null +++ b/packages/cardano/src/ui/typings/i18next.d.ts @@ -0,0 +1,10 @@ +import 'i18next'; +import type { Translations } from '@lace/translation'; + +declare module 'i18next' { + interface CustomTypeOptions { + resources: { + translation: Translations; + }; + } +} diff --git a/packages/common/src/ui/lib/i18n.ts b/packages/common/src/ui/lib/i18n.ts deleted file mode 100644 index 9db41e9e2..000000000 --- a/packages/common/src/ui/lib/i18n.ts +++ /dev/null @@ -1,3 +0,0 @@ -export enum Language { - en = 'en' -} diff --git a/packages/common/src/ui/lib/index.ts b/packages/common/src/ui/lib/index.ts index d42370c9c..d03ba4fda 100644 --- a/packages/common/src/ui/lib/index.ts +++ b/packages/common/src/ui/lib/index.ts @@ -2,5 +2,4 @@ export * from './add-ellipsis'; export * from './format-number'; export * from './get-random-icon'; export * from './text-formatters'; -export * from './i18n'; export * from './get-number-unit'; diff --git a/packages/core/.storybook/preview.js b/packages/core/.storybook/preview.js index 6cd56b772..2aa7898e7 100644 --- a/packages/core/.storybook/preview.js +++ b/packages/core/.storybook/preview.js @@ -1,5 +1,6 @@ import React from 'react'; import { ThemeColorScheme, ThemeProvider, colorSchemaDecorator } from '@lace/ui'; +import '@lace/translation'; import 'antd/dist/antd.css'; import 'normalize.css'; import './index.scss'; diff --git a/packages/core/package.json b/packages/core/package.json index 5ba6dc705..c8d856615 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -43,6 +43,7 @@ "@lace/cardano": "0.1.0", "@lace/common": "0.1.0", "@lace/icons": "0.1.0", + "@lace/translation": "0.1.0", "@lace/ui": "^0.1.0", "antd": "^4.24.10", "axios": "0.28.0", @@ -83,7 +84,7 @@ "sass": "^1.68.0", "storybook": "^7.4.3", "tsconfig-paths-webpack-plugin": "3.5.2", - "typescript": "^4.3.5" + "typescript": "^4.9.5" }, "peerDependencies": { "react": "17.0.2", diff --git a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx index ba2e441fe..8360d417b 100644 --- a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx +++ b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx @@ -10,11 +10,12 @@ import { ReactComponent as PendingIcon } from '../../assets/icons/pending.compon import { ReactComponent as ErrorIcon } from '../../assets/icons/error.component.svg'; import pluralize from 'pluralize'; import { txIconSize } from '@src/ui/utils/icon-size'; -import { useTranslate } from '@src/ui/hooks'; import { DelegationActivityType, TransactionActivityType } from '../ActivityDetail/types'; import type { ActivityType } from '../ActivityDetail/types'; import styles from './AssetActivityItem.module.scss'; import { ActivityTypeIcon } from '../ActivityDetail/ActivityTypeIcon'; +import { useTranslation } from 'react-i18next'; +import { TranslationKey } from '@lace/translation'; export type ActivityAssetInfo = { ticker: string }; export type ActivityAssetProp = { id: string; val: string; info?: ActivityAssetInfo }; @@ -108,7 +109,7 @@ export const AssetActivityItem = ({ assets, formattedTimestamp }: AssetActivityItemProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); const ref = useRef(null); const [assetsToShow, setAssetsToShow] = React.useState(0); @@ -193,7 +194,7 @@ export const AssetActivityItem = ({
{isPendingTx && type !== TransactionActivityType.self && !(type in DelegationActivityType) ? t('core.assetActivityItem.entry.name.sending') - : t(`core.assetActivityItem.entry.name.${type}`)} + : t(`core.assetActivityItem.entry.name.${type}` as unknown as TranslationKey)}
{descriptionContent} diff --git a/packages/core/src/ui/components/Activity/AssetActivityList.tsx b/packages/core/src/ui/components/Activity/AssetActivityList.tsx index f8a55e752..8a1fe9a6a 100644 --- a/packages/core/src/ui/components/Activity/AssetActivityList.tsx +++ b/packages/core/src/ui/components/Activity/AssetActivityList.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { AssetActivityItem, AssetActivityItemProps } from './AssetActivityItem'; import styles from './AssetActivityList.module.scss'; -import { useTranslate } from '@src/ui/hooks/useTranslate'; +import { useTranslation } from 'react-i18next'; export interface AssetActivityListProps { /** @@ -22,7 +22,7 @@ export const AssetActivityList = ({ title, isDrawerView }: AssetActivityListProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); return ( { - const { t } = useTranslate(); + const { t } = useTranslation(); const getTooltipText = (): string => { switch (status) { diff --git a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx index a2d4d2c41..b74e4af84 100644 --- a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx @@ -1,10 +1,10 @@ import React from 'react'; import cn from 'classnames'; import styles from './TransactionDetails.module.scss'; -import { useTranslate } from '@src/ui/hooks'; import { ActivityStatus } from '../Activity/AssetActivityItem'; import { Ellipsis } from '@lace/common'; import { ActivityDetailHeader } from './ActivityDetailHeader'; +import { useTranslation } from 'react-i18next'; type RewardItem = { pool?: { name: string; ticker: string; id: string }; @@ -38,7 +38,7 @@ export const RewardsDetails = ({ coinSymbol, rewards }: RewardsDetailsProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); const poolRewards = rewards.rewards.filter((reward) => !!reward.pool); const tooltipContent = t('core.activityDetails.rewardsDescription'); diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx index a755b06e2..e3b1460ff 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx @@ -4,7 +4,6 @@ import cn from 'classnames'; import { Ellipsis, toast } from '@lace/common'; import { Box, Text } from '@lace/ui'; -import { useTranslate } from '@ui/hooks'; import { getAddressTagTranslations, renderAddressTag } from '@ui/utils'; import { TransactionDetailAsset, TransactionMetadataProps, TxOutputInput, TxSummary } from './TransactionDetailAsset'; @@ -24,6 +23,8 @@ import { TransactionActivityType } from './types'; import { Collateral, CollateralStatus } from './Collateral'; +import { useTranslation } from 'react-i18next'; +import { TranslationKey } from '@lace/translation'; // eslint-disable-next-line @typescript-eslint/no-explicit-any const displayMetadataMsg = (value: any[]): string => value?.find((val: any) => val.hasOwnProperty('msg'))?.msg || ''; @@ -138,7 +139,7 @@ export const TransactionDetails = ({ certificates, collateral }: TransactionDetailsProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); const isSending = status === ActivityStatus.PENDING; const isSuccess = status === ActivityStatus.SUCCESS; @@ -158,7 +159,7 @@ export const TransactionDetails = ({ ...detail, ...('title' in detail && detail.title === 'certificateType' && { - details: [t(`core.assetActivityItem.entry.name.${detail.details[0]}`)] + details: [t(`core.assetActivityItem.entry.name.${detail.details[0]}` as unknown as TranslationKey)] }), ...('title' in detail && detail.title === 'anchorURL' && { @@ -178,7 +179,7 @@ export const TransactionDetails = ({ ...p, ...('title' in p && p.title === 'type' && { - details: [t(`core.activityDetails.governanceActions.${p.details[0]}`)] + details: [t(`core.activityDetails.governanceActions.${p.details[0]}` as unknown as TranslationKey)] }), ...('title' in p && p.title === 'anchorURL' && { @@ -220,7 +221,7 @@ export const TransactionDetails = ({ ...p, ...('title' in p && ['voterType', 'voteTypes'].includes(p.title) && { - details: [t(`core.activityDetails.${p.title}.${p.details[0]}`)] + details: [t(`core.activityDetails.${p.title}.${p.details[0]}` as unknown as TranslationKey)] }), ...('title' in p && p.title === 'anchorURL' && { diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionFee.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionFee.tsx index 670347915..314c0db63 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionFee.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionFee.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { useTranslate } from '@src/ui/hooks'; import { TransactionSummary } from '@lace/ui'; +import { useTranslation } from 'react-i18next'; export interface TransactionFeeProps { fee: string; @@ -24,7 +24,7 @@ export const TransactionFee = ({ displayFiat, highlightPositiveAmount }: TransactionFeeProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); return ( { const [isVisible, setIsVisible] = useState(); - const { t } = useTranslate(); + const { t } = useTranslation(); const animation = isVisible ? rotateOpen : rotateClose; const Icon = BracketDown ? : ; diff --git a/packages/core/src/ui/components/AssetInput/AssetInput.tsx b/packages/core/src/ui/components/AssetInput/AssetInput.tsx index c5e262913..774de2f8d 100644 --- a/packages/core/src/ui/components/AssetInput/AssetInput.tsx +++ b/packages/core/src/ui/components/AssetInput/AssetInput.tsx @@ -3,11 +3,12 @@ import React, { useState, useEffect, useRef, useLayoutEffect, useCallback } from 'react'; import { Tooltip, Input } from 'antd'; import { Button, getTextWidth } from '@lace/common'; -import { useTranslate } from '@src/ui/hooks/useTranslate'; import { ReactComponent as Chevron } from '../../assets/icons/chevron-right.component.svg'; import styles from './AssetInput.module.scss'; import { validateNumericValue } from '@src/ui/utils/validate-numeric-value'; import { sanitizeNumber } from '@ui/utils/sanitize-number'; +import { useTranslation } from 'react-i18next'; +import { TranslationKey } from '@lace/translation'; const isSameNumberFormat = (num1: string, num2: string) => { if (!num1 || !num2) return false; @@ -38,7 +39,7 @@ export interface AssetInputProps { hasReachedMaxAmount?: boolean; focused?: boolean; onBlurErrors?: Set; - getErrorMessage: (message: string) => string; + getErrorMessage: (message: string) => TranslationKey; setFocusInput?: (input?: string) => void; setFocus?: (focus: boolean) => void; } @@ -103,7 +104,7 @@ export const AssetInput = ({ } }, [compactValue, value, focused]); - const { t } = useTranslate(); + const { t } = useTranslation(); useEffect(() => { setIsInvalid(invalid); diff --git a/packages/core/src/ui/components/AssetSelector/AssetSelectorOverlay.tsx b/packages/core/src/ui/components/AssetSelector/AssetSelectorOverlay.tsx index f9aa5deee..c1873e05c 100644 --- a/packages/core/src/ui/components/AssetSelector/AssetSelectorOverlay.tsx +++ b/packages/core/src/ui/components/AssetSelector/AssetSelectorOverlay.tsx @@ -8,8 +8,9 @@ import { TokenItem, TokenItemProps } from '../Token'; import styles from './AssetSelectorOverlay.module.scss'; import { TranslationsFor } from '@src/ui/utils/types'; -import { useTranslate } from '@src/ui/hooks/useTranslate'; import { ListEmptyState } from '../ListEmptyState'; +import { useTranslation } from 'react-i18next'; +import { TFunction } from 'i18next'; export const stringIncludesValue = (string: string, searchValue: string): boolean => string.toLowerCase().includes(searchValue.toLowerCase()); @@ -28,7 +29,7 @@ const getTokensContent = ( tokens: DropdownList[]; selectedTokenList?: Array; }, - t: ReturnType['t'], + t: TFunction, removeTokenFromList: (id: string) => void, handleTokenClick: (id: string) => void ) => { @@ -70,7 +71,7 @@ const getNftsContent = ( selectedTokenList?: Array; nftListConfig?: { rows?: number }; }, - t: ReturnType['t'], + t: TFunction, removeTokenFromList: (id: string) => void, handleTokenClick: (id: string) => void ) => { @@ -142,7 +143,7 @@ export const AssetSelectorOverlay = ({ className, groups = [ASSET_COMPONENTS.TOKENS, ASSET_COMPONENTS.NFTS] }: AssetSelectorOverlayProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); const [value, setValue] = useState(); const [section, setSection] = useState(intialSection); const [focus, setFocus] = useState(false); diff --git a/packages/core/src/ui/components/AssetTable/AssetTable.tsx b/packages/core/src/ui/components/AssetTable/AssetTable.tsx index 1706d9042..1f2f5e62c 100644 --- a/packages/core/src/ui/components/AssetTable/AssetTable.tsx +++ b/packages/core/src/ui/components/AssetTable/AssetTable.tsx @@ -4,7 +4,7 @@ import { InfiniteScrollableTable, useHasScrollBar } from '@lace/common'; import { ColumnsType } from 'antd/lib/table'; import React, { useState } from 'react'; import styles from './AssetTable.module.scss'; -import { useTranslate } from '@src/ui/hooks/useTranslate'; +import { useTranslation } from 'react-i18next'; export interface IRow { id: string; @@ -118,7 +118,7 @@ export const AssetTable = ({ const handleRowClick = (record: IAssetColumn) => ({ onClick: () => onRowClick(record?.key) }); - const { t } = useTranslate(); + const { t } = useTranslation(); const columns: ColumnsType = [ { diff --git a/packages/core/src/ui/components/AuthorizeDapp/AuthorizeDapp.tsx b/packages/core/src/ui/components/AuthorizeDapp/AuthorizeDapp.tsx index b0b0292e9..516db9663 100644 --- a/packages/core/src/ui/components/AuthorizeDapp/AuthorizeDapp.tsx +++ b/packages/core/src/ui/components/AuthorizeDapp/AuthorizeDapp.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { DappInfo, DappInfoProps } from '../DappInfo'; import styles from './AuthorizeDapp.module.scss'; -import { useTranslate } from '@ui/hooks'; +import { useTranslation } from 'react-i18next'; export interface AuthorizeDappProps { /** dApp information such as logo, name and url */ @@ -10,7 +10,7 @@ export interface AuthorizeDappProps { } export const AuthorizeDapp = ({ dappInfo, warningBanner }: AuthorizeDappProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); return (
diff --git a/packages/core/src/ui/components/DappAddressSections/DappAddressSection.tsx b/packages/core/src/ui/components/DappAddressSections/DappAddressSection.tsx index ea229a387..1f0c963d5 100644 --- a/packages/core/src/ui/components/DappAddressSections/DappAddressSection.tsx +++ b/packages/core/src/ui/components/DappAddressSections/DappAddressSection.tsx @@ -4,10 +4,11 @@ import { Wallet } from '@lace/cardano'; import { Cardano, AssetInfoWithAmount } from '@cardano-sdk/core'; import styles from './DappAddressSections.module.scss'; -import { useTranslate } from '@src/ui/hooks'; import { Text, TransactionAssets, DappTransactionSummary, Tooltip, SummaryExpander, Box, Flex } from '@lace/ui'; import { getAddressTagTranslations, renderAddressTag } from '@src/ui/utils'; +import { useTranslation } from 'react-i18next'; +import { TFunction } from 'i18next'; interface GroupedAddressAssets { nfts: Array; @@ -49,7 +50,7 @@ const getAssetTokenName = (assetWithAmount: AssetInfoWithAmount) => { const charBeforeEllName = 9; const charAfterEllName = 0; -type UseTranslate = ReturnType['t']; +type UseTranslate = TFunction; const getTransactionAssetTranslations = (t: UseTranslate) => ({ assetId: t('core.dappTransaction.assetId'), @@ -116,7 +117,7 @@ export const DappAddressSection = ({ ownAddresses, addressToNameMap }: DappAddressSectionProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); const itemsCountCopy = t('core.dappTransaction.items'); diff --git a/packages/core/src/ui/components/DappAddressSections/DappAddressSections.tsx b/packages/core/src/ui/components/DappAddressSections/DappAddressSections.tsx index 671aa22af..05370ce7d 100644 --- a/packages/core/src/ui/components/DappAddressSections/DappAddressSections.tsx +++ b/packages/core/src/ui/components/DappAddressSections/DappAddressSections.tsx @@ -2,9 +2,8 @@ import React from 'react'; import { Cardano, AssetInfoWithAmount } from '@cardano-sdk/core'; -import { useTranslate } from '@src/ui/hooks'; - import { DappAddressSection } from './DappAddressSection'; +import { useTranslation } from 'react-i18next'; interface GroupedAddressAssets { nfts: Array; @@ -31,7 +30,7 @@ export const DappAddressSections = ({ ownAddresses, addressToNameMap }: DappAddressSectionProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); return ( <> diff --git a/packages/core/src/ui/components/DappTransaction/DappTransaction.tsx b/packages/core/src/ui/components/DappTransaction/DappTransaction.tsx index 420ff5d86..4888f7986 100644 --- a/packages/core/src/ui/components/DappTransaction/DappTransaction.tsx +++ b/packages/core/src/ui/components/DappTransaction/DappTransaction.tsx @@ -7,7 +7,6 @@ import { Cardano, TransactionSummaryInspection, TokenTransferValue, AssetInfoWit import { DappTransactionHeader, DappTransactionHeaderProps, TransactionTypes } from '../DappTransactionHeader'; import styles from './DappTransaction.module.scss'; -import { useTranslate } from '@src/ui/hooks'; import { TransactionFee, Collateral } from '@ui/components/ActivityDetail'; import { @@ -21,6 +20,7 @@ import { Divider } from '@lace/ui'; import { DappAddressSections } from '../DappAddressSections/DappAddressSections'; +import { useTranslation } from 'react-i18next'; const amountTransformer = (fiat: { price: number; code: string }) => (ada: string) => `${Wallet.util.convertAdaToFiat({ ada, fiat: fiat.price })} ${fiat.code}`; @@ -127,7 +127,7 @@ export const DappTransaction = ({ ownAddresses = [], addressToNameMap = new Map() }: DappTransactionProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); const groupedToAddresses = groupAddresses(toAddress); const groupedFromAddresses = groupAddresses(fromAddress); diff --git a/packages/core/src/ui/components/DappTransactionHeader/DappTransactionHeader.tsx b/packages/core/src/ui/components/DappTransactionHeader/DappTransactionHeader.tsx index d35e40d02..a539c7aed 100644 --- a/packages/core/src/ui/components/DappTransactionHeader/DappTransactionHeader.tsx +++ b/packages/core/src/ui/components/DappTransactionHeader/DappTransactionHeader.tsx @@ -2,9 +2,9 @@ import React from 'react'; import { Typography } from 'antd'; import styles from './DappTransactionHeader.module.scss'; -import { useTranslate } from '@src/ui/hooks'; import { TransactionType, SummaryExpander, Card } from '@lace/ui'; +import { useTranslation } from 'react-i18next'; const { Text } = Typography; @@ -26,7 +26,7 @@ export interface DappTransactionHeaderProps { } export const DappTransactionHeader = ({ transactionType, name }: DappTransactionHeaderProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); return (
diff --git a/packages/core/src/ui/components/OutputSummary/OutputSummary.tsx b/packages/core/src/ui/components/OutputSummary/OutputSummary.tsx index 97f50e27d..53a4cc9f4 100644 --- a/packages/core/src/ui/components/OutputSummary/OutputSummary.tsx +++ b/packages/core/src/ui/components/OutputSummary/OutputSummary.tsx @@ -4,7 +4,7 @@ import styles from './OutputSummary.module.scss'; import { TranslationsFor } from '@ui/utils/types'; import { Text, Flex, Box } from '@lace/ui'; import { getAddressTagTranslations, renderAddressTag } from '@src/ui/utils'; -import { useTranslate } from '@src/ui/hooks'; +import { useTranslation } from 'react-i18next'; export type SentAssetsList = Array<{ assetAmount: string; @@ -26,7 +26,7 @@ export const OutputSummary = ({ recipientName, ownAddresses }: OutputSummaryProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); return (
diff --git a/packages/core/src/ui/components/Token/TokenItem.tsx b/packages/core/src/ui/components/Token/TokenItem.tsx index dd091af78..e282f2b74 100644 --- a/packages/core/src/ui/components/Token/TokenItem.tsx +++ b/packages/core/src/ui/components/Token/TokenItem.tsx @@ -4,7 +4,7 @@ import DefaultActivityImage from '../../assets/images/token-default-logo.png'; import { ReactComponent as SelectedIcon } from '../../assets/icons/check-token-icon.svg'; import styles from './TokenItem.module.scss'; -import { useTranslate } from '@src/ui/hooks'; +import { useTranslation } from 'react-i18next'; export interface TokenItemProps { amount: string; @@ -25,7 +25,7 @@ export const TokenItem = ({ selected, logo = DefaultActivityImage }: TokenItemProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); const [isDeselectVisible, setDeselectVisibility] = useState(false); const handleMouseIn = () => setDeselectVisibility(true); diff --git a/packages/core/src/ui/components/WalletAddresses/WalletAddressItem.tsx b/packages/core/src/ui/components/WalletAddresses/WalletAddressItem.tsx index 1d0d19fcb..c714e8a5d 100644 --- a/packages/core/src/ui/components/WalletAddresses/WalletAddressItem.tsx +++ b/packages/core/src/ui/components/WalletAddresses/WalletAddressItem.tsx @@ -5,7 +5,7 @@ import { Typography, Tooltip } from 'antd'; import { Ellipsis, addEllipsis } from '@lace/common'; import { ReactComponent as MissingIcon } from '../../assets/icons/missing.component.svg'; import styles from './WalletAddressItem.module.scss'; -import { useTranslate } from '@src/ui/hooks'; +import { useTranslation } from 'react-i18next'; const { Text } = Typography; interface AddressBookSchema { @@ -43,7 +43,7 @@ export const WalletAddressItem = ({ shouldUseEllipsis, isAddressWarningVisible = false }: WalletAddressItemProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); return (
{ const [isVisible, setIsVisible] = useState(show); - const { t } = useTranslate(); + const { t } = useTranslation(); const handleConfirm = () => { setIsVisible(false); diff --git a/packages/core/src/ui/components/WalletSetup/LegalTranslations.tsx b/packages/core/src/ui/components/WalletSetup/LegalTranslations.tsx index 30295cd64..e1c992ab8 100644 --- a/packages/core/src/ui/components/WalletSetup/LegalTranslations.tsx +++ b/packages/core/src/ui/components/WalletSetup/LegalTranslations.tsx @@ -1,42 +1,39 @@ import React from 'react'; -import { useTranslate } from '@ui/hooks'; +import { Trans } from 'react-i18next'; -export const LegalTranslations = (): React.ReactElement => { - const { Trans } = useTranslate(); - return ( - , - strong: , - i: , - b: , - div:
, - u: , - uunderline: , - a: , - privacyPolicy: ( - - ), - iogdmcapolicy: ( - - ), - rulesstreamlinedarbitration: , - rulescomprehensivearbitration: ( - - ), - jamsadr: , - contactform: - }} - /> - ); -}; +export const LegalTranslations = (): React.ReactElement => ( + , + strong: , + i: , + b: , + div:
, + u: , + uunderline: , + a: , + privacyPolicy: ( + + ), + iogdmcapolicy: ( + + ), + rulesstreamlinedarbitration: , + rulescomprehensivearbitration: ( + + ), + jamsadr: , + contactform: + }} + /> +); diff --git a/packages/core/src/ui/components/WalletSetup/WalletAnalyticsInfo.tsx b/packages/core/src/ui/components/WalletSetup/WalletAnalyticsInfo.tsx index 7aa90a2eb..710d61f28 100644 --- a/packages/core/src/ui/components/WalletSetup/WalletAnalyticsInfo.tsx +++ b/packages/core/src/ui/components/WalletSetup/WalletAnalyticsInfo.tsx @@ -2,10 +2,10 @@ import React, { ReactElement } from 'react'; import Check from '../../assets/icons/check.svg'; import NotAllowed from '../../assets/icons/x.svg'; import styles from './WalletAnalyticsInfo.module.scss'; -import { useTranslate } from '@ui/hooks'; +import { useTranslation } from 'react-i18next'; export const WalletAnalyticsInfo = (): ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); const infoTexts = [ { icon: check, diff --git a/packages/core/src/ui/components/WalletSetup/WalletSetupConfirmationDialogProvider.tsx b/packages/core/src/ui/components/WalletSetup/WalletSetupConfirmationDialogProvider.tsx index 5da26eea4..63336ef71 100644 --- a/packages/core/src/ui/components/WalletSetup/WalletSetupConfirmationDialogProvider.tsx +++ b/packages/core/src/ui/components/WalletSetup/WalletSetupConfirmationDialogProvider.tsx @@ -1,8 +1,8 @@ /* eslint-disable unicorn/no-null */ import React, { createContext, useContext, useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { useTranslate } from '@src/ui/hooks'; import { BehaviorSubject } from 'rxjs'; import { StartOverDialog } from '@ui/components/SharedWallet/StartOverDialog'; +import { useTranslation } from 'react-i18next'; interface Props { children: React.ReactNode; @@ -27,7 +27,7 @@ export const WalletSetupConfirmationDialogProvider = ({ children }: Props): Reac const handleOnConfirmRef = useRef(() => void 0); const shouldShowDialog = useRef(false); const shouldShowDialog$ = useMemo(() => new BehaviorSubject(false), []); - const { t } = useTranslate(); + const { t } = useTranslation(); useEffect(() => { const subscription = shouldShowDialog$.subscribe((value) => { diff --git a/packages/core/src/ui/components/WalletSetup/WalletSetupNamePasswordStep/WalletSetupNamePasswordStep.tsx b/packages/core/src/ui/components/WalletSetup/WalletSetupNamePasswordStep/WalletSetupNamePasswordStep.tsx index f957fb9ab..6653dc920 100644 --- a/packages/core/src/ui/components/WalletSetup/WalletSetupNamePasswordStep/WalletSetupNamePasswordStep.tsx +++ b/packages/core/src/ui/components/WalletSetup/WalletSetupNamePasswordStep/WalletSetupNamePasswordStep.tsx @@ -2,7 +2,6 @@ import React, { useMemo, useState } from 'react'; import { WalletSetupStepLayout, WalletTimelineSteps } from '../WalletSetupStepLayout'; import { PasswordVerification } from '@lace/common'; import { passwordComplexity } from '@src/ui/utils/password-complexity'; -import { useTranslate } from '@src/ui/hooks'; import { BarStates, WalletSetupNamePasswordSubmitParams } from './types'; import styles from './styles.module.scss'; import { @@ -15,6 +14,7 @@ import { import { WalletNameInput } from './WalletNameInput'; import { WalletPasswordConfirmationInput } from './WalletPasswordConfirmationInput'; import { TranslationsFor } from '@ui/utils/types'; +import { useTranslation } from 'react-i18next'; export interface WalletSetupNamePasswordStepProps { onBack: () => void; @@ -43,7 +43,7 @@ export const WalletSetupNamePasswordStep = ({ onChange, translations }: WalletSetupNamePasswordStepProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); const [password, setPassword] = useState(''); const [passwordConfirmation, setPasswordConfirmation] = useState(''); const [passHasBeenValidated, setPassHasBeenValidated] = useState(false); diff --git a/packages/core/src/ui/components/WalletSetup/WalletSetupNamePasswordStep/utils.ts b/packages/core/src/ui/components/WalletSetup/WalletSetupNamePasswordStep/utils.ts index 92322594b..6533cbd1c 100644 --- a/packages/core/src/ui/components/WalletSetup/WalletSetupNamePasswordStep/utils.ts +++ b/packages/core/src/ui/components/WalletSetup/WalletSetupNamePasswordStep/utils.ts @@ -1,11 +1,12 @@ import { complexityLevels } from '@lace/common'; import { ValidationErrorKeys } from './types'; +import { TranslationKey } from '@lace/translation'; // Depending on what is the result of the A/B test, we might want to use these functions/constants in WalletSetupRegisterStep.tsx and WalletSetupPasswordStep.tsx to clean thing up export const MINIMUM_PASSWORD_LEVEL_REQUIRED = 3; export const WALLET_NAME_INPUT_MAX_LENGTH = 30; -export const passwordStrengthFeedbackMap: Record = { +export const passwordStrengthFeedbackMap: Record = { 0: 'core.walletNameAndPasswordSetupStep.firstLevelPasswordStrengthFeedback', 1: 'core.walletNameAndPasswordSetupStep.firstLevelPasswordStrengthFeedback', 2: 'core.walletNameAndPasswordSetupStep.secondLevelPasswordStrengthFeedback' diff --git a/packages/core/src/ui/components/WalletSetup/WalletSetupSelectAccountsStep.tsx b/packages/core/src/ui/components/WalletSetup/WalletSetupSelectAccountsStep.tsx index db56cc87c..6df6c45dc 100644 --- a/packages/core/src/ui/components/WalletSetup/WalletSetupSelectAccountsStep.tsx +++ b/packages/core/src/ui/components/WalletSetup/WalletSetupSelectAccountsStep.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { WalletSetupStepLayout, WalletTimelineSteps } from './WalletSetupStepLayout'; import styles from './WalletSetupSelectAccountsStep.module.scss'; import { Radio } from 'antd'; -import { useTranslate } from '@src/ui//hooks'; +import { useTranslation } from 'react-i18next'; export interface WalletSetupSelectAccountsStepProps { accounts: number; @@ -19,7 +19,7 @@ export const WalletSetupSelectAccountsStep = ({ wallet }: WalletSetupSelectAccountsStepProps): React.ReactElement => { const [selectedAccount, setSelectedAccount] = useState(); - const { t } = useTranslate(); + const { t } = useTranslation(); return ( { - const { t } = useTranslate(); + const { t } = useTranslation(); const nextButtonContainerRef = useRef(null); const flow = useWalletSetupFlow(); diff --git a/packages/core/src/ui/components/WalletSetupRevamp/WalletSetupNamePasswordStepRevamp.tsx b/packages/core/src/ui/components/WalletSetupRevamp/WalletSetupNamePasswordStepRevamp.tsx index 3f6c5a58b..3e3ed996e 100644 --- a/packages/core/src/ui/components/WalletSetupRevamp/WalletSetupNamePasswordStepRevamp.tsx +++ b/packages/core/src/ui/components/WalletSetupRevamp/WalletSetupNamePasswordStepRevamp.tsx @@ -13,9 +13,9 @@ import { WalletNameInput } from '../WalletSetup/WalletSetupNamePasswordStep/Wall import { WalletPasswordConfirmationInput } from '../WalletSetup/WalletSetupNamePasswordStep/WalletPasswordConfirmationInput'; import { WalletSetupStepLayoutRevamp } from './WalletSetupStepLayoutRevamp'; import { TranslationsFor } from '@ui/utils/types'; -import { useTranslate } from '@ui/hooks'; import { passwordComplexity } from '@ui/utils/password-complexity'; import styles from '../WalletSetup/WalletSetupNamePasswordStep/styles.module.scss'; +import { useTranslation } from 'react-i18next'; export interface WalletSetupNamePasswordStepProps { onBack: () => void; @@ -44,7 +44,7 @@ export const WalletSetupNamePasswordStepRevamp = ({ onChange, translations }: WalletSetupNamePasswordStepProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); const [password, setPassword] = useState(''); const [passwordConfirmation, setPasswordConfirmation] = useState(''); const [nextButtonLoading, setNextButtonLoading] = useState(false); diff --git a/packages/core/src/ui/components/WalletSetupRevamp/WalletSetupSelectAccountsStepRevamp.tsx b/packages/core/src/ui/components/WalletSetupRevamp/WalletSetupSelectAccountsStepRevamp.tsx index 89527262d..3fa10d24f 100644 --- a/packages/core/src/ui/components/WalletSetupRevamp/WalletSetupSelectAccountsStepRevamp.tsx +++ b/packages/core/src/ui/components/WalletSetupRevamp/WalletSetupSelectAccountsStepRevamp.tsx @@ -1,10 +1,10 @@ import React, { ChangeEvent, useMemo, useState } from 'react'; import styles from './WalletSetupSelectAccountsStepRevamp.module.scss'; -import { useTranslate } from '@src/ui/hooks'; import { Input } from '@lace/common'; import { Box, SelectGroup } from '@lace/ui'; import { WalletTimelineSteps } from '../WalletSetup'; import { WalletSetupStepLayoutRevamp } from './WalletSetupStepLayoutRevamp'; +import { useTranslation } from 'react-i18next'; const INITIAL_WALLET_NAME = 'Wallet 1'; const nameShouldHaveRightLengthRegex = /^.{1,20}$/; @@ -29,7 +29,7 @@ export const WalletSetupSelectAccountsStepRevamp = ({ const [selectedAccount, setSelectedAccount] = useState('0'); const [walletName, setWalletName] = useState(INITIAL_WALLET_NAME); const [isDirty, setIsDirty] = useState(false); - const { t } = useTranslate(); + const { t } = useTranslation(); const isNameValid = useMemo(() => validateName(walletName), [walletName]); diff --git a/packages/core/src/ui/components/WalletSetupRevamp/WalletSetupStepLayoutRevamp.tsx b/packages/core/src/ui/components/WalletSetupRevamp/WalletSetupStepLayoutRevamp.tsx index 0396e0677..672c97739 100644 --- a/packages/core/src/ui/components/WalletSetupRevamp/WalletSetupStepLayoutRevamp.tsx +++ b/packages/core/src/ui/components/WalletSetupRevamp/WalletSetupStepLayoutRevamp.tsx @@ -4,9 +4,9 @@ import cn from 'classnames'; import { Button, Timeline } from '@lace/common'; import { Tooltip } from 'antd'; import { urls } from '@ui/utils/constants'; -import { useTranslate } from '@ui/hooks'; -import i18n from '@ui/lib/i18n'; +import { i18n } from '@lace/translation'; import { WalletTimelineSteps } from '../WalletSetup'; +import { useTranslation } from 'react-i18next'; export interface WalletSetupStepLayoutRevampProps { title: React.ReactNode; @@ -67,7 +67,7 @@ export const WalletSetupStepLayoutRevamp = ({ currentTimelineStep, isHardwareWallet = false }: WalletSetupStepLayoutRevampProps): React.ReactElement => { - const { t } = useTranslate(); + const { t } = useTranslation(); const nextButtonContainerRef = useRef(null); const defaultLabel = { diff --git a/packages/core/src/ui/hooks/index.ts b/packages/core/src/ui/hooks/index.ts index e0cbd2ca0..752f81f10 100644 --- a/packages/core/src/ui/hooks/index.ts +++ b/packages/core/src/ui/hooks/index.ts @@ -1,4 +1,3 @@ export * from './usePriceFetcher'; -export * from './useTranslate'; export * from './useOnClickOutside'; export * from './useDialogWithData'; diff --git a/packages/core/src/ui/hooks/useTranslate.tsx b/packages/core/src/ui/hooks/useTranslate.tsx deleted file mode 100644 index 773093b4a..000000000 --- a/packages/core/src/ui/hooks/useTranslate.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { useCallback, useEffect } from 'react'; -import i18n, { StringMap, TOptions } from 'i18next'; -import { useTranslation, setI18n, Trans } from 'react-i18next'; -import fallbackInstance from '../lib/i18n'; - -// If no i18n instance found in context then use the local one -setI18n(fallbackInstance); - -export interface UseTranslate { - t: (key: string | string[], defaultValue?: string, options?: TOptions) => string; - Trans: typeof Trans; - i18n: typeof i18n; -} - -export const useTranslate = (args: Parameters = []): UseTranslate => { - const { i18n: i18nInstance } = useTranslation(...args); - - useEffect(() => { - fallbackInstance.init(); - if (!i18nInstance?.isInitialized) i18nInstance.init(); - }, [i18nInstance]); - - const t = useCallback( - (key: string | string[], defaultValue?: string, options?: TOptions) => { - // If key not found in the current i18n instance tries to find it in the fallback one - if (!i18nInstance.exists(key, options) && fallbackInstance.exists(key, options)) { - return fallbackInstance.t(key, defaultValue, options); - } - return i18nInstance.t(key, defaultValue, options); - }, - [i18nInstance] - ); - - return { - t, - Trans: ({ children, ...props }) => ( - - {children} - - ), - i18n: i18nInstance - }; -}; diff --git a/packages/core/src/ui/lib/en.ts b/packages/core/src/ui/lib/en.ts deleted file mode 100644 index 56c185ac5..000000000 --- a/packages/core/src/ui/lib/en.ts +++ /dev/null @@ -1,3 +0,0 @@ -import enjson from './translations/en.json'; - -export const en = enjson; diff --git a/packages/core/src/ui/lib/i18n.ts b/packages/core/src/ui/lib/i18n.ts deleted file mode 100644 index 085975771..000000000 --- a/packages/core/src/ui/lib/i18n.ts +++ /dev/null @@ -1,28 +0,0 @@ -import i18n from 'i18next'; - -type I18NextResources = Partial>; - -export enum SupportedLanguages { - EN = 'en' -} - -const resources: I18NextResources = {}; -for (const lang of Object.values(SupportedLanguages)) { - Object.assign(resources, { - [lang]: { - translation: { ...require(`./translations/${lang}.json`) } - } - }); -} - -// Create i18n instance with translations from this package -export default i18n.createInstance({ - fallbackLng: 'en', - interpolation: { escapeValue: false }, - lng: 'en', - resources, - react: { - useSuspense: false, - transSupportBasicHtmlNodes: true - } -}); diff --git a/packages/core/src/ui/lib/index.ts b/packages/core/src/ui/lib/index.ts index 67574ef62..2466ac845 100644 --- a/packages/core/src/ui/lib/index.ts +++ b/packages/core/src/ui/lib/index.ts @@ -1,2 +1 @@ export * from './axios'; -export * as translations from './en'; diff --git a/packages/core/src/ui/typings/i18next.d.ts b/packages/core/src/ui/typings/i18next.d.ts new file mode 100644 index 000000000..9504b1ac7 --- /dev/null +++ b/packages/core/src/ui/typings/i18next.d.ts @@ -0,0 +1,10 @@ +import 'i18next'; +import type { Translations } from '@lace/translation'; + +declare module 'i18next' { + interface CustomTypeOptions { + resources: { + translation: Translations; + }; + } +} diff --git a/packages/core/src/ui/utils/render-address-tag.tsx b/packages/core/src/ui/utils/render-address-tag.tsx index 1b3bb9a3b..75d05e38d 100644 --- a/packages/core/src/ui/utils/render-address-tag.tsx +++ b/packages/core/src/ui/utils/render-address-tag.tsx @@ -1,10 +1,10 @@ import * as React from 'react'; import { AddressTag, AddressTagVariants } from '@lace/ui'; -import { UseTranslate } from '@ui/hooks'; +import type { TFunction } from 'i18next'; export type AddressTagTranslations = { own: string; foreign: string }; -export const getAddressTagTranslations = (t: UseTranslate['t']): AddressTagTranslations => ({ +export const getAddressTagTranslations = (t: TFunction): AddressTagTranslations => ({ own: t('core.addressTags.own'), foreign: t('core.addressTags.foreign') }); diff --git a/packages/e2e-tests/src/utils/translationService.ts b/packages/e2e-tests/src/utils/translationService.ts index d34209a58..44f11f81f 100644 --- a/packages/e2e-tests/src/utils/translationService.ts +++ b/packages/e2e-tests/src/utils/translationService.ts @@ -8,14 +8,17 @@ type Translations = { [index: string]: any }; const loadTranslations = async function (translationOrigin: TranslationsOrigin) { const language = process.env.LACE_LOCALE ?? 'en'; - const extensionTranslationPath = `../../../../apps/browser-extension-wallet/src/lib/translations/${language}.json`; - const coreTranslationPath = `../../../../packages/core/dist/translations/${language}.json`; + const extensionTranslationPath = `../../../../packages/translation/src/lib/translations/browser-extension-wallet/${language}.json`; + const coreTranslationPath = `../../../../packages/translation/src/lib/translations/core/${language}.json`; + const cardanoTranslationPath = `../../../../packages/translation/src/lib/translations/cardano/${language}.json`; const extension: Translations = await flatten( JSON.parse(readFromFile(__dirname, extensionTranslationPath).toString()) ); const core: Translations = await flatten(JSON.parse(readFromFile(__dirname, coreTranslationPath).toString())); + const cardano: Translations = await flatten(JSON.parse(readFromFile(__dirname, cardanoTranslationPath).toString())); const baseTranslations = { + ...cardano, ...core, ...extension }; diff --git a/packages/staking/.storybook/preview.tsx b/packages/staking/.storybook/preview.tsx index 3daab8044..561c5648a 100644 --- a/packages/staking/.storybook/preview.tsx +++ b/packages/staking/.storybook/preview.tsx @@ -2,6 +2,7 @@ import React from 'react'; import type { Preview, Decorator } from '@storybook/react'; // @ts-ignore import { StakingStorybookProvider } from './StakingStorybookProvider'; +import '@lace/translation'; const wrapWith = (Component: React.FunctionComponent): Decorator => diff --git a/packages/staking/package.json b/packages/staking/package.json index 7be4ea882..1654c1f3e 100644 --- a/packages/staking/package.json +++ b/packages/staking/package.json @@ -53,6 +53,7 @@ "@lace/common": "^0.1.0", "@lace/core": "0.1.0", "@lace/icons": "0.1.0", + "@lace/translation": "^0.1.0", "@lace/ui": "^0.1.0", "@radix-ui/react-slider": "^1.1.2", "@vanilla-extract/css": "^1.11.1", diff --git a/packages/staking/src/features/BrowsePools/BrowsePoolsPreferencesCard/BrowsePoolsPreferencesCardContainer.tsx b/packages/staking/src/features/BrowsePools/BrowsePoolsPreferencesCard/BrowsePoolsPreferencesCardContainer.tsx index 109a93a32..59f7b7b61 100644 --- a/packages/staking/src/features/BrowsePools/BrowsePoolsPreferencesCard/BrowsePoolsPreferencesCardContainer.tsx +++ b/packages/staking/src/features/BrowsePools/BrowsePoolsPreferencesCard/BrowsePoolsPreferencesCardContainer.tsx @@ -1,4 +1,4 @@ -import { initI18n } from 'features/i18n'; +import '@lace/translation'; import { StakingPage } from 'features/staking'; import { SetupBase } from 'features/staking/Setup/SetupBase'; import { PoolsFilter, QueryStakePoolsFilters, activePageSelector, useDelegationPortfolioStore } from 'features/store'; @@ -6,7 +6,6 @@ import { useState } from 'react'; import { useQueryStakePools } from '../hooks'; import { BrowsePoolsPreferencesCard } from './BrowsePoolsPreferencesCard'; import { SortAndFilterTab } from './types'; -initI18n(); export const BrowsePoolsPreferencesCardContainer = ({ theme }: { theme: 'light' | 'dark' }) => { const activePage = useDelegationPortfolioStore(activePageSelector); diff --git a/packages/staking/src/features/DelegationCard/DelegationCard.tsx b/packages/staking/src/features/DelegationCard/DelegationCard.tsx index 70ab78868..a56af18bb 100644 --- a/packages/staking/src/features/DelegationCard/DelegationCard.tsx +++ b/packages/staking/src/features/DelegationCard/DelegationCard.tsx @@ -1,8 +1,8 @@ +import { TranslationKey } from '@lace/translation'; import { Card, PIE_CHART_DEFAULT_COLOR_SET, PieChart, PieChartColor, PieChartGradientColor, Text } from '@lace/ui'; import cn from 'classnames'; import { Fragment, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import { TranslationKey } from '../i18n'; import { PERCENTAGE_SCALE_MAX, sumPercentagesSanitized } from '../store'; import * as styles from './DelegationCard.css'; import { DelegationTooltip } from './DelegationTooltip'; diff --git a/packages/staking/src/features/i18n/i18n.ts b/packages/staking/src/features/i18n/i18n.ts deleted file mode 100644 index eefe114b8..000000000 --- a/packages/staking/src/features/i18n/i18n.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Language } from '@lace/common'; -import { createInstance, i18n } from 'i18next'; -import { initReactI18next } from 'react-i18next'; -import { en } from './translations'; - -let i18nInstance: i18n; - -export const getI18n = () => { - if (!i18nInstance) throw new Error('i18n instance not initialized'); - return i18nInstance; -}; - -export const initI18n = () => { - if (i18nInstance) return; - - i18nInstance = createInstance(); - i18nInstance.use(initReactI18next).init({ - fallbackLng: Language.en, - interpolation: { - escapeValue: false, // not needed for react as it escapes by default - }, - lng: Language.en, - resources: { - [Language.en]: { - translation: en, - }, - }, - supportedLngs: Object.values(Language), - }); -}; - -export const changeLanguage = async (language: Language) => { - if (!Object.values(Language).includes(language)) { - throw new Error(`Attempted to switch to unsupported language "${language}"`); - } - console.debug(`Changing language to "${language}"`); - - await getI18n().changeLanguage(language); -}; diff --git a/packages/staking/src/features/i18n/index.ts b/packages/staking/src/features/i18n/index.ts deleted file mode 100644 index 644f760bb..000000000 --- a/packages/staking/src/features/i18n/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { changeLanguage, getI18n, initI18n } from './i18n'; -export type { TranslationKey } from './types'; diff --git a/packages/staking/src/features/overview/StakingInfoCard/StakingInfoCard.tsx b/packages/staking/src/features/overview/StakingInfoCard/StakingInfoCard.tsx index a9276fa36..244161f1d 100644 --- a/packages/staking/src/features/overview/StakingInfoCard/StakingInfoCard.tsx +++ b/packages/staking/src/features/overview/StakingInfoCard/StakingInfoCard.tsx @@ -1,6 +1,7 @@ import Icon from '@ant-design/icons'; import { Wallet } from '@lace/cardano'; import { getRandomIcon } from '@lace/common'; +import { TranslationKey } from '@lace/translation'; import { Flex } from '@lace/ui'; import BigNumber from 'bignumber.js'; import cn from 'classnames'; @@ -8,7 +9,6 @@ import React, { ReactNode } from 'react'; import { useTranslation } from 'react-i18next'; import MoonIcon from '../../../assets/icons/moon.component.svg'; import WarningIcon from '../../../assets/icons/warning.component.svg'; -import { TranslationKey } from '../../i18n'; import { StakePoolInfo } from './StakePoolInfo'; import styles from './StakingInfoCard.module.scss'; import { Stats } from './Stats'; diff --git a/packages/staking/src/features/staking/Setup/Setup.tsx b/packages/staking/src/features/staking/Setup/Setup.tsx index ac70eaae3..63cdf4370 100644 --- a/packages/staking/src/features/staking/Setup/Setup.tsx +++ b/packages/staking/src/features/staking/Setup/Setup.tsx @@ -1,6 +1,6 @@ import { useObservable } from '@lace/common'; import { useBrowsePoolsPersistence } from 'features/BrowsePools'; -import { initI18n } from 'features/i18n'; +import '@lace/translation'; import { useOutsideHandles } from 'features/outside-handles-provider'; import { useDelegationPortfolioStore } from 'features/store'; import { useEffect } from 'react'; @@ -8,8 +8,6 @@ import { StakingProps } from '../types'; import { SetupBase, SetupBaseProps } from './SetupBase'; import '../reset.css'; -initI18n(); - type SetupProps = Omit & Pick & { view: 'popup' | 'expanded'; diff --git a/packages/staking/src/features/staking/Setup/SetupBase.tsx b/packages/staking/src/features/staking/Setup/SetupBase.tsx index 127f17dab..3a07a1501 100644 --- a/packages/staking/src/features/staking/Setup/SetupBase.tsx +++ b/packages/staking/src/features/staking/Setup/SetupBase.tsx @@ -1,27 +1,25 @@ +import { i18n } from '@lace/translation'; import { ThemeColorScheme, ThemeProvider } from '@lace/ui'; import { Skeleton } from 'antd'; -import { PropsWithChildren } from 'react'; +import { PropsWithChildren, Suspense } from 'react'; import { I18nextProvider } from 'react-i18next'; -import { initI18n } from '../../i18n'; -import { StakingProps } from '../types'; -import { useI18n } from './useI18n'; -import 'features/theme'; -initI18n(); +import { StakingProps } from '../types'; export type SetupBaseProps = Omit, 'currentChain'> & { loading?: boolean; }; -export const SetupBase = ({ language, loading, theme, children }: SetupBaseProps) => { - const i18n = useI18n(language); +export const SetupBase = ({ loading, theme, children }: SetupBaseProps) => { const themeColorScheme = theme === 'light' ? ThemeColorScheme.Light : ThemeColorScheme.Dark; return ( - - - {children} - - + }> + + + {children} + + + ); }; diff --git a/packages/staking/src/features/staking/Setup/useI18n.test.ts b/packages/staking/src/features/staking/Setup/useI18n.test.ts deleted file mode 100644 index 856a1791c..000000000 --- a/packages/staking/src/features/staking/Setup/useI18n.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* eslint-disable no-magic-numbers */ -import { Language } from '@lace/common'; -import { renderHook } from '@testing-library/react-hooks'; -import { i18n } from 'i18next'; -import { expect, vi } from 'vitest'; -import { changeLanguage, getI18n } from '../../i18n'; -import { useI18n } from './useI18n'; - -vi.mock('../../i18n', () => ({ - changeLanguage: vi.fn(), - getI18n: vi.fn(), -})); - -describe('useI18n hook', () => { - it('does not change the language if it is not provided', () => { - const i18nInstance = { - language: 'en', - } as i18n; - vi.mocked(getI18n).mockReturnValue(i18nInstance); - renderHook(() => useI18n()); - expect(changeLanguage).not.toHaveBeenCalled(); - }); - - it('changes the language only if it is different from the current language', () => { - const i18nInstance = { - language: 'en', - } as i18n; - vi.mocked(getI18n).mockReturnValue(i18nInstance); - - renderHook(() => useI18n(Language.en)); - expect(changeLanguage).not.toHaveBeenCalled(); - - renderHook(() => useI18n('pl' as Language)); - expect(changeLanguage).toHaveBeenNthCalledWith(1, 'pl' as Language); - }); - - it('returns loading property indicating the language change is in pogress', async () => { - const i18nInstance = { - language: 'en', - } as i18n; - vi.mocked(getI18n).mockReturnValue(i18nInstance); - - // eslint-disable-next-line unicorn/consistent-function-scoping, @typescript-eslint/no-empty-function - let resolveChangeLanguagePromise = () => {}; - vi.mocked(changeLanguage).mockReturnValue( - new Promise((resolve) => { - resolveChangeLanguagePromise = resolve; - }) - ); - - const run1 = renderHook(() => useI18n()); - expect(run1.result.current.loading).toEqual(false); - - const run2 = renderHook(() => useI18n('pl' as Language)); - expect(run2.result.current.loading).toEqual(true); - - resolveChangeLanguagePromise(); - await run2.waitForNextUpdate(); - expect(run2.result.current.loading).toEqual(false); - }); -}); diff --git a/packages/staking/src/features/staking/Setup/useI18n.ts b/packages/staking/src/features/staking/Setup/useI18n.ts deleted file mode 100644 index 9c0667e15..000000000 --- a/packages/staking/src/features/staking/Setup/useI18n.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Language } from '@lace/common'; -import { useEffect, useState } from 'react'; -import { changeLanguage, getI18n } from '../../i18n'; - -export const useI18n = (language?: Language) => { - const [loading, setLoading] = useState(true); - const i18n = getI18n(); - - useEffect(() => { - (async () => { - if (language && i18n.language !== language) { - setLoading(true); - await changeLanguage(language); - } - - setLoading(false); - })(); - }, [i18n.language, language]); - - return { - i18n, - loading, - }; -}; diff --git a/packages/staking/src/features/staking/types.ts b/packages/staking/src/features/staking/types.ts index 8c32c6412..91605a480 100644 --- a/packages/staking/src/features/staking/types.ts +++ b/packages/staking/src/features/staking/types.ts @@ -1,5 +1,5 @@ import { Wallet } from '@lace/cardano'; -import { Language } from '@lace/common'; +import { Language } from '@lace/translation'; export type StakingProps = { currentChain: Wallet.Cardano.ChainId; diff --git a/packages/staking/src/typings/i18next.d.ts b/packages/staking/src/typings/i18next.d.ts index d8a9388ac..9504b1ac7 100644 --- a/packages/staking/src/typings/i18next.d.ts +++ b/packages/staking/src/typings/i18next.d.ts @@ -1,5 +1,5 @@ import 'i18next'; -import { Translations } from '../features/i18n/types'; +import type { Translations } from '@lace/translation'; declare module 'i18next' { interface CustomTypeOptions { diff --git a/packages/translation/.eslintignore b/packages/translation/.eslintignore new file mode 100644 index 000000000..d2a686915 --- /dev/null +++ b/packages/translation/.eslintignore @@ -0,0 +1,2 @@ +dist/** +rollup.config.js diff --git a/packages/translation/.eslintrc.js b/packages/translation/.eslintrc.js new file mode 100644 index 000000000..f08e71cc6 --- /dev/null +++ b/packages/translation/.eslintrc.js @@ -0,0 +1,226 @@ +const path = require('node:path'); + +module.exports = { + $schema: 'https://json.schemastore.org/eslintrc.json', + root: true, + extends: [ + 'plugin:react/recommended', + 'plugin:unicorn/recommended', + 'plugin:storybook/recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'plugin:@typescript-eslint/strict', + 'plugin:functional/external-typescript-recommended', + 'plugin:functional/lite', + 'plugin:functional/stylistic', + 'prettier', + 'plugin:prettier/recommended', + ], + parser: '@typescript-eslint/parser', + parserOptions: { + project: ['./tsconfig.eslint.json'], + tsconfigRootDir: path.resolve(__dirname), + }, + plugins: [ + 'eslint-plugin-import', + 'prefer-arrow-functions', + '@typescript-eslint', + 'functional', + 'prettier', + ], + settings: { + // Fixes eslint not being able to detect react version + react: { pragma: 'React', fragment: 'Fragment', version: 'detect' }, + }, + rules: { + 'max-params': ['error', 2], + 'no-void': 'off', + 'prettier/prettier': 'error', + 'import/no-default-export': 'error', + 'react/no-multi-comp': 'error', + 'prefer-arrow-functions/prefer-arrow-functions': 'error', + 'import/order': [ + 'error', + { + groups: [ + 'builtin', + 'external', + 'internal', + 'parent', + 'sibling', + 'index', + 'object', + 'type', + ], + pathGroups: [ + { + pattern: 'react', + group: 'builtin', + }, + { + pattern: 'react', + group: 'builtin', + }, + { + pattern: '@storybook/**', + group: 'external', + }, + ], + alphabetize: { + order: 'asc', + caseInsensitive: true, + }, + 'newlines-between': 'always', + pathGroupsExcludedImportTypes: ['react'], + }, + ], + 'unicorn/prevent-abbreviations': [ + 'error', + { + allowList: { + Props: true, + props: true, + args: true, + vars: true, + createVar: true, + ref: true, + }, + replacements: { + s: { + currentState: true, + }, + }, + }, + ], + '@typescript-eslint/consistent-type-imports': 'error', + '@typescript-eslint/consistent-type-exports': 'error', + '@typescript-eslint/explicit-function-return-type': 'error', + '@typescript-eslint/explicit-member-accessibility': [ + 'error', + { + accessibility: 'explicit', + overrides: { + parameterProperties: 'no-public', + }, + }, + ], + '@typescript-eslint/explicit-module-boundary-types': 'error', + '@typescript-eslint/member-ordering': 'error', + '@typescript-eslint/naming-convention': [ + 'error', + { + selector: 'variable', + types: ['boolean'], + format: ['PascalCase'], + prefix: ['is', 'should', 'has', 'can', 'did', 'will'], + }, + ], + '@typescript-eslint/no-confusing-void-expression': 'error', + '@typescript-eslint/no-redundant-type-constituents': 'error', + '@typescript-eslint/no-require-imports': 'error', + '@typescript-eslint/no-type-alias': [ + 'off', + { + allowGenerics: 'always', + allowAliases: 'always', + allowMappedTypes: 'in-unions-and-intersections', + }, + ], + '@typescript-eslint/no-unused-vars': 'error', + '@typescript-eslint/prefer-enum-initializers': 'error', + '@typescript-eslint/prefer-readonly': 'error', + '@typescript-eslint/promise-function-async': 'error', + '@typescript-eslint/sort-type-constituents': 'error', + '@typescript-eslint/strict-boolean-expressions': 'error', + '@typescript-eslint/switch-exhaustiveness-check': 'error', + 'functional/immutable-data': [ + 'error', + { + ignoreAccessorPattern: [ + 'draft.*', + '**.parameters', + '**.play', + '**.argTypes', + '**.args', + ], + }, + ], + 'functional/functional-parameters': 'off', + 'functional/no-mixed-types': 'off', + 'functional/no-return-void': 'off', + 'functional/no-expression-statements': 'off', + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['*design-system/*/*'], + message: 'usage of design system private modules not allowed.', + }, + { + group: ['*design-tokens/*'], + message: 'usage of design tokens private modules not allowed.', + }, + { + group: ['*types/*'], + message: 'usage of types private modules not allowed.', + }, + ], + }, + ], + }, + overrides: [ + { + files: [ + 'index.js', + '.eslintrc.js', + 'rollup.config.js', + '.storybook/*.js', + ], + rules: { + 'unicorn/prefer-module': ['off'], + '@typescript-eslint/no-unsafe-assignment': ['off'], + '@typescript-eslint/no-var-requires': ['off'], + '@typescript-eslint/no-unsafe-call': ['off'], + '@typescript-eslint/require-await': ['off'], + '@typescript-eslint/no-require-imports': ['off'], + 'functional/no-expression-statements': ['off'], + 'functional/immutable-data': ['off'], + '@typescript-eslint/strict-boolean-expressions': ['off'], + '@typescript-eslint/explicit-module-boundary-types': ['off'], + '@typescript-eslint/explicit-function-return-type': ['off'], + 'import/no-default-export': ['off'], + '@typescript-eslint/no-unsafe-member-access': ['off'], + '@typescript-eslint/no-unsafe-return': ['off'], + }, + }, + { + files: ['*.spec.tsx', '*.spec.ts'], + rules: { + 'functional/no-expression-statements': ['off'], + 'functional/no-return-void': ['off'], + }, + }, + { + files: ['jest.config.js'], + rules: { + '@typescript-eslint/restrict-template-expressions': ['off'], + '@typescript-eslint/no-unsafe-call': ['off'], + 'unicorn/prefer-module': ['off'], + 'functional/immutable-data': [ + 'error', + { + ignorePattern: 'module.exports', + }, + ], + }, + }, + { + files: ['src/**/*.stories.tsx'], + rules: { + 'react/no-multi-comp': ['off'], + 'import/no-default-export': ['off'], + }, + }, + ], +}; diff --git a/packages/translation/.gitignore b/packages/translation/.gitignore new file mode 100644 index 000000000..36ea6c51a --- /dev/null +++ b/packages/translation/.gitignore @@ -0,0 +1,2 @@ +# Do not ignore the following +!*.d.ts diff --git a/packages/translation/.prettierrc.js b/packages/translation/.prettierrc.js new file mode 100644 index 000000000..6d0050026 --- /dev/null +++ b/packages/translation/.prettierrc.js @@ -0,0 +1,6 @@ +module.exports = { + arrowParens: 'avoid', + bracketSpacing: true, + singleQuote: true, + trailingComma: 'all', +}; diff --git a/packages/translation/README.md b/packages/translation/README.md new file mode 100644 index 000000000..b5c7d1596 --- /dev/null +++ b/packages/translation/README.md @@ -0,0 +1,53 @@ +# Lace UI toolkit + +## Getting Started + +First, install the dependencies: + +```bash +yarn install --frozen-lockfile +``` + +## Storybook + +Storybook is used for development + +```bash +yarn storybook +``` + +### Stories format + +| Type | PURPOSE | +| ------------ | :-----------------------------------------------------------------------: | +| Overview | Dumb components presented as 1:1 parity from Figma file | +| Interactions | Used for testing and to simulate user interactions | +| Controls | Interact with a component's arguments dynamically without needing to code | + +### Docs + +Make sure to export `components` and `subcomponents` so they are displayed in the `Docs` tab. + +```jsx +export default { + title: 'List & tables/Assets table', + component: AssetsTable, + subcomponents: { + TokenProfile, + TokenAmount, + MarketPrice, + } +} as Meta; +``` + +## File naming convention + +| FILES | PURPOSE | +| ---------------- | :----------------------------------------------------------------------------: | +| \*.index.ts | Defines the public API to be imported by other modules | +| \*.component.tsx | Defines the UI component | +| \*.css.ts | Vanilla-extract CSS files | +| \*.stories.ts | Storybook files | +| \*.data.ts | Defines the data/types representation of the UI component or application logic | +| \*.context.ts | Defines the UI component's inner state to be consumed by nested children | +| \*.hooks.ts | Defines methods to manipulate the context state | diff --git a/packages/translation/package.json b/packages/translation/package.json new file mode 100644 index 000000000..423075ee5 --- /dev/null +++ b/packages/translation/package.json @@ -0,0 +1,50 @@ +{ + "name": "@lace/translation", + "version": "0.1.0", + "description": "Lace Transaction Package", + "homepage": "https://github.com/input-output-hk/lace/blob/master/packages/translation/README.md", + "bugs": { + "url": "https://github.com/input-output-hk/lace/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/input-output-hk/lace.git" + }, + "license": "Apache-2.0", + "author": "IOHK", + "main": "dist/index.js", + "module": "dist/index.esm.js", + "typings": "dist/index.d.ts", + "scripts": { + "build": "run -T rollup -c rollup.config.js", + "cleanup": "yarn exec rm -rf dist node_modules", + "format": "yarn prettier --write '**/*.(tsx|ts)'", + "lint": "eslint .", + "test": "echo \"@lace/ui: no test specified\"", + "typecheck": "tsc --noEmit", + "watch": "yarn build --watch" + }, + "dependencies": { + "i18next": "^22.5.1", + "react-i18next": "^12.3.1" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "20.0.0", + "@rollup/plugin-json": "^6.0.0", + "@rollup/plugin-typescript": "^11.1.1", + "@typescript-eslint/eslint-plugin": "^5.51.0", + "@typescript-eslint/parser": "^5.51.0", + "eslint": "8.33.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-boundaries": "^3.1.0", + "eslint-plugin-functional": "^5.0.4", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-max-params-no-constructor": "^0.0.4", + "eslint-plugin-prefer-arrow-functions": "^3.1.4", + "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-react": "7.31.8", + "eslint-plugin-storybook": "^0.6.11", + "eslint-plugin-unicorn": "^45.0.2", + "prettier": "3.2.5" + } +} diff --git a/packages/translation/rollup.config.js b/packages/translation/rollup.config.js new file mode 100644 index 000000000..f99b655f1 --- /dev/null +++ b/packages/translation/rollup.config.js @@ -0,0 +1,30 @@ +import commonjs from '@rollup/plugin-commonjs'; +import json from '@rollup/plugin-json'; +import typescript from '@rollup/plugin-typescript'; + +import packageJson from './package.json'; + +export default () => ({ + input: 'src/index.ts', + plugins: [ + typescript({ + tsconfig: './tsconfig.json', + composite: false, + }), + commonjs(), + json(), + ], + output: [ + { + file: packageJson.main, + format: 'cjs', + sourcemap: true, + }, + { + file: packageJson.module, + format: 'esm', + sourcemap: true, + }, + ], + external: [/node_modules/], +}); diff --git a/packages/translation/src/index.ts b/packages/translation/src/index.ts new file mode 100644 index 000000000..5f05ecf60 --- /dev/null +++ b/packages/translation/src/index.ts @@ -0,0 +1,3 @@ +export * from './types'; +export * from './lib/i18n'; +export { default as i18n } from './lib/i18n'; diff --git a/packages/translation/src/lib/i18n.ts b/packages/translation/src/lib/i18n.ts new file mode 100644 index 000000000..ac8227a8b --- /dev/null +++ b/packages/translation/src/lib/i18n.ts @@ -0,0 +1,44 @@ +/* eslint-disable unicorn/prefer-export-from */ +/* eslint-disable import/no-default-export */ +/* eslint-disable @typescript-eslint/no-floating-promises */ +/* eslint-disable functional/no-loop-statements */ +/* eslint-disable functional/immutable-data */ +import i18n from 'i18next'; +import { initReactI18next } from 'react-i18next'; + +import * as translations from './translations'; + +export enum Language { + en = 'en', +} + +type I18NextResources = Partial>; + +const DEFAULT_LANG = Language.en; + +const resources: I18NextResources = {}; +for (const lang of Object.values(Language)) { + Object.assign(resources, { + [lang]: { + translation: { + ...translations[lang], + }, + }, + }); +} + +i18n.use(initReactI18next).init({ + fallbackLng: DEFAULT_LANG, + interpolation: { + // not needed for react as it escapes by default + escapeValue: false, + }, + lng: Language.en, + resources, + react: { + useSuspense: false, + transSupportBasicHtmlNodes: true, + }, +}); + +export default i18n; diff --git a/apps/browser-extension-wallet/src/lib/translations/cookie-policy.en.ts b/packages/translation/src/lib/translations/browser-extension-wallet/cookie-policy.en.ts similarity index 99% rename from apps/browser-extension-wallet/src/lib/translations/cookie-policy.en.ts rename to packages/translation/src/lib/translations/browser-extension-wallet/cookie-policy.en.ts index 2943e36e7..810d1cfd1 100644 --- a/apps/browser-extension-wallet/src/lib/translations/cookie-policy.en.ts +++ b/packages/translation/src/lib/translations/browser-extension-wallet/cookie-policy.en.ts @@ -121,5 +121,5 @@ export const cookiePolicy = { Longmont, CO 80504
-` +`, }; diff --git a/apps/browser-extension-wallet/src/lib/translations/en.json b/packages/translation/src/lib/translations/browser-extension-wallet/en.json similarity index 61% rename from apps/browser-extension-wallet/src/lib/translations/en.json rename to packages/translation/src/lib/translations/browser-extension-wallet/en.json index 107ee9864..0c3d05168 100644 --- a/apps/browser-extension-wallet/src/lib/translations/en.json +++ b/packages/translation/src/lib/translations/browser-extension-wallet/en.json @@ -534,449 +534,6 @@ "browserView.walletSetup.mnemonicResetModal.header": "Are you sure you want to start again?", "browserView.walletSetup.support": "Help & Support", "browserView.welcome": "Welcome!", - "cardano.catalystConfirmationStep.confirmBody": "Please sign the voting registration transaction. This will link your wallet balance as proof of voting power. Funds will not leave your wallet, but requires a transaction fee, displayed at the bottom of the screen.", - "cardano.catalystConfirmationStep.confirmHeader": "Confirm the registration transaction", - "cardano.catalystConfirmationStep.register": "Register to vote in", - "cardano.catalystConfirmationStep.totalFee": "Total fee", - "cardano.catalystPinStep.confirmPin": "Confirm your PIN code", - "cardano.catalystPinStep.pinNotMatching": "PIN is not matching", - "cardano.catalystPinStep.resetPin": "Reset PIN?", - "cardano.catalystPinStep.setPin": "Set a PIN code. You'll need it everytime you want to access the Catalyst app and to vote", - "cardano.catalystRegistrationStep.registerNow": "In the Catalyst App, click on the 'Register now' button", - "cardano.catalystScanStep.body1": "The following QR code is the generated certificate required by the Catalyst App to be able to participate in the voting process of Cardano.", - "cardano.catalystScanStep.body2": "We strongly suggest to take a screenshot of the QR code as a backup. You won't be able to access it after clicking on 'Done'.", - "cardano.catalystScanStep.doneButton": "Done", - "cardano.catalystScanStep.downloadButton": "Download QR code", - "cardano.catalystScanStep.header": "Use the Catalyst Voting App to scan the QR code", - "cardano.currentCatalystFund.endOfRegistration": "until end of registration", - "cardano.general.cancelButton": "Cancel", - "cardano.general.confirmButton": "Confirm", - "cardano.general.nextButton": "Next", - "cardano.networkInfo.averageMargin": "Average margin", - "cardano.networkInfo.averageRos": "Average ROS", - "cardano.networkInfo.currentEpoch": "Current epoch", - "cardano.networkInfo.epochEnd": "Epoch end", - "cardano.networkInfo.percentageStaked": "% Staked", - "cardano.networkInfo.title": "Network Info", - "cardano.networkInfo.totalPools": "Total pools", - "cardano.stakePoolMetricsBrowser.activeStake": "Active stake", - "cardano.stakePoolMetricsBrowser.blocks": "Blocks", - "cardano.stakePoolMetricsBrowser.cost": "Cost p/ epoch", - "cardano.stakePoolMetricsBrowser.delegators": "Delegators", - "cardano.stakePoolMetricsBrowser.liveStake": "Live stake", - "cardano.stakePoolMetricsBrowser.margin": "Pool margin", - "cardano.stakePoolMetricsBrowser.pledge": "Pledge", - "cardano.stakePoolMetricsBrowser.ros": "ROS", - "cardano.stakePoolMetricsBrowser.saturation": "Saturation", - "cardano.stakePoolSearch.gettingSaturated": "This pool starts to be saturated", - "cardano.stakePoolSearch.overSaturated": "This pool is over-saturated", - "cardano.stakePoolSearch.saturated": "This pool is saturated", - "cardano.stakePoolSearch.searchPlaceholder": "Search by ID or name", - "cardano.stakePoolSearch.staking": "You are staking on this pool", - "cardano.stakePoolStatusLogo.delegating": "You are delegating to this pool", - "cardano.stakePoolStatusLogo.retired": "This pool is retired. Re-delegate to an other pool to receive rewards", - "cardano.stakePoolStatusLogo.retiring": "This pool is retiring. Re-delegate to an other pool to avoid losing rewards", - "cardano.stakePoolStatusLogo.saturated": "This pool is too saturated. Stake on another pool to avoid losing rewards", - "cardano.stakePoolTableBrowser.tableHeader.blocks.title": "Blocks", - "cardano.stakePoolTableBrowser.tableHeader.blocks.tooltip": "Total blocks created by the pool.", - "cardano.stakePoolTableBrowser.tableHeader.cost.title": "Cost", - "cardano.stakePoolTableBrowser.tableHeader.cost.tooltip": "The cost is not directly paid by the delegator; they are deducted from a pool's rewards, consisting of a fixed cost and a variable cost, which fund the pool's operational costs", - "cardano.stakePoolTableBrowser.tableHeader.liveStake.title": "Live Stake", - "cardano.stakePoolTableBrowser.tableHeader.liveStake.tooltip": "Refers to the total amount of a cryptocurrency that is currently being staked in a particular staking pool", - "cardano.stakePoolTableBrowser.tableHeader.margin.title": "Margin", - "cardano.stakePoolTableBrowser.tableHeader.margin.tooltip": "The percentage of rewards taken by the stake pool operator after the fixed cost but before rewards are distributed", - "cardano.stakePoolTableBrowser.tableHeader.pledge.title": "Pledge", - "cardano.stakePoolTableBrowser.tableHeader.pledge.tooltip": "An amount of self‐bonded assets intended to remain staked to the pool for as long as it operates", - "cardano.stakePoolTableBrowser.tableHeader.ros.title": "ROS", - "cardano.stakePoolTableBrowser.tableHeader.ros.tooltip": "An estimation of the potential rewards you will earn per epoch if you delegate the intended amount of stake. The system looks at the pool's parameters and historical performance data to calculate potential rewards, assuming that the pool reaches optimal saturation.", - "cardano.stakePoolTableBrowser.tableHeader.saturation.title": "Saturation", - "cardano.stakePoolTableBrowser.tableHeader.saturation.tooltip": "Once a pool reaches the point of saturation, it will offer diminishing rewards", - "cardano.stakePoolTableBrowser.tableHeader.ticker.title": "Ticker", - "cardano.stakePoolTableBrowser.tableHeader.ticker.tooltip": "Refers to the unique identifier of a staking pool", - "cardano.stakingConfirmationInfo.delegateTo": "Delegate to", - "cardano.stakingConfirmationInfo.deposit": "Deposit", - "cardano.stakingConfirmationInfo.poolId": "Pool ID", - "cardano.stakingConfirmationInfo.transactionFee": "Transaction fee", - "cardano.votingParticipation.walletStatus": "Wallet status", - "cardano.waitForNextFundCard.message": "While waiting for the next fund you can register your wallet if it is not already done", - "cardano.waitForNextFundCard.phase0": "Phase 0", - "cardano.waitForNextFundCard.register": "Register", - "cardano.waitForNextFundCard.registered": "Registered", - "core.general.saveButton": "Save", - "core.general.cancelButton": "Cancel", - "core.addressForm.addAddress": "Add address", - "core.addressForm.name": "Name", - "core.addressForm.address": "Address", - "core.addressForm.addNew": "Add new address", - "core.addressForm.addNewSubtitle": "Save your favorite addresses to find them easily.", - "core.dapp.beta": "DApp connector Beta", - "core.authorizeDapp.warning": "Only connect to trusted DApps", - "core.authorizeDapp.nonssl": "This site is unsecured", - "core.authorizeDapp.nonsslTooltip": "This site does not follow common web standards", - "core.dappTransaction.transaction": "Transaction", - "core.dappTransaction.amount": "Amount", - "core.dappTransaction.fee": "Fee", - "core.dappTransaction.recipient": "Recipient", - "core.dappTransaction.insufficientFunds": "You do not have enough funds to complete the transaction", - "core.dappTransaction.signedSuccessfully": "The transaction was signed successfully.", - "core.dappTransaction.tryingToUseAssetNotInWallet": "This DApp is trying to use token not held in your wallet.", - "core.dappTransaction.noCollateral": "Wallet should not be able to sign dapp txs without collateral.", - "core.ProposalProcedures.title": "Confirm Governance Action", - "core.ProposalProcedure.dRepId": "DRep ID", - "core.ProposalProcedure.txDetails.deposit": "Deposit", - "core.ProposalProcedure.txDetails.rewardAccount": "Reward Account", - "core.ProposalProcedure.txDetails.title": "Transaction Details", - "core.ProposalProcedure.txDetails.txType": "Transaction Type", - "core.ProposalProcedure.procedure.anchor.hash": "Anchor Hash", - "core.ProposalProcedure.procedure.anchor.url": "Anchor URL", - "core.ProposalProcedure.procedure.title": "Procedure", - "core.ProposalProcedure.procedure.dRepId": "DRep ID", - "core.ProposalProcedure.governanceAction.actionId.title": "Action ID", - "core.ProposalProcedure.governanceAction.actionId.index": "Index", - "core.ProposalProcedure.governanceAction.actionId.txId": "TX ID", - "core.ProposalProcedure.governanceAction.hardForkInitiation.title": "Hard Fork Initiation", - "core.ProposalProcedure.governanceAction.hardForkInitiation.protocolVersion.major": "Protocol Version Major", - "core.ProposalProcedure.governanceAction.hardForkInitiation.protocolVersion.minor": "Protocol Version Minor", - "core.ProposalProcedure.governanceAction.hardForkInitiation.protocolVersion.patch": "Protocol Version Patch", - "core.ProposalProcedure.governanceAction.newConstitutionAction.title": "New Constitution Action", - "core.ProposalProcedure.governanceAction.newConstitutionAction.constitution.title": "Constitution Details", - "core.ProposalProcedure.governanceAction.newConstitutionAction.constitution.anchor.dataHash": "Anchor Data Hash", - "core.ProposalProcedure.governanceAction.newConstitutionAction.constitution.anchor.url": "Constitution Anchor URL", - "core.ProposalProcedure.governanceAction.newConstitutionAction.constitution.scriptHash": "Constitution Script Hash", - "core.ProposalProcedure.governanceAction.infoAction.title": "Info Action", - "core.ProposalProcedure.governanceAction.noConfidenceAction.title": "No Confidence", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.title": "Protocol Parameter Update", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.memory": "Memory", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.step": "Step", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.title": "Network Group", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxBBSize": "Max BB Size", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxTxSize": "Max Tx Size", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxBHSize": "Max BH Size", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxValSize": "Max Val Size", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxTxExUnits": "Max TX Ex Units", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxBlockExUnits": "Max BLK Ex Units", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxCollateralInputs": "Max Coll Inputs", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.tooltip.maxBBSize": "Max block body size", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.tooltip.maxTxSize": "Max transaction size", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.tooltip.maxBHSize": "Max block header size", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.tooltip.maxValSize": "Max size of a serialized asset value", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.tooltip.maxTxExUnits": "Max script execution units in a single transaction", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.tooltip.maxBlockExUnits": "Max script execution units in a single block", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.tooltip.maxCollateralInputs": "Max number of collateral inputs", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.title": "Economic Group", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.minFeeA": "Min Fee A", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.minFeeB": "Min Fee B", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.keyDeposit": "Key Deposit", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.poolDeposit": "Pool Deposit", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.rho": "Rho", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.tau": "Tau", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.minPoolCost": "Min Pool Cost", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.coinsPerUTxOByte": "Coins/UTxO Byte", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.prices": "Price", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.tooltip.minFeeA": "Min fee coefficient", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.tooltip.minFeeB": "Min fee constant", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.tooltip.keyDeposit": "Delegation key Lovelace deposit", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.tooltip.poolDeposit": "Pool registration Lovelace deposit", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.tooltip.rho": "Monetary expansion", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.tooltip.tau": "Treasury expansion", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.tooltip.minPoolCost": "Min fixed rewards cut for pools", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.tooltip.coinsPerUTxOByte": "Min Lovelace deposit per byte of serialized UTxO", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.tooltip.prices": "Prices of Plutus execution units", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.title": "Technical Group", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.a0": "A0", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.eMax": "EMax", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.nOpt": "NOpt", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.costModels": "Cost Models", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.PlutusV1": "PlutusV1", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.PlutusV2": "PlutusV2", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.collateralPercentage": "Coll Percentage", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.tooltip.a0": "Pool pledge influence", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.tooltip.eMax": "Pool retirement maximum epoch", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.tooltip.nOpt": "Desired number of pools", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.tooltip.costModels": "Plutus execution cost models", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.tooltip.collateralPercentage": "Proportion of collateral needed for scripts", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.title": "Governance Group", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.govActionLifetime": "Gov Act Lifetime", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.govActionDeposit": "Gov Act Deposit", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.drepDeposit": "DRep Deposit", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.drepActivity": "DRep Activity", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.ccMinSize": "CC Min Size", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.ccMaxTermLength": "CC Max Term Length", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.title": "Governance Voting Thresholds", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.motionNoConfidence": "Motion No Conf", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.committeeNormal": "Comm Normal", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.committeeNoConfidence": "Comm No Conf", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.updateConstitution": "Update Const", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.hardForkInitiation": "Hard Fork Init", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.ppNetworkGroup": "PP Network Grp", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.ppEconomicGroup": "PP Economic Grp", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.ppTechnicalGroup": "PP Technical Grp", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.ppGovernanceGroup": "PP Governance Grp", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.treasuryWithdrawal": "Treasury Withdraw", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.govActionLifetime": "governance action maximum lifetime in epochs", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.govActionDeposit": "governance action deposit", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.drepDeposit": "DRep deposit amount", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.drepActivity": "DRep activity period in epochs", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.ccMinSize": "Min constitutional committee size", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.ccMaxTermLength": "Max term length (in epochs) for the constitutional committee members", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.dRepVotingThresholds.title": "Governance voting thresholds", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.dRepVotingThresholds.motionNoConfidence": "1. Motion of no-confidence", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.dRepVotingThresholds.committeeNormal": "2a. New committee/threshold (normal state)", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.dRepVotingThresholds.committeeNoConfidence": "2b. New committee/threshold (state of no-confidence)", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.dRepVotingThresholds.updateConstitution": "3. Update to the Constitution or proposal policy", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.dRepVotingThresholds.hardForkInitiation": "4. Hard-fork initiation", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.dRepVotingThresholds.ppNetworkGroup": "5a. Protocol parameter changes, network group", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.dRepVotingThresholds.ppEconomicGroup": "5b. Protocol parameter changes, economic group", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.dRepVotingThresholds.ppTechnicalGroup": "5c. Protocol parameter changes, technical group", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.dRepVotingThresholds.ppGovernanceGroup": "5d. Protocol parameter changes, governance group", - "core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.tooltip.dRepVotingThresholds.treasuryWithdrawal": "6. Treasury withdrawal", - "core.ProposalProcedure.governanceAction.treasuryWithdrawals.title": "Treasury Withdrawals", - "core.ProposalProcedure.governanceAction.treasuryWithdrawals.withdrawals.lovelace": "Withdrawal Amount", - "core.ProposalProcedure.governanceAction.treasuryWithdrawals.withdrawals.rewardAccount": "Withdrawal Reward Account", - "core.ProposalProcedure.governanceAction.updateCommitteeAction.title": "Update Committee Action", - "core.ProposalProcedure.governanceAction.updateCommitteeAction.membersToBeAdded.title": "Members To Be Added", - "core.ProposalProcedure.governanceAction.updateCommitteeAction.membersToBeAdded.coldCredential.hash": "Cold Credential Hash", - "core.ProposalProcedure.governanceAction.updateCommitteeAction.membersToBeAdded.coldCredential.epoch": "Epoch", - "core.ProposalProcedure.governanceAction.updateCommitteeAction.membersToBeRemoved.title": "Members To Be Removed", - "core.ProposalProcedure.governanceAction.updateCommitteeAction.membersToBeRemoved.hash": "Hash", - "core.ProposalProcedure.governanceAction.updateCommitteeAction.newQuorumThreshold.title": "New Quorum Threshold", - "core.ProposalProcedure.governanceAction.updateCommitteeAction.newQuorumThreshold.denominator": "Denominator", - "core.ProposalProcedure.governanceAction.updateCommitteeAction.newQuorumThreshold.numerator": "Numerator", - "core.VotingProcedures.title": "Confirm Vote", - "core.VotingProcedures.voterType": "Voter Type", - "core.VotingProcedures.procedureTitle": "Procedure", - "core.VotingProcedures.actionIdTitle": "Action ID", - "core.VotingProcedures.vote": "Vote", - "core.VotingProcedures.actionId.index": "Index", - "core.VotingProcedures.actionId.txHash": "TX Hash", - "core.VotingProcedures.anchor.hash": "Anchor Hash", - "core.VotingProcedures.anchor.url": "Anchor URL", - "core.VotingProcedures.dRepId": "DRep ID", - "core.VotingProcedures.voterTypes.constitutionalCommittee": "Constitutional Committee", - "core.VotingProcedures.voterTypes.spo": "SPO", - "core.VotingProcedures.voterTypes.drep": "DRep", - "core.VotingProcedures.votes.yes": "Yes", - "core.VotingProcedures.votes.no": "No", - "core.VotingProcedures.votes.abstain": "Abstain", - "core.VotingProcedures.NonRegisteredUserModal.title": "You're not a registered DRep", - "core.VotingProcedures.NonRegisteredUserModal.description": "Proceeding with this vote won't have any impact. Do you still want to proceed?", - "core.VotingProcedures.NonRegisteredUserModal.cta.ok": "Proceed anyway", - "core.VotingProcedures.NonRegisteredUserModal.cta.cancel": "Cancel", - "core.DRepRegistration.title": "Confirm DRep Registration", - "core.DRepRegistration.metadata": "Metadata", - "core.DRepRegistration.url": "URL", - "core.DRepRegistration.hash": "Hash", - "core.DRepRegistration.drepId": "DRep ID", - "core.DRepRegistration.depositPaid": "Deposit paid", - "core.DRepRetirement.title": "Confirm DRep Retirement", - "core.DRepRetirement.metadata": "Metadata", - "core.DRepRetirement.drepId": "DRep ID", - "core.DRepRetirement.depositReturned": "Deposit returned", - "core.DRepRetirement.drepIdMismatchScreen.title": "DRep ID mismatch", - "core.DRepRetirement.drepIdMismatchScreen.description": "The presented DRepID does not match your wallet's DRepID", - "core.DRepRetirement.drepIdMismatchScreen.cancel": "Cancel", - "core.DRepUpdate.title": "Confirm DRep Update", - "core.DRepUpdate.metadata": "Metadata", - "core.DRepUpdate.drepId": "DRep ID", - "core.DRepUpdate.url": "URL", - "core.DRepUpdate.hash": "Hash", - "core.VoteDelegation.title": "Confirm Vote Delegation", - "core.VoteDelegation.metadata": "Metadata", - "core.VoteDelegation.drepId": "DRep ID", - "core.VoteDelegation.alwaysAbstain": "Abstain", - "core.VoteDelegation.alwaysNoConfidence": "No Confidence", - "core.VoteDelegation.option": "Yes", - "core.StakeVoteDelegation.title": "Confirm Staking & Vote Delegation", - "core.StakeVoteDelegation.metadata": "Metadata", - "core.StakeVoteDelegation.drepId": "DRep ID", - "core.StakeVoteDelegation.alwaysAbstain": "Abstain", - "core.StakeVoteDelegation.alwaysNoConfidence": "No Confidence", - "core.StakeVoteDelegation.option": "Yes", - "core.StakeVoteDelegation.stakeKeyHash": "Stake Key Hash", - "core.StakeVoteDelegation.poolId": "Pool ID", - "core.StakeVoteDelegationRegistration.title": "Confirm Vote Delegation & Staking", - "core.StakeVoteDelegationRegistration.metadata": "Metadata", - "core.StakeVoteDelegationRegistration.drepId": "DRep ID", - "core.StakeVoteDelegationRegistration.alwaysAbstain": "Abstain", - "core.StakeVoteDelegationRegistration.alwaysNoConfidence": "No Confidence", - "core.StakeVoteDelegationRegistration.option": "Yes", - "core.StakeVoteDelegationRegistration.stakeKeyHash": "Stake Key Hash", - "core.StakeVoteDelegationRegistration.poolId": "Pool ID", - "core.StakeVoteDelegationRegistration.depositPaid": "Deposit paid", - "core.StakeRegistrationDelegation.title": "Confirm Staking", - "core.StakeRegistrationDelegation.metadata": "Metadata", - "core.StakeRegistrationDelegation.stakeKeyHash": "Stake Key Hash", - "core.StakeRegistrationDelegation.poolId": "Pool ID", - "core.StakeRegistrationDelegation.depositPaid": "Deposit paid", - "core.VoteRegistrationDelegation.title": "Confirm Vote Delegation", - "core.VoteRegistrationDelegation.metadata": "Metadata", - "core.VoteRegistrationDelegation.drepId": "DRep ID", - "core.VoteRegistrationDelegation.alwaysAbstain": "Abstain", - "core.VoteRegistrationDelegation.alwaysNoConfidence": "No Confidence", - "core.VoteRegistrationDelegation.option": "Yes", - "core.VoteRegistrationDelegation.stakeKeyHash": "Stake Key Hash", - "core.VoteRegistrationDelegation.depositPaid": "Deposit paid", - "core.Mint.title": "Confirm transaction", - "core.Burn.title": "Confirm transaction", - "core.Send.title": "Confirm transaction", - "core.destinationAddressInput.recipientAddress": "Recipient's address or $handle", - "core.editAddressForm.walletName": "Wallet name", - "core.editAddressForm.address": "Recipient’s address or $handle", - "core.editAddressForm.submissionError": "Address could not be submitted", - "core.editAddressForm.doneButton": "Done", - "core.infoWallet.copy": "Copy", - "core.infoWallet.addressCopied": "Address copied", - "core.infoWallet.handleCopied": "Handle copied", - "core.nftDetail.title": "NFT detail", - "core.nftDetail.tokenInformation": "Token Information", - "core.nftDetail.attributes": "Attributes", - "core.nftDetail.sendNFT": "Send NFT", - "core.nftDetail.directory": "Folder", - "core.outputSummaryList.recipientAddress": "Recipient address", - "core.outputSummaryList.sending": "Sending", - "core.outputSummaryList.txFee": "Transaction fee", - "core.outputSummaryList.metaData": "Metadata", - "core.outputSummaryList.deposit": "Deposit", - "core.outputSummaryList.output": "Bundle", - "core.outputSummaryList.expiresBy": "Expires by", - "core.outputSummaryList.expiresByTooltip": "This transaction can be added to the blockchain until the specified time. After this, it will automatically expire and no longer be valid.", - "core.outputSummaryList.noLimit": "No limit", - "core.outputSummaryList.utc": "UTC", - "core.sendReceive.send": "Send", - "core.sendReceive.receive": "Receive", - "core.coinInputSelection.assetSelection": "Select tokens or NFTs", - "core.coinInputSelection.tokens": "Tokens", - "core.coinInputSelection.nfts": "NFTs", - "core.walletAddressList.name": "Name", - "core.walletAddressList.address": "Recipient’s address or $handle", - "core.walletBasicInfo.balance": "Balance", - "core.walletAnalyticsInfo.title": "Help us improve your experience", - "core.walletAnalyticsInfo.description": "Please opt in to share your data with us. We'll collect anonymous analytics info from your browser extension to\n help us improve the quality and performance of Lace.", - "core.walletAnalyticsInfo.gotIt": "Got it", - "core.walletAnalyticsInfo.allowOptout": "Always allow you to opt-out via Settings", - "core.walletAnalyticsInfo.collectPrivateKeys": "Never collect private keys", - "core.walletAnalyticsInfo.collectIp": "Never collect your IP address", - "core.walletAnalyticsInfo.personalData": "Never sell your personal data", - "core.walletSetupConnectHardwareWalletStep.title": "Connect hardware wallet", - "core.walletSetupConnectHardwareWalletStep.subTitle": "Choose the brand of your hardware wallet.", - "core.walletSetupConnectHardwareWalletStep.subTitleFull": "Select your hardware wallet brand", - "core.walletSetupConnectHardwareWalletStep.supportedDevicesFull": "Lace supports Ledger Nano X, Nano S, Nano S Plus, and Trezor Model T", - "core.walletSetupConnectHardwareWalletStep.supportedDevices": "Lace is supporting Ledger Nano X, Nano S and Nano S Plus", - "core.walletSetupConnectHardwareWalletStep.connectDevice": "Just connect your device to your computer, unlock and open the Cardano app to hit continue.", - "core.walletSetupConnectHardwareWalletStep.connectDeviceFull": "Just connect your device to your computer and unlock it to continue. If you're using a Ledger device, make sure you open the Cardano App.", - "core.walletSetupConnectHardwareWalletStepRevamp.title": "Connect your device", - "core.walletSetupConnectHardwareWalletStepRevamp.subTitleLedgerOnly": "Lace supports Ledger Nano X, Nano S, Nano S Plus. Unlock your device and open the Cardano app.", - "core.walletSetupConnectHardwareWalletStepRevamp.subTitle": "Lace supports Ledger Nano X, Nano S, Nano S Plus, Trezor Model T. Unlock your device and for Ledger, open the Cardano app.", - "core.walletSetupConnectHardwareWalletStepRevamp.errorMessage.userGestureRequired": "It appears the page reload interrupted the search for connected hardware wallet devices.", - "core.walletSetupConnectHardwareWalletStepRevamp.errorMessage.devicePickerRejected": "No hardware wallet device was chosen.", - "core.walletSetupConnectHardwareWalletStepRevamp.errorMessage.deviceLocked": "Your hardware wallet device seems to be locked. Please unlock it to proceed.", - "core.walletSetupConnectHardwareWalletStepRevamp.errorMessage.deviceBusy": "Your hardware wallet device seems to be busy with some other App. Please ensure it is free to connect.", - "core.walletSetupConnectHardwareWalletStepRevamp.errorMessage.cardanoAppNotOpen": "Cardano App is not open on your hardware wallet device. Please open it to proceed.", - "core.walletSetupConnectHardwareWalletStepRevamp.errorMessage.generic": "Something went wrong. Please try again.", - "core.walletSetupConnectHardwareWalletStepRevamp.errorCta": "Try again", - "core.walletSetupCreateStep.title": "Creating your wallet", - "core.walletSetupCreateStep.description": "Confirm exporting your public key on your hardware wallet device to create your Lace wallet.", - "core.walletSetupRestoreStep.title": "Restoring your wallet", - "core.walletSetupMnemonicStep.writePassphrase": "Write down your secret passphrase", - "core.walletSetupMnemonicStep.enterPassphrase": "Enter your secret passphrase", - "core.walletSetupMnemonicStep.enterPassphraseDescription": "Please enter each word of your recovery phrase in the right order to verify it and recover your wallet.", - "core.walletSetupMnemonicStep.body": "Now let's check you've got the correct secret passphrase. Enter each word of your passphrase in the right order to verify it.", - "core.walletSetupMnemonicStep.passphraseInfo1": "Make sure you create an offline backup of your secret passphrase.", - "core.walletSetupMnemonicStep.passphraseInfo2": "Do not store your backup digitally.", - "core.walletSetupMnemonicStep.passphraseInfo3": "Find out more.", - "core.walletSetupMnemonicStep.passphraseError": "Make sure the words of your recovery phrase are in the right order and spelled correctly.", - "core.walletSetupMnemonicStepRevamp.writePassphraseTitle": "Start by saving your recovery phrase", - "core.walletSetupMnemonicStepRevamp.enterPassphrase": "Enter your recovery passphrase", - "core.walletSetupMnemonicStepRevamp.enterPassphraseLength": "Choose recovery phrase length", - "core.walletSetupMnemonicStepRevamp.enterPassphraseDescription": "Let's check you've got the correct recovery phrase. Type each word in the right order or paste from clipboard to verify it.", - "core.walletSetupMnemonicStepRevamp.writePassphraseSubtitle1": "Consider your recovery phrase as the master key to your wallet.", - "core.walletSetupMnemonicStepRevamp.writePassphraseSubtitle2": "Watch video.", - "core.walletSetupMnemonicStepRevamp.passphraseError": "Make sure the words of your recovery phrase are in the right order and spelled correctly.", - "core.walletSetupMnemonicStepRevamp.copyToClipboard": "Copy to clipboard", - "core.walletSetupMnemonicStepRevamp.pasteFromClipboard": "Paste from clipboard", - "core.walletSetupMnemonicIntroStep.title": "Keeping your wallet secure", - "core.walletSetupMnemonicIntroStep.description": "Consider your recovery phrase as the master key to your wallet, and the only way to access your funds.", - "core.walletSetupMnemonicIntroStep.link": "Read More.", - "core.mnemonicVideoPopupContent.title": "Keeping your wallet secure", - "core.mnemonicVideoPopupContent.description": "Learn about what is a recovery phrase, and how to keep it safe from the video below.", - "core.mnemonicVideoPopupContent.link": "Read More.", - "core.mnemonicVideoPopupContent.closeButton": "Got it", - "core.walletSetupMnemonicVerificationStep.enterPassphrase": "Enter your secret passphrase", - "core.walletSetupMnemonicVerificationStepRevamp.enterPassphrase": "Enter your recovery phrase", - "core.walletSetupOptionsStep.title": "Let's explore Web3 together", - "core.walletSetupOptionsStep.subTitle": "Choose an option to get started", - "core.walletSetupOptionsStep.newWallet.title": "New wallet", - "core.walletSetupOptionsStep.newWallet.description": "Create a new\nLace wallet", - "core.walletSetupOptionsStep.newWallet.button": "Create", - "core.walletSetupOptionsStep.hardwareWallet.title": "Hardware wallet", - "core.walletSetupOptionsStep.hardwareWallet.description": "Connect your hardware wallet to Lace", - "core.walletSetupOptionsStep.hardwareWallet.button": "Connect", - "core.walletSetupOptionsStep.restoreWallet.title": "Restore wallet", - "core.walletSetupOptionsStep.restoreWallet.description": "Enter your passphrase to recover your wallet", - "core.walletSetupOptionsStep.restoreWallet.button": "Restore", - "core.walletSetupRegisterStep.title": "Let's set up your new wallet", - "core.walletSetupRegisterStep.titlePassword": "Set up your password", - "core.walletSetupRegisterStep.description": "Choose a name to help you identify your wallet. It will only be visible to you.", - "core.walletSetupRegisterStep.passwordDescription": "You'll use this to log into your wallet and make transactions.", - "core.walletSetupRegisterStep.walletName": "Wallet name", - "core.walletSetupRegisterStep.nameMaxLength": "Max. 20 characters", - "core.walletSetupRegisterStep.capitalLetterRequired": "1 capital letter required", - "core.walletSetupRegisterStep.lowercaseLetterRequired": "1 lowercase letter required", - "core.walletSetupRegisterStep.numberRequired": "1 number required", - "core.walletSetupRegisterStep.charactersRequired": "8 characters is min", - "core.walletSetupRegisterStep.nameRequired": "Wallet name is required", - "core.walletSetupRegisterStep.password": "Password", - "core.walletSetupRegisterStep.confirmPassword": "Confirm password", - "core.walletSetupRegisterStep.noMatchPassword": "Oops! The passwords don't match.", - "core.walletSetupRegisterStep.validationMessage": "8+ characters with at least 1 uppercase letter, 1 lowercase letter, 1 number", - "core.walletSetupSelectAccountsStep.setupLaceWallet": "Let's set up your Lace wallet", - "core.walletSetupSelectAccountsStep.maxCharacters": "Max. 20 characters", - "core.walletSetupSelectAccountsStep.chooseWalletName": "Choose a name to help identify your wallet and which account you would like to export. You can change this later!", - "core.walletSetupSelectAccountsStep.enterWallet": "Enter wallet", - "core.walletSetupSelectAccountsStep.walletName": "Wallet name", - "core.walletSetupSelectAccountsStep.selectAccount": "Select Account", - "core.walletSetupSelectAccountsStep.exportKeys": "Next", - "core.walletSetupSelectAccountsStep.chooseAccountToExport": "Choose which account you would like to export.", - "core.walletSetupSelectAccountsStep.useHWToConfirm": "Use your device to confirm the export of your public key", - "core.walletSetupSelectAccountsStep.account": "Account", - "core.walletSetupWalletNameStep.maxCharacters": "Max. 20 characters", - "core.walletSetupWalletNameStep.walletName": "Wallet name", - "core.walletSetupWalletNameStep.nameYourWallet": "Name your wallet", - "core.walletSetupWalletNameStep.create": "Create", - "core.walletSetupWalletNameStep.chooseName": "Choose a name to easily identify your wallet.", - "core.walletSetupWalletModeStep.title": "Choose your wallet mode", - "core.walletSetupWalletModeStep.modes": "Wallet modes", - "core.walletSetupWalletModeStep.instructions": "You are able to have multiple wallets, each with a different mode selected.", - "core.walletSetupWalletModeStep.lightWalletOption": "Light wallet mode", - "core.walletSetupWalletModeStep.fullNodeOption": "Full node mode", - "core.walletSetupWalletModeStep.lightWalletDescription": "Light wallet connected to a synced server", - "core.walletSetupWalletModeStep.fullNodeWalletDescription": "Trustless wallet running on a full node", - "core.walletSetupRecoveryPhraseLengthStep.title": "Recovery phrase length", - "core.walletSetupRecoveryPhraseLengthStep.description": "Choose your recovery phrase length of either 12, 15 or 24 words to restore your wallet.", - "core.walletSetupRecoveryPhraseLengthStep.wordPassphrase": "word passphrase", - "core.password.feedback.1": "Weak password. Add some numbers and characters to make it stronger.", - "core.password.feedback.2": "Getting there! Add some symbols and numbers to make it stronger.", - "core.password.feedback.3": "No need for symbols, digits, or uppercase letters.", - "core.password.feedback.4": "Use a longer keyboard pattern with more turns.", - "core.password.feedback.5": "Avoid repeated words and characters.", - "core.password.feedback.6": "Avoid sequences.", - "core.password.feedback.7": "Avoid recent years.", - "core.password.feedback.8": "Avoid years that are associated with you.", - "core.password.feedback.9": "Avoid dates and years that are associated with you.", - "core.password.feedback.10": "Capitalization doesn't help very much.", - "core.password.feedback.11": "All-uppercase is almost as easy to guess as all-lowercase.", - "core.password.feedback.12": "Reversed words aren't much harder to guess.", - "core.password.feedback.13": "Predictable substitutions like '@' instead of 'a' don't help very much.", - "core.password.feedback.14": "Well done! That's one strong password.", - "core.password.feedback.15": "Hurray! Your password is super strong.", - "core.receive.usedAddresses.title": "Used Addresses ({{count}})", - "core.receive.usedAddresses.subtitle": "New addresses are automatically generated after a transaction.", - "core.receive.usedAddresses.copy": "Copy Address", - "core.receive.usedAddresses.addressCopied": "Address copied", - "core.receive.showUsedAddresses": "Show used addresses", - "core.addressTags.own": "own", - "core.addressTags.foreign": "foreign", - "cardano.waitForNextFundCard.title": "Waiting for next Fund", "corruptedData.actionDescription": "You will need to restore your wallet again with your recovery phrase.", "corruptedData.btn.confirm": "Restore your wallet", "corruptedData.errorDescription": "Looks like some of your data is missing or invalid. Don't worry your funds are safe.", diff --git a/apps/browser-extension-wallet/src/lib/translations/en.ts b/packages/translation/src/lib/translations/browser-extension-wallet/en.ts similarity index 74% rename from apps/browser-extension-wallet/src/lib/translations/en.ts rename to packages/translation/src/lib/translations/browser-extension-wallet/en.ts index 4d218537b..198223a46 100644 --- a/apps/browser-extension-wallet/src/lib/translations/en.ts +++ b/packages/translation/src/lib/translations/browser-extension-wallet/en.ts @@ -1,11 +1,9 @@ -import enjson from './en.json'; -import { translations } from '@lace/core'; import { cookiePolicy } from './cookie-policy.en'; +import enjson from './en.json'; import { legal } from './legal.en'; export const en = { ...cookiePolicy, ...legal, ...enjson, - ...translations.en }; diff --git a/apps/browser-extension-wallet/src/lib/translations/index.ts b/packages/translation/src/lib/translations/browser-extension-wallet/index.ts similarity index 100% rename from apps/browser-extension-wallet/src/lib/translations/index.ts rename to packages/translation/src/lib/translations/browser-extension-wallet/index.ts diff --git a/apps/browser-extension-wallet/src/lib/translations/legal.en.ts b/packages/translation/src/lib/translations/browser-extension-wallet/legal.en.ts similarity index 99% rename from apps/browser-extension-wallet/src/lib/translations/legal.en.ts rename to packages/translation/src/lib/translations/browser-extension-wallet/legal.en.ts index 8b9328ed1..65f01aba7 100644 --- a/apps/browser-extension-wallet/src/lib/translations/legal.en.ts +++ b/packages/translation/src/lib/translations/browser-extension-wallet/legal.en.ts @@ -579,5 +579,5 @@ export const legal = { matter hereof and supersedes and merges all prior discussions between the parties with respect to such subject matter.

- ` + `, }; diff --git a/packages/translation/src/lib/translations/cardano/en.json b/packages/translation/src/lib/translations/cardano/en.json new file mode 100644 index 000000000..46b26b211 --- /dev/null +++ b/packages/translation/src/lib/translations/cardano/en.json @@ -0,0 +1,71 @@ +{ + "cardano.catalystConfirmationStep.confirmBody": "Please sign the voting registration transaction. This will link your wallet balance as proof of voting power. Funds will not leave your wallet, but requires a transaction fee, displayed at the bottom of the screen.", + "cardano.catalystConfirmationStep.confirmHeader": "Confirm the registration transaction", + "cardano.catalystConfirmationStep.register": "Register to vote in", + "cardano.catalystConfirmationStep.totalFee": "Total fee", + "cardano.catalystPinStep.confirmPin": "Confirm your PIN code", + "cardano.catalystPinStep.pinNotMatching": "PIN is not matching", + "cardano.catalystPinStep.resetPin": "Reset PIN?", + "cardano.catalystPinStep.setPin": "Set a PIN code. You'll need it everytime you want to access the Catalyst app and to vote", + "cardano.catalystRegistrationStep.registerNow": "In the Catalyst App, click on the 'Register now' button", + "cardano.catalystScanStep.body1": "The following QR code is the generated certificate required by the Catalyst App to be able to participate in the voting process of Cardano.", + "cardano.catalystScanStep.body2": "We strongly suggest to take a screenshot of the QR code as a backup. You won't be able to access it after clicking on 'Done'.", + "cardano.catalystScanStep.doneButton": "Done", + "cardano.catalystScanStep.downloadButton": "Download QR code", + "cardano.catalystScanStep.header": "Use the Catalyst Voting App to scan the QR code", + "cardano.currentCatalystFund.endOfRegistration": "until end of registration", + "cardano.general.cancelButton": "Cancel", + "cardano.general.confirmButton": "Confirm", + "cardano.general.nextButton": "Next", + "cardano.networkInfo.averageMargin": "Average margin", + "cardano.networkInfo.averageRos": "Average ROS", + "cardano.networkInfo.currentEpoch": "Current epoch", + "cardano.networkInfo.epochEnd": "Epoch end", + "cardano.networkInfo.percentageStaked": "% Staked", + "cardano.networkInfo.title": "Network Info", + "cardano.networkInfo.totalPools": "Total pools", + "cardano.stakePoolMetricsBrowser.activeStake": "Active stake", + "cardano.stakePoolMetricsBrowser.blocks": "Blocks", + "cardano.stakePoolMetricsBrowser.cost": "Cost p/ epoch", + "cardano.stakePoolMetricsBrowser.delegators": "Delegators", + "cardano.stakePoolMetricsBrowser.liveStake": "Live stake", + "cardano.stakePoolMetricsBrowser.margin": "Pool margin", + "cardano.stakePoolMetricsBrowser.pledge": "Pledge", + "cardano.stakePoolMetricsBrowser.ros": "ROS", + "cardano.stakePoolMetricsBrowser.saturation": "Saturation", + "cardano.stakePoolSearch.gettingSaturated": "This pool starts to be saturated", + "cardano.stakePoolSearch.overSaturated": "This pool is over-saturated", + "cardano.stakePoolSearch.saturated": "This pool is saturated", + "cardano.stakePoolSearch.searchPlaceholder": "Search by ID or name", + "cardano.stakePoolSearch.staking": "You are staking on this pool", + "cardano.stakePoolStatusLogo.delegating": "You are delegating to this pool", + "cardano.stakePoolStatusLogo.retired": "This pool is retired. Re-delegate to an other pool to receive rewards", + "cardano.stakePoolStatusLogo.retiring": "This pool is retiring. Re-delegate to an other pool to avoid losing rewards", + "cardano.stakePoolStatusLogo.saturated": "This pool is too saturated. Stake on another pool to avoid losing rewards", + "cardano.stakePoolTableBrowser.tableHeader.blocks.title": "Blocks", + "cardano.stakePoolTableBrowser.tableHeader.blocks.tooltip": "Total blocks created by the pool.", + "cardano.stakePoolTableBrowser.tableHeader.cost.title": "Cost", + "cardano.stakePoolTableBrowser.tableHeader.cost.tooltip": "The cost is not directly paid by the delegator; they are deducted from a pool's rewards, consisting of a fixed cost and a variable cost, which fund the pool's operational costs", + "cardano.stakePoolTableBrowser.tableHeader.liveStake.title": "Live Stake", + "cardano.stakePoolTableBrowser.tableHeader.liveStake.tooltip": "Refers to the total amount of a cryptocurrency that is currently being staked in a particular staking pool", + "cardano.stakePoolTableBrowser.tableHeader.margin.title": "Margin", + "cardano.stakePoolTableBrowser.tableHeader.margin.tooltip": "The percentage of rewards taken by the stake pool operator after the fixed cost but before rewards are distributed", + "cardano.stakePoolTableBrowser.tableHeader.pledge.title": "Pledge", + "cardano.stakePoolTableBrowser.tableHeader.pledge.tooltip": "An amount of self‐bonded assets intended to remain staked to the pool for as long as it operates", + "cardano.stakePoolTableBrowser.tableHeader.ros.title": "ROS", + "cardano.stakePoolTableBrowser.tableHeader.ros.tooltip": "An estimation of the potential rewards you will earn per epoch if you delegate the intended amount of stake. The system looks at the pool's parameters and historical performance data to calculate potential rewards, assuming that the pool reaches optimal saturation.", + "cardano.stakePoolTableBrowser.tableHeader.saturation.title": "Saturation", + "cardano.stakePoolTableBrowser.tableHeader.saturation.tooltip": "Once a pool reaches the point of saturation, it will offer diminishing rewards", + "cardano.stakePoolTableBrowser.tableHeader.ticker.title": "Ticker", + "cardano.stakePoolTableBrowser.tableHeader.ticker.tooltip": "Refers to the unique identifier of a staking pool", + "cardano.stakingConfirmationInfo.delegateTo": "Delegate to", + "cardano.stakingConfirmationInfo.deposit": "Deposit", + "cardano.stakingConfirmationInfo.poolId": "Pool ID", + "cardano.stakingConfirmationInfo.transactionFee": "Transaction fee", + "cardano.votingParticipation.walletStatus": "Wallet status", + "cardano.waitForNextFundCard.message": "While waiting for the next fund you can register your wallet if it is not already done", + "cardano.waitForNextFundCard.phase0": "Phase 0", + "cardano.waitForNextFundCard.register": "Register", + "cardano.waitForNextFundCard.registered": "Registered", + "cardano.waitForNextFundCard.title": "Waiting for next Fund" +} diff --git a/packages/translation/src/lib/translations/cardano/en.ts b/packages/translation/src/lib/translations/cardano/en.ts new file mode 100644 index 000000000..397d8905c --- /dev/null +++ b/packages/translation/src/lib/translations/cardano/en.ts @@ -0,0 +1,5 @@ +import enjson from './en.json'; + +export const en = { + ...enjson, +}; diff --git a/packages/core/src/ui/lib/translations/en.json b/packages/translation/src/lib/translations/core/en.json similarity index 99% rename from packages/core/src/ui/lib/translations/en.json rename to packages/translation/src/lib/translations/core/en.json index d94399bd7..a21b85e79 100644 --- a/packages/core/src/ui/lib/translations/en.json +++ b/packages/translation/src/lib/translations/core/en.json @@ -6,6 +6,7 @@ "core.activityDetails.certificateTitles.anchorHash": "Anchor Hash", "core.activityDetails.certificateTitles.anchorURL": "Anchor URL", "core.activityDetails.certificateTitles.certificateType": "Type", + "core.activityDetails.certificateTitles.certificate": "Certificate", "core.activityDetails.certificateTitles.coldCredential": "Cold credential", "core.activityDetails.certificateTitles.depositPaid": "Deposit paid", "core.activityDetails.certificateTitles.depositPaidInfo": "Deposit paid", @@ -264,6 +265,10 @@ "core.outputSummaryList.deposit": "Deposit", "core.outputSummaryList.metaData": "Metadata", "core.outputSummaryList.output": "Bundle", + "core.outputSummaryList.expiresBy": "Expires by", + "core.outputSummaryList.expiresByTooltip": "This transaction can be added to the blockchain until the specified time. After this, it will automatically expire and no longer be valid.", + "core.outputSummaryList.noLimit": "No limit", + "core.outputSummaryList.utc": "UTC", "core.outputSummaryList.recipientAddress": "Recipient address", "core.outputSummaryList.sending": "Sending", "core.outputSummaryList.txFee": "Transaction fee", @@ -596,5 +601,6 @@ "core.walletSetupWalletNameStep.create": "Create", "core.walletSetupWalletNameStep.maxCharacters": "Max. 20 characters", "core.walletSetupWalletNameStep.nameYourWallet": "Name your wallet", - "core.walletSetupWalletNameStep.walletName": "Wallet name" + "core.walletSetupWalletNameStep.walletName": "Wallet name", + "core.nftDetail.directory": "Folder" } diff --git a/packages/translation/src/lib/translations/core/en.ts b/packages/translation/src/lib/translations/core/en.ts new file mode 100644 index 000000000..397d8905c --- /dev/null +++ b/packages/translation/src/lib/translations/core/en.ts @@ -0,0 +1,5 @@ +import enjson from './en.json'; + +export const en = { + ...enjson, +}; diff --git a/packages/translation/src/lib/translations/index.ts b/packages/translation/src/lib/translations/index.ts new file mode 100644 index 000000000..f0f58b30c --- /dev/null +++ b/packages/translation/src/lib/translations/index.ts @@ -0,0 +1,11 @@ +import { en as extension } from './browser-extension-wallet/en'; +import { en as cardano } from './cardano/en'; +import { en as core } from './core/en'; +import { en as staking } from './staking/en'; + +export const en = { + ...core, + ...cardano, + ...extension, + ...staking, +}; diff --git a/packages/translation/src/lib/translations/staking/en.json b/packages/translation/src/lib/translations/staking/en.json new file mode 100644 index 000000000..5e8c4a753 --- /dev/null +++ b/packages/translation/src/lib/translations/staking/en.json @@ -0,0 +1,205 @@ +{ + "activity.rewardsChart.all": "All", + "activity.rewardsChart.epoch": "Epoch", + "activity.rewardsChart.epochs": "Epochs", + "activity.rewardsChart.last": "Last", + "activity.rewardsChart.rewards": "Rewards", + "activity.rewardsChart.title": "Rewards", + "activity.rewardsHistory.noStakingActivityYet": "No staking activity yet.", + "activity.rewardsHistory.title": "History", + "browsePools.header.poolsCount": "Pools ({{poolsCount}})", + "browsePools.preferencesCard.filter.input.from": "From", + "browsePools.preferencesCard.filter.input.select": "Select", + "browsePools.preferencesCard.filter.input.to": "To", + "browsePools.preferencesCard.filter.performance": "Performance", + "browsePools.preferencesCard.filter.profitMargin": "Profit Margin", + "browsePools.preferencesCard.filter.ros.lastEpoch": "Last epoch", + "browsePools.preferencesCard.filter.ros.other": "other", + "browsePools.preferencesCard.filter.ros.title": "ROS", + "browsePools.preferencesCard.filter.saturation": "saturation", + "browsePools.preferencesCard.headers.filters": "Filters", + "browsePools.preferencesCard.headers.moreOptions": "More options", + "browsePools.preferencesCard.headers.sorting": "Sorting", + "browsePools.preferencesCard.sort.blocks": "Produced blocks", + "browsePools.preferencesCard.sort.cost": "Cost", + "browsePools.preferencesCard.sort.liveStake": "Live Stake", + "browsePools.preferencesCard.sort.margin": "Margin", + "browsePools.preferencesCard.sort.pledge": "Pledge", + "browsePools.preferencesCard.sort.ros": "ROS", + "browsePools.preferencesCard.sort.saturation": "Saturation", + "browsePools.preferencesCard.sort.ticker": "Ticker", + "browsePools.stakePoolGrid.notAvailable": "N/A", + "browsePools.stakePoolGrid.selected": "Selected", + "browsePools.stakePoolTableBrowser.addPool": "Add pool", + "browsePools.stakePoolTableBrowser.emptyMessage": "No results matching your search", + "browsePools.stakePoolTableBrowser.searchInputPlaceholder": "Search by pool name, ticker, or ID", + "browsePools.stakePoolTableBrowser.stake": "Stake", + "browsePools.stakePoolTableBrowser.unselect": "Unselect", + "browsePools.tableHeaders.blocks": "Blocks", + "browsePools.tableHeaders.cost": "Cost", + "browsePools.tableHeaders.liveStake": "Live Stake", + "browsePools.tableHeaders.margin": "Margin", + "browsePools.tableHeaders.pledge": "Pledge", + "browsePools.tableHeaders.ros": "ROS", + "browsePools.tableHeaders.saturation": "Saturation", + "browsePools.tableHeaders.ticker": "Ticker", + "browsePools.tooltips.blocks": "The total number of produced blocks the stake pool has produced.", + "browsePools.tooltips.cost": "Fixed operational costs that the stake pool retains from any rewards earned during each epoch", + "browsePools.tooltips.liveStake": "Measures the amount of stake pledged by the pool plus the amount of stake currently delegated to the pool, versus the total amount in the system.", + "browsePools.tooltips.margin": "The pool's profit, defined as the rewards percentage kept by the pool from the stake that was delegated to it.", + "browsePools.tooltips.maxNumberPoolsSelected": "Maximum number of pools selected", + "browsePools.tooltips.pledge": "The amount of stake that a pool operator contributes to a pool. Pools with higher pledge amounts earn more rewards for themselves and their delegators. Pools that do not honor their pledge earn zero rewards and accrue low ranking.", + "browsePools.tooltips.ros": "An estimation of the potential rewards you will earn per epoch if you delegate the intended amount of stake. The system looks at the pool's parameters and historical performance data to calculate potential rewards, assuming that the pool reaches optimal saturation.", + "browsePools.tooltips.saturation": "Once a pool reaches the point of saturation, it will offer diminishing rewards.", + "browsePools.tooltips.ticker": "Refers to the unique identifier of a staking pool", + "drawer.confirmation.button.confirm": "Next", + "drawer.confirmation.button.confirmWithDevice": "Confirm with {{hardwareWallet}}", + "drawer.confirmation.button.continueInAdvancedView": "Continue in Advanced View", + "drawer.confirmation.button.signing": "Signing in progress", + "drawer.confirmation.cardanoName": "Cardano", + "drawer.confirmation.chargedDepositAmountInfo": "The amount you'll be charged for registering your stake key.", + "drawer.confirmation.errors.utxoBalanceInsufficient": "Balance Insufficient", + "drawer.confirmation.errors.utxoFullyDepleted": "UTxO Fully Depleted", + "drawer.confirmation.noPools": "No pools", + "drawer.confirmation.reclaimDepositAmountInfo": "The amount you'll be awarded for de-registering your stake key.", + "drawer.confirmation.stakingDeposit": "Staking deposit", + "drawer.confirmation.subTitle": "Confirm the amount and the stake pool", + "drawer.confirmation.theAmountYoullBeChargedToProcessYourTransaction": "The amount you'll be charged to process your transaction", + "drawer.confirmation.title": "Confirmation", + "drawer.confirmation.transactionCost.title": "Transaction cost", + "drawer.confirmation.transactionFee": "Transaction fee", + "drawer.confirmation.transactionReturn.title": "Transaction return", + "drawer.confirmation.transactionTotal.title": "Total", + "drawer.details.addStakingPool": "Add staking pool", + "drawer.details.information": "Information", + "drawer.details.manageDelegation": "Manage delegation", + "drawer.details.metrics.activeStake": "Active stake", + "drawer.details.metrics.blocks": "Blocks", + "drawer.details.metrics.cost": "Cost p/ epoch", + "drawer.details.metrics.delegators": "Delegators", + "drawer.details.metrics.liveStake": "Live stake", + "drawer.details.metrics.margin": "Pool margin", + "drawer.details.metrics.pledge": "Pledge", + "drawer.details.metrics.ros": "ROS", + "drawer.details.metrics.saturation": "Saturation", + "drawer.details.owners": "Owners", + "drawer.details.poolIds": "Pool IDs", + "drawer.details.selectForMultiStaking": "Select pool for multi-staking", + "drawer.details.social": "Social links", + "drawer.details.stakeOnPoolButton": "Stake all on this pool", + "drawer.details.statistics": "Statistics", + "drawer.details.status.delegating": "You are delegating to this pool", + "drawer.details.status.retired": "This pool is retired. Re-delegate to an other pool to receive rewards", + "drawer.details.status.retiring": "This pool is retiring. Re-delegate to an other pool to avoid losing rewards", + "drawer.details.status.saturated": "This pool is too saturated. Stake on another pool to avoid losing rewards", + "drawer.details.unselectPool": "Unselect pool", + "drawer.failure.button.back": "Back", + "drawer.failure.button.cancel": "Cancel", + "drawer.failure.button.close": "Close", + "drawer.failure.button.removePools": "Remove pools", + "drawer.failure.button.retry": "Retry", + "drawer.failure.customSubmitApiWarning": "Custom submit API enabled to send transactions. To disable, go to Settings >> Custom submit API", + "drawer.failure.deviceUpdate.subTitle": "Your device needs to be up to date in order to use Multi-delegation. You can still delegate to a single pool with your current version", + "drawer.failure.deviceUpdate.title": "Device update required", + "drawer.failure.subTitle": "The transaction was not successful. Please try again.", + "drawer.failure.title": "Oops! Something went wrong...", + "drawer.preferences.addPoolButton": "Add stake pool", + "drawer.preferences.browsePools": "Browse pools", + "drawer.preferences.confirmButton": "Confirm new portfolio", + "drawer.preferences.ctaButtonTooltip.invalidAllocation": "You need to have a 100% allocation in order to proceed", + "drawer.preferences.ctaButtonTooltip.zeroPercentageSliderError": "Every portfolio pool requires more than 0% allocation", + "drawer.preferences.noSelectedPools": "You don't have any staking pool selected", + "drawer.preferences.pickMorePools": "You need to stake at least to one pool.", + "drawer.preferences.poolDetails.actualRatio": "Actual ratio", + "drawer.preferences.poolDetails.actualRatioTooltip": "The current ratio of your stake in this pool as verified by the on-chain state.", + "drawer.preferences.poolDetails.actualStake": "Actual stake", + "drawer.preferences.poolDetails.actualStakeTooltip": "The amount of ADA currently staked in this pool as verified by the on-chain state.", + "drawer.preferences.poolDetails.savedRatio": "Saved ratio", + "drawer.preferences.poolDetails.savedRatioTooltip": "The ratio previously saved for this pool. Note: This may not reflect the current on-chain state due to potential stake drift.", + "drawer.preferences.rebalanceButton": "Rebalance portfolio", + "drawer.preferences.removePoolButton": "Remove pool from portfolio", + "drawer.preferences.selectedStakePools": "Selected stake pools ({{count}})", + "drawer.sign.confirmation.title": "Staking confirmation", + "drawer.sign.enterWalletPasswordToConfirmTransaction": "Enter your wallet password to confirm transaction", + "drawer.sign.error.invalidPassword": "Wrong password", + "drawer.sign.passwordPlaceholder": "Password", + "drawer.success.modification.title": "Hurray! Your modification has been submitted", + "drawer.success.subTitle": "You'll start receiving your staking rewards after two epochs.", + "drawer.success.switchedPools.subTitle": "You'll start receiving your staking rewards from the new pool after two epochs. Until then you'll continue receiving rewards from the previous one.", + "drawer.success.switchedPools.title": "Hurray! You've switched pools", + "drawer.success.title": "Hurray! You've staked your funds", + "drawer.title": "Stake pool detail", + "drawer.titleSecond": "Manage staking", + "general.button.close": "Close", + "general.button.confirm": "Confirm", + "modals.beta.button": "Got it", + "modals.beta.description": "This feature allows you to stake to up to {{maxPools}} pools. This is still in beta version, so some functionality might not be available. Read more about multi-delegation in our dedicated blog.", + "modals.beta.pill": "Beta", + "modals.beta.portfolioPersistence.description": "Lace now supports on-chain portfolio persistence! This feature helps protect portfolios from significant drift and ensures cross-device syncing. If you've previously submitted a delegation, please resubmit your current (or a new) delegation to enable on-chain portfolio persistence.", + "modals.beta.portfolioPersistence.title": "Multi-delegation: Portfolio Persistence", + "modals.beta.title": "Multi-delegation", + "modals.changingPreferences.buttons.cancel": "Cancel", + "modals.changingPreferences.buttons.confirm": "Fine by me", + "modals.changingPreferences.description": "That's totally fine! Just please note that you'll continue receiving rewards from your former pool(s) for two epochs. After that, you'll start to receiving rewards from your new pool(s).", + "modals.changingPreferences.title": "Changing staking preferences?", + "modals.dapp.button": "Got it", + "modals.dapp.description": "Multi-delegation allows you to delegate to multiple pools using a single payment key for an enhanced user experience. However, as not all dApps support this new mechanism, if you encounter issues with dApps after multi-delegating, refer to the 'Multi-staking' section of our FAQ to revert your wallet to its previous state before multi-delegating.", + "modals.dapp.title": "Multi-delegation", + "modals.poolsManagement.buttons.cancel": "Cancel", + "modals.poolsManagement.buttons.confirm": "Fine by me", + "modals.poolsManagement.description.adjustment": "Reducing pool numbers needs a stake key de-registration, triggering the return of the initial ADA deposit and possibly losing any undistributed rewards. When changing pools, you'll get rewards from the former pool for two epochs, then start receiving them from the new pool.", + "modals.poolsManagement.description.reduction": "Reducing your pool count requires stake key de-registration, which returns the initial ADA deposit and may cause the loss of undistributed rewards in the calculation epoch phase.", + "modals.poolsManagement.title": "Switching Pool?", + "overview.banners.pendingFirstDelegation.message": "You will see your staking portfolio here once the transaction has been validated", + "overview.banners.pendingFirstDelegation.title": "Your staking transaction has been submitted", + "overview.banners.pendingPortfolioModification.message": "In case of changing pools you will continue to receive rewards from your former stake pool(s) for two epochs", + "overview.banners.pendingPortfolioModification.title": "You are modifying your staking portfolio", + "overview.banners.portfolioDrifted.message": "Make sure to rebalance your staking ratios if you want to match your preferences", + "overview.banners.portfolioDrifted.title": "Your current delegation portfolio has shifted", + "overview.banners.saturatedOrRetiredPool.message": "Please make sure to choose other pool(s) to avoid losing rewards", + "overview.banners.saturatedOrRetiredPool.title": "One or several of your pools are too saturated / retired", + "overview.delegationCard.label.balance": "ADA Balance", + "overview.delegationCard.label.pools": "Pool(s)", + "overview.delegationCard.label.status": "Status", + "overview.delegationCard.statuses.multiDelegation": "Multi delegation", + "overview.delegationCard.statuses.noSelection": "No selection", + "overview.delegationCard.statuses.overAllocated": "Over allocated", + "overview.delegationCard.statuses.simpleDelegation": "Simple delegation", + "overview.delegationCard.statuses.underAllocated": "Under allocated", + "overview.noFunds.button": "Copy address", + "overview.noFunds.description": "Add funds to start staking", + "overview.noFunds.title": "Welcome", + "overview.noStaking.balanceTitle": "Available balance", + "overview.noStaking.description": "Stake your funds on up to {{maxPools}} pools to start receiving rewards.", + "overview.noStaking.followSteps": "Follow these steps to start staking your funds", + "overview.noStaking.getStarted": "Get started", + "overview.noStaking.searchForPoolDescription": "Click the Stake Pools tab or click here then search for your desired pool.", + "overview.noStaking.searchForPoolTitle": "Browse stake pools", + "overview.noStaking.selectPoolsDescription": "You can select up to {{maxPools}} pools to delegate to. Click here to learn more.", + "overview.noStaking.selectPoolsTitle": "Select one or more pools to stake to", + "overview.noStaking.title": "Start staking", + "overview.stakingInfoCard.fee": "Fee", + "overview.stakingInfoCard.lastReward": "Last reward", + "overview.stakingInfoCard.margin": "Margin", + "overview.stakingInfoCard.poolRetired": "Pool retired", + "overview.stakingInfoCard.poolRetiring": "Pool retiring", + "overview.stakingInfoCard.poolSaturated": "Pool over-saturated", + "overview.stakingInfoCard.ros": "ROS", + "overview.stakingInfoCard.tooltipFiatLabel": "{{currencyCode}} Value", + "overview.stakingInfoCard.totalRewards": "Total rewards", + "overview.stakingInfoCard.totalStaked": "Total staked", + "overview.yourPoolsSection.heading": "Your pools", + "overview.yourPoolsSection.manageButtonLabel": "Manage", + "popup.expandBanner.button": "Expand view", + "popup.expandBanner.description": "Get more information on the network and the pool in the browser experience", + "popup.expandBanner.title": "There is more!", + "portfolioBar.clear": "Clear", + "portfolioBar.maxPools": "(max {{maxPoolsCount}})", + "portfolioBar.next": "Next", + "portfolioBar.selectedPools": "{{selectedPoolsCount}} pools selected", + "root.nav.activityTitle": "Activity", + "root.nav.browsePoolsTitle": "Browse pools", + "root.nav.overviewTitle": "Overview", + "root.nav.title": "Staking Navigation", + "root.title": "Staking" +} diff --git a/packages/translation/src/lib/translations/staking/en.ts b/packages/translation/src/lib/translations/staking/en.ts new file mode 100644 index 000000000..397d8905c --- /dev/null +++ b/packages/translation/src/lib/translations/staking/en.ts @@ -0,0 +1,5 @@ +import enjson from './en.json'; + +export const en = { + ...enjson, +}; diff --git a/packages/staking/src/features/i18n/translations/index.ts b/packages/translation/src/lib/translations/staking/index.ts similarity index 100% rename from packages/staking/src/features/i18n/translations/index.ts rename to packages/translation/src/lib/translations/staking/index.ts diff --git a/packages/translation/src/types/index.ts b/packages/translation/src/types/index.ts new file mode 100644 index 000000000..fcb073fef --- /dev/null +++ b/packages/translation/src/types/index.ts @@ -0,0 +1 @@ +export * from './types'; diff --git a/apps/browser-extension-wallet/src/lib/translations/types.ts b/packages/translation/src/types/types.ts similarity index 70% rename from apps/browser-extension-wallet/src/lib/translations/types.ts rename to packages/translation/src/types/types.ts index 9e64fa184..9febd90e6 100644 --- a/apps/browser-extension-wallet/src/lib/translations/types.ts +++ b/packages/translation/src/types/types.ts @@ -1,4 +1,4 @@ -import { en } from './en'; +import type { en } from '../lib/translations'; export type TranslationKey = keyof typeof en; diff --git a/packages/translation/src/typings/i18next.d.ts b/packages/translation/src/typings/i18next.d.ts new file mode 100644 index 000000000..d75b78b87 --- /dev/null +++ b/packages/translation/src/typings/i18next.d.ts @@ -0,0 +1,10 @@ +import 'i18next'; +import type { Translations } from '../types/types'; + +declare module 'i18next' { + interface CustomTypeOptions { + resources: { + translation: Translations; + }; + } +} diff --git a/packages/translation/tsconfig.eslint.json b/packages/translation/tsconfig.eslint.json new file mode 100644 index 000000000..e4f9fe999 --- /dev/null +++ b/packages/translation/tsconfig.eslint.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "include": [".eslintrc.js", "src/**/*", "rollup.config.js"] +} diff --git a/packages/translation/tsconfig.json b/packages/translation/tsconfig.json new file mode 100644 index 000000000..dc4e36993 --- /dev/null +++ b/packages/translation/tsconfig.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "compilerOptions": { + "allowJs": true, + "allowSyntheticDefaultImports": true, + "declaration": true, + "declarationDir": "./", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["dom", "dom.iterable", "esnext"], + "module": "esnext", + "moduleResolution": "node", + "noEmit": true, + "noFallthroughCasesInSwitch": true, + "outDir": "dist/", + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "target": "ES2018" + }, + "exclude": ["dist"] +} diff --git a/yarn.lock b/yarn.lock index d03910ea7..132e3856a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1996,6 +1996,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.24.5": + version: 7.24.5 + resolution: "@babel/helper-validator-identifier@npm:7.24.5" + checksum: 75d6f9f475c08f3be87bae4953e9b8d8c72983e16ed2860870b328d048cb20dccb4fcbf85eacbdd817ea1efbb38552a6db9046e2e37bfe13bdec44ac8939024c + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.14.5": version: 7.14.5 resolution: "@babel/helper-validator-option@npm:7.14.5" @@ -2206,7 +2213,19 @@ __metadata: languageName: node linkType: hard -"@babel/highlight@npm:^7.10.4, @babel/highlight@npm:^7.14.5": +"@babel/highlight@npm:^7.10.4": + version: 7.24.5 + resolution: "@babel/highlight@npm:7.24.5" + dependencies: + "@babel/helper-validator-identifier": ^7.24.5 + chalk: ^2.4.2 + js-tokens: ^4.0.0 + picocolors: ^1.0.0 + checksum: eece0e63e9210e902f1ee88f15cabfa31d2693bd2e56806eb849478b859d274c24477081c649cee6a241c4aed7da6f3e05c7afa5c3cd70094006ed095292b0d0 + languageName: node + linkType: hard + +"@babel/highlight@npm:^7.14.5": version: 7.14.5 resolution: "@babel/highlight@npm:7.14.5" dependencies: @@ -10000,6 +10019,23 @@ __metadata: languageName: node linkType: hard +"@eslint/eslintrc@npm:^1.4.1": + version: 1.4.1 + resolution: "@eslint/eslintrc@npm:1.4.1" + dependencies: + ajv: ^6.12.4 + debug: ^4.3.2 + espree: ^9.4.0 + globals: ^13.19.0 + ignore: ^5.2.0 + import-fresh: ^3.2.1 + js-yaml: ^4.1.0 + minimatch: ^3.1.2 + strip-json-comments: ^3.1.1 + checksum: cd3e5a8683db604739938b1c1c8b77927dc04fce3e28e0c88e7f2cd4900b89466baf83dfbad76b2b9e4d2746abdd00dd3f9da544d3e311633d8693f327d04cd7 + languageName: node + linkType: hard + "@eslint/eslintrc@npm:^2.0.0": version: 2.0.3 resolution: "@eslint/eslintrc@npm:2.0.3" @@ -10225,14 +10261,7 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^1.2.0": - version: 1.2.0 - resolution: "@humanwhocodes/object-schema@npm:1.2.0" - checksum: 40b75480376de8104d65f7c44a7dd76d30fb57823ca8ba3a3239b2b568323be894d93440578a72fd8e5e2cc3df3577ce0d2f0fe308b990dd51cf35392bf3c9a2 - languageName: node - linkType: hard - -"@humanwhocodes/object-schema@npm:^1.2.1": +"@humanwhocodes/object-schema@npm:^1.2.0, @humanwhocodes/object-schema@npm:^1.2.1": version: 1.2.1 resolution: "@humanwhocodes/object-schema@npm:1.2.1" checksum: a824a1ec31591231e4bad5787641f59e9633827d0a2eaae131a288d33c9ef0290bd16fda8da6f7c0fcb014147865d12118df10db57f27f41e20da92369fcb3f1 @@ -11110,6 +11139,7 @@ __metadata: "@lace/common": 0.1.0 "@lace/core": 0.1.0 "@lace/staking": 0.1.0 + "@lace/translation": 0.1.0 "@lace/ui": ^0.1.0 "@react-rxjs/core": ^0.9.8 "@react-rxjs/utils": ^0.9.5 @@ -11236,6 +11266,7 @@ __metadata: "@lace/cardano": 0.1.0 "@lace/common": 0.1.0 "@lace/icons": 0.1.0 + "@lace/translation": 0.1.0 "@lace/ui": ^0.1.0 "@storybook/addon-actions": ^6.5.16 "@storybook/addon-essentials": ^6.5.16 @@ -11269,7 +11300,7 @@ __metadata: sass: ^1.68.0 storybook: ^7.4.3 tsconfig-paths-webpack-plugin: 3.5.2 - typescript: ^4.3.5 + typescript: ^4.9.5 uuid: ^8.3.2 zxcvbn: ^4.4.2 peerDependencies: @@ -11347,6 +11378,7 @@ __metadata: "@lace/common": ^0.1.0 "@lace/core": 0.1.0 "@lace/icons": 0.1.0 + "@lace/translation": ^0.1.0 "@lace/ui": ^0.1.0 "@radix-ui/react-slider": ^1.1.2 "@storybook/addon-actions": ^7.6.7 @@ -11425,6 +11457,32 @@ __metadata: languageName: unknown linkType: soft +"@lace/translation@0.1.0, @lace/translation@^0.1.0, @lace/translation@workspace:packages/translation": + version: 0.0.0-use.local + resolution: "@lace/translation@workspace:packages/translation" + dependencies: + "@rollup/plugin-commonjs": 20.0.0 + "@rollup/plugin-json": ^6.0.0 + "@rollup/plugin-typescript": ^11.1.1 + "@typescript-eslint/eslint-plugin": ^5.51.0 + "@typescript-eslint/parser": ^5.51.0 + eslint: 8.33.0 + eslint-config-prettier: ^9.1.0 + eslint-plugin-boundaries: ^3.1.0 + eslint-plugin-functional: ^5.0.4 + eslint-plugin-import: ^2.27.5 + eslint-plugin-max-params-no-constructor: ^0.0.4 + eslint-plugin-prefer-arrow-functions: ^3.1.4 + eslint-plugin-prettier: ^5.1.3 + eslint-plugin-react: 7.31.8 + eslint-plugin-storybook: ^0.6.11 + eslint-plugin-unicorn: ^45.0.2 + i18next: ^22.5.1 + prettier: 3.2.5 + react-i18next: ^12.3.1 + languageName: unknown + linkType: soft + "@lace/ui@^0.1.0, @lace/ui@workspace:packages/ui": version: 0.0.0-use.local resolution: "@lace/ui@workspace:packages/ui" @@ -29877,7 +29935,17 @@ __metadata: languageName: node linkType: hard -"enquirer@npm:^2.3.5, enquirer@npm:^2.3.6": +"enquirer@npm:^2.3.5": + version: 2.4.1 + resolution: "enquirer@npm:2.4.1" + dependencies: + ansi-colors: ^4.1.1 + strip-ansi: ^6.0.1 + checksum: f080f11a74209647dbf347a7c6a83c8a47ae1ebf1e75073a808bc1088eb780aa54075bfecd1bcdb3e3c724520edb8e6ee05da031529436b421b71066fcc48cb5 + languageName: node + linkType: hard + +"enquirer@npm:^2.3.6": version: 2.3.6 resolution: "enquirer@npm:2.3.6" dependencies: @@ -31459,6 +31527,55 @@ __metadata: languageName: node linkType: hard +"eslint@npm:8.33.0": + version: 8.33.0 + resolution: "eslint@npm:8.33.0" + dependencies: + "@eslint/eslintrc": ^1.4.1 + "@humanwhocodes/config-array": ^0.11.8 + "@humanwhocodes/module-importer": ^1.0.1 + "@nodelib/fs.walk": ^1.2.8 + ajv: ^6.10.0 + chalk: ^4.0.0 + cross-spawn: ^7.0.2 + debug: ^4.3.2 + doctrine: ^3.0.0 + escape-string-regexp: ^4.0.0 + eslint-scope: ^7.1.1 + eslint-utils: ^3.0.0 + eslint-visitor-keys: ^3.3.0 + espree: ^9.4.0 + esquery: ^1.4.0 + esutils: ^2.0.2 + fast-deep-equal: ^3.1.3 + file-entry-cache: ^6.0.1 + find-up: ^5.0.0 + glob-parent: ^6.0.2 + globals: ^13.19.0 + grapheme-splitter: ^1.0.4 + ignore: ^5.2.0 + import-fresh: ^3.0.0 + imurmurhash: ^0.1.4 + is-glob: ^4.0.0 + is-path-inside: ^3.0.3 + js-sdsl: ^4.1.4 + js-yaml: ^4.1.0 + json-stable-stringify-without-jsonify: ^1.0.1 + levn: ^0.4.1 + lodash.merge: ^4.6.2 + minimatch: ^3.1.2 + natural-compare: ^1.4.0 + optionator: ^0.9.1 + regexpp: ^3.2.0 + strip-ansi: ^6.0.1 + strip-json-comments: ^3.1.0 + text-table: ^0.2.0 + bin: + eslint: bin/eslint.js + checksum: 727e63ab8b7acf281442323c5971f6afdd5b656fbcebc4476cf54e35af51b2f180617433fc5e1952f0449ca3f43a905527f9407ea4b8a7ea7562fc9c3f278d4c + languageName: node + linkType: hard + "eslint@npm:8.38.0": version: 8.38.0 resolution: "eslint@npm:8.38.0" @@ -33906,11 +34023,11 @@ __metadata: linkType: hard "globals@npm:^13.6.0, globals@npm:^13.9.0": - version: 13.11.0 - resolution: "globals@npm:13.11.0" + version: 13.24.0 + resolution: "globals@npm:13.24.0" dependencies: type-fest: ^0.20.2 - checksum: e9e5624154261a3e5344d2105a94886c5f2ca48028fa8258cd7b9119c5f00cf2909392817bb2d162c9a1a31b55d9b2c14e8f2271c45a22f77806f5b9322541cf + checksum: 56066ef058f6867c04ff203b8a44c15b038346a62efbc3060052a1016be9f56f4cf0b2cd45b74b22b81e521a889fc7786c73691b0549c2f3a6e825b3d394f43c languageName: node linkType: hard @@ -48257,7 +48374,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.3.7, semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.0": +"semver@npm:7.3.7, semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.0": version: 7.5.2 resolution: "semver@npm:7.5.2" dependencies: @@ -48308,6 +48425,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.2.1": + version: 7.6.2 + resolution: "semver@npm:7.6.2" + bin: + semver: bin/semver.js + checksum: 40f6a95101e8d854357a644da1b8dd9d93ce786d5c6a77227bc69dbb17bea83d0d1d1d7c4cd5920a6df909f48e8bd8a5909869535007f90278289f2451d0292d + languageName: node + linkType: hard + "semver@npm:^7.5.3, semver@npm:^7.5.4": version: 7.5.4 resolution: "semver@npm:7.5.4" @@ -50486,16 +50612,15 @@ __metadata: linkType: hard "table@npm:^6.0.9": - version: 6.7.1 - resolution: "table@npm:6.7.1" + version: 6.8.2 + resolution: "table@npm:6.8.2" dependencies: ajv: ^8.0.1 - lodash.clonedeep: ^4.5.0 lodash.truncate: ^4.4.2 slice-ansi: ^4.0.0 - string-width: ^4.2.0 - strip-ansi: ^6.0.0 - checksum: 053b61fa4e8f8396c65ff7a95da90e85620370932652d501ff7a0a3ed7317f1cc549702bd2abf2bd9ed01e20757b73a8b57374f8a8a2ac02fbe0550276263fb6 + string-width: ^4.2.3 + strip-ansi: ^6.0.1 + checksum: 61188652f53a980d1759ca460ca8dea5c5322aece3210457e7084882f053c2b6a870041295e08a82cb1d676e31b056406845d94b0abf3c79a4b104777bec413b languageName: node linkType: hard @@ -51858,16 +51983,6 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^4.3.5": - version: 4.3.5 - resolution: "typescript@npm:4.3.5" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: bab033b5e2b0790dd35b77fd005df976ef80b8d84fd2c6e63cc31808151875beae9216e5a315fe7068e8499905c3c354248fe83272cdfc13b7705635f0c66c97 - languageName: node - linkType: hard - "typescript@npm:^4.6.4": version: 4.9.4 resolution: "typescript@npm:4.9.4" @@ -51898,16 +52013,6 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@^4.3.5#~builtin": - version: 4.3.5 - resolution: "typescript@patch:typescript@npm%3A4.3.5#~builtin::version=4.3.5&hash=dba6d9" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 365df18cf979c971ef9543b2acaa8694377a803f98e1804c41d0ede0b09d7046cb0cd98f2eaf3884b0fe923c01a60af1f653841bd8805c9715d5479c09a4ebe4 - languageName: node - linkType: hard - "typescript@patch:typescript@^4.6.4#~builtin": version: 4.9.4 resolution: "typescript@patch:typescript@npm%3A4.9.4#~builtin::version=4.9.4&hash=289587" @@ -52774,7 +52879,14 @@ __metadata: languageName: node linkType: hard -"v8-compile-cache@npm:^2.0.3, v8-compile-cache@npm:^2.2.0, v8-compile-cache@npm:^2.3.0": +"v8-compile-cache@npm:^2.0.3": + version: 2.4.0 + resolution: "v8-compile-cache@npm:2.4.0" + checksum: 8eb6ddb59d86f24566503f1e6ca98f3e6f43599f05359bd3ab737eaaf1585b338091478a4d3d5c2646632cf8030288d7888684ea62238cdce15a65ae2416718f + languageName: node + linkType: hard + +"v8-compile-cache@npm:^2.2.0, v8-compile-cache@npm:^2.3.0": version: 2.3.0 resolution: "v8-compile-cache@npm:2.3.0" checksum: adb0a271eaa2297f2f4c536acbfee872d0dd26ec2d76f66921aa7fc437319132773483344207bdbeee169225f4739016d8d2dbf0553913a52bb34da6d0334f8e