react-native-marketap-sdk 0.1.0-beta.11 → 0.1.0-beta.13
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 +1 -1
- package/android/src/main/AndroidManifest.xml +1 -10
- package/android/src/main/java/com/marketapsdk/MarketapSdkModule.kt +278 -69
- package/android/src/main/java/com/marketapsdk/ReactNativeBridgeRegistry.kt +110 -0
- package/ios/MarketapSdk.m +30 -23
- package/ios/MarketapSdk.swift +163 -22
- package/lib/commonjs/MarketapWebBridge.js +205 -15
- package/lib/commonjs/MarketapWebBridge.js.map +1 -1
- package/lib/commonjs/core/MarketapCore.js +233 -0
- package/lib/commonjs/core/MarketapCore.js.map +1 -0
- package/lib/commonjs/index.js +20 -166
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/internal/marketapCore.js +9 -0
- package/lib/commonjs/internal/marketapCore.js.map +1 -0
- package/lib/commonjs/internal/marketapPlugin.js +40 -0
- package/lib/commonjs/internal/marketapPlugin.js.map +1 -0
- package/lib/commonjs/version.js +1 -1
- package/lib/module/MarketapWebBridge.js +204 -15
- package/lib/module/MarketapWebBridge.js.map +1 -1
- package/lib/module/core/MarketapCore.js +226 -0
- package/lib/module/core/MarketapCore.js.map +1 -0
- package/lib/module/index.js +20 -165
- package/lib/module/index.js.map +1 -1
- package/lib/module/internal/marketapCore.js +3 -0
- package/lib/module/internal/marketapCore.js.map +1 -0
- package/lib/module/internal/marketapPlugin.js +35 -0
- package/lib/module/internal/marketapPlugin.js.map +1 -0
- package/lib/module/version.js +1 -1
- package/lib/typescript/MarketapWebBridge.d.ts +33 -6
- package/lib/typescript/MarketapWebBridge.d.ts.map +1 -1
- package/lib/typescript/core/MarketapCore.d.ts +54 -0
- package/lib/typescript/core/MarketapCore.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +2 -41
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/internal/marketapCore.d.ts +3 -0
- package/lib/typescript/internal/marketapCore.d.ts.map +1 -0
- package/lib/typescript/internal/marketapPlugin.d.ts +10 -0
- package/lib/typescript/internal/marketapPlugin.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +1 -2
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/version.d.ts +1 -1
- package/package.json +1 -1
- package/react-native-marketap-sdk.podspec +1 -1
package/android/build.gradle
CHANGED
|
@@ -99,7 +99,7 @@ dependencies {
|
|
|
99
99
|
implementation "com.facebook.react:react-native:+"
|
|
100
100
|
|
|
101
101
|
// MarketapSDK dependency with forced version constraints
|
|
102
|
-
implementation('com.github.marketap-dev:marketap-android-sdk:1.
|
|
102
|
+
implementation('com.github.marketap-dev:marketap-android-sdk:1.3.2') {
|
|
103
103
|
exclude group: 'androidx.appcompat', module: 'appcompat'
|
|
104
104
|
exclude group: 'androidx.core', module: 'core-ktx'
|
|
105
105
|
}
|
|
@@ -1,12 +1,3 @@
|
|
|
1
1
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
2
|
package="com.marketapsdk">
|
|
3
|
-
|
|
4
|
-
<service
|
|
5
|
-
android:name="com.marketap.sdk.client.push.MarketapFirebaseMessagingService"
|
|
6
|
-
android:exported="false">
|
|
7
|
-
<intent-filter>
|
|
8
|
-
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
|
9
|
-
</intent-filter>
|
|
10
|
-
</service>
|
|
11
|
-
</application>
|
|
12
|
-
</manifest>
|
|
3
|
+
</manifest>
|
|
@@ -13,6 +13,8 @@ import com.facebook.react.bridge.Arguments
|
|
|
13
13
|
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
14
14
|
import com.facebook.react.bridge.LifecycleEventListener
|
|
15
15
|
import com.marketap.sdk.Marketap
|
|
16
|
+
import com.marketap.sdk.MarketapPlugin
|
|
17
|
+
import com.marketap.sdk.MarketapWebBridge
|
|
16
18
|
import com.marketap.sdk.model.external.MarketapCampaignType
|
|
17
19
|
import com.marketap.sdk.model.external.MarketapLogLevel
|
|
18
20
|
import com.marketap.sdk.client.CurrentActivityHolder
|
|
@@ -22,30 +24,45 @@ private fun ReadableMap?.toNonNullableMap(): Map<String, Any>? {
|
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
25
|
-
ReactContextBaseJavaModule(reactContext), LifecycleEventListener {
|
|
27
|
+
ReactContextBaseJavaModule(reactContext), LifecycleEventListener, ReactNativeBridgeTarget {
|
|
26
28
|
|
|
27
29
|
companion object {
|
|
28
30
|
const val NAME = "MarketapSdk"
|
|
29
31
|
private const val CLICK_EVENT = "MarketapClickEvent"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
private const val IN_APP_MESSAGE_EVENT = "MarketapInAppMessageEvent"
|
|
33
|
+
|
|
34
|
+
private var isExternalInAppCallbackRegistered = false
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
private var hasListeners = false
|
|
35
38
|
private var isInitialized = false
|
|
36
39
|
private var initializedProjectId: String? = null
|
|
40
|
+
private var clickHandlerRegistered = false
|
|
41
|
+
private var isModuleActive = true
|
|
37
42
|
|
|
38
43
|
init {
|
|
39
44
|
reactApplicationContext.addLifecycleEventListener(this)
|
|
45
|
+
ReactNativeBridgeRegistry.register(this)
|
|
46
|
+
registerExternalInAppCallback()
|
|
40
47
|
}
|
|
41
48
|
|
|
42
49
|
override fun getName(): String {
|
|
43
50
|
return NAME
|
|
44
51
|
}
|
|
45
52
|
|
|
53
|
+
override val isAttachedToReact: Boolean
|
|
54
|
+
get() = isModuleActive
|
|
55
|
+
|
|
56
|
+
override val isClickHandlerRegistered: Boolean
|
|
57
|
+
get() = clickHandlerRegistered
|
|
58
|
+
|
|
59
|
+
override val isReactReady: Boolean
|
|
60
|
+
get() = isModuleActive && hasListeners && isReactInstanceReady()
|
|
61
|
+
|
|
46
62
|
@ReactMethod
|
|
47
|
-
fun initialize(
|
|
63
|
+
fun initialize(payload: ReadableMap?, promise: Promise) {
|
|
48
64
|
try {
|
|
65
|
+
val projectId = payload?.getString("projectId") ?: ""
|
|
49
66
|
if (!isMainProcess()) {
|
|
50
67
|
promise.resolve(null)
|
|
51
68
|
return
|
|
@@ -75,7 +92,13 @@ class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
|
75
92
|
}
|
|
76
93
|
|
|
77
94
|
@ReactMethod
|
|
78
|
-
fun setLogLevel(
|
|
95
|
+
fun setLogLevel(payload: ReadableMap?) {
|
|
96
|
+
val logLevel =
|
|
97
|
+
if (payload != null && payload.hasKey("logLevel") && !payload.isNull("logLevel")) {
|
|
98
|
+
payload.getInt("logLevel")
|
|
99
|
+
} else {
|
|
100
|
+
0
|
|
101
|
+
}
|
|
79
102
|
val resolvedLevel = MarketapLogLevel.values().firstOrNull { level ->
|
|
80
103
|
level.value == logLevel
|
|
81
104
|
} ?: MarketapLogLevel.NONE
|
|
@@ -88,16 +111,29 @@ class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
|
88
111
|
}
|
|
89
112
|
|
|
90
113
|
@ReactMethod
|
|
91
|
-
fun signup(
|
|
92
|
-
userId: String,
|
|
93
|
-
userProperties: ReadableMap?,
|
|
94
|
-
eventProperties: ReadableMap?,
|
|
95
|
-
persistUser: Boolean?,
|
|
96
|
-
promise: Promise
|
|
97
|
-
) {
|
|
114
|
+
fun signup(payload: ReadableMap?, promise: Promise) {
|
|
98
115
|
try {
|
|
116
|
+
val userId = payload?.getString("userId") ?: ""
|
|
117
|
+
val userProperties =
|
|
118
|
+
if (payload != null && payload.hasKey("userProperties") && !payload.isNull("userProperties")) {
|
|
119
|
+
payload.getMap("userProperties")
|
|
120
|
+
} else {
|
|
121
|
+
null
|
|
122
|
+
}
|
|
123
|
+
val eventProperties =
|
|
124
|
+
if (payload != null && payload.hasKey("eventProperties") && !payload.isNull("eventProperties")) {
|
|
125
|
+
payload.getMap("eventProperties")
|
|
126
|
+
} else {
|
|
127
|
+
null
|
|
128
|
+
}
|
|
129
|
+
val persistUser =
|
|
130
|
+
if (payload != null && payload.hasKey("persistUser") && !payload.isNull("persistUser")) {
|
|
131
|
+
payload.getBoolean("persistUser")
|
|
132
|
+
} else {
|
|
133
|
+
true
|
|
134
|
+
}
|
|
99
135
|
// Call MarketapSDK signup method
|
|
100
|
-
Marketap.signup(userId, userProperties.toNonNullableMap(), eventProperties.toNonNullableMap(), persistUser
|
|
136
|
+
Marketap.signup(userId, userProperties.toNonNullableMap(), eventProperties.toNonNullableMap(), persistUser)
|
|
101
137
|
promise.resolve(null)
|
|
102
138
|
} catch (e: Exception) {
|
|
103
139
|
promise.reject("SIGNUP_ERROR", e.message, e)
|
|
@@ -105,13 +141,21 @@ class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
|
105
141
|
}
|
|
106
142
|
|
|
107
143
|
@ReactMethod
|
|
108
|
-
fun login(
|
|
109
|
-
userId: String,
|
|
110
|
-
userProperties: ReadableMap?,
|
|
111
|
-
eventProperties: ReadableMap?,
|
|
112
|
-
promise: Promise
|
|
113
|
-
) {
|
|
144
|
+
fun login(payload: ReadableMap?, promise: Promise) {
|
|
114
145
|
try {
|
|
146
|
+
val userId = payload?.getString("userId") ?: ""
|
|
147
|
+
val userProperties =
|
|
148
|
+
if (payload != null && payload.hasKey("userProperties") && !payload.isNull("userProperties")) {
|
|
149
|
+
payload.getMap("userProperties")
|
|
150
|
+
} else {
|
|
151
|
+
null
|
|
152
|
+
}
|
|
153
|
+
val eventProperties =
|
|
154
|
+
if (payload != null && payload.hasKey("eventProperties") && !payload.isNull("eventProperties")) {
|
|
155
|
+
payload.getMap("eventProperties")
|
|
156
|
+
} else {
|
|
157
|
+
null
|
|
158
|
+
}
|
|
115
159
|
// Call MarketapSDK login method
|
|
116
160
|
Marketap.login(userId, userProperties.toNonNullableMap(), eventProperties.toNonNullableMap())
|
|
117
161
|
promise.resolve(null)
|
|
@@ -121,8 +165,14 @@ class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
|
121
165
|
}
|
|
122
166
|
|
|
123
167
|
@ReactMethod
|
|
124
|
-
fun logout(
|
|
168
|
+
fun logout(payload: ReadableMap?, promise: Promise) {
|
|
125
169
|
try {
|
|
170
|
+
val eventProperties =
|
|
171
|
+
if (payload != null && payload.hasKey("eventProperties") && !payload.isNull("eventProperties")) {
|
|
172
|
+
payload.getMap("eventProperties")
|
|
173
|
+
} else {
|
|
174
|
+
null
|
|
175
|
+
}
|
|
126
176
|
// Call MarketapSDK logout method
|
|
127
177
|
Marketap.logout(eventProperties.toNonNullableMap())
|
|
128
178
|
promise.resolve(null)
|
|
@@ -132,8 +182,15 @@ class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
|
132
182
|
}
|
|
133
183
|
|
|
134
184
|
@ReactMethod
|
|
135
|
-
fun track(
|
|
185
|
+
fun track(payload: ReadableMap?, promise: Promise) {
|
|
136
186
|
try {
|
|
187
|
+
val eventName = payload?.getString("eventName") ?: ""
|
|
188
|
+
val eventProperties =
|
|
189
|
+
if (payload != null && payload.hasKey("eventProperties") && !payload.isNull("eventProperties")) {
|
|
190
|
+
payload.getMap("eventProperties")
|
|
191
|
+
} else {
|
|
192
|
+
null
|
|
193
|
+
}
|
|
137
194
|
// Call MarketapSDK track method
|
|
138
195
|
Marketap.track(eventName, eventProperties.toNonNullableMap())
|
|
139
196
|
promise.resolve(null)
|
|
@@ -143,8 +200,20 @@ class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
|
143
200
|
}
|
|
144
201
|
|
|
145
202
|
@ReactMethod
|
|
146
|
-
fun trackPurchase(
|
|
203
|
+
fun trackPurchase(payload: ReadableMap?, promise: Promise) {
|
|
147
204
|
try {
|
|
205
|
+
val revenue =
|
|
206
|
+
if (payload != null && payload.hasKey("revenue") && !payload.isNull("revenue")) {
|
|
207
|
+
payload.getDouble("revenue")
|
|
208
|
+
} else {
|
|
209
|
+
0.0
|
|
210
|
+
}
|
|
211
|
+
val eventProperties =
|
|
212
|
+
if (payload != null && payload.hasKey("eventProperties") && !payload.isNull("eventProperties")) {
|
|
213
|
+
payload.getMap("eventProperties")
|
|
214
|
+
} else {
|
|
215
|
+
null
|
|
216
|
+
}
|
|
148
217
|
// Call MarketapSDK trackPurchase method
|
|
149
218
|
Marketap.trackPurchase(revenue, eventProperties.toNonNullableMap())
|
|
150
219
|
promise.resolve(null)
|
|
@@ -154,13 +223,21 @@ class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
|
154
223
|
}
|
|
155
224
|
|
|
156
225
|
@ReactMethod
|
|
157
|
-
fun trackRevenue(
|
|
158
|
-
eventName: String,
|
|
159
|
-
revenue: Double,
|
|
160
|
-
eventProperties: ReadableMap?,
|
|
161
|
-
promise: Promise
|
|
162
|
-
) {
|
|
226
|
+
fun trackRevenue(payload: ReadableMap?, promise: Promise) {
|
|
163
227
|
try {
|
|
228
|
+
val eventName = payload?.getString("eventName") ?: ""
|
|
229
|
+
val revenue =
|
|
230
|
+
if (payload != null && payload.hasKey("revenue") && !payload.isNull("revenue")) {
|
|
231
|
+
payload.getDouble("revenue")
|
|
232
|
+
} else {
|
|
233
|
+
0.0
|
|
234
|
+
}
|
|
235
|
+
val eventProperties =
|
|
236
|
+
if (payload != null && payload.hasKey("eventProperties") && !payload.isNull("eventProperties")) {
|
|
237
|
+
payload.getMap("eventProperties")
|
|
238
|
+
} else {
|
|
239
|
+
null
|
|
240
|
+
}
|
|
164
241
|
// Call MarketapSDK trackRevenue method
|
|
165
242
|
Marketap.trackRevenue(eventName, revenue, eventProperties.toNonNullableMap())
|
|
166
243
|
promise.resolve(null)
|
|
@@ -170,8 +247,14 @@ class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
|
170
247
|
}
|
|
171
248
|
|
|
172
249
|
@ReactMethod
|
|
173
|
-
fun trackPageView(
|
|
250
|
+
fun trackPageView(payload: ReadableMap?, promise: Promise) {
|
|
174
251
|
try {
|
|
252
|
+
val eventProperties =
|
|
253
|
+
if (payload != null && payload.hasKey("eventProperties") && !payload.isNull("eventProperties")) {
|
|
254
|
+
payload.getMap("eventProperties")
|
|
255
|
+
} else {
|
|
256
|
+
null
|
|
257
|
+
}
|
|
175
258
|
// Call MarketapSDK trackPageView method
|
|
176
259
|
Marketap.trackPageView(eventProperties.toNonNullableMap())
|
|
177
260
|
promise.resolve(null)
|
|
@@ -181,8 +264,15 @@ class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
|
181
264
|
}
|
|
182
265
|
|
|
183
266
|
@ReactMethod
|
|
184
|
-
fun identify(
|
|
267
|
+
fun identify(payload: ReadableMap?, promise: Promise) {
|
|
185
268
|
try {
|
|
269
|
+
val userId = payload?.getString("userId") ?: ""
|
|
270
|
+
val userProperties =
|
|
271
|
+
if (payload != null && payload.hasKey("userProperties") && !payload.isNull("userProperties")) {
|
|
272
|
+
payload.getMap("userProperties")
|
|
273
|
+
} else {
|
|
274
|
+
null
|
|
275
|
+
}
|
|
186
276
|
// Call MarketapSDK identify method
|
|
187
277
|
Marketap.identify(userId, userProperties.toNonNullableMap())
|
|
188
278
|
promise.resolve(null)
|
|
@@ -205,14 +295,14 @@ class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
|
205
295
|
@ReactMethod
|
|
206
296
|
fun setClickHandler(promise: Promise) {
|
|
207
297
|
try {
|
|
208
|
-
|
|
298
|
+
clickHandlerRegistered = true
|
|
209
299
|
Marketap.setClickHandler { event ->
|
|
210
300
|
val clickData = convertClickEventToMap(event)
|
|
211
301
|
|
|
212
|
-
|
|
302
|
+
ReactNativeBridgeRegistry.deliverClick(clickData)
|
|
213
303
|
}
|
|
214
304
|
|
|
215
|
-
|
|
305
|
+
ReactNativeBridgeRegistry.flushIfPending()
|
|
216
306
|
promise.resolve(null)
|
|
217
307
|
} catch (e: Exception) {
|
|
218
308
|
promise.reject("SET_CLICK_HANDLER_ERROR", e.message, e)
|
|
@@ -233,35 +323,139 @@ class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
|
233
323
|
}
|
|
234
324
|
}
|
|
235
325
|
|
|
326
|
+
// 웹브릿지 인앱 메시지 관련 메서드
|
|
236
327
|
@ReactMethod
|
|
237
|
-
fun
|
|
328
|
+
fun trackFromWebBridge(payload: ReadableMap?, promise: Promise) {
|
|
329
|
+
try {
|
|
330
|
+
val eventName = payload?.getString("eventName") ?: ""
|
|
331
|
+
val eventProperties =
|
|
332
|
+
if (payload != null && payload.hasKey("eventProperties") && !payload.isNull("eventProperties")) {
|
|
333
|
+
payload.getMap("eventProperties")
|
|
334
|
+
} else {
|
|
335
|
+
null
|
|
336
|
+
}
|
|
337
|
+
val handleInAppInReactNative =
|
|
338
|
+
if (payload != null && payload.hasKey("handleInAppInReactNative") && !payload.isNull("handleInAppInReactNative")) {
|
|
339
|
+
payload.getBoolean("handleInAppInReactNative")
|
|
340
|
+
} else {
|
|
341
|
+
false
|
|
342
|
+
}
|
|
343
|
+
if (handleInAppInReactNative) {
|
|
344
|
+
ReactNativeBridgeRegistry.setWebBridgeSourceTarget(this)
|
|
345
|
+
MarketapWebBridge.setExternalWebBridgeActive(true)
|
|
346
|
+
} else {
|
|
347
|
+
ReactNativeBridgeRegistry.clearWebBridgeSourceTarget()
|
|
348
|
+
MarketapWebBridge.setExternalWebBridgeActive(false)
|
|
349
|
+
}
|
|
350
|
+
MarketapPlugin.trackEvent(eventName, eventProperties.toNonNullableMap())
|
|
351
|
+
promise.resolve(null)
|
|
352
|
+
} catch (e: Exception) {
|
|
353
|
+
promise.reject("TRACK_FROM_WEB_BRIDGE_ERROR", e.message, e)
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
@ReactMethod
|
|
358
|
+
fun setUserProperties(payload: ReadableMap?, promise: Promise) {
|
|
238
359
|
try {
|
|
239
|
-
|
|
360
|
+
val userProperties =
|
|
361
|
+
if (payload != null && payload.hasKey("userProperties") && !payload.isNull("userProperties")) {
|
|
362
|
+
payload.getMap("userProperties")
|
|
363
|
+
} else {
|
|
364
|
+
null
|
|
365
|
+
}
|
|
366
|
+
val props = userProperties.toNonNullableMap()
|
|
367
|
+
if (props == null) {
|
|
368
|
+
promise.reject("ARG_ERROR", "Missing userProperties", null)
|
|
369
|
+
return
|
|
370
|
+
}
|
|
371
|
+
MarketapPlugin.setUserProperties(props)
|
|
240
372
|
promise.resolve(null)
|
|
241
373
|
} catch (e: Exception) {
|
|
242
|
-
promise.reject("
|
|
374
|
+
promise.reject("SET_USER_PROPERTIES_ERROR", e.message, e)
|
|
243
375
|
}
|
|
244
376
|
}
|
|
245
377
|
|
|
246
378
|
@ReactMethod
|
|
247
|
-
fun
|
|
379
|
+
fun trackInAppImpression(payload: ReadableMap?, promise: Promise) {
|
|
248
380
|
try {
|
|
249
|
-
val
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
381
|
+
val campaignId = payload?.getString("campaignId")
|
|
382
|
+
val messageId = payload?.getString("messageId")
|
|
383
|
+
val layoutSubType = payload?.getString("layoutSubType")
|
|
384
|
+
if (campaignId == null || messageId == null) {
|
|
385
|
+
android.util.Log.w(
|
|
386
|
+
NAME,
|
|
387
|
+
"trackInAppImpression: missing required params (campaignId=$campaignId, messageId=$messageId)"
|
|
388
|
+
)
|
|
254
389
|
promise.resolve(null)
|
|
390
|
+
return
|
|
255
391
|
}
|
|
392
|
+
MarketapPlugin.trackInAppImpression(campaignId, messageId, layoutSubType)
|
|
393
|
+
promise.resolve(null)
|
|
256
394
|
} catch (e: Exception) {
|
|
257
|
-
promise.reject("
|
|
395
|
+
promise.reject("TRACK_INAPP_IMPRESSION_ERROR", e.message, e)
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
@ReactMethod
|
|
400
|
+
fun trackInAppClick(payload: ReadableMap?, promise: Promise) {
|
|
401
|
+
try {
|
|
402
|
+
val campaignId = payload?.getString("campaignId")
|
|
403
|
+
val messageId = payload?.getString("messageId")
|
|
404
|
+
val locationId = payload?.getString("locationId")
|
|
405
|
+
val url = payload?.getString("url")
|
|
406
|
+
val layoutSubType = payload?.getString("layoutSubType")
|
|
407
|
+
if (campaignId == null || messageId == null || locationId == null) {
|
|
408
|
+
android.util.Log.w(
|
|
409
|
+
NAME,
|
|
410
|
+
"trackInAppClick: missing required params (campaignId=$campaignId, messageId=$messageId, locationId=$locationId)"
|
|
411
|
+
)
|
|
412
|
+
promise.resolve(null)
|
|
413
|
+
return
|
|
414
|
+
}
|
|
415
|
+
MarketapPlugin.trackInAppClick(campaignId, messageId, locationId, url, layoutSubType)
|
|
416
|
+
promise.resolve(null)
|
|
417
|
+
} catch (e: Exception) {
|
|
418
|
+
promise.reject("TRACK_INAPP_CLICK_ERROR", e.message, e)
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
@ReactMethod
|
|
423
|
+
fun hideCampaign(payload: ReadableMap?, promise: Promise) {
|
|
424
|
+
try {
|
|
425
|
+
val campaignId = payload?.getString("campaignId")
|
|
426
|
+
val hideType = payload?.getString("hideType")
|
|
427
|
+
if (campaignId == null) {
|
|
428
|
+
android.util.Log.w(NAME, "hideCampaign: missing campaignId")
|
|
429
|
+
promise.resolve(null)
|
|
430
|
+
return
|
|
431
|
+
}
|
|
432
|
+
MarketapPlugin.hideInAppMessage(campaignId, hideType)
|
|
433
|
+
promise.resolve(null)
|
|
434
|
+
} catch (e: Exception) {
|
|
435
|
+
promise.reject("HIDE_CAMPAIGN_ERROR", e.message, e)
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
@ReactMethod
|
|
440
|
+
fun setDeviceOptIn(payload: ReadableMap?, promise: Promise) {
|
|
441
|
+
try {
|
|
442
|
+
val optIn: Boolean? =
|
|
443
|
+
if (payload != null && payload.hasKey("optIn") && !payload.isNull("optIn")) {
|
|
444
|
+
payload.getBoolean("optIn")
|
|
445
|
+
} else {
|
|
446
|
+
null
|
|
447
|
+
}
|
|
448
|
+
Marketap.setDeviceOptIn(optIn)
|
|
449
|
+
promise.resolve(null)
|
|
450
|
+
} catch (e: Exception) {
|
|
451
|
+
promise.reject("SET_DEVICE_OPT_IN_ERROR", e.message, e)
|
|
258
452
|
}
|
|
259
453
|
}
|
|
260
454
|
|
|
261
455
|
@ReactMethod
|
|
262
456
|
fun addListener(eventName: String) {
|
|
263
457
|
hasListeners = true
|
|
264
|
-
|
|
458
|
+
ReactNativeBridgeRegistry.flushIfPending()
|
|
265
459
|
}
|
|
266
460
|
|
|
267
461
|
@ReactMethod
|
|
@@ -270,7 +464,7 @@ class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
|
270
464
|
}
|
|
271
465
|
|
|
272
466
|
private fun sendEvent(eventName: String, params: WritableMap?): Boolean {
|
|
273
|
-
if (!hasListeners || !
|
|
467
|
+
if (!hasListeners || !isReactInstanceReady()) {
|
|
274
468
|
return false
|
|
275
469
|
}
|
|
276
470
|
reactApplicationContext.runOnJSQueueThread {
|
|
@@ -281,28 +475,7 @@ class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
|
281
475
|
return true
|
|
282
476
|
}
|
|
283
477
|
|
|
284
|
-
private fun
|
|
285
|
-
if (hasListeners && isReactReady()) {
|
|
286
|
-
if (sendEvent(CLICK_EVENT, clickData)) {
|
|
287
|
-
pendingClickEvent = null
|
|
288
|
-
} else {
|
|
289
|
-
pendingClickEvent = clickData
|
|
290
|
-
}
|
|
291
|
-
} else {
|
|
292
|
-
pendingClickEvent = clickData
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
private fun flushPendingClick() {
|
|
297
|
-
val pendingEvent = pendingClickEvent
|
|
298
|
-
if (pendingEvent != null && hasListeners && isReactReady()) {
|
|
299
|
-
if (sendEvent(CLICK_EVENT, pendingEvent)) {
|
|
300
|
-
pendingClickEvent = null
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
private fun isReactReady(): Boolean {
|
|
478
|
+
private fun isReactInstanceReady(): Boolean {
|
|
306
479
|
return reactApplicationContext.hasActiveCatalystInstance() &&
|
|
307
480
|
reactApplicationContext.hasActiveReactInstance()
|
|
308
481
|
}
|
|
@@ -320,16 +493,52 @@ class MarketapSdkModule(reactContext: ReactApplicationContext) :
|
|
|
320
493
|
return map
|
|
321
494
|
}
|
|
322
495
|
|
|
496
|
+
override fun sendInAppMessage(
|
|
497
|
+
campaign: Map<String, Any?>,
|
|
498
|
+
messageId: String,
|
|
499
|
+
hasCustomClickHandler: Boolean
|
|
500
|
+
) {
|
|
501
|
+
val args = Arguments.createMap()
|
|
502
|
+
args.putMap("campaign", Arguments.makeNativeMap(campaign))
|
|
503
|
+
args.putString("messageId", messageId)
|
|
504
|
+
args.putBoolean("hasCustomClickHandler", hasCustomClickHandler)
|
|
505
|
+
sendEvent(IN_APP_MESSAGE_EVENT, args)
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
override fun sendClick(clickData: WritableMap) {
|
|
509
|
+
sendEvent(CLICK_EVENT, clickData)
|
|
510
|
+
}
|
|
511
|
+
|
|
323
512
|
override fun onHostResume() {
|
|
324
513
|
val activity = getCurrentActivity() ?: return
|
|
325
514
|
CurrentActivityHolder.set(activity)
|
|
326
|
-
|
|
515
|
+
ReactNativeBridgeRegistry.flushIfPending()
|
|
327
516
|
}
|
|
328
517
|
|
|
329
518
|
override fun onHostPause() {
|
|
330
519
|
}
|
|
331
520
|
|
|
332
521
|
override fun onHostDestroy() {
|
|
522
|
+
isModuleActive = false
|
|
523
|
+
ReactNativeBridgeRegistry.unregister(this)
|
|
524
|
+
reactApplicationContext.removeLifecycleEventListener(this)
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
override fun invalidate() {
|
|
528
|
+
isModuleActive = false
|
|
529
|
+
ReactNativeBridgeRegistry.unregister(this)
|
|
333
530
|
reactApplicationContext.removeLifecycleEventListener(this)
|
|
531
|
+
super.invalidate()
|
|
334
532
|
}
|
|
335
|
-
|
|
533
|
+
|
|
534
|
+
private fun registerExternalInAppCallback() {
|
|
535
|
+
if (isExternalInAppCallbackRegistered) {
|
|
536
|
+
return
|
|
537
|
+
}
|
|
538
|
+
isExternalInAppCallbackRegistered = true
|
|
539
|
+
|
|
540
|
+
MarketapWebBridge.setExternalInAppMessageCallback { campaign, messageId, hasCustomClickHandler ->
|
|
541
|
+
ReactNativeBridgeRegistry.sendInAppMessage(campaign, messageId, hasCustomClickHandler)
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
package com.marketapsdk
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.WritableMap
|
|
4
|
+
|
|
5
|
+
internal interface ReactNativeBridgeTarget {
|
|
6
|
+
val isAttachedToReact: Boolean
|
|
7
|
+
val isClickHandlerRegistered: Boolean
|
|
8
|
+
val isReactReady: Boolean
|
|
9
|
+
|
|
10
|
+
fun sendInAppMessage(
|
|
11
|
+
campaign: Map<String, Any?>,
|
|
12
|
+
messageId: String,
|
|
13
|
+
hasCustomClickHandler: Boolean
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
fun sendClick(clickData: WritableMap)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
internal object ReactNativeBridgeRegistry {
|
|
20
|
+
private val activeTargets: MutableList<ReactNativeBridgeTarget> = mutableListOf()
|
|
21
|
+
|
|
22
|
+
private val clickHandlerTargets: List<ReactNativeBridgeTarget>
|
|
23
|
+
get() = activeTargets.filter { it.isClickHandlerRegistered && it.isAttachedToReact }
|
|
24
|
+
private val attachedTargets: List<ReactNativeBridgeTarget>
|
|
25
|
+
get() = activeTargets.filter { it.isAttachedToReact }
|
|
26
|
+
|
|
27
|
+
private var lastPendingClick: WritableMap? = null
|
|
28
|
+
|
|
29
|
+
// trackFromWebBridge를 호출한 타겟 (인앱 메시지 전달 대상)
|
|
30
|
+
private var webBridgeSourceTarget: ReactNativeBridgeTarget? = null
|
|
31
|
+
|
|
32
|
+
fun register(target: ReactNativeBridgeTarget) {
|
|
33
|
+
log("Register target: $target")
|
|
34
|
+
activeTargets.add(target)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
fun unregister(target: ReactNativeBridgeTarget) {
|
|
38
|
+
log("Unregister target: $target")
|
|
39
|
+
activeTargets.remove(target)
|
|
40
|
+
if (webBridgeSourceTarget == target) {
|
|
41
|
+
webBridgeSourceTarget = null
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* trackFromWebBridge 호출 시 소스 타겟 설정
|
|
47
|
+
*/
|
|
48
|
+
fun setWebBridgeSourceTarget(target: ReactNativeBridgeTarget) {
|
|
49
|
+
webBridgeSourceTarget = target
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 소스 타겟 초기화
|
|
54
|
+
*/
|
|
55
|
+
fun clearWebBridgeSourceTarget() {
|
|
56
|
+
webBridgeSourceTarget = null
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 네이티브 SDK에서 RN으로 인앱 메시지 전달
|
|
61
|
+
* trackFromWebBridge를 호출한 타겟에만 전달
|
|
62
|
+
*/
|
|
63
|
+
fun sendInAppMessage(
|
|
64
|
+
campaign: Map<String, Any?>,
|
|
65
|
+
messageId: String,
|
|
66
|
+
hasCustomClickHandler: Boolean
|
|
67
|
+
) {
|
|
68
|
+
val target = webBridgeSourceTarget
|
|
69
|
+
webBridgeSourceTarget = null
|
|
70
|
+
|
|
71
|
+
if (target != null && target.isAttachedToReact && target.isReactReady) {
|
|
72
|
+
target.sendInAppMessage(campaign, messageId, hasCustomClickHandler)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
fun flushIfPending() {
|
|
77
|
+
log("flush called, $lastPendingClick")
|
|
78
|
+
lastPendingClick?.let { clickData ->
|
|
79
|
+
log("Flush pending click on new instance: $clickData")
|
|
80
|
+
deliverClick(clickData)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
fun deliverClick(clickData: WritableMap) {
|
|
85
|
+
log("Deliver click: $clickData")
|
|
86
|
+
val readyTargets = clickHandlerTargets.filter { it.isReactReady }
|
|
87
|
+
if (readyTargets.isNotEmpty()) {
|
|
88
|
+
log("There are ${readyTargets.size} click handler targets available; delivery click: $clickData")
|
|
89
|
+
readyTargets.forEach { target ->
|
|
90
|
+
log("Deliver click to $target: $clickData")
|
|
91
|
+
target.sendClick(clickData)
|
|
92
|
+
}
|
|
93
|
+
lastPendingClick = null
|
|
94
|
+
} else {
|
|
95
|
+
log("Targets not ready; store click: $clickData")
|
|
96
|
+
lastPendingClick = clickData
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
fun popPendingClick(): WritableMap? {
|
|
101
|
+
val pending = lastPendingClick
|
|
102
|
+
lastPendingClick = null
|
|
103
|
+
return pending
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private fun log(message: String) {
|
|
107
|
+
// TODO: route to Marketap logger when available in RN layer
|
|
108
|
+
android.util.Log.d("MarketapBridgeRegistry", message)
|
|
109
|
+
}
|
|
110
|
+
}
|