Updated on 2026-08-14

This commit is contained in:
Tangem 2023-02-17 14:58:12 +03:00
commit 978bf25e96
28 changed files with 321 additions and 61 deletions

View file

@ -60,8 +60,18 @@ sealed class AnalyticsParam {
object BlockchainSdk : Error("Blockchain Sdk Error")
}
sealed class ScannedFrom(val value: String) {
object Introduction : ScannedFrom("Introduction")
object Main : ScannedFrom("Main")
object SignIn : ScannedFrom("Sign In")
object MyWallets : ScannedFrom("My Wallets")
}
companion object Key {
const val BatchId = "Batch"
const val Batch = "Batch"
const val ProductType = "Product Type"
const val Firmware = "Firmware"
const val Currency = "Currency"
const val ErrorDescription = "Error Description"
const val ErrorCode = "Error Code"
const val ErrorKey = "Error Key"

View file

@ -11,6 +11,15 @@ sealed class Basic(
error: Throwable? = null,
) : AnalyticsEvent("Basic", event, params, error) {
class CardWasScanned(
source: AnalyticsParam.ScannedFrom,
) : Basic(
event = "Card Was Scanned",
params = mapOf(
"Source" to source.value,
),
)
class SignedIn(
state: AnalyticsParam.CardBalanceState,
currency: AnalyticsParam.CardCurrency,
@ -19,14 +28,14 @@ sealed class Basic(
event = "Signed in",
params = mapOf(
"State" to state.value,
"Currency" to currency.value,
AnalyticsParam.BatchId to batch,
AnalyticsParam.Currency to currency.value,
AnalyticsParam.Batch to batch,
),
)
class ToppedUp(currency: AnalyticsParam.CardCurrency) : Basic(
event = "Topped up",
params = mapOf("Currency" to currency.value),
params = mapOf(AnalyticsParam.Currency to currency.value),
)
class ScanError(error: Throwable) : Basic(

View file

@ -14,6 +14,5 @@ sealed class IntroductionProcess(
class ButtonTokensList : IntroductionProcess("Button - Tokens List")
class ButtonBuyCards : IntroductionProcess("Button - Buy Cards")
class ButtonScanCard : IntroductionProcess("Button - Scan Card")
class CardWasScanned : IntroductionProcess("Card Was Scanned")
class ButtonRequestSupport : IntroductionProcess("Button - Request Support")
}

View file

@ -13,7 +13,6 @@ sealed class MainScreen(
class ScreenOpened : MainScreen("Screen opened")
class ButtonScanCard : MainScreen("Button - Scan Card")
class CardWasScanned : MainScreen("Card Was Scanned")
class ButtonMyWallets : MainScreen("Button - My Wallets")
class EnableBiometrics(state: AnalyticsParam.OnOffState) : MainScreen(

View file

@ -8,7 +8,6 @@ sealed class MyWallets(
) : AnalyticsEvent("My Wallets", event, params) {
class MyWalletsScreenOpened : MyWallets(event = "My Wallets Screen Opened")
class CardWasScanned : MyWallets(event = "Card Was Scanned")
sealed class Button {
class ScanNewCard : MyWallets(event = "Button - Scan New Card")

View file

@ -51,7 +51,7 @@ sealed class Onboarding(
class ButtonBuyCrypto(currency: AnalyticsParam.CurrencyType) : Topup(
event = "Button - Buy Crypto",
params = mapOf("Currency" to currency.value),
params = mapOf(AnalyticsParam.Currency to currency.value),
)
class ButtonShowWalletAddress : Topup("Button - Show the Wallet Address")
@ -67,8 +67,10 @@ sealed class Onboarding(
class SetupFinished : Twins("Twin Setup Finished")
}
class PinScreenOpened : Onboarding("Onboarding", "PIN screen opened")
class PinCodeSet : Onboarding("Onboarding", "PIN code set")
class ButtonConnect : Onboarding("Onboarding", "Button - Connect")
class KYCScreenOpened : Onboarding("Onboarding", "KYC screen opened")
class KYCStarted : Onboarding("Onboarding", "KYC started")
class KYCInProgress : Onboarding("Onboarding", "KYC in progress")
class KYCRejected : Onboarding("Onboarding", "KYC rejected")

View file

@ -12,7 +12,6 @@ sealed class SignIn(
) : AnalyticsEvent("Sign In", event, params, error) {
class ScreenOpened : SignIn(event = "Sing In Screen Opened")
class CardWasScanned : SignIn(event = "Card Was Scanned")
class ButtonBiometricSignIn : SignIn(event = "Button - Biometric Sign In")
class ButtonCardSignIn : SignIn(event = "Button - Card Sign In")

View file

@ -1,21 +0,0 @@
package com.tangem.tap.common.analytics.paramsInterceptor
import com.tangem.core.analytics.api.ParamsInterceptor
import com.tangem.core.analytics.AnalyticsEvent
import com.tangem.tap.common.analytics.events.AnalyticsParam
/**
[REDACTED_AUTHOR]
*/
class BatchIdParamsInterceptor(
val batchId: String,
) : ParamsInterceptor {
override fun id(): String = this::class.java.simpleName
override fun canBeAppliedTo(event: AnalyticsEvent): Boolean = true
override fun intercept(params: MutableMap<String, String>) {
params[AnalyticsParam.BatchId] = batchId
}
}

View file

@ -0,0 +1,65 @@
package com.tangem.tap.common.analytics.paramsInterceptor
import com.tangem.core.analytics.AnalyticsEvent
import com.tangem.core.analytics.api.ParamsInterceptor
import com.tangem.domain.common.ProductType
import com.tangem.domain.common.ScanResponse
import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.features.demo.DemoHelper
/**
[REDACTED_AUTHOR]
*/
class CardContextInterceptor(
private val scanResponse: ScanResponse?,
) : ParamsInterceptor {
override fun id(): String = CardContextInterceptor.id()
override fun canBeAppliedTo(event: AnalyticsEvent): Boolean = true
override fun intercept(params: MutableMap<String, String>) {
scanResponse ?: return
val card = scanResponse.card
params[AnalyticsParam.Batch] = card.batchId
params[AnalyticsParam.ProductType] = getProductType(scanResponse)
params[AnalyticsParam.Firmware] = card.firmwareVersion.stringValue
ParamCardCurrencyConverter().convert(scanResponse)?.let {
params[AnalyticsParam.Currency] = it.value
}
}
private fun getProductType(scanResponse: ScanResponse): String {
return when (scanResponse.productType) {
ProductType.Note -> "Note"
ProductType.Twins -> "Twin"
ProductType.Wallet -> "Wallet"
ProductType.SaltPay -> if (scanResponse.isSaltPayVisa()) {
"Visa"
} else {
"Visa Backup"
}
ProductType.Start2Coin -> "Start2Coin"
else -> if (DemoHelper.isDemoCard(scanResponse)) {
if (DemoHelper.isTestDemoCard(scanResponse)) {
"Demo Test"
} else {
when (scanResponse.card.cardId.substring(0..1)) {
"AC" -> "Demo Wallet"
"AB" -> "Demo Note"
else -> "Demo Other"
}
}
} else {
"Other"
}
}
}
companion object {
fun id(): String = CardContextInterceptor::class.java.simpleName
}
}

View file

@ -0,0 +1,16 @@
package com.tangem.tap.common.extensions
import com.tangem.core.analytics.Analytics
import com.tangem.domain.common.ScanResponse
import com.tangem.tap.common.analytics.paramsInterceptor.CardContextInterceptor
/**
[REDACTED_AUTHOR]
*/
fun Analytics.addCardContext(scanResponse: ScanResponse) {
addParamsInterceptor(CardContextInterceptor(scanResponse))
}
fun Analytics.eraseCardContext() {
removeParamsInterceptor(CardContextInterceptor.id())
}

View file

@ -13,7 +13,7 @@ import com.tangem.domain.common.extensions.withMainContext
import com.tangem.operations.backup.BackupService
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
import com.tangem.tap.backupService
import com.tangem.tap.common.analytics.paramsInterceptor.BatchIdParamsInterceptor
import com.tangem.tap.common.extensions.addCardContext
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.primaryCardIsSaltPayVisa
import com.tangem.tap.common.redux.global.GlobalAction
@ -75,7 +75,7 @@ object ScanCardProcessor {
tangemSdkManager.changeDisplayedCardIdNumbersCount(scanResponse)
onScanStateChange(false)
sendAnalytics(analyticsEvent, scanResponse.card.batchId)
sendAnalytics(analyticsEvent, scanResponse)
checkForUnfinishedBackupForSaltPay(
backupService = backupService,
@ -103,9 +103,9 @@ object ScanCardProcessor {
private fun sendAnalytics(
analyticsEvent: AnalyticsEvent?,
batchId: String,
scanResponse: ScanResponse,
) {
Analytics.addParamsInterceptor(BatchIdParamsInterceptor(batchId))
Analytics.addCardContext(scanResponse)
analyticsEvent?.let { Analytics.send(it) }
}

View file

@ -49,6 +49,8 @@ object DemoHelper {
fun isDemoCard(scanResponse: ScanResponse): Boolean = isDemoCardId(scanResponse.card.cardId)
fun isTestDemoCard(scanResponse: ScanResponse): Boolean = config.isTestDemoCardId(scanResponse.card.cardId)
fun isDemoCardId(cardId: String): Boolean = config.isDemoCardId(cardId)
fun tryHandle(appState: () -> AppState?, action: Action): Boolean {
@ -108,6 +110,8 @@ class DemoConfig {
fun isDemoCardId(cardId: String): Boolean = demoCardIds.contains(cardId)
fun isTestDemoCardId(cardId: String): Boolean = testDemoCardIds.contains(cardId)
fun getBalance(blockchain: Blockchain): Amount = walletBalances[blockchain]?.copy()
?: Amount(BigDecimal.ZERO, blockchain).copy()
@ -117,9 +121,6 @@ class DemoConfig {
private val releaseDemoCardIds = mutableListOf(
// === Not from the Google Sheet table ===
"FB10000000000196", // Note BTC
"FB20000000000186", // Note ETH
"FB30000000000176", // Wallet
"AC01000000041225",
"AC01000000041472",
"AB01000000046498",
@ -489,17 +490,19 @@ class DemoConfig {
class DemoTransactionSender(
private val walletManager: WalletManager,
private val sender: TransactionSender = walletManager as TransactionSender
private val sender: TransactionSender = walletManager as TransactionSender,
) : TransactionSender {
override suspend fun getFee(amount: Amount, destination: String): Result<List<Amount>> {
val blockchain = walletManager.wallet.blockchain
return when (walletManager) {
is BitcoinWalletManager -> Result.Success(listOf(
Amount(0.0001.toBigDecimal(), blockchain),
Amount(0.0003.toBigDecimal(), blockchain),
Amount(0.00055.toBigDecimal(), blockchain),
))
is BitcoinWalletManager -> Result.Success(
listOf(
Amount(0.0001.toBigDecimal(), blockchain),
Amount(0.0003.toBigDecimal(), blockchain),
Amount(0.00055.toBigDecimal(), blockchain),
),
)
else -> sender.getFee(amount, destination)
}
}
@ -508,7 +511,7 @@ class DemoTransactionSender(
val dataToSign = randomString(32).toByteArray()
val signerResponse = signer.sign(
hash = dataToSign,
publicKey = walletManager.wallet.publicKey
publicKey = walletManager.wallet.publicKey,
)
return when (signerResponse) {
is CompletionResult.Success -> SimpleResult.Failure(Exception(ID).toBlockchainSdkError())
@ -529,5 +532,4 @@ class DemoTransactionSender(
companion object {
val ID = DemoTransactionSender::class.java.simpleName
}
}

View file

@ -29,7 +29,7 @@ class HomeFragment : Fragment(), StoreSubscriber<HomeState> {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Analytics.send(IntroductionProcess.ScreenOpened())
store.dispatch(HomeAction.OnCreate)
store.dispatch(HomeAction.Init)
}

View file

@ -1,16 +1,18 @@
package com.tangem.tap.features.home.redux
import com.tangem.core.analytics.AnalyticsEvent
import com.tangem.tap.common.analytics.events.IntroductionProcess
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.Basic
import com.tangem.tap.common.entities.IndeterminateProgressButton
import org.rekotlin.Action
sealed class HomeAction : Action {
object OnCreate : HomeAction()
object Init : HomeAction()
data class ReadCard(
val analyticsEvent: AnalyticsEvent? = IntroductionProcess.CardWasScanned(),
val analyticsEvent: AnalyticsEvent? = Basic.CardWasScanned(AnalyticsParam.ScannedFrom.Introduction),
) : HomeAction()
data class ScanInProgress(val scanInProgress: Boolean) : HomeAction()

View file

@ -5,10 +5,12 @@ import com.tangem.common.doOnResult
import com.tangem.common.doOnSuccess
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.AnalyticsEvent
import com.tangem.tap.common.analytics.events.IntroductionProcess
import com.tangem.tap.common.analytics.events.Shop
import com.tangem.tap.common.entities.IndeterminateProgressButton
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.dispatchOpenUrl
import com.tangem.tap.common.extensions.eraseCardContext
import com.tangem.tap.common.extensions.onCardScanned
import com.tangem.tap.common.extensions.onUserWalletSelected
import com.tangem.tap.common.redux.AppState
@ -51,6 +53,10 @@ private val homeMiddleware: Middleware<AppState> = { _, _ ->
private fun handleHomeAction(action: Action) {
when (action) {
is HomeAction.OnCreate -> {
Analytics.eraseCardContext()
Analytics.send(IntroductionProcess.ScreenOpened())
}
is HomeAction.Init -> {
store.dispatch(GlobalAction.RestoreAppCurrency)
store.dispatch(GlobalAction.ExchangeManager.Init)

View file

@ -258,6 +258,8 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
}
is OnboardingSaltPayAction.SetStep -> {
when (action.newStep) {
SaltPayActivationStep.NeedPin -> Analytics.send(Onboarding.PinScreenOpened())
SaltPayActivationStep.KycIntro -> Analytics.send(Onboarding.KYCScreenOpened())
SaltPayActivationStep.KycStart -> Analytics.send(Onboarding.KYCStarted())
SaltPayActivationStep.KycWaiting -> Analytics.send(Onboarding.KYCInProgress())
SaltPayActivationStep.KycReject -> Analytics.send(Onboarding.KYCRejected())

View file

@ -15,6 +15,7 @@ import com.tangem.operations.attestation.OnlineCardVerifier
import com.tangem.tap.common.analytics.converters.BasicEventsPreChecker
import com.tangem.tap.common.analytics.converters.BasicEventsSourceData
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.Basic
import com.tangem.tap.common.analytics.events.MainScreen
import com.tangem.tap.common.analytics.events.Token
import com.tangem.tap.common.extensions.copyToClipboard
@ -378,7 +379,7 @@ class WalletMiddleware {
}
else -> {
Analytics.send(MainScreen.ButtonScanCard())
store.dispatch(WalletAction.Scan(MainScreen.CardWasScanned()))
store.dispatch(WalletAction.Scan(Basic.CardWasScanned(AnalyticsParam.ScannedFrom.Main)))
}
}
}

View file

@ -0,0 +1,21 @@
package com.tangem.tap.features.wallet.ui.wallet.saltPay
import com.tangem.blockchain.common.TransactionData
import com.tangem.blockchain.common.TransactionStatus
import com.tangem.tap.features.wallet.models.PendingTransactionType
/**
[REDACTED_AUTHOR]
*/
data class HistoryTransactionData(
val transactionData: TransactionData,
private val walletAddress: String,
) {
fun isInProgress(): Boolean = transactionData.status == TransactionStatus.Unconfirmed
fun getTransactionType(): PendingTransactionType = when {
transactionData.sourceAddress.lowercase() == walletAddress.lowercase() -> PendingTransactionType.Outgoing
transactionData.destinationAddress.lowercase() == walletAddress.lowercase() -> PendingTransactionType.Incoming
else -> PendingTransactionType.Unknown
}
}

View file

@ -0,0 +1,33 @@
package com.tangem.tap.features.wallet.ui.wallet.saltPay.rv
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
/**
[REDACTED_AUTHOR]
*/
open class ShimmerRecyclerAdapter(
private val viewHolderViewFactory: (ViewGroup) -> ViewGroup,
) : ListAdapter<ShimmerData, ShimmerVH>(DiffUtilCallback) {
override fun getItemId(position: Int): Long {
return if (currentList.isEmpty()) 0 else currentList[position].hashCode().toLong()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ShimmerVH {
return ShimmerVH(viewHolderViewFactory.invoke(parent))
}
override fun onBindViewHolder(holder: ShimmerVH, position: Int) {}
object DiffUtilCallback : DiffUtil.ItemCallback<ShimmerData>() {
override fun areContentsTheSame(oldItem: ShimmerData, newItem: ShimmerData) = oldItem == newItem
override fun areItemsTheSame(oldItem: ShimmerData, newItem: ShimmerData) = oldItem == newItem
}
}
class ShimmerVH(viewGroup: ViewGroup) : RecyclerView.ViewHolder(viewGroup)
data class ShimmerData(private val any: String = "")

View file

@ -0,0 +1,103 @@
package com.tangem.tap.features.wallet.ui.wallet.saltPay.rv
import android.graphics.PorterDuff
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.tangem.tap.common.extensions.getColor
import com.tangem.tap.common.extensions.setDrawable
import com.tangem.tap.common.extensions.show
import com.tangem.tap.common.extensions.toFormattedCurrencyString
import com.tangem.tap.features.wallet.models.PendingTransactionType
import com.tangem.tap.features.wallet.ui.wallet.saltPay.HistoryTransactionData
import com.tangem.wallet.R
import com.tangem.wallet.databinding.ItemSaltPayTxHistoryBinding
/**
[REDACTED_AUTHOR]
*/
internal class TransactionHistoryAdapter : ListAdapter<HistoryTransactionData, TransactionItemVH>(DiffUtilCallback) {
override fun getItemId(position: Int): Long {
return if (currentList.isEmpty()) 0
else currentList[position].transactionData.hash.hashCode().toLong()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransactionItemVH {
val inflater = LayoutInflater.from(parent.context)
val layout = ItemSaltPayTxHistoryBinding.inflate(inflater, parent, false)
return TransactionItemVH(layout)
}
override fun onBindViewHolder(holder: TransactionItemVH, position: Int) {
holder.bind(currentList[position])
}
object DiffUtilCallback : DiffUtil.ItemCallback<HistoryTransactionData>() {
override fun areContentsTheSame(
oldItem: HistoryTransactionData,
newItem: HistoryTransactionData,
) = oldItem == newItem
override fun areItemsTheSame(
oldItem: HistoryTransactionData,
newItem: HistoryTransactionData,
) = oldItem == newItem
}
}
internal class TransactionItemVH(
private val binding: ItemSaltPayTxHistoryBinding,
) : RecyclerView.ViewHolder(binding.root) {
fun bind(data: HistoryTransactionData) = with(binding) {
setupImage(data)
setupTitle(data)
setupSubtitle(data)
setupBalance(data)
}
private fun setupImage(data: HistoryTransactionData) = with(binding) {
val drawable = when (data.getTransactionType()) {
PendingTransactionType.Incoming -> R.drawable.ic_tx_incoming
PendingTransactionType.Outgoing -> R.drawable.ic_tx_outgoing
PendingTransactionType.Unknown -> null
}
drawable?.let { imvTx.setDrawable(it) }
if (data.isInProgress()) {
imvTx.setColorFilter(imvTx.getColor(R.color.icon_attention), PorterDuff.Mode.MULTIPLY)
} else {
imvTx.clearColorFilter()
}
}
private fun setupTitle(data: HistoryTransactionData) = with(binding) {
val hash = data.transactionData.hash ?: return@with
val formattedHash = "${hash.substring(0..5)}...${hash.substring(hash.length - 4)}"
tvTxHash.text = formattedHash
}
private fun setupSubtitle(data: HistoryTransactionData) = with(binding) {
val inProgress = data.isInProgress()
tvTxStatus.show(inProgress)
tvTxTime.show(!inProgress)
val time = data.transactionData.date?.timeInMillis.toString() ?: "none"
tvTxTime.text = time
}
private fun setupBalance(data: HistoryTransactionData) = with(binding) {
val sign = when (data.getTransactionType()) {
PendingTransactionType.Incoming -> "+"
PendingTransactionType.Outgoing -> "-"
PendingTransactionType.Unknown -> ""
}
val amount = data.transactionData.amount
tvTxAmountSign.text = sign
tvTxAmountValue.text = amount.value?.toFormattedCurrencyString(8, amount.currencySymbol)
}
}

View file

@ -9,8 +9,10 @@ import com.tangem.common.map
import com.tangem.core.analytics.Analytics
import com.tangem.domain.common.ScanResponse
import com.tangem.domain.common.util.UserWalletId
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.Basic
import com.tangem.tap.common.analytics.events.MyWallets
import com.tangem.tap.common.analytics.paramsInterceptor.BatchIdParamsInterceptor
import com.tangem.tap.common.extensions.addCardContext
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.onUserWalletSelected
import com.tangem.tap.common.redux.AppState
@ -136,7 +138,7 @@ internal class WalletSelectorMiddleware {
)
ScanCardProcessor.scan(
analyticsEvent = MyWallets.CardWasScanned(),
analyticsEvent = Basic.CardWasScanned(AnalyticsParam.ScannedFrom.MyWallets),
onWalletNotCreated = {
// No need to rollback policy, continue with the policy set before the card scan
store.dispatchOnMain(WalletSelectorAction.AddWallet.Success)
@ -197,8 +199,7 @@ internal class WalletSelectorMiddleware {
.doOnSuccess {
val selectedUserWallet = userWalletsListManager.selectedUserWalletSync
if (selectedUserWallet != null) {
val batchId = selectedUserWallet.scanResponse.card.batchId
Analytics.addParamsInterceptor(BatchIdParamsInterceptor(batchId))
Analytics.addCardContext(selectedUserWallet.scanResponse)
store.dispatchOnMain(NavigationAction.PopBackTo(AppScreen.Wallet))
store.onUserWalletSelected(selectedUserWallet)

View file

@ -5,6 +5,7 @@ import com.tangem.common.core.TangemError
import org.rekotlin.Action
internal sealed interface WelcomeAction : Action {
object OnCreate: WelcomeAction
object ProceedWithBiometrics : WelcomeAction {
object Success : WelcomeAction
data class Error(val error: TangemError) : WelcomeAction

View file

@ -4,9 +4,14 @@ import android.content.Intent
import com.tangem.common.core.TangemSdkError
import com.tangem.common.doOnFailure
import com.tangem.common.doOnSuccess
import com.tangem.core.analytics.Analytics
import com.tangem.domain.common.ScanResponse
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.Basic
import com.tangem.tap.common.analytics.events.SignIn
import com.tangem.tap.common.extensions.addCardContext
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.eraseCardContext
import com.tangem.tap.common.extensions.onUserWalletSelected
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.navigation.AppScreen
@ -38,6 +43,10 @@ internal class WelcomeMiddleware {
private fun handleAction(action: WelcomeAction, state: WelcomeState) {
when (action) {
is WelcomeAction.OnCreate -> {
Analytics.eraseCardContext()
Analytics.send(SignIn.ScreenOpened())
}
is WelcomeAction.ProceedWithBiometrics -> {
proceedWithBiometry(state)
}
@ -62,6 +71,7 @@ internal class WelcomeMiddleware {
}
.doOnSuccess { selectedUserWallet ->
if (selectedUserWallet != null) {
Analytics.addCardContext(selectedUserWallet.scanResponse)
store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Wallet))
store.dispatchOnMain(WelcomeAction.ProceedWithBiometrics.Success)
store.onUserWalletSelected(selectedUserWallet)
@ -101,7 +111,7 @@ internal class WelcomeMiddleware {
useBiometricsForAccessCode = preferencesStorage.shouldSaveAccessCodes,
)
ScanCardProcessor.scan(
analyticsEvent = SignIn.CardWasScanned(),
analyticsEvent = Basic.CardWasScanned(AnalyticsParam.ScannedFrom.SignIn),
onSuccess = { scanResponse ->
scope.launch { onCardScanned(scanResponse) }
},

View file

@ -26,6 +26,7 @@ internal object WelcomeReducer {
is WelcomeAction.ProceedWithBiometrics.Success -> state.copy(isUnlockWithBiometricsInProgress = false)
is WelcomeAction.ProceedWithCard.Success -> state.copy(isUnlockWithCardInProgress = false)
is WelcomeAction.CloseError -> state.copy(error = null)
else -> state
}
}
}

View file

@ -19,13 +19,13 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.colorResource
import androidx.fragment.app.viewModels
import com.tangem.core.analytics.Analytics
import com.tangem.core.ui.components.SystemBarsEffect
import com.tangem.core.ui.fragments.ComposeFragment
import com.tangem.core.ui.res.TangemTheme
import com.tangem.tap.common.analytics.events.SignIn
import com.tangem.tap.features.details.ui.cardsettings.resolveReference
import com.tangem.tap.features.welcome.redux.WelcomeAction
import com.tangem.tap.features.welcome.ui.components.WelcomeScreenContent
import com.tangem.tap.store
import com.tangem.wallet.R
internal class WelcomeFragment : ComposeFragment<WelcomeScreenState>() {
@ -33,7 +33,7 @@ internal class WelcomeFragment : ComposeFragment<WelcomeScreenState>() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Analytics.send(SignIn.ScreenOpened())
store.dispatch(WelcomeAction.OnCreate)
}
@Composable

View file

@ -54,8 +54,8 @@ object Analytics : GlobalAnalyticsEventHandler {
paramsInterceptors[interceptor.id()] = interceptor
}
override fun removeParamsInterceptor(interceptor: ParamsInterceptor): ParamsInterceptor? {
return paramsInterceptors.remove(interceptor.id())
override fun removeParamsInterceptor(interceptorId: String): ParamsInterceptor? {
return paramsInterceptors.remove(interceptorId)
}
override fun send(event: AnalyticsEvent) {

View file

@ -13,5 +13,5 @@ interface ParamsInterceptor {
interface ParamsInterceptorHolder {
fun addParamsInterceptor(interceptor: ParamsInterceptor)
fun removeParamsInterceptor(interceptor: ParamsInterceptor): ParamsInterceptor?
fun removeParamsInterceptor(interceptorId: String): ParamsInterceptor?
}

View file

@ -22,5 +22,5 @@ object NetworkLogConfig {
object AnalyticsHandlersLogConfig {
val firebase: Boolean = false
val appsFlyer: Boolean = false
val amplitude: Boolean = false
val amplitude: Boolean = true
}