diff --git a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/providers/entity/BlockchainProvidersUM.kt b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/providers/entity/BlockchainProvidersUM.kt index 70a08b1976..f63f49d696 100644 --- a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/providers/entity/BlockchainProvidersUM.kt +++ b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/providers/entity/BlockchainProvidersUM.kt @@ -2,11 +2,13 @@ package com.tangem.feature.tester.presentation.providers.entity import androidx.compose.runtime.Immutable import com.tangem.blockchain.common.network.providers.ProviderType +import com.tangem.core.ui.components.fields.entity.SearchBarUM import com.tangem.feature.tester.presentation.common.components.appbar.TopBarWithRefreshUM import kotlinx.collections.immutable.ImmutableList internal data class BlockchainProvidersUM( val topBar: TopBarWithRefreshUM, + val searchBar: SearchBarUM, val blockchainProviders: ImmutableList, ) { diff --git a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/providers/ui/BlockchainProvidersScreen.kt b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/providers/ui/BlockchainProvidersScreen.kt index 2623f47666..fab6c7afac 100644 --- a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/providers/ui/BlockchainProvidersScreen.kt +++ b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/providers/ui/BlockchainProvidersScreen.kt @@ -24,22 +24,29 @@ import androidx.compose.ui.draw.rotate import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastForEachIndexed +import com.tangem.blockchain.common.network.providers.ProviderType import com.tangem.core.ui.components.AdditionalTextInputDialogUM import com.tangem.core.ui.components.DialogButtonUM import com.tangem.core.ui.components.TextInputDialog +import com.tangem.core.ui.components.fields.SearchBar +import com.tangem.core.ui.components.fields.entity.SearchBarUM import com.tangem.core.ui.components.rows.RowText import com.tangem.core.ui.extensions.getActiveIconRes import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview import com.tangem.feature.tester.impl.R import com.tangem.feature.tester.presentation.common.components.appbar.TopBarWithRefresh +import com.tangem.feature.tester.presentation.common.components.appbar.TopBarWithRefreshUM import com.tangem.feature.tester.presentation.common.components.notification.CustomSetupNotification import com.tangem.feature.tester.presentation.providers.entity.BlockchainProvidersUM import com.tangem.feature.tester.presentation.providers.entity.BlockchainProvidersUM.ProviderUM import com.tangem.feature.tester.presentation.providers.entity.BlockchainProvidersUM.ProvidersUM +import kotlinx.collections.immutable.persistentListOf private const val CHEVRON_ROTATION_EXPANDED = 180f private const val CHEVRON_ROTATION_COLLAPSED = 0f @@ -53,7 +60,9 @@ internal fun BlockchainProvidersScreen(state: BlockchainProvidersUM) { .background(TangemTheme.colors.background.primary), ) { LazyColumn { - stickyHeader { TopBarWithRefresh(state = state.topBar) } + stickyHeader { + Header(topBar = state.topBar, searchBar = state.searchBar) + } if (state.topBar.refreshButton.isVisible) { item(key = "notification", contentType = "notification") { @@ -79,6 +88,22 @@ internal fun BlockchainProvidersScreen(state: BlockchainProvidersUM) { } } +@Composable +private fun Header(topBar: TopBarWithRefreshUM, searchBar: SearchBarUM) { + Column( + modifier = Modifier.background(TangemTheme.colors.background.primary), + verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8), + ) { + TopBarWithRefresh(state = topBar) + SearchBar( + state = searchBar, + modifier = Modifier + .padding(horizontal = 16.dp) + .padding(bottom = TangemTheme.dimens.spacing12), + ) + } +} + @Composable private fun BlockchainProvidersItem(state: ProvidersUM) { var isExpanded by remember { mutableStateOf(state.isExpanded) } @@ -361,4 +386,48 @@ private class ProvidersDnDTarget( return true } +} + +@Preview +@Composable +private fun Preview_BlockchainProvidersScreen() { + TangemThemePreview { + BlockchainProvidersScreen( + state = BlockchainProvidersUM( + topBar = TopBarWithRefreshUM( + titleResId = R.string.blockchain_providers, + onBackClick = {}, + refreshButton = TopBarWithRefreshUM.RefreshButton( + isVisible = true, + onRefreshClick = { }, + ), + ), + searchBar = SearchBarUM( + placeholderText = resourceReference(R.string.manage_tokens_search_placeholder), + query = "", + onQueryChange = {}, + isActive = false, + onActiveChange = {}, + ), + blockchainProviders = persistentListOf( + ProvidersUM( + blockchainId = "ETH", + blockchainName = "Ethereum", + blockchainSymbol = "ETH", + isExpanded = false, + onDrop = { _, _ -> }, + addPublicProviderDialog = BlockchainProvidersUM.AddPublicProviderDialogUM( + hasError = false, + onValueChange = {}, + onSaveClick = {}, + ), + providers = persistentListOf( + ProviderUM(type = ProviderType.NowNodes), + ProviderUM(type = ProviderType.GetBlock), + ), + ), + ), + ), + ) + } } \ No newline at end of file diff --git a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/providers/viewmodel/BlockchainProvidersViewModel.kt b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/providers/viewmodel/BlockchainProvidersViewModel.kt index e1157cac8b..97cf7d9d36 100644 --- a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/providers/viewmodel/BlockchainProvidersViewModel.kt +++ b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/providers/viewmodel/BlockchainProvidersViewModel.kt @@ -7,6 +7,8 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.network.providers.ProviderType import com.tangem.blockchainsdk.providers.BlockchainProvidersTypesManager import com.tangem.blockchainsdk.providers.MutableBlockchainProvidersTypesManager +import com.tangem.core.ui.components.fields.entity.SearchBarUM +import com.tangem.core.ui.extensions.resourceReference import com.tangem.feature.tester.impl.R import com.tangem.feature.tester.presentation.common.components.appbar.TopBarWithRefreshUM import com.tangem.feature.tester.presentation.navigation.InnerTesterRouter @@ -34,10 +36,21 @@ internal class BlockchainProvidersViewModel @Inject constructor( onBackClick = {}, refreshButton = TopBarWithRefreshUM.RefreshButton(isVisible = false, onRefreshClick = ::onRefreshClick), ), + searchBar = SearchBarUM( + placeholderText = resourceReference(R.string.manage_tokens_search_placeholder), + query = "", + onQueryChange = { + searchQuery.value = it.trim() + }, + isActive = false, + onActiveChange = {}, + ), blockchainProviders = persistentListOf(), ), ) + private val searchQuery = MutableStateFlow(value = "") + private val manager = blockchainProvidersTypesManager as MutableBlockchainProvidersTypesManager init { @@ -53,8 +66,12 @@ internal class BlockchainProvidersViewModel @Inject constructor( } private fun subscribeOnBlockchainProviderTypesUpdates() { - manager.get() - .onEach { blockchainProviderTypes -> + combine( + flow = manager.get(), + flow2 = searchQuery, + transform = { blockchainProviderTypes, query -> blockchainProviderTypes to query }, + ) + .onEach { (blockchainProviderTypes, query) -> val isChanged = !manager.isMatchWithMerged() _state.update { state -> @@ -62,7 +79,13 @@ internal class BlockchainProvidersViewModel @Inject constructor( topBar = state.topBar.copy( refreshButton = state.topBar.refreshButton.copy(isVisible = isChanged), ), - blockchainProviders = blockchainProviderTypes.toProvidersUM(), + searchBar = state.searchBar.copy(query = query), + blockchainProviders = blockchainProviderTypes + .filter { + it.key.fullName.contains(other = query, ignoreCase = true) || + it.key.currency.contains(other = query, ignoreCase = true) + } + .toProvidersUM(), ) } } @@ -87,6 +110,7 @@ internal class BlockchainProvidersViewModel @Inject constructor( ), ) } + .sortedBy(ProvidersUM::blockchainName) .toImmutableList() } @@ -153,10 +177,12 @@ internal class BlockchainProvidersViewModel @Inject constructor( // Before: [a, b, c, d, e]; previous = 0 (a), current = 4 (e) // After: [e, b, c, d, a] private fun List.replaceElements(prev: Int, current: Int): List { - return toMutableList().apply { - set(prev, this[current]) - set(current, this[prev]) - } + val mutableList = toMutableList() + + mutableList[prev] = this[current] + mutableList[current] = this[prev] + + return mutableList } private fun onPublicProviderUrlChange(id: String, url: String) {