Updated on 2026-08-14

This commit is contained in:
Tangem 2025-01-10 18:26:40 +03:00
parent ebe3b78647
commit 89d38f5ab0
3 changed files with 105 additions and 8 deletions

View file

@ -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<ProvidersUM>,
) {

View file

@ -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),
),
),
),
),
)
}
}

View file

@ -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<ProviderUM>.replaceElements(prev: Int, current: Int): List<ProviderUM> {
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) {