From a21442e59b4ff102a1a6db754ea8f16e18bc4437 Mon Sep 17 00:00:00 2001 From: RyosukeCla Date: Tue, 4 Jun 2024 20:18:55 +0900 Subject: [PATCH 1/3] [android] Add retention property to NativebrikUser class --- .../src/main/java/com/nativebrik/sdk/data/user/user.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/android/nativebrik/src/main/java/com/nativebrik/sdk/data/user/user.kt b/android/nativebrik/src/main/java/com/nativebrik/sdk/data/user/user.kt index 15f6d3c..4463ef4 100644 --- a/android/nativebrik/src/main/java/com/nativebrik/sdk/data/user/user.kt +++ b/android/nativebrik/src/main/java/com/nativebrik/sdk/data/user/user.kt @@ -59,6 +59,11 @@ class NativebrikUser { return this.properties[BuiltinUserProperty.userId.toString()] ?: "" } + val retention: Int + get() { + return (this.properties[BuiltinUserProperty.retentionPeriod.toString()] ?: "0").toInt() + } + internal constructor(context: Context, seed: Int? = null) { this.preferences = getNativebrikUserSharedPreferences(context) From e732ee210f72e696ebf45849179cb74462874c32 Mon Sep 17 00:00:00 2001 From: RyosukeCla Date: Tue, 4 Jun 2024 20:19:09 +0900 Subject: [PATCH 2/3] [android] Add user event dispatching in TriggerViewModel --- .../com/nativebrik/sdk/component/trigger.kt | 85 ++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/android/nativebrik/src/main/java/com/nativebrik/sdk/component/trigger.kt b/android/nativebrik/src/main/java/com/nativebrik/sdk/component/trigger.kt index 06b0e04..994f432 100644 --- a/android/nativebrik/src/main/java/com/nativebrik/sdk/component/trigger.kt +++ b/android/nativebrik/src/main/java/com/nativebrik/sdk/component/trigger.kt @@ -1,11 +1,21 @@ package com.nativebrik.sdk.component +import android.util.Log import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalLifecycleOwner +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.ViewModel import com.nativebrik.sdk.NativebrikEvent import com.nativebrik.sdk.data.Container +import com.nativebrik.sdk.data.user.NativebrikUser +import com.nativebrik.sdk.data.user.getNativebrikUserSharedPreferences import com.nativebrik.sdk.schema.TriggerEventNameDefs import com.nativebrik.sdk.schema.UIBlock import com.nativebrik.sdk.schema.UIRootBlock @@ -14,17 +24,52 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch -internal class TriggerViewModel(internal val container: Container) : ViewModel() { +internal class TriggerViewModel(internal val container: Container, internal val user: NativebrikUser) : ViewModel() { + private val ignoreFirstUserEventToForegroundEvent = mutableStateOf(true) internal val modalStacks = mutableStateListOf() + internal fun ignoreFirstCall(): Boolean { + return if (this.ignoreFirstUserEventToForegroundEvent.value) { + this.ignoreFirstUserEventToForegroundEvent.value = false + true + } else { + false + } + } + + internal fun callWhenUserComesBack() { + this.user.comeBack() + + // dispatch the event when every time the user is activated + this.dispatch(NativebrikEvent(TriggerEventNameDefs.USER_ENTER_TO_APP.name)) + + val retention = this.user.retention + if (retention == 1) { + this.dispatch(NativebrikEvent(TriggerEventNameDefs.RETENTION_1.name)) + } else if (retention in 2..3) { + this.dispatch(NativebrikEvent(TriggerEventNameDefs.RETENTION_2_3.name)) + } else if (retention in 4..7) { + this.dispatch(NativebrikEvent(TriggerEventNameDefs.RETENTION_4_7.name)) + } else if (retention in 8..14) { + this.dispatch(NativebrikEvent(TriggerEventNameDefs.RETENTION_8_14.name)) + } else if (retention > 14) { + this.dispatch(NativebrikEvent(TriggerEventNameDefs.RETENTION_15.name)) + } + } + @OptIn(DelicateCoroutinesApi::class) fun dispatch(event: NativebrikEvent) { + Log.d("[DATADOG]", event.name) val self = this GlobalScope.launch(Dispatchers.IO) { self.container.fetchInAppMessage(event.name).onSuccess { GlobalScope.launch(Dispatchers.Main) { if (it is UIBlock.UnionUIRootBlock) { - self.modalStacks.add(it.data) + if (self.modalStacks.indexOfFirst { stack -> + stack.id == it.data.id + } < 0) { + self.modalStacks.add(it.data) + } } } } @@ -41,8 +86,44 @@ internal class TriggerViewModel(internal val container: Container) : ViewModel() @Composable internal fun Trigger(trigger: TriggerViewModel) { + val context = LocalContext.current LaunchedEffect("") { + // dispatch user boot trigger.dispatch(NativebrikEvent(TriggerEventNameDefs.USER_BOOT_APP.name)) + + // dispatch the first time visit + val preferences = getNativebrikUserSharedPreferences(context) + val countKey = "NATIVEBRIK_SDK_INITIALIZED_COUNT" + val count: Int = preferences?.getInt(countKey, 0) ?: 0 + preferences?.edit()?.putInt(countKey, count + 1)?.apply() + if (count == 0) { + trigger.dispatch(NativebrikEvent(TriggerEventNameDefs.USER_ENTER_TO_APP_FIRSTLY.name)) + } + + trigger.callWhenUserComesBack() + } + + val lifecycleOwner = LocalLifecycleOwner.current + val observer = remember { + LifecycleEventObserver { _, event -> + when (event) { + Lifecycle.Event.ON_START -> { + if (trigger.ignoreFirstCall()) { + return@LifecycleEventObserver + } + trigger.dispatch(NativebrikEvent(TriggerEventNameDefs.USER_ENTER_TO_FOREGROUND.name)) + trigger.callWhenUserComesBack() + } + else -> {} + } + } + } + DisposableEffect(lifecycleOwner) { + val lifecycle = lifecycleOwner.lifecycle + lifecycle.addObserver(observer) + onDispose { + lifecycle.removeObserver(observer) + } } if (trigger.modalStacks.isNotEmpty()) { From f4afb77f89685cc34f5d1356d8f327b6c5b9d52a Mon Sep 17 00:00:00 2001 From: RyosukeCla Date: Tue, 4 Jun 2024 20:19:27 +0900 Subject: [PATCH 3/3] [android] Update TriggerViewModel constructor to include user parameter --- android/nativebrik/src/main/java/com/nativebrik/sdk/sdk.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/nativebrik/src/main/java/com/nativebrik/sdk/sdk.kt b/android/nativebrik/src/main/java/com/nativebrik/sdk/sdk.kt index 92e6592..d5fed3d 100644 --- a/android/nativebrik/src/main/java/com/nativebrik/sdk/sdk.kt +++ b/android/nativebrik/src/main/java/com/nativebrik/sdk/sdk.kt @@ -128,7 +128,7 @@ public class NativebrikExperiment { db = db, context = context, ) - this.trigger = TriggerViewModel(this.container) + this.trigger = TriggerViewModel(this.container, user) } public fun dispatch(event: NativebrikEvent) {