Updated on 2026-08-14

This commit is contained in:
Tangem 2023-02-08 15:07:02 +03:00
parent e15e633ee1
commit 5dba95e1ca
228 changed files with 338 additions and 37 deletions

View file

@ -25,5 +25,4 @@ data class ApprovePermissionButton(
data class CancelPermissionButton(
val enabled: Boolean,
val onClick: () -> Unit,
)

View file

@ -4,7 +4,6 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.OnBackPressedCallback
import androidx.compose.animation.Crossfade
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.ComposeView
@ -12,8 +11,8 @@ import androidx.core.view.WindowCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.tangem.feature.swap.router.CustomTabsManager
import com.tangem.feature.swap.router.SwapNavScreen
import com.tangem.feature.swap.router.SwapRouter
import com.tangem.feature.swap.router.SwapScreen
import com.tangem.feature.swap.ui.SwapScreen
import com.tangem.feature.swap.ui.SwapSelectTokenScreen
import com.tangem.feature.swap.ui.SwapSuccessScreen
@ -36,15 +35,6 @@ class SwapFragment : Fragment() {
)
viewModel.onScreenOpened()
activity?.onBackPressedDispatcher?.addCallback(
viewLifecycleOwner,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
viewModel.uiState.onBackClicked()
}
},
)
return ComposeView(inflater.context).apply {
setContent {
ScreenContent(viewModel = viewModel)
@ -57,8 +47,8 @@ class SwapFragment : Fragment() {
private fun ScreenContent(viewModel: SwapViewModel) {
Crossfade(targetState = viewModel.currentScreen) { screen ->
when (screen) {
SwapScreen.Main -> SwapScreen(stateHolder = viewModel.uiState)
SwapScreen.Success -> {
SwapNavScreen.Main -> SwapScreen(stateHolder = viewModel.uiState)
SwapNavScreen.Success -> {
val successState = viewModel.uiState.successState
if (successState != null) {
SwapSuccessScreen(state = successState, viewModel.uiState.onBackClicked)
@ -66,7 +56,7 @@ class SwapFragment : Fragment() {
SwapScreen(stateHolder = viewModel.uiState)
}
}
SwapScreen.SelectToken -> {
SwapNavScreen.SelectToken -> {
val tokenState = viewModel.uiState.selectTokenState
if (tokenState != null) {
SwapSelectTokenScreen(

View file

@ -11,16 +11,16 @@ internal class SwapRouter(
private val customTabsManager: CustomTabsManager,
) {
var currentScreen by mutableStateOf(SwapScreen.Main)
var currentScreen by mutableStateOf(SwapNavScreen.Main)
private set
fun openScreen(screen: SwapScreen) {
fun openScreen(screen: SwapNavScreen) {
currentScreen = screen
}
fun back() {
if (currentScreen == SwapScreen.SelectToken) {
currentScreen = SwapScreen.Main
if (currentScreen == SwapNavScreen.SelectToken) {
currentScreen = SwapNavScreen.Main
} else {
fragmentManager.get()?.popBackStack()
}
@ -31,6 +31,6 @@ internal class SwapRouter(
}
}
enum class SwapScreen {
enum class SwapNavScreen {
Main, Success, SelectToken
}

View file

@ -241,7 +241,6 @@ internal class StateBuilder(val actions: UiActions) {
),
cancelButton = CancelPermissionButton(
enabled = true,
onClick = {},
),
)
}

View file

@ -1,6 +1,5 @@
package com.tangem.feature.swap.ui
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@ -32,8 +31,6 @@ import com.tangem.feature.swap.presentation.R
@Composable
fun SwapPermissionBottomSheetContent(data: SwapPermissionState.ReadyForRequest, onCancel: () -> Unit) {
BackHandler(onBack = onCancel)
Column(
modifier = Modifier
.background(color = TangemTheme.colors.background.primary)
@ -83,7 +80,6 @@ fun SwapPermissionBottomSheetContent(data: SwapPermissionState.ReadyForRequest,
text = stringResource(id = R.string.common_cancel),
modifier = Modifier.fillMaxWidth(),
onClick = {
data.cancelButton.onClick()
onCancel()
},
)
@ -142,7 +138,7 @@ private fun InformationItem(subtitle: String, value: String) {
text = value,
color = TangemTheme.colors.text.tertiary,
style = TangemTheme.typography.body2,
modifier = Modifier.padding(start = TangemTheme.dimens.spacing16)
modifier = Modifier.padding(start = TangemTheme.dimens.spacing16),
)
}
}
@ -204,7 +200,7 @@ private val previewData = SwapPermissionState.ReadyForRequest(
spenderAddress = "",
fee = "2,14$",
approveButton = ApprovePermissionButton(true) {},
cancelButton = CancelPermissionButton(true) {},
cancelButton = CancelPermissionButton(true),
)
//endregion preview

View file

@ -1,10 +1,12 @@
package com.tangem.feature.swap.ui
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.ModalBottomSheetLayout
import androidx.compose.material.ModalBottomSheetState
import androidx.compose.material.ModalBottomSheetValue
import androidx.compose.material.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
@ -14,6 +16,7 @@ import androidx.compose.ui.Modifier
import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.swap.models.SwapPermissionState
import com.tangem.feature.swap.models.SwapStateHolder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterialApi::class)
@ -24,6 +27,15 @@ internal fun SwapScreen(stateHolder: SwapStateHolder) {
initialValue = ModalBottomSheetValue.Hidden,
skipHalfExpanded = true,
)
BackHandler(
onBack = {
if (bottomSheetState.isVisible) {
hideBottomSheet(coroutineScope, stateHolder, bottomSheetState)
} else {
stateHolder.onBackClicked()
}
},
)
TangemTheme {
ModalBottomSheetLayout(
@ -32,10 +44,7 @@ internal fun SwapScreen(stateHolder: SwapStateHolder) {
SwapPermissionBottomSheetContent(
data = stateHolder.permissionState,
onCancel = {
coroutineScope.launch {
stateHolder.onCancelPermissionBottomSheet.invoke()
bottomSheetState.hide()
}
hideBottomSheet(coroutineScope, stateHolder, bottomSheetState)
},
)
} else {
@ -72,4 +81,16 @@ internal fun SwapScreen(stateHolder: SwapStateHolder) {
},
)
}
}
@OptIn(ExperimentalMaterialApi::class)
private fun hideBottomSheet(
coroutineScope: CoroutineScope,
stateHolder: SwapStateHolder,
bottomSheetState: ModalBottomSheetState,
) {
coroutineScope.launch {
stateHolder.onCancelPermissionBottomSheet.invoke()
bottomSheetState.hide()
}
}

View file

@ -23,7 +23,7 @@ import com.tangem.feature.swap.models.SwapStateHolder
import com.tangem.feature.swap.models.UiActions
import com.tangem.feature.swap.presentation.SwapFragment
import com.tangem.feature.swap.router.SwapRouter
import com.tangem.feature.swap.router.SwapScreen
import com.tangem.feature.swap.router.SwapNavScreen
import com.tangem.feature.swap.ui.StateBuilder
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.Debouncer
@ -69,7 +69,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 = SwapScreen.Main
var currentScreen = SwapNavScreen.Main
get() = swapRouter.currentScreen
init {
@ -90,11 +90,11 @@ internal class SwapViewModel @Inject constructor(
uiState = uiState.copy(
onBackClicked = router::back,
onSelectTokenClick = {
router.openScreen(SwapScreen.SelectToken)
router.openScreen(SwapNavScreen.SelectToken)
analyticsEventHandler.send(SwapEvents.ChooseTokenScreenOpened)
},
onSuccess = {
router.openScreen(SwapScreen.Success)
router.openScreen(SwapNavScreen.Success)
},
)
}
@ -235,7 +235,7 @@ internal class SwapViewModel @Inject constructor(
}
}
analyticsEventHandler.send(SwapEvents.SwapInProgressScreen)
swapRouter.openScreen(SwapScreen.Success)
swapRouter.openScreen(SwapNavScreen.Success)
}
else -> {
uiState = stateBuilder.createSwapErrorTransaction(uiState) {
@ -304,7 +304,7 @@ internal class SwapViewModel @Inject constructor(
toCurrency = toToken,
)
startLoadingQuotes(fromToken, toToken, lastAmount.value)
swapRouter.openScreen(SwapScreen.Main)
swapRouter.openScreen(SwapNavScreen.Main)
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before After
Before After