@lifi/widget 3.32.2 → 3.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/esm/AppProvider.js +2 -1
- package/dist/esm/AppProvider.js.map +1 -1
- package/dist/esm/components/Header/NavigationHeader.js +4 -1
- package/dist/esm/components/Header/NavigationHeader.js.map +1 -1
- package/dist/esm/components/Tools/Tools.js +1 -1
- package/dist/esm/components/Tools/Tools.js.map +1 -1
- package/dist/esm/config/version.d.ts +1 -1
- package/dist/esm/config/version.js +1 -1
- package/dist/esm/hooks/useHeader.js +4 -1
- package/dist/esm/hooks/useHeader.js.map +1 -1
- package/dist/esm/hooks/useLanguages.d.ts +2 -3
- package/dist/esm/hooks/useLanguages.js +50 -14
- package/dist/esm/hooks/useLanguages.js.map +1 -1
- package/dist/esm/hooks/useRoutes.js +1 -1
- package/dist/esm/hooks/useRoutes.js.map +1 -1
- package/dist/esm/hooks/useSettingMonitor.js +2 -1
- package/dist/esm/hooks/useSettingMonitor.js.map +1 -1
- package/dist/esm/hooks/useTokenBalances.js +2 -1
- package/dist/esm/hooks/useTokenBalances.js.map +1 -1
- package/dist/esm/hooks/useTools.js +2 -1
- package/dist/esm/hooks/useTools.js.map +1 -1
- package/dist/esm/pages/LanguagesPage.js +6 -1
- package/dist/esm/pages/LanguagesPage.js.map +1 -1
- package/dist/esm/pages/SelectEnabledToolsPage.js +1 -1
- package/dist/esm/pages/SelectEnabledToolsPage.js.map +1 -1
- package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js +1 -1
- package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/LanguageSetting.js +7 -2
- package/dist/esm/pages/SettingsPage/LanguageSetting.js.map +1 -1
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js +1 -1
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js.map +1 -1
- package/dist/esm/providers/I18nProvider/I18nProvider.js +47 -41
- package/dist/esm/providers/I18nProvider/I18nProvider.js.map +1 -1
- package/dist/esm/providers/I18nProvider/constants.d.ts +3 -0
- package/dist/esm/providers/I18nProvider/constants.js +39 -0
- package/dist/esm/providers/I18nProvider/constants.js.map +1 -0
- package/dist/esm/providers/I18nProvider/enResource.d.ts +2 -0
- package/dist/esm/providers/I18nProvider/enResource.js +4 -0
- package/dist/esm/providers/I18nProvider/enResource.js.map +1 -0
- package/dist/esm/providers/I18nProvider/i18n.d.ts +3 -0
- package/dist/esm/providers/I18nProvider/i18n.js +19 -0
- package/dist/esm/providers/I18nProvider/i18n.js.map +1 -0
- package/dist/esm/providers/I18nProvider/types.d.ts +4 -11
- package/dist/esm/providers/WalletProvider/SDKProviders.js +1 -1
- package/dist/esm/providers/WalletProvider/SDKProviders.js.map +1 -1
- package/dist/esm/stores/bookmarks/createBookmarkStore.d.ts +19 -1
- package/dist/esm/stores/bookmarks/createBookmarkStore.js +3 -3
- package/dist/esm/stores/bookmarks/createBookmarkStore.js.map +1 -1
- package/dist/esm/stores/chains/ChainOrderStore.js +3 -1
- package/dist/esm/stores/chains/ChainOrderStore.js.map +1 -1
- package/dist/esm/stores/chains/createChainOrderStore.d.ts +33 -1
- package/dist/esm/stores/chains/createChainOrderStore.js +3 -3
- package/dist/esm/stores/chains/createChainOrderStore.js.map +1 -1
- package/dist/esm/stores/chains/useChainOrder.js +5 -2
- package/dist/esm/stores/chains/useChainOrder.js.map +1 -1
- package/dist/esm/stores/form/createFormStore.d.ts +1 -1
- package/dist/esm/stores/form/createFormStore.js +3 -3
- package/dist/esm/stores/form/createFormStore.js.map +1 -1
- package/dist/esm/stores/header/useHeaderStore.js +3 -3
- package/dist/esm/stores/header/useHeaderStore.js.map +1 -1
- package/dist/esm/stores/routes/createRouteExecutionStore.d.ts +17 -1
- package/dist/esm/stores/routes/createRouteExecutionStore.js +3 -3
- package/dist/esm/stores/routes/createRouteExecutionStore.js.map +1 -1
- package/dist/esm/stores/settings/SettingsStore.d.ts +9 -0
- package/dist/esm/stores/settings/SettingsStore.js +24 -0
- package/dist/esm/stores/settings/SettingsStore.js.map +1 -0
- package/dist/esm/stores/settings/createSettingsStore.d.ts +51 -0
- package/dist/esm/stores/settings/{useSettingsStore.js → createSettingsStore.js} +38 -11
- package/dist/esm/stores/settings/createSettingsStore.js.map +1 -0
- package/dist/esm/stores/settings/types.d.ts +7 -1
- package/dist/esm/stores/settings/types.js.map +1 -1
- package/dist/esm/stores/settings/useSendToWalletStore.d.ts +1 -1
- package/dist/esm/stores/settings/useSendToWalletStore.js +3 -3
- package/dist/esm/stores/settings/useSendToWalletStore.js.map +1 -1
- package/dist/esm/stores/settings/useSettings.js +1 -1
- package/dist/esm/stores/settings/useSettings.js.map +1 -1
- package/dist/esm/stores/settings/useSettingsActions.d.ts +1 -0
- package/dist/esm/stores/settings/useSettingsActions.js +9 -1
- package/dist/esm/stores/settings/useSettingsActions.js.map +1 -1
- package/dist/esm/stores/settings/useSplitSubvariantStore.js +3 -3
- package/dist/esm/stores/settings/useSplitSubvariantStore.js.map +1 -1
- package/dist/esm/stores/settings/utils/getStateValues.js +1 -0
- package/dist/esm/stores/settings/utils/getStateValues.js.map +1 -1
- package/dist/esm/utils/tokenList.d.ts +1 -1
- package/dist/esm/utils/tokenList.js +3 -3
- package/dist/esm/utils/tokenList.js.map +1 -1
- package/package.json +12 -12
- package/package.json.tmp +14 -14
- package/src/AppProvider.tsx +14 -11
- package/src/components/Header/NavigationHeader.tsx +4 -1
- package/src/components/Tools/Tools.tsx +1 -1
- package/src/config/version.ts +1 -1
- package/src/hooks/useHeader.ts +4 -1
- package/src/hooks/useLanguages.ts +73 -15
- package/src/hooks/useRoutes.ts +1 -1
- package/src/hooks/useSettingMonitor.ts +2 -4
- package/src/hooks/useTokenBalances.ts +2 -1
- package/src/hooks/useTools.ts +3 -1
- package/src/pages/LanguagesPage.tsx +10 -1
- package/src/pages/SelectEnabledToolsPage.tsx +1 -1
- package/src/pages/SettingsPage/BridgeAndExchangeSettings.tsx +1 -1
- package/src/pages/SettingsPage/LanguageSetting.tsx +9 -2
- package/src/pages/SettingsPage/SlippageSettings/SlippageSettings.tsx +1 -1
- package/src/providers/I18nProvider/I18nProvider.tsx +66 -51
- package/src/providers/I18nProvider/constants.ts +41 -0
- package/src/providers/I18nProvider/enResource.ts +4 -0
- package/src/providers/I18nProvider/i18n.ts +26 -0
- package/src/providers/I18nProvider/types.ts +21 -12
- package/src/providers/WalletProvider/SDKProviders.tsx +2 -1
- package/src/stores/bookmarks/createBookmarkStore.ts +3 -5
- package/src/stores/chains/ChainOrderStore.tsx +3 -1
- package/src/stores/chains/createChainOrderStore.ts +3 -5
- package/src/stores/chains/useChainOrder.ts +10 -2
- package/src/stores/form/createFormStore.ts +3 -3
- package/src/stores/header/useHeaderStore.tsx +31 -34
- package/src/stores/routes/createRouteExecutionStore.ts +3 -5
- package/src/stores/settings/SettingsStore.tsx +45 -0
- package/src/stores/settings/createSettingsStore.ts +223 -0
- package/src/stores/settings/types.ts +8 -1
- package/src/stores/settings/useSendToWalletStore.ts +8 -11
- package/src/stores/settings/useSettings.ts +1 -1
- package/src/stores/settings/useSettingsActions.ts +13 -4
- package/src/stores/settings/useSplitSubvariantStore.tsx +9 -12
- package/src/stores/settings/utils/getStateValues.ts +1 -0
- package/src/themes/types.ts +0 -3
- package/src/utils/tokenList.ts +3 -3
- package/dist/esm/i18n/index.d.ts +0 -16
- package/dist/esm/i18n/index.js +0 -17
- package/dist/esm/i18n/index.js.map +0 -1
- package/dist/esm/stores/settings/useSettingsStore.d.ts +0 -5
- package/dist/esm/stores/settings/useSettingsStore.js.map +0 -1
- package/src/i18n/index.ts +0 -17
- package/src/stores/settings/useSettingsStore.ts +0 -185
package/src/AppProvider.tsx
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
} from './providers/WidgetProvider/WidgetProvider.js'
|
|
17
17
|
import { URLSearchParamsBuilder } from './stores/form/URLSearchParamsBuilder.js'
|
|
18
18
|
import { StoreProvider } from './stores/StoreProvider.js'
|
|
19
|
+
import { SettingsStoreProvider } from './stores/settings/SettingsStore.js'
|
|
19
20
|
import type { WidgetConfigProps } from './types/widget.js'
|
|
20
21
|
|
|
21
22
|
export const AppProvider: React.FC<PropsWithChildren<WidgetConfigProps>> = ({
|
|
@@ -25,17 +26,19 @@ export const AppProvider: React.FC<PropsWithChildren<WidgetConfigProps>> = ({
|
|
|
25
26
|
}) => {
|
|
26
27
|
return (
|
|
27
28
|
<QueryClientProvider>
|
|
28
|
-
<
|
|
29
|
-
<
|
|
30
|
-
<
|
|
31
|
-
<
|
|
32
|
-
<
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
<SettingsStoreProvider config={config}>
|
|
30
|
+
<WidgetProvider config={config}>
|
|
31
|
+
<I18nProvider>
|
|
32
|
+
<ThemeProvider>
|
|
33
|
+
<WalletProvider>
|
|
34
|
+
<StoreProvider config={config} formRef={formRef}>
|
|
35
|
+
<AppRouter>{children}</AppRouter>
|
|
36
|
+
</StoreProvider>
|
|
37
|
+
</WalletProvider>
|
|
38
|
+
</ThemeProvider>
|
|
39
|
+
</I18nProvider>
|
|
40
|
+
</WidgetProvider>
|
|
41
|
+
</SettingsStoreProvider>
|
|
39
42
|
</QueryClientProvider>
|
|
40
43
|
)
|
|
41
44
|
}
|
|
@@ -22,7 +22,10 @@ export const NavigationHeader: React.FC = () => {
|
|
|
22
22
|
useWidgetConfig()
|
|
23
23
|
const { navigateBack } = useNavigateBack()
|
|
24
24
|
const { account } = useAccount()
|
|
25
|
-
const
|
|
25
|
+
const [element, title] = useHeaderStore((state) => [
|
|
26
|
+
state.element,
|
|
27
|
+
state.title,
|
|
28
|
+
])
|
|
26
29
|
const { pathname } = useLocation()
|
|
27
30
|
|
|
28
31
|
const cleanedPathname = pathname.endsWith('/')
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ToolsResponse } from '@lifi/sdk'
|
|
2
2
|
import { useMemo, useRef } from 'react'
|
|
3
3
|
import { useTranslation } from 'react-i18next'
|
|
4
|
+
import { useSettingsStore } from '../../stores/settings/SettingsStore.js'
|
|
4
5
|
import { useSettingsActions } from '../../stores/settings/useSettingsActions.js'
|
|
5
|
-
import { useSettingsStore } from '../../stores/settings/useSettingsStore.js'
|
|
6
6
|
import { SearchList } from '../Search/SearchInput.style.js'
|
|
7
7
|
import { SearchNotFound } from '../Search/SearchNotFound.js'
|
|
8
8
|
import { ToolItem } from './ToolItem.js'
|
package/src/config/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const name = '@lifi/widget'
|
|
2
|
-
export const version = '3.
|
|
2
|
+
export const version = '3.33.0'
|
package/src/hooks/useHeader.ts
CHANGED
|
@@ -3,7 +3,10 @@ import { useEffect } from 'react'
|
|
|
3
3
|
import { useHeaderStore } from '../stores/header/useHeaderStore.js'
|
|
4
4
|
|
|
5
5
|
export function useHeader(title: string, action?: ReactNode) {
|
|
6
|
-
const
|
|
6
|
+
const [setTitle, setAction] = useHeaderStore((state) => [
|
|
7
|
+
state.setTitle,
|
|
8
|
+
state.setAction,
|
|
9
|
+
])
|
|
7
10
|
|
|
8
11
|
useEffect(() => {
|
|
9
12
|
const removeTitle = setTitle(title)
|
|
@@ -1,31 +1,89 @@
|
|
|
1
|
+
import { useCallback, useMemo } from 'react'
|
|
1
2
|
import { useTranslation } from 'react-i18next'
|
|
3
|
+
import { allLanguages } from '../providers/I18nProvider/constants.js'
|
|
4
|
+
import { loadLocale } from '../providers/I18nProvider/i18n.js'
|
|
5
|
+
import type {
|
|
6
|
+
LanguageKey,
|
|
7
|
+
LanguageResource,
|
|
8
|
+
} from '../providers/I18nProvider/types.js'
|
|
2
9
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
3
10
|
import { useSettings } from '../stores/settings/useSettings.js'
|
|
4
11
|
import { useSettingsActions } from '../stores/settings/useSettingsActions.js'
|
|
12
|
+
import { getConfigItemSets, isItemAllowedForSets } from '../utils/item.js'
|
|
5
13
|
|
|
6
14
|
export const useLanguages = () => {
|
|
7
|
-
const {
|
|
8
|
-
const { languages } = useWidgetConfig()
|
|
15
|
+
const { i18n } = useTranslation()
|
|
16
|
+
const { languages: languagesConfig, languageResources } = useWidgetConfig()
|
|
9
17
|
const { language } = useSettings(['language'])
|
|
10
|
-
const {
|
|
18
|
+
const { setValues } = useSettingsActions()
|
|
11
19
|
|
|
12
|
-
const sortedLanguages =
|
|
20
|
+
const sortedLanguages = useMemo(() => {
|
|
21
|
+
const loadedLanguageKeys = Object.keys(i18n.store.data)
|
|
22
|
+
// NB: custom language resources added statically to i18n might not exist in allLanguages (language files)
|
|
23
|
+
const allLanguagesWithCustom = [
|
|
24
|
+
...new Set([...allLanguages, ...loadedLanguageKeys]),
|
|
25
|
+
]
|
|
26
|
+
let supportedLanguages: (LanguageKey | string)[] = []
|
|
27
|
+
if (!languagesConfig) {
|
|
28
|
+
supportedLanguages = allLanguagesWithCustom
|
|
29
|
+
} else {
|
|
30
|
+
const languagesConfigSets = getConfigItemSets(
|
|
31
|
+
languagesConfig,
|
|
32
|
+
(languages) => new Set(languages)
|
|
33
|
+
)
|
|
34
|
+
supportedLanguages = allLanguagesWithCustom.filter((language) =>
|
|
35
|
+
isItemAllowedForSets(language, languagesConfigSets)
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
return supportedLanguages.sort()
|
|
39
|
+
}, [languagesConfig, i18n.store.data])
|
|
13
40
|
|
|
14
|
-
const
|
|
15
|
-
|
|
41
|
+
const handleLanguageChange = useCallback(
|
|
42
|
+
async (languageKey: string) => {
|
|
43
|
+
// Cache the language resource to prevent blinking
|
|
44
|
+
// after switching languages and reloading the page.
|
|
45
|
+
let newLanguageCache: LanguageResource | undefined
|
|
46
|
+
if (
|
|
47
|
+
!i18n.hasResourceBundle(languageKey, 'translation') &&
|
|
48
|
+
languageKey !== 'en'
|
|
49
|
+
) {
|
|
50
|
+
await loadLocale(
|
|
51
|
+
languageKey as LanguageKey,
|
|
52
|
+
languageResources?.[languageKey as LanguageKey]
|
|
53
|
+
).then((languageResource) => {
|
|
54
|
+
i18n.addResourceBundle(
|
|
55
|
+
languageKey,
|
|
56
|
+
'translation',
|
|
57
|
+
languageResource,
|
|
58
|
+
true,
|
|
59
|
+
true
|
|
60
|
+
)
|
|
61
|
+
newLanguageCache = languageResource
|
|
62
|
+
})
|
|
63
|
+
} else {
|
|
64
|
+
// If the language is already loaded, just cache the existing resource
|
|
65
|
+
newLanguageCache = i18n.getResourceBundle(languageKey, 'translation')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Set the new language and language cache to the settings store.
|
|
69
|
+
setValues({ language: languageKey, languageCache: newLanguageCache })
|
|
70
|
+
|
|
71
|
+
// Update the i18n instance to the new language.
|
|
72
|
+
if (languageKey !== i18n.language) {
|
|
73
|
+
await i18n.changeLanguage(languageKey)
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
[i18n, languageResources, setValues]
|
|
16
77
|
)
|
|
17
|
-
|
|
18
|
-
|
|
78
|
+
|
|
79
|
+
const selectedLanguage = language || i18n.resolvedLanguage || ''
|
|
80
|
+
const selectedLanguageCode = sortedLanguages.includes(selectedLanguage)
|
|
81
|
+
? selectedLanguage
|
|
82
|
+
: languagesConfig?.default || 'en'
|
|
19
83
|
|
|
20
84
|
return {
|
|
21
85
|
availableLanguages: sortedLanguages,
|
|
22
86
|
selectedLanguageCode: selectedLanguageCode,
|
|
23
|
-
|
|
24
|
-
lng: selectedLanguageCode,
|
|
25
|
-
}),
|
|
26
|
-
setLanguageWithCode: (code: string) => {
|
|
27
|
-
setValue('language', code)
|
|
28
|
-
i18n.changeLanguage(code)
|
|
29
|
-
},
|
|
87
|
+
setLanguageWithCode: handleLanguageChange,
|
|
30
88
|
}
|
|
31
89
|
}
|
package/src/hooks/useRoutes.ts
CHANGED
|
@@ -16,8 +16,8 @@ import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
|
16
16
|
import { useFieldValues } from '../stores/form/useFieldValues.js'
|
|
17
17
|
import { useIntermediateRoutesStore } from '../stores/routes/useIntermediateRoutesStore.js'
|
|
18
18
|
import { useSetExecutableRoute } from '../stores/routes/useSetExecutableRoute.js'
|
|
19
|
+
import { defaultSlippage } from '../stores/settings/createSettingsStore.js'
|
|
19
20
|
import { useSettings } from '../stores/settings/useSettings.js'
|
|
20
|
-
import { defaultSlippage } from '../stores/settings/useSettingsStore.js'
|
|
21
21
|
import { WidgetEvent } from '../types/events.js'
|
|
22
22
|
import { getChainTypeFromAddress } from '../utils/chainType.js'
|
|
23
23
|
import { getQueryKey } from '../utils/queries.js'
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
2
|
+
import { defaultConfigurableSettings } from '../stores/settings/createSettingsStore.js'
|
|
3
|
+
import { useSettingsStore } from '../stores/settings/SettingsStore.js'
|
|
2
4
|
import { useSettingsActions } from '../stores/settings/useSettingsActions.js'
|
|
3
|
-
import {
|
|
4
|
-
defaultConfigurableSettings,
|
|
5
|
-
useSettingsStore,
|
|
6
|
-
} from '../stores/settings/useSettingsStore.js'
|
|
7
5
|
import { useTools } from './useTools.js'
|
|
8
6
|
|
|
9
7
|
export const useSettingMonitor = () => {
|
|
@@ -72,7 +72,7 @@ export const useTokenBalances = (
|
|
|
72
72
|
const { processedTokens, withCategories } = useMemo(() => {
|
|
73
73
|
return processTokenBalances(
|
|
74
74
|
isBalanceLoading,
|
|
75
|
-
isAllNetworks
|
|
75
|
+
isAllNetworks || !!search,
|
|
76
76
|
configTokens,
|
|
77
77
|
selectedChainId,
|
|
78
78
|
displayedTokensList,
|
|
@@ -85,6 +85,7 @@ export const useTokenBalances = (
|
|
|
85
85
|
selectedChainId,
|
|
86
86
|
displayedTokensList,
|
|
87
87
|
displayedTokensWithBalances,
|
|
88
|
+
search,
|
|
88
89
|
])
|
|
89
90
|
|
|
90
91
|
return {
|
package/src/hooks/useTools.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { getTools, type ToolsResponse } from '@lifi/sdk'
|
|
2
2
|
import { useQuery } from '@tanstack/react-query'
|
|
3
3
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
4
|
-
import {
|
|
4
|
+
import { useSettingsStoreContext } from '../stores/settings/SettingsStore.js'
|
|
5
5
|
import { getConfigItemSets, isItemAllowedForSets } from '../utils/item.js'
|
|
6
6
|
import { getQueryKey } from '../utils/queries.js'
|
|
7
7
|
|
|
8
8
|
export const useTools = () => {
|
|
9
9
|
const { bridges, exchanges, keyPrefix } = useWidgetConfig()
|
|
10
|
+
const settingsStore = useSettingsStoreContext()
|
|
11
|
+
|
|
10
12
|
const { data } = useQuery({
|
|
11
13
|
queryKey: [
|
|
12
14
|
getQueryKey('tools', keyPrefix),
|
|
@@ -6,6 +6,7 @@ import { PageContainer } from '../components/PageContainer.js'
|
|
|
6
6
|
import { SettingsListItemButton } from '../components/SettingsListItemButton.js'
|
|
7
7
|
import { useHeader } from '../hooks/useHeader.js'
|
|
8
8
|
import { useLanguages } from '../hooks/useLanguages.js'
|
|
9
|
+
import { languageNames } from '../providers/I18nProvider/constants.js'
|
|
9
10
|
|
|
10
11
|
export const LanguagesPage: React.FC = () => {
|
|
11
12
|
const { t } = useTranslation()
|
|
@@ -33,7 +34,15 @@ export const LanguagesPage: React.FC = () => {
|
|
|
33
34
|
key={language}
|
|
34
35
|
onClick={() => setLanguageWithCode(language)}
|
|
35
36
|
>
|
|
36
|
-
<ListItemText
|
|
37
|
+
<ListItemText
|
|
38
|
+
primary={
|
|
39
|
+
languageNames[language as keyof typeof languageNames] ||
|
|
40
|
+
t('language.name', {
|
|
41
|
+
lng: language,
|
|
42
|
+
}) ||
|
|
43
|
+
language
|
|
44
|
+
}
|
|
45
|
+
/>
|
|
37
46
|
{selectedLanguageCode === language && <Check color="primary" />}
|
|
38
47
|
</SettingsListItemButton>
|
|
39
48
|
))}
|
|
@@ -15,8 +15,8 @@ import { useDefaultElementId } from '../hooks/useDefaultElementId.js'
|
|
|
15
15
|
import { useHeader } from '../hooks/useHeader.js'
|
|
16
16
|
import { useScrollableContainer } from '../hooks/useScrollableContainer.js'
|
|
17
17
|
import { useTools } from '../hooks/useTools.js'
|
|
18
|
+
import { useSettingsStore } from '../stores/settings/SettingsStore.js'
|
|
18
19
|
import { useSettingsActions } from '../stores/settings/useSettingsActions.js'
|
|
19
|
-
import { useSettingsStore } from '../stores/settings/useSettingsStore.js'
|
|
20
20
|
|
|
21
21
|
interface SelectAllCheckboxProps {
|
|
22
22
|
allCheckboxesSelected: boolean
|
|
@@ -5,7 +5,7 @@ import { useNavigate } from 'react-router-dom'
|
|
|
5
5
|
import { CardButton } from '../../components/Card/CardButton.js'
|
|
6
6
|
import { useSettingMonitor } from '../../hooks/useSettingMonitor.js'
|
|
7
7
|
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
|
|
8
|
-
import { useSettingsStore } from '../../stores/settings/
|
|
8
|
+
import { useSettingsStore } from '../../stores/settings/SettingsStore.js'
|
|
9
9
|
import { HiddenUI } from '../../types/widget.js'
|
|
10
10
|
import { navigationRoutes } from '../../utils/navigationRoutes.js'
|
|
11
11
|
import { BadgedValue } from './SettingsCard/BadgedValue.js'
|
|
@@ -4,6 +4,7 @@ import { useNavigate } from 'react-router-dom'
|
|
|
4
4
|
import { CardButton } from '../../components/Card/CardButton.js'
|
|
5
5
|
import { CardValue } from '../../components/Card/CardButton.style.js'
|
|
6
6
|
import { useLanguages } from '../../hooks/useLanguages.js'
|
|
7
|
+
import { languageNames } from '../../providers/I18nProvider/constants.js'
|
|
7
8
|
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
|
|
8
9
|
import { HiddenUI } from '../../types/widget.js'
|
|
9
10
|
import { navigationRoutes } from '../../utils/navigationRoutes.js'
|
|
@@ -12,7 +13,7 @@ export const LanguageSetting: React.FC = () => {
|
|
|
12
13
|
const { t } = useTranslation()
|
|
13
14
|
const navigate = useNavigate()
|
|
14
15
|
const { hiddenUI } = useWidgetConfig()
|
|
15
|
-
const {
|
|
16
|
+
const { selectedLanguageCode } = useLanguages()
|
|
16
17
|
|
|
17
18
|
if (hiddenUI?.includes(HiddenUI.Language)) {
|
|
18
19
|
return null
|
|
@@ -28,7 +29,13 @@ export const LanguageSetting: React.FC = () => {
|
|
|
28
29
|
icon={<Language />}
|
|
29
30
|
title={t('language.title')}
|
|
30
31
|
>
|
|
31
|
-
<CardValue>
|
|
32
|
+
<CardValue>
|
|
33
|
+
{languageNames[selectedLanguageCode as keyof typeof languageNames] ||
|
|
34
|
+
t('language.name', {
|
|
35
|
+
lng: selectedLanguageCode,
|
|
36
|
+
}) ||
|
|
37
|
+
selectedLanguageCode}
|
|
38
|
+
</CardValue>
|
|
32
39
|
</CardButton>
|
|
33
40
|
)
|
|
34
41
|
}
|
|
@@ -5,9 +5,9 @@ import type { ChangeEventHandler, FocusEventHandler } from 'react'
|
|
|
5
5
|
import { useRef, useState } from 'react'
|
|
6
6
|
import { useTranslation } from 'react-i18next'
|
|
7
7
|
import { useSettingMonitor } from '../../../hooks/useSettingMonitor.js'
|
|
8
|
+
import { defaultSlippage } from '../../../stores/settings/createSettingsStore.js'
|
|
8
9
|
import { useSettings } from '../../../stores/settings/useSettings.js'
|
|
9
10
|
import { useSettingsActions } from '../../../stores/settings/useSettingsActions.js'
|
|
10
|
-
import { defaultSlippage } from '../../../stores/settings/useSettingsStore.js'
|
|
11
11
|
import { formatInputAmount, formatSlippage } from '../../../utils/format.js'
|
|
12
12
|
import { BadgedValue } from '../SettingsCard/BadgedValue.js'
|
|
13
13
|
import { SettingCardExpandable } from '../SettingsCard/SettingCardExpandable.js'
|
|
@@ -1,67 +1,82 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import {
|
|
3
|
-
import { useMemo } from 'react'
|
|
1
|
+
import { createInstance, type i18n } from 'i18next'
|
|
2
|
+
import { useMemo, useRef } from 'react'
|
|
4
3
|
import { I18nextProvider } from 'react-i18next'
|
|
5
|
-
import * as supportedLanguages from '../../i18n/index.js'
|
|
6
4
|
import { useSettings } from '../../stores/settings/useSettings.js'
|
|
7
5
|
import { compactNumberFormatter } from '../../utils/compactNumberFormatter.js'
|
|
8
6
|
import { currencyExtendedFormatter } from '../../utils/currencyExtendedFormatter.js'
|
|
9
|
-
import { deepMerge } from '../../utils/deepMerge.js'
|
|
10
|
-
import { getConfigItemSets, isItemAllowedForSets } from '../../utils/item.js'
|
|
11
7
|
import { percentFormatter } from '../../utils/percentFormatter.js'
|
|
12
8
|
import { useWidgetConfig } from '../WidgetProvider/WidgetProvider.js'
|
|
13
|
-
import
|
|
9
|
+
import { allLanguages } from './constants.js'
|
|
10
|
+
import { enResource } from './enResource.js'
|
|
11
|
+
import { mergeWithLanguageResources } from './i18n.js'
|
|
12
|
+
import type { LanguageKey, LanguageResource, PartialResource } from './types.js'
|
|
14
13
|
|
|
15
14
|
export const I18nProvider: React.FC<React.PropsWithChildren> = ({
|
|
16
15
|
children,
|
|
17
16
|
}) => {
|
|
18
|
-
const {
|
|
19
|
-
const { language } = useSettings(['language'])
|
|
17
|
+
const { languages, languageResources } = useWidgetConfig()
|
|
18
|
+
const { language, languageCache } = useSettings(['language', 'languageCache'])
|
|
19
|
+
const i18nInstanceRef = useRef<i18n | null>(null)
|
|
20
20
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
languageResources[lng]
|
|
35
|
-
) as LanguageTranslationResources)
|
|
36
|
-
: // biome-ignore lint/performance/noDynamicNamespaceImportAccess: TODO: make it dynamic
|
|
37
|
-
supportedLanguages[lng],
|
|
38
|
-
}
|
|
39
|
-
return resources
|
|
40
|
-
}, {} as LanguageTranslationResources)
|
|
41
|
-
|
|
42
|
-
if (languageResources) {
|
|
43
|
-
resources = Object.keys(languageResources).reduce((resources, lng) => {
|
|
44
|
-
if (!resources[lng]) {
|
|
45
|
-
resources[lng] = {
|
|
46
|
-
translation: languageResources[lng as LanguageKey]!,
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return resources
|
|
50
|
-
}, resources)
|
|
21
|
+
const i18nInstance = useMemo(() => {
|
|
22
|
+
if (i18nInstanceRef.current) {
|
|
23
|
+
// Update i18n instance with language and language cache updates
|
|
24
|
+
if (language && languageCache && language !== 'en') {
|
|
25
|
+
i18nInstanceRef.current.addResourceBundle(
|
|
26
|
+
language,
|
|
27
|
+
'translation',
|
|
28
|
+
languageCache,
|
|
29
|
+
true,
|
|
30
|
+
true
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
return i18nInstanceRef.current
|
|
51
34
|
}
|
|
52
35
|
|
|
36
|
+
// Custom language resources (of non-default languages) are added statically.
|
|
37
|
+
// If custom language resources extend existing languages, they are merged with dynamically loaded resources.
|
|
38
|
+
const customLanguageKeys = languageResources
|
|
39
|
+
? Object.keys(languageResources).filter(
|
|
40
|
+
(key: string) => !allLanguages.includes(key as LanguageKey)
|
|
41
|
+
)
|
|
42
|
+
: []
|
|
43
|
+
const initialLanguage = language || languages?.default
|
|
53
44
|
const i18n = createInstance({
|
|
54
|
-
lng:
|
|
55
|
-
fallbackLng:
|
|
56
|
-
? 'en'
|
|
57
|
-
: languages?.default ||
|
|
58
|
-
languages?.allow?.[0] ||
|
|
59
|
-
Object.keys(resources)?.[0],
|
|
45
|
+
lng: initialLanguage,
|
|
46
|
+
fallbackLng: 'en',
|
|
60
47
|
lowerCaseLng: true,
|
|
61
|
-
interpolation: {
|
|
62
|
-
|
|
48
|
+
interpolation: { escapeValue: false },
|
|
49
|
+
resources: {
|
|
50
|
+
en: {
|
|
51
|
+
translation: mergeWithLanguageResources(
|
|
52
|
+
enResource,
|
|
53
|
+
languageResources?.en
|
|
54
|
+
),
|
|
55
|
+
},
|
|
56
|
+
...(initialLanguage &&
|
|
57
|
+
initialLanguage !== 'en' &&
|
|
58
|
+
languageCache && {
|
|
59
|
+
[initialLanguage]: {
|
|
60
|
+
translation: languageCache,
|
|
61
|
+
},
|
|
62
|
+
}),
|
|
63
|
+
// Add non-existing custom language resources
|
|
64
|
+
...customLanguageKeys.reduce(
|
|
65
|
+
(acc, key) => {
|
|
66
|
+
const customResource = languageResources?.[key as LanguageKey]
|
|
67
|
+
if (customResource) {
|
|
68
|
+
acc[key] = {
|
|
69
|
+
translation: customResource,
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return acc
|
|
73
|
+
},
|
|
74
|
+
{} as Record<
|
|
75
|
+
string,
|
|
76
|
+
{ translation: PartialResource<LanguageResource> }
|
|
77
|
+
>
|
|
78
|
+
),
|
|
63
79
|
},
|
|
64
|
-
resources,
|
|
65
80
|
detection: {
|
|
66
81
|
caches: [],
|
|
67
82
|
},
|
|
@@ -73,9 +88,9 @@ export const I18nProvider: React.FC<React.PropsWithChildren> = ({
|
|
|
73
88
|
i18n.services.formatter?.addCached('numberExt', compactNumberFormatter)
|
|
74
89
|
i18n.services.formatter?.addCached('currencyExt', currencyExtendedFormatter)
|
|
75
90
|
i18n.services.formatter?.addCached('percent', percentFormatter)
|
|
76
|
-
|
|
91
|
+
i18nInstanceRef.current = i18n
|
|
77
92
|
return i18n
|
|
78
|
-
}, [language, languageResources, languages])
|
|
93
|
+
}, [language, languageResources, languages?.default, languageCache])
|
|
79
94
|
|
|
80
|
-
return <I18nextProvider i18n={
|
|
95
|
+
return <I18nextProvider i18n={i18nInstance}>{children}</I18nextProvider>
|
|
81
96
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { LanguageKey } from './types.js'
|
|
2
|
+
|
|
3
|
+
export const allLanguages: LanguageKey[] = [
|
|
4
|
+
'en',
|
|
5
|
+
'es',
|
|
6
|
+
'fr',
|
|
7
|
+
'de',
|
|
8
|
+
'it',
|
|
9
|
+
'pt',
|
|
10
|
+
'ja',
|
|
11
|
+
'ko',
|
|
12
|
+
'zh',
|
|
13
|
+
'hi',
|
|
14
|
+
'bn',
|
|
15
|
+
'th',
|
|
16
|
+
'vi',
|
|
17
|
+
'tr',
|
|
18
|
+
'uk',
|
|
19
|
+
'id',
|
|
20
|
+
'pl',
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
export const languageNames: Record<LanguageKey, string> = {
|
|
24
|
+
en: 'English',
|
|
25
|
+
es: 'Español',
|
|
26
|
+
fr: 'Français',
|
|
27
|
+
de: 'Deutsch',
|
|
28
|
+
it: 'Italiano',
|
|
29
|
+
pt: 'Português',
|
|
30
|
+
ja: '日本語',
|
|
31
|
+
ko: '한국어',
|
|
32
|
+
zh: '中文',
|
|
33
|
+
hi: 'हिन्दी',
|
|
34
|
+
bn: 'বাংলা',
|
|
35
|
+
th: 'ไทย',
|
|
36
|
+
vi: 'Tiếng Việt',
|
|
37
|
+
tr: 'Türkçe',
|
|
38
|
+
uk: 'Українська',
|
|
39
|
+
id: 'Bahasa Indonesia',
|
|
40
|
+
pl: 'Polski',
|
|
41
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { deepMerge } from '../../utils/deepMerge.js'
|
|
2
|
+
import type { LanguageKey, LanguageResource, PartialResource } from './types.js'
|
|
3
|
+
|
|
4
|
+
// Dynamically import the JSON file for the specified language
|
|
5
|
+
export async function loadLocale(
|
|
6
|
+
lng: LanguageKey,
|
|
7
|
+
customLanguageResource?: PartialResource<LanguageResource>
|
|
8
|
+
) {
|
|
9
|
+
let languageResource: LanguageResource
|
|
10
|
+
try {
|
|
11
|
+
const languageResourceModule = await import(`../../i18n/${lng}.json`)
|
|
12
|
+
languageResource = languageResourceModule.default as LanguageResource
|
|
13
|
+
} catch {
|
|
14
|
+
languageResource = {} as LanguageResource
|
|
15
|
+
}
|
|
16
|
+
return mergeWithLanguageResources(languageResource, customLanguageResource)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function mergeWithLanguageResources(
|
|
20
|
+
languageResource: LanguageResource,
|
|
21
|
+
customLanguageResource?: PartialResource<LanguageResource>
|
|
22
|
+
) {
|
|
23
|
+
return customLanguageResource
|
|
24
|
+
? deepMerge(languageResource, customLanguageResource)
|
|
25
|
+
: languageResource
|
|
26
|
+
}
|
|
@@ -1,14 +1,31 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import type { enResource } from './enResource.js'
|
|
2
2
|
|
|
3
|
-
type PartialResource<T> = T extends object
|
|
3
|
+
export type PartialResource<T> = T extends object
|
|
4
4
|
? {
|
|
5
5
|
[P in keyof T]?: PartialResource<T[P]>
|
|
6
6
|
}
|
|
7
7
|
: T
|
|
8
8
|
|
|
9
|
-
export type LanguageKey =
|
|
9
|
+
export type LanguageKey =
|
|
10
|
+
| 'en'
|
|
11
|
+
| 'es'
|
|
12
|
+
| 'fr'
|
|
13
|
+
| 'de'
|
|
14
|
+
| 'it'
|
|
15
|
+
| 'pt'
|
|
16
|
+
| 'ja'
|
|
17
|
+
| 'ko'
|
|
18
|
+
| 'zh'
|
|
19
|
+
| 'hi'
|
|
20
|
+
| 'bn'
|
|
21
|
+
| 'th'
|
|
22
|
+
| 'vi'
|
|
23
|
+
| 'tr'
|
|
24
|
+
| 'uk'
|
|
25
|
+
| 'id'
|
|
26
|
+
| 'pl'
|
|
10
27
|
|
|
11
|
-
type LanguageResource = typeof
|
|
28
|
+
export type LanguageResource = typeof enResource
|
|
12
29
|
|
|
13
30
|
export type LanguageResources =
|
|
14
31
|
| {
|
|
@@ -17,11 +34,3 @@ export type LanguageResources =
|
|
|
17
34
|
| {
|
|
18
35
|
[language: string]: PartialResource<LanguageResource>
|
|
19
36
|
}
|
|
20
|
-
|
|
21
|
-
type LanguageTranslationResource = {
|
|
22
|
-
[N in 'translation']: PartialResource<LanguageResource>
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export type LanguageTranslationResources = {
|
|
26
|
-
[language: string]: LanguageTranslationResource
|
|
27
|
-
}
|
|
@@ -38,7 +38,8 @@ export const SDKProviders = () => {
|
|
|
38
38
|
if (!hasConfiguredEVMProvider) {
|
|
39
39
|
providers.push(
|
|
40
40
|
EVM({
|
|
41
|
-
getWalletClient: () =>
|
|
41
|
+
getWalletClient: () =>
|
|
42
|
+
getWagmiConnectorClient(wagmiConfig, { assertChainId: false }),
|
|
42
43
|
switchChain: async (chainId: number) => {
|
|
43
44
|
const chain = await switchChain(wagmiConfig, { chainId })
|
|
44
45
|
return getWagmiConnectorClient(wagmiConfig, { chainId: chain.id })
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { create } from 'zustand'
|
|
2
2
|
import { persist } from 'zustand/middleware'
|
|
3
|
-
import { createWithEqualityFn } from 'zustand/traditional'
|
|
4
3
|
import type { ToAddress } from '../../types/widget.js'
|
|
5
4
|
import type { PersistStoreProps } from '../types.js'
|
|
6
5
|
import type { BookmarkState } from './types.js'
|
|
@@ -14,7 +13,7 @@ export const createBookmarksStore = ({
|
|
|
14
13
|
namePrefix,
|
|
15
14
|
toAddress,
|
|
16
15
|
}: PersistBookmarkProps) =>
|
|
17
|
-
|
|
16
|
+
create<BookmarkState>()(
|
|
18
17
|
persist(
|
|
19
18
|
(set, get) => ({
|
|
20
19
|
selectedBookmark: toAddress,
|
|
@@ -76,6 +75,5 @@ export const createBookmarksStore = ({
|
|
|
76
75
|
}
|
|
77
76
|
},
|
|
78
77
|
}
|
|
79
|
-
)
|
|
80
|
-
Object.is
|
|
78
|
+
)
|
|
81
79
|
)
|
|
@@ -64,7 +64,9 @@ export function ChainOrderStoreProvider({
|
|
|
64
64
|
|
|
65
65
|
// Show "All networks" button if there are multiple networks
|
|
66
66
|
const showAllNetworks = filteredChains.length > 1
|
|
67
|
-
|
|
67
|
+
if (!showAllNetworks) {
|
|
68
|
+
storeRef.current?.getState().setIsAllNetworks(false, key)
|
|
69
|
+
}
|
|
68
70
|
storeRef.current?.getState().setShowAllNetworks(showAllNetworks, key)
|
|
69
71
|
|
|
70
72
|
const [chainValue] = getFieldValues(`${key}Chain`)
|