Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-16 15:45:41 +08:00
parent 9c52a130c4
commit bb22f11954
13 changed files with 40 additions and 47 deletions

View file

@ -22,6 +22,7 @@ sealed class Settings(
class ButtonAppSettings : Settings(event = "Button - App Settings")
class ButtonCreateBackup : Settings(event = "Button - Create Backup")
class ButtonWalletConnect : Settings(event = "Button - Wallet Connect")
object ScanNewCard : Settings(event = "Button - Scan New Card")
class ButtonSocialNetwork(network: SocialNetwork) : Settings(
event = "Button - Social Network",
@ -78,5 +79,10 @@ sealed class Settings(
)
object ButtonEnableBiometricAuthentication : AppSettings(event = "Button - Enable Biometric Authentication")
class MainCurrencyChanged(currencyType: String) : MainScreen(
event = "Main Currency Changed",
params = mapOf("Currency Type" to currencyType),
)
}
}

View file

@ -2,10 +2,12 @@ package com.tangem.tap.features.details.ui.appcurrency
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.navigation.ReduxNavController
import com.tangem.domain.appcurrency.GetAvailableCurrenciesUseCase
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.SelectAppCurrencyUseCase
import com.tangem.tap.common.analytics.events.Settings
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.StateFlow
@ -20,6 +22,7 @@ internal class AppCurrencySelectorViewModel @Inject constructor(
private val selectAppCurrencyUseCase: SelectAppCurrencyUseCase,
private val reduxNavController: ReduxNavController,
private val dispatchers: CoroutineDispatcherProvider,
private val analyticsEventHandler: AnalyticsEventHandler,
) : ViewModel(), AppCurrencySelectorIntents {
private val stateController = AppCurrencySelectorStateHolder(
@ -45,7 +48,12 @@ internal class AppCurrencySelectorViewModel @Inject constructor(
override fun onCurrencyClick(currency: AppCurrencySelectorState.Currency) {
viewModelScope.launch(dispatchers.io) {
selectAppCurrencyUseCase(currency.id)
.onRight { reduxNavController.popBackStack() }
.onRight {
analyticsEventHandler.send(
event = Settings.AppSettings.MainCurrencyChanged(currencyType = currency.name),
)
reduxNavController.popBackStack()
}
}
}

View file

@ -161,6 +161,7 @@ internal class DetailsViewModel(
}
private fun scanAndSaveUserWallet() {
Analytics.send(Settings.ScanNewCard)
store.dispatch(DetailsAction.ScanAndSaveUserWallet)
}

View file

@ -4,26 +4,11 @@ import androidx.compose.animation.Crossfade
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
@ -64,7 +49,7 @@ fun ExpandableSearchView(
onBackClick: () -> Unit,
onSearchChange: (String) -> Unit,
onSearchDisplayClose: () -> Unit,
onFocusChange: (Boolean) -> Unit,
onFocusChange: (Boolean) -> Unit = {},
title: String? = null,
placeholderSearchText: String = "",
expandedInitially: Boolean = false,

View file

@ -26,13 +26,12 @@ class ReferralFragment : ComposeFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.onScreenOpened()
viewModel.setRouter(ReferralRouter(fragmentManager = WeakReference(parentFragmentManager)))
}
@Composable
override fun ScreenContent(modifier: Modifier) {
viewModel.onScreenOpened()
val backgroundColor = TangemTheme.colors.background.secondary
SystemBarsEffect { setSystemBarsColor(backgroundColor) }

View file

@ -14,7 +14,16 @@ sealed class SwapEvents(
object SendTokenBalanceClicked : SwapEvents(event = "Send Token Balance Clicked")
object ChooseTokenScreenOpened : SwapEvents(event = "Choose Token Screen Opened")
object SearchTokenClicked : SwapEvents(event = "Searched Token Clicked")
data class SearchTokenClicked(val currencySymbol: String?) : SwapEvents(
event = "Searched Token Clicked",
params = buildMap {
if (currencySymbol != null) {
put("Token", currencySymbol)
}
},
)
data class ButtonSwapClicked(val sendToken: String, val receiveToken: String) : SwapEvents(
event = "Button - Swap",
params = mapOf("Send Token" to sendToken, "Receive Token" to receiveToken),

View file

@ -25,7 +25,6 @@ data class SwapStateHolder(
val onRefresh: () -> Unit,
val onBackClicked: () -> Unit,
val onChangeCardsClicked: () -> Unit,
val onSearchFocusChange: (Boolean) -> Unit,
val onSelectTokenClick: (() -> Unit)? = null,
val onSuccess: (() -> Unit)? = null,
val onMaxAmountSelected: (() -> Unit)? = null,

View file

@ -5,7 +5,6 @@ import com.tangem.feature.swap.domain.models.ui.TxFee
data class UiActions(
val onSearchEntered: (String) -> Unit,
val onSearchFocusChange: (Boolean) -> Unit,
val onTokenSelected: (String) -> Unit,
val onAmountChanged: (String) -> Unit,
val onAmountSelected: (Boolean) -> Unit,

View file

@ -52,7 +52,7 @@ class SwapFragment : ComposeFragment() {
@Suppress("TopLevelComposableFunctions")
@Composable
private fun ScreenContent(viewModel: SwapViewModel) {
Crossfade(targetState = viewModel.currentScreen) { screen ->
Crossfade(targetState = viewModel.currentScreen, label = "") { screen ->
when (screen) {
SwapNavScreen.Main -> SwapScreen(stateHolder = viewModel.uiState)
SwapNavScreen.Success -> {
@ -66,11 +66,7 @@ class SwapFragment : ComposeFragment() {
SwapNavScreen.SelectToken -> {
val tokenState = viewModel.uiState.selectTokenState
if (tokenState != null) {
SwapSelectTokenScreen(
state = tokenState,
onSearchFocusChange = viewModel.uiState.onSearchFocusChange,
onBack = viewModel.uiState.onBackClicked,
)
SwapSelectTokenScreen(state = tokenState, onBack = viewModel.uiState.onBackClicked)
} else {
SwapScreen(stateHolder = viewModel.uiState)
}

View file

@ -58,7 +58,6 @@ internal class StateBuilder(val actions: UiActions, val isBalanceHiddenProvider:
networkCurrency = networkInfo.blockchainCurrency,
swapButton = SwapButton(enabled = false, loading = true, onClick = {}),
onRefresh = {},
onSearchFocusChange = actions.onSearchFocusChange,
onBackClicked = actions.onBackClicked,
onChangeCardsClicked = actions.onChangeCardsClicked,
onMaxAmountSelected = actions.onMaxAmountSelected,

View file

@ -454,8 +454,6 @@ private val state = SwapStateHolder(
onChangeCardsClicked = {},
permissionState = SwapPermissionState.InProgress,
blockchainId = "POLYGON",
onSearchFocusChange = {},
// alert = SwapWarning.GenericWarning("There was an error. Please try again.") {},
)
@Preview

View file

@ -41,11 +41,7 @@ import com.tangem.feature.swap.presentation.R
import kotlinx.coroutines.launch
@Composable
fun SwapSelectTokenScreen(
state: SwapSelectTokenStateHolder,
onSearchFocusChange: (Boolean) -> Unit,
onBack: () -> Unit,
) {
fun SwapSelectTokenScreen(state: SwapSelectTokenStateHolder, onBack: () -> Unit) {
Scaffold(
modifier = Modifier
.systemBarsPadding()
@ -60,7 +56,6 @@ fun SwapSelectTokenScreen(
placeholderSearchText = stringResource(id = R.string.common_search_tokens),
onSearchChange = state.onSearchEntered,
onSearchDisplayClose = { state.onSearchEntered("") },
onFocusChange = onSearchFocusChange,
subtitle = state.network.name,
icon = painterResource(id = getActiveIconRes(state.network.blockchainId)),
)
@ -283,7 +278,6 @@ private fun TokenScreenPreview() {
onTokenSelected = {},
network = Network("Ethereum", "ETH"),
),
onSearchFocusChange = {},
onBack = {},
)
}

View file

@ -87,7 +87,7 @@ internal class SwapViewModel @Inject constructor(
private var isOrderReversed = false
private val lastAmount = mutableStateOf(INITIAL_AMOUNT)
private var swapRouter: SwapRouter by Delegates.notNull()
var currentScreen = SwapNavScreen.Main
val currentScreen: SwapNavScreen
get() = swapRouter.currentScreen
init {
@ -359,6 +359,11 @@ internal class SwapViewModel @Inject constructor(
private fun onTokenSelect(id: String) {
val foundToken = swapInteractor.findTokenById(id)
analyticsEventHandler.send(
event = SwapEvents.SearchTokenClicked(currencySymbol = foundToken?.symbol),
)
if (foundToken != null) {
val fromToken: Currency
val toToken: Currency
@ -471,11 +476,6 @@ internal class SwapViewModel @Inject constructor(
analyticsEventHandler.send(SwapEvents.ButtonPermissionCancelClicked)
},
onAmountSelected = { onAmountSelected(it) },
onSearchFocusChange = { focused ->
if (focused) {
analyticsEventHandler.send(SwapEvents.SearchTokenClicked)
}
},
onChangeApproveType = { approveType ->
uiState = stateBuilder.updateApproveType(uiState, approveType)
},