@selligent-marketing-cloud/selligent-react-native 3.6.0 → 3.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -25,7 +25,7 @@ This module supports the following SDK and tools:
25
25
  npm install @selligent-marketing-cloud/selligent-react-native --save
26
26
  ```
27
27
 
28
- 2. Create a `selligent.json` file (name is case sensitive) in the root of the React Native project with the following content:
28
+ 2. Create a `selligent.json` file (name is case sensitive) in the root of the React Native project (you can alternatively place it inside another folder or inside a `selligent` folder which will automatically be checked by the wrapper) with the following content:
29
29
 
30
30
  ```json
31
31
  {
@@ -170,7 +170,7 @@ This module supports the following SDK and tools:
170
170
 
171
171
  1. Copy the `node_modules/@selligent-marketing-cloud/selligent-react-native/ios` folder to the **Xcode project**. Drop it under the `Libraries` Folder. This will link the module to the iOS project.
172
172
 
173
- 2. Drag and drop the `selligent.json` you created from the root folder to the Xcode project inside the `Copy Bundle Resources` in `Build phases` of your target:
173
+ 2. Drag and drop the `selligent.json` you created (or the full folder(s) containing it) to the Xcode project inside the `Copy Bundle Resources` in `Build phases` of your target:
174
174
 
175
175
  > Do not check the "copy if needed" option to make sure you only have to manage one selligent.json file
176
176
 
@@ -186,13 +186,18 @@ This module supports the following SDK and tools:
186
186
 
187
187
  ```objective-c
188
188
  @import RNSelligentMobileSDK;
189
+ // OR
190
+ // #import <RNSelligentMobileSDK/RNSelligentMobileSDK-Swift.h>
189
191
 
190
192
  // You can alternatively specify a different file name (without the extension) from where to load the Marigold Engage configs (defaults to 'selligent')
191
193
  // if (!launchOptions) {
192
194
  // launchOptions = [NSMutableDictionary new];
193
195
  // }
194
196
  // [launchOptions setValue:@"alternativeFileName" forKey:@"RN_SELLIGENT_JSON"];
197
+ // [launchOptions setValue:@"selligent/alternativeFileName" forKey:@"RN_SELLIGENT_JSON"];
198
+ // [launchOptions setValue:@"alternativeFolder/alternativeFileName" forKey:@"RN_SELLIGENT_JSON"];
195
199
 
200
+ // At the end of application:didFinishLaunchingWithOptions:
196
201
  [RNSelligent configureWithLaunchOptions:launchOptions];
197
202
  ```
198
203
 
@@ -201,7 +206,7 @@ This module supports the following SDK and tools:
201
206
  <details open>
202
207
  <summary>With autolinking (RN 0.60 and above)</summary>
203
208
 
204
- 1. Drag and drop the `selligent.json` you created from the root folder to the Xcode project inside the `Copy Bundle Resources` in `Build phases` of your target:
209
+ 1. Drag and drop the `selligent.json` you created (or the full folder(s) containing it) to the Xcode project inside the `Copy Bundle Resources` in `Build phases` of your target:
205
210
 
206
211
  > Do not check the "copy if needed" option to make sure you only have to manage one selligent.json file
207
212
 
@@ -214,6 +219,14 @@ This module supports the following SDK and tools:
214
219
  // OR
215
220
  // #import <RNSelligentMobileSDK/RNSelligentMobileSDK-Swift.h>
216
221
 
222
+ // You can alternatively specify a different file name (without the extension) from where to load the Marigold Engage configs (defaults to 'selligent')
223
+ // if (!launchOptions) {
224
+ // launchOptions = [NSMutableDictionary new];
225
+ // }
226
+ // [launchOptions setValue:@"alternativeFileName" forKey:@"RN_SELLIGENT_JSON"];
227
+ // [launchOptions setValue:@"selligent/alternativeFileName" forKey:@"RN_SELLIGENT_JSON"];
228
+ // [launchOptions setValue:@"alternativeFolder/alternativeFileName" forKey:@"RN_SELLIGENT_JSON"];
229
+
217
230
  // At the end of application:didFinishLaunchingWithOptions:
218
231
  [RNSelligent configureWithLaunchOptions:launchOptions];
219
232
  ```
@@ -55,7 +55,6 @@ repositories {
55
55
  url "$projectDir/../node_modules/react-native/android"
56
56
  }
57
57
  google()
58
- maven { url 'https://developer.huawei.com/repo/' }
59
58
  }
60
59
 
61
60
  dependencies {
@@ -80,9 +79,9 @@ def loadSelligentSettings(variant) {
80
79
  def variantFileName = "selligent.${variant.getName()}.json"
81
80
  def resultingSettings = null
82
81
 
83
- File variantFile = new File("$project.rootDir/../$variantFileName")
84
- File defaultFile = new File("$project.rootDir/../$defaultFileName")
85
- File flavorFile = new File("$project.rootDir/../$currentFlavor/$defaultFileName")
82
+ File variantFile = getFile(variantFileName)
83
+ File defaultFile = getFile(defaultFileName)
84
+ File flavorFile = getFile("$currentFlavor/$defaultFileName")
86
85
 
87
86
  if (variantFile.exists()) {
88
87
  println("Reading Marigold Engage properties for variant ${variant.getName()} from $variantFile.path")
@@ -109,16 +108,31 @@ def loadSelligentSettings(variant) {
109
108
  }
110
109
  }
111
110
  else {
112
- throw new InvalidUserDataException("The selligent.json file could not be found. Please make sure you provide this file in the root of this project.")
111
+ println("WARNING: No selligent.json file could be found for the given task. Disregard this message if the executing task is not building/executing the app.")
113
112
  }
114
113
 
115
114
  return resultingSettings
116
115
  }
117
116
 
117
+ def getFile(filePath) {
118
+ File defaultFile = new File("$project.rootDir/../$filePath")
119
+ File unifiedLocationFile = new File("$project.rootDir/../selligent/$filePath")
120
+
121
+ if (defaultFile.exists()) {
122
+ println("selligent.json found in the root of the project")
123
+ return defaultFile
124
+ }
125
+ else if (unifiedLocationFile.exists()) {
126
+ println("selligent.json found in the unified `selligent` folder")
127
+ }
128
+
129
+ return unifiedLocationFile
130
+ }
131
+
118
132
  def getCurrentFlavor() {
119
133
  Gradle gradle = getGradle()
120
134
  String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()
121
- Pattern pattern = Pattern.compile("(install|assemble)(\\w+)(Release|Debug)")
135
+ Pattern pattern = Pattern.compile("(install|assemble|bundle)(\\w+)(Release|Debug)")
122
136
  Matcher matcher = pattern.matcher(tskReqStr)
123
137
 
124
138
  if (matcher.find()) {
@@ -3,16 +3,12 @@ package com.selligent;
3
3
  import android.content.BroadcastReceiver;
4
4
  import android.content.Context;
5
5
  import android.content.Intent;
6
- import android.text.TextUtils;
7
6
 
8
- import com.facebook.react.bridge.WritableMap;
9
7
  import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
10
8
  import com.selligent.rnmobilesdk.BroadcastDataFactory;
11
9
 
12
-
13
10
  class EventReceiver extends BroadcastReceiver {
14
-
15
- private RCTDeviceEventEmitter rctDeviceEventEmitter;
11
+ private final RCTDeviceEventEmitter rctDeviceEventEmitter;
16
12
 
17
13
  public EventReceiver(RCTDeviceEventEmitter rctDeviceEventEmitter) {
18
14
  this.rctDeviceEventEmitter = rctDeviceEventEmitter;
@@ -20,13 +16,13 @@ class EventReceiver extends BroadcastReceiver {
20
16
 
21
17
  @Override
22
18
  public void onReceive(Context context, Intent intent) {
23
- final String smBroadcastEventType = intent.getAction();
24
- if (TextUtils.isEmpty(smBroadcastEventType)) return;
19
+ String smBroadcastEventType = intent.getAction();
25
20
 
26
- final WritableMap broadcastData = BroadcastDataFactory.getBroadcastData(smBroadcastEventType, intent);
27
- final String eventName = broadcastData.getString("broadcastEventType");
21
+ if (smBroadcastEventType == null || smBroadcastEventType.isEmpty()) return;
28
22
 
29
- rctDeviceEventEmitter.emit(eventName, broadcastData);
23
+ this.rctDeviceEventEmitter.emit(
24
+ smBroadcastEventType,
25
+ BroadcastDataFactory.getBroadcastData(smBroadcastEventType, intent)
26
+ );
30
27
  }
31
-
32
28
  }
@@ -0,0 +1,59 @@
1
+ package com.selligent;
2
+
3
+ import com.facebook.react.bridge.Arguments;
4
+ import com.facebook.react.bridge.WritableArray;
5
+ import com.facebook.react.bridge.WritableMap;
6
+
7
+ import java.util.List;
8
+ import java.util.Map;
9
+
10
+ final class RNHelpers {
11
+ private RNHelpers() { }
12
+
13
+ static WritableArray convertListToWritableArray(List<Map<String, Object>> list) {
14
+ WritableArray array = Arguments.createArray();
15
+
16
+ if (list.isEmpty()) { return array; }
17
+
18
+ for (Map<String, Object> map : list) {
19
+ array.pushMap(RNHelpers.convertMapToWritableMap(map));
20
+ }
21
+
22
+ return array;
23
+ }
24
+
25
+ static WritableMap convertMapToWritableMap(Map<String, Object> map) {
26
+ WritableMap writableMap = Arguments.createMap();
27
+
28
+ if (map.entrySet().isEmpty()) { return writableMap; }
29
+
30
+ for (Map.Entry<String, Object> entry : map.entrySet()) {
31
+ Object value = entry.getValue();
32
+ String key = entry.getKey();
33
+
34
+ if (value instanceof Map) {
35
+ writableMap.putMap(key, RNHelpers.convertMapToWritableMap((Map<String, Object>) value));
36
+ }
37
+ else if (value instanceof List) {
38
+ writableMap.putArray(key, RNHelpers.convertListToWritableArray((List<Map<String, Object>>) value));
39
+ }
40
+ else if (value instanceof Boolean) {
41
+ writableMap.putBoolean(key, (Boolean) value);
42
+ }
43
+ else if (value instanceof Integer) {
44
+ writableMap.putInt(key, (Integer) value);
45
+ }
46
+ else if (value instanceof Double) {
47
+ writableMap.putDouble(key, (Double) value);
48
+ }
49
+ else if (value instanceof String) {
50
+ writableMap.putString(key, (String) value);
51
+ }
52
+ else {
53
+ writableMap.putNull(key);
54
+ }
55
+ }
56
+
57
+ return writableMap;
58
+ }
59
+ }
@@ -1,19 +1,15 @@
1
-
2
1
  package com.selligent;
3
2
 
3
+ import android.annotation.SuppressLint;
4
4
  import android.app.Activity;
5
5
  import android.app.Application;
6
+ import android.content.Context;
6
7
  import android.content.Intent;
7
- import android.content.IntentFilter;
8
- import android.content.res.Resources;
9
8
 
9
+ import androidx.annotation.NonNull;
10
10
  import androidx.appcompat.app.AppCompatActivity;
11
- import androidx.lifecycle.Observer;
12
11
  import androidx.localbroadcastmanager.content.LocalBroadcastManager;
13
12
 
14
- import android.graphics.Color;
15
- import android.util.Log;
16
-
17
13
  import com.facebook.react.bridge.ActivityEventListener;
18
14
  import com.facebook.react.bridge.Callback;
19
15
  import com.facebook.react.bridge.LifecycleEventListener;
@@ -23,604 +19,259 @@ import com.facebook.react.bridge.ReactMethod;
23
19
  import com.facebook.react.bridge.ReadableArray;
24
20
  import com.facebook.react.bridge.ReadableMap;
25
21
  import com.facebook.react.bridge.ReadableType;
26
- import com.facebook.react.bridge.WritableArray;
27
- import com.facebook.react.bridge.WritableMap;
28
- import com.facebook.react.bridge.WritableNativeArray;
29
- import com.facebook.react.bridge.WritableNativeMap;
30
22
  import com.facebook.react.modules.core.DeviceEventManagerModule;
31
- import com.google.gson.Gson;
32
- import com.google.gson.reflect.TypeToken;
33
- import com.selligent.rnmobilesdk.BroadcastEventType;
34
- import com.selligent.rnmobilesdk.ButtonAction;
35
- import com.selligent.rnmobilesdk.ButtonBroadcastEventDataParser;
36
- import com.selligent.rnmobilesdk.DeviceIdBroadcastEventDataParser;
37
- import com.selligent.rnmobilesdk.Event;
38
- import com.selligent.rnmobilesdk.GCMTokenBroadcastEventDataParser;
39
- import com.selligent.rnmobilesdk.InAppMessageBroadcastEventDataParser;
40
- import com.selligent.rnmobilesdk.InAppMessageRefreshType;
41
- import com.selligent.rnmobilesdk.NotificationMessageBroadcastEventDataParser;
42
- import com.selligent.rnmobilesdk.RemoteMessageDisplayType;
43
- import com.selligent.rnmobilesdk.SMEventFactory;
44
- import com.selligent.rnmobilesdk.SMSettingsFactory;
45
- import com.selligent.rnmobilesdk.Settings;
46
- import com.selligent.sdk.SMCallback;
47
- import com.selligent.sdk.SMEvent;
23
+ import com.selligent.rnmobilesdk.Manager;
48
24
  import com.selligent.sdk.SMForegroundGcmBroadcastReceiver;
49
- import com.selligent.sdk.SMInAppMessage;
50
- import com.selligent.sdk.SMInAppRefreshType;
51
- import com.selligent.sdk.SMManager;
52
- import com.selligent.sdk.SMNotificationButton;
53
- import com.selligent.sdk.SMNotificationMessage;
54
- import com.selligent.sdk.SMObserverManager;
55
- import com.selligent.sdk.SMRemoteMessageDisplayType;
56
- import com.selligent.sdk.SMSettings;
57
25
 
58
- import java.util.HashMap;
26
+ import java.util.Map;
59
27
 
60
28
  public class RNSelligent extends ReactContextBaseJavaModule implements LifecycleEventListener, ActivityEventListener {
61
-
62
- private static final String RN_SELLIGENT_NAME = "RNSelligent";
63
29
  private final ReactApplicationContext reactContext;
64
- private final SMManager smManager;
30
+ private final Manager manager;
65
31
  EventReceiver eventReceiver;
66
32
  SMForegroundGcmBroadcastReceiver receiver;
67
- private static SMInAppRefreshType inAppMessageRefreshType;
68
- private static boolean inAppMessageCustomUi;
69
-
70
- public static final String REACT_CLASS = "SelligentReactNative"; // for logging purposes
71
-
72
- boolean areObserverStarted = false;
73
33
 
74
- //region getter
75
- static SMManager getSMManager()
76
- {
77
- return SMManager.getInstance();
34
+ static Manager getManager() {
35
+ return Manager.getInstance();
78
36
  }
79
37
 
80
- static String getSelligentSettings()
81
- {
38
+ static String getSelligentSettings() {
82
39
  return BuildConfig.SELLIGENT_SETTINGS;
83
40
  }
84
41
 
85
- static Class<? extends Activity> getActivityClass(String notificationActivityName) throws Exception
86
- {
87
- return (Class<? extends Activity>) Class.forName(notificationActivityName);
88
- }
89
- //endregion
90
-
91
-
92
42
  public RNSelligent(ReactApplicationContext reactContext) {
93
43
  super(reactContext);
44
+
94
45
  this.reactContext = reactContext;
95
46
  reactContext.addLifecycleEventListener(this);
96
47
  reactContext.addActivityEventListener(this);
97
- this.smManager = getSMManager();
48
+ this.manager = RNSelligent.getManager();
98
49
  }
99
50
 
51
+ @NonNull
100
52
  @Override
101
53
  public String getName() {
102
- return RN_SELLIGENT_NAME;
54
+ return Manager.RN_SELLIGENT_NAME;
103
55
  }
104
56
 
105
57
  public static void configure(Application application) {
106
- try {
107
- final HashMap<String, Object> settingsHashMap = new Gson().fromJson(
108
- getSelligentSettings(), new TypeToken<HashMap<String, Object>>() {}.getType()
109
- );
110
- final Settings settings = Settings.fromHashMap(settingsHashMap);
111
- final SMSettings smSettings = SMSettingsFactory.getSMSettings(settings);
112
- final String notificationActivityName = settings.getActivityName();
113
-
114
- SMManager.NOTIFICATION_ACTIVITY = getActivityClass(notificationActivityName);
115
- inAppMessageRefreshType = settings.getInAppMessageRefreshType().getSmInAppRefreshType();
116
- inAppMessageCustomUi = settings.getCustomInAppUi();
117
-
118
- final SMManager smManager = getSMManager();
119
- SMManager.DEBUG = BuildConfig.BUILD_TYPE.equals("debug") || settings.getEnableAndroidLogging();
120
- smManager.start(smSettings, application);
121
-
122
- final Resources resources = application.getResources();
123
-
124
- if (settings.getNotificationSmallIcon() != null && !settings.getNotificationSmallIcon().isEmpty()) {
125
- final int smallIconResourceId = resources.getIdentifier(settings.getNotificationSmallIcon(), "drawable", application.getPackageName());
126
- if(smallIconResourceId != 0) {
127
- smManager.setNotificationSmallIcon(smallIconResourceId);
128
- }
129
- }
130
-
131
- if (settings.getNotificationLargeIcon() != null && !settings.getNotificationLargeIcon().isEmpty()) {
132
- final int largeIconResourceId = resources.getIdentifier(settings.getNotificationLargeIcon(), "drawable", application.getPackageName());
133
- if (largeIconResourceId != 0) {
134
- smManager.setNotificationLargeIcon(largeIconResourceId);
135
- }
136
- }
137
-
138
- if (settings.getNotificationIconColor() != null && !settings.getNotificationIconColor().isEmpty()) {
139
- try {
140
- final int color = Color.parseColor(settings.getNotificationIconColor());
141
- smManager.setNotificationIconColor(color);
142
- } catch (IllegalArgumentException e) {
143
- Log.e(RN_SELLIGENT_NAME, "notificationIconColor must be a color hex string.");
144
- }
145
- }
146
-
147
- } catch (Exception e) {
148
- Log.e(RN_SELLIGENT_NAME, "SMManager start failed: an error occurred while setting the NotificationActivity", e);
149
- }
58
+ RNSelligent.getManager().configure(application, RNSelligent.getSelligentSettings(), BuildConfig.BUILD_TYPE.equals("debug"));
150
59
  }
151
60
 
152
- /* Our methods: */
153
-
154
61
  @ReactMethod
155
62
  public void getVersionLib(Callback successCallback) {
156
- final String versionLib = SMManager.VERSION_LIB;
157
- successCallback.invoke(versionLib);
63
+ successCallback.invoke(manager.getVersionLib());
158
64
  }
159
65
 
160
66
  @ReactMethod
161
67
  public void enableInAppMessages(ReadableMap enabled) {
162
- final String enabledProperty = "enabled";
163
- final ReadableType enabledType = enabled.getType(enabledProperty);
68
+ String enabledProperty = "enabled";
69
+ ReadableType enabledType = enabled.getType(enabledProperty);
164
70
 
165
71
  if (enabledType == ReadableType.Boolean) {
166
- enableInAppMessages(enabled.getBoolean(enabledProperty));
167
- }
168
- else if (enabledType == ReadableType.Number) {
169
- enableInAppMessages(enabled.getInt(enabledProperty));
72
+ this.manager.enableInAppMessages(enabled.getBoolean(enabledProperty));
170
73
  }
171
- }
172
-
173
- private void enableInAppMessages(boolean enable) {
174
- if (enable) {
175
- smManager.enableInAppMessages(inAppMessageRefreshType);
176
- } else {
177
- smManager.disableInAppMessages();
74
+ else if (enabledType == ReadableType.Number) {
75
+ this.manager.enableInAppMessages(enabled.getInt(enabledProperty));
178
76
  }
179
77
  }
180
78
 
181
- private void enableInAppMessages(Integer inAppMessageRefreshTypeIndex) {
182
- final InAppMessageRefreshType refreshType = InAppMessageRefreshType.valueOf(inAppMessageRefreshTypeIndex);
183
- final SMInAppRefreshType smInAppRefreshType = refreshType.getSmInAppRefreshType();
184
-
185
- smManager.enableInAppMessages(smInAppRefreshType);
186
- }
187
-
188
79
  @ReactMethod
189
80
  public void areInAppMessagesEnabled(Callback successCallback) {
190
- final Boolean areInAppMessagesEnabled = smManager.areInAppMessagesEnabled();
191
- successCallback.invoke(areInAppMessagesEnabled);
81
+ successCallback.invoke(this.manager.areInAppMessagesEnabled());
192
82
  }
193
83
 
194
84
  @ReactMethod
195
85
  public void displayMessage(String messageId) {
196
- final Activity currentActivity = getCurrentActivity();
197
-
198
- if (currentActivity != null) {
199
- smManager.displayInAppMessage(messageId, currentActivity);
200
- }
86
+ this.manager.displayMessage(messageId, this.getCurrentActivity());
201
87
  }
202
88
 
203
89
  @ReactMethod
204
- public void getInAppMessages(final Callback successCallback) {
205
- smManager.getInAppMessages(inAppMessages -> {
206
- WritableArray resultingMessagesArray = new WritableNativeArray();
207
-
208
- for (SMInAppMessage message : inAppMessages) {
209
- WritableMap messageMap = new WritableNativeMap();
210
-
211
- messageMap.putString("id", message.id);
212
- messageMap.putString("title", message.title);
213
- messageMap.putString("body", message.getBody());
214
- messageMap.putDouble("creationDate", message.getCreationDate());
215
- messageMap.putDouble("expirationDate", message.getExpirationDate());
216
- messageMap.putDouble("receptionDate", message.getReceptionDate());
217
- messageMap.putBoolean("hasBeenSeen", message.hasBeenSeen());
218
- messageMap.putDouble("type", message.getType().getValue());
219
-
220
- WritableArray buttonsArray = new WritableNativeArray();
221
-
222
- SMNotificationButton[] buttons = message.getButtons();
223
-
224
- if(buttons != null) {
225
- for(SMNotificationButton button : buttons) {
226
- WritableMap buttonMap = new WritableNativeMap();
227
-
228
- buttonMap.putString("id", button.id);
229
- buttonMap.putString("value", button.value);
230
- buttonMap.putString("label", button.label);
231
- buttonMap.putInt("type", ButtonAction.valueOf(button.action).getValue());
232
-
233
- buttonsArray.pushMap(buttonMap);
234
- }
235
- }
236
-
237
- messageMap.putArray("buttons", buttonsArray);
238
-
239
- resultingMessagesArray.pushMap(messageMap);
240
- }
241
-
242
- successCallback.invoke(resultingMessagesArray);
243
- });
90
+ public void getInAppMessages(Callback successCallback) {
91
+ this.manager.getInAppMessages(list ->
92
+ successCallback.invoke(RNHelpers.convertListToWritableArray(list))
93
+ );
244
94
  }
245
95
 
246
96
  @ReactMethod
247
- public void setInAppMessageAsSeen(final String messageId, final Callback successCallback, final Callback errorCallback) {
248
- smManager.getInAppMessages(inAppMessages ->
249
- {
250
- for(SMInAppMessage message : inAppMessages)
251
- {
252
- if(message.id.equals(messageId))
253
- {
254
- smManager.setInAppMessageAsSeen(message);
255
- successCallback.invoke();
256
- return;
257
- }
258
- }
259
- errorCallback.invoke(String.format("No message with id %s found", messageId));
260
- });
97
+ public void setInAppMessageAsSeen(String messageId, Callback successCallback, Callback errorCallback) {
98
+ this.manager.setInAppMessageAsSeen(messageId, error ->
99
+ processErrorStringToCallback(error, successCallback, errorCallback)
100
+ );
261
101
  }
262
102
 
263
103
  @ReactMethod
264
- public void setInAppMessageAsUnseen(final String messageId, final Callback successCallback, final Callback errorCallback)
265
- {
266
- smManager.getInAppMessages(inAppMessages ->
267
- {
268
- for(SMInAppMessage message : inAppMessages)
269
- {
270
- if(message.id.equals(messageId))
271
- {
272
- smManager.setInAppMessageAsUnseen(message);
273
- successCallback.invoke();
274
- return;
275
- }
276
- }
277
- errorCallback.invoke(String.format("No message with id %s found", messageId));
278
- });
104
+ public void setInAppMessageAsUnseen(String messageId, Callback successCallback, Callback errorCallback) {
105
+ this.manager.setInAppMessageAsUnseen(messageId, error ->
106
+ processErrorStringToCallback(error, successCallback, errorCallback)
107
+ );
279
108
  }
280
109
 
281
110
  @ReactMethod
282
- public void setInAppMessageAsDeleted(final String messageId, final Callback successCallback, final Callback errorCallback)
283
- {
284
- smManager.getInAppMessages(inAppMessages ->
285
- {
286
- for(SMInAppMessage message : inAppMessages)
287
- {
288
- if(message.id.equals(messageId))
289
- {
290
- smManager.deleteInAppMessage(messageId);
291
- successCallback.invoke();
292
- return;
293
- }
294
- }
295
- errorCallback.invoke(String.format("No message with id %s found", messageId));
296
- });
111
+ public void setInAppMessageAsDeleted(String messageId, Callback successCallback, Callback errorCallback) {
112
+ this.manager.setInAppMessageAsDeleted(messageId, error ->
113
+ processErrorStringToCallback(error, successCallback, errorCallback)
114
+ );
297
115
  }
298
116
 
299
117
  @ReactMethod
300
- public void executeButtonAction(final String buttonId, final String messageId, final Callback successCallback, final Callback errorCallback) {
301
- smManager.getInAppMessages(inAppMessages -> {
302
- for(SMInAppMessage message : inAppMessages) {
303
- if(message.id.equals(messageId))
304
- {
305
- SMNotificationButton[] buttons = message.getButtons();
306
- if (buttons != null)
307
- {
308
- for (SMNotificationButton button : message.getButtons())
309
- {
310
- if (button.id.equals(buttonId))
311
- {
312
- smManager.executeButtonAction(reactContext, button, message);
313
- successCallback.invoke();
314
- return;
315
- }
316
- }
317
- }
318
- errorCallback.invoke("buttonId does not exist in message.");
319
- return;
320
- }
321
- }
322
- errorCallback.invoke(String.format("No message with id %s found", messageId));
323
- });
118
+ public void executeButtonAction(String buttonId, String messageId, Callback successCallback, Callback errorCallback) {
119
+ this.manager.executeButtonAction(this.reactContext, buttonId, messageId, error ->
120
+ processErrorStringToCallback(error, successCallback, errorCallback)
121
+ );
324
122
  }
325
123
 
326
124
  @ReactMethod
327
125
  public void setDebug(Boolean enable) {
328
- SMManager.DEBUG = enable;
126
+ Manager.setDebug(enable);
329
127
  }
330
128
 
331
129
  @ReactMethod
332
- public void sendEvent(ReadableMap eventMap, final Callback successCallback, final Callback errorCallback) {
333
- final Event event = Event.fromHashMap(eventMap.toHashMap());
334
- final SMEvent smEvent = SMEventFactory.getSMEvent(event, new SMCallback() {
335
- @Override
336
- public void onSuccess(String message) {
337
- successCallback.invoke(message);
338
- }
339
-
340
- @Override
341
- public void onError(int responseCode, Exception e) {
342
- errorCallback.invoke(responseCode);
343
- }
344
- });
345
-
346
- smManager.sendSMEvent(smEvent);
130
+ public void sendEvent(ReadableMap eventMap, Callback successCallback, Callback errorCallback) {
131
+ this.manager.sendEvent(eventMap.toHashMap(), successCallback::invoke, errorCallback::invoke);
347
132
  }
348
133
 
349
134
  @ReactMethod
350
135
  public void getDeviceId(Callback successCallback) {
351
- final String deviceId = smManager.getDeviceId();
352
- successCallback.invoke(deviceId);
136
+ successCallback.invoke(this.manager.getDeviceId());
353
137
  }
354
138
 
355
139
  @ReactMethod
356
140
  public void enableNotifications(Boolean enable) {
357
- if (Boolean.TRUE.equals(enable)) {
358
- smManager.enableNotifications();
359
- } else {
360
- smManager.disableNotifications();
361
- }
141
+ this.manager.enableNotifications(enable);
362
142
  }
363
143
 
364
144
  public static void enableNotifications() {
365
- SMManager.getInstance().enableNotifications();
145
+ RNSelligent.getManager().enableNotifications(true);
366
146
  }
367
147
 
368
148
  @ReactMethod
149
+ @SuppressWarnings("unused")
369
150
  public void displayLastReceivedRemotePushNotification(String templateId) {
370
- final Activity currentActivity = getCurrentActivity();
371
-
372
- if (currentActivity != null) {
373
- smManager.displayLastReceivedNotificationContent(currentActivity);
374
- }
151
+ this.manager.displayLastReceivedRemotePushNotification(this.getCurrentActivity());
375
152
  }
376
153
 
377
154
  @ReactMethod
378
- public void displayLastReceivedNotification()
379
- {
380
- smManager.displayLastReceivedNotification();
155
+ public void displayLastReceivedNotification() {
156
+ this.manager.displayLastReceivedNotification();
381
157
  }
382
158
 
383
159
  @ReactMethod
384
160
  public void getLastRemotePushNotification(Callback successCallback) {
385
- final SMNotificationMessage notification = smManager.retrieveLastReceivedNotificationContent();
386
-
387
- WritableMap resultingNotificationMap = new WritableNativeMap();
388
-
389
- if (notification != null) {
390
- resultingNotificationMap.putString("id", notification.getId());
391
- resultingNotificationMap.putString("title", notification.getNotificationTitle());
392
- }
393
-
394
- successCallback.invoke(resultingNotificationMap);
161
+ successCallback.invoke(
162
+ RNHelpers.convertMapToWritableMap(this.manager.getLastRemotePushNotification())
163
+ );
395
164
  }
396
165
 
397
166
  @ReactMethod
398
167
  public void setNotificationSmallIcon(String iconName) {
399
- final int resourceId = processNotificationIcon(iconName);
400
- smManager.setNotificationSmallIcon(resourceId);
168
+ this.manager.setNotificationSmallIcon(this.reactContext, iconName);
401
169
  }
402
170
 
403
171
  @ReactMethod
404
172
  public void setNotificationLargeIcon(String iconName) {
405
- final int resourceId = processNotificationIcon(iconName);
406
-
407
- smManager.setNotificationLargeIcon(resourceId);
408
- }
409
-
410
- private int processNotificationIcon(String iconName) {
411
- final Resources resources = reactContext.getResources();
412
- final int resourceId = resources.getIdentifier(iconName, "drawable", reactContext.getPackageName());
413
-
414
- if (resourceId == 0) {
415
- throw new IllegalArgumentException("Could not find a drawable with the name " + iconName);
416
- }
417
-
418
- return resourceId;
173
+ this.manager.setNotificationLargeIcon(this.reactContext, iconName);
419
174
  }
420
175
 
421
176
  @ReactMethod
422
- public void setNotificationIconColor(final String colorString, final Callback successCallback, final Callback errorCallback) {
423
- try {
424
- final int color = Color.parseColor(colorString);
425
- smManager.setNotificationIconColor(color);
426
- successCallback.invoke();
427
- } catch (IllegalArgumentException e) {
428
- errorCallback.invoke("color must be a color hex string.");
429
- }
177
+ public void setNotificationIconColor(String colorString, Callback successCallback, Callback errorCallback) {
178
+ processErrorStringToCallback(
179
+ this.manager.setNotificationIconColor(colorString),
180
+ successCallback,
181
+ errorCallback
182
+ );
430
183
  }
431
184
 
432
185
  @ReactMethod
433
- public void setNotificationActivity(final String activityName, final Callback successCallback, final Callback errorCallback) {
434
- try {
435
- SMManager.NOTIFICATION_ACTIVITY = (Class<? extends Activity>) Class.forName(activityName);
436
- successCallback.invoke();
437
- } catch (ClassNotFoundException e) {
438
- errorCallback.invoke(String.format("Activity %s not found.", activityName));
439
- }
186
+ public void setNotificationActivity(String activityName, Callback successCallback, Callback errorCallback) {
187
+ processErrorStringToCallback(
188
+ Manager.setNotificationActivity(activityName),
189
+ successCallback,
190
+ errorCallback
191
+ );
440
192
  }
441
193
 
442
194
  @ReactMethod
443
195
  public void getGCMToken(Callback callback) {
444
- final String gcmToken = smManager.getGCMToken();
445
- callback.invoke(gcmToken);
196
+ callback.invoke(this.manager.getGCMToken());
446
197
  }
447
198
 
448
199
  @ReactMethod
449
200
  public void getRemoteMessagesDisplayType(Callback successCallback) {
450
- final SMRemoteMessageDisplayType smRemoteMessageDisplayType = smManager.getRemoteMessagesDisplayType();
451
- final RemoteMessageDisplayType remoteMessageDisplayType = RemoteMessageDisplayType.valueOf(smRemoteMessageDisplayType);
452
- final Integer resultingRemoteMessageDisplayTypeIndex = remoteMessageDisplayType.getIndex();
453
-
454
- successCallback.invoke(resultingRemoteMessageDisplayTypeIndex);
201
+ successCallback.invoke(this.manager.getRemoteMessagesDisplayType());
455
202
  }
456
203
 
457
204
  @ReactMethod
458
205
  public void areNotificationsEnabled(Callback successCallback) {
459
- final Boolean areNotificationsEnabled = smManager.areNotificationEnabled();
460
-
461
- successCallback.invoke(areNotificationsEnabled);
206
+ successCallback.invoke(this.manager.areNotificationsEnabled());
462
207
  }
463
208
 
464
209
  @ReactMethod
465
210
  public void subscribeToEvents(ReadableArray customEvents) {
466
- final Activity currentActivity = getCurrentActivity();
467
-
468
- if (currentActivity != null)
469
- {
470
- if (currentActivity instanceof AppCompatActivity)
471
- {
472
- AppCompatActivity thisActivity = (AppCompatActivity)currentActivity;
473
- DeviceEventManagerModule.RCTDeviceEventEmitter rctDeviceEventEmitter = reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
474
-
475
- thisActivity.runOnUiThread(() -> {
476
- if (!areObserverStarted)
477
- {
478
- Log.d(RN_SELLIGENT_NAME, "Instantiating the observers on the UI thread");
479
- SMObserverManager observerManager = smManager.getObserverManager();
480
-
481
- // Token received
482
- final Observer<String> tokenObserver = token -> {
483
- String eventName = BroadcastEventType.ReceivedGCMToken.getBroadcastEventType();
484
- GCMTokenBroadcastEventDataParser broadcastEventDataParser = new GCMTokenBroadcastEventDataParser();
485
- final WritableMap data = broadcastEventDataParser.wrap(token);
486
- rctDeviceEventEmitter.emit(eventName, getBroadcastData(eventName, data));
487
- };
488
- observerManager.observeToken(thisActivity, tokenObserver);
489
-
490
- // Device id received
491
- final Observer<String> deviceIdObserver = deviceId -> {
492
- String eventName = BroadcastEventType.ReceivedDeviceId.getBroadcastEventType();
493
- DeviceIdBroadcastEventDataParser broadcastEventDataParser = new DeviceIdBroadcastEventDataParser();
494
- final WritableMap data = broadcastEventDataParser.wrap(deviceId);
495
- rctDeviceEventEmitter.emit(eventName, getBroadcastData(eventName, data));
496
- };
497
- observerManager.observeDeviceId(thisActivity, deviceIdObserver);
498
-
499
- // InApp messages received
500
- final Observer<SMInAppMessage[]> inAppMessageObserver = inAppMessages -> {
501
- if (inAppMessages != null)
502
- {
503
- String eventName = BroadcastEventType.ReceivedInAppMessage.getBroadcastEventType();
504
- InAppMessageBroadcastEventDataParser broadcastEventDataParser = new InAppMessageBroadcastEventDataParser();
505
- final WritableMap data = broadcastEventDataParser.wrap(inAppMessages);
506
- rctDeviceEventEmitter.emit(eventName, getBroadcastData(eventName, data));
507
- }
508
- };
509
- observerManager.observeInAppMessages(thisActivity, inAppMessageObserver);
510
-
511
- // Button clicked
512
- final Observer<SMNotificationButton> clickedButtonObserver = button -> {
513
- if (button != null)
514
- {
515
- String eventName = BroadcastEventType.ButtonClicked.getBroadcastEventType();
516
- ButtonBroadcastEventDataParser broadcastEventDataParser = new ButtonBroadcastEventDataParser();
517
- final WritableMap data = broadcastEventDataParser.wrap(button);
518
- rctDeviceEventEmitter.emit(eventName, getBroadcastData(eventName, data));
519
- }
520
- };
521
- observerManager.observeClickedButton(thisActivity, clickedButtonObserver);
522
-
523
- // Message dismissed
524
- final Observer<Void> dismissedMessageObserver = object -> {
525
- String eventName = BroadcastEventType.WillDismissNotification.getBroadcastEventType();
526
- rctDeviceEventEmitter.emit(eventName, getBroadcastData(eventName, null));
527
- };
528
- observerManager.observeDismissedMessage(thisActivity, dismissedMessageObserver);
529
-
530
- // Message displayed
531
- final Observer<Void> displayedMessageObserver = object -> {
532
- String eventName = BroadcastEventType.WillDisplayNotification.getBroadcastEventType();
533
- rctDeviceEventEmitter.emit(eventName, getBroadcastData(eventName, null));
534
- };
535
- observerManager.observeDisplayedMessage(thisActivity, displayedMessageObserver);
536
-
537
- // Push received
538
- final Observer<SMNotificationMessage> pushReceivedObserver = notificationMessage -> {
539
- if (notificationMessage != null)
540
- {
541
- String eventName = BroadcastEventType.ReceivedNotification.getBroadcastEventType();
542
- NotificationMessageBroadcastEventDataParser broadcastEventDataParser = new NotificationMessageBroadcastEventDataParser();
543
- final WritableMap data = broadcastEventDataParser.wrap(notificationMessage);
544
- rctDeviceEventEmitter.emit(eventName, getBroadcastData(eventName, data));
545
- }
546
- };
547
- observerManager.observePushReceived(thisActivity, pushReceivedObserver);
548
-
549
- // Custom events
550
- final Observer<String> customEventObserver = event -> rctDeviceEventEmitter.emit(BroadcastEventType.TriggeredCustomEvent.getBroadcastEventType(), getBroadcastData(event, null));
551
- observerManager.observeEvent(thisActivity, customEventObserver);
552
-
553
- areObserverStarted = true;
554
- }
555
- else
556
- {
557
- Log.d(RN_SELLIGENT_NAME, "Observers already instantiated");
558
- }
559
- });
560
- }
561
- else
562
- {
563
- final LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(currentActivity);
564
-
565
- if (eventReceiver == null) {
566
- eventReceiver = new EventReceiver(reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class));
567
- } else {
568
- localBroadcastManager.unregisterReceiver(eventReceiver);
569
- }
570
-
571
- final IntentFilter filter = new IntentFilter();
572
- filter.addAction(SMManager.BROADCAST_EVENT_RECEIVED_IN_APP_MESSAGE);
573
- filter.addAction(SMManager.BROADCAST_EVENT_WILL_DISPLAY_NOTIFICATION);
574
- filter.addAction(SMManager.BROADCAST_EVENT_WILL_DISMISS_NOTIFICATION);
575
- filter.addAction(SMManager.BROADCAST_EVENT_BUTTON_CLICKED);
576
- filter.addAction(SMManager.BROADCAST_EVENT_RECEIVED_GCM_TOKEN);
577
-
578
- for (int i = 0; i < customEvents.size(); i++) {
579
- filter.addAction(customEvents.getString(i));
580
- }
581
-
582
- localBroadcastManager.registerReceiver(eventReceiver, filter);
583
- }
211
+ Activity currentActivity = this.getCurrentActivity();
212
+
213
+ if (currentActivity == null) { return; }
214
+
215
+ if (currentActivity instanceof AppCompatActivity) {
216
+ AppCompatActivity activity = (AppCompatActivity)currentActivity;
217
+
218
+ activity.runOnUiThread(() ->
219
+ this.manager.initializeObservers(activity, this::broadcastEvent)
220
+ );
221
+
222
+ return;
584
223
  }
585
- }
586
224
 
587
- WritableMap getBroadcastData(String eventName, WritableMap data)
588
- {
589
- final WritableMap broadcastData = new WritableNativeMap();
225
+ LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(currentActivity);
590
226
 
591
- broadcastData.putString("broadcastEventType", eventName);
592
- broadcastData.putMap("data", data);
227
+ if (this.eventReceiver == null) {
228
+ this.eventReceiver = new EventReceiver(
229
+ reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class
230
+ ));
231
+ }
232
+ else {
233
+ localBroadcastManager.unregisterReceiver(this.eventReceiver);
234
+ }
593
235
 
594
- return broadcastData;
236
+ localBroadcastManager.registerReceiver(
237
+ this.eventReceiver,
238
+ Manager.eventsIntentFilter(customEvents.toArrayList())
239
+ );
595
240
  }
596
241
 
597
242
  @ReactMethod
598
243
  public void setFirebaseToken(String token) {
599
- smManager.setFirebaseToken(token);
244
+ this.manager.setFirebaseToken(token);
600
245
  }
601
246
 
247
+ @SuppressLint("UnspecifiedRegisterReceiverFlag")
602
248
  @Override
603
249
  public void onHostResume() {
604
- final Activity currentActivity = getCurrentActivity();
250
+ Activity currentActivity = this.getCurrentActivity();
605
251
 
606
- if (currentActivity != null) {
607
- if (receiver == null)
608
- {
609
- receiver = new SMForegroundGcmBroadcastReceiver(currentActivity);
610
- }
252
+ if (currentActivity == null) { return; }
611
253
 
612
- currentActivity.registerReceiver(receiver, receiver.getIntentFilter());
613
- this.DisplayInAppMessage(currentActivity.getIntent(), currentActivity);
254
+ if (this.receiver == null) {
255
+ this.receiver = new SMForegroundGcmBroadcastReceiver(currentActivity);
614
256
  }
257
+
258
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
259
+ currentActivity.registerReceiver(this.receiver, this.receiver.getIntentFilter(), Context.RECEIVER_NOT_EXPORTED);
260
+ }
261
+ else {
262
+ currentActivity.registerReceiver(this.receiver, this.receiver.getIntentFilter());
263
+ }
264
+
265
+ this.manager.checkAndDisplayMessage(currentActivity.getIntent(), currentActivity, this::broadcastEvent);
615
266
  }
616
267
 
617
268
  @Override
618
269
  public void onHostPause() {
619
- final Activity currentActivity = getCurrentActivity();
270
+ Activity currentActivity = this.getCurrentActivity();
620
271
 
621
- if (currentActivity != null) {
622
- currentActivity.unregisterReceiver(receiver);
623
- }
272
+ if (currentActivity == null) { return; }
273
+
274
+ currentActivity.unregisterReceiver(this.receiver);
624
275
  }
625
276
 
626
277
  @Override
@@ -628,30 +279,30 @@ public class RNSelligent extends ReactContextBaseJavaModule implements Lifecycle
628
279
 
629
280
  @Override
630
281
  public void onNewIntent(Intent intent) {
631
- final Activity currentActivity = getCurrentActivity();
282
+ Activity currentActivity = this.getCurrentActivity();
632
283
 
633
- if (currentActivity != null) {
634
- currentActivity.setIntent(intent);
635
- this.DisplayInAppMessage(intent, currentActivity);
636
- }
284
+ if (currentActivity == null) { return; }
285
+
286
+ currentActivity.setIntent(intent);
287
+ this.manager.checkAndDisplayMessage(intent, currentActivity, this::broadcastEvent);
637
288
  }
638
289
 
639
290
  @Override
640
291
  public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { }
641
-
642
- private void DisplayInAppMessage(Intent intent, Activity currentActivity) {
643
- smManager.checkAndDisplayMessage(intent, currentActivity, message -> {
644
- if (!inAppMessageCustomUi) {
645
- return true;
646
- }
647
-
648
- DeviceEventManagerModule.RCTDeviceEventEmitter rctDeviceEventEmitter = reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
649
- InAppMessageBroadcastEventDataParser inAppDataParser = new InAppMessageBroadcastEventDataParser();
650
- String eventName = BroadcastEventType.DisplayingInAppMessage.getBroadcastEventType();
651
- WritableMap data = inAppDataParser.wrap(message);
652
- rctDeviceEventEmitter.emit(eventName, getBroadcastData(eventName, data));
653
-
654
- return false;
655
- });
292
+
293
+ private void broadcastEvent(String eventName, Map<String, Object> data) {
294
+ this.reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(
295
+ eventName,
296
+ RNHelpers.convertMapToWritableMap(data)
297
+ );
298
+ }
299
+
300
+ private void processErrorStringToCallback(String error, Callback successCallback, Callback errorCallback) {
301
+ if (error == null) {
302
+ successCallback.invoke();
303
+ return;
304
+ }
305
+
306
+ errorCallback.invoke(error);
656
307
  }
657
308
  }
@@ -1,7 +1,7 @@
1
-
2
1
  package com.selligent;
3
2
 
4
- import java.util.Arrays;
3
+ import androidx.annotation.NonNull;
4
+
5
5
  import java.util.Collections;
6
6
  import java.util.List;
7
7
 
@@ -10,19 +10,22 @@ import com.facebook.react.bridge.NativeModule;
10
10
  import com.facebook.react.bridge.ReactApplicationContext;
11
11
  import com.facebook.react.uimanager.ViewManager;
12
12
  import com.facebook.react.bridge.JavaScriptModule;
13
+
13
14
  public class RNSelligentPackage implements ReactPackage {
15
+ @NonNull
14
16
  @Override
15
- public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
16
- return Arrays.<NativeModule>asList(new RNSelligent(reactContext));
17
+ public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
18
+ return Collections.singletonList(new RNSelligent(reactContext));
17
19
  }
18
20
 
19
- // Deprecated from RN 0.47
20
21
  public List<Class<? extends JavaScriptModule>> createJSModules() {
21
- return Collections.emptyList();
22
+ return Collections.emptyList();
22
23
  }
23
24
 
25
+ @NonNull
24
26
  @Override
25
- public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
26
- return Collections.emptyList();
27
+ @SuppressWarnings("rawtypes")
28
+ public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
29
+ return Collections.emptyList();
27
30
  }
28
31
  }
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  },
5
5
  "name": "@selligent-marketing-cloud/selligent-react-native",
6
6
  "title": "Marigold Engage React Native",
7
- "version": "3.6.0",
7
+ "version": "3.7.1",
8
8
  "description": "React Native wrapper for the Marigold Engage Android and iOS SDKs",
9
9
  "main": "index.js",
10
10
  "repository": {