Updated on 2026-08-14

This commit is contained in:
Tangem 2024-12-02 17:37:19 +04:00
parent 9315fd5b15
commit eaa676e9f5
6 changed files with 79 additions and 30 deletions

View file

@ -0,0 +1,33 @@
package com.tangem.core.ui.utils
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.SoftwareKeyboardController
/**
* [NestedScrollConnection] that calls [SoftwareKeyboardController.hide] on pre scroll
*
* @property keyboardController keyboard controller
*
[REDACTED_AUTHOR]
*/
private class HideKeyboardNestedScrollConnection(
private val keyboardController: SoftwareKeyboardController?,
) : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
keyboardController?.hide()
return super.onPreScroll(available, source)
}
}
@Composable
fun rememberHideKeyboardNestedScrollConnection(): NestedScrollConnection {
val keyboardController = LocalSoftwareKeyboardController.current
return remember { HideKeyboardNestedScrollConnection(keyboardController = keyboardController) }
}

View file

@ -20,12 +20,8 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@ -65,6 +61,7 @@ import com.tangem.core.ui.res.LocalSnackbarHostState
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.utils.WindowInsetsZero
import com.tangem.core.ui.utils.rememberHideKeyboardNestedScrollConnection
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.managetokens.component.ManageTokensComponent
import com.tangem.features.managetokens.component.ManageTokensSource
@ -82,16 +79,7 @@ private const val LOAD_ITEMS_BUFFER = 10
@Composable
internal fun ManageTokensScreen(state: ManageTokensUM, modifier: Modifier = Modifier) {
val keyboardController = LocalSoftwareKeyboardController.current
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
keyboardController?.hide()
return super.onPreScroll(available, source)
}
}
}
val nestedScrollConnection = rememberHideKeyboardNestedScrollConnection()
Scaffold(
modifier = modifier.nestedScroll(nestedScrollConnection),

View file

@ -6,14 +6,9 @@ import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.FabPosition
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
@ -29,6 +24,7 @@ import com.tangem.core.ui.res.LocalSnackbarHostState
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.utils.WindowInsetsZero
import com.tangem.core.ui.utils.rememberHideKeyboardNestedScrollConnection
import com.tangem.features.managetokens.component.OnboardingManageTokensComponent
import com.tangem.features.managetokens.component.preview.PreviewOnboardingManageTokensComponent
import com.tangem.features.managetokens.entity.managetokens.OnboardingManageTokensUM
@ -36,16 +32,7 @@ import com.tangem.features.managetokens.impl.R
@Composable
internal fun OnboardingManageTokensContent(state: OnboardingManageTokensUM, modifier: Modifier = Modifier) {
val keyboardController = LocalSoftwareKeyboardController.current
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
keyboardController?.hide()
return super.onPreScroll(available, source)
}
}
}
val nestedScrollConnection = rememberHideKeyboardNestedScrollConnection()
Scaffold(
modifier = modifier.nestedScroll(nestedScrollConnection),

View file

@ -9,10 +9,12 @@ import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.rememberHideKeyboardNestedScrollConnection
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.selecttoken.entity.OnrampOperationUM
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
@ -26,8 +28,10 @@ internal fun OnrampSelectToken(
) {
BackHandler(onBack = state.onBackClick)
val nestedScrollConnection = rememberHideKeyboardNestedScrollConnection()
LazyColumn(
modifier = modifier
.nestedScroll(nestedScrollConnection)
.background(TangemTheme.colors.background.secondary)
.imePadding()
.systemBarsPadding(),

View file

@ -8,12 +8,16 @@ import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.rememberHideKeyboardNestedScrollConnection
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.swap.availablepairs.AvailableSwapPairsComponent
import com.tangem.features.onramp.swap.entity.ExchangeCardUM
@ -40,11 +44,16 @@ internal fun SwapSelectTokens(
) {
BackHandler(onBack = state.onBackClick)
val nestedScrollConnection = rememberHideKeyboardNestedScrollConnection()
val lazyListState = rememberLazyListState()
LazyColumn(
modifier = modifier
.nestedScroll(nestedScrollConnection)
.background(TangemTheme.colors.background.secondary)
.imePadding()
.systemBarsPadding(),
state = lazyListState,
contentPadding = PaddingValues(bottom = 8.dp),
) {
stickyHeader(key = "header") {
@ -98,4 +107,9 @@ internal fun SwapSelectTokens(
}
}
}
// scroll to top after "from" token selection
LaunchedEffect(state.exchangeFrom !is ExchangeCardUM.Empty) {
lazyListState.scrollToItem(index = 0)
}
}

View file

@ -24,7 +24,24 @@ internal class SwapRouter(
if (currentScreen == SwapNavScreen.SelectToken) {
currentScreen = SwapNavScreen.Main
} else {
router.pop()
val selectTokensIndex = router.stack.getSelectTokensRouteIndexOrNull()
/*
* If select token screen is not in stack, then just pop to previous screen.
* Otherwise, pop to previous screen that was before select token screen.
*/
if (selectTokensIndex == null) {
router.pop()
} else {
// find previous screen that was before select token
val prevRoute = router.stack.getOrNull(index = selectTokensIndex - 1)
if (prevRoute != null) {
router.popTo(prevRoute)
} else {
router.pop()
}
}
}
}
@ -46,6 +63,12 @@ internal class SwapRouter(
}
}
}
private fun List<AppRoute>.getSelectTokensRouteIndexOrNull(): Int? {
return this
.indexOfFirst { it::class == AppRoute.SwapCrypto::class }
.takeIf { it != -1 }
}
}
enum class SwapNavScreen {