diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..8d73aad --- /dev/null +++ b/.npmignore @@ -0,0 +1,44 @@ +# OSX +# +.DS_Store + +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate +project.xcworkspace + +# Android/IJ +# +*.iml +.idea +.gradle +local.properties + +# node.js +# +node_modules/ +npm-debug.log + +# BUCK +buck-out/ +\.buckd/ +android/app/libs +android/keystores/debug.keystore + +# npmignore +sample diff --git a/README.md b/README.md new file mode 100644 index 0000000..b5c6488 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# react-native-simple-toast +React Native Toast component for both Android and iOS. It just let iOS have the same toast performance with Android. Using [scalessec/Toast](https://github.com/scalessec/Toast) for iOS; + +## Install +You can use [rnpm](https://github.com/rnpm/rnpm) to install native component easily; + +```bash +npm install react-native-simple-toast --save +npm link +``` + +## Usage + +It's just the same as [ToastAndroid](http://facebook.github.io/react-native/docs/toastandroid.html) + +```javascript +import Toast from 'react-native-simple-toast'; + +Toast.show('This is a toast.'); +Toast.show('This is a long toast.',Toast.LONG); +``` diff --git a/index.android.js b/index.android.js deleted file mode 100644 index 114bcc3..0000000 --- a/index.android.js +++ /dev/null @@ -1,11 +0,0 @@ -import {ToastAndroid} from 'react-native'; - -var SimpleToast = { - SHORT: ToastAndroid.SHORT, - LONG: ToastAndroid.LONG, - show: function (message:string, duration:number):void { - ToastAndroid.show(message, duration === undefined ? this.SHORT : duration); - } -}; - -export default SimpleToast; diff --git a/index.ios.js b/index.ios.js deleted file mode 100644 index c913ebb..0000000 --- a/index.ios.js +++ /dev/null @@ -1,13 +0,0 @@ -import {NativeModules} from 'react-native'; - -var RCTToastModule = NativeModules.LRDRCTSimpleToast; - -var SimpleToast = { - SHORT: RCTToastModule.SHORT, - LONG: RCTToastModule.LONG, - show: function (message:string, duration:number):void { - RCTToastModule.show(message, duration === undefined ? this.SHORT : duration); - } -}; - -export default SimpleToast; diff --git a/index.js b/index.js new file mode 100644 index 0000000..ec70f07 --- /dev/null +++ b/index.js @@ -0,0 +1,31 @@ +import {NativeModules,ToastAndroid,Platform} from 'react-native'; + +var RCTToastAndroid = Platform.OS === 'android' ? ToastAndroid : NativeModules.LRDRCTSimpleToast; + +var SimpleToast = { + // Toast duration constants + SHORT: RCTToastAndroid.SHORT, + LONG: RCTToastAndroid.LONG, + + // Toast gravity constants + TOP: RCTToastAndroid.TOP, + BOTTOM: RCTToastAndroid.BOTTOM, + CENTER: RCTToastAndroid.CENTER, + + show: function ( + message, + duration + ) { + RCTToastAndroid.show(message, duration === undefined ? this.SHORT : duration); + }, + + showWithGravity: function ( + message, + duration, + gravity, + ) { + RCTToastAndroid.showWithGravity(message, duration === undefined ? this.SHORT : duration, gravity); + }, +}; + +export default SimpleToast; diff --git a/ios/LRDRCTSimpleToast.xcodeproj/project.xcworkspace/xcuserdata/luoruidong.xcuserdatad/UserInterfaceState.xcuserstate b/ios/LRDRCTSimpleToast.xcodeproj/project.xcworkspace/xcuserdata/luoruidong.xcuserdatad/UserInterfaceState.xcuserstate index 1964936..70cccd4 100644 Binary files a/ios/LRDRCTSimpleToast.xcodeproj/project.xcworkspace/xcuserdata/luoruidong.xcuserdatad/UserInterfaceState.xcuserstate and b/ios/LRDRCTSimpleToast.xcodeproj/project.xcworkspace/xcuserdata/luoruidong.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ios/LRDRCTSimpleToast/LRDRCTSimpleToast.m b/ios/LRDRCTSimpleToast/LRDRCTSimpleToast.m index d848a93..f78bcc5 100644 --- a/ios/LRDRCTSimpleToast/LRDRCTSimpleToast.m +++ b/ios/LRDRCTSimpleToast/LRDRCTSimpleToast.m @@ -9,42 +9,94 @@ #import "RCTBridgeModule.h" #import "UIView+Toast.h" -NSInteger const LRDRCTSimpleToastBottomOffset = 28; +NSInteger const LRDRCTSimpleToastBottomOffset = 40; double const LRDRCTSimpleToastShortDuration = 3.0; double const LRDRCTSimpleToastLongDuration = 5.0; +NSInteger const LRDRCTSimpleToastGravityBottom = 1; +NSInteger const LRDRCTSimpleToastGravityCenter = 2; +NSInteger const LRDRCTSimpleToastGravityTop = 3; @interface LRDRCTSimpleToast : NSObject @end -@implementation LRDRCTSimpleToast +@implementation LRDRCTSimpleToast { + CGFloat _keyOffset; +} + +- (instancetype)init { + if (self = [super init]) { + _keyOffset = 0; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(keyboardWasShown:) + name:UIKeyboardDidShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(keyboardWillHiden:) + name:UIKeyboardWillHideNotification + object:nil]; + } + return self; +} + +- (void)keyboardWasShown:(NSNotification *)notification { + + CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; + + int height = MIN(keyboardSize.height,keyboardSize.width); + int width = MAX(keyboardSize.height,keyboardSize.width); + + _keyOffset = height; +} + +- (void)keyboardWillHiden:(NSNotification *)notification { + _keyOffset = 0; +} + RCT_EXPORT_MODULE() - (NSDictionary *)constantsToExport { return @{ @"SHORT": [NSNumber numberWithDouble:LRDRCTSimpleToastShortDuration], - @"LONG": [NSNumber numberWithDouble:LRDRCTSimpleToastLongDuration] + @"LONG": [NSNumber numberWithDouble:LRDRCTSimpleToastLongDuration], + @"BOTTOM": [NSNumber numberWithInteger:LRDRCTSimpleToastGravityBottom], + @"CENTER": [NSNumber numberWithInteger:LRDRCTSimpleToastGravityCenter], + @"TOP": [NSNumber numberWithInteger:LRDRCTSimpleToastGravityTop] }; } RCT_EXPORT_METHOD(show:(NSString *)msg duration:(double)duration { - [self _show:msg duration:duration]; + [self _show:msg duration:duration gravity:LRDRCTSimpleToastGravityBottom]; }); -- (void)_show:(NSString *)msg duration:(NSTimeInterval)duration { +RCT_EXPORT_METHOD(showWithGravity:(NSString *)msg duration:(double)duration gravity:(nonnull NSNumber *)gravity{ + [self _show:msg duration:duration gravity:gravity.intValue]; +}); + +- (void)_show:(NSString *)msg duration:(NSTimeInterval)duration gravity:(NSInteger)gravity { dispatch_async(dispatch_get_main_queue(), ^{ UIView *root = [[[[[UIApplication sharedApplication] delegate] window] rootViewController] view]; CGRect bound = root.bounds; - if (bound.size.height > LRDRCTSimpleToastBottomOffset) { - bound.size.height -= LRDRCTSimpleToastBottomOffset; + bound.size.height -= _keyOffset; + if (bound.size.height > LRDRCTSimpleToastBottomOffset*2) { + bound.origin.y += LRDRCTSimpleToastBottomOffset; + bound.size.height -= LRDRCTSimpleToastBottomOffset*2; } UIView *view = [[UIView alloc] initWithFrame:bound]; view.userInteractionEnabled = NO; [root addSubview:view]; UIView __weak *blockView = view; + id position; + if (gravity == LRDRCTSimpleToastGravityTop) { + position = CSToastPositionTop; + } else if (gravity == LRDRCTSimpleToastGravityCenter) { + position = CSToastPositionCenter; + } else { + position = CSToastPositionBottom; + } [view makeToast:msg duration:duration - position:[CSToastManager defaultPosition] + position:position title:nil image:nil style:nil diff --git a/package.json b/package.json index 51a0138..d19ffbc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-native-simple-toast", - "version": "0.0.1", - "description": "simple toast for react-native. In Android it's just native toast, in iOS it's https://github.com/scalessec/Toast", + "version": "0.0.5", + "description": "Simple Toast for react-native. In Android it's just native toast, in iOS it's https://github.com/scalessec/Toast", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" @@ -10,10 +10,10 @@ "react-native", "toast" ], - "author": "lrdcq", - "license": "ISC", - "dependencies": { - "react": "15.1.0", - "react-native": "^0.28.0" - } + "repository": { + "type": "git", + "url": "git+https://github.com/xgfe/react-native-simple-toast.git" + }, + "author": "xgfe", + "license": "MIT" } diff --git a/sample/android/app/src/main/AndroidManifest.xml b/sample/android/app/src/main/AndroidManifest.xml index 564892c..59f2b3d 100644 --- a/sample/android/app/src/main/AndroidManifest.xml +++ b/sample/android/app/src/main/AndroidManifest.xml @@ -1,30 +1,32 @@ + package="com.samples" + android:versionCode="1" + android:versionName="1.0"> - + + android:minSdkVersion="16" + android:targetSdkVersion="22"/> - - - - - - - + android:name=".MainApplication" + android:allowBackup="true" + android:label="@string/app_name" + android:icon="@mipmap/ic_launcher" + android:theme="@style/AppTheme"> + + + + + + + + diff --git a/sample/android/app/src/main/java/com/samples/MainActivity.java b/sample/android/app/src/main/java/com/samples/MainActivity.java index fa870ea..eddff3e 100644 --- a/sample/android/app/src/main/java/com/samples/MainActivity.java +++ b/sample/android/app/src/main/java/com/samples/MainActivity.java @@ -17,24 +17,4 @@ public class MainActivity extends ReactActivity { protected String getMainComponentName() { return "samples"; } - - /** - * Returns whether dev mode should be enabled. - * This enables e.g. the dev menu. - */ - @Override - protected boolean getUseDeveloperSupport() { - return BuildConfig.DEBUG; - } - - /** - * A list of packages used by the app. If the app uses additional views - * or modules besides the default ones, add more packages here. - */ - @Override - protected List getPackages() { - return Arrays.asList( - new MainReactPackage() - ); - } } diff --git a/sample/android/app/src/main/java/com/samples/MainApplication.java b/sample/android/app/src/main/java/com/samples/MainApplication.java new file mode 100644 index 0000000..9d03373 --- /dev/null +++ b/sample/android/app/src/main/java/com/samples/MainApplication.java @@ -0,0 +1,34 @@ +package com.samples; + +import com.facebook.react.ReactApplication; +import com.facebook.react.ReactNativeHost; +import com.facebook.react.ReactPackage; +import com.facebook.react.shell.MainReactPackage; + +import android.app.Application; + +import java.util.Arrays; +import java.util.List; + + +public class MainApplication extends Application implements ReactApplication { + + private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { + @Override + protected boolean getUseDeveloperSupport() { + return BuildConfig.DEBUG; + } + + @Override + protected List getPackages() { + return Arrays.asList(new MainReactPackage()); + } + }; + + @Override + public ReactNativeHost getReactNativeHost() { + return mReactNativeHost; + } + + +} diff --git a/sample/android/build.gradle b/sample/android/build.gradle index fcba4c5..dea8311 100644 --- a/sample/android/build.gradle +++ b/sample/android/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:1.3.1' + classpath 'com.android.tools.build:gradle:2.1.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/sample/android/gradle/wrapper/gradle-wrapper.properties b/sample/android/gradle/wrapper/gradle-wrapper.properties index b9fbfab..b01a7bd 100644 --- a/sample/android/gradle/wrapper/gradle-wrapper.properties +++ b/sample/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Tue Oct 11 11:35:38 CST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip diff --git a/sample/index.android.js b/sample/index.android.js index cb77ad9..4d53930 100644 --- a/sample/index.android.js +++ b/sample/index.android.js @@ -12,7 +12,7 @@ import { Text, View } from 'react-native'; -import Toast from './node_modules/react-native-simple-toast/index.android'; +import Toast from 'react-native-simple-toast'; class samples extends Component { render() { return ( @@ -26,7 +26,10 @@ class samples extends Component { {Toast.show("This is a Toast",Toast.LONG)}}> Tap to show Toast! - + + {Toast.showWithGravity("This is a Toast Center",Toast.LONG,Toast.CENTER)}}> + Tap to show Toast Center! + ); } diff --git a/sample/index.ios.js b/sample/index.ios.js index c91822e..4d53930 100644 --- a/sample/index.ios.js +++ b/sample/index.ios.js @@ -12,7 +12,7 @@ import { Text, View } from 'react-native'; -import Toast from './node_modules/react-native-simple-toast/index.ios'; +import Toast from 'react-native-simple-toast'; class samples extends Component { render() { return ( @@ -26,7 +26,10 @@ class samples extends Component { {Toast.show("This is a Toast",Toast.LONG)}}> Tap to show Toast! - + + {Toast.showWithGravity("This is a Toast Center",Toast.LONG,Toast.CENTER)}}> + Tap to show Toast Center! + ); } diff --git a/sample/package.json b/sample/package.json index 6a9f61d..c4d1df5 100644 --- a/sample/package.json +++ b/sample/package.json @@ -6,7 +6,8 @@ "start": "react-native start" }, "dependencies": { - "react": "15.1.0", - "react-native": "^0.28.0" + "react": "15.3.0", + "react-native": "^0.34.1", + "react-native-simple-toast": "0.0.5" } }