Merge pull request #8 from ticketea/master

Added Android support
This commit is contained in:
Alexander Zaytsev 2015-12-22 11:06:39 +05:00
commit a0cdd64da0
8 changed files with 188 additions and 7 deletions

View File

@ -6,8 +6,56 @@ Integrates [I18n.js](https://github.com/fnando/i18n-js) with React Native. Uses
`$ npm install react-native-i18n --save` `$ 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). 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 ## Usage
```js ```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!`. 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 ### Device's locale
You can get the device's locale with the `RNI18n` native module: You can get the device's locale with the `RNI18n` native module:
```js ```js
var deviceLocale = require('react-native').NativeModules.RNI18n.locale 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 ### 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). For more info about I18n.js methods (`localize`, `pluralize`, etc) and settings see [its documentation](https://github.com/fnando/i18n-js#setting-up).

View File

@ -232,7 +232,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.3; IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -268,7 +268,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.3; IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;

34
android/build.gradle Executable file
View File

@ -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.+'
}

View File

@ -0,0 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.i18n.reactnativei18n">
</manifest>

View File

@ -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<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new ReactNativeI18nLocale(reactContext));
return modules;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}

View File

@ -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);
}
}

View File

@ -1,8 +1,15 @@
'use strict'; 'use strict';
var I18n = require('./vendor/i18n'); let { Platform, NativeModules } = require('react-native')
var { RNI18n } = require('react-native').NativeModules; 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; module.exports = I18n;

15
vendor/i18n.js vendored
View File

@ -82,6 +82,9 @@
// Set default locale. This locale will be used when fallback is enabled and // Set default locale. This locale will be used when fallback is enabled and
// the translation doesn't exist in a particular locale. // the translation doesn't exist in a particular locale.
defaultLocale: "en" 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`. // Set the current locale to `en`.
, locale: "en" , locale: "en"
// Set the translation key separator. // Set the translation key separator.
@ -107,6 +110,10 @@
// the translation doesn't exist in a particular locale. // the translation doesn't exist in a particular locale.
this.defaultLocale = DEFAULT_OPTIONS.defaultLocale; 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`. // Set the current locale to `en`.
this.locale = DEFAULT_OPTIONS.locale; this.locale = DEFAULT_OPTIONS.locale;
@ -136,6 +143,9 @@
if (typeof(this.defaultLocale) === "undefined" && this.defaultLocale !== null) if (typeof(this.defaultLocale) === "undefined" && this.defaultLocale !== null)
this.defaultLocale = DEFAULT_OPTIONS.defaultLocale; 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) if (typeof(this.locale) === "undefined" && this.locale !== null)
this.locale = DEFAULT_OPTIONS.locale; this.locale = DEFAULT_OPTIONS.locale;
@ -280,6 +290,11 @@
while (locales.length) { while (locales.length) {
locale = locales.shift(); locale = locales.shift();
if (this.baseLanguage !== null && locale == this.baseLanguage) {
return scope;
}
scopes = scope.split(this.defaultSeparator); scopes = scope.split(this.defaultSeparator);
translations = this.translations[locale]; translations = this.translations[locale];