Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ buildscript {
plugins {
id "org.sonarqube" version "3.5.0.2730"
id "org.jlleitschuh.gradle.ktlint" version "13.0.0"
Comment thread
Mansi-mParticle marked this conversation as resolved.
id "org.jetbrains.kotlin.plugin.compose" version "2.0.0"
}

sonarqube {
Expand All @@ -29,7 +30,7 @@ sonarqube {
}
}

apply plugin: 'org.jlleitschuh.gradle.ktlint'

apply plugin: "kotlin-android"
apply plugin: 'com.mparticle.kit'

Expand All @@ -48,6 +49,9 @@ android {
jvmArgs += ['--add-opens', 'java.base/java.lang.reflect=ALL-UNNAMED']
}
}
buildFeatures {
compose true
}
}

repositories {
Expand All @@ -58,12 +62,16 @@ repositories {
dependencies {
implementation 'androidx.annotation:annotation:1.5.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
implementation 'androidx.compose.runtime:runtime-android:1.8.3'
api 'com.rokt:roktsdk:4.11.0'

testImplementation files('libs/java-json.jar')
testImplementation 'com.squareup.assertj:assertj-android:1.2.0'
testImplementation ("io.mockk:mockk:1.13.4")
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4'
compileOnly 'androidx.compose.ui:ui:1.0.0'
compileOnly 'androidx.compose.material:material:1.0.0'
compileOnly 'androidx.compose.ui:ui-tooling:1.0.0'
}

ktlint {
Expand Down
64 changes: 54 additions & 10 deletions src/main/kotlin/com/mparticle/kits/RoktKit.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,20 @@ import com.mparticle.rokt.RoktConfig
import com.mparticle.rokt.RoktEmbeddedView
import com.rokt.roktsdk.CacheConfig
import com.rokt.roktsdk.Rokt
import com.rokt.roktsdk.Rokt.RoktCallback
import com.rokt.roktsdk.Rokt.SdkFrameworkType.Android
import com.rokt.roktsdk.Rokt.SdkFrameworkType.Cordova
import com.rokt.roktsdk.Rokt.SdkFrameworkType.Flutter
import com.rokt.roktsdk.Rokt.SdkFrameworkType.ReactNative
import com.rokt.roktsdk.RoktEvent
import com.rokt.roktsdk.RoktWidgetDimensionCallBack
import com.rokt.roktsdk.Widget
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import java.lang.ref.WeakReference
import java.math.BigDecimal

Expand All @@ -56,7 +61,10 @@ class RoktKit :

override fun getInstance(): RoktKit = this

private var deferredAttributes: CompletableDeferred<Map<String, String>>? = null

public override fun onKitCreate(settings: Map<String, String>, ctx: Context): List<ReportingMessage> {
register(this)
applicationContext = ctx.applicationContext
val roktTagId = settings[ROKT_ACCOUNT_ID]
if (KitUtils.isEmpty(roktTagId)) {
Expand Down Expand Up @@ -186,6 +194,23 @@ class RoktKit :
}?.toMap()

this.mpRoktEventCallback = mpRoktEventCallback
val finalAttributes = prepareFinalAttributes(filterUser, attributes)
val roktConfig = mpRoktConfig?.let { mapToRoktConfig(it) }
Rokt.execute(
viewName,
finalAttributes,
this,
// Pass placeholders and fontTypefaces only if they are not empty or null
placeholders.takeIf { it?.isNotEmpty() == true },
fontTypefaces.takeIf { it?.isNotEmpty() == true },
roktConfig,
)
}

private fun prepareFinalAttributes(
filterUser: FilteredMParticleUser?,
attributes: Map<String, String>,
): Map<String, String> {
val finalAttributes = mutableMapOf<String, String>()
filterUser?.userAttributes?.let { userAttrs ->
for ((key, value) in userAttrs) {
Expand All @@ -203,16 +228,7 @@ class RoktKit :
finalAttributes.put(ROKT_ATTRIBUTE_SANDBOX_MODE, value)
}
verifyHashedEmail(finalAttributes)
val roktConfig = mpRoktConfig?.let { mapToRoktConfig(it) }
Rokt.execute(
viewName,
finalAttributes,
this,
// Pass placeholders and fontTypefaces only if they are not empty or null
placeholders.takeIf { it?.isNotEmpty() == true },
fontTypefaces.takeIf { it?.isNotEmpty() == true },
roktConfig,
)
return finalAttributes
}

override fun events(identifier: String): Flow<com.mparticle.RoktEvent> = Rokt.events(identifier).map { event ->
Expand Down Expand Up @@ -274,6 +290,26 @@ class RoktKit :
Rokt.close()
}

override fun enrichAttributes(attributes: MutableMap<String, String>, user: FilteredMParticleUser?) {
val finalAttributes = prepareFinalAttributes(user, attributes)
deferredAttributes?.complete(finalAttributes)
}

suspend fun runComposableWithCallback(
attributes: Map<String, String>,
mpRoktEventCallback: MpRoktEventCallback?,
onResult: (Map<String, String>, RoktCallback) -> Unit,
) {
val instance = MParticle.getInstance()
deferredAttributes = CompletableDeferred()
instance?.Internal()?.kitManager?.prepareAttributesAsync(attributes)
this.mpRoktEventCallback = mpRoktEventCallback
CoroutineScope(Dispatchers.Default).launch {
val resultAttributes = deferredAttributes!!.await()
onResult(resultAttributes, this@RoktKit)
}
Comment thread
Mansi-mParticle marked this conversation as resolved.
}

private fun mapToRoktConfig(config: RoktConfig): com.rokt.roktsdk.RoktConfig {
val colorMode = when (config.colorMode) {
RoktConfig.ColorMode.LIGHT -> com.rokt.roktsdk.RoktConfig.ColorMode.LIGHT
Expand Down Expand Up @@ -367,6 +403,14 @@ class RoktKit :
}

companion object {
@Volatile
var instance: RoktKit? = null
private set

fun register(kit: RoktKit) {
instance = kit
}

const val NAME = "Rokt"
const val ROKT_ACCOUNT_ID = "accountId"
const val MPID = "mpid"
Expand Down
42 changes: 42 additions & 0 deletions src/main/kotlin/com/mparticle/kits/RoktLayout.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.mparticle.kits

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import com.mparticle.MpRoktEventCallback
import com.rokt.roktsdk.Rokt

@Composable
@Suppress("FunctionName")
fun RoktLayout(
sdkTriggered: Boolean,
viewName: String,
attributes: Map<String, String>,
location: String,
modifier: Modifier = Modifier,
mpRoktEventCallback: MpRoktEventCallback? = null,
) {
val instance = RoktKit.instance
val resultMapState = remember { mutableStateOf<RoktResult?>(null) }
if (sdkTriggered) {
LaunchedEffect(Unit) {
instance?.runComposableWithCallback(attributes, mpRoktEventCallback, { resultMap, callback ->
resultMapState.value = RoktResult(resultMap, callback)
})
}
}

resultMapState.value?.let { resultMap ->
com.rokt.roktsdk.RoktLayout(
sdkTriggered, viewName, modifier, resultMap.attributes, location,
onLoad = { resultMap.callback.onLoad() },
onShouldShowLoadingIndicator = { resultMap.callback.onShouldShowLoadingIndicator() },
onShouldHideLoadingIndicator = { resultMap.callback.onShouldHideLoadingIndicator() },
onUnload = { reason -> resultMap.callback.onUnload(reason) },
)
}
}

data class RoktResult(val attributes: Map<String, String>, val callback: Rokt.RoktCallback)
Loading