diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/appbar/AppBarWithSearch.kt b/core/ui/src/main/java/com/tangem/core/ui/components/appbar/AppBarWithSearch.kt index b10c630c32..55b0a08fe3 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/appbar/AppBarWithSearch.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/appbar/AppBarWithSearch.kt @@ -28,6 +28,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier 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.painter.Painter import androidx.compose.ui.platform.LocalFocusManager @@ -63,6 +64,7 @@ fun ExpandableSearchView( onBackClick: () -> Unit, onSearchChange: (String) -> Unit, onSearchDisplayClose: () -> Unit, + onFocusChange: (Boolean) -> Unit, title: String? = null, placeholderSearchText: String = "", expandedInitially: Boolean = false, @@ -79,6 +81,7 @@ fun ExpandableSearchView( onSearchChange = onSearchChange, onSearchDisplayClose = onSearchDisplayClose, onExpandedChange = onExpandedChanged, + onFocusChange = onFocusChange, tint = tint, ) } else { @@ -171,12 +174,14 @@ private fun SubtitleView(subtitle: String, icon: Painter?) { } } +@Suppress("LongParameterList") @Composable private fun ExpandedSearchView( placeholderSearchText: String, onSearchChange: (String) -> Unit, onSearchDisplayClose: () -> Unit, onExpandedChange: (Boolean) -> Unit, + onFocusChange: (Boolean) -> Unit, tint: Color, ) { val focusManager = LocalFocusManager.current @@ -216,7 +221,8 @@ private fun ExpandedSearchView( singleLine = true, modifier = Modifier .fillMaxWidth() - .focusRequester(textFieldFocusRequester), + .focusRequester(textFieldFocusRequester) + .onFocusChanged { onFocusChange(it.hasFocus) }, placeholder = { Text(text = placeholderSearchText) }, @@ -245,6 +251,7 @@ private fun CollapsedSearchViewPreview() { placeholderSearchText = "Search", onSearchChange = {}, onSearchDisplayClose = {}, + onFocusChange = {}, subtitle = "Ethereum", icon = painterResource(id = R.drawable.img_eth_22), ) @@ -262,6 +269,7 @@ private fun ExpandedSearchViewPreview() { onSearchChange = {}, expandedInitially = true, onSearchDisplayClose = {}, + onFocusChange = {}, ) } } \ No newline at end of file diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt index cacf9a5bd4..0910eefc5f 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt @@ -20,6 +20,7 @@ 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, diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/UiActions.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/UiActions.kt index 5273bc3b30..9fea79221a 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/UiActions.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/UiActions.kt @@ -2,6 +2,7 @@ package com.tangem.feature.swap.models data class UiActions( val onSearchEntered: (String) -> Unit, + val onSearchFocusChange: (Boolean) -> Unit, val onTokenSelected: (String) -> Unit, val onAmountChanged: (String) -> Unit, val onAmountSelected: (Boolean) -> Unit, diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt index 5b78f92a71..2f4911d75a 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt @@ -61,6 +61,7 @@ class SwapFragment : Fragment() { if (tokenState != null) { SwapSelectTokenScreen( state = tokenState, + onSearchFocusChange = viewModel.uiState.onSearchFocusChange, onBack = viewModel.uiState.onBackClicked, ) } else { diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt index 0e3878c821..34ce93172d 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt @@ -26,6 +26,7 @@ import com.tangem.feature.swap.models.UiActions /** * State builder creates a specific states for SwapScreen */ +@Suppress("LargeClass") internal class StateBuilder(val actions: UiActions) { private val tokensDataConverter = TokensDataConverter(actions.onSearchEntered, actions.onTokenSelected) @@ -60,6 +61,7 @@ internal class StateBuilder(val actions: UiActions) { networkCurrency = networkInfo.blockchainCurrency, swapButton = SwapButton(enabled = false, loading = true, onClick = {}), onRefresh = {}, + onSearchFocusChange = actions.onSearchFocusChange, onBackClicked = actions.onBackClicked, onChangeCardsClicked = actions.onChangeCardsClicked, onMaxAmountSelected = actions.onMaxAmountSelected, @@ -319,7 +321,13 @@ internal class StateBuilder(val actions: UiActions) { onClick: () -> Unit, ): SwapStateHolder { val renewWarnings = uiState.warnings.filterNot { it is SwapWarning.GenericWarning }.toMutableList() - renewWarnings.add(SwapWarning.GenericWarning(message, shouldWrapMessage = shouldWrapMessage, onClick = onClick)) + renewWarnings.add( + SwapWarning.GenericWarning( + message = message, + shouldWrapMessage = shouldWrapMessage, + onClick = onClick, + ), + ) return uiState.copy( warnings = renewWarnings, ) diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt index c71240070f..d684b65c7b 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt @@ -390,9 +390,12 @@ private val state = SwapStateHolder( warnings = listOf(SwapWarning.PermissionNeeded("DAI")), networkCurrency = "MATIC", swapButton = SwapButton(enabled = true, loading = false, onClick = {}), - onRefresh = {}, onBackClicked = {}, onChangeCardsClicked = {}, + onRefresh = {}, + onBackClicked = {}, + onChangeCardsClicked = {}, permissionState = SwapPermissionState.InProgress, blockchainId = "POLYGON", + onSearchFocusChange = {}, // alert = SwapWarning.GenericWarning("There was an error. Please try again.") {}, ) diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapSelectTokenScreen.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapSelectTokenScreen.kt index 9d83769508..04ece1204a 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapSelectTokenScreen.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapSelectTokenScreen.kt @@ -44,7 +44,11 @@ import com.tangem.feature.swap.presentation.R import com.valentinilk.shimmer.shimmer @Composable -fun SwapSelectTokenScreen(state: SwapSelectTokenStateHolder, onBack: () -> Unit) { +fun SwapSelectTokenScreen( + state: SwapSelectTokenStateHolder, + onSearchFocusChange: (Boolean) -> Unit, + onBack: () -> Unit, +) { TangemTheme { Scaffold( content = { padding -> @@ -57,6 +61,7 @@ fun SwapSelectTokenScreen(state: SwapSelectTokenStateHolder, onBack: () -> Unit) placeholderSearchText = stringResource(id = R.string.search_tokens_title), onSearchChange = state.onSearchEntered, onSearchDisplayClose = { state.onSearchEntered("") }, + onFocusChange = onSearchFocusChange, subtitle = state.network.name, icon = painterResource(id = getActiveIconRes(state.network.blockchainId)), ) @@ -264,6 +269,7 @@ private fun TokenScreenPreview() { onTokenSelected = {}, network = Network("Ethereum", "ETH"), ), + onSearchFocusChange = {}, onBack = {}, ) } \ No newline at end of file diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt index 68daa1ca45..bc58f26eb1 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt @@ -379,10 +379,7 @@ internal class SwapViewModel @Inject constructor( private fun createUiActions(): UiActions { return UiActions( onSearchEntered = { onSearchEntered(it) }, - onTokenSelected = { - onTokenSelect(it) - analyticsEventHandler.send(SwapEvents.SearchTokenClicked) - }, + onTokenSelected = { onTokenSelect(it) }, onAmountChanged = { onAmountChanged(it) }, onSwapClick = { onSwapClick() @@ -414,6 +411,11 @@ internal class SwapViewModel @Inject constructor( analyticsEventHandler.send(SwapEvents.ButtonPermissionCancelClicked) }, onAmountSelected = { onAmountSelected(it) }, + onSearchFocusChange = { focused -> + if (focused) { + analyticsEventHandler.send(SwapEvents.SearchTokenClicked) + } + }, ) }