From e09ca3d6a79ccc68882bc5e70cad79e1df994681 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Sat, 18 Nov 2017 18:17:24 -0200 Subject: [PATCH] Push notification on android (#84) --- android/app/build.gradle | 1 + android/app/src/main/AndroidManifest.xml | 30 +++++ .../com/rocketchatrn/MainApplication.java | 5 +- android/settings.gradle | 3 +- app/lib/rocketchat.js | 19 +++- app/presentation/RoomItem.js | 2 +- app/push.js | 36 ++++++ app/sagas/init.js | 1 - app/sagas/login.js | 2 + app/views/RoomsListView.js | 16 +-- index.android.js | 4 +- index.ios.js | 2 +- ios/RocketChatRN.xcodeproj/project.pbxproj | 107 ++++++++++++++++++ ios/RocketChatRN/AppDelegate.m | 27 +++++ package-lock.json | 99 +++++++++++++++- package.json | 7 +- 16 files changed, 332 insertions(+), 29 deletions(-) create mode 100644 app/push.js diff --git a/android/app/build.gradle b/android/app/build.gradle index 986dcfde..808336bb 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -150,6 +150,7 @@ dependencies { compile project(':react-native-fetch-blob') compile project(':react-native-zeroconf') compile project(':realm') + compile project(':react-native-push-notification') compile fileTree(dir: "libs", include: ["*.jar"]) compile "com.android.support:appcompat-v7:23.0.1" compile "com.facebook.react:react-native:+" // From node_modules diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 2b5ce37c..645ff882 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,6 +7,14 @@ + + + + + + @@ -28,6 +36,28 @@ + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/java/com/rocketchatrn/MainApplication.java b/android/app/src/main/java/com/rocketchatrn/MainApplication.java index 71794a94..e81c036e 100644 --- a/android/app/src/main/java/com/rocketchatrn/MainApplication.java +++ b/android/app/src/main/java/com/rocketchatrn/MainApplication.java @@ -13,7 +13,7 @@ import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebook.react.shell.MainReactPackage; import com.facebook.soloader.SoLoader; - +import com.dieam.reactnativepushnotification.ReactNativePushNotificationPackage; import java.util.Arrays; import java.util.List; @@ -34,7 +34,8 @@ public class MainApplication extends Application implements ReactApplication { new VectorIconsPackage(), new RNFetchBlobPackage(), new ZeroconfReactPackage(), - new RealmReactPackage() + new RealmReactPackage(), + new ReactNativePushNotificationPackage() ); } }; diff --git a/android/settings.gradle b/android/settings.gradle index fcc9db10..61081513 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -11,5 +11,6 @@ include ':react-native-zeroconf' project(':react-native-zeroconf').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-zeroconf/android') include ':realm' project(':realm').projectDir = new File(rootProject.projectDir, '../node_modules/realm/android') - +include ':react-native-push-notification' +project(':react-native-push-notification').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-push-notification/android') include ':app' diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 70d394b5..b4bcdea3 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -1,6 +1,6 @@ import Meteor from 'react-native-meteor'; import Random from 'react-native-meteor/lib/Random'; -import { AsyncStorage } from 'react-native'; +import { AsyncStorage, Platform } from 'react-native'; import { hashPassword } from 'react-native-meteor/lib/utils'; import RNFetchBlob from 'react-native-fetch-blob'; @@ -254,6 +254,21 @@ const RocketChat = { return cb && cb(); }); }, + registerPushToken(id, token) { + const key = Platform.OS === 'ios' ? 'apn' : 'gcm'; + const data = { + id: `RocketChatRN${ id }`, + token: { [key]: token }, + appName: 'main', + userId: id, + metadata: {} + }; + return call('raix:push-update', data); + }, + + updatePushToken(pushId) { + return call('raix:push-setuser', pushId); + }, loadMessagesForRoom(rid, end, cb) { return new Promise((resolve, reject) => { @@ -432,8 +447,8 @@ const RocketChat = { } }, getRooms() { + const { server, login } = reduxStore.getState(); return Promise.all([call('subscriptions/get'), call('rooms/get')]).then(([subscriptions, rooms]) => { - const { server, login } = reduxStore.getState(); const data = subscriptions.map((subscription) => { subscription._updatedAt = (rooms.find(room => room._id === subscription.rid) || {})._updatedAt; subscription._server = { id: server.server }; diff --git a/app/presentation/RoomItem.js b/app/presentation/RoomItem.js index fd294202..6f143076 100644 --- a/app/presentation/RoomItem.js +++ b/app/presentation/RoomItem.js @@ -66,7 +66,7 @@ export default class RoomItem extends React.PureComponent { static propTypes = { type: PropTypes.string.isRequired, name: PropTypes.string.isRequired, - _updatedAt: PropTypes.date, + _updatedAt: PropTypes.instanceOf(Date), unread: PropTypes.number, baseUrl: PropTypes.string, onPress: PropTypes.func, diff --git a/app/push.js b/app/push.js new file mode 100644 index 00000000..df993636 --- /dev/null +++ b/app/push.js @@ -0,0 +1,36 @@ +import PushNotification from 'react-native-push-notification'; +import { AsyncStorage } from 'react-native'; + +PushNotification.configure({ + + // (optional) Called when Token is generated (iOS and Android) + async onRegister({ token }) { + AsyncStorage.setItem('pushId', token); + }, + + // (required) Called when a remote or local notification is opened or received + onNotification(notification) { + console.log('NOTIFICATION:', notification); + }, + + // ANDROID ONLY: GCM Sender ID (optional - not required for local notifications, but is need to receive remote push notifications) + senderID: '673693445664', + + // IOS ONLY (optional): default: all - Permissions to register. + permissions: { + alert: true, + badge: true, + sound: true + }, + + // Should the initial notification be popped automatically + // default: true + popInitialNotification: false, + + /** + * (optional) default: true + * - Specified if permissions (ios) and token (android and ios) will requested or not, + * - if not, you must call PushNotificationsHandler.requestPermissions() later + */ + requestPermissions: true +}); diff --git a/app/sagas/init.js b/app/sagas/init.js index c86b5caa..26255156 100644 --- a/app/sagas/init.js +++ b/app/sagas/init.js @@ -17,7 +17,6 @@ const restore = function* restore() { if (currentServer) { yield put(setServer(currentServer)); } - yield put(actions.appReady({})); } catch (e) { console.log(e); diff --git a/app/sagas/login.js b/app/sagas/login.js index bd9b5287..b02ff994 100644 --- a/app/sagas/login.js +++ b/app/sagas/login.js @@ -62,6 +62,8 @@ const saveToken = function* saveToken() { const [server, user] = yield all([select(getServer), select(getUser)]); yield AsyncStorage.setItem(RocketChat.TOKEN_KEY, user.token); yield AsyncStorage.setItem(`${ RocketChat.TOKEN_KEY }-${ server }`, JSON.stringify(user)); + const token = yield AsyncStorage.getItem('pushId'); + yield token && RocketChat.registerPushToken(user.user.id, token); }; const handleLoginRequest = function* handleLoginRequest({ credentials }) { diff --git a/app/views/RoomsListView.js b/app/views/RoomsListView.js index 06228adc..010a098b 100644 --- a/app/views/RoomsListView.js +++ b/app/views/RoomsListView.js @@ -91,8 +91,7 @@ export default class RoomsListView extends React.Component { size={26} backgroundColor='transparent' onPress={params.createChannel} - /> - ); + />); return { headerRight }; }; @@ -102,10 +101,7 @@ export default class RoomsListView extends React.Component { this.state = { dataSource: [], - searching: false, - searchDataSource: [], - searchText: '', - login: false + searchText: '' }; this.data = realm.objects('subscriptions').filtered('_server.id = $0', this.props.server).sorted('_updatedAt', true); } @@ -118,7 +114,6 @@ export default class RoomsListView extends React.Component { }); this.setState({ - ...this.state, dataSource: ds.cloneWithRows(this.data) }); } @@ -138,8 +133,7 @@ export default class RoomsListView extends React.Component { onSearchChangeText = (text) => { const searchText = text.trim(); this.setState({ - searchText: text, - searching: searchText !== '' + searchText: text }); if (searchText === '') { return this.setState({ @@ -206,9 +200,7 @@ export default class RoomsListView extends React.Component { const clearSearch = () => { this.setState({ - searchText: '', - searching: false, - searchDataSource: [] + searchText: '' }); }; diff --git a/index.android.js b/index.android.js index 460c0b87..c0528220 100644 --- a/index.android.js +++ b/index.android.js @@ -2,8 +2,10 @@ import 'babel-polyfill'; import 'regenerator-runtime/runtime'; import { AppRegistry } from 'react-native'; - +import './app/push'; import RocketChat from './app/index'; + + // import { AppRegistry } from 'react-native'; // import Routes from './app/routes'; // diff --git a/index.ios.js b/index.ios.js index e0da1173..df7c5d93 100644 --- a/index.ios.js +++ b/index.ios.js @@ -3,9 +3,9 @@ import 'regenerator-runtime/runtime'; import { AppRegistry } from 'react-native'; +import './app/push'; import RocketChat from './app/index'; // import { AppRegistry } from 'react-native'; // import Routes from './app/routes'; // AppRegistry.registerComponent('RocketChatRN', () => RocketChat); - diff --git a/ios/RocketChatRN.xcodeproj/project.pbxproj b/ios/RocketChatRN.xcodeproj/project.pbxproj index 7ec2a0d4..265cb70e 100644 --- a/ios/RocketChatRN.xcodeproj/project.pbxproj +++ b/ios/RocketChatRN.xcodeproj/project.pbxproj @@ -49,6 +49,7 @@ 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 8A159EDB97C44E52AF62D69C /* libRNSVG.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA50CE47374C4C35BE6D9D58 /* libRNSVG.a */; }; AE5D35882AE04CC29630FB3D /* Entypo.ttf in Resources */ = {isa = PBXBuildFile; fileRef = DC6EE17B5550465E98C70FF0 /* Entypo.ttf */; }; + B88F586F1FBF57F600B352B8 /* libRCTPushNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88F58461FBF55E200B352B8 /* libRCTPushNotification.a */; }; B8E79AF41F3CD167005B464F /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB61A68108700A75B9A /* Info.plist */; }; BED2B77AA660460E8BC9F8E0 /* libRNFetchBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6533FB90166345D29F1B91C0 /* libRNFetchBlob.a */; }; C758F0BD5C3244E2BA073E61 /* libRNImagePicker.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B696712EE2345A59F007A88 /* libRNImagePicker.a */; }; @@ -296,6 +297,48 @@ remoteGlobalIDString = 58B5119B1A9E6C1200147676; remoteInfo = RCTText; }; + B88F58451FBF55E200B352B8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B88F58361FBF55E200B352B8 /* RCTPushNotification.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 134814201AA4EA6300B7C361; + remoteInfo = RCTPushNotification; + }; + B88F58471FBF55E200B352B8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B88F58361FBF55E200B352B8 /* RCTPushNotification.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3D05745F1DE6004600184BB4; + remoteInfo = "RCTPushNotification-tvOS"; + }; + B88F58521FBF55E200B352B8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3DBE0D001F3B181A0099AA32; + remoteInfo = fishhook; + }; + B88F58541FBF55E200B352B8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3DBE0D0D1F3B181C0099AA32; + remoteInfo = "fishhook-tvOS"; + }; + B88F58641FBF55E200B352B8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 9936F3131F5F2E4B0010BF04; + remoteInfo = privatedata; + }; + B88F58661FBF55E200B352B8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 9936F32F1F5F2E5B0010BF04; + remoteInfo = "privatedata-tvOS"; + }; B8E79A8D1F3CCC6D005B464F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4CD38E4891ED4601B7481448 /* RNFetchBlob.xcodeproj */; @@ -368,6 +411,7 @@ 9A1E1766CCB84C91A62BD5A6 /* Foundation.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Foundation.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Foundation.ttf"; sourceTree = ""; }; A18EFC3B0CFE40E0918A8F0C /* EvilIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = EvilIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf"; sourceTree = ""; }; B37C79D9BD0742CE936B6982 /* libc++.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; + B88F58361FBF55E200B352B8 /* RCTPushNotification.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTPushNotification.xcodeproj; path = "../node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj"; sourceTree = ""; }; BAAE4B947F5D44959F0A9D5A /* libRNZeroconf.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNZeroconf.a; sourceTree = ""; }; C23AEF1D9EBE4A38A1A6B97B /* RNSVG.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNSVG.xcodeproj; path = "../node_modules/react-native-svg/ios/RNSVG.xcodeproj"; sourceTree = ""; }; DA50CE47374C4C35BE6D9D58 /* libRNSVG.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNSVG.a; sourceTree = ""; }; @@ -391,6 +435,7 @@ buildActionMask = 2147483647; files = ( 146834051AC3E58100842450 /* libReact.a in Frameworks */, + B88F586F1FBF57F600B352B8 /* libRCTPushNotification.a in Frameworks */, 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */, 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, @@ -510,6 +555,8 @@ children = ( 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */, 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */, + B88F58531FBF55E200B352B8 /* libfishhook.a */, + B88F58551FBF55E200B352B8 /* libfishhook-tvOS.a */, ); name = Products; sourceTree = ""; @@ -543,6 +590,8 @@ 607D610F1F325B7E00F639C4 /* libthird-party.a */, 607D61111F325B7E00F639C4 /* libdouble-conversion.a */, 607D61131F325B7E00F639C4 /* libdouble-conversion.a */, + B88F58651FBF55E200B352B8 /* libprivatedata.a */, + B88F58671FBF55E200B352B8 /* libprivatedata-tvOS.a */, ); name = Products; sourceTree = ""; @@ -592,6 +641,7 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( + B88F58361FBF55E200B352B8 /* RCTPushNotification.xcodeproj */, 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */, 146833FF1AC3E56700842450 /* React.xcodeproj */, 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, @@ -665,6 +715,15 @@ name = Resources; sourceTree = ""; }; + B88F58371FBF55E200B352B8 /* Products */ = { + isa = PBXGroup; + children = ( + B88F58461FBF55E200B352B8 /* libRCTPushNotification.a */, + B88F58481FBF55E200B352B8 /* libRCTPushNotification-tvOS.a */, + ); + name = Products; + sourceTree = ""; + }; B8E79A681F3CCC69005B464F /* Recovered References */ = { isa = PBXGroup; children = ( @@ -854,6 +913,10 @@ ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */; ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; }, + { + ProductGroup = B88F58371FBF55E200B352B8 /* Products */; + ProjectRef = B88F58361FBF55E200B352B8 /* RCTPushNotification.xcodeproj */; + }, { ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */; ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; @@ -1134,6 +1197,48 @@ remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + B88F58461FBF55E200B352B8 /* libRCTPushNotification.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libRCTPushNotification.a; + remoteRef = B88F58451FBF55E200B352B8 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + B88F58481FBF55E200B352B8 /* libRCTPushNotification-tvOS.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libRCTPushNotification-tvOS.a"; + remoteRef = B88F58471FBF55E200B352B8 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + B88F58531FBF55E200B352B8 /* libfishhook.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libfishhook.a; + remoteRef = B88F58521FBF55E200B352B8 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + B88F58551FBF55E200B352B8 /* libfishhook-tvOS.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libfishhook-tvOS.a"; + remoteRef = B88F58541FBF55E200B352B8 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + B88F58651FBF55E200B352B8 /* libprivatedata.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libprivatedata.a; + remoteRef = B88F58641FBF55E200B352B8 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + B88F58671FBF55E200B352B8 /* libprivatedata-tvOS.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libprivatedata-tvOS.a"; + remoteRef = B88F58661FBF55E200B352B8 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; B8E79A8E1F3CCC6D005B464F /* libRNFetchBlob.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -1393,6 +1498,7 @@ "$(SRCROOT)/../node_modules/react-native-image-picker/ios", "$(SRCROOT)/../node_modules/react-native-navigation/ios/**", "$(SRCROOT)/../node_modules/react-native-autogrow-textinput/ios", + "$(SRCROOT)/../node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj/**", ); INFOPLIST_FILE = RocketChatRN/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1427,6 +1533,7 @@ "$(SRCROOT)/../node_modules/react-native-image-picker/ios", "$(SRCROOT)/../node_modules/react-native-navigation/ios/**", "$(SRCROOT)/../node_modules/react-native-autogrow-textinput/ios", + "$(SRCROOT)/../node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj/**", ); INFOPLIST_FILE = RocketChatRN/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; diff --git a/ios/RocketChatRN/AppDelegate.m b/ios/RocketChatRN/AppDelegate.m index 0cb97ee6..576c1e4d 100644 --- a/ios/RocketChatRN/AppDelegate.m +++ b/ios/RocketChatRN/AppDelegate.m @@ -9,6 +9,7 @@ #import "AppDelegate.h" +#import #import #import @@ -34,4 +35,30 @@ return YES; } +// Required to register for notifications + - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings + { + [RCTPushNotificationManager didRegisterUserNotificationSettings:notificationSettings]; + } + // Required for the register event. + - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken + { + [RCTPushNotificationManager didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; + } + // Required for the notification event. You must call the completion handler after handling the remote notification. + - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo + fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler + { + [RCTPushNotificationManager didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; + } + // Required for the registrationError event. + - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error + { + [RCTPushNotificationManager didFailToRegisterForRemoteNotificationsWithError:error]; + } + // Required for the localNotification event. + - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification + { + [RCTPushNotificationManager didReceiveLocalNotification:notification]; + } @end diff --git a/package-lock.json b/package-lock.json index 0412b89f..641edeab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1058,6 +1058,12 @@ "integrity": "sha1-NOmzALFHnd2Y7HfqC76TQt/jloQ=", "dev": true }, + "babel-helper-is-react-class": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-is-react-class/-/babel-helper-is-react-class-1.0.0.tgz", + "integrity": "sha1-7282eLBcdtve7a3q16+YwnJNhDE=", + "dev": true + }, "babel-helper-is-void-0": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/babel-helper-is-void-0/-/babel-helper-is-void-0-0.2.0.tgz", @@ -1801,6 +1807,15 @@ "babel-runtime": "6.26.0" } }, + "babel-plugin-transform-react-inline-elements": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-inline-elements/-/babel-plugin-transform-react-inline-elements-6.22.0.tgz", + "integrity": "sha1-ZochGjK0mlLyLFc6K1UEol7xfFM=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, "babel-plugin-transform-react-jsx": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", @@ -1830,6 +1845,21 @@ "babel-runtime": "6.26.0" } }, + "babel-plugin-transform-react-pure-class-to-function": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-pure-class-to-function/-/babel-plugin-transform-react-pure-class-to-function-1.0.1.tgz", + "integrity": "sha1-MqZJyX1lMlC0Gc/RSJMxsCkNnuQ=", + "dev": true, + "requires": { + "babel-helper-is-react-class": "1.0.0" + } + }, + "babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.10.tgz", + "integrity": "sha512-JlT+Bsnuk5gRroIm2Wl4k0e84bVCtqPEfbijvF3Gl8o5+CTrs/lwRiXhZh2cVeHt/KLA89sU9tCkawY8gLoizA==", + "dev": true + }, "babel-plugin-transform-regenerator": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", @@ -1963,6 +1993,38 @@ } } }, + "babel-preset-es2015": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", + "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0" + } + }, "babel-preset-es2015-node": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/babel-preset-es2015-node/-/babel-preset-es2015-node-6.1.1.tgz", @@ -2116,6 +2178,26 @@ "react-transform-hmr": "1.0.4" } }, + "babel-preset-react-optimize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-react-optimize/-/babel-preset-react-optimize-1.0.1.tgz", + "integrity": "sha1-wjUJ+6fLx2195wUOfSa80ivDBOg=", + "dev": true, + "requires": { + "babel-plugin-transform-react-constant-elements": "6.23.0", + "babel-plugin-transform-react-inline-elements": "6.22.0", + "babel-plugin-transform-react-pure-class-to-function": "1.0.1", + "babel-plugin-transform-react-remove-prop-types": "0.2.12" + }, + "dependencies": { + "babel-plugin-transform-react-remove-prop-types": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.2.12.tgz", + "integrity": "sha1-NAZpbfC4tFYIn51ybSfn4SPS+Sk=", + "dev": true + } + } + }, "babel-preset-stage-0": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz", @@ -12044,9 +12126,9 @@ "integrity": "sha1-rS7pV/f2zAE5aJPqA9hMsq2y43Y=" }, "react-native-img-cache": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/react-native-img-cache/-/react-native-img-cache-1.5.0.tgz", - "integrity": "sha1-8Kwl3Va6T3E8tbzB+bTC7qFTbmw=", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/react-native-img-cache/-/react-native-img-cache-1.5.2.tgz", + "integrity": "sha1-6HG4MJk3t/mSbgmwFuTk5nWKOfo=", "requires": { "crypto-js": "3.1.9-1" } @@ -12123,6 +12205,11 @@ "prop-types": "15.6.0" } }, + "react-native-push-notification": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/react-native-push-notification/-/react-native-push-notification-3.0.1.tgz", + "integrity": "sha1-DiPbMC0Du0o/KNwHLcryqaEXjtg=" + }, "react-native-svg": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-6.0.0.tgz", @@ -12407,9 +12494,9 @@ } }, "realm": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/realm/-/realm-2.0.6.tgz", - "integrity": "sha1-bnoUD9w4qgT5czI6pQ17gpg8Ot8=", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/realm/-/realm-2.0.7.tgz", + "integrity": "sha1-1SbWxzksVklafHgASDwG61hcbdY=", "requires": { "command-line-args": "4.0.7", "decompress": "4.2.0", diff --git a/package.json b/package.json index b65a312a..3eefff0e 100644 --- a/package.json +++ b/package.json @@ -27,19 +27,20 @@ "react-native-easy-markdown": "git+https://github.com/lappalj4/react-native-easy-markdown.git", "react-native-fetch-blob": "^0.10.8", "react-native-image-picker": "^0.26.7", - "react-native-img-cache": "^1.5.0", + "react-native-img-cache": "^1.5.2", "react-native-keyboard-aware-scroll-view": "^0.4.1", "react-native-loading-spinner-overlay": "^0.5.2", "react-native-meteor": "^1.2.0", "react-native-modal": "^4.1.1", "react-native-optimized-flatlist": "^1.0.3", + "react-native-push-notification": "^3.0.1", "react-native-svg": "^6.0.0", "react-native-svg-image": "^2.0.1", "react-native-vector-icons": "^4.4.2", "react-native-zeroconf": "^0.8.3", "react-navigation": "^1.0.0-beta.19", "react-redux": "^5.0.6", - "realm": "^2.0.6", + "realm": "^2.0.7", "redux": "^3.7.2", "redux-immutable-state-invariant": "^2.1.0", "redux-logger": "^3.0.6", @@ -53,6 +54,8 @@ "@storybook/react-native": "^3.2.15", "babel-eslint": "^8.0.2", "babel-jest": "21.2.0", + "babel-plugin-transform-react-remove-prop-types": "^0.4.10", + "babel-preset-es2015": "^6.24.1", "babel-preset-react-native": "4.0.0", "codecov": "^3.0.0", "eslint": "^4.11.0",