From eaa676e9f51e71bb2f6e7a6960caf360cfe707d8 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 2 Dec 2024 17:37:19 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../HideKeyboardNestedScrollConnection.kt | 33 +++++++++++++++++++ .../managetokens/ui/ManageTokensScreen.kt | 16 ++------- .../ui/OnboardingManageTokensContent.kt | 17 ++-------- .../selecttoken/ui/OnrampSelectToken.kt | 4 +++ .../onramp/swap/ui/SwapSelectTokens.kt | 14 ++++++++ .../tangem/feature/swap/router/SwapRouter.kt | 25 +++++++++++++- 6 files changed, 79 insertions(+), 30 deletions(-) create mode 100644 core/ui/src/main/java/com/tangem/core/ui/utils/HideKeyboardNestedScrollConnection.kt diff --git a/core/ui/src/main/java/com/tangem/core/ui/utils/HideKeyboardNestedScrollConnection.kt b/core/ui/src/main/java/com/tangem/core/ui/utils/HideKeyboardNestedScrollConnection.kt new file mode 100644 index 0000000000..4cdea96a77 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/utils/HideKeyboardNestedScrollConnection.kt @@ -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) } +} \ No newline at end of file diff --git a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/ManageTokensScreen.kt b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/ManageTokensScreen.kt index 3a85636b3e..f7643e76c1 100644 --- a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/ManageTokensScreen.kt +++ b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/ManageTokensScreen.kt @@ -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), diff --git a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/OnboardingManageTokensContent.kt b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/OnboardingManageTokensContent.kt index 04fd191d63..d40b7fb3e2 100644 --- a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/OnboardingManageTokensContent.kt +++ b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/OnboardingManageTokensContent.kt @@ -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), diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/ui/OnrampSelectToken.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/ui/OnrampSelectToken.kt index 174a8d1ba2..efbc6b5cfa 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/ui/OnrampSelectToken.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/ui/OnrampSelectToken.kt @@ -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(), diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/ui/SwapSelectTokens.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/ui/SwapSelectTokens.kt index b2c0e550bd..0b5d331ad5 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/ui/SwapSelectTokens.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/ui/SwapSelectTokens.kt @@ -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) + } } \ No newline at end of file diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/router/SwapRouter.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/router/SwapRouter.kt index 19b2c2dca6..dad11a62e1 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/router/SwapRouter.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/router/SwapRouter.kt @@ -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.getSelectTokensRouteIndexOrNull(): Int? { + return this + .indexOfFirst { it::class == AppRoute.SwapCrypto::class } + .takeIf { it != -1 } + } } enum class SwapNavScreen {