From 80b421b6696c597754ad8d0c3cb42c844c5e5a1c Mon Sep 17 00:00:00 2001 From: Miguel Araujo Perez Date: Thu, 22 Oct 2015 17:35:22 +0200 Subject: [PATCH 1/8] Added Android support Added java code for bridging current locale in an Android device to javascript. Beware that Android communicates values to javascript through callbacks or events emitted, this means communication is asynchronous. --- README.md | 9 ++++- android/build.gradle | 34 +++++++++++++++++++ android/src/main/AndroidManifest.xml | 4 +++ .../i18n/reactnativei18n/ReactNativeI18n.java | 32 +++++++++++++++++ .../ReactNativeI18nLocale.java | 31 +++++++++++++++++ index.js | 11 ++++-- 6 files changed, 118 insertions(+), 3 deletions(-) create mode 100755 android/build.gradle create mode 100644 android/src/main/AndroidManifest.xml create mode 100644 android/src/main/java/com/i18n/reactnativei18n/ReactNativeI18n.java create mode 100644 android/src/main/java/com/i18n/reactnativei18n/ReactNativeI18nLocale.java diff --git a/README.md b/README.md index 26b25a1..d4056c6 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,14 @@ You can get the device's locale with the `RNI18n` native module: ```js var deviceLocale = require('react-native').NativeModules.RNI18n.locale ``` -Returns `en_US`. + +Returns `en_US`. This equals to: + +```js +var I18n = require('react-native-i18n'); +var deviceLocale = I18n.locale; +``` + ### I18n.js documentation For more info about I18n.js methods (`localize`, `pluralize`, etc) and settings see [its documentation](https://github.com/fnando/i18n-js#setting-up). diff --git a/android/build.gradle b/android/build.gradle new file mode 100755 index 0000000..1f9f4e0 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,34 @@ +buildscript { + repositories { + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:1.1.3' + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.1" + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 22 + versionCode 1 + versionName "1.0" + } + lintOptions { + abortOnError false + } +} + +repositories { + mavenCentral() +} + +dependencies { + compile 'com.facebook.react:react-native:0.12.+' +} \ No newline at end of file diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000..17a0dbd --- /dev/null +++ b/android/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + diff --git a/android/src/main/java/com/i18n/reactnativei18n/ReactNativeI18n.java b/android/src/main/java/com/i18n/reactnativei18n/ReactNativeI18n.java new file mode 100644 index 0000000..2a1b608 --- /dev/null +++ b/android/src/main/java/com/i18n/reactnativei18n/ReactNativeI18n.java @@ -0,0 +1,32 @@ +package com.i18n.reactnativei18n; + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.JavaScriptModule; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ViewManager; + +import java.util.ArrayList; +import java.util.List; +import java.util.Collections; + + +public class ReactNativeI18n implements ReactPackage { + + @Override + public List createNativeModules(ReactApplicationContext reactContext) { + List modules = new ArrayList<>(); + modules.add(new ReactNativeI18nLocale(reactContext)); + return modules; + } + + @Override + public List> createJSModules() { + return Collections.emptyList(); + } + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } +} diff --git a/android/src/main/java/com/i18n/reactnativei18n/ReactNativeI18nLocale.java b/android/src/main/java/com/i18n/reactnativei18n/ReactNativeI18nLocale.java new file mode 100644 index 0000000..bb2daa8 --- /dev/null +++ b/android/src/main/java/com/i18n/reactnativei18n/ReactNativeI18nLocale.java @@ -0,0 +1,31 @@ +package com.i18n.reactnativei18n; + +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.Callback; + + +public class ReactNativeI18nLocale extends ReactContextBaseJavaModule { + + ReactContext reactContext; + + public ReactNativeI18nLocale(ReactApplicationContext reactContext) { + super(reactContext); + this.reactContext = reactContext; + } + + @Override + public String getName() { + return "RNI18n"; + } + + @ReactMethod + public void getCurrentLocale( + Callback successCallback + ) { + String current = reactContext.getResources().getConfiguration().locale.toString(); + successCallback.invoke(current); + } +} diff --git a/index.js b/index.js index 30db660..36c0217 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,15 @@ 'use strict'; +var Platform = require('Platform'); var I18n = require('./vendor/i18n'); var { RNI18n } = require('react-native').NativeModules; -I18n.locale = RNI18n.locale.replace(/_/, '-'); +if (Platform.OS === 'android') { + RNI18n.getCurrentLocale( function(locale) { + I18n.locale = locale.replace(/_/, '-'); + }); +} else { + I18n.locale = RNI18n.locale.replace(/_/, '-'); +} -module.exports = I18n; \ No newline at end of file +module.exports = I18n; From c1336d331f1ee026d60d7a6d5f8f119d8642e8f2 Mon Sep 17 00:00:00 2001 From: Miguel Araujo Perez Date: Wed, 11 Nov 2015 12:23:28 +0100 Subject: [PATCH 2/8] Updated README with Android installation instructions --- README.md | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d4056c6..8b2c7a4 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,56 @@ Integrates [I18n.js](https://github.com/fnando/i18n-js) with React Native. Uses `$ npm install react-native-i18n --save` +### iOS + Add `RNI18n.xcodeproj` to **Libraries** and add `libRNI18n.a` to **Link Binary With Libraries** under **Build Phases**. [More info and screenshots about how to do this is available in the React Native documentation](http://facebook.github.io/react-native/docs/linking-libraries.html). +### Android + +Add `react-native-i18n` to your `./android/settings.gradle` file as follows: + +``` +include ':app', ':react-native-i18n' +project(':react-native-i18n').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-i18n/android') +``` + +Include it as dependency in `./android/app/build.gradle` file: + +``` +dependencies { + ... + compile project(':react-native-i18n') +} +``` + +Finally, you need to add the package within the `ReactInstanceManager` of your MainActivity (`./android/app/src/main/java/your/bundle/MainActivity.java`): + +```java + +import com.i18n.reactnativei18n.ReactNativeI18n; // <---- import this one + +... + + +@Override +protected void onCreate(Bundle savedInstanceState) { + ... + + mReactInstanceManager = ReactInstanceManager.builder() + .setApplication(getApplication()) + .addPackage(new ReactNativeI18n()) // <---- add this line + .build(); + + ... +} + +... + +``` + + +After that, you will need to recompile your project with `react-native run-android`. + ## Usage ```js @@ -57,19 +105,22 @@ I18n.translations = { For a device with a `en_GB` locale this will return `Hi from the UK!'`, for a device with a `en_US` locale it will return `Hi!`. ### Device's locale + You can get the device's locale with the `RNI18n` native module: ```js var deviceLocale = require('react-native').NativeModules.RNI18n.locale ``` -Returns `en_US`. This equals to: +Returns `en_US`. You can also do: ```js var I18n = require('react-native-i18n'); var deviceLocale = I18n.locale; ``` +Returns `en-US`. + ### I18n.js documentation For more info about I18n.js methods (`localize`, `pluralize`, etc) and settings see [its documentation](https://github.com/fnando/i18n-js#setting-up). From b4873738428966dfa4530e03472eb3bed53e8d6e Mon Sep 17 00:00:00 2001 From: Jorge Maroto Date: Tue, 1 Dec 2015 11:51:58 +0100 Subject: [PATCH 3/8] Suport base language --- vendor/i18n.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/vendor/i18n.js b/vendor/i18n.js index eb0d402..96a1de6 100644 --- a/vendor/i18n.js +++ b/vendor/i18n.js @@ -82,6 +82,9 @@ // Set default locale. This locale will be used when fallback is enabled and // the translation doesn't exist in a particular locale. defaultLocale: "en" + // Set the base language. If it is not null, key will be returned directly when + // use this language in the device. + , baseLanguage: null // Set the current locale to `en`. , locale: "en" // Set the translation key separator. @@ -107,6 +110,10 @@ // the translation doesn't exist in a particular locale. this.defaultLocale = DEFAULT_OPTIONS.defaultLocale; + // Set the base language. If it is not null, key will be returned directly when + // use this language in the device. + this.baseLanguage = DEFAULT_OPTIONS.baseLanguage; + // Set the current locale to `en`. this.locale = DEFAULT_OPTIONS.locale; @@ -136,6 +143,9 @@ if (typeof(this.defaultLocale) === "undefined" && this.defaultLocale !== null) this.defaultLocale = DEFAULT_OPTIONS.defaultLocale; + if (typeof(this.baseLanguage) === "undefined" && this.baseLanguage !== null) + this.baseLanguage = DEFAULT_OPTIONS.baseLanguage; + if (typeof(this.locale) === "undefined" && this.locale !== null) this.locale = DEFAULT_OPTIONS.locale; @@ -280,6 +290,12 @@ while (locales.length) { locale = locales.shift(); + + if (this.baseLanguage !== null && locale == this.baseLanguage) { + console.log(`Devolviendo inglés: ${scope}`) + return scope; + } + scopes = scope.split(this.defaultSeparator); translations = this.translations[locale]; From 141f0c59952a6791e27ccd727e3e29398be9271f Mon Sep 17 00:00:00 2001 From: Jorge Maroto Date: Tue, 1 Dec 2015 11:55:17 +0100 Subject: [PATCH 4/8] Removing console.log --- vendor/i18n.js | 1 - 1 file changed, 1 deletion(-) diff --git a/vendor/i18n.js b/vendor/i18n.js index 96a1de6..bcd7807 100644 --- a/vendor/i18n.js +++ b/vendor/i18n.js @@ -292,7 +292,6 @@ locale = locales.shift(); if (this.baseLanguage !== null && locale == this.baseLanguage) { - console.log(`Devolviendo inglés: ${scope}`) return scope; } From cd6e47dfc0893d7959a0a5dc6e907ded4b3d8046 Mon Sep 17 00:00:00 2001 From: Jorge Maroto Date: Fri, 11 Dec 2015 13:17:27 +0100 Subject: [PATCH 5/8] Update requires to be compatible with ES6 --- index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 36c0217..4fbe376 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,7 @@ 'use strict'; -var Platform = require('Platform'); -var I18n = require('./vendor/i18n'); -var { RNI18n } = require('react-native').NativeModules; +let { Platform, NativeModules/RNI18N } = require('react-native') +let I18n = require('./vendor/i18n') if (Platform.OS === 'android') { RNI18n.getCurrentLocale( function(locale) { From 8699f6d752eb8d30f994fc4424b021792410018f Mon Sep 17 00:00:00 2001 From: Jorge Maroto Date: Fri, 11 Dec 2015 13:37:50 +0100 Subject: [PATCH 6/8] FIX last commit --- index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 4fbe376..f6ac696 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ 'use strict'; -let { Platform, NativeModules/RNI18N } = require('react-native') +let { Platform, NativeModules } = require('react-native') +let { RNI18N } = NativeModules let I18n = require('./vendor/i18n') if (Platform.OS === 'android') { From e062a7e807d611320e38c341edc3c7b4e699960a Mon Sep 17 00:00:00 2001 From: Miguel Araujo Perez Date: Mon, 14 Dec 2015 11:39:36 +0100 Subject: [PATCH 7/8] Wrong variable name --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index f6ac696..491d148 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ 'use strict'; let { Platform, NativeModules } = require('react-native') -let { RNI18N } = NativeModules +let { RNI18n } = NativeModules let I18n = require('./vendor/i18n') if (Platform.OS === 'android') { From 9ab02d1c5717e34043893394f3f799d6be3e15d5 Mon Sep 17 00:00:00 2001 From: Jorge Maroto Date: Wed, 16 Dec 2015 10:56:29 +0100 Subject: [PATCH 8/8] Move deployment target to 8.0 This should remove some XCode warnings --- RNI18n.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RNI18n.xcodeproj/project.pbxproj b/RNI18n.xcodeproj/project.pbxproj index e7434c8..6384e50 100644 --- a/RNI18n.xcodeproj/project.pbxproj +++ b/RNI18n.xcodeproj/project.pbxproj @@ -232,7 +232,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -268,7 +268,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES;