expo-localization 15.0.1 → 15.0.3
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 +10 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/localization/LocalizationModule.kt +26 -8
- package/android/src/main/java/expo/modules/localization/LocalizationPackage.kt +1 -1
- package/android/src/main/res/values/strings.xml +1 -0
- package/ios/LocalizationModule.swift +16 -5
- package/package.json +2 -2
- package/plugin/build/withExpoLocalization.d.ts +1 -0
- package/plugin/build/withExpoLocalization.js +26 -9
- package/plugin/src/withExpoLocalization.ts +33 -12
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 15.0.3 — 2024-05-06
|
|
14
|
+
|
|
15
|
+
### 🎉 New features
|
|
16
|
+
|
|
17
|
+
- Added a `forcesRTL` manifest flag for forcing RTL to be on. ([#28129](https://github.com/expo/expo/pull/28129) by [@aleqsio](https://github.com/aleqsio))
|
|
18
|
+
|
|
19
|
+
## 15.0.2 — 2024-05-01
|
|
20
|
+
|
|
21
|
+
_This version does not introduce any user-facing changes._
|
|
22
|
+
|
|
13
23
|
## 15.0.1 — 2024-04-23
|
|
14
24
|
|
|
15
25
|
_This version does not introduce any user-facing changes._
|
package/android/build.gradle
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
apply plugin: 'com.android.library'
|
|
2
2
|
|
|
3
3
|
group = 'host.exp.exponent'
|
|
4
|
-
version = '15.0.
|
|
4
|
+
version = '15.0.3'
|
|
5
5
|
|
|
6
6
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
7
7
|
apply from: expoModulesCorePlugin
|
|
@@ -14,7 +14,7 @@ android {
|
|
|
14
14
|
namespace "expo.modules.localization"
|
|
15
15
|
defaultConfig {
|
|
16
16
|
versionCode 22
|
|
17
|
-
versionName "15.0.
|
|
17
|
+
versionName "15.0.3"
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -22,7 +22,7 @@ import java.util.*
|
|
|
22
22
|
// must be kept in sync with https://github.com/facebook/react-native/blob/main/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nUtil.java
|
|
23
23
|
private const val SHARED_PREFS_NAME = "com.facebook.react.modules.i18nmanager.I18nUtil"
|
|
24
24
|
private const val KEY_FOR_PREFS_ALLOWRTL = "RCTI18nUtil_allowRTL"
|
|
25
|
-
|
|
25
|
+
private const val KEY_FOR_PREFS_FORCERTL = "RCTI18nUtil_forceRTL"
|
|
26
26
|
private const val LOCALE_SETTINGS_CHANGED = "onLocaleSettingsChanged"
|
|
27
27
|
private const val CALENDAR_SETTINGS_CHANGED = "onCalendarSettingsChanged"
|
|
28
28
|
|
|
@@ -70,14 +70,31 @@ class LocalizationModule : Module() {
|
|
|
70
70
|
// These keys are used by React Native here: https://github.com/facebook/react-native/blob/main/React/Modules/RCTI18nUtil.m
|
|
71
71
|
// We set them before React loads to ensure it gets rendered correctly the first time the app is opened.
|
|
72
72
|
val supportsRTL = appContext.reactContext?.getString(R.string.ExpoLocalization_supportsRTL)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
val forcesRTL = appContext.reactContext?.getString(R.string.ExpoLocalization_forcesRTL)
|
|
74
|
+
|
|
75
|
+
if (forcesRTL == "true") {
|
|
76
|
+
context
|
|
77
|
+
.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE)
|
|
78
|
+
.edit()
|
|
79
|
+
.also {
|
|
80
|
+
it.putBoolean(KEY_FOR_PREFS_ALLOWRTL, true)
|
|
81
|
+
it.putBoolean(KEY_FOR_PREFS_FORCERTL, true)
|
|
82
|
+
it.apply()
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
if (supportsRTL == "true" || supportsRTL == "false") {
|
|
86
|
+
context
|
|
87
|
+
.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE)
|
|
88
|
+
.edit()
|
|
89
|
+
.also {
|
|
90
|
+
it.putBoolean(KEY_FOR_PREFS_ALLOWRTL, supportsRTL == "true")
|
|
91
|
+
if (forcesRTL == "false") {
|
|
92
|
+
it.putBoolean(KEY_FOR_PREFS_FORCERTL, false)
|
|
93
|
+
}
|
|
94
|
+
it.apply()
|
|
95
|
+
}
|
|
80
96
|
}
|
|
97
|
+
}
|
|
81
98
|
}
|
|
82
99
|
|
|
83
100
|
// TODO: Bacon: add set language
|
|
@@ -114,6 +131,7 @@ class LocalizationModule : Module() {
|
|
|
114
131
|
}
|
|
115
132
|
locales
|
|
116
133
|
} else {
|
|
134
|
+
@Suppress("DEPRECATION")
|
|
117
135
|
listOf(configuration.locale)
|
|
118
136
|
}
|
|
119
137
|
}
|
|
@@ -24,7 +24,7 @@ object Notifier {
|
|
|
24
24
|
|
|
25
25
|
// TODO: Move to new listener API once it's available
|
|
26
26
|
class LocalizationPackage : Package {
|
|
27
|
-
override fun createApplicationLifecycleListeners(context: Context?): List<
|
|
27
|
+
override fun createApplicationLifecycleListeners(context: Context?): List<ApplicationLifecycleListener> {
|
|
28
28
|
return listOf(object : ApplicationLifecycleListener {
|
|
29
29
|
override fun onConfigurationChanged(newConfig: Configuration?) {
|
|
30
30
|
super.onConfigurationChanged(newConfig)
|
|
@@ -23,8 +23,12 @@ public class LocalizationModule: Module {
|
|
|
23
23
|
return Self.getCalendars()
|
|
24
24
|
}
|
|
25
25
|
OnCreate {
|
|
26
|
-
if let
|
|
27
|
-
self.
|
|
26
|
+
if let forceRTL = Bundle.main.object(forInfoDictionaryKey: "ExpoLocalization_forcesRTL") as? Bool {
|
|
27
|
+
self.setRTLPreferences(true, forceRTL)
|
|
28
|
+
} else {
|
|
29
|
+
if let enableRTL = Bundle.main.object(forInfoDictionaryKey: "ExpoLocalization_supportsRTL") as? Bool {
|
|
30
|
+
self.setRTLPreferences(enableRTL, false)
|
|
31
|
+
}
|
|
28
32
|
}
|
|
29
33
|
}
|
|
30
34
|
|
|
@@ -53,13 +57,20 @@ public class LocalizationModule: Module {
|
|
|
53
57
|
return NSLocale.characterDirection(forLanguage: NSLocale.preferredLanguages.first ?? "en-US") == NSLocale.LanguageDirection.rightToLeft
|
|
54
58
|
}
|
|
55
59
|
|
|
56
|
-
func
|
|
60
|
+
func setRTLPreferences(_ supportsRTL: Bool, _ forceRTL: Bool) {
|
|
57
61
|
// These keys are used by React Native here: https://github.com/facebook/react-native/blob/main/React/Modules/RCTI18nUtil.m
|
|
58
62
|
// We set them before React loads to ensure it gets rendered correctly the first time the app is opened.
|
|
59
63
|
// On iOS we need to set both forceRTL and allowRTL so apps don't have to include localization strings.
|
|
60
64
|
// Uses required reason API based on the following reason: CA92.1
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
|
|
66
|
+
if forceRTL {
|
|
67
|
+
UserDefaults.standard.set(true, forKey: "RCTI18nUtil_allowRTL")
|
|
68
|
+
UserDefaults.standard.set(true, forKey: "RCTI18nUtil_forceRTL")
|
|
69
|
+
} else {
|
|
70
|
+
UserDefaults.standard.set(supportsRTL, forKey: "RCTI18nUtil_allowRTL")
|
|
71
|
+
UserDefaults.standard.set(supportsRTL ? isRTLPreferredForCurrentLocale() : false, forKey: "RCTI18nUtil_forceRTL")
|
|
72
|
+
}
|
|
73
|
+
|
|
63
74
|
UserDefaults.standard.synchronize()
|
|
64
75
|
}
|
|
65
76
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-localization",
|
|
3
|
-
"version": "15.0.
|
|
3
|
+
"version": "15.0.3",
|
|
4
4
|
"description": "Provides an interface for native user localization information.",
|
|
5
5
|
"main": "build/Localization.js",
|
|
6
6
|
"types": "build/Localization.d.ts",
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"expo": "*"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "7995f30a8d2af4836f3aef9fe322e9403fc23d34"
|
|
51
51
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ExpoConfig } from '@expo/config-types';
|
|
2
2
|
type ConfigPluginProps = {
|
|
3
3
|
supportsRTL?: boolean;
|
|
4
|
+
forcesRTL?: boolean;
|
|
4
5
|
allowDynamicLocaleChangesAndroid?: boolean;
|
|
5
6
|
};
|
|
6
7
|
declare function withExpoLocalization(config: ExpoConfig, data?: ConfigPluginProps): ExpoConfig;
|
|
@@ -2,14 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const Manifest_1 = require("@expo/config-plugins/build/android/Manifest");
|
|
4
4
|
const config_plugins_1 = require("expo/config-plugins");
|
|
5
|
-
function withExpoLocalizationIos(config) {
|
|
6
|
-
|
|
5
|
+
function withExpoLocalizationIos(config, data) {
|
|
6
|
+
const mergedConfig = { ...config.extra, ...data };
|
|
7
|
+
if (mergedConfig?.supportsRTL == null && mergedConfig?.forcesRTL == null)
|
|
7
8
|
return config;
|
|
8
9
|
if (!config.ios)
|
|
9
10
|
config.ios = {};
|
|
10
11
|
if (!config.ios.infoPlist)
|
|
11
12
|
config.ios.infoPlist = {};
|
|
12
|
-
|
|
13
|
+
if (mergedConfig?.supportsRTL != null) {
|
|
14
|
+
config.ios.infoPlist.ExpoLocalization_supportsRTL = mergedConfig?.supportsRTL;
|
|
15
|
+
}
|
|
16
|
+
if (mergedConfig?.forcesRTL != null) {
|
|
17
|
+
config.ios.infoPlist.ExpoLocalization_forcesRTL = mergedConfig?.forcesRTL;
|
|
18
|
+
}
|
|
13
19
|
return config;
|
|
14
20
|
}
|
|
15
21
|
function withExpoLocalizationAndroid(config, data) {
|
|
@@ -26,12 +32,23 @@ function withExpoLocalizationAndroid(config, data) {
|
|
|
26
32
|
});
|
|
27
33
|
}
|
|
28
34
|
return (0, config_plugins_1.withStringsXml)(config, (config) => {
|
|
29
|
-
config.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
const mergedConfig = { ...config.extra, ...data };
|
|
36
|
+
if (mergedConfig?.supportsRTL != null) {
|
|
37
|
+
config.modResults = config_plugins_1.AndroidConfig.Strings.setStringItem([
|
|
38
|
+
{
|
|
39
|
+
$: { name: 'ExpoLocalization_supportsRTL', translatable: 'false' },
|
|
40
|
+
_: String(mergedConfig?.supportsRTL ?? 'unset'),
|
|
41
|
+
},
|
|
42
|
+
], config.modResults);
|
|
43
|
+
}
|
|
44
|
+
if (mergedConfig?.forcesRTL != null) {
|
|
45
|
+
config.modResults = config_plugins_1.AndroidConfig.Strings.setStringItem([
|
|
46
|
+
{
|
|
47
|
+
$: { name: 'ExpoLocalization_forcesRTL', translatable: 'false' },
|
|
48
|
+
_: String(mergedConfig?.forcesRTL ?? 'unset'),
|
|
49
|
+
},
|
|
50
|
+
], config.modResults);
|
|
51
|
+
}
|
|
35
52
|
return config;
|
|
36
53
|
});
|
|
37
54
|
}
|
|
@@ -9,14 +9,21 @@ import {
|
|
|
9
9
|
|
|
10
10
|
type ConfigPluginProps = {
|
|
11
11
|
supportsRTL?: boolean;
|
|
12
|
+
forcesRTL?: boolean;
|
|
12
13
|
allowDynamicLocaleChangesAndroid?: boolean;
|
|
13
14
|
};
|
|
14
15
|
|
|
15
|
-
function withExpoLocalizationIos(config: ExpoConfig) {
|
|
16
|
-
|
|
16
|
+
function withExpoLocalizationIos(config: ExpoConfig, data: ConfigPluginProps) {
|
|
17
|
+
const mergedConfig = { ...config.extra, ...data };
|
|
18
|
+
if (mergedConfig?.supportsRTL == null && mergedConfig?.forcesRTL == null) return config;
|
|
17
19
|
if (!config.ios) config.ios = {};
|
|
18
20
|
if (!config.ios.infoPlist) config.ios.infoPlist = {};
|
|
19
|
-
|
|
21
|
+
if (mergedConfig?.supportsRTL != null) {
|
|
22
|
+
config.ios.infoPlist.ExpoLocalization_supportsRTL = mergedConfig?.supportsRTL;
|
|
23
|
+
}
|
|
24
|
+
if (mergedConfig?.forcesRTL != null) {
|
|
25
|
+
config.ios.infoPlist.ExpoLocalization_forcesRTL = mergedConfig?.forcesRTL;
|
|
26
|
+
}
|
|
20
27
|
return config;
|
|
21
28
|
}
|
|
22
29
|
|
|
@@ -34,15 +41,29 @@ function withExpoLocalizationAndroid(config: ExpoConfig, data: ConfigPluginProps
|
|
|
34
41
|
});
|
|
35
42
|
}
|
|
36
43
|
return withStringsXml(config, (config) => {
|
|
37
|
-
config.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
const mergedConfig = { ...config.extra, ...data };
|
|
45
|
+
if (mergedConfig?.supportsRTL != null) {
|
|
46
|
+
config.modResults = AndroidConfig.Strings.setStringItem(
|
|
47
|
+
[
|
|
48
|
+
{
|
|
49
|
+
$: { name: 'ExpoLocalization_supportsRTL', translatable: 'false' },
|
|
50
|
+
_: String(mergedConfig?.supportsRTL ?? 'unset'),
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
config.modResults
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
if (mergedConfig?.forcesRTL != null) {
|
|
57
|
+
config.modResults = AndroidConfig.Strings.setStringItem(
|
|
58
|
+
[
|
|
59
|
+
{
|
|
60
|
+
$: { name: 'ExpoLocalization_forcesRTL', translatable: 'false' },
|
|
61
|
+
_: String(mergedConfig?.forcesRTL ?? 'unset'),
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
config.modResults
|
|
65
|
+
);
|
|
66
|
+
}
|
|
46
67
|
return config;
|
|
47
68
|
});
|
|
48
69
|
}
|