@loyalytics/swan-react-native-sdk 2.5.1-beta.1 → 2.5.1-beta.3
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/android/src/main/kotlin/com/loyalytics/swan/templates/carousel/CarouselTemplate.kt +14 -3
- package/lib/commonjs/index.js +16 -7
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/version.js +1 -1
- package/lib/module/index.js +16 -7
- package/lib/module/index.js.map +1 -1
- package/lib/module/version.js +1 -1
- package/lib/typescript/commonjs/src/index.d.ts +1 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/version.d.ts +1 -1
- package/lib/typescript/module/src/index.d.ts +1 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -84,7 +84,8 @@ class CarouselTemplate : SwanNotificationTemplate {
|
|
|
84
84
|
notificationId: Int,
|
|
85
85
|
messageId: String,
|
|
86
86
|
itemIndex: Int,
|
|
87
|
-
itemRoute: String
|
|
87
|
+
itemRoute: String,
|
|
88
|
+
isContentIntent: Boolean = false
|
|
88
89
|
): PendingIntent {
|
|
89
90
|
val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)
|
|
90
91
|
?: Intent(Intent.ACTION_MAIN).apply {
|
|
@@ -107,8 +108,15 @@ class CarouselTemplate : SwanNotificationTemplate {
|
|
|
107
108
|
PendingIntent.FLAG_UPDATE_CURRENT
|
|
108
109
|
}
|
|
109
110
|
|
|
111
|
+
// Use different request codes for image click vs content intent to prevent collision
|
|
112
|
+
val requestCode = if (isContentIntent) {
|
|
113
|
+
"${notificationId}CONTENT_CLICK".hashCode()
|
|
114
|
+
} else {
|
|
115
|
+
"$notificationId${ACTION_CLICK}$itemIndex".hashCode()
|
|
116
|
+
}
|
|
117
|
+
|
|
110
118
|
return PendingIntent.getActivity(
|
|
111
|
-
context,
|
|
119
|
+
context, requestCode, launchIntent, flags
|
|
112
120
|
)
|
|
113
121
|
}
|
|
114
122
|
}
|
|
@@ -447,13 +455,16 @@ class CarouselTemplate : SwanNotificationTemplate {
|
|
|
447
455
|
extras: Bundle
|
|
448
456
|
): PendingIntent {
|
|
449
457
|
// For CLICK, use PendingIntent.getActivity() to avoid Android 12+ trampoline restriction
|
|
458
|
+
// This is always the content intent (notification body tap) — image clicks go through
|
|
459
|
+
// createClickActivityPendingIntent() directly from RemoteViews builders
|
|
450
460
|
if (action == ACTION_CLICK) {
|
|
451
461
|
return createClickActivityPendingIntent(
|
|
452
462
|
context,
|
|
453
463
|
notificationId,
|
|
454
464
|
extras.getString(EXTRA_MESSAGE_ID, ""),
|
|
455
465
|
extras.getInt(EXTRA_ITEM_INDEX, 0),
|
|
456
|
-
extras.getString(EXTRA_ITEM_ROUTE, "")
|
|
466
|
+
extras.getString(EXTRA_ITEM_ROUTE, ""),
|
|
467
|
+
isContentIntent = true
|
|
457
468
|
)
|
|
458
469
|
}
|
|
459
470
|
|
package/lib/commonjs/index.js
CHANGED
|
@@ -160,6 +160,7 @@ function _resetClickDedup() {
|
|
|
160
160
|
|
|
161
161
|
class SwanSDK {
|
|
162
162
|
listeners = {};
|
|
163
|
+
coldStartCheckDone = false;
|
|
163
164
|
SDK_VERSION = _version.SDK_VERSION;
|
|
164
165
|
isProduction = 'STAGE';
|
|
165
166
|
appId = '';
|
|
@@ -628,6 +629,16 @@ class SwanSDK {
|
|
|
628
629
|
}
|
|
629
630
|
this.listeners[event].push(callback);
|
|
630
631
|
|
|
632
|
+
// On first NOTIFICATION_OPENED listener, check for pending cold-start notifications.
|
|
633
|
+
// The native side holds click data until consumed — we just need to ask when ready.
|
|
634
|
+
if (event === SwanSDK.EVENTS.NOTIFICATION_OPENED && !this.coldStartCheckDone) {
|
|
635
|
+
this.coldStartCheckDone = true;
|
|
636
|
+
// Defer to next microtask so the listener is fully registered before events emit
|
|
637
|
+
Promise.resolve().then(() => {
|
|
638
|
+
this.checkPendingCarouselClick();
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
|
|
631
642
|
// Return a subscription object for easy cleanup
|
|
632
643
|
return {
|
|
633
644
|
remove: () => {
|
|
@@ -958,9 +969,6 @@ class SwanSDK {
|
|
|
958
969
|
_Logger.default.log('[SwanSDK] Tracking initial app launch event...');
|
|
959
970
|
this.appLaunched();
|
|
960
971
|
|
|
961
|
-
// Check for pending carousel click (covers killed/quit → fresh launch)
|
|
962
|
-
this.checkPendingCarouselClick();
|
|
963
|
-
|
|
964
972
|
// AppState listener setup (always runs)
|
|
965
973
|
_Logger.default.log('[SwanSDK] Setting up AppState listener...');
|
|
966
974
|
this.setupAppStateListener();
|
|
@@ -1826,11 +1834,12 @@ class SwanSDK {
|
|
|
1826
1834
|
// Read click data from App Group (written by Content Extension)
|
|
1827
1835
|
clickData = await _SharedCredentialsManager.SharedCredentialsManager.readTemplateClickData();
|
|
1828
1836
|
|
|
1829
|
-
//
|
|
1830
|
-
// The Content Extension may still be writing when the app foregrounds.
|
|
1837
|
+
// Exponential backoff: Content Extension may still be writing to App Group
|
|
1831
1838
|
if (!clickData) {
|
|
1832
|
-
|
|
1833
|
-
|
|
1839
|
+
for (let attempt = 0; attempt < 4 && !clickData; attempt++) {
|
|
1840
|
+
await new Promise(r => setTimeout(r, 100 * Math.pow(2, attempt)));
|
|
1841
|
+
clickData = await _SharedCredentialsManager.SharedCredentialsManager.readTemplateClickData();
|
|
1842
|
+
}
|
|
1834
1843
|
}
|
|
1835
1844
|
}
|
|
1836
1845
|
if (!clickData) return;
|