185 lines
9.1 KiB
Diff
185 lines
9.1 KiB
Diff
diff --git a/node_modules/react-native-notifications/RNNotifications/RNNotificationEventHandler.m b/node_modules/react-native-notifications/RNNotifications/RNNotificationEventHandler.m
|
|
index edc4fd4..694f01f 100644
|
|
--- a/node_modules/react-native-notifications/RNNotifications/RNNotificationEventHandler.m
|
|
+++ b/node_modules/react-native-notifications/RNNotifications/RNNotificationEventHandler.m
|
|
@@ -3,6 +3,8 @@
|
|
#import "RNNotificationUtils.h"
|
|
#import "RCTConvert+RNNotifications.h"
|
|
#import "RNNotificationParser.h"
|
|
+#import <MMKV/MMKV.h>
|
|
+#import "SecureStorage.h"
|
|
|
|
@implementation RNNotificationEventHandler {
|
|
RNNotificationsStore* _store;
|
|
@@ -28,9 +30,140 @@ - (void)didReceiveForegroundNotification:(UNNotification *)notification withComp
|
|
[RNEventEmitter sendEvent:RNNotificationReceivedForeground body:[RNNotificationParser parseNotification:notification]];
|
|
}
|
|
|
|
+/*
|
|
+ * Generate a random alphanumeric string to message id
|
|
+*/
|
|
+-(NSString *)random:(int)len {
|
|
+ NSString *letters = @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
+ NSMutableString *randomString = [NSMutableString stringWithCapacity:len];
|
|
+
|
|
+ for (int i=0; i<len; i++) {
|
|
+ [randomString appendFormat: @"%C", [letters characterAtIndex: arc4random_uniform([letters length])]];
|
|
+ }
|
|
+
|
|
+ return randomString;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Remove trailing slash on server url from notification
|
|
+*/
|
|
+- (NSString *)serverURL:(NSString *)host {
|
|
+ if ([host length] > 0) {
|
|
+ unichar last = [host characterAtIndex:[host length] - 1];
|
|
+ if (last == '/') {
|
|
+ host = [host substringToIndex:[host length] - 1];
|
|
+ }
|
|
+ }
|
|
+ return host;
|
|
+}
|
|
+
|
|
+- (NSString *)stringToHex:(NSString *)string
|
|
+{
|
|
+ char *utf8 = (char *)[string UTF8String];
|
|
+ NSMutableString *hex = [NSMutableString string];
|
|
+ while (*utf8) [hex appendFormat:@"%02X", *utf8++ & 0x00FF];
|
|
+
|
|
+ return [[NSString stringWithFormat:@"%@", hex] lowercaseString];
|
|
+}
|
|
+
|
|
+- (NSDictionary *) retrieveCredentialsForServer:(NSString *)serverURL {
|
|
+ // AppGroup MMKV
|
|
+ NSString *groupDir = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"AppGroup"]].path;
|
|
+
|
|
+ // Make sure MMKV is using the group directory
|
|
+ [MMKV initializeMMKV:nil groupDir:groupDir logLevel:MMKVLogNone];
|
|
+
|
|
+ // Start the MMKV container
|
|
+ __block MMKV *mmkv;
|
|
+ SecureStorage *secureStorage = [[SecureStorage alloc] init];
|
|
+
|
|
+ // https://github.com/ammarahm-ed/react-native-mmkv-storage/blob/master/src/loader.js#L31
|
|
+ [secureStorage getSecureKey:[self stringToHex:@"com.MMKV.default"] callback:^(NSArray *response) {
|
|
+ // error handling
|
|
+ if ([response objectAtIndex:0] != [NSNull null]) {
|
|
+ return;
|
|
+ }
|
|
+ NSString *key = [response objectAtIndex:1];
|
|
+ NSData *cryptKey = [key dataUsingEncoding:NSUTF8StringEncoding];
|
|
+ mmkv = [MMKV mmkvWithID:@"default" cryptKey:cryptKey mode:MMKVMultiProcess];
|
|
+ }];
|
|
+
|
|
+ if (!mmkv) {
|
|
+ return @{
|
|
+ @"userId": @"",
|
|
+ @"userToken": @""
|
|
+ };
|
|
+ }
|
|
+ // Get credentials
|
|
+ NSString *TOKEN_KEY = @"reactnativemeteor_usertoken";
|
|
+ NSString *userId = [mmkv getStringForKey:[NSString stringWithFormat:@"%@-%@", TOKEN_KEY, serverURL]];
|
|
+ NSString *userToken = [mmkv getStringForKey:[NSString stringWithFormat:@"%@-%@", TOKEN_KEY, userId]];
|
|
+
|
|
+ // Retrive a NSDictionary with the credentials
|
|
+ return @{
|
|
+ @"userId": userId,
|
|
+ @"userToken": userToken
|
|
+ };
|
|
+}
|
|
+
|
|
- (void)didReceiveNotificationResponse:(UNNotificationResponse *)response completionHandler:(void (^)(void))completionHandler {
|
|
- [_store setActionCompletionHandler:completionHandler withCompletionKey:response.notification.request.identifier];
|
|
- [RNEventEmitter sendEvent:RNNotificationOpened body:[RNNotificationParser parseNotificationResponse:response]];
|
|
+ // if notification response is a REPLY_ACTION
|
|
+ if ([response.actionIdentifier isEqualToString:@"REPLY_ACTION"]) {
|
|
+ // convert notification data to dictionary payload
|
|
+ NSDictionary *notification = [RCTConvert UNNotificationPayload:response.notification];
|
|
+
|
|
+ // parse ejson from notification
|
|
+ NSData *ejsonData = [[notification valueForKey:@"ejson"] dataUsingEncoding:NSUTF8StringEncoding];
|
|
+ NSError *error;
|
|
+ NSDictionary *ejson = [NSJSONSerialization JSONObjectWithData:ejsonData options:kNilOptions error:&error];
|
|
+
|
|
+ // data from notification
|
|
+ NSString *host = [ejson valueForKey:@"host"];
|
|
+ NSString *rid = [ejson valueForKey:@"rid"];
|
|
+
|
|
+ // msg on textinput of notification
|
|
+ NSString *msg = [(UNTextInputNotificationResponse *)response userText];
|
|
+
|
|
+ // get credentials
|
|
+ NSDictionary *credentials = [self retrieveCredentialsForServer:[self serverURL:host]];
|
|
+ NSString *userId = [credentials valueForKey:@"userId"];
|
|
+ NSString *token = [credentials valueForKey:@"userToken"];
|
|
+
|
|
+ // background task - we need this because fetch doesn't work if app is closed/killed
|
|
+ UIApplication *app = [UIApplication sharedApplication];
|
|
+ __block UIBackgroundTaskIdentifier task = [app beginBackgroundTaskWithExpirationHandler:^{
|
|
+ [app endBackgroundTask:task];
|
|
+ task = UIBackgroundTaskInvalid;
|
|
+ }];
|
|
+ // we use global queue to make requests with app closed/killed
|
|
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
+ // we make a synchronous request to post new message
|
|
+ NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/chat.sendMessage", [self serverURL:host]]]];
|
|
+
|
|
+ NSString *message = [NSString stringWithFormat:@"{ \"message\": { \"_id\": \"%@\", \"msg\": \"%@\", \"rid\": \"%@\" } }", [self random:17], msg, rid];
|
|
+
|
|
+ [request setHTTPMethod:@"POST"];
|
|
+ [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
|
|
+ [request addValue:userId forHTTPHeaderField:@"x-user-id"];
|
|
+ [request addValue:token forHTTPHeaderField:@"x-auth-token"];
|
|
+ [request setHTTPBody:[message dataUsingEncoding:NSUTF8StringEncoding]];
|
|
+
|
|
+ NSURLResponse *response = nil;
|
|
+ NSError *error = nil;
|
|
+ NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
|
|
+
|
|
+ // end background task
|
|
+ [app endBackgroundTask:task];
|
|
+ task = UIBackgroundTaskInvalid;
|
|
+
|
|
+ // complete notification response
|
|
+ completionHandler();
|
|
+ });
|
|
+ } else {
|
|
+ // We only set initial notification and emit event to JS when not is a reply action
|
|
+ [_store setActionCompletionHandler:completionHandler withCompletionKey:response.notification.request.identifier];
|
|
+ [RNEventEmitter sendEvent:RNNotificationOpened body:[RNNotificationParser parseNotificationResponse:response]];
|
|
+ }
|
|
}
|
|
|
|
@end
|
|
diff --git a/node_modules/react-native-notifications/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java b/node_modules/react-native-notifications/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java
|
|
index 524ff07..70f22d5 100644
|
|
--- a/node_modules/react-native-notifications/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java
|
|
+++ b/node_modules/react-native-notifications/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java
|
|
@@ -31,7 +31,7 @@ public class PushNotification implements IPushNotification {
|
|
final protected AppLifecycleFacade mAppLifecycleFacade;
|
|
final protected AppLaunchHelper mAppLaunchHelper;
|
|
final protected JsIOHelper mJsIOHelper;
|
|
- final protected PushNotificationProps mNotificationProps;
|
|
+ protected PushNotificationProps mNotificationProps;
|
|
final protected AppVisibilityListener mAppVisibilityListener = new AppVisibilityListener() {
|
|
@Override
|
|
public void onAppVisible() {
|
|
diff --git a/node_modules/react-native-notifications/android/app/src/reactNative59/java/com/wix/reactnativenotifications/NotificationManagerCompatFacade.java b/node_modules/react-native-notifications/android/app/src/reactNative59/java/com/wix/reactnativenotifications/NotificationManagerCompatFacade.java
|
|
index f9c858b..94ea188 100644
|
|
--- a/node_modules/react-native-notifications/android/app/src/reactNative59/java/com/wix/reactnativenotifications/NotificationManagerCompatFacade.java
|
|
+++ b/node_modules/react-native-notifications/android/app/src/reactNative59/java/com/wix/reactnativenotifications/NotificationManagerCompatFacade.java
|
|
@@ -2,8 +2,8 @@
|
|
package com.wix.reactnativenotifications;
|
|
|
|
import android.content.Context;
|
|
-import android.support.annotation.NonNull;
|
|
-import android.support.v4.app.NotificationManagerCompat;
|
|
+import androidx.annotation.NonNull;
|
|
+import androidx.core.app.NotificationManagerCompat;
|
|
|
|
public abstract class NotificationManagerCompatFacade {
|
|
public static NotificationManagerCompat from(@NonNull Context context) {
|