-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathRoktEventHandler.kt
More file actions
118 lines (105 loc) · 4.69 KB
/
Copy pathRoktEventHandler.kt
File metadata and controls
118 lines (105 loc) · 4.69 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
package com.mparticle.mparticle_flutter_sdk
import android.app.Activity
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.mparticle.RoktEvent
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.EventChannel
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentLinkedDeque
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
class RoktEventHandler(private val messenger: BinaryMessenger) {
private val eventListeners = ConcurrentHashMap<Any?, ConcurrentLinkedDeque<EventChannel.EventSink>>()
private val eventSubscriptions = mutableMapOf<String, Job?>()
init {
setupEventChannel()
}
fun subscribeToEvents(events: Flow<RoktEvent>, identifier: String? = null, activity: Activity) {
val activeJob = eventSubscriptions[identifier.orEmpty()]?.takeIf { it.isActive }
if (activeJob != null) {
return
}
val owner = activity as? LifecycleOwner ?: return
val job = owner.lifecycleScope.launch {
owner.lifecycle.repeatOnLifecycle(Lifecycle.State.CREATED) {
events.collect { event ->
val params = mutableMapOf<String, String>()
params["event"] = event::class.simpleName ?: "RoktEvent"
event.placementId?.let { params["placementId"] = it }
when (event) {
is RoktEvent.InitComplete -> {
params["status"] = event.success.toString()
}
is RoktEvent.OpenUrl -> {
params["url"] = event.url
}
is RoktEvent.CartItemInstantPurchase -> {
params["cartItemId"] = event.cartItemId
params["catalogItemId"] = event.catalogItemId
params["currency"] = event.currency
params["description"] = event.description
params["linkedProductId"] = event.linkedProductId
params["totalPrice"] = event.totalPrice.toString()
params["quantity"] = event.quantity.toString()
params["unitPrice"] = event.unitPrice.toString()
}
else -> {
// No custom parameters needed for other events
}
}
identifier?.let { params["identifier"] = it }
eventListeners.values.flatten().forEach { listener -> listener.success(params) }
}
}
}
eventSubscriptions[identifier.orEmpty()] = job
}
private fun setupEventChannel() {
EventChannel(messenger, EVENT_CHANNEL_NAME).setStreamHandler(
object : EventChannel.StreamHandler {
override fun onListen(
arguments: Any?,
sink: EventChannel.EventSink?,
) {
sink?.let {
val sinks = eventListeners.getOrPut(arguments ?: "") { ConcurrentLinkedDeque() }
sinks.addLast(it)
}
}
override fun onCancel(arguments: Any?) {
val sinks = eventListeners[arguments ?: ""]
if (sinks?.isNotEmpty() == true) {
sinks.removeLast()
}
if (sinks?.isEmpty() == true) {
eventListeners.remove(arguments ?: "")
}
}
},
)
}
private val RoktEvent.placementId: String?
get() = when (this) {
is RoktEvent.FirstPositiveEngagement -> placementId
is RoktEvent.OfferEngagement -> placementId
is RoktEvent.PlacementClosed -> placementId
is RoktEvent.PlacementCompleted -> placementId
is RoktEvent.PlacementFailure -> placementId
is RoktEvent.PlacementInteractive -> placementId
is RoktEvent.PlacementReady -> placementId
is RoktEvent.PositiveEngagement -> placementId
is RoktEvent.OpenUrl -> placementId
is RoktEvent.CartItemInstantPurchase -> placementId
else -> null
}
companion object {
private const val EVENT_CHANNEL_NAME = "MPRoktEvents"
}
}