Skip to content

Commit 342cb06

Browse files
[WALL] Lubega / WALL-4791 / Wallets RTL support for اللغة العربية (AR) (deriv-com#16660)
* feat: wallets arabic language * fix: retrigger * Update trade-type-list.spec.jsx * Update account-wizard.jsx * fix: unit test * fix: cfd and options arrow direction * fix: transfer rtl support * fix: reformat with css logical properties * chore: useIsRtl unit test * fix: added remaining rtl support * fix: update default language in wallets app * fix: translations scroll issue * chore: filter language for mobile and accounts language switcher * fix: applied comments * fix: text alignment * fix: app card badge border radius * fix: applied comments * fix: crypto transaction alignment * fix: withdrawal crypto receipt padding * fix: deriv apps get accounts header * fix: sent email content alignment * fix: switching logic * fix: remove local storage dependency * fix: useIsRtl hook * fix: default language for numbers * fix: reformat displayMoney * fix: missing translations * fix: mt5 zero spread translations * fix: compare accounts header * fix: jurisdiction card alignment * fix: enter password alignment * fix: cashier translation fixes * fix: wallet action modal alignment * fix: api provider language reconnection * fix: update deriv-com/translations version * fix: update api-v2 jest config * fix: compare accounts header title * fix: subtasks * fix: arrow direction * fix: trader account switcher icon * fix: test case * fix: added language loader * fix: remove language loader * fix: debug language loading * fix: added initial language switch * fix: initial language switching logic * fix: debug * fix: POI/POA alignment issues * fix: revert language change * fix: change default language source * fix: added preferred language * fix: added language switch * fix: remove switch language * fix: remove preferred language * fix: subtasks * fix: add preferred language * fix: revert webpack update * fix: added useLanguage hook * fix: update useLanguage hook * fix: failing test * fix: add preferred language to core app content * fix: mock store * fix: update api provider websocket url language source * fix: update WS url language settings * fix: remove preferred language from core app content * fix: reorder apiprovider language * fix: deriv mt5 investor * fix(wallets): 🚑 align positive/negative sign for rtl language * fix(wallets): 🧪 fix test, add rtl support for pending transactions * fix: test case * fix: sonarcloud smell --------- Co-authored-by: heorhi-deriv <[email protected]>
1 parent b3167b3 commit 342cb06

File tree

215 files changed

+1600
-823
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

215 files changed

+1600
-823
lines changed

__mocks__/translation.mock.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,6 @@ const localize = mockFn;
4646

4747
const getAllowedLanguages = jest.fn(() => ({ EN: 'English', VI: 'Tiếng Việt' }));
4848

49-
export { Localize, localize, useTranslations, getAllowedLanguages };
49+
const getInitialLanguage = jest.fn(() => 'EN');
50+
51+
export { Localize, localize, useTranslations, getAllowedLanguages, getInitialLanguage };

packages/account/src/Containers/Account/account.tsx

-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ type TAccountProps = RouteComponentProps & {
2323
const Account = observer(({ history, location, routes }: TAccountProps) => {
2424
const { client, ui } = useStore();
2525
const {
26-
has_wallet,
2726
is_virtual,
2827
is_logged_in,
2928
is_logging_in,
@@ -70,10 +69,6 @@ const Account = observer(({ history, location, routes }: TAccountProps) => {
7069
if (route.path === shared_routes.passkeys) {
7170
route.is_hidden = should_remove_passkeys_route;
7271
}
73-
74-
if (route.path === shared_routes.languages) {
75-
route.is_hidden = has_wallet;
76-
}
7772
});
7873
}
7974
});

packages/account/src/Sections/Profile/LanguageSettings/__tests__/language-settings.spec.tsx

+20-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ describe('LanguageSettings', () => {
4242
common: {
4343
current_language: 'lang_1',
4444
},
45+
client: {
46+
has_wallet: false,
47+
},
4548
});
4649
(useTranslations as jest.Mock).mockReturnValue({
4750
currentLang: 'EN',
@@ -56,7 +59,7 @@ describe('LanguageSettings', () => {
5659
});
5760
};
5861

59-
it('should render LanguageSettings', () => {
62+
it('should render LanguageSettings with all allowed languages for non-wallets accounts', () => {
6063
renderLanguageSettings();
6164

6265
expect(screen.getByText('Select language')).toBeInTheDocument();
@@ -70,6 +73,22 @@ describe('LanguageSettings', () => {
7073
expect(lang_2).toBeInTheDocument();
7174
});
7275

76+
it('should render LanguageSettings with only wallets-allowed languages for wallets accounts', () => {
77+
mockRootStore.client.has_wallet = true;
78+
79+
renderLanguageSettings();
80+
81+
expect(screen.getByText('Select language')).toBeInTheDocument();
82+
83+
const lang_1 = screen.getByText('English');
84+
const lang_2 = screen.queryByText('Tiếng Việt');
85+
86+
expect(screen.getByText(/Language 1 Flag/)).toBeInTheDocument();
87+
expect(screen.queryByText(/Language 2 Flag/)).not.toBeInTheDocument();
88+
expect(lang_1).toBeInTheDocument();
89+
expect(lang_2).not.toBeInTheDocument();
90+
});
91+
7392
it('should trigger language change', () => {
7493
renderLanguageSettings();
7594

packages/account/src/Sections/Profile/LanguageSettings/language-settings.tsx

+10-3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import { useDevice } from '@deriv-com/ui';
99
const LanguageSettings = observer(() => {
1010
const { client, common } = useStore();
1111
const { switchLanguage, currentLang, localize } = useTranslations();
12-
const { has_wallet } = client;
1312
// [TODO]: Remove changeSelectedLanguage() when whole app starts to use @deriv-com/translations
1413
const { changeSelectedLanguage } = common;
14+
const { has_wallet } = client;
1515
const { isDesktop } = useDevice();
1616

17-
if (!isDesktop || has_wallet) {
17+
if (!isDesktop) {
1818
return <Redirect to={routes.traders_hub} />;
1919
}
2020

@@ -25,7 +25,14 @@ const LanguageSettings = observer(() => {
2525
switchLanguage(language_key);
2626
};
2727

28-
const allowed_languages: Record<string, string> = getAllowedLanguages(UNSUPPORTED_LANGUAGES);
28+
let allowed_languages: Record<string, string> = getAllowedLanguages(UNSUPPORTED_LANGUAGES);
29+
30+
if (has_wallet) {
31+
allowed_languages = Object.fromEntries(
32+
Object.entries(allowed_languages).filter(([language_key]) => ['EN', 'AR'].includes(language_key))
33+
);
34+
}
35+
2936
return (
3037
<div className='settings-language'>
3138
<FormSubHeader title={localize('Select language')} />

packages/api-v2/jest.config.js

+3
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ const baseConfigForPackages = require('../../jest.config.base');
22

33
module.exports = {
44
...baseConfigForPackages,
5+
moduleNameMapper: {
6+
'@deriv-com/translations': '<rootDir>/../../__mocks__/translation.mock.js',
7+
},
58
};

packages/api-v2/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"main": "src/index.ts",
66
"dependencies": {
77
"@deriv-com/utils": "^0.0.34",
8+
"@deriv-com/translations": "1.3.9",
89
"@deriv/deriv-api": "^1.0.15",
910
"@deriv/shared": "^1.0.0",
1011
"@deriv/utils": "^1.0.0",

packages/api-v2/src/APIProvider.tsx

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { PropsWithChildren, createContext, useContext, useEffect, useRef, useState, useCallback } from 'react';
22
import { getAppId, getSocketURL } from '@deriv/shared';
3+
import { getInitialLanguage } from '@deriv-com/translations';
34
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
45
import { TSocketRequestPayload, TSocketResponseData, TSocketSubscribableEndpointNames } from '../types';
56
import { hashObject } from './utils';
@@ -35,7 +36,11 @@ type APIContextData = {
3536
const getWebSocketURL = () => {
3637
const endpoint = getSocketURL();
3738
const app_id = getAppId();
38-
const language = localStorage.getItem('i18n_language');
39+
const initial_language = getInitialLanguage();
40+
const wallet_allowed_languages = initial_language === 'EN' || initial_language === 'AR';
41+
// fallback to EN if language on initial load is not EN/AR
42+
const language = wallet_allowed_languages ? initial_language : 'EN';
43+
3944
return `wss://${endpoint}/websockets/v3?app_id=${app_id}&l=${language}&brand=deriv`;
4045
};
4146

@@ -84,6 +89,9 @@ const APIProvider = ({ children }: PropsWithChildren<TAPIProviderProps>) => {
8489
const isOpenRef = useRef<boolean>(false);
8590
const wsClientRef = useRef<WSClient>(new WSClient());
8691

92+
const language = getInitialLanguage();
93+
const [prevLanguage, setPrevLanguage] = useState<string>(language);
94+
8795
useEffect(() => {
8896
isMounted.current = true;
8997
return () => {
@@ -218,6 +226,15 @@ const APIProvider = ({ children }: PropsWithChildren<TAPIProviderProps>) => {
218226
return () => clearTimeout(reconnectTimerId);
219227
}, [reconnect]);
220228

229+
// reconnects to latest WS url for new language only when language changes
230+
useEffect(() => {
231+
if (prevLanguage !== language) {
232+
setReconnect(true);
233+
setPrevLanguage(language);
234+
}
235+
// eslint-disable-next-line react-hooks/exhaustive-deps
236+
}, [language]);
237+
221238
return (
222239
<APIContext.Provider
223240
value={{

packages/api-v2/src/hooks/useCryptoTransactions.ts

+1-16
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import { useCallback, useEffect, useMemo, useState } from 'react';
22
import useSubscription from '../useSubscription';
3-
import useActiveAccount from './useActiveAccount';
4-
import useAuthorize from './useAuthorize';
5-
import { displayMoney } from '../utils';
63

74
type TTransaction = NonNullable<
85
NonNullable<ReturnType<typeof useSubscription<'cashier_payments'>>['data']>['cashier_payments']
@@ -26,13 +23,6 @@ type TModifiedTransaction = Omit<TTransaction, 'status_code' | 'transaction_type
2623
const useCryptoTransactions = () => {
2724
const { subscribe, data, ...rest } = useSubscription('cashier_payments');
2825
const [transactions, setTransactions] = useState<TModifiedTransaction[]>();
29-
const {
30-
data: { preferred_language },
31-
} = useAuthorize();
32-
33-
const { data: account } = useActiveAccount();
34-
const display_code = account?.currency_config?.display_code || 'USD';
35-
const fractional_digits = account?.currency_config?.fractional_digits || 2;
3626

3727
// Reset transactions data
3828
const resetData = useCallback(() => setTransactions(undefined), []);
@@ -72,17 +62,12 @@ const useCryptoTransactions = () => {
7262

7363
return transactions.map(transaction => ({
7464
...transaction,
75-
/** Formatted amount */
76-
formatted_amount: displayMoney(transaction.amount || 0, display_code, {
77-
fractional_digits,
78-
preferred_language,
79-
}),
8065
/** Determine if the transaction is a deposit or not. */
8166
is_deposit: transaction.transaction_type === 'deposit',
8267
/** Determine if the transaction is a withdrawal or not. */
8368
is_withdrawal: transaction.transaction_type === 'withdrawal',
8469
}));
85-
}, [display_code, fractional_digits, preferred_language, transactions]);
70+
}, [transactions]);
8671

8772
// Sort transactions by submit time.
8873
const sorted_transactions = useMemo(

packages/api-v2/src/hooks/useCtraderAccountsList.ts

+3-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import useTradingAccountsList from './useTradingAccountsList';
88

99
/** A custom hook that gets the list of created cTrader accounts. */
1010
const useCtraderAccountsList = () => {
11-
const { data: authorize_data, isSuccess } = useAuthorize();
11+
const { isSuccess } = useAuthorize();
1212
const { data: ctrader_accounts, ...rest } = useQuery('trading_platform_accounts', {
1313
payload: { platform: 'ctrader' },
1414
options: { enabled: isSuccess },
@@ -35,20 +35,12 @@ const useCtraderAccountsList = () => {
3535
/** The platform of the account */
3636
platform: 'ctrader' as const,
3737
/** Formatted display balance */
38-
display_balance: displayMoney(account.balance || 0, account.currency || 'USD', {
39-
preferred_language: authorize_data?.preferred_language,
40-
}),
38+
display_balance: displayMoney(account.balance || 0, account.currency || 'USD'),
4139
/** Converted balance from the exchange rate */
4240
converted_balance: getExchangeRate(fiat_account, account.currency ?? 'USD') * balance,
4341
};
4442
}),
45-
[
46-
authorize_data?.preferred_language,
47-
fiat_account,
48-
getConfig,
49-
getExchangeRate,
50-
ctrader_accounts?.trading_platform_accounts,
51-
]
43+
[fiat_account, getConfig, getExchangeRate, ctrader_accounts?.trading_platform_accounts]
5244
);
5345
return {
5446
/** List of all created cTrader accounts */

packages/api-v2/src/hooks/useDxtradeAccountsList.ts

+3-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import useExchangeRates from './useExchangeRates';
88

99
/** A custom hook that gets the list of created Deriv X accounts. */
1010
const useDxtradeAccountsList = () => {
11-
const { data: authorize_data, isSuccess } = useAuthorize();
11+
const { isSuccess } = useAuthorize();
1212
const { data: dxtrade_accounts, ...rest } = useQuery('trading_platform_accounts', {
1313
payload: { platform: 'dxtrade' },
1414
options: { enabled: isSuccess },
@@ -27,9 +27,7 @@ const useDxtradeAccountsList = () => {
2727
/** Account's currency config information */
2828
currency_config: account.currency ? getConfig(account.currency) : undefined,
2929
/** The balance of the account in currency format. */
30-
display_balance: displayMoney(account?.balance || 0, account?.currency || 'USD', {
31-
preferred_language: authorize_data?.preferred_language,
32-
}),
30+
display_balance: displayMoney(account?.balance || 0, account?.currency || 'USD'),
3331
/** indicating whether the account is a virtual-money account. */
3432
is_virtual: account.account_type === 'demo',
3533
/** Landing company shortcode the account belongs to. */
@@ -42,13 +40,7 @@ const useDxtradeAccountsList = () => {
4240
converted_balance: getExchangeRate(fiat_account, account.currency ?? 'USD') * balance,
4341
};
4442
}),
45-
[
46-
authorize_data?.preferred_language,
47-
dxtrade_accounts?.trading_platform_accounts,
48-
fiat_account,
49-
getConfig,
50-
getExchangeRate,
51-
]
43+
[dxtrade_accounts?.trading_platform_accounts, fiat_account, getConfig, getExchangeRate]
5244
);
5345

5446
return {

packages/api-v2/src/hooks/useInfiniteTransactions.ts

+3-15
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,7 @@ type TFilter = NonNullable<TSocketRequestPayload<'statement'>['payload']>['actio
1010

1111
/** A custom hook to get the summary of account transactions */
1212
const useInfiniteTransactions = () => {
13-
const {
14-
data: { preferred_language },
15-
isFetching,
16-
isSuccess,
17-
} = useAuthorize();
13+
const { isFetching, isSuccess } = useAuthorize();
1814

1915
const { data: account } = useActiveAccount();
2016
const display_code = account?.currency_config?.display_code || 'USD';
@@ -58,18 +54,10 @@ const useInfiniteTransactions = () => {
5854

5955
return flatten_data?.map(transaction => ({
6056
...transaction,
61-
/** The transaction amount in currency format. */
62-
display_amount: displayMoney(transaction?.amount || 0, display_code, {
63-
fractional_digits,
64-
preferred_language,
65-
}),
6657
/** The balance of account after the transaction in currency format. */
67-
display_balance_after: displayMoney(transaction?.balance_after || 0, display_code, {
68-
fractional_digits,
69-
preferred_language,
70-
}),
58+
display_balance_after: displayMoney(transaction?.balance_after || 0, display_code, { fractional_digits }),
7159
}));
72-
}, [flatten_data, preferred_language, fractional_digits, display_code]);
60+
}, [flatten_data, fractional_digits, display_code]);
7361

7462
return {
7563
/** List of account transactions */

packages/api-v2/src/hooks/useMT5AccountsList.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import useExchangeRates from './useExchangeRates';
88

99
/** A custom hook that gets the list created MT5 accounts of the user. */
1010
const useMT5AccountsList = () => {
11-
const { data: authorize_data, isSuccess } = useAuthorize();
11+
const { isSuccess } = useAuthorize();
1212
const { getConfig } = useCurrencyConfig();
1313
const { fiat_account } = useTradingAccountsList();
1414
const { getExchangeRate } = useExchangeRates();
@@ -34,9 +34,7 @@ const useMT5AccountsList = () => {
3434
/** The id of the account */
3535
loginid: account.login,
3636
/** The balance of the account in currency format. */
37-
display_balance: displayMoney(account.balance || 0, account.currency || 'USD', {
38-
preferred_language: authorize_data?.preferred_language,
39-
}),
37+
display_balance: displayMoney(account.balance || 0, account.currency || 'USD'),
4038
/** indicating whether the account is a virtual-money account. */
4139
is_virtual: account.account_type === 'demo',
4240
/** The platform of the account */
@@ -45,7 +43,7 @@ const useMT5AccountsList = () => {
4543
converted_balance: getExchangeRate(fiat_account, account.currency ?? 'USD') * balance,
4644
};
4745
});
48-
}, [authorize_data?.preferred_language, fiat_account, getConfig, getExchangeRate, mt5_accounts?.mt5_login_list]);
46+
}, [fiat_account, getConfig, getExchangeRate, mt5_accounts?.mt5_login_list]);
4947

5048
return {
5149
/** The list of created MT5 accounts */

packages/api-v2/src/hooks/useTransactions.ts

+4-14
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,7 @@ type TFilter = NonNullable<TSocketRequestPayload<'statement'>['payload']>['actio
1010

1111
/** A custom hook to get the summary of account transactions */
1212
const useTransactions = () => {
13-
const {
14-
data: { preferred_language },
15-
isFetching,
16-
isSuccess,
17-
} = useAuthorize();
13+
const { isFetching, isSuccess } = useAuthorize();
1814

1915
const { data: account } = useActiveAccount();
2016
const display_code = account?.currency_config?.display_code || 'USD';
@@ -52,17 +48,11 @@ const useTransactions = () => {
5248
return data?.statement?.transactions?.map(transaction => ({
5349
...transaction,
5450
/** The transaction amount in currency format. */
55-
display_amount: displayMoney(transaction?.amount || 0, display_code, {
56-
fractional_digits,
57-
preferred_language,
58-
}),
51+
display_amount: displayMoney(transaction?.amount || 0, display_code, { fractional_digits }),
5952
/** The balance of account after the transaction in currency format. */
60-
display_balance_after: displayMoney(transaction?.balance_after || 0, display_code, {
61-
fractional_digits,
62-
preferred_language,
63-
}),
53+
display_balance_after: displayMoney(transaction?.balance_after || 0, display_code, { fractional_digits }),
6454
}));
65-
}, [data?.statement?.transactions, display_code, fractional_digits, preferred_language]);
55+
}, [data?.statement?.transactions, display_code, fractional_digits]);
6656

6757
return {
6858
/** List of account transactions */

0 commit comments

Comments
 (0)