@attentive-mobile/attentive-react-native-sdk 2.0.0-beta.3 → 2.0.0-beta.5

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.
Files changed (27) hide show
  1. package/README.md +145 -10
  2. package/android/build.gradle +4 -0
  3. package/android/src/main/AndroidManifest.xml +2 -0
  4. package/android/src/main/kotlin/com/attentivereactnativesdk/AttentivePushHelper.kt +93 -0
  5. package/android/src/main/kotlin/com/attentivereactnativesdk/AttentiveReactNativeSdkModule.kt +382 -56
  6. package/android/src/main/kotlin/com/attentivereactnativesdk/debug/NetworkingHelper.kt +220 -0
  7. package/ios/AttentiveReactNativeSdk.mm +33 -0
  8. package/ios/AttentiveReactNativeSdk.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  9. package/ios/AttentiveReactNativeSdk.xcodeproj/project.xcworkspace/xcuserdata/zheref.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  10. package/ios/AttentiveReactNativeSdk.xcodeproj/xcuserdata/zheref.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
  11. package/ios/Bridging/ATTNNativeSDK.swift +47 -6
  12. package/lib/commonjs/NativeAttentiveReactNativeSdk.js.map +1 -1
  13. package/lib/commonjs/eventTypes.js.map +1 -1
  14. package/lib/commonjs/index.js +28 -9
  15. package/lib/commonjs/index.js.map +1 -1
  16. package/lib/module/NativeAttentiveReactNativeSdk.js.map +1 -1
  17. package/lib/module/eventTypes.js.map +1 -1
  18. package/lib/module/index.js +29 -11
  19. package/lib/module/index.js.map +1 -1
  20. package/lib/typescript/NativeAttentiveReactNativeSdk.d.ts +9 -1
  21. package/lib/typescript/NativeAttentiveReactNativeSdk.d.ts.map +1 -1
  22. package/lib/typescript/index.d.ts +24 -9
  23. package/lib/typescript/index.d.ts.map +1 -1
  24. package/package.json +7 -3
  25. package/src/NativeAttentiveReactNativeSdk.ts +11 -2
  26. package/src/index.tsx +29 -10
  27. package/ios/AttentiveReactNativeSdk.xcworkspace/contents.xcworkspacedata +0 -10
@@ -0,0 +1,220 @@
1
+ package com.attentivereactnativesdk.debug
2
+
3
+ import android.util.Log
4
+ import okhttp3.*
5
+ import okhttp3.logging.HttpLoggingInterceptor
6
+ import java.io.IOException
7
+ import java.util.concurrent.TimeUnit
8
+
9
+ /**
10
+ * Networking helper for debugging HTTP requests made by the Attentive SDK.
11
+ *
12
+ * This class provides:
13
+ * - HTTP request/response logging
14
+ * - Network call tracking for debugging
15
+ * - Integration with the debug overlay
16
+ *
17
+ * Note: This is for debugging purposes only and should be disabled in production builds.
18
+ */
19
+ class NetworkingHelper(private val debugHelper: AttentiveDebugHelper) {
20
+
21
+ companion object {
22
+ private const val TAG = "AttentiveNetworking"
23
+
24
+ /**
25
+ * Creates an OkHttpClient with logging interceptor for debugging network calls.
26
+ * This can be used to wrap network requests and log all traffic.
27
+ *
28
+ * @param enableLogging Whether to enable detailed HTTP logging
29
+ * @return Configured OkHttpClient instance
30
+ */
31
+ fun createDebugClient(enableLogging: Boolean = true): OkHttpClient {
32
+ val builder = OkHttpClient.Builder()
33
+ .connectTimeout(30, TimeUnit.SECONDS)
34
+ .readTimeout(30, TimeUnit.SECONDS)
35
+ .writeTimeout(30, TimeUnit.SECONDS)
36
+
37
+ if (enableLogging) {
38
+ val loggingInterceptor = HttpLoggingInterceptor { message ->
39
+ Log.d(TAG, "🌐 [HTTP] $message")
40
+ }.apply {
41
+ level = HttpLoggingInterceptor.Level.BODY
42
+ }
43
+
44
+ builder.addInterceptor(loggingInterceptor)
45
+ }
46
+
47
+ return builder.build()
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Logs a network request for debugging purposes.
53
+ *
54
+ * @param url The request URL
55
+ * @param method The HTTP method (GET, POST, etc.)
56
+ * @param headers Request headers
57
+ * @param body Request body (if any)
58
+ */
59
+ fun logRequest(
60
+ url: String,
61
+ method: String,
62
+ headers: Map<String, String>? = null,
63
+ body: String? = null
64
+ ) {
65
+ Log.i(TAG, "📤 [Network Request]")
66
+ Log.i(TAG, " Method: $method")
67
+ Log.i(TAG, " URL: $url")
68
+
69
+ headers?.let {
70
+ Log.d(TAG, " Headers:")
71
+ it.forEach { (key, value) ->
72
+ Log.d(TAG, " $key: $value")
73
+ }
74
+ }
75
+
76
+ body?.let {
77
+ Log.d(TAG, " Body: $it")
78
+ }
79
+
80
+ if (debugHelper.isDebuggingEnabled()) {
81
+ val debugData = mutableMapOf<String, Any>()
82
+ debugData["request_method"] = method
83
+ debugData["request_url"] = url
84
+ headers?.let { debugData["headers_count"] = it.size.toString() }
85
+ body?.let { debugData["body_length"] = it.length.toString() }
86
+
87
+ debugHelper.showDebugInfo("Network Request", debugData)
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Logs a network response for debugging purposes.
93
+ *
94
+ * @param url The request URL
95
+ * @param statusCode HTTP status code
96
+ * @param headers Response headers
97
+ * @param body Response body (if any)
98
+ * @param durationMs Request duration in milliseconds
99
+ */
100
+ fun logResponse(
101
+ url: String,
102
+ statusCode: Int,
103
+ headers: Map<String, String>? = null,
104
+ body: String? = null,
105
+ durationMs: Long? = null
106
+ ) {
107
+ val statusEmoji = when {
108
+ statusCode in 200..299 -> "✅"
109
+ statusCode in 300..399 -> "↪️"
110
+ statusCode in 400..499 -> "⚠️"
111
+ statusCode >= 500 -> "❌"
112
+ else -> "❓"
113
+ }
114
+
115
+ Log.i(TAG, "📥 [Network Response] $statusEmoji")
116
+ Log.i(TAG, " URL: $url")
117
+ Log.i(TAG, " Status: $statusCode")
118
+ durationMs?.let { Log.i(TAG, " Duration: ${it}ms") }
119
+
120
+ headers?.let {
121
+ Log.d(TAG, " Headers:")
122
+ it.forEach { (key, value) ->
123
+ Log.d(TAG, " $key: $value")
124
+ }
125
+ }
126
+
127
+ body?.let {
128
+ Log.d(TAG, " Body: ${it.take(500)}${if (it.length > 500) "..." else ""}")
129
+ }
130
+
131
+ if (debugHelper.isDebuggingEnabled()) {
132
+ val debugData = mutableMapOf<String, Any>()
133
+ debugData["response_status"] = statusCode.toString()
134
+ debugData["response_url"] = url
135
+ debugData["status_emoji"] = statusEmoji
136
+ headers?.let { debugData["headers_count"] = it.size.toString() }
137
+ body?.let { debugData["body_length"] = it.length.toString() }
138
+ durationMs?.let { debugData["duration_ms"] = it.toString() }
139
+
140
+ debugHelper.showDebugInfo("Network Response", debugData)
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Logs a network error for debugging purposes.
146
+ *
147
+ * @param url The request URL
148
+ * @param error The error that occurred
149
+ * @param durationMs Request duration in milliseconds (if applicable)
150
+ */
151
+ fun logError(
152
+ url: String,
153
+ error: Throwable,
154
+ durationMs: Long? = null
155
+ ) {
156
+ Log.e(TAG, "❌ [Network Error]")
157
+ Log.e(TAG, " URL: $url")
158
+ Log.e(TAG, " Error: ${error.message}")
159
+ durationMs?.let { Log.e(TAG, " Duration: ${it}ms") }
160
+ Log.e(TAG, " Exception:", error)
161
+
162
+ if (debugHelper.isDebuggingEnabled()) {
163
+ val debugData = mutableMapOf<String, Any>()
164
+ debugData["error_url"] = url
165
+ debugData["error_message"] = error.message ?: "Unknown error"
166
+ debugData["error_type"] = error.javaClass.simpleName
167
+ durationMs?.let { debugData["duration_ms"] = it.toString() }
168
+
169
+ debugHelper.showDebugInfo("Network Error", debugData)
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Creates an interceptor that can be added to OkHttpClient for automatic logging.
175
+ * This is useful for transparently logging all SDK network calls.
176
+ *
177
+ * @return An OkHttp Interceptor for network logging
178
+ */
179
+ fun createLoggingInterceptor(): Interceptor {
180
+ return Interceptor { chain ->
181
+ val request = chain.request()
182
+ val startTime = System.currentTimeMillis()
183
+
184
+ // Log request
185
+ logRequest(
186
+ url = request.url.toString(),
187
+ method = request.method,
188
+ headers = request.headers.toMultimap().mapValues { it.value.firstOrNull() ?: "" },
189
+ body = request.body?.toString()
190
+ )
191
+
192
+ try {
193
+ val response = chain.proceed(request)
194
+ val duration = System.currentTimeMillis() - startTime
195
+
196
+ // Log response
197
+ logResponse(
198
+ url = request.url.toString(),
199
+ statusCode = response.code,
200
+ headers = response.headers.toMultimap().mapValues { it.value.firstOrNull() ?: "" },
201
+ body = response.peekBody(1024).string(),
202
+ durationMs = duration
203
+ )
204
+
205
+ response
206
+ } catch (e: IOException) {
207
+ val duration = System.currentTimeMillis() - startTime
208
+
209
+ // Log error
210
+ logError(
211
+ url = request.url.toString(),
212
+ error = e,
213
+ durationMs = duration
214
+ )
215
+
216
+ throw e
217
+ }
218
+ }
219
+ }
220
+ }
@@ -335,6 +335,38 @@ customIdentifiers:(NSDictionary *)customIdentifiers {
335
335
  }
336
336
  return UNAuthorizationStatusNotDetermined;
337
337
  }
338
+
339
+ // Helper to convert UNAuthorizationStatus to string for getPushAuthorizationStatus
340
+ - (NSString *)authorizationStatusToRNString:(UNAuthorizationStatus)status {
341
+ switch (status) {
342
+ case UNAuthorizationStatusAuthorized:
343
+ return @"authorized";
344
+ case UNAuthorizationStatusDenied:
345
+ return @"denied";
346
+ case UNAuthorizationStatusNotDetermined:
347
+ return @"notDetermined";
348
+ #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000
349
+ case UNAuthorizationStatusProvisional:
350
+ return @"provisional";
351
+ #endif
352
+ #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
353
+ case UNAuthorizationStatusEphemeral:
354
+ return @"ephemeral";
355
+ #endif
356
+ default:
357
+ return @"notDetermined";
358
+ }
359
+ }
360
+
361
+ - (void)getPushAuthorizationStatus:(RCTPromiseResolveBlock)resolve
362
+ reject:(RCTPromiseRejectBlock)reject {
363
+ UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
364
+ [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
365
+ NSString *status = [self authorizationStatusToRNString:settings.authorizationStatus];
366
+ resolve(status);
367
+ }];
368
+ }
369
+
338
370
  - (void)triggerCreative:(NSString *)creativeId {
339
371
  dispatch_async(dispatch_get_main_queue(), ^{
340
372
  UIWindow *window = [[UIApplication sharedApplication] keyWindow];
@@ -350,6 +382,7 @@ customIdentifiers:(NSDictionary *)customIdentifiers {
350
382
  - (void)destroyCreative {
351
383
  dispatch_async(dispatch_get_main_queue(), ^{
352
384
  // [self->_sdk closeCreative]
385
+ [self->_sdk notifyCreativeDestroyed];
353
386
  });
354
387
  }
355
388
 
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Workspace
3
+ version = "1.0">
4
+ <FileRef
5
+ location = "self:">
6
+ </FileRef>
7
+ </Workspace>
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>SchemeUserState</key>
6
+ <dict>
7
+ <key>AttentiveReactNativeSdk.xcscheme_^#shared#^_</key>
8
+ <dict>
9
+ <key>orderHint</key>
10
+ <integer>0</integer>
11
+ </dict>
12
+ </dict>
13
+ </dict>
14
+ </plist>
@@ -124,9 +124,20 @@ struct DebugEvent {
124
124
  }
125
125
  }
126
126
 
127
+ /// Called from the native bridge when destroyCreative is invoked; shows debug overlay when debug mode is on.
128
+ @objc
129
+ public func notifyCreativeDestroyed() {
130
+ if debuggingEnabled {
131
+ showDebugInfo(event: "Creative Destroyed", data: ["action": "destroyCreative"])
132
+ }
133
+ }
134
+
127
135
  @objc(updateDomain:)
128
136
  public func updateDomain(domain: String) {
129
137
  sdk.update(domain:domain)
138
+ if debuggingEnabled {
139
+ showDebugInfo(event: "Domain Updated", data: ["domain": domain])
140
+ }
130
141
  }
131
142
 
132
143
  @objc(identify:)
@@ -136,6 +147,10 @@ struct DebugEvent {
136
147
 
137
148
  sdk.identify(identifiers)
138
149
 
150
+ if debuggingEnabled {
151
+ showDebugInfo(event: "User Identified", data: ["identifiers": identifiers])
152
+ }
153
+
139
154
  print("✅ [AttentiveSDK] identify completed")
140
155
  print(" User is now identified with the SDK")
141
156
  print(" SDK can now make network calls")
@@ -144,6 +159,9 @@ struct DebugEvent {
144
159
  @objc
145
160
  public func clearUser() {
146
161
  sdk.clearUser()
162
+ if debuggingEnabled {
163
+ showDebugInfo(event: "User Cleared", data: ["action": "clearUser"])
164
+ }
147
165
  }
148
166
 
149
167
  // MARK: - Push Notification Methods
@@ -628,13 +646,19 @@ public extension ATTNNativeSDK {
628
646
 
629
647
  @objc
630
648
  func recordPurchaseEvent(_ attributes: [String: Any]) {
631
- let attrOrder = attributes["order"] as? [String: String] ?? [:]
632
- guard let orderId = attrOrder["id"] else { return }
649
+ // React Native bridge sends top-level "orderId"; legacy format used "order"["id"]
650
+ let orderId = (attributes["orderId"] as? String)
651
+ ?? (attributes["order"] as? [String: String])?["id"]
652
+ guard let orderId = orderId else { return }
633
653
  let order = ATTNOrder(orderId: orderId)
634
654
  let items = parseItems(attributes["items"] as? [[String : Any]] ?? [])
635
655
  let event = ATTNPurchaseEvent(items: items, order: order)
656
+
657
+ #if DEBUG
658
+ print("[Attentive]", event.debugDescription)
659
+ #endif
636
660
  ATTNEventTracker.sharedInstance()?.record(event: event)
637
-
661
+
638
662
  if debuggingEnabled {
639
663
  // Enhanced debug data to show parsed item details
640
664
  var debugData: [String: Any] = [
@@ -727,18 +751,35 @@ private extension ATTNNativeSDK {
727
751
  debugHistory.append(debugEvent)
728
752
 
729
753
  DispatchQueue.main.async {
730
- // Create debug overlay with history
731
754
  guard let keyWindow = UIApplication.shared.connectedScenes
732
755
  .compactMap({ $0 as? UIWindowScene })
733
756
  .first?.windows
734
- .first(where: { $0.isKeyWindow }) else { return }
757
+ .first(where: { $0.isKeyWindow }),
758
+ let rootVC = keyWindow.rootViewController else { return }
759
+
760
+ // Present from the topmost view controller so the debug window always appears on top
761
+ let topmost = self.topmostViewController(from: rootVC)
735
762
 
736
763
  let debugVC = DebugOverlayViewController(currentEvent: event, currentData: data, history: self.debugHistory)
737
764
  debugVC.modalPresentationStyle = .overFullScreen
738
765
  debugVC.modalTransitionStyle = .crossDissolve
739
766
 
740
- keyWindow.rootViewController?.present(debugVC, animated: true)
767
+ topmost.present(debugVC, animated: true)
768
+ }
769
+ }
770
+
771
+ /// Returns the topmost view controller so the debug overlay is presented on top of any existing modals.
772
+ func topmostViewController(from base: UIViewController) -> UIViewController {
773
+ if let presented = base.presentedViewController {
774
+ return topmostViewController(from: presented)
775
+ }
776
+ if let nav = base as? UINavigationController, let visible = nav.visibleViewController {
777
+ return topmostViewController(from: visible)
778
+ }
779
+ if let tab = base as? UITabBarController, let selected = tab.selectedViewController {
780
+ return topmostViewController(from: selected)
741
781
  }
782
+ return base
742
783
  }
743
784
  }
744
785
 
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","isTurboModuleEnabled","global","__turboModuleProxy","AttentiveReactNativeSdkModule","TurboModuleRegistry","get","NativeModules","AttentiveReactNativeSdk","_default","exports","default"],"sourceRoot":"../../src","sources":["NativeAttentiveReactNativeSdk.ts"],"mappings":";;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AA8IA;AACA;AACA,MAAMC,oBAAoB,GAAIC,MAAM,CAASC,kBAAkB,IAAI,IAAI;AAEvE,MAAMC,6BAA6B,GAAGH,oBAAoB,GACtDI,gCAAmB,CAACC,GAAG,CAAO,yBAAyB,CAAC,GACxDC,0BAAa,CAACC,uBAAuB;AAAC,IAAAC,QAAA,GAE3BL,6BAA6B;AAAAM,OAAA,CAAAC,OAAA,GAAAF,QAAA","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","isTurboModuleEnabled","global","__turboModuleProxy","AttentiveReactNativeSdkModule","TurboModuleRegistry","get","NativeModules","AttentiveReactNativeSdk","_default","exports","default"],"sourceRoot":"../../src","sources":["NativeAttentiveReactNativeSdk.ts"],"mappings":";;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AAuJA;AACA;AACA,MAAMC,oBAAoB,GAAIC,MAAM,CAASC,kBAAkB,IAAI,IAAI;AAEvE,MAAMC,6BAA6B,GAAGH,oBAAoB,GACtDI,gCAAmB,CAACC,GAAG,CAAO,yBAAyB,CAAC,GACxDC,0BAAa,CAACC,uBAAuB;AAAC,IAAAC,QAAA,GAE3BL,6BAA6B;AAAAM,OAAA,CAAAC,OAAA,GAAAF,QAAA"}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sourceRoot":"../../src","sources":["eventTypes.tsx"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sourceRoot":"../../src","sources":["eventTypes.tsx"],"mappings":""}
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.clearUser = clearUser;
7
7
  exports.destroyCreative = destroyCreative;
8
8
  exports.exportDebugLogs = exportDebugLogs;
9
+ exports.getPushAuthorizationStatus = getPushAuthorizationStatus;
9
10
  exports.handleForegroundNotification = handleForegroundNotification;
10
11
  exports.handleForegroundPush = handleForegroundPush;
11
12
  exports.handlePushOpen = handlePushOpen;
@@ -130,13 +131,13 @@ function exportDebugLogs() {
130
131
  }
131
132
 
132
133
  // =============================================================================
133
- // Push Notification Methods (iOS only - Android is no-op with TODO stubs)
134
+ // Push Notification Methods (iOS and Android)
134
135
  // =============================================================================
135
136
 
136
137
  /**
137
138
  * Request push notification permission from the user.
138
139
  * On iOS, this will trigger the system permission dialog.
139
- * On Android, this is currently a no-op (TODO: implement FCM integration).
140
+ * On Android 13+, this requests POST_NOTIFICATIONS; on older versions, no-op.
140
141
  *
141
142
  * @example
142
143
  * ```typescript
@@ -150,12 +151,30 @@ function registerForPushNotifications() {
150
151
  AttentiveReactNativeSdk.registerForPushNotifications();
151
152
  }
152
153
 
154
+ /**
155
+ * Get the current push notification authorization status.
156
+ * On Android, uses the SDK's native check (POST_NOTIFICATIONS on API 33+).
157
+ * On iOS, uses UNUserNotificationCenter notification settings.
158
+ *
159
+ * @returns Promise resolving to 'authorized' | 'denied' | 'notDetermined' (and on iOS possibly 'provisional' | 'ephemeral')
160
+ *
161
+ * @example
162
+ * ```typescript
163
+ * import { getPushAuthorizationStatus, handleRegularOpen } from 'attentive-react-native-sdk';
164
+ *
165
+ * getPushAuthorizationStatus().then((status) => handleRegularOpen(status));
166
+ * ```
167
+ */
168
+ function getPushAuthorizationStatus() {
169
+ return AttentiveReactNativeSdk.getPushAuthorizationStatus();
170
+ }
171
+
153
172
  /**
154
173
  * Register the device token received from APNs/FCM with the Attentive backend.
155
174
  * Call this from your AppDelegate's didRegisterForRemoteNotificationsWithDeviceToken.
156
175
  *
157
176
  * On iOS, the token should be the hex-encoded string representation of the device token Data.
158
- * On Android, this is currently a no-op (TODO: implement FCM integration).
177
+ * On Android, registers the FCM token when provided by the host app.
159
178
  *
160
179
  * @param token - The device token as a hex-encoded string
161
180
  * @param authorizationStatus - Current push authorization status
@@ -178,7 +197,7 @@ function registerDeviceToken(token, authorizationStatus) {
178
197
  *
179
198
  * On iOS, this will register the device token with the Attentive SDK and invoke the callback
180
199
  * after the registration completes (success or failure).
181
- * On Android, this is currently a no-op (TODO: implement FCM integration).
200
+ * On Android, registers the FCM token when provided by the host app.
182
201
  *
183
202
  * @param token - The hex-encoded device token string from APNs
184
203
  * @param authorizationStatus - Current push authorization status
@@ -225,7 +244,7 @@ function registerDeviceTokenWithCallback(token, authorizationStatus, callback) {
225
244
  *
226
245
  * On iOS, this will notify the Attentive SDK that the app was opened directly
227
246
  * (not from a push notification tap).
228
- * On Android, this is currently a no-op (TODO: implement FCM integration).
247
+ * On Android, registers the FCM token when provided by the host app.
229
248
  *
230
249
  * @param authorizationStatus - Current push authorization status
231
250
  *
@@ -268,7 +287,7 @@ function handleRegularOpen(authorizationStatus) {
268
287
  *
269
288
  * On iOS, this will track the push open event and handle the notification appropriately
270
289
  * based on whether the app was in the foreground, background, or not running.
271
- * On Android, this is currently a no-op (TODO: implement FCM integration).
290
+ * On Android, registers the FCM token when provided by the host app.
272
291
  *
273
292
  * @param userInfo - The notification payload from the push notification
274
293
  * @param applicationState - The app state when the notification was opened ('active', 'inactive', 'background')
@@ -295,7 +314,7 @@ function handlePushOpened(userInfo, applicationState, authorizationStatus) {
295
314
  * Call this from your notification handler when a notification is received while the app is active.
296
315
  *
297
316
  * On iOS, this allows the Attentive SDK to track the notification event.
298
- * On Android, this is currently a no-op (TODO: implement FCM integration).
317
+ * On Android, registers the FCM token when provided by the host app.
299
318
  *
300
319
  * @param userInfo - The notification payload from the push notification
301
320
  *
@@ -323,7 +342,7 @@ function handleForegroundNotification(userInfo) {
323
342
  * ```
324
343
  *
325
344
  * On iOS, this properly tracks foreground push notifications.
326
- * On Android, this is currently a no-op (TODO: implement FCM integration).
345
+ * On Android, registers the FCM token when provided by the host app.
327
346
  *
328
347
  * @param userInfo - The notification payload from the push notification
329
348
  * @param authorizationStatus - Current push authorization status
@@ -356,7 +375,7 @@ function handleForegroundPush(userInfo, authorizationStatus) {
356
375
  * ```
357
376
  *
358
377
  * On iOS, this properly tracks push notification opens.
359
- * On Android, this is currently a no-op (TODO: implement FCM integration).
378
+ * On Android, registers the FCM token when provided by the host app.
360
379
  *
361
380
  * @param userInfo - The notification payload from the push notification
362
381
  * @param authorizationStatus - Current push authorization status
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","_NativeAttentiveReactNativeSdk","_interopRequireDefault","obj","__esModule","default","LINKING_ERROR","Platform","select","ios","AttentiveReactNativeSdk","NativeAttentiveReactNativeSdkModule","Proxy","get","Error","initialize","configuration","attentiveDomain","mode","skipFatigueOnCreatives","enableDebugger","triggerCreative","creativeId","destroyCreative","updateDomain","domain","identify","identifiers","phone","email","klaviyoId","shopifyId","clientUserId","customIdentifiers","clearUser","recordAddToCartEvent","attrs","items","deeplink","recordProductViewEvent","recordPurchaseEvent","orderId","cartId","cartCoupon","recordCustomEvent","type","properties","invokeAttentiveDebugHelper","exportDebugLogs","registerForPushNotifications","registerDeviceToken","token","authorizationStatus","registerDeviceTokenWithCallback","callback","handleRegularOpen","console","log","handlePushOpened","userInfo","applicationState","handleForegroundNotification","handleForegroundPush","handlePushOpen"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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AACwC,mBAAmB,CAACC,KAAK,EAAEC,mBAAmB,CAAC;AACzE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,+BAA+BA,CACtCF,KAAa,EACbC,mBAA4C,EAC5CE,QAKS,EACH;EACN5C,uBAAuB,CAAC2C,+BAA+B,CACrDF,KAAK,EACLC,mBAAmB,EACnBE,QACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,iBAAiBA,CAACH,mBAA4C,EAAQ;EAC7EI,OAAO,CAACC,GAAG,CAAC,6DAA6D,CAAC;EAC1ED,OAAO,CAACC,GAAG,CAAC,4BAA4BL,mBAAmB,EAAE,CAAC;EAC9DI,OAAO,CAACC,GAAG,CACT,mEACF,CAAC;EAED/C,uBAAuB,CAAC6C,iBAAiB,CAACH,mBAAmB,CAAC;EAE9DI,OAAO,CAACC,GAAG,CAAC,mDAAmD,CAAC;AAClE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,gBAAgBA,CACvBC,QAAkC,EAClCC,gBAAkC,EAClCR,mBAA4C,EACtC;EACN1C,uBAAuB,CAACgD,gBAAgB,CACtCC,QAAQ,EACRC,gBAAgB,EAChBR,mBACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASS,4BAA4BA,CACnCF,QAAkC,EAC5B;EACNjD,uBAAuB,CAACmD,4BAA4B,CAACF,QAAkB,CAAC;AAC1E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASG,oBAAoBA,CAC3BH,QAAkC,EAClCP,mBAA4C,EACtC;EACN1C,uBAAuB,CAACoD,oBAAoB,CAC1CH,QAAQ,EACRP,mBACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASW,cAAcA,CACrBJ,QAAkC,EAClCP,mBAA4C,EACtC;EACN1C,uBAAuB,CAACqD,cAAc,CACpCJ,QAAQ,EACRP,mBACF,CAAC;AACH","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","_NativeAttentiveReactNativeSdk","_interopRequireDefault","obj","__esModule","default","LINKING_ERROR","Platform","select","ios","AttentiveReactNativeSdk","NativeAttentiveReactNativeSdkModule","Proxy","get","Error","initialize","configuration","attentiveDomain","mode","skipFatigueOnCreatives","enableDebugger","triggerCreative","creativeId","destroyCreative","updateDomain","domain","identify","identifiers","phone","email","klaviyoId","shopifyId","clientUserId","customIdentifiers","clearUser","recordAddToCartEvent","attrs","items","deeplink","recordProductViewEvent","recordPurchaseEvent","orderId","cartId","cartCoupon","recordCustomEvent","type","properties","invokeAttentiveDebugHelper","exportDebugLogs","registerForPushNotifications","getPushAuthorizationStatus","registerDeviceToken","token","authorizationStatus","registerDeviceTokenWithCallback","callback","handleRegularOpen","console","log","handlePushOpened","userInfo","applicationState","handleForegroundNotification","handleForegroundPush","handlePushOpen"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,mBAAmBA,CAC1BC,KAAa,EACbC,mBAA4C,EACtC;EACN3C,uBAAuB,CAACyC,mBAAmB,CAACC,KAAK,EAAEC,mBAAmB,CAAC;AACzE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,+BAA+BA,CACtCF,KAAa,EACbC,mBAA4C,EAC5CE,QAKS,EACH;EACN7C,uBAAuB,CAAC4C,+BAA+B,CACrDF,KAAK,EACLC,mBAAmB,EACnBE,QAAQ,CACT;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,iBAAiBA,CAACH,mBAA4C,EAAQ;EAC7EI,OAAO,CAACC,GAAG,CAAC,6DAA6D,CAAC;EAC1ED,OAAO,CAACC,GAAG,CAAE,4BAA2BL,mBAAoB,EAAC,CAAC;EAC9DI,OAAO,CAACC,GAAG,CACT,mEAAmE,CACpE;EAEDhD,uBAAuB,CAAC8C,iBAAiB,CAACH,mBAAmB,CAAC;EAE9DI,OAAO,CAACC,GAAG,CAAC,mDAAmD,CAAC;AAClE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,gBAAgBA,CACvBC,QAAkC,EAClCC,gBAAkC,EAClCR,mBAA4C,EACtC;EACN3C,uBAAuB,CAACiD,gBAAgB,CACtCC,QAAQ,EACRC,gBAAgB,EAChBR,mBAAmB,CACpB;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASS,4BAA4BA,CACnCF,QAAkC,EAC5B;EACNlD,uBAAuB,CAACoD,4BAA4B,CAACF,QAAQ,CAAW;AAC1E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASG,oBAAoBA,CAC3BH,QAAkC,EAClCP,mBAA4C,EACtC;EACN3C,uBAAuB,CAACqD,oBAAoB,CAC1CH,QAAQ,EACRP,mBAAmB,CACpB;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASW,cAAcA,CACrBJ,QAAkC,EAClCP,mBAA4C,EACtC;EACN3C,uBAAuB,CAACsD,cAAc,CACpCJ,QAAQ,EACRP,mBAAmB,CACpB;AACH"}
@@ -1 +1 @@
1
- {"version":3,"names":["TurboModuleRegistry","NativeModules","isTurboModuleEnabled","global","__turboModuleProxy","AttentiveReactNativeSdkModule","get","AttentiveReactNativeSdk"],"sourceRoot":"../../src","sources":["NativeAttentiveReactNativeSdk.ts"],"mappings":"AACA,SAASA,mBAAmB,EAAEC,aAAa,QAAQ,cAAc;AA8IjE;AACA;AACA,MAAMC,oBAAoB,GAAIC,MAAM,CAASC,kBAAkB,IAAI,IAAI;AAEvE,MAAMC,6BAA6B,GAAGH,oBAAoB,GACtDF,mBAAmB,CAACM,GAAG,CAAO,yBAAyB,CAAC,GACxDL,aAAa,CAACM,uBAAuB;AAEzC,eAAeF,6BAA6B","ignoreList":[]}
1
+ {"version":3,"names":["TurboModuleRegistry","NativeModules","isTurboModuleEnabled","global","__turboModuleProxy","AttentiveReactNativeSdkModule","get","AttentiveReactNativeSdk"],"sourceRoot":"../../src","sources":["NativeAttentiveReactNativeSdk.ts"],"mappings":"AACA,SAASA,mBAAmB,EAAEC,aAAa,QAAQ,cAAc;AAuJjE;AACA;AACA,MAAMC,oBAAoB,GAAIC,MAAM,CAASC,kBAAkB,IAAI,IAAI;AAEvE,MAAMC,6BAA6B,GAAGH,oBAAoB,GACtDF,mBAAmB,CAACM,GAAG,CAAO,yBAAyB,CAAC,GACxDL,aAAa,CAACM,uBAAuB;AAEzC,eAAeF,6BAA6B"}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sourceRoot":"../../src","sources":["eventTypes.tsx"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sourceRoot":"../../src","sources":["eventTypes.tsx"],"mappings":""}