Updated on 2026-08-14
This commit is contained in:
commit
74522f0304
27 changed files with 216 additions and 109 deletions
|
|
@ -11,10 +11,13 @@ import androidx.compose.foundation.text.KeyboardActions
|
|||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusManager
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
|
|
@ -47,6 +50,7 @@ fun SearchBar(
|
|||
) {
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
val focusManager = LocalFocusManager.current
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
|
||||
BasicTextField(
|
||||
|
|
@ -60,6 +64,7 @@ fun SearchBar(
|
|||
state.onActiveChange(false)
|
||||
}
|
||||
}
|
||||
.focusRequester(focusRequester)
|
||||
.testTag(SelectCountryBottomSheetTestTags.SEARCH_BAR),
|
||||
enabled = enabled,
|
||||
value = state.query,
|
||||
|
|
@ -92,6 +97,10 @@ fun SearchBar(
|
|||
)
|
||||
},
|
||||
)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
focusRequester.requestFocus()
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
|
|
|
|||
|
|
@ -13,11 +13,17 @@ interface ChooseManagedTokensComponent : ComposableContentComponent {
|
|||
val selectedCurrency: CryptoCurrency?,
|
||||
val source: Source,
|
||||
val showSendViaSwapNotification: Boolean,
|
||||
val callback: ModelCallback? = null,
|
||||
)
|
||||
|
||||
enum class Source {
|
||||
SendViaSwap,
|
||||
}
|
||||
|
||||
interface ModelCallback {
|
||||
fun onResult()
|
||||
fun onBack()
|
||||
}
|
||||
|
||||
interface Factory : ComponentFactory<Params, ChooseManagedTokensComponent>
|
||||
}
|
||||
|
|
@ -70,7 +70,7 @@ internal class DefaultChooseManagedTokensComponent @AssistedInject constructor(
|
|||
cryptoCurrency = cryptoCurrency,
|
||||
shouldResetNavigation = params.selectedCurrency != null,
|
||||
)
|
||||
router.pop()
|
||||
params.callback?.onResult() ?: router.pop()
|
||||
}
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -89,13 +89,13 @@ internal class ChooseManagedTokensModel @Inject constructor(
|
|||
return ChooseManagedTokenUM(
|
||||
notificationUM = getNotification(),
|
||||
readContent = ManageTokensUM.ReadContent(
|
||||
popBack = router::pop,
|
||||
popBack = { params.callback?.onBack() ?: router.pop() },
|
||||
isInitialBatchLoading = true,
|
||||
isNextBatchLoading = false,
|
||||
items = getLoadingItems(),
|
||||
topBar = ManageTokensTopBarUM.ReadContent(
|
||||
title = resourceReference(R.string.common_choose_token),
|
||||
onBackButtonClick = router::pop,
|
||||
onBackButtonClick = { params.callback?.onBack() ?: router.pop() },
|
||||
),
|
||||
search = SearchBarUM(
|
||||
placeholderText = resourceReference(R.string.common_search),
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ dependencies {
|
|||
/** Core */
|
||||
implementation(projects.core.decompose)
|
||||
implementation(projects.core.ui)
|
||||
implementation(projects.core.analytics.models)
|
||||
|
||||
/** Common */
|
||||
implementation(projects.common.ui)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.features.send.v2.common.analytics
|
||||
package com.tangem.features.send.v2.api.analytics
|
||||
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsParam.Key.BLOCKCHAIN
|
||||
|
|
@ -6,9 +6,9 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.SOURCE
|
|||
import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM
|
||||
|
||||
/**
|
||||
* Send screen analytics
|
||||
* Send analytics
|
||||
*/
|
||||
internal sealed class CommonSendAnalyticEvents(
|
||||
sealed class CommonSendAnalyticEvents(
|
||||
category: String,
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
|
|
@ -114,12 +114,26 @@ internal sealed class CommonSendAnalyticEvents(
|
|||
),
|
||||
)
|
||||
|
||||
/** Token chosen to convert with sending */
|
||||
data class TokenChosen(
|
||||
val categoryName: String,
|
||||
val token: String,
|
||||
val blockchain: String,
|
||||
) : CommonSendAnalyticEvents(
|
||||
category = categoryName,
|
||||
event = "Token chosen",
|
||||
params = mapOf(
|
||||
TOKEN_PARAM to token,
|
||||
BLOCKCHAIN to blockchain,
|
||||
),
|
||||
)
|
||||
|
||||
companion object {
|
||||
const val SEND_CATEGORY = "Token / Send"
|
||||
const val NFT_SEND_CATEGORY = "NFT"
|
||||
}
|
||||
|
||||
internal enum class SendScreenSource {
|
||||
enum class SendScreenSource {
|
||||
Address,
|
||||
Amount,
|
||||
Fee,
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package com.tangem.features.send.v2.subcomponents.amount.analytics
|
||||
package com.tangem.features.send.v2.api.subcomponents.amount.analytics
|
||||
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsParam.Key.TYPE
|
||||
|
||||
internal sealed class SendAmountAnalyticEvents(
|
||||
sealed class CommonSendAmountAnalyticEvents(
|
||||
category: String,
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
|
|
@ -13,7 +13,7 @@ internal sealed class SendAmountAnalyticEvents(
|
|||
data class SelectedCurrency(
|
||||
val categoryName: String,
|
||||
val type: SelectedCurrencyType,
|
||||
) : SendAmountAnalyticEvents(
|
||||
) : CommonSendAmountAnalyticEvents(
|
||||
category = categoryName,
|
||||
event = "Selected Currency",
|
||||
params = mapOf(TYPE to type.value),
|
||||
|
|
@ -22,9 +22,9 @@ internal sealed class SendAmountAnalyticEvents(
|
|||
/** Max amount button clicked */
|
||||
data class MaxAmountButtonClicked(
|
||||
val categoryName: String,
|
||||
) : SendAmountAnalyticEvents(category = categoryName, event = "Max Amount Taped")
|
||||
) : CommonSendAmountAnalyticEvents(category = categoryName, event = "Max Amount Taped")
|
||||
|
||||
internal enum class SelectedCurrencyType(val value: String) {
|
||||
enum class SelectedCurrencyType(val value: String) {
|
||||
Token("Token"),
|
||||
AppCurrency("App Currency"),
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package com.tangem.features.send.v2.subcomponents.fee.analytics
|
||||
package com.tangem.features.send.v2.api.subcomponents.feeSelector.analytics
|
||||
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
|
||||
internal sealed class SendFeeAnalyticEvents(
|
||||
sealed class CommonSendFeeAnalyticEvents(
|
||||
category: String,
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
|
|
@ -15,7 +15,7 @@ internal sealed class SendFeeAnalyticEvents(
|
|||
data class SelectedFee(
|
||||
override val categoryName: String,
|
||||
val feeType: AnalyticsParam.FeeType,
|
||||
) : SendFeeAnalyticEvents(
|
||||
) : CommonSendFeeAnalyticEvents(
|
||||
category = categoryName,
|
||||
event = "Fee Selected",
|
||||
params = mapOf("Fee Type" to feeType.value),
|
||||
|
|
@ -24,7 +24,7 @@ internal sealed class SendFeeAnalyticEvents(
|
|||
/** Custom fee selected */
|
||||
data class CustomFeeButtonClicked(
|
||||
override val categoryName: String,
|
||||
) : SendFeeAnalyticEvents(
|
||||
) : CommonSendFeeAnalyticEvents(
|
||||
category = categoryName,
|
||||
event = "Custom Fee Clicked",
|
||||
)
|
||||
|
|
@ -32,7 +32,7 @@ internal sealed class SendFeeAnalyticEvents(
|
|||
/** Custom fee edited */
|
||||
data class GasPriceInserter(
|
||||
override val categoryName: String,
|
||||
) : SendFeeAnalyticEvents(
|
||||
) : CommonSendFeeAnalyticEvents(
|
||||
category = categoryName,
|
||||
event = "Gas Price Inserted",
|
||||
)
|
||||
|
|
@ -21,6 +21,7 @@ dependencies {
|
|||
implementation(projects.features.txhistory.api)
|
||||
implementation(projects.features.nft.api)
|
||||
implementation(projects.features.swapV2.api)
|
||||
implementation(projects.features.manageTokens.api)
|
||||
|
||||
/** Libs */
|
||||
implementation(projects.libs.crypto)
|
||||
|
|
|
|||
|
|
@ -1,18 +1,29 @@
|
|||
package com.tangem.features.send.v2.entrypoint
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.arkivanov.decompose.ComponentContext
|
||||
import com.arkivanov.decompose.extensions.compose.stack.Children
|
||||
import com.arkivanov.decompose.extensions.compose.stack.animation.fade
|
||||
import com.arkivanov.decompose.extensions.compose.stack.animation.plus
|
||||
import com.arkivanov.decompose.extensions.compose.stack.animation.slide
|
||||
import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation
|
||||
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
||||
import com.arkivanov.decompose.router.stack.StackNavigation
|
||||
import com.arkivanov.decompose.router.stack.childStack
|
||||
import com.arkivanov.decompose.router.stack.pop
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.child
|
||||
import com.tangem.core.decompose.context.childByContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.decompose.navigation.inner.InnerRouter
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.features.managetokens.component.ChooseManagedTokensComponent
|
||||
import com.tangem.features.send.v2.api.SendComponent
|
||||
import com.tangem.features.send.v2.api.SendEntryPointComponent
|
||||
import com.tangem.features.send.v2.entrypoint.model.SendEntryPoint
|
||||
import com.tangem.features.send.v2.entrypoint.model.SendEntryPointModel
|
||||
import com.tangem.features.swap.v2.api.SendWithSwapComponent
|
||||
import dagger.assisted.Assisted
|
||||
|
|
@ -24,9 +35,17 @@ internal class DefaultSendEntryPointComponent @AssistedInject constructor(
|
|||
@Assisted private val params: SendEntryPointComponent.Params,
|
||||
sendWithSwapComponentFactory: SendWithSwapComponent.Factory,
|
||||
sendComponentFactory: SendComponent.Factory,
|
||||
private val chooseManagedTokensComponentFactory: ChooseManagedTokensComponent.Factory,
|
||||
) : SendEntryPointComponent, AppComponentContext by appComponentContext {
|
||||
|
||||
private val model: SendEntryPointModel = getOrCreateModel(params = params)
|
||||
private val stackNavigation = StackNavigation<SendEntryRoute>()
|
||||
|
||||
private val innerRouter = InnerRouter<SendEntryRoute>(
|
||||
stackNavigation = stackNavigation,
|
||||
popCallback = { onChildBack() },
|
||||
)
|
||||
|
||||
private val model: SendEntryPointModel = getOrCreateModel(params = params, router = innerRouter)
|
||||
|
||||
private val sendWithSwapComponent = sendWithSwapComponentFactory.create(
|
||||
context = child("sendEntrySendWithSwap"),
|
||||
|
|
@ -46,18 +65,76 @@ internal class DefaultSendEntryPointComponent @AssistedInject constructor(
|
|||
),
|
||||
)
|
||||
|
||||
private val childStack = childStack(
|
||||
key = "sendEntryStack",
|
||||
source = stackNavigation,
|
||||
serializer = null,
|
||||
initialConfiguration = SendEntryRoute.Send,
|
||||
handleBackButton = true,
|
||||
childFactory = { configuration, factoryContext ->
|
||||
getChildComponent(
|
||||
configuration = configuration,
|
||||
factoryContext = childByContext(
|
||||
componentContext = factoryContext,
|
||||
router = innerRouter,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val sendEntryState by model.sendEntryPointState.collectAsStateWithLifecycle()
|
||||
val childStackValue by childStack.subscribeAsState()
|
||||
|
||||
sendComponent.Content(modifier)
|
||||
Children(
|
||||
stack = childStackValue,
|
||||
animation = stackAnimation { child ->
|
||||
when (child.configuration) {
|
||||
SendEntryRoute.Send,
|
||||
SendEntryRoute.SendWithSwap,
|
||||
-> fade()
|
||||
is SendEntryRoute.ChooseToken -> slide(orientation = Orientation.Vertical) + fade()
|
||||
}
|
||||
},
|
||||
) { child ->
|
||||
child.instance.Content(modifier.fillMaxSize())
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = sendEntryState == SendEntryPoint.SendWithSwap,
|
||||
enter = fadeIn(),
|
||||
exit = fadeOut(),
|
||||
) {
|
||||
sendWithSwapComponent.Content(modifier)
|
||||
private fun getChildComponent(
|
||||
configuration: SendEntryRoute,
|
||||
factoryContext: AppComponentContext,
|
||||
): ComposableContentComponent = when (configuration) {
|
||||
is SendEntryRoute.ChooseToken -> getManagedTokensComponent(
|
||||
componentContext = factoryContext,
|
||||
showSendViaSwapNotification = configuration.showSendViaSwapNotification,
|
||||
)
|
||||
SendEntryRoute.Send -> sendComponent
|
||||
SendEntryRoute.SendWithSwap -> sendWithSwapComponent
|
||||
}
|
||||
|
||||
private fun getManagedTokensComponent(
|
||||
componentContext: ComponentContext,
|
||||
showSendViaSwapNotification: Boolean,
|
||||
): ChooseManagedTokensComponent {
|
||||
return chooseManagedTokensComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = ChooseManagedTokensComponent.Params(
|
||||
userWalletId = params.userWalletId,
|
||||
initialCurrency = params.cryptoCurrency,
|
||||
source = ChooseManagedTokensComponent.Source.SendViaSwap,
|
||||
selectedCurrency = null,
|
||||
showSendViaSwapNotification = showSendViaSwapNotification,
|
||||
callback = model,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun onChildBack() {
|
||||
if (childStack.value.backStack.isEmpty()) {
|
||||
router.pop()
|
||||
} else {
|
||||
stackNavigation.pop()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
package com.tangem.features.send.v2.entrypoint
|
||||
|
||||
import com.tangem.core.decompose.navigation.Route
|
||||
|
||||
internal sealed class SendEntryRoute : Route {
|
||||
data object Send : SendEntryRoute()
|
||||
data object SendWithSwap : SendEntryRoute()
|
||||
data class ChooseToken(
|
||||
val showSendViaSwapNotification: Boolean,
|
||||
) : SendEntryRoute()
|
||||
}
|
||||
|
|
@ -1,90 +1,74 @@
|
|||
package com.tangem.features.send.v2.entrypoint.model
|
||||
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.common.ui.notifications.NotificationId
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.domain.notifications.ShouldShowNotificationUseCase
|
||||
import com.tangem.features.managetokens.component.ChooseManagedTokensComponent
|
||||
import com.tangem.features.send.v2.api.SendComponent
|
||||
import com.tangem.features.send.v2.api.SendEntryPointComponent
|
||||
import com.tangem.features.send.v2.entrypoint.SendEntryRoute
|
||||
import com.tangem.features.send.v2.subcomponents.amount.SendAmountUpdateTrigger
|
||||
import com.tangem.features.swap.v2.api.SendWithSwapComponent
|
||||
import com.tangem.features.swap.v2.api.choosetoken.SwapChooseTokenNetworkListener
|
||||
import com.tangem.features.swap.v2.api.subcomponents.SwapAmountUpdateTrigger
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.JobHolder
|
||||
import com.tangem.utils.coroutines.saveIn
|
||||
import jakarta.inject.Inject
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@ModelScoped
|
||||
internal class SendEntryPointModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
val appRouter: AppRouter,
|
||||
private val swapChooseTokenNetworkListener: SwapChooseTokenNetworkListener,
|
||||
val router: Router,
|
||||
private val sendAmountUpdateTrigger: SendAmountUpdateTrigger,
|
||||
private val swapAmountUpdateTrigger: SwapAmountUpdateTrigger,
|
||||
private val shouldShowNotificationUseCase: ShouldShowNotificationUseCase,
|
||||
) : Model(), SendComponent.ModelCallback, SendWithSwapComponent.ModelCallback {
|
||||
) : Model(),
|
||||
SendComponent.ModelCallback,
|
||||
SendWithSwapComponent.ModelCallback,
|
||||
ChooseManagedTokensComponent.ModelCallback {
|
||||
|
||||
private val params: SendEntryPointComponent.Params = paramsContainer.require()
|
||||
|
||||
val sendEntryPointState: StateFlow<SendEntryPoint>
|
||||
field = MutableStateFlow(SendEntryPoint.SendVanilla)
|
||||
|
||||
private var swapChooseTokenListenerJobHolder = JobHolder()
|
||||
private var lastSavedAmount = ""
|
||||
|
||||
override fun onConvertToAnotherToken(lastAmount: String) {
|
||||
lastSavedAmount = lastAmount
|
||||
modelScope.launch {
|
||||
val showSendViaSwapNotification = shouldShowNotificationUseCase(
|
||||
NotificationId.SendViaSwapTokenSelectorNotification.key,
|
||||
)
|
||||
appRouter.push(
|
||||
AppRoute.ChooseManagedTokens(
|
||||
userWalletId = params.userWalletId,
|
||||
initialCurrency = params.cryptoCurrency,
|
||||
selectedCurrency = null,
|
||||
source = AppRoute.ChooseManagedTokens.Source.SendViaSwap,
|
||||
router.push(
|
||||
SendEntryRoute.ChooseToken(
|
||||
showSendViaSwapNotification = showSendViaSwapNotification,
|
||||
),
|
||||
)
|
||||
observeChooseSelectToken(lastAmount)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCloseSwap(lastAmount: String) {
|
||||
lastSavedAmount = lastAmount
|
||||
modelScope.launch {
|
||||
if (lastAmount.isNotBlank()) {
|
||||
sendAmountUpdateTrigger.triggerUpdateAmount(lastAmount)
|
||||
}
|
||||
triggerScreenUpdate(SendEntryPoint.SendVanilla)
|
||||
router.replaceAll(SendEntryRoute.Send)
|
||||
}
|
||||
}
|
||||
|
||||
private fun observeChooseSelectToken(lastAmount: String) {
|
||||
swapChooseTokenNetworkListener.swapChooseTokenNetworkResultFlow
|
||||
.onEach { currency ->
|
||||
if (lastAmount.isNotBlank()) {
|
||||
swapAmountUpdateTrigger.triggerUpdateAmount(lastAmount)
|
||||
}
|
||||
triggerScreenUpdate(SendEntryPoint.SendWithSwap)
|
||||
@Suppress("MagicNumber")
|
||||
override fun onResult() {
|
||||
modelScope.launch {
|
||||
if (lastSavedAmount.isNotBlank()) {
|
||||
swapAmountUpdateTrigger.triggerUpdateAmount(lastSavedAmount)
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
.saveIn(swapChooseTokenListenerJobHolder)
|
||||
// Workaround in order to execute correct exit animation on SendEntryRoute.ChooseToken
|
||||
router.pop()
|
||||
delay(10L)
|
||||
router.replaceAll(SendEntryRoute.SendWithSwap)
|
||||
}
|
||||
}
|
||||
|
||||
private fun triggerScreenUpdate(entry: SendEntryPoint) {
|
||||
swapChooseTokenListenerJobHolder.cancel()
|
||||
sendEntryPointState.update { entry }
|
||||
override fun onBack() {
|
||||
router.pop()
|
||||
}
|
||||
}
|
||||
|
||||
enum class SendEntryPoint {
|
||||
SendVanilla,
|
||||
SendWithSwap,
|
||||
}
|
||||
|
|
@ -24,10 +24,10 @@ import com.tangem.core.ui.extensions.resourceReference
|
|||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
|
||||
import com.tangem.features.send.v2.api.SendComponent
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
|
||||
import com.tangem.features.send.v2.common.CommonSendRoute
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.common.ui.SendContent
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.FEE_TYPE
|
|||
import com.tangem.core.analytics.models.AnalyticsParam.Key.NONCE
|
||||
import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM
|
||||
import com.tangem.core.ui.extensions.capitalize
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
|
||||
|
||||
/**
|
||||
* Send screen analytics
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
|
|||
import com.tangem.domain.utils.convertToSdkAmount
|
||||
import com.tangem.features.send.v2.api.SendNotificationsComponent
|
||||
import com.tangem.features.send.v2.api.SendNotificationsComponent.Params.NotificationData
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents.SendScreenSource
|
||||
import com.tangem.features.send.v2.api.callbacks.FeeSelectorModelCallback
|
||||
import com.tangem.features.send.v2.api.entity.FeeNonce
|
||||
import com.tangem.features.send.v2.api.params.FeeSelectorParams.FeeStateConfiguration
|
||||
|
|
@ -48,8 +50,6 @@ import com.tangem.features.send.v2.api.subcomponents.notifications.SendNotificat
|
|||
import com.tangem.features.send.v2.common.CommonSendRoute
|
||||
import com.tangem.features.send.v2.common.SendBalanceUpdater
|
||||
import com.tangem.features.send.v2.common.SendConfirmAlertFactory
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.SendScreenSource
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.send.analytics.SendAnalyticHelper
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ import com.tangem.core.ui.format.bigdecimal.format
|
|||
import com.tangem.core.ui.utils.parseToBigDecimal
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.utils.formatFooterFiatFee
|
||||
import com.tangem.features.send.v2.api.utils.getTronTokenFeeSendingText
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.checkIfFeeTooHigh
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ import com.tangem.core.ui.format.bigdecimal.fiat
|
|||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
|
||||
import com.tangem.features.send.v2.api.subcomponents.feeSelector.utils.FeeCalculationUtils
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
import com.tangem.features.send.v2.api.utils.formatFooterFiatFee
|
||||
import com.tangem.features.send.v2.api.utils.getTronTokenFeeSendingText
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ import com.tangem.domain.wallets.models.GetUserWalletError
|
|||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.features.send.v2.api.SendComponent
|
||||
import com.tangem.features.send.v2.api.SendFeatureToggles
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents.SendScreenSource
|
||||
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
|
||||
import com.tangem.features.send.v2.api.entity.PredefinedValues
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponent
|
||||
|
|
@ -48,8 +50,6 @@ import com.tangem.features.send.v2.api.subcomponents.destination.entity.Destinat
|
|||
import com.tangem.features.send.v2.common.CommonSendRoute
|
||||
import com.tangem.features.send.v2.common.CommonSendRoute.*
|
||||
import com.tangem.features.send.v2.common.SendConfirmAlertFactory
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.SendScreenSource
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
import com.tangem.features.send.v2.send.confirm.SendConfirmComponent
|
||||
import com.tangem.features.send.v2.send.success.SendConfirmSuccessComponent
|
||||
|
|
|
|||
|
|
@ -12,14 +12,17 @@ import com.tangem.core.navigation.share.ShareManager
|
|||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents.SendScreenSource
|
||||
import com.tangem.features.send.v2.common.CommonSendRoute
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.SendScreenSource
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.send.success.SendConfirmSuccessComponent
|
||||
import com.tangem.features.send.v2.send.ui.state.SendUM
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ import com.tangem.core.ui.decompose.ComposableContentComponent
|
|||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.features.nft.component.NFTDetailsBlockComponent
|
||||
import com.tangem.features.send.v2.api.NFTSendComponent
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
|
||||
import com.tangem.features.send.v2.common.CommonSendRoute
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.common.ui.SendContent
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.FEE_TYPE
|
|||
import com.tangem.core.analytics.models.AnalyticsParam.Key.NONCE
|
||||
import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM
|
||||
import com.tangem.core.ui.extensions.capitalize
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
|
||||
|
||||
/**
|
||||
* Send screen analytics
|
||||
|
|
|
|||
|
|
@ -22,23 +22,23 @@ import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
|||
import com.tangem.domain.feedback.models.BlockchainErrorInfo
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.requireColdWallet
|
||||
import com.tangem.domain.settings.IsSendTapHelpEnabledUseCase
|
||||
import com.tangem.domain.settings.NeverShowTapHelpUseCase
|
||||
import com.tangem.domain.transaction.usecase.CreateNFTTransferTransactionUseCase
|
||||
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
|
||||
import com.tangem.domain.models.wallet.requireColdWallet
|
||||
import com.tangem.features.nft.entity.NFTSendSuccessTrigger
|
||||
import com.tangem.features.send.v2.api.SendNotificationsComponent
|
||||
import com.tangem.features.send.v2.api.SendNotificationsComponent.Params.NotificationData
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents.SendScreenSource
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
|
||||
import com.tangem.features.send.v2.api.subcomponents.notifications.SendNotificationsUpdateListener
|
||||
import com.tangem.features.send.v2.api.subcomponents.notifications.SendNotificationsUpdateTrigger
|
||||
import com.tangem.features.send.v2.common.CommonSendRoute
|
||||
import com.tangem.features.send.v2.common.SendBalanceUpdater
|
||||
import com.tangem.features.send.v2.common.SendConfirmAlertFactory
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.SendScreenSource
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.sendnft.analytics.NFTSendAnalyticHelper
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ import com.tangem.core.ui.extensions.wrappedList
|
|||
import com.tangem.core.ui.utils.parseToBigDecimal
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.utils.formatFooterFiatFee
|
||||
import com.tangem.features.send.v2.api.utils.getTronTokenFeeSendingText
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.checkIfFeeTooHigh
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM
|
||||
|
|
|
|||
|
|
@ -30,14 +30,14 @@ import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
|
|||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.features.send.v2.api.SendFeatureToggles
|
||||
import com.tangem.features.send.v2.api.entity.PredefinedValues
|
||||
import com.tangem.features.send.v2.api.subcomponents.amount.analytics.CommonSendAmountAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.subcomponents.amount.analytics.CommonSendAmountAnalyticEvents.SelectedCurrencyType
|
||||
import com.tangem.features.send.v2.api.subcomponents.feeSelector.FeeSelectorReloadTrigger
|
||||
import com.tangem.features.send.v2.common.CommonSendRoute
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.subcomponents.amount.SendAmountComponentParams
|
||||
import com.tangem.features.send.v2.subcomponents.amount.SendAmountReduceListener
|
||||
import com.tangem.features.send.v2.subcomponents.amount.SendAmountUpdateListener
|
||||
import com.tangem.features.send.v2.subcomponents.amount.analytics.SendAmountAnalyticEvents
|
||||
import com.tangem.features.send.v2.subcomponents.amount.analytics.SendAmountAnalyticEvents.SelectedCurrencyType
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeData
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeReloadTrigger
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -218,7 +218,7 @@ internal class SendAmountModel @Inject constructor(
|
|||
),
|
||||
)
|
||||
analyticsEventHandler.send(
|
||||
SendAmountAnalyticEvents.MaxAmountButtonClicked(categoryName = analyticsCategoryName),
|
||||
CommonSendAmountAnalyticEvents.MaxAmountButtonClicked(categoryName = analyticsCategoryName),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -229,7 +229,7 @@ internal class SendAmountModel @Inject constructor(
|
|||
override fun onAmountNext() {
|
||||
(uiState.value as? AmountState.Data)?.amountTextField?.isFiatValue?.let { isFiatSelected ->
|
||||
analyticsEventHandler.send(
|
||||
SendAmountAnalyticEvents.SelectedCurrency(
|
||||
CommonSendAmountAnalyticEvents.SelectedCurrency(
|
||||
categoryName = analyticsCategoryName,
|
||||
type = if (isFiatSelected) {
|
||||
SelectedCurrencyType.AppCurrency
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@ import com.tangem.domain.transaction.usecase.ValidateWalletMemoUseCase
|
|||
import com.tangem.domain.txhistory.usecase.GetFixedTxHistoryItemsUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.send.v2.api.SendFeatureToggles
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents.SendScreenSource
|
||||
import com.tangem.features.send.v2.api.entity.PredefinedValues
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams.DestinationBlockParams
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.SendScreenSource
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.subcomponents.destination.analytics.EnterAddressSource
|
||||
import com.tangem.features.send.v2.subcomponents.destination.analytics.SendDestinationAnalyticEvents
|
||||
|
|
|
|||
|
|
@ -11,14 +11,13 @@ import com.tangem.core.decompose.model.ParamsContainer
|
|||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.transaction.usecase.IsFeeApproximateUseCase
|
||||
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.NonceInserted
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.subcomponents.feeSelector.analytics.CommonSendFeeAnalyticEvents
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadListener
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadTrigger
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeComponentParams
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeReloadListener
|
||||
import com.tangem.features.send.v2.subcomponents.fee.analytics.SendFeeAnalyticEvents
|
||||
import com.tangem.features.send.v2.subcomponents.fee.analytics.SendFeeAnalyticEvents.GasPriceInserter
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.transformers.*
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeType
|
||||
|
|
@ -112,7 +111,7 @@ internal class SendFeeModel @Inject constructor(
|
|||
updateFeeNotifications()
|
||||
if (feeType == FeeType.Custom) {
|
||||
analyticsEventHandler.send(
|
||||
SendFeeAnalyticEvents.CustomFeeButtonClicked(categoryName = analyticsCategoryName),
|
||||
CommonSendFeeAnalyticEvents.CustomFeeButtonClicked(categoryName = analyticsCategoryName),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -155,10 +154,12 @@ internal class SendFeeModel @Inject constructor(
|
|||
val isCustomFeeEdited =
|
||||
feeSelectorUM.selectedFee?.amount?.value != feeSelectorUM.fees.normal.amount.value
|
||||
if (feeSelectorUM.selectedType == FeeType.Custom && isCustomFeeEdited) {
|
||||
analyticsEventHandler.send(GasPriceInserter(categoryName = analyticsCategoryName))
|
||||
analyticsEventHandler.send(
|
||||
CommonSendFeeAnalyticEvents.GasPriceInserter(categoryName = analyticsCategoryName),
|
||||
)
|
||||
}
|
||||
analyticsEventHandler.send(
|
||||
SendFeeAnalyticEvents.SelectedFee(
|
||||
CommonSendFeeAnalyticEvents.SelectedFee(
|
||||
categoryName = analyticsCategoryName,
|
||||
feeType = feeSelectorUM.selectedType.toAnalyticType(feeSelectorUM),
|
||||
),
|
||||
|
|
@ -166,7 +167,7 @@ internal class SendFeeModel @Inject constructor(
|
|||
|
||||
if (feeSelectorUM.nonce != null) {
|
||||
analyticsEventHandler.send(
|
||||
NonceInserted(
|
||||
CommonSendAnalyticEvents.NonceInserted(
|
||||
categoryName = analyticsCategoryName,
|
||||
token = cryptoCurrencyStatus.currency.symbol,
|
||||
blockchain = cryptoCurrencyStatus.currency.network.name,
|
||||
|
|
|
|||
|
|
@ -80,8 +80,8 @@ reownWeb3 = "1.1.2"
|
|||
prettyLogger = "2.2.0"
|
||||
okHttp-prettyLogging = "3.1.0"
|
||||
chucker = "4.0.0"
|
||||
mlKit-barcodeScanning = "17.2.0"
|
||||
androidXCamera = "1.3.0"
|
||||
mlKit-barcodeScanning = "17.3.0"
|
||||
androidXCamera = "1.4.2"
|
||||
listenableFuture = "1.0"
|
||||
swipeRefreshLayout = "1.1.0"
|
||||
web3j = "4.12.3-SNAPSHOT"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue