@capillarytech/react-native-hydra-lib 1.7.0-beta.1 → 1.7.0-beta.10
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/build.gradle +12 -13
- package/android/src/main/java/com/hydralib/delegates/NonHydraNotificationActivity.kt +22 -10
- package/android/src/main/java/com/hydralib/eventemitter/HydraEventEmitter.kt +34 -4
- package/android/src/main/java/com/hydralib/eventemitter/HydraEventType.kt +5 -1
- package/android/src/main/java/com/hydralib/gamification/GamificationBannerViewManager.kt +34 -3
- package/android/src/main/java/com/hydralib/gamification/GamificationEmbedViewManager.kt +25 -4
- package/android/src/main/java/com/hydralib/gamification/GamificationLoyaltyViewManager.kt +41 -6
- package/android/src/main/java/com/hydralib/hydrasdk/HydraCore.kt +109 -6
- package/android/src/main/java/com/hydralib/hydrasdk/HydraInAppMessages.kt +68 -41
- package/android/src/main/java/com/hydralib/hydrasdk/HydraInbox.kt +2 -2
- package/android/src/main/java/com/hydralib/hydrasdk/HydraPushNotification.kt +29 -1
- package/android/src/newarch/HydraLibModule.kt +16 -0
- package/android/src/oldarch/HydraLibModule.kt +20 -0
- package/ios/Delegates/HydraApplicationDelegate.swift +8 -0
- package/ios/EventEmitter/HydraEventType.swift +2 -0
- package/ios/GamificationViews/GamificationBannerViewComponentView.mm +43 -6
- package/ios/GamificationViews/GamificationEmbedViewComponentView.mm +37 -6
- package/ios/GamificationViews/GamificationLoyaltyViewComponentView.mm +45 -5
- package/ios/HydraLib.h +3 -4
- package/ios/HydraLib.mm +16 -0
- package/ios/HydraSDK/HydraInAppMessages.swift +35 -8
- package/ios/HydraSDK/HydraInbox.swift +36 -9
- package/ios/HydraSDK/HydraInboxUI.swift +5 -1
- package/ios/HydraSDK/HydraPushNotification.swift +2 -2
- package/ios/HydraSDK/HydraSDKCore.swift +185 -82
- package/ios/Utils/HydraExtensions.swift +1 -1
- package/lib/commonjs/GamificationBannerViewNativeComponent.ts +10 -0
- package/lib/commonjs/GamificationEmbedViewNativeComponent.ts +10 -0
- package/lib/commonjs/GamificationLoyaltyViewNativeComponent.ts +10 -0
- package/lib/commonjs/NativeHydraLib.ts +85 -0
- package/lib/commonjs/components/GamificationBannerView.js +1 -1
- package/lib/commonjs/components/GamificationEmbedView.js +1 -1
- package/lib/commonjs/components/GamificationLoyaltyView.js +1 -1
- package/lib/commonjs/hydra-apis/Hydra.js +14 -1
- package/lib/commonjs/hydra-apis/Hydra.js.map +1 -1
- package/lib/commonjs/hydra-apis/HydraCore.js +1 -1
- package/lib/commonjs/hydra-apis/HydraInAppMessaging.js +1 -1
- package/lib/commonjs/hydra-apis/HydraInbox.js +1 -1
- package/lib/commonjs/hydra-apis/HydraInboxUI.js +1 -1
- package/lib/commonjs/hydra-apis/HydraNativeEventEmitter.js +11 -1
- package/lib/commonjs/hydra-apis/HydraNativeEventEmitter.js.map +1 -1
- package/lib/commonjs/hydra-apis/HydraPushNotification.js +1 -1
- package/lib/commonjs/index.js +7 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/models/HydraNativeEvent.js +2 -0
- package/lib/commonjs/models/HydraNativeEvent.js.map +1 -1
- package/lib/commonjs/models/ThemeMode.js +14 -0
- package/lib/commonjs/models/ThemeMode.js.map +1 -0
- package/lib/module/GamificationBannerViewNativeComponent.ts +10 -0
- package/lib/module/GamificationEmbedViewNativeComponent.ts +10 -0
- package/lib/module/GamificationLoyaltyViewNativeComponent.ts +10 -0
- package/lib/module/NativeHydraLib.ts +85 -0
- package/lib/module/components/GamificationBannerView.js +1 -1
- package/lib/module/components/GamificationEmbedView.js +1 -1
- package/lib/module/components/GamificationLoyaltyView.js +1 -1
- package/lib/module/hydra-apis/Hydra.js +14 -1
- package/lib/module/hydra-apis/Hydra.js.map +1 -1
- package/lib/module/hydra-apis/HydraCore.js +1 -1
- package/lib/module/hydra-apis/HydraInAppMessaging.js +1 -1
- package/lib/module/hydra-apis/HydraInbox.js +1 -1
- package/lib/module/hydra-apis/HydraInboxUI.js +1 -1
- package/lib/module/hydra-apis/HydraNativeEventEmitter.js +11 -1
- package/lib/module/hydra-apis/HydraNativeEventEmitter.js.map +1 -1
- package/lib/module/hydra-apis/HydraPushNotification.js +1 -1
- package/lib/module/index.js +2 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/models/HydraNativeEvent.js +2 -0
- package/lib/module/models/HydraNativeEvent.js.map +1 -1
- package/lib/module/models/ThemeMode.js +10 -0
- package/lib/module/models/ThemeMode.js.map +1 -0
- package/lib/typescript/commonjs/src/NativeHydraLib.d.ts +4 -0
- package/lib/typescript/commonjs/src/NativeHydraLib.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/hydra-apis/Hydra.d.ts +5 -0
- package/lib/typescript/commonjs/src/hydra-apis/Hydra.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/hydra-apis/HydraNativeEventEmitter.d.ts +2 -0
- package/lib/typescript/commonjs/src/hydra-apis/HydraNativeEventEmitter.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.d.ts +2 -1
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/models/HydraNativeEvent.d.ts +3 -1
- package/lib/typescript/commonjs/src/models/HydraNativeEvent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/models/ThemeMode.d.ts +7 -0
- package/lib/typescript/commonjs/src/models/ThemeMode.d.ts.map +1 -0
- package/lib/typescript/module/src/NativeHydraLib.d.ts +4 -0
- package/lib/typescript/module/src/NativeHydraLib.d.ts.map +1 -1
- package/lib/typescript/module/src/hydra-apis/Hydra.d.ts +5 -0
- package/lib/typescript/module/src/hydra-apis/Hydra.d.ts.map +1 -1
- package/lib/typescript/module/src/hydra-apis/HydraNativeEventEmitter.d.ts +2 -0
- package/lib/typescript/module/src/hydra-apis/HydraNativeEventEmitter.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts +2 -1
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/models/HydraNativeEvent.d.ts +3 -1
- package/lib/typescript/module/src/models/HydraNativeEvent.d.ts.map +1 -1
- package/lib/typescript/module/src/models/ThemeMode.d.ts +7 -0
- package/lib/typescript/module/src/models/ThemeMode.d.ts.map +1 -0
- package/package.json +13 -4
- package/react-native-hydra-lib.podspec +9 -1
- package/react-native.config.js +9 -23
- package/sbom.spdx.json +4 -4
- package/scripts/HydraPods.rb +1 -1
- package/scripts/preserve-codegen-specs.js +117 -0
- package/src/NativeHydraLib.ts +4 -0
- package/src/hydra-apis/Hydra.ts +18 -0
- package/src/hydra-apis/HydraNativeEventEmitter.ts +20 -0
- package/src/index.tsx +2 -0
- package/src/models/HydraNativeEvent.ts +2 -0
- package/src/models/ThemeMode.ts +6 -0
- package/android/generated/java/com/hydralib/NativeHydraLibSpec.java +0 -185
- package/android/generated/jni/CMakeLists.txt +0 -36
- package/android/generated/jni/RNHydraLibSpec-generated.cpp +0 -248
- package/android/generated/jni/RNHydraLibSpec.h +0 -31
- package/android/generated/jni/react/renderer/components/RNHydraLibSpec/ComponentDescriptors.cpp +0 -24
- package/android/generated/jni/react/renderer/components/RNHydraLibSpec/ComponentDescriptors.h +0 -26
- package/android/generated/jni/react/renderer/components/RNHydraLibSpec/EventEmitters.cpp +0 -18
- package/android/generated/jni/react/renderer/components/RNHydraLibSpec/EventEmitters.h +0 -37
- package/android/generated/jni/react/renderer/components/RNHydraLibSpec/Props.cpp +0 -39
- package/android/generated/jni/react/renderer/components/RNHydraLibSpec/Props.h +0 -47
- package/android/generated/jni/react/renderer/components/RNHydraLibSpec/RNHydraLibSpecJSI-generated.cpp +0 -283
- package/android/generated/jni/react/renderer/components/RNHydraLibSpec/RNHydraLibSpecJSI.h +0 -395
- package/android/generated/jni/react/renderer/components/RNHydraLibSpec/ShadowNodes.cpp +0 -19
- package/android/generated/jni/react/renderer/components/RNHydraLibSpec/ShadowNodes.h +0 -54
- package/android/generated/jni/react/renderer/components/RNHydraLibSpec/States.cpp +0 -16
- package/android/generated/jni/react/renderer/components/RNHydraLibSpec/States.h +0 -53
- package/ios/generated/RNHydraLibSpec/ComponentDescriptors.cpp +0 -24
- package/ios/generated/RNHydraLibSpec/ComponentDescriptors.h +0 -26
- package/ios/generated/RNHydraLibSpec/EventEmitters.cpp +0 -18
- package/ios/generated/RNHydraLibSpec/EventEmitters.h +0 -37
- package/ios/generated/RNHydraLibSpec/Props.cpp +0 -39
- package/ios/generated/RNHydraLibSpec/Props.h +0 -47
- package/ios/generated/RNHydraLibSpec/RCTComponentViewHelpers.h +0 -28
- package/ios/generated/RNHydraLibSpec/RNHydraLibSpec-generated.mm +0 -291
- package/ios/generated/RNHydraLibSpec/RNHydraLibSpec.h +0 -167
- package/ios/generated/RNHydraLibSpec/ShadowNodes.cpp +0 -19
- package/ios/generated/RNHydraLibSpec/ShadowNodes.h +0 -54
- package/ios/generated/RNHydraLibSpec/States.cpp +0 -16
- package/ios/generated/RNHydraLibSpec/States.h +0 -53
- package/ios/generated/RNHydraLibSpecJSI-generated.cpp +0 -283
- package/ios/generated/RNHydraLibSpecJSI.h +0 -395
- package/lib/commonjs/GamificationBannerViewNativeComponent.js +0 -10
- package/lib/commonjs/GamificationBannerViewNativeComponent.js.map +0 -1
- package/lib/commonjs/GamificationEmbedViewNativeComponent.js +0 -10
- package/lib/commonjs/GamificationEmbedViewNativeComponent.js.map +0 -1
- package/lib/commonjs/GamificationLoyaltyViewNativeComponent.js +0 -10
- package/lib/commonjs/GamificationLoyaltyViewNativeComponent.js.map +0 -1
- package/lib/commonjs/NativeHydraLib.js +0 -11
- package/lib/commonjs/NativeHydraLib.js.map +0 -1
- package/lib/module/GamificationBannerViewNativeComponent.js +0 -5
- package/lib/module/GamificationBannerViewNativeComponent.js.map +0 -1
- package/lib/module/GamificationEmbedViewNativeComponent.js +0 -5
- package/lib/module/GamificationEmbedViewNativeComponent.js.map +0 -1
- package/lib/module/GamificationLoyaltyViewNativeComponent.js +0 -5
- package/lib/module/GamificationLoyaltyViewNativeComponent.js.map +0 -1
- package/lib/module/NativeHydraLib.js +0 -7
- package/lib/module/NativeHydraLib.js.map +0 -1
|
@@ -66,33 +66,46 @@ object HydraInAppMessages {
|
|
|
66
66
|
message: ReadableMap?,
|
|
67
67
|
promise: Promise?
|
|
68
68
|
) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
69
|
+
if (message == null) {
|
|
70
|
+
Logger.e("HydraInAppMessages.reportMessageClicked", "message is null, cannot report click")
|
|
71
|
+
promise?.reject("Error", "message is null")
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
val messageMap = message.toMap()
|
|
75
|
+
val nativeJsonPayload = messageMap["nativeJsonPayload"]
|
|
76
|
+
if (nativeJsonPayload == null) {
|
|
77
|
+
Logger.e("HydraInAppMessages.reportMessageClicked", "nativeJsonPayload missing in message, cannot report click")
|
|
78
|
+
promise?.reject("Error", "nativeJsonPayload missing in message")
|
|
79
|
+
return
|
|
79
80
|
}
|
|
81
|
+
val jsonString = Gson().toJson(nativeJsonPayload)
|
|
82
|
+
val payloadFromJson = Gson().fromJson(jsonString, CampaignPayload::class.java)
|
|
83
|
+
HydraInAppUIHelper.getInstance()
|
|
84
|
+
.reportInAppMessageIsClicked(HydraCore.appContext!!, payloadFromJson)
|
|
85
|
+
promise?.resolve(true)
|
|
80
86
|
}
|
|
81
87
|
|
|
82
88
|
fun reportMessageDismissed(
|
|
83
89
|
message: ReadableMap?,
|
|
84
90
|
promise: Promise?
|
|
85
91
|
) {
|
|
86
|
-
message
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
if (message == null) {
|
|
93
|
+
Logger.e("HydraInAppMessages.reportMessageDismissed", "message is null, cannot report dismissal")
|
|
94
|
+
promise?.reject("Error", "message is null")
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
val messageMap = message.toMap()
|
|
98
|
+
val nativeJsonPayload = messageMap["nativeJsonPayload"]
|
|
99
|
+
if (nativeJsonPayload == null) {
|
|
100
|
+
Logger.e("HydraInAppMessages.reportMessageDismissed", "nativeJsonPayload missing in message, cannot report dismissal")
|
|
101
|
+
promise?.reject("Error", "nativeJsonPayload missing in message")
|
|
102
|
+
return
|
|
95
103
|
}
|
|
104
|
+
val jsonString = Gson().toJson(nativeJsonPayload)
|
|
105
|
+
val payloadFromJson = Gson().fromJson(jsonString, CampaignPayload::class.java)
|
|
106
|
+
HydraInAppUIHelper.getInstance()
|
|
107
|
+
.reportInAppMessageDismissed(HydraCore.appContext!!, payloadFromJson)
|
|
108
|
+
promise?.resolve(true)
|
|
96
109
|
}
|
|
97
110
|
|
|
98
111
|
fun reportMessageRating(
|
|
@@ -100,16 +113,23 @@ object HydraInAppMessages {
|
|
|
100
113
|
rating: Double,
|
|
101
114
|
promise: Promise?
|
|
102
115
|
) {
|
|
103
|
-
message
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
116
|
+
if (message == null) {
|
|
117
|
+
Logger.e("HydraInAppMessages.reportMessageRating", "message is null, cannot report rating")
|
|
118
|
+
promise?.reject("Error", "message is null")
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
val messageMap = message.toMap()
|
|
122
|
+
val nativeJsonPayload = messageMap["nativeJsonPayload"]
|
|
123
|
+
if (nativeJsonPayload == null) {
|
|
124
|
+
Logger.e("HydraInAppMessages.reportMessageRating", "nativeJsonPayload missing in message, cannot report rating")
|
|
125
|
+
promise?.reject("Error", "nativeJsonPayload missing in message")
|
|
126
|
+
return
|
|
112
127
|
}
|
|
128
|
+
val jsonString = Gson().toJson(nativeJsonPayload)
|
|
129
|
+
val payloadFromJson = Gson().fromJson(jsonString, CampaignPayload::class.java)
|
|
130
|
+
HydraInAppUIHelper.getInstance()
|
|
131
|
+
.reportInAppMessageRating(HydraCore.appContext!!, payloadFromJson, rating.toInt())
|
|
132
|
+
promise?.resolve(true)
|
|
113
133
|
}
|
|
114
134
|
|
|
115
135
|
fun reportMessageFeedback(
|
|
@@ -118,19 +138,26 @@ object HydraInAppMessages {
|
|
|
118
138
|
feedbackOptions: ReadableArray?,
|
|
119
139
|
promise: Promise?
|
|
120
140
|
) {
|
|
121
|
-
message
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
promise?.resolve(true)
|
|
133
|
-
}
|
|
141
|
+
if (message == null) {
|
|
142
|
+
Logger.e("HydraInAppMessages.reportMessageFeedback", "message is null, cannot report feedback")
|
|
143
|
+
promise?.reject("Error", "message is null")
|
|
144
|
+
return
|
|
145
|
+
}
|
|
146
|
+
val messageMap = message.toMap()
|
|
147
|
+
val nativeJsonPayload = messageMap["nativeJsonPayload"]
|
|
148
|
+
if (nativeJsonPayload == null) {
|
|
149
|
+
Logger.e("HydraInAppMessages.reportMessageFeedback", "nativeJsonPayload missing in message, cannot report feedback")
|
|
150
|
+
promise?.reject("Error", "nativeJsonPayload missing in message")
|
|
151
|
+
return
|
|
134
152
|
}
|
|
153
|
+
val jsonString = Gson().toJson(nativeJsonPayload)
|
|
154
|
+
val payloadFromJson = Gson().fromJson(jsonString, CampaignPayload::class.java)
|
|
155
|
+
val feedbackOptionsList = feedbackOptions?.toList()?.mapNotNull { option -> option as? Int } ?: listOf()
|
|
156
|
+
HydraInAppUIHelper.getInstance().reportInAppMessageFeedback(
|
|
157
|
+
HydraCore.appContext!!,
|
|
158
|
+
payloadFromJson,
|
|
159
|
+
feedbackOptionsList
|
|
160
|
+
)
|
|
161
|
+
promise?.resolve(true)
|
|
135
162
|
}
|
|
136
163
|
}
|
|
@@ -43,7 +43,7 @@ object HydraInbox {
|
|
|
43
43
|
Logger.d("HydraInbox.markInboxMessageAsRead", "Inbox message marked read successfully")
|
|
44
44
|
return
|
|
45
45
|
}
|
|
46
|
-
Logger.
|
|
46
|
+
Logger.e("HydraInbox.markInboxMessageAsRead", "Invalid inbox message details, input message = $inboxMessage")
|
|
47
47
|
promise?.resolve(false)
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -56,7 +56,7 @@ object HydraInbox {
|
|
|
56
56
|
Logger.d("HydraInbox.deleteInboxMessage", "Inbox message deleted successfully")
|
|
57
57
|
return
|
|
58
58
|
}
|
|
59
|
-
Logger.
|
|
59
|
+
Logger.e("HydraInbox.deleteInboxMessage", "Invalid inbox message details, input message = $inboxMessage")
|
|
60
60
|
promise?.resolve(false)
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -6,10 +6,12 @@ import android.app.NotificationManager
|
|
|
6
6
|
import android.app.PendingIntent
|
|
7
7
|
import android.content.Context
|
|
8
8
|
import android.content.Intent
|
|
9
|
+
import android.content.pm.PackageManager
|
|
9
10
|
import android.net.Uri
|
|
10
11
|
import android.os.Build
|
|
11
12
|
import com.hydralib.delegates.NonHydraNotificationActivity
|
|
12
13
|
import androidx.core.app.NotificationCompat
|
|
14
|
+
import androidx.core.content.ContextCompat
|
|
13
15
|
import com.capillary.hydra.android.sdk.utils.Logger
|
|
14
16
|
import com.capillary.hydra.firebase.HydraFirebaseAPI
|
|
15
17
|
import com.capillary.hydra.firebase.listener.NonHydraPushListener
|
|
@@ -155,6 +157,32 @@ object HydraPushNotification {
|
|
|
155
157
|
return
|
|
156
158
|
}
|
|
157
159
|
|
|
160
|
+
// Already granted: answer from the OS state instead of asking again. requestPushPermission
|
|
161
|
+
// starts PermissionActivity unconditionally, and that activity lands in the host app's task
|
|
162
|
+
// even when it has nothing to show and finishes immediately. During a notification-click
|
|
163
|
+
// cold start that pulls the app back on top of the browser we just handed an EXTERNAL CTA
|
|
164
|
+
// to, so the external link looks like it did nothing.
|
|
165
|
+
//
|
|
166
|
+
// Placed before the listener registration on purpose: the promise below is resolved from
|
|
167
|
+
// NotificationPermissionListener, which only fires in response to requestPushPermission, so
|
|
168
|
+
// returning after registering would leak a listener that never fires and hang the promise.
|
|
169
|
+
// Spelled out rather than Manifest.permission.POST_NOTIFICATIONS: that constant is API 33,
|
|
170
|
+
// and this library's compileSdkVersion falls back to 31 (gradle.properties) for any host app
|
|
171
|
+
// whose rootProject.ext does not override it, so the symbol would not resolve there. The
|
|
172
|
+
// string is the platform's own value and is stable.
|
|
173
|
+
val context = HydraCore.appContext
|
|
174
|
+
if (context != null &&
|
|
175
|
+
ContextCompat.checkSelfPermission(context, "android.permission.POST_NOTIFICATIONS")
|
|
176
|
+
== PackageManager.PERMISSION_GRANTED
|
|
177
|
+
) {
|
|
178
|
+
Logger.d(
|
|
179
|
+
"HydraPushNotification.requestPermission",
|
|
180
|
+
"POST_NOTIFICATIONS already granted, resolving without starting PermissionActivity"
|
|
181
|
+
)
|
|
182
|
+
promise?.resolve(true)
|
|
183
|
+
return
|
|
184
|
+
}
|
|
185
|
+
|
|
158
186
|
var listener: NotificationPermissionListener? = null
|
|
159
187
|
listener = NotificationPermissionListener { isGranted ->
|
|
160
188
|
Logger.d(
|
|
@@ -190,7 +218,7 @@ object HydraPushNotification {
|
|
|
190
218
|
|
|
191
219
|
fun getFCMToken(promise: Promise?) {
|
|
192
220
|
if (fcmToken == null) {
|
|
193
|
-
Logger.
|
|
221
|
+
Logger.e("HydraPushNotification.getFCMToken", "Token is not available, try later")
|
|
194
222
|
promise?.reject("TokenNotSet", "Token is not available, try later")
|
|
195
223
|
return
|
|
196
224
|
}
|
|
@@ -121,6 +121,22 @@ class HydraLibModule(reactContext: ReactApplicationContext) :
|
|
|
121
121
|
HydraCore.setCapToken(token, promise)
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
override fun setGamificationSuppressed(suppressed: Boolean, promise: Promise?) {
|
|
125
|
+
HydraCore.setGamificationSuppressed(suppressed, promise)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
override fun isGamificationSuppressed(promise: Promise?) {
|
|
129
|
+
HydraCore.isGamificationSuppressed(promise)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
override fun setThemeMode(mode: String, promise: Promise?) {
|
|
133
|
+
HydraCore.setThemeMode(mode, promise)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
override fun getThemeMode(promise: Promise?) {
|
|
137
|
+
HydraCore.getThemeMode(promise)
|
|
138
|
+
}
|
|
139
|
+
|
|
124
140
|
override fun openExternalUrl(url: String, promise: Promise?) {
|
|
125
141
|
HydraPushNotification.openExternalUrl(url, promise)
|
|
126
142
|
}
|
|
@@ -141,6 +141,26 @@ class HydraLibModule internal constructor(context: ReactApplicationContext) :
|
|
|
141
141
|
HydraCore.setCapToken(token, promise)
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
@ReactMethod(isBlockingSynchronousMethod = false)
|
|
145
|
+
fun setGamificationSuppressed(suppressed: Boolean, promise: Promise?) {
|
|
146
|
+
HydraCore.setGamificationSuppressed(suppressed, promise)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
@ReactMethod(isBlockingSynchronousMethod = false)
|
|
150
|
+
fun isGamificationSuppressed(promise: Promise?) {
|
|
151
|
+
HydraCore.isGamificationSuppressed(promise)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@ReactMethod(isBlockingSynchronousMethod = false)
|
|
155
|
+
fun setThemeMode(mode: String, promise: Promise?) {
|
|
156
|
+
HydraCore.setThemeMode(mode, promise)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@ReactMethod(isBlockingSynchronousMethod = false)
|
|
160
|
+
fun getThemeMode(promise: Promise?) {
|
|
161
|
+
HydraCore.getThemeMode(promise)
|
|
162
|
+
}
|
|
163
|
+
|
|
144
164
|
@ReactMethod(isBlockingSynchronousMethod = false)
|
|
145
165
|
fun openExternalUrl(url: String, promise: Promise?) {
|
|
146
166
|
HydraPushNotification.openExternalUrl(url, promise)
|
|
@@ -32,6 +32,14 @@ import HydraCore
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
fileprivate func setupNavigationController(_ application: UIApplication) {
|
|
35
|
+
// Wrapping the app's rootViewController in a UINavigationController is only
|
|
36
|
+
// needed to push the Hydra NotificationCenter (see HydraInboxUI). Apps that
|
|
37
|
+
// don't enable InboxUI keep their own root view controller untouched.
|
|
38
|
+
guard HydraSDKCore.isInboxUIEnabled() else {
|
|
39
|
+
Logger.info("HydraApplicationDelegate: setupNavigationController: enable_inbox_ui is false, skipping navigation controller setup")
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
35
43
|
//Create and set NavigationController as rootController, will be required to show NotificationCenter
|
|
36
44
|
let storyboard = UIStoryboard(name: Bundle.main.infoDictionary?["UILaunchStoryboardName"] as? String ?? "LaunchScreen", bundle: nil)
|
|
37
45
|
let viewController = storyboard.instantiateInitialViewController()
|
|
@@ -25,4 +25,6 @@ enum HydraEventType : String, CaseIterable{
|
|
|
25
25
|
case ON_VISITOR_SESSION_READY = "onVisitorSessionReady"
|
|
26
26
|
case ON_USER_STATE_CHANGED = "onUserStateChanged"
|
|
27
27
|
case ON_GAMIFICATION_VIEW_HEIGHT_CHANGED = "onGamificationViewHeightChanged"
|
|
28
|
+
case ON_GAMIFICATION_ANALYTICS_EVENT = "gamificationAnalyticsEvent"
|
|
29
|
+
case ON_GAMIFICATION_DEEPLINK = "gamificationDeeplink"
|
|
28
30
|
}
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
#import "GamificationBannerViewComponentView.h"
|
|
4
4
|
|
|
5
|
-
#import
|
|
6
|
-
#import
|
|
7
|
-
#import
|
|
8
|
-
#import
|
|
5
|
+
#import <react/renderer/components/RNHydraLibSpec/ComponentDescriptors.h>
|
|
6
|
+
#import <react/renderer/components/RNHydraLibSpec/EventEmitters.h>
|
|
7
|
+
#import <react/renderer/components/RNHydraLibSpec/Props.h>
|
|
8
|
+
#import <react/renderer/components/RNHydraLibSpec/RCTComponentViewHelpers.h>
|
|
9
9
|
#import "RCTFabricComponentsPlugins.h"
|
|
10
10
|
#import <React/RCTBridgeModule.h>
|
|
11
11
|
#import <React/RCTComponentViewFactory.h>
|
|
@@ -53,12 +53,37 @@ using namespace facebook::react;
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
- (void)gamificationDataReloaded {
|
|
56
|
+
// Always dispatch to main: the SDK may post this from a background queue,
|
|
57
|
+
// and createGamificationBannerView is a UIKit/MainActor call.
|
|
56
58
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
59
|
+
// Fabric keeps unmounted component views alive in its recycle pool, and a pooled view is
|
|
60
|
+
// still a registered observer here. It must NOT rebuild: every successful
|
|
61
|
+
// createGamificationBannerView records an impression against the entry point's display count
|
|
62
|
+
// (conditions.showCount.count), so an off-screen pooled view would silently burn the cap and
|
|
63
|
+
// the banner would vanish for real users far sooner than configured. A mounted view always
|
|
64
|
+
// has a superview; a pooled one never does (Fabric asserts this when enqueueing).
|
|
65
|
+
if (self.superview == nil) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
57
68
|
self->_needsBannerView = YES;
|
|
58
69
|
[self attachBannerViewIfPossible];
|
|
59
70
|
});
|
|
60
71
|
}
|
|
61
72
|
|
|
73
|
+
// Fabric recycles component views. RCTViewComponentView's own prepareForRecycle resets the event
|
|
74
|
+
// emitter and react subviews but NOT `contentView`, and setContentView: re-adds it to the container
|
|
75
|
+
// view — so without this a recycled instance keeps the previous mount's banner view (a live
|
|
76
|
+
// WKWebView showing an already-rendered campaign). updateProps would then see `contentView != nil`
|
|
77
|
+
// with an unchanged bannerId and never ask the SDK again, bypassing the frequency-cap/visibility
|
|
78
|
+
// check entirely and displaying stale content the SDK has decided to hide.
|
|
79
|
+
- (void)prepareForRecycle {
|
|
80
|
+
self.contentView = nil;
|
|
81
|
+
_bannerId = nil;
|
|
82
|
+
_needsBannerView = NO;
|
|
83
|
+
_retryPending = NO;
|
|
84
|
+
[super prepareForRecycle];
|
|
85
|
+
}
|
|
86
|
+
|
|
62
87
|
- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps {
|
|
63
88
|
const auto &newProps = *std::static_pointer_cast<const GamificationBannerViewProps>(props);
|
|
64
89
|
|
|
@@ -87,7 +112,11 @@ using namespace facebook::react;
|
|
|
87
112
|
if (!_needsBannerView || _bannerId.length == 0) {
|
|
88
113
|
return;
|
|
89
114
|
}
|
|
90
|
-
|
|
115
|
+
// Only WIDTH has to be laid out: the SDK ignores our bounds entirely (it measures the window)
|
|
116
|
+
// and seeds the real height back through onHeight. Requiring a non-empty rect would wedge a
|
|
117
|
+
// surface that has legitimately collapsed to height 0 — it could never rebuild when fresh data
|
|
118
|
+
// arrives, because its own bounds would stay empty forever.
|
|
119
|
+
if (self.bounds.size.width <= 0) {
|
|
91
120
|
return;
|
|
92
121
|
}
|
|
93
122
|
|
|
@@ -99,7 +128,15 @@ using namespace facebook::react;
|
|
|
99
128
|
_needsBannerView = NO;
|
|
100
129
|
_retryPending = NO;
|
|
101
130
|
} else {
|
|
102
|
-
NSLog(@"[GamificationBanner] SDK returned nil — scheduling long fallback");
|
|
131
|
+
NSLog(@"[GamificationBanner] SDK returned nil — collapsing and scheduling long fallback");
|
|
132
|
+
// nil means "do not render this banner now" — hidden, frequency-capped, or no resolved URL.
|
|
133
|
+
// Drop anything already attached so a previously loaded webview can't outlive that decision.
|
|
134
|
+
// The SDK has already pushed height 0 through onHeight, so the JS side collapses with us.
|
|
135
|
+
self.contentView = nil;
|
|
136
|
+
// Don't retry aggressively: the SDK may have entry points loaded but
|
|
137
|
+
// reward/program data not yet ready. The HydraGamificationDataReloaded
|
|
138
|
+
// notification fires when everything is ready and will call us again.
|
|
139
|
+
// This 5-second fallback only fires if that notification is missed.
|
|
103
140
|
[self scheduleFallbackRetry];
|
|
104
141
|
}
|
|
105
142
|
}
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
#import "GamificationEmbedViewComponentView.h"
|
|
4
4
|
|
|
5
|
-
#import
|
|
6
|
-
#import
|
|
7
|
-
#import
|
|
8
|
-
#import
|
|
5
|
+
#import <react/renderer/components/RNHydraLibSpec/ComponentDescriptors.h>
|
|
6
|
+
#import <react/renderer/components/RNHydraLibSpec/EventEmitters.h>
|
|
7
|
+
#import <react/renderer/components/RNHydraLibSpec/Props.h>
|
|
8
|
+
#import <react/renderer/components/RNHydraLibSpec/RCTComponentViewHelpers.h>
|
|
9
9
|
#import "RCTFabricComponentsPlugins.h"
|
|
10
10
|
#import <React/RCTBridgeModule.h>
|
|
11
11
|
#import <React/RCTComponentViewFactory.h>
|
|
@@ -56,11 +56,34 @@ using namespace facebook::react;
|
|
|
56
56
|
// Always dispatch to main: the SDK may post this from a background queue,
|
|
57
57
|
// and createGamificationEmbedView is a UIKit/MainActor call.
|
|
58
58
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
59
|
+
// Fabric keeps unmounted component views alive in its recycle pool, and a pooled view is
|
|
60
|
+
// still a registered observer here. It must NOT rebuild: every successful
|
|
61
|
+
// createGamificationEmbedView records an impression against the entry point's display count
|
|
62
|
+
// (conditions.showCount.count), so an off-screen pooled view would silently burn the cap and
|
|
63
|
+
// the embed would vanish for real users far sooner than configured. A mounted view always
|
|
64
|
+
// has a superview; a pooled one never does (Fabric asserts this when enqueueing).
|
|
65
|
+
if (self.superview == nil) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
59
68
|
self->_needsEmbedView = YES;
|
|
60
69
|
[self attachEmbedViewIfPossible];
|
|
61
70
|
});
|
|
62
71
|
}
|
|
63
72
|
|
|
73
|
+
// Fabric recycles component views. RCTViewComponentView's own prepareForRecycle resets the event
|
|
74
|
+
// emitter and react subviews but NOT `contentView`, and setContentView: re-adds it to the container
|
|
75
|
+
// view — so without this a recycled instance keeps the previous mount's EmbedView (a live WKWebView
|
|
76
|
+
// showing an already-rendered campaign). updateProps would then see `contentView != nil` with an
|
|
77
|
+
// unchanged embedId and never ask the SDK again, bypassing the frequency-cap/visibility check
|
|
78
|
+
// entirely and displaying stale content the SDK has decided to hide.
|
|
79
|
+
- (void)prepareForRecycle {
|
|
80
|
+
self.contentView = nil;
|
|
81
|
+
_embedId = nil;
|
|
82
|
+
_needsEmbedView = NO;
|
|
83
|
+
_retryPending = NO;
|
|
84
|
+
[super prepareForRecycle];
|
|
85
|
+
}
|
|
86
|
+
|
|
64
87
|
- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps {
|
|
65
88
|
const auto &newProps = *std::static_pointer_cast<const GamificationEmbedViewProps>(props);
|
|
66
89
|
|
|
@@ -89,7 +112,11 @@ using namespace facebook::react;
|
|
|
89
112
|
if (!_needsEmbedView || _embedId.length == 0) {
|
|
90
113
|
return;
|
|
91
114
|
}
|
|
92
|
-
|
|
115
|
+
// Only WIDTH has to be laid out: the SDK ignores our bounds entirely (it measures the window)
|
|
116
|
+
// and seeds the real height back through onHeight. Requiring a non-empty rect would wedge a
|
|
117
|
+
// surface that has legitimately collapsed to height 0 — it could never rebuild when fresh data
|
|
118
|
+
// arrives, because its own bounds would stay empty forever.
|
|
119
|
+
if (self.bounds.size.width <= 0) {
|
|
93
120
|
return;
|
|
94
121
|
}
|
|
95
122
|
|
|
@@ -101,7 +128,11 @@ using namespace facebook::react;
|
|
|
101
128
|
_needsEmbedView = NO;
|
|
102
129
|
_retryPending = NO;
|
|
103
130
|
} else {
|
|
104
|
-
NSLog(@"[GamificationEmbed] SDK returned nil — scheduling long fallback");
|
|
131
|
+
NSLog(@"[GamificationEmbed] SDK returned nil — collapsing and scheduling long fallback");
|
|
132
|
+
// nil means "do not render this embed now" — hidden, frequency-capped, or no resolved URL.
|
|
133
|
+
// Drop anything already attached so a previously loaded webview can't outlive that decision.
|
|
134
|
+
// The SDK has already pushed height 0 through onHeight, so the JS side collapses with us.
|
|
135
|
+
self.contentView = nil;
|
|
105
136
|
// Don't retry aggressively: the SDK may have entry points loaded but
|
|
106
137
|
// reward/program data not yet ready. The HydraGamificationDataReloaded
|
|
107
138
|
// notification fires when everything is ready and will call us again.
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
#import "GamificationLoyaltyViewComponentView.h"
|
|
4
4
|
|
|
5
|
-
#import
|
|
6
|
-
#import
|
|
7
|
-
#import
|
|
8
|
-
#import
|
|
5
|
+
#import <react/renderer/components/RNHydraLibSpec/ComponentDescriptors.h>
|
|
6
|
+
#import <react/renderer/components/RNHydraLibSpec/EventEmitters.h>
|
|
7
|
+
#import <react/renderer/components/RNHydraLibSpec/Props.h>
|
|
8
|
+
#import <react/renderer/components/RNHydraLibSpec/RCTComponentViewHelpers.h>
|
|
9
9
|
#import "RCTFabricComponentsPlugins.h"
|
|
10
10
|
#import <React/RCTBridgeModule.h>
|
|
11
11
|
#import <React/RCTComponentViewFactory.h>
|
|
@@ -53,12 +53,37 @@ using namespace facebook::react;
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
- (void)gamificationDataReloaded {
|
|
56
|
+
// Always dispatch to main: the SDK may post this from a background queue,
|
|
57
|
+
// and createGamificationLoyaltyView is a UIKit/MainActor call.
|
|
56
58
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
59
|
+
// Fabric keeps unmounted component views alive in its recycle pool, and a pooled view is
|
|
60
|
+
// still a registered observer here. It must NOT rebuild: every successful
|
|
61
|
+
// createGamificationLoyaltyView records an impression against the entry point's display count
|
|
62
|
+
// (conditions.showCount.count), so an off-screen pooled view would silently burn the cap and
|
|
63
|
+
// the widget would vanish for real users far sooner than configured. A mounted view always
|
|
64
|
+
// has a superview; a pooled one never does (Fabric asserts this when enqueueing).
|
|
65
|
+
if (self.superview == nil) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
57
68
|
self->_needsLoyaltyView = YES;
|
|
58
69
|
[self attachLoyaltyViewIfPossible];
|
|
59
70
|
});
|
|
60
71
|
}
|
|
61
72
|
|
|
73
|
+
// Fabric recycles component views. RCTViewComponentView's own prepareForRecycle resets the event
|
|
74
|
+
// emitter and react subviews but NOT `contentView`, and setContentView: re-adds it to the container
|
|
75
|
+
// view — so without this a recycled instance keeps the previous mount's loyalty view (a live
|
|
76
|
+
// WKWebView showing an already-rendered campaign). updateProps would then see `contentView != nil`
|
|
77
|
+
// with an unchanged loyaltyId and never ask the SDK again, bypassing the frequency-cap/visibility
|
|
78
|
+
// check entirely and displaying stale content the SDK has decided to hide.
|
|
79
|
+
- (void)prepareForRecycle {
|
|
80
|
+
self.contentView = nil;
|
|
81
|
+
_loyaltyId = nil;
|
|
82
|
+
_needsLoyaltyView = NO;
|
|
83
|
+
_retryPending = NO;
|
|
84
|
+
[super prepareForRecycle];
|
|
85
|
+
}
|
|
86
|
+
|
|
62
87
|
- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps {
|
|
63
88
|
const auto &newProps = *std::static_pointer_cast<const GamificationLoyaltyViewProps>(props);
|
|
64
89
|
|
|
@@ -85,16 +110,31 @@ using namespace facebook::react;
|
|
|
85
110
|
if (!_needsLoyaltyView || _loyaltyId.length == 0) {
|
|
86
111
|
return;
|
|
87
112
|
}
|
|
88
|
-
|
|
113
|
+
// Only WIDTH has to be laid out: the SDK ignores our bounds entirely (it measures the window)
|
|
114
|
+
// and seeds the real height back through onHeight. Requiring a non-empty rect would wedge a
|
|
115
|
+
// surface that has legitimately collapsed to height 0 — it could never rebuild when fresh data
|
|
116
|
+
// arrives, because its own bounds would stay empty forever.
|
|
117
|
+
if (self.bounds.size.width <= 0) {
|
|
89
118
|
return;
|
|
90
119
|
}
|
|
91
120
|
|
|
121
|
+
NSLog(@"[GamificationLoyalty] trying createGamificationLoyaltyView(loyaltyId=%@)", _loyaltyId);
|
|
92
122
|
UIView *loyaltyView = [[HydraSDKCore shared] createGamificationLoyaltyViewWithLoyaltyId:_loyaltyId];
|
|
93
123
|
if (loyaltyView) {
|
|
124
|
+
NSLog(@"[GamificationLoyalty] loyalty view created OK");
|
|
94
125
|
self.contentView = loyaltyView;
|
|
95
126
|
_needsLoyaltyView = NO;
|
|
96
127
|
_retryPending = NO;
|
|
97
128
|
} else {
|
|
129
|
+
NSLog(@"[GamificationLoyalty] SDK returned nil — collapsing and scheduling long fallback");
|
|
130
|
+
// nil means "do not render this now" — hidden, frequency-capped, or no resolved URL.
|
|
131
|
+
// Drop anything already attached so a previously loaded webview can't outlive that decision.
|
|
132
|
+
// The SDK has already pushed height 0 through onHeight, so the JS side collapses with us.
|
|
133
|
+
self.contentView = nil;
|
|
134
|
+
// Don't retry aggressively: the SDK may have entry points loaded but
|
|
135
|
+
// reward/program data not yet ready. The HydraGamificationDataReloaded
|
|
136
|
+
// notification fires when everything is ready and will call us again.
|
|
137
|
+
// This 5-second fallback only fires if that notification is missed.
|
|
98
138
|
[self scheduleFallbackRetry];
|
|
99
139
|
}
|
|
100
140
|
}
|
package/ios/HydraLib.h
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
#import <React/RCTEventEmitter.h>
|
|
2
2
|
|
|
3
3
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
4
|
-
|
|
4
|
+
// Codegen output is generated by the consuming app's own build against its own
|
|
5
|
+
// React Native version, and exposed on the header search path by the
|
|
6
|
+
// ReactCodegen pod - this package no longer ships a pre-generated copy.
|
|
5
7
|
#import <RNHydraLibSpec/RNHydraLibSpec.h>
|
|
6
|
-
#else
|
|
7
|
-
#import "generated/RNHydraLibSpec/RNHydraLibSpec.h"
|
|
8
|
-
#endif
|
|
9
8
|
@interface HydraLib : RCTEventEmitter <NativeHydraLibSpec>
|
|
10
9
|
#else
|
|
11
10
|
#import <React/RCTBridgeModule.h>
|
package/ios/HydraLib.mm
CHANGED
|
@@ -194,6 +194,22 @@ RCT_EXPORT_METHOD(reportMessageRating:(nonnull NSDictionary *)message rating:(do
|
|
|
194
194
|
[[HydraSDKCore shared] setCapToken:token resolve:resolve reject:reject];
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
- (void)setGamificationSuppressed:(BOOL)suppressed resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
|
|
198
|
+
[[HydraSDKCore shared] setGamificationSuppressed:suppressed resolve:resolve reject:reject];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
- (void)isGamificationSuppressed:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
|
|
202
|
+
[[HydraSDKCore shared] isGamificationSuppressed:resolve reject:reject];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
- (void)setThemeMode:(nonnull NSString *)mode resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
|
|
206
|
+
[[HydraSDKCore shared] setThemeMode:mode resolve:resolve reject:reject];
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
- (void)getThemeMode:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
|
|
210
|
+
[[HydraSDKCore shared] getThemeMode:resolve reject:reject];
|
|
211
|
+
}
|
|
212
|
+
|
|
197
213
|
|
|
198
214
|
|
|
199
215
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
@@ -60,22 +60,49 @@ import React
|
|
|
60
60
|
// }
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
// NOTE: these four methods do not yet call into a corresponding HydraCore/HydraInAppMessage
|
|
64
|
+
// report API (unlike the Android side, which calls HydraInAppUIHelper...reportInAppMessage*).
|
|
65
|
+
// The logging/resolve/reject below only makes failures visible and stops the RN promise
|
|
66
|
+
// from hanging forever — it does not report the click/dismiss/rating/feedback to the SDK.
|
|
67
|
+
|
|
63
68
|
@objc public func reportMessageClicked(_ message: [String: Any]?, resolve : RCTPromiseResolveBlock?, reject : RCTPromiseRejectBlock?) -> Void{
|
|
64
|
-
|
|
65
|
-
Logger.
|
|
69
|
+
guard let payload = message?["nativeJsonPayload"] as? [String: Any] else {
|
|
70
|
+
Logger.error("HydraInAppMessages: reportMessageClicked: message is nil or missing nativeJsonPayload")
|
|
71
|
+
reject?("Error", "message is nil or missing nativeJsonPayload", nil)
|
|
72
|
+
return
|
|
66
73
|
}
|
|
74
|
+
Logger.debug("HydraInAppMessages.reportMessageClicked payload = \(payload)")
|
|
75
|
+
resolve?(true)
|
|
67
76
|
}
|
|
68
|
-
|
|
77
|
+
|
|
69
78
|
@objc public func reportMessageDismissed(_ message: [String: Any]?, resolve : RCTPromiseResolveBlock?, reject : RCTPromiseRejectBlock?) -> Void{
|
|
70
|
-
|
|
79
|
+
guard let payload = message?["nativeJsonPayload"] as? [String: Any] else {
|
|
80
|
+
Logger.error("HydraInAppMessages: reportMessageDismissed: message is nil or missing nativeJsonPayload")
|
|
81
|
+
reject?("Error", "message is nil or missing nativeJsonPayload", nil)
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
Logger.debug("HydraInAppMessages.reportMessageDismissed payload = \(payload)")
|
|
85
|
+
resolve?(true)
|
|
71
86
|
}
|
|
72
|
-
|
|
87
|
+
|
|
73
88
|
@objc public func reportMessageRating(_ message: [String: Any]?, rating: Double, resolve : RCTPromiseResolveBlock?, reject : RCTPromiseRejectBlock?) -> Void{
|
|
74
|
-
|
|
89
|
+
guard let payload = message?["nativeJsonPayload"] as? [String: Any] else {
|
|
90
|
+
Logger.error("HydraInAppMessages: reportMessageRating: message is nil or missing nativeJsonPayload")
|
|
91
|
+
reject?("Error", "message is nil or missing nativeJsonPayload", nil)
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
Logger.debug("HydraInAppMessages.reportMessageRating payload = \(payload), rating = \(rating)")
|
|
95
|
+
resolve?(true)
|
|
75
96
|
}
|
|
76
|
-
|
|
97
|
+
|
|
77
98
|
@objc public func reportMessageFeedback(_ message: [String: Any]?, feedback: String, feedbackOptions: [String], resolve : RCTPromiseResolveBlock?, reject : RCTPromiseRejectBlock?) -> Void{
|
|
78
|
-
|
|
99
|
+
guard let payload = message?["nativeJsonPayload"] as? [String: Any] else {
|
|
100
|
+
Logger.error("HydraInAppMessages: reportMessageFeedback: message is nil or missing nativeJsonPayload")
|
|
101
|
+
reject?("Error", "message is nil or missing nativeJsonPayload", nil)
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
Logger.debug("HydraInAppMessages.reportMessageFeedback payload = \(payload), feedback = \(feedback), feedbackOptions = \(feedbackOptions)")
|
|
105
|
+
resolve?(true)
|
|
79
106
|
}
|
|
80
107
|
}
|
|
81
108
|
|