diff --git a/README.md b/README.md index 26b25a1..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,12 +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`. + +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). 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; 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..491d148 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,15 @@ 'use strict'; -var I18n = require('./vendor/i18n'); -var { RNI18n } = require('react-native').NativeModules; +let { Platform, NativeModules } = require('react-native') +let { RNI18n } = NativeModules +let I18n = require('./vendor/i18n') -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; diff --git a/vendor/i18n.js b/vendor/i18n.js index eb0d402..bcd7807 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,11 @@ while (locales.length) { locale = locales.shift(); + + if (this.baseLanguage !== null && locale == this.baseLanguage) { + return scope; + } + scopes = scope.split(this.defaultSeparator); translations = this.translations[locale];