Updated on 2026-08-14
This commit is contained in:
parent
cdebec35d0
commit
64de5b2599
7 changed files with 105 additions and 2 deletions
|
|
@ -48,6 +48,7 @@ android {
|
|||
|
||||
dependencies {
|
||||
/** Core modules */
|
||||
implementation(project(":core:analytics"))
|
||||
implementation(project(":core:res"))
|
||||
implementation(project(":core:utils"))
|
||||
implementation(project(":core:ui"))
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ class ReferralFragment : Fragment() {
|
|||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
activity?.window?.let { WindowCompat.setDecorFitsSystemWindows(it, true) }
|
||||
viewModel.setRouter(ReferralRouter(fragmentManager = WeakReference(parentFragmentManager)))
|
||||
viewModel.onScreenOpened()
|
||||
return ComposeView(inflater.context).apply {
|
||||
isTransitionGroup = true
|
||||
setContent {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.feature.referral.analytics
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
|
||||
sealed class ReferralEvents(
|
||||
event: String,
|
||||
) : AnalyticsEvent(REFERRAL_PROGRAM_CATEGORY, event) {
|
||||
|
||||
object ReferralScreenOpened : ReferralEvents(event = "Referral Screen Opened")
|
||||
object ClickParticipate : ReferralEvents(event = "Button - Participate")
|
||||
object ClickCopy : ReferralEvents(event = "Button - Copy")
|
||||
object ClickShare : ReferralEvents(event = "Button - Share")
|
||||
object ClickTaC : ReferralEvents(event = "Link - TaC")
|
||||
}
|
||||
|
||||
private const val REFERRAL_PROGRAM_CATEGORY = "Referral program"
|
||||
|
|
@ -4,6 +4,7 @@ internal data class ReferralStateHolder(
|
|||
val headerState: HeaderState,
|
||||
val referralInfoState: ReferralInfoState,
|
||||
val errorSnackbar: ErrorSnackbar? = null,
|
||||
val analytics: Analytics,
|
||||
) {
|
||||
|
||||
data class HeaderState(val onBackClicked: () -> Unit)
|
||||
|
|
@ -42,4 +43,10 @@ internal data class ReferralStateHolder(
|
|||
val throwable: Throwable,
|
||||
val onOkClicked: () -> Unit,
|
||||
)
|
||||
|
||||
data class Analytics(
|
||||
val onAgreementClicked: () -> Unit,
|
||||
val onCopyClicked: () -> Unit,
|
||||
val onShareClicked: () -> Unit,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ internal fun ParticipateBottomBlock(
|
|||
shareLink: String,
|
||||
onAgreementClicked: () -> Unit,
|
||||
showCopySnackbar: () -> Unit,
|
||||
onCopyClicked: () -> Unit,
|
||||
onShareClicked: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
|
@ -56,7 +58,13 @@ internal fun ParticipateBottomBlock(
|
|||
),
|
||||
)
|
||||
PersonalCodeCard(code = code)
|
||||
AdditionalButtons(code = code, shareLink = shareLink, showCopySnackbar = showCopySnackbar)
|
||||
AdditionalButtons(
|
||||
code = code,
|
||||
shareLink = shareLink,
|
||||
showCopySnackbar = showCopySnackbar,
|
||||
onCopyClicked = onCopyClicked,
|
||||
onShareClicked = onShareClicked,
|
||||
)
|
||||
AgreementText(firstPartResId = R.string.referral_tos_enroled_prefix, onClicked = onAgreementClicked)
|
||||
}
|
||||
}
|
||||
|
|
@ -94,7 +102,13 @@ private fun PersonalCodeCard(code: String) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun AdditionalButtons(code: String, shareLink: String, showCopySnackbar: () -> Unit) {
|
||||
private fun AdditionalButtons(
|
||||
code: String,
|
||||
shareLink: String,
|
||||
showCopySnackbar: () -> Unit,
|
||||
onCopyClicked: () -> Unit,
|
||||
onShareClicked: () -> Unit,
|
||||
) {
|
||||
val clipboardManager = LocalClipboardManager.current
|
||||
val hapticFeedback = LocalHapticFeedback.current
|
||||
|
||||
|
|
@ -107,6 +121,7 @@ private fun AdditionalButtons(code: String, shareLink: String, showCopySnackbar:
|
|||
text = stringResource(id = R.string.common_copy),
|
||||
iconResId = R.drawable.ic_copy,
|
||||
onClicked = {
|
||||
onCopyClicked.invoke()
|
||||
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
clipboardManager.setText(AnnotatedString(code))
|
||||
showCopySnackbar()
|
||||
|
|
@ -119,6 +134,7 @@ private fun AdditionalButtons(code: String, shareLink: String, showCopySnackbar:
|
|||
text = stringResource(id = R.string.common_share),
|
||||
iconResId = R.drawable.ic_share,
|
||||
onClicked = {
|
||||
onShareClicked.invoke()
|
||||
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
context.shareText(context.getString(R.string.referral_share_link, shareLink))
|
||||
},
|
||||
|
|
@ -147,6 +163,8 @@ fun Preview_ParticipateBottomBlock_InLightTheme() {
|
|||
shareLink = "",
|
||||
onAgreementClicked = {},
|
||||
showCopySnackbar = {},
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -163,6 +181,8 @@ fun Preview_ParticipateBottomBlock_InDarkTheme() {
|
|||
shareLink = "",
|
||||
onAgreementClicked = {},
|
||||
showCopySnackbar = {},
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ internal fun ReferralScreen(stateHolder: ReferralStateHolder) {
|
|||
ReferralContent(
|
||||
stateHolder = stateHolder,
|
||||
onAgreementClicked = {
|
||||
stateHolder.analytics.onAgreementClicked.invoke()
|
||||
coroutineScope.launch {
|
||||
if (bottomSheetScaffoldState.bottomSheetState.isCollapsed) {
|
||||
bottomSheetScaffoldState.bottomSheetState.expand()
|
||||
|
|
@ -191,6 +192,8 @@ private fun ReferralInfo(
|
|||
shareLink = state.shareLink,
|
||||
onAgreementClicked = onAgreementClicked,
|
||||
showCopySnackbar = showCopySnackbar,
|
||||
onCopyClicked = stateHolder.analytics.onCopyClicked,
|
||||
onShareClicked = stateHolder.analytics.onShareClicked,
|
||||
)
|
||||
}
|
||||
is ReferralInfoState.NonParticipantContent -> {
|
||||
|
|
@ -479,6 +482,11 @@ fun Preview_ReferralScreen_Participant_InLightTheme() {
|
|||
url = "",
|
||||
),
|
||||
errorSnackbar = null,
|
||||
analytics = ReferralStateHolder.Analytics(
|
||||
onAgreementClicked = {},
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -502,6 +510,11 @@ fun Preview_ReferralScreen_Participant_InDarkTheme() {
|
|||
url = "",
|
||||
),
|
||||
errorSnackbar = null,
|
||||
analytics = ReferralStateHolder.Analytics(
|
||||
onAgreementClicked = {},
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -522,6 +535,11 @@ fun Preview_ReferralScreen_NonParticipant_InLightTheme() {
|
|||
onParticipateClicked = {},
|
||||
),
|
||||
errorSnackbar = null,
|
||||
analytics = ReferralStateHolder.Analytics(
|
||||
onAgreementClicked = {},
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -542,6 +560,11 @@ fun Preview_ReferralScreen_NonParticipant_InDarkTheme() {
|
|||
onParticipateClicked = {},
|
||||
),
|
||||
errorSnackbar = null,
|
||||
analytics = ReferralStateHolder.Analytics(
|
||||
onAgreementClicked = {},
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -556,6 +579,11 @@ fun Preview_ReferralScreen_Loading_InLightTheme() {
|
|||
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
|
||||
referralInfoState = ReferralInfoState.Loading,
|
||||
errorSnackbar = null,
|
||||
analytics = ReferralStateHolder.Analytics(
|
||||
onAgreementClicked = {},
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -570,6 +598,11 @@ fun Preview_ReferralScreen_Loading_InDarkTheme() {
|
|||
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
|
||||
referralInfoState = ReferralInfoState.Loading,
|
||||
errorSnackbar = null,
|
||||
analytics = ReferralStateHolder.Analytics(
|
||||
onAgreementClicked = {},
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.feature.referral.analytics.ReferralEvents
|
||||
import com.tangem.feature.referral.domain.ReferralInteractor
|
||||
import com.tangem.feature.referral.domain.models.DiscountType
|
||||
import com.tangem.feature.referral.domain.models.ReferralData
|
||||
|
|
@ -24,6 +26,7 @@ import kotlin.properties.Delegates
|
|||
internal class ReferralViewModel @Inject constructor(
|
||||
private val referralInteractor: ReferralInteractor,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
) : ViewModel() {
|
||||
|
||||
var uiState: ReferralStateHolder by mutableStateOf(createInitiallyUiState())
|
||||
|
|
@ -40,10 +43,19 @@ internal class ReferralViewModel @Inject constructor(
|
|||
uiState = uiState.copy(headerState = ReferralStateHolder.HeaderState(onBackClicked = router::back))
|
||||
}
|
||||
|
||||
fun onScreenOpened() {
|
||||
analyticsEventHandler.send(ReferralEvents.ReferralScreenOpened)
|
||||
}
|
||||
|
||||
private fun createInitiallyUiState() = ReferralStateHolder(
|
||||
headerState = ReferralStateHolder.HeaderState(onBackClicked = { }),
|
||||
referralInfoState = ReferralInfoState.Loading,
|
||||
errorSnackbar = null,
|
||||
analytics = ReferralStateHolder.Analytics(
|
||||
onAgreementClicked = ::onAgreementClicked,
|
||||
onCopyClicked = ::onCopyClicked,
|
||||
onShareClicked = ::onShareClicked,
|
||||
),
|
||||
)
|
||||
|
||||
private fun loadReferralData() {
|
||||
|
|
@ -56,6 +68,7 @@ internal class ReferralViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun participate() {
|
||||
analyticsEventHandler.send(ReferralEvents.ClickParticipate)
|
||||
uiState = uiState.copy(referralInfoState = ReferralInfoState.Loading)
|
||||
viewModelScope.launch(dispatchers.main) {
|
||||
runCatching(dispatchers.io) { referralInteractor.startReferral() }
|
||||
|
|
@ -74,6 +87,18 @@ internal class ReferralViewModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun onAgreementClicked() {
|
||||
analyticsEventHandler.send(ReferralEvents.ClickTaC)
|
||||
}
|
||||
|
||||
private fun onCopyClicked() {
|
||||
analyticsEventHandler.send(ReferralEvents.ClickCopy)
|
||||
}
|
||||
|
||||
private fun onShareClicked() {
|
||||
analyticsEventHandler.send(ReferralEvents.ClickShare)
|
||||
}
|
||||
|
||||
private fun ReferralData.convertToReferralInfoState(): ReferralInfoState = when (this) {
|
||||
is ReferralData.ParticipantData -> ReferralInfoState.ParticipantContent(
|
||||
award = getAwardValue(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue