Updated on 2026-08-14
This commit is contained in:
parent
f24a92f859
commit
9b6cb2f235
29 changed files with 195 additions and 119 deletions
|
|
@ -22,7 +22,6 @@ import com.tangem.domain.common.LogConfig
|
|||
import com.tangem.tap.common.IntentHandler
|
||||
import com.tangem.tap.common.analytics.AnalyticsFactory
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
import com.tangem.tap.common.analytics.filters.BasicSignInFilter
|
||||
import com.tangem.tap.common.analytics.filters.BasicTopUpFilter
|
||||
import com.tangem.tap.common.analytics.handlers.amplitude.AmplitudeAnalyticsHandler
|
||||
import com.tangem.tap.common.analytics.handlers.appsFlyer.AppsFlyerAnalyticsHandler
|
||||
|
|
@ -187,7 +186,6 @@ class TapApplication : Application(), ImageLoaderFactory {
|
|||
factory.addHandlerBuilder(AppsFlyerAnalyticsHandler.Builder())
|
||||
factory.addHandlerBuilder(FirebaseAnalyticsHandler.Builder())
|
||||
|
||||
factory.addFilter(BasicSignInFilter())
|
||||
factory.addFilter(BasicTopUpFilter(preferencesStorage.toppedUpWalletStorage))
|
||||
|
||||
val buildData = AnalyticsHandlerBuilder.Data(
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ class BasicEventsPreChecker {
|
|||
fun tryToSend(converterData: BasicEventsSourceData) {
|
||||
if (!isReadyToSend(converterData)) return
|
||||
|
||||
BasicSignInEventConverter().convert(converterData)?.let { Analytics.send(it) }
|
||||
BasicTopUpEventConverter().convert(converterData)?.let { Analytics.send(it) }
|
||||
}
|
||||
|
||||
|
|
@ -99,12 +98,8 @@ data class BasicEventsSourceData(
|
|||
val walletState: WalletState,
|
||||
val biometricsWalletDataModels: List<WalletDataModel>?,
|
||||
) {
|
||||
val batchId: String by lazy { scanResponse.card.batchId }
|
||||
|
||||
val userWalletIdStringValue: String? by lazy {
|
||||
UserWalletIdBuilder.scanResponse(scanResponse)
|
||||
.build()
|
||||
?.stringValue
|
||||
UserWalletIdBuilder.scanResponse(scanResponse).build()?.stringValue
|
||||
}
|
||||
|
||||
val paramCardCurrency: AnalyticsParam.CardCurrency? by lazy {
|
||||
|
|
@ -164,21 +159,6 @@ private class BalanceCalculator(
|
|||
}
|
||||
}
|
||||
|
||||
class BasicSignInEventConverter : Converter<BasicEventsSourceData, Basic.SignedIn?> {
|
||||
|
||||
override fun convert(value: BasicEventsSourceData): Basic.SignedIn? {
|
||||
if (value.paramCardCurrency == null || value.userWalletIdStringValue == null) return null
|
||||
|
||||
return Basic.SignedIn(
|
||||
state = value.paramCardBalanceState,
|
||||
currency = value.paramCardCurrency!!,
|
||||
batch = value.batchId,
|
||||
).apply {
|
||||
filterData = value.userWalletIdStringValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BasicTopUpEventConverter : Converter<BasicEventsSourceData, Basic.ToppedUp?> {
|
||||
|
||||
override fun convert(value: BasicEventsSourceData): Basic.ToppedUp? {
|
||||
|
|
|
|||
|
|
@ -21,17 +21,21 @@ sealed class Basic(
|
|||
)
|
||||
|
||||
class SignedIn(
|
||||
state: AnalyticsParam.CardBalanceState,
|
||||
currency: AnalyticsParam.CardCurrency,
|
||||
batch: String,
|
||||
signInType: SignInType,
|
||||
) : Basic(
|
||||
event = "Signed in",
|
||||
params = mapOf(
|
||||
"State" to state.value,
|
||||
AnalyticsParam.Currency to currency.value,
|
||||
AnalyticsParam.Batch to batch,
|
||||
"Sign in type" to signInType.name,
|
||||
),
|
||||
)
|
||||
) {
|
||||
enum class SignInType {
|
||||
Card, Biometric
|
||||
}
|
||||
}
|
||||
|
||||
class ToppedUp(currency: AnalyticsParam.CardCurrency) : Basic(
|
||||
event = "Topped up",
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ sealed class Settings(
|
|||
sealed class AppSettings(
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
) : Settings("Settings / App Settings", event, params) {
|
||||
) : Settings(category = "Settings / App Settings", event = event, params = params) {
|
||||
|
||||
class SaveWalletSwitcherChanged(state: AnalyticsParam.OnOffState) : CardSettings(
|
||||
event = "Save Wallet Switcher Changed",
|
||||
|
|
|
|||
|
|
@ -52,6 +52,11 @@ sealed class Token(
|
|||
params = mapOf("Token" to type.value),
|
||||
)
|
||||
|
||||
object ShowWalletAddress : Token(
|
||||
category = "Token",
|
||||
event = "Button - Show the Wallet Address"
|
||||
)
|
||||
|
||||
sealed class Receive(
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
package com.tangem.tap.common.analytics.filters
|
||||
|
||||
import com.tangem.core.analytics.api.AnalyticsEventFilter
|
||||
import com.tangem.core.analytics.api.AnalyticsHandler
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.events.Basic
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class BasicSignInFilter : AnalyticsEventFilter {
|
||||
|
||||
private val alreadySignedIn = mutableSetOf<String>()
|
||||
|
||||
override fun canBeAppliedTo(event: AnalyticsEvent): Boolean = event is Basic.SignedIn
|
||||
|
||||
override fun canBeSent(event: AnalyticsEvent): Boolean {
|
||||
val userWalletId = event.filterData as? String ?: return false
|
||||
|
||||
val canBeSent = !alreadySignedIn.contains(userWalletId)
|
||||
alreadySignedIn.add(userWalletId)
|
||||
|
||||
return canBeSent
|
||||
}
|
||||
|
||||
override fun canBeConsumedByHandler(handler: AnalyticsHandler, event: AnalyticsEvent): Boolean = true
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWallet
|
|||
import com.tangem.tap.features.saveWallet.redux.SaveWalletReducer
|
||||
import com.tangem.tap.features.send.redux.reducers.SendScreenReducer
|
||||
import com.tangem.tap.features.shop.redux.ShopReducer
|
||||
import com.tangem.tap.features.signin.redux.SignInReducer
|
||||
import com.tangem.tap.features.sprinklr.redux.SprinklrReducer
|
||||
import com.tangem.tap.features.tokens.redux.TokensReducer
|
||||
import com.tangem.tap.features.wallet.redux.reducers.WalletReducer
|
||||
|
|
@ -44,6 +45,7 @@ fun appReducer(action: Action, state: AppState?, appStateHolder: AppStateHolder)
|
|||
saveWalletState = SaveWalletReducer.reduce(action, state),
|
||||
walletSelectorState = WalletSelectorReducer.reduce(action, state),
|
||||
sprinklrState = SprinklrReducer.reduce(action, state),
|
||||
signInState = SignInReducer.reduce(action, state),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ import com.tangem.tap.features.send.redux.middlewares.SendMiddleware
|
|||
import com.tangem.tap.features.send.redux.states.SendState
|
||||
import com.tangem.tap.features.shop.redux.ShopMiddleware
|
||||
import com.tangem.tap.features.shop.redux.ShopState
|
||||
import com.tangem.tap.features.signin.redux.SignInMiddleware
|
||||
import com.tangem.tap.features.signin.redux.SignInState
|
||||
import com.tangem.tap.features.sprinklr.redux.SprinklrMiddleware
|
||||
import com.tangem.tap.features.sprinklr.redux.SprinklrState
|
||||
import com.tangem.tap.features.tokens.redux.TokensMiddleware
|
||||
|
|
@ -64,6 +66,7 @@ data class AppState(
|
|||
val saveWalletState: SaveWalletState = SaveWalletState(),
|
||||
val walletSelectorState: WalletSelectorState = WalletSelectorState(),
|
||||
val sprinklrState: SprinklrState = SprinklrState(),
|
||||
val signInState: SignInState = SignInState()
|
||||
) : StateType {
|
||||
|
||||
val domainState: DomainState
|
||||
|
|
@ -105,6 +108,7 @@ data class AppState(
|
|||
LockUserWalletsTimerMiddleware().middleware,
|
||||
AccessCodeRequestPolicyMiddleware().middleware,
|
||||
SprinklrMiddleware().middleware,
|
||||
SignInMiddleware.middleware
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.common.doOnSuccess
|
|||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.tap.common.analytics.events.Basic
|
||||
import com.tangem.tap.common.analytics.events.IntroductionProcess
|
||||
import com.tangem.tap.common.analytics.events.Shop
|
||||
import com.tangem.tap.common.entities.IndeterminateProgressButton
|
||||
|
|
@ -23,6 +24,7 @@ import com.tangem.tap.features.home.BELARUS_COUNTRY_CODE
|
|||
import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
|
||||
import com.tangem.tap.features.home.redux.HomeMiddleware.BUY_WALLET_URL
|
||||
import com.tangem.tap.features.send.redux.states.ButtonState
|
||||
import com.tangem.tap.features.signin.redux.SignInAction
|
||||
import com.tangem.tap.preferencesStorage
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
|
|
@ -112,9 +114,10 @@ fun proceedWithScanResponse(scanResponse: ScanResponse) {
|
|||
Timber.e(error, "Unable to save user wallet")
|
||||
}
|
||||
.doOnSuccess {
|
||||
scope.launch { store.onUserWalletSelected(userWallet) }
|
||||
scope.launch { store.onUserWalletSelected(userWallet = userWallet) }
|
||||
}
|
||||
.doOnResult {
|
||||
store.dispatchOnMain(SignInAction.SetSignInType(Basic.SignedIn.SignInType.Card))
|
||||
navigateTo(AppScreen.Wallet)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.core.analytics.Analytics
|
|||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.Basic
|
||||
import com.tangem.tap.common.analytics.events.Onboarding
|
||||
import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
|
||||
import com.tangem.tap.common.extensions.dispatchDialogShow
|
||||
|
|
@ -159,6 +160,15 @@ private fun handleNoteAction(appState: () -> AppState?, action: Action, dispatch
|
|||
}
|
||||
is OnboardingNoteAction.Balance.Set -> {
|
||||
if (action.balance.balanceIsToppedUp()) {
|
||||
Analytics.send(
|
||||
event = Basic.ToppedUp(
|
||||
currency = AnalyticsParam.CardCurrency.SingleCurrency(
|
||||
type = AnalyticsParam.CurrencyType.Blockchain(
|
||||
blockchain = scanResponse.cardTypesResolver.getBlockchain(),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
store.dispatch(OnboardingNoteAction.SetStepOfScreen(OnboardingNoteStep.Done))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.tangem.domain.common.ScanResponse
|
|||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.Basic
|
||||
import com.tangem.tap.common.analytics.events.Onboarding
|
||||
import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
|
||||
import com.tangem.tap.common.extensions.dispatchDialogShow
|
||||
|
|
@ -261,6 +262,15 @@ private fun handle(action: Action, dispatch: DispatchFunction) {
|
|||
}
|
||||
is TwinCardsAction.Balance.Set -> {
|
||||
if (action.balance.balanceIsToppedUp()) {
|
||||
Analytics.send(
|
||||
event = Basic.ToppedUp(
|
||||
currency = AnalyticsParam.CardCurrency.SingleCurrency(
|
||||
type = AnalyticsParam.CurrencyType.Blockchain(
|
||||
blockchain = getScanResponse().cardTypesResolver.getBlockchain(),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
scope.launch {
|
||||
withMainContext { store.dispatch(TwinCardsAction.SetStepOfScreen(TwinCardsStep.Done)) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.redux
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import org.rekotlin.Action
|
||||
|
||||
|
|
@ -22,10 +21,9 @@ sealed class OnboardingWalletAction : Action {
|
|||
|
||||
sealed class BackupAction : Action {
|
||||
|
||||
object DetermineBackupStep : BackupAction()
|
||||
object IntroduceBackup : BackupAction()
|
||||
object StartBackup : BackupAction()
|
||||
object DismissBackup : BackupAction()
|
||||
object SkipBackup : BackupAction()
|
||||
|
||||
object StartAddingPrimaryCard : BackupAction()
|
||||
object ScanPrimaryCard : BackupAction()
|
||||
|
|
@ -41,13 +39,6 @@ sealed class BackupAction : Action {
|
|||
object Success : BackupAction()
|
||||
}
|
||||
|
||||
data class LoadBackupCardArtwork(
|
||||
val cardId: CardId,
|
||||
val cardPublicKey: ByteArray,
|
||||
) : BackupAction() {
|
||||
data class Success(val cardId: CardId, val artwork: Bitmap)
|
||||
}
|
||||
|
||||
object FinishAddingBackupCards : BackupAction()
|
||||
|
||||
object ShowAccessCodeInfoScreen : BackupAction()
|
||||
|
|
@ -55,7 +46,6 @@ sealed class BackupAction : Action {
|
|||
data class CheckAccessCode(val accessCode: String) : BackupAction()
|
||||
data class SetAccessCodeError(val error: AccessCodeError?) : BackupAction()
|
||||
data class SaveFirstAccessCode(val accessCode: String) : BackupAction()
|
||||
object ShowReenterAccessCodeScreen : BackupAction()
|
||||
data class SaveAccessCodeConfirmation(val accessCodeConfirmation: String) : BackupAction()
|
||||
object OnAccessCodeDialogClosed : BackupAction()
|
||||
|
||||
|
|
|
|||
|
|
@ -329,15 +329,6 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
|
|||
}
|
||||
}
|
||||
}
|
||||
is BackupAction.FinishBackup -> {
|
||||
if (action.withAnalytics) {
|
||||
Analytics.send(Onboarding.Backup.Finished(backupState.backupCardsNumber))
|
||||
}
|
||||
if (!onboardingWalletState.isSaltPay) {
|
||||
Analytics.send(Onboarding.Finished())
|
||||
finishCardActivation(backupState, card)
|
||||
}
|
||||
}
|
||||
is BackupAction.DiscardBackup -> {
|
||||
backupService.discardSavedBackup()
|
||||
}
|
||||
|
|
@ -362,15 +353,36 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
|
|||
)
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.OnboardingWallet))
|
||||
}
|
||||
is BackupAction.DismissBackup -> {
|
||||
is BackupAction.SkipBackup -> {
|
||||
Analytics.send(Onboarding.Backup.Skipped())
|
||||
if (onboardingWalletState.isSaltPay) throw UnsupportedOperationException()
|
||||
store.dispatch(BackupAction.FinishBackup())
|
||||
if (onboardingWalletState.isSaltPay) return
|
||||
|
||||
Analytics.send(Onboarding.Finished())
|
||||
finishCardActivation(gatherCardIds(backupState, card))
|
||||
}
|
||||
is BackupAction.FinishBackup -> {
|
||||
if (action.withAnalytics) {
|
||||
Analytics.send(Onboarding.Backup.Finished(backupState.backupCardsNumber))
|
||||
}
|
||||
if (onboardingWalletState.isSaltPay) return
|
||||
|
||||
val notActivatedCardIds = gatherCardIds(backupState, card)
|
||||
.mapNotNull { if (cardActivationIsFinished(it)) null else it }
|
||||
|
||||
// All cardIds may already be activated if the backup was skipped before.
|
||||
if (notActivatedCardIds.isEmpty()) return
|
||||
|
||||
Analytics.send(Onboarding.Finished())
|
||||
finishCardActivation(notActivatedCardIds)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
private fun cardActivationIsFinished(cardId: String): Boolean {
|
||||
return preferencesStorage.usedCardsPrefStorage.isActivationFinished(cardId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Wallet cards start activation at OnboardingWalletAction.CreateWallet
|
||||
* SaltPay cards start activation at OnboardingWalletAction.StartSaltPayCardActivation
|
||||
|
|
@ -380,16 +392,19 @@ private fun startCardActivation(scanResponse: ScanResponse) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Standard Wallet cards finish activation at BackupAction.FinishBackup
|
||||
* Standard Wallet cards finish activation at BackupAction.SkipBackup and BackupAction.FinishBackup
|
||||
* SaltPay cards finish activation at OnboardingWalletAction.FinishOnboarding
|
||||
*/
|
||||
internal fun finishCardActivation(backupState: BackupState, card: CardDTO?) {
|
||||
(listOf(backupState.primaryCardId, card?.cardId) + backupState.backupCardIds)
|
||||
.distinct()
|
||||
internal fun finishCardActivation(cardIds: List<String>) {
|
||||
cardIds.forEach { cardId ->
|
||||
preferencesStorage.usedCardsPrefStorage.activationFinished(cardId)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun gatherCardIds(backupState: BackupState, card: CardDTO?): List<String> {
|
||||
return (listOf(backupState.primaryCardId, card?.cardId) + backupState.backupCardIds)
|
||||
.filterNotNull()
|
||||
.forEach { cardId ->
|
||||
preferencesStorage.usedCardsPrefStorage.activationFinished(cardId)
|
||||
}
|
||||
.distinct()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -415,7 +430,8 @@ private fun initSaltPayOnBackupFinishedIfNeeded(
|
|||
card = scanResponse.card,
|
||||
).create()
|
||||
store.dispatchOnMain(OnboardingSaltPayAction.SetDependencies(manager))
|
||||
store.dispatchOnMain(OnboardingSaltPayAction.Update(false))
|
||||
store.dispatchOnMain(OnboardingSaltPayAction.Update(withAnalytics = false))
|
||||
store.dispatchOnMain(OnboardingSaltPayAction.OnSwitchedToSaltPayProcess)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ private object BackupReducer {
|
|||
} else {
|
||||
state.copy(backupStep = BackupStep.WriteBackupCard(action.cardNumber))
|
||||
}
|
||||
is BackupAction.SkipBackup -> state.copy(backupStep = BackupStep.Finished)
|
||||
is BackupAction.FinishBackup -> state.copy(backupStep = BackupStep.Finished)
|
||||
BackupAction.OnAccessCodeDialogClosed -> state.copy(backupStep = BackupStep.AddBackupCards)
|
||||
BackupAction.DiscardBackup -> BackupState()
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.tangem.tap.features.demo.DemoHelper
|
|||
import com.tangem.tap.features.onboarding.OnboardingManager
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletState
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.finishCardActivation
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.gatherCardIds
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.AllSymbolsTheSameFilter
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.SaltPayActivationManager
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.SaltPayExceptionHandler
|
||||
|
|
@ -79,7 +80,7 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
|
|||
}
|
||||
}
|
||||
is OnboardingSaltPayAction.OnSwitchedToSaltPayProcess -> {
|
||||
sendAnalyticsScreenOpened(getState().step, newStep = SaltPayActivationStep.None)
|
||||
sendAnalyticsScreenOpened(SaltPayActivationStep.None, newStep = getState().step)
|
||||
}
|
||||
is OnboardingSaltPayAction.Update -> {
|
||||
handleInProgress = true
|
||||
|
|
@ -279,10 +280,8 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
|
|||
store.dispatchDebugErrorNotification("OnboardingManager can't be NULL")
|
||||
return
|
||||
}
|
||||
finishCardActivation(
|
||||
getOnboardingWalletState().backupState,
|
||||
onboardingManager.scanResponse.card,
|
||||
)
|
||||
val cardIds = gatherCardIds(getOnboardingWalletState().backupState, onboardingManager.scanResponse.card)
|
||||
finishCardActivation(cardIds)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ class OnboardingWalletFragment : BaseFragment(R.layout.fragment_onboarding_walle
|
|||
btnWalletMainAction.setOnClickListener { store.dispatch(BackupAction.StartBackup) }
|
||||
|
||||
btnWalletAlternativeAction.text = getText(R.string.onboarding_button_skip_backup)
|
||||
btnWalletAlternativeAction.setOnClickListener { store.dispatch(BackupAction.DismissBackup) }
|
||||
btnWalletAlternativeAction.setOnClickListener { store.dispatch(BackupAction.SkipBackup) }
|
||||
btnWalletAlternativeAction.show(state.canSkipBackup && !isSaltPay)
|
||||
}
|
||||
animator.showBackupIntro(state)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.tap.features.signin.redux
|
||||
|
||||
import com.tangem.tap.common.analytics.events.Basic
|
||||
import org.rekotlin.Action
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
sealed interface SignInAction : Action {
|
||||
|
||||
data class SetSignInType(val type: Basic.SignedIn.SignInType) : SignInAction
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.tap.features.signin.redux
|
||||
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import org.rekotlin.Middleware
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
object SignInMiddleware {
|
||||
val middleware: Middleware<AppState> = { _, _ ->
|
||||
{ next ->
|
||||
{ action -> next(action) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.tangem.tap.features.signin.redux
|
||||
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import org.rekotlin.Action
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
object SignInReducer {
|
||||
fun reduce(action: Action, state: AppState): SignInState {
|
||||
if (action !is SignInAction) return state.signInState
|
||||
|
||||
return when (action) {
|
||||
is SignInAction.SetSignInType -> state.signInState.copy(type = action.type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.tap.features.signin.redux
|
||||
|
||||
import com.tangem.tap.common.analytics.events.Basic
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
data class SignInState(val type: Basic.SignedIn.SignInType? = null)
|
||||
|
|
@ -364,6 +364,10 @@ suspend fun handleBasicAnalyticsEvent() {
|
|||
null
|
||||
}
|
||||
|
||||
val converterData = BasicEventsSourceData(scanResponse, store.state.walletState, biometricsWalletDataModels)
|
||||
val converterData = BasicEventsSourceData(
|
||||
scanResponse = scanResponse,
|
||||
walletState = store.state.walletState,
|
||||
biometricsWalletDataModels = biometricsWalletDataModels,
|
||||
)
|
||||
BasicEventsPreChecker().tryToSend(converterData)
|
||||
}
|
||||
|
|
@ -22,7 +22,6 @@ import com.tangem.core.ui.fragments.setStatusBarColor
|
|||
import com.tangem.core.ui.utils.OneTouchClickListener
|
||||
import com.tangem.feature.swap.domain.SwapInteractor
|
||||
import com.tangem.tap.MainActivity
|
||||
import com.tangem.tap.common.analytics.events.MainScreen
|
||||
import com.tangem.tap.common.analytics.events.Portfolio
|
||||
import com.tangem.tap.common.extensions.show
|
||||
import com.tangem.tap.common.recyclerView.SpaceItemDecoration
|
||||
|
|
@ -66,6 +65,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
|
||||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
lifecycle.addObserver(viewModel)
|
||||
activity?.lifecycleScope?.launchWhenCreated {
|
||||
viewModel.launch()
|
||||
}
|
||||
|
|
@ -75,7 +75,6 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
super.onCreate(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
|
||||
Analytics.send(MainScreen.ScreenOpened())
|
||||
activity?.onBackPressedDispatcher?.addCallback(
|
||||
this,
|
||||
object : OnBackPressedCallback(true) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
package com.tangem.tap.features.wallet.ui
|
||||
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter
|
||||
import com.tangem.tap.common.analytics.events.Basic
|
||||
import com.tangem.tap.common.analytics.events.MainScreen
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.domain.userWalletList.UserWalletsListManager
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
|
|
@ -19,7 +25,7 @@ import org.rekotlin.StoreSubscriber
|
|||
|
||||
// TODO: Kill me, please
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
internal class WalletViewModel : ViewModel(), StoreSubscriber<UserWalletsListManager?> {
|
||||
internal class WalletViewModel : ViewModel(), StoreSubscriber<UserWalletsListManager?>, DefaultLifecycleObserver {
|
||||
private var observeWalletStoresUpdatesJob: Job? = null
|
||||
set(value) {
|
||||
field?.cancel()
|
||||
|
|
@ -41,6 +47,27 @@ internal class WalletViewModel : ViewModel(), StoreSubscriber<UserWalletsListMan
|
|||
}
|
||||
}
|
||||
|
||||
override fun onCreate(owner: LifecycleOwner) {
|
||||
val scanResponse = store.state.globalState.scanResponse
|
||||
if (scanResponse != null) {
|
||||
val currency = ParamCardCurrencyConverter().convert(scanResponse.cardTypesResolver)
|
||||
val signInType = store.state.signInState.type
|
||||
if (currency != null && signInType != null) {
|
||||
Analytics.send(
|
||||
Basic.SignedIn(
|
||||
currency = currency,
|
||||
batch = scanResponse.card.batchId,
|
||||
signInType = signInType,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart(owner: LifecycleOwner) {
|
||||
Analytics.send(MainScreen.ScreenOpened())
|
||||
}
|
||||
|
||||
fun launch() {
|
||||
val manager = store.state.globalState.userWalletsListManager
|
||||
if (manager != null) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package com.tangem.tap.features.wallet.ui.wallet
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.events.Token
|
||||
import com.tangem.tap.common.extensions.beginDelayedTransition
|
||||
import com.tangem.tap.common.extensions.fitChipsByGroupWidth
|
||||
import com.tangem.tap.common.extensions.getQuantityString
|
||||
|
|
@ -118,6 +120,8 @@ class SingleWalletView : WalletView() {
|
|||
}
|
||||
}
|
||||
lAddress.btnShowQr.setOnClickListener {
|
||||
Analytics.send(Token.ShowWalletAddress)
|
||||
|
||||
walletData.walletAddresses?.selectedAddress?.let { selectedAddress ->
|
||||
store.dispatch(
|
||||
WalletAction.DialogAction.QrCode(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ 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
|
||||
|
|
|
|||
|
|
@ -4,13 +4,10 @@ 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.dispatchOnMain
|
||||
import com.tangem.tap.common.extensions.eraseContext
|
||||
import com.tangem.tap.common.extensions.onUserWalletSelected
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
|
|
@ -19,6 +16,7 @@ import com.tangem.tap.domain.model.builders.UserWalletBuilder
|
|||
import com.tangem.tap.domain.scanCard.ScanCardProcessor
|
||||
import com.tangem.tap.domain.userWalletList.unlockIfLockable
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.message.SaltPayActivationError
|
||||
import com.tangem.tap.features.signin.redux.SignInAction
|
||||
import com.tangem.tap.intentHandler
|
||||
import com.tangem.tap.preferencesStorage
|
||||
import com.tangem.tap.scope
|
||||
|
|
@ -44,10 +42,6 @@ internal class WelcomeMiddleware {
|
|||
|
||||
private fun handleAction(action: WelcomeAction, state: WelcomeState) {
|
||||
when (action) {
|
||||
is WelcomeAction.OnCreate -> {
|
||||
Analytics.eraseContext()
|
||||
Analytics.send(SignIn.ScreenOpened())
|
||||
}
|
||||
is WelcomeAction.ProceedWithBiometrics -> {
|
||||
proceedWithBiometrics(state)
|
||||
}
|
||||
|
|
@ -74,9 +68,10 @@ internal class WelcomeMiddleware {
|
|||
store.dispatchOnMain(WelcomeAction.ProceedWithBiometrics.Error(error))
|
||||
}
|
||||
.doOnSuccess { selectedUserWallet ->
|
||||
store.dispatchOnMain(SignInAction.SetSignInType(Basic.SignedIn.SignInType.Biometric))
|
||||
store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
store.dispatchOnMain(WelcomeAction.ProceedWithBiometrics.Success)
|
||||
store.onUserWalletSelected(selectedUserWallet)
|
||||
store.onUserWalletSelected(userWallet = selectedUserWallet)
|
||||
|
||||
intentHandler.handleWalletConnectLink(state.intent)
|
||||
}
|
||||
|
|
@ -93,9 +88,10 @@ internal class WelcomeMiddleware {
|
|||
store.dispatchOnMain(WelcomeAction.ProceedWithCard.Error(error))
|
||||
}
|
||||
.doOnSuccess {
|
||||
store.dispatchOnMain(SignInAction.SetSignInType(Basic.SignedIn.SignInType.Card))
|
||||
store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
store.dispatchOnMain(WelcomeAction.ProceedWithCard.Success)
|
||||
store.onUserWalletSelected(userWallet)
|
||||
store.onUserWalletSelected(userWallet = userWallet)
|
||||
|
||||
intentHandler.handleWalletConnectLink(state.intent)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.tap.features.welcome.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
|
|
@ -19,22 +18,25 @@ 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.common.extensions.eraseContext
|
||||
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.WarningDialog
|
||||
import com.tangem.tap.features.welcome.ui.components.WelcomeScreenContent
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
|
||||
internal class WelcomeFragment : ComposeFragment<WelcomeScreenState>() {
|
||||
|
||||
private val viewModel by viewModels<WelcomeViewModel>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
store.dispatch(WelcomeAction.OnCreate)
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
Analytics.eraseContext()
|
||||
Analytics.send(SignIn.ScreenOpened())
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@ package com.tangem.feature.referral.analytics
|
|||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
|
||||
sealed class ReferralEvents(
|
||||
event: String,
|
||||
) : AnalyticsEvent(REFERRAL_PROGRAM_CATEGORY, event) {
|
||||
sealed class ReferralEvents(event: String) : AnalyticsEvent(REFERRAL_PROGRAM_CATEGORY, event) {
|
||||
|
||||
object ReferralScreenOpened : ReferralEvents(event = "Referral Screen Opened")
|
||||
object ClickParticipate : ReferralEvents(event = "Button - Participate")
|
||||
|
|
@ -13,4 +11,4 @@ sealed class ReferralEvents(
|
|||
object ClickTaC : ReferralEvents(event = "Link - TaC")
|
||||
}
|
||||
|
||||
private const val REFERRAL_PROGRAM_CATEGORY = "Referral program"
|
||||
private const val REFERRAL_PROGRAM_CATEGORY = "Referral Program"
|
||||
|
|
@ -15,16 +15,16 @@ sealed class SwapEvents(
|
|||
object SendTokenBalanceClicked : SwapEvents(event = "Send Token Balance Clicked")
|
||||
object ReceiveTokenClicked : SwapEvents(event = "Receive Token Clicked")
|
||||
object ChooseTokenScreenOpened : SwapEvents(event = "Choose Token Screen Opened")
|
||||
object SearchTokenClicked : SwapEvents(event = "Search Token Clicked")
|
||||
object SearchTokenClicked : SwapEvents(event = "Searched Token Clicked")
|
||||
data class ButtonSwapClicked(val sendToken: String, val receiveToken: String) : SwapEvents(
|
||||
event = "Button - Swap",
|
||||
params = mapOf("Send Token" to sendToken, "Receive Token" to receiveToken),
|
||||
)
|
||||
|
||||
object ButtonGivePermissionClicked : SwapEvents(event = "Button - Give permission") // ?
|
||||
object ButtonGivePermissionClicked : SwapEvents(event = "Button - Give permission")
|
||||
object ButtonPermissionApproveClicked : SwapEvents(event = "Button - Permission Approve")
|
||||
object ButtonPermissionCancelClicked : SwapEvents(event = "Button - Permission Cancel")
|
||||
object ButtonPermitAndSwapClicked : SwapEvents(event = "Button - Permit and Swap") // ?
|
||||
object ButtonPermitAndSwapClicked : SwapEvents(event = "Button - Permit and Swap")
|
||||
object ButtonSwipeClicked : SwapEvents(event = "Button - Swipe")
|
||||
object SwapInProgressScreen : SwapEvents(event = "Swap in Progress Screen Opened")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue