mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-01-19 05:45:15 +01:00
ADD: RTL language support
This commit is contained in:
parent
4fc332a504
commit
1458fcadda
@ -16,6 +16,7 @@
|
|||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
|
|
||||||
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name"
|
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name"
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
#import <React/RCTLinkingManager.h>
|
#import <React/RCTLinkingManager.h>
|
||||||
#import <React/RCTBundleURLProvider.h>
|
#import <React/RCTBundleURLProvider.h>
|
||||||
|
#import <React/RCTI18nUtil.h>
|
||||||
#import <React/RCTRootView.h>
|
#import <React/RCTRootView.h>
|
||||||
#import "RNQuickActionManager.h"
|
#import "RNQuickActionManager.h"
|
||||||
#import <UserNotifications/UserNotifications.h>
|
#import <UserNotifications/UserNotifications.h>
|
||||||
@ -64,6 +65,7 @@ static void InitializeFlipper(UIApplication *application) {
|
|||||||
// Define UNUserNotificationCenter
|
// Define UNUserNotificationCenter
|
||||||
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
||||||
center.delegate = self;
|
center.delegate = self;
|
||||||
|
[[RCTI18nUtil sharedInstance] allowRTL:YES];
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,13 +249,13 @@ PODS:
|
|||||||
- React
|
- React
|
||||||
- react-native-blur (0.8.0):
|
- react-native-blur (0.8.0):
|
||||||
- React
|
- React
|
||||||
- react-native-camera (3.42.0):
|
- react-native-camera (3.42.2):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-camera/RCT (= 3.42.0)
|
- react-native-camera/RCT (= 3.42.2)
|
||||||
- react-native-camera/RN (= 3.42.0)
|
- react-native-camera/RN (= 3.42.2)
|
||||||
- react-native-camera/RCT (3.42.0):
|
- react-native-camera/RCT (3.42.2):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-camera/RN (3.42.0):
|
- react-native-camera/RN (3.42.2):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-document-picker (3.5.4):
|
- react-native-document-picker (3.5.4):
|
||||||
- React
|
- React
|
||||||
@ -263,7 +263,7 @@ PODS:
|
|||||||
- React
|
- React
|
||||||
- react-native-idle-timer (2.1.6):
|
- react-native-idle-timer (2.1.6):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-image-picker (3.1.4):
|
- react-native-image-picker (3.2.1):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-is-catalyst (1.0.0):
|
- react-native-is-catalyst (1.0.0):
|
||||||
- React
|
- React
|
||||||
@ -276,7 +276,7 @@ PODS:
|
|||||||
- react-native-tcp-socket (3.7.1):
|
- react-native-tcp-socket (3.7.1):
|
||||||
- CocoaAsyncSocket
|
- CocoaAsyncSocket
|
||||||
- React
|
- React
|
||||||
- react-native-webview (11.2.1):
|
- react-native-webview (11.2.3):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-widget-center (0.0.4):
|
- react-native-widget-center (0.0.4):
|
||||||
- React
|
- React
|
||||||
@ -359,13 +359,13 @@ PODS:
|
|||||||
- React-Core
|
- React-Core
|
||||||
- RNFS (2.16.6):
|
- RNFS (2.16.6):
|
||||||
- React
|
- React
|
||||||
- RNGestureHandler (1.9.0):
|
- RNGestureHandler (1.10.1):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNHandoff (0.0.3):
|
- RNHandoff (0.0.3):
|
||||||
- React
|
- React
|
||||||
- RNInAppBrowser (3.5.1):
|
- RNInAppBrowser (3.5.1):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNLocalize (2.0.1):
|
- RNLocalize (2.0.2):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNPrivacySnapshot (1.0.0):
|
- RNPrivacySnapshot (1.0.0):
|
||||||
- React
|
- React
|
||||||
@ -697,17 +697,17 @@ SPEC CHECKSUMS:
|
|||||||
React-jsinspector: 8e68ffbfe23880d3ee9bafa8be2777f60b25cbe2
|
React-jsinspector: 8e68ffbfe23880d3ee9bafa8be2777f60b25cbe2
|
||||||
react-native-blue-crypto: 23f1558ad3d38d7a2edb7e2f6ed1bc520ed93e56
|
react-native-blue-crypto: 23f1558ad3d38d7a2edb7e2f6ed1bc520ed93e56
|
||||||
react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c
|
react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c
|
||||||
react-native-camera: d145df27a9178041b48b839b80ad79c9ef373fbd
|
react-native-camera: 48557b70b49c5c8a099b0600d774ba374cf18587
|
||||||
react-native-document-picker: c5752781fbc0c126c627c1549b037c139444a4cf
|
react-native-document-picker: c5752781fbc0c126c627c1549b037c139444a4cf
|
||||||
react-native-fingerprint-scanner: c68136ca57e3704d7bdf5faa554ea535ce15b1d0
|
react-native-fingerprint-scanner: c68136ca57e3704d7bdf5faa554ea535ce15b1d0
|
||||||
react-native-idle-timer: 97b8283237d45146a7a5c25bdebe9e1e85f3687b
|
react-native-idle-timer: 97b8283237d45146a7a5c25bdebe9e1e85f3687b
|
||||||
react-native-image-picker: 248afb60a0c5a24153cb7c7483b257f30541323b
|
react-native-image-picker: 0c28bf3cb089cfe840bc5cc9fac3dcc10f2188d9
|
||||||
react-native-is-catalyst: 52ee70e0123c82419dd4ce47dc4cc94b22467512
|
react-native-is-catalyst: 52ee70e0123c82419dd4ce47dc4cc94b22467512
|
||||||
react-native-randombytes: 45ae693012df24c9a07a5e578b3b567c01468581
|
react-native-randombytes: 45ae693012df24c9a07a5e578b3b567c01468581
|
||||||
react-native-safe-area-context: 86612d2c9a9e94e288319262d10b5f93f0b395f5
|
react-native-safe-area-context: 86612d2c9a9e94e288319262d10b5f93f0b395f5
|
||||||
react-native-slider: b733e17fdd31186707146debf1f04b5d94aa1a93
|
react-native-slider: b733e17fdd31186707146debf1f04b5d94aa1a93
|
||||||
react-native-tcp-socket: 96a4f104cdcc9c6621aafe92937f163d88447c5b
|
react-native-tcp-socket: 96a4f104cdcc9c6621aafe92937f163d88447c5b
|
||||||
react-native-webview: dbe6c1ad149740f0e2d84a963f1d3c3e77f2d99c
|
react-native-webview: 36561eaf7508e67f72d8c959b713bac841f3652e
|
||||||
react-native-widget-center: 0f81d17beb163e7fb5848b06754d7d277fe7d99a
|
react-native-widget-center: 0f81d17beb163e7fb5848b06754d7d277fe7d99a
|
||||||
React-RCTActionSheet: 53ea72699698b0b47a6421cb1c8b4ab215a774aa
|
React-RCTActionSheet: 53ea72699698b0b47a6421cb1c8b4ab215a774aa
|
||||||
React-RCTAnimation: 1befece0b5183c22ae01b966f5583f42e69a83c2
|
React-RCTAnimation: 1befece0b5183c22ae01b966f5583f42e69a83c2
|
||||||
@ -728,10 +728,10 @@ SPEC CHECKSUMS:
|
|||||||
RNDefaultPreference: 21816c0a6f61a2829ccc0cef034392e9b509ee5f
|
RNDefaultPreference: 21816c0a6f61a2829ccc0cef034392e9b509ee5f
|
||||||
RNDeviceInfo: 54401b60514387f9120ab8265be5ed9103d842b9
|
RNDeviceInfo: 54401b60514387f9120ab8265be5ed9103d842b9
|
||||||
RNFS: 2bd9eb49dc82fa9676382f0585b992c424cd59df
|
RNFS: 2bd9eb49dc82fa9676382f0585b992c424cd59df
|
||||||
RNGestureHandler: 9b7e605a741412e20e13c512738a31bd1611759b
|
RNGestureHandler: 5e58135436aacc1c5d29b75547d3d2b9430d052c
|
||||||
RNHandoff: d3b0754cca3a6bcd9b25f544f733f7f033ccf5fa
|
RNHandoff: d3b0754cca3a6bcd9b25f544f733f7f033ccf5fa
|
||||||
RNInAppBrowser: 3733c1aa6699983a1c9b4963e85d5e5a48ad297e
|
RNInAppBrowser: 3733c1aa6699983a1c9b4963e85d5e5a48ad297e
|
||||||
RNLocalize: dcf0fdb332b37b0d24178e876a7ce4dbbc9c838d
|
RNLocalize: 47e22ef8c36df1d572e42a87c8ae22e3fcf551dd
|
||||||
RNPrivacySnapshot: 71919dde3c6a29dd332115409c2aec564afee8f4
|
RNPrivacySnapshot: 71919dde3c6a29dd332115409c2aec564afee8f4
|
||||||
RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93
|
RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93
|
||||||
RNRate: 2b31dad120cd1b78e33c6034808561c386a3dddf
|
RNRate: 2b31dad120cd1b78e33c6034808561c386a3dddf
|
||||||
@ -752,4 +752,4 @@ SPEC CHECKSUMS:
|
|||||||
|
|
||||||
PODFILE CHECKSUM: 070fb164a2dfb94605ea7862fd9b1c25e95ff046
|
PODFILE CHECKSUM: 070fb164a2dfb94605ea7862fd9b1c25e95ff046
|
||||||
|
|
||||||
COCOAPODS: 1.10.0
|
COCOAPODS: 1.10.1
|
||||||
|
@ -295,7 +295,7 @@
|
|||||||
"groundcontrol_explanation": "GroundControl is a free, open-source push notifications server for Bitcoin wallets. You can install your own GroundControl server and put its URL here to not rely on BlueWallet’s infrastructure. Leave blank to use GroundControl’s default server.",
|
"groundcontrol_explanation": "GroundControl is a free, open-source push notifications server for Bitcoin wallets. You can install your own GroundControl server and put its URL here to not rely on BlueWallet’s infrastructure. Leave blank to use GroundControl’s default server.",
|
||||||
"header": "Settings",
|
"header": "Settings",
|
||||||
"language": "Language",
|
"language": "Language",
|
||||||
"language_restart": "When selecting a new language, restarting BlueWallet may be required for the change to take effect.",
|
"language_isRTL": "Restarting BlueWallet is required for the language orientation to take effect.",
|
||||||
"lightning_error_lndhub_uri": "Not a valid LNDHub URI",
|
"lightning_error_lndhub_uri": "Not a valid LNDHub URI",
|
||||||
"lightning_saved": "Your changes have been saved successfully.",
|
"lightning_saved": "Your changes have been saved successfully.",
|
||||||
"lightning_settings": "Lightning Settings",
|
"lightning_settings": "Lightning Settings",
|
||||||
|
@ -9,6 +9,7 @@ import BigNumber from 'bignumber.js';
|
|||||||
import { AppStorage } from '../class';
|
import { AppStorage } from '../class';
|
||||||
import { BitcoinUnit } from '../models/bitcoinUnits';
|
import { BitcoinUnit } from '../models/bitcoinUnits';
|
||||||
import { AvailableLanguages } from './languages';
|
import { AvailableLanguages } from './languages';
|
||||||
|
import { I18nManager } from 'react-native';
|
||||||
const currency = require('../blue_modules/currency');
|
const currency = require('../blue_modules/currency');
|
||||||
|
|
||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
@ -130,8 +131,15 @@ const setDateTimeLocale = async () => {
|
|||||||
}
|
}
|
||||||
if (localeForDayJSAvailable) {
|
if (localeForDayJSAvailable) {
|
||||||
dayjs.locale(lang.split('_')[0]);
|
dayjs.locale(lang.split('_')[0]);
|
||||||
|
const language = AvailableLanguages.find(language => language.value === lang.replace('_', '-'));
|
||||||
|
if (language?.isRTL) {
|
||||||
|
I18nManager.forceRTL(true);
|
||||||
|
} else {
|
||||||
|
I18nManager.forceRTL(false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dayjs.locale('en');
|
dayjs.locale('en');
|
||||||
|
I18nManager.forceRTL(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -150,6 +158,7 @@ const setLanguageLocale = async () => {
|
|||||||
} else {
|
} else {
|
||||||
strings.saveLanguage('en');
|
strings.saveLanguage('en');
|
||||||
strings.setLanguage('en');
|
strings.setLanguage('en');
|
||||||
|
I18nManager.forceRTL(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export const AvailableLanguages = Object.freeze([
|
export const AvailableLanguages = Object.freeze([
|
||||||
{ label: 'English', value: 'en' },
|
{ label: 'English', value: 'en' },
|
||||||
{ label: 'Afrikaans (AFR)', value: 'zar_afr' },
|
{ label: 'Afrikaans (AFR)', value: 'zar_afr' },
|
||||||
{ label: 'Arabic (AR)', value: 'ar' },
|
{ label: 'Arabic (AR)', value: 'ar', isRTL: true },
|
||||||
{ label: 'Български (BG)', value: 'bg_bg' },
|
{ label: 'Български (BG)', value: 'bg_bg' },
|
||||||
{ label: 'Català (CA)', value: 'ca' },
|
{ label: 'Català (CA)', value: 'ca' },
|
||||||
{ label: 'Chinese (TW)', value: 'zh_tw' },
|
{ label: 'Chinese (TW)', value: 'zh_tw' },
|
||||||
@ -14,7 +14,7 @@ export const AvailableLanguages = Object.freeze([
|
|||||||
{ label: 'Español (Spain) (es_ES)', value: 'es' },
|
{ label: 'Español (Spain) (es_ES)', value: 'es' },
|
||||||
{ label: 'Español (Latin America) (es_419)', value: 'es_419' },
|
{ label: 'Español (Latin America) (es_419)', value: 'es_419' },
|
||||||
{ label: 'Ελληνικά (EL)', value: 'el' },
|
{ label: 'Ελληνικά (EL)', value: 'el' },
|
||||||
{ label: 'فارسی (FA)', value: 'fa' },
|
{ label: 'فارسی (FA)', value: 'fa', isRTL: true },
|
||||||
{ label: 'Français (FR)', value: 'fr_fr' },
|
{ label: 'Français (FR)', value: 'fr_fr' },
|
||||||
{ label: 'עִברִית (HE)', value: 'he' },
|
{ label: 'עִברִית (HE)', value: 'he' },
|
||||||
{ label: 'Italiano (IT)', value: 'it' },
|
{ label: 'Italiano (IT)', value: 'it' },
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* global alert */
|
||||||
import React, { useState, useEffect, useContext } from 'react';
|
import React, { useState, useEffect, useContext } from 'react';
|
||||||
import { FlatList, StyleSheet } from 'react-native';
|
import { FlatList, StyleSheet } from 'react-native';
|
||||||
import { useNavigation, useTheme } from '@react-navigation/native';
|
import { useNavigation, useTheme } from '@react-navigation/native';
|
||||||
@ -37,10 +38,16 @@ const Language = () => {
|
|||||||
const renderItem = item => {
|
const renderItem = item => {
|
||||||
return (
|
return (
|
||||||
<BlueListItem
|
<BlueListItem
|
||||||
onPress={async () => {
|
onPress={() => {
|
||||||
await loc.saveLanguage(item.item.value);
|
const currentLanguage = AvailableLanguages.find(language => language.value === selectedLanguage);
|
||||||
setSelectedLanguage(item.item.value);
|
if (currentLanguage.isRTL || item.item.isRTL) {
|
||||||
setLanguage();
|
alert(loc.settings.language_isRTL);
|
||||||
|
}
|
||||||
|
|
||||||
|
loc.saveLanguage(item.item.value).then(() => {
|
||||||
|
setSelectedLanguage(item.item.value);
|
||||||
|
setLanguage();
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
title={item.item.label}
|
title={item.item.label}
|
||||||
checkmark={selectedLanguage === item.item.value}
|
checkmark={selectedLanguage === item.item.value}
|
||||||
|
Loading…
Reference in New Issue
Block a user