-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathMPRoktModule.kt
More file actions
133 lines (116 loc) · 5.08 KB
/
Copy pathMPRoktModule.kt
File metadata and controls
133 lines (116 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package com.mparticle.react.rokt
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.ReadableType
import com.facebook.react.bridge.UiThreadUtil
import com.facebook.react.uimanager.UIManagerHelper
import com.mparticle.MParticle
import com.mparticle.WrapperSdk
import com.mparticle.react.NativeMPRoktSpec
import com.mparticle.rokt.RoktEmbeddedView
import com.mparticle.internal.Logger
import java.lang.ref.WeakReference
import java.util.concurrent.CountDownLatch
class MPRoktModule(
private val reactContext: ReactApplicationContext,
) : NativeMPRoktSpec(reactContext) {
init {
MParticle.getInstance()?.setWrapperSdk(WrapperSdk.WrapperSdkReactNative, "")
}
private val impl = MPRoktModuleImpl(reactContext)
override fun getName(): String = impl.getName()
@ReactMethod
override fun selectPlacements(
identifier: String,
attributes: ReadableMap?,
placeholders: ReadableMap?,
roktConfig: ReadableMap?,
fontFilesMap: ReadableMap?,
) {
if (identifier.isBlank()) {
Logger.warning("selectPlacements failed. identifier cannot be empty")
return
}
MParticle.getInstance()?.Rokt()?.events(identifier)?.let {
impl.startRoktEventListener(it, reactContext.currentActivity, identifier)
}
// Process placeholders for Fabric
val placeholdersMap = processPlaceholders(placeholders)
val config = roktConfig?.let { impl.buildRoktConfig(it) }
MParticle.getInstance()?.Rokt()?.selectPlacements(
identifier = identifier,
attributes = impl.readableMapToMapOfStrings(attributes),
callbacks = impl.createRoktCallback(),
embeddedViews = placeholdersMap,
fontTypefaces = null, // TODO
config = config,
)
}
@ReactMethod
override fun purchaseFinalized(
placementId: String,
catalogItemId: String,
success: Boolean,
) {
impl.purchaseFinalized(placementId, catalogItemId, success)
}
/**
* Process placeholders from ReadableMap to a map of Widgets for use with Rokt.
* This method handles the Fabric-specific view resolution.
*/
private fun processPlaceholders(placeholders: ReadableMap?): Map<String, WeakReference<RoktEmbeddedView>> {
val placeholdersMap = HashMap<String, WeakReference<RoktEmbeddedView>>()
if (placeholders != null) {
// Use CountDownLatch to wait for UI thread processing
val latch = CountDownLatch(1)
// Run view resolution on UI thread
UiThreadUtil.runOnUiThread {
try {
val iterator = placeholders.keySetIterator()
while (iterator.hasNextKey()) {
val key = iterator.nextKey()
try {
// Get the tag value as an integer
val reactTag =
when {
placeholders.getType(key) == ReadableType.Number ->
placeholders.getDouble(key).toInt()
else -> {
Logger.warning("Invalid view tag for key: $key")
continue
}
}
// Get the UIManager for this specific tag
val uiManager =
UIManagerHelper.getUIManagerForReactTag(reactContext, reactTag)
if (uiManager == null) {
Logger.warning("UIManager not found for tag: $reactTag")
continue
}
// Resolve the view using the manager (now on UI thread)
val view = uiManager.resolveView(reactTag)
if (view is RoktEmbeddedView) {
placeholdersMap[key] = WeakReference(view)
Logger.debug("Successfully found Widget for key: $key with tag: $reactTag")
} else {
Logger.warning("View with tag $reactTag is not a Widget: ${view?.javaClass?.simpleName}")
}
} catch (e: Exception) {
Logger.warning("Error processing placeholder for key $key: ${e.message}")
}
}
} finally {
latch.countDown()
}
}
try {
// Wait for UI thread to finish processing
latch.await()
} catch (e: InterruptedException) {
Logger.warning("Interrupted while waiting for UI thread: ${e.message}")
}
}
return placeholdersMap
}
}