Updated on 2026-08-14

This commit is contained in:
Tangem 2025-01-06 18:23:30 +03:00
parent a98ecb4182
commit 6417281c76
11 changed files with 165 additions and 116 deletions

View file

@ -0,0 +1,18 @@
package com.tangem.feature.tester.presentation.common.components.appbar
import androidx.compose.runtime.Composable
import com.tangem.core.ui.components.appbar.AppBarWithBackButtonAndIcon
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.tester.impl.R
@Composable
internal fun TopBarWithRefresh(state: TopBarWithRefreshUM) {
AppBarWithBackButtonAndIcon(
onBackClick = state.onBackClick,
text = stringResourceSafe(state.titleResId),
iconRes = R.drawable.ic_refresh_24.takeIf { state.refreshButton.isVisible },
onIconClick = state.refreshButton.onRefreshClick,
backgroundColor = TangemTheme.colors.background.primary,
)
}

View file

@ -0,0 +1,12 @@
package com.tangem.feature.tester.presentation.common.components.appbar
import androidx.annotation.StringRes
internal data class TopBarWithRefreshUM(
@StringRes val titleResId: Int,
val onBackClick: () -> Unit,
val refreshButton: RefreshButton,
) {
data class RefreshButton(val isVisible: Boolean, val onRefreshClick: () -> Unit)
}

View file

@ -0,0 +1,21 @@
package com.tangem.feature.tester.presentation.common.components.notification
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.tangem.core.ui.components.notifications.Notification
import com.tangem.core.ui.components.notifications.NotificationConfig
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.feature.tester.impl.R
@Composable
internal fun CustomSetupNotification(subtitle: TextReference, modifier: Modifier = Modifier) {
Notification(
config = NotificationConfig(
subtitle = subtitle,
iconResId = R.drawable.ic_alert_triangle_20,
title = resourceReference(id = R.string.custom_setup_warning_title),
),
modifier = modifier,
)
}

View file

@ -114,7 +114,7 @@ private fun TogglesNotification(appVersion: String, isVisible: Boolean, modifier
wrappedList(appVersion), wrappedList(appVersion),
), ),
iconResId = R.drawable.ic_alert_triangle_20, iconResId = R.drawable.ic_alert_triangle_20,
title = resourceReference(id = R.string.feature_toggles_custom_setup_warning_title), title = resourceReference(id = R.string.custom_setup_warning_title),
), ),
) )
} }

View file

@ -1,42 +1,22 @@
package com.tangem.feature.tester.presentation.featuretoggles.state package com.tangem.feature.tester.presentation.featuretoggles.state
import com.tangem.feature.tester.presentation.common.components.appbar.TopBarWithRefreshUM
import com.tangem.feature.tester.presentation.featuretoggles.models.TesterFeatureToggle import com.tangem.feature.tester.presentation.featuretoggles.models.TesterFeatureToggle
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
/** /**
* Content state of feature toggles screen * Content state of feature toggles screen
* *
* @property topBarState top bar state * @property topBar top bar state
* @property appVersion app version * @property appVersion app version
* @property featureToggles feature toggles list * @property featureToggles feature toggles list
* @property onBackClick the lambda to be invoked when back button is pressed
* @property onToggleValueChange the lambda to be invoked when switch button is pressed * @property onToggleValueChange the lambda to be invoked when switch button is pressed
* @property onRestartAppClick the lambda to be invoked when restart app button is pressed * @property onRestartAppClick the lambda to be invoked when restart app button is pressed
*/ */
internal data class FeatureTogglesContentState( internal data class FeatureTogglesContentState(
val topBarState: TopBarState, val topBar: TopBarWithRefreshUM,
val appVersion: String, val appVersion: String,
val featureToggles: ImmutableList<TesterFeatureToggle>, val featureToggles: ImmutableList<TesterFeatureToggle>,
val onBackClick: () -> Unit,
val onToggleValueChange: (String, Boolean) -> Unit, val onToggleValueChange: (String, Boolean) -> Unit,
val onRestartAppClick: () -> Unit, val onRestartAppClick: () -> Unit,
) { )
/** Top bar state */
sealed interface TopBarState {
/**
* Config setup
*
* @property onBackClick the lambda to be invoked when back button is pressed
*/
data object ConfigSetup : TopBarState
/**
* Custom setup
*
* @property onRecoverClick the lambda to be invoked when recover button is pressed
*/
data class CustomSetup(val onRecoverClick: () -> Unit) : TopBarState
}
}

View file

@ -15,15 +15,15 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.PrimaryButton import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.components.TangemSwitch import com.tangem.core.ui.components.TangemSwitch
import com.tangem.core.ui.components.appbar.AppBarWithBackButtonAndIcon
import com.tangem.core.ui.components.notifications.Notification
import com.tangem.core.ui.components.notifications.NotificationConfig
import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.extensions.wrappedList import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.feature.tester.impl.R 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.featuretoggles.models.TesterFeatureToggle import com.tangem.feature.tester.presentation.featuretoggles.models.TesterFeatureToggle
import com.tangem.feature.tester.presentation.featuretoggles.state.FeatureTogglesContentState import com.tangem.feature.tester.presentation.featuretoggles.state.FeatureTogglesContentState
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@ -41,12 +41,15 @@ internal fun FeatureTogglesScreen(state: FeatureTogglesContentState) {
.fillMaxSize() .fillMaxSize()
.background(TangemTheme.colors.background.secondary), .background(TangemTheme.colors.background.secondary),
) { ) {
stickyHeader { TopAppBar(state = state.topBarState, onBackClick = state.onBackClick) } stickyHeader { TopBarWithRefresh(state = state.topBar) }
if (state.topBarState is FeatureTogglesContentState.TopBarState.CustomSetup) { if (state.topBar.refreshButton.isVisible) {
item(key = "warning_notification", contentType = "warning_notification") { item(key = "warning_notification", contentType = "warning_notification") {
WarningNotification( CustomSetupNotification(
appVersion = state.appVersion, subtitle = resourceReference(
id = R.string.feature_toggles_custom_setup_warning_description,
wrappedList(state.appVersion),
),
modifier = Modifier modifier = Modifier
.animateItem() .animateItem()
.padding(horizontal = 16.dp) .padding(horizontal = 16.dp)
@ -78,39 +81,6 @@ internal fun FeatureTogglesScreen(state: FeatureTogglesContentState) {
} }
} }
@Composable
private fun TopAppBar(state: FeatureTogglesContentState.TopBarState, onBackClick: () -> Unit) {
AppBarWithBackButtonAndIcon(
onBackClick = onBackClick,
text = stringResourceSafe(id = R.string.feature_toggles),
iconRes = if (state is FeatureTogglesContentState.TopBarState.CustomSetup) {
R.drawable.ic_refresh_24
} else {
null
},
onIconClick = if (state is FeatureTogglesContentState.TopBarState.CustomSetup) {
state.onRecoverClick
} else {
null
},
)
}
@Composable
private fun WarningNotification(appVersion: String, modifier: Modifier = Modifier) {
Notification(
config = NotificationConfig(
subtitle = resourceReference(
id = R.string.feature_toggles_custom_setup_warning_description,
wrappedList(appVersion),
),
iconResId = R.drawable.ic_alert_triangle_20,
title = resourceReference(id = R.string.feature_toggles_custom_setup_warning_title),
),
modifier = modifier,
)
}
@Composable @Composable
private fun FeatureToggleItem(toggle: TesterFeatureToggle, onCheckedChange: (Boolean) -> Unit) { private fun FeatureToggleItem(toggle: TesterFeatureToggle, onCheckedChange: (Boolean) -> Unit) {
Row( Row(
@ -145,17 +115,19 @@ private fun PreviewFeatureTogglesScreen() {
FeatureTogglesScreen( FeatureTogglesScreen(
state = FeatureTogglesContentState( state = FeatureTogglesContentState(
topBarState = if (isCustomSetup) { topBar = TopBarWithRefreshUM(
FeatureTogglesContentState.TopBarState.CustomSetup(onRecoverClick = { isCustomSetup = false }) titleResId = R.string.feature_toggles,
} else { onBackClick = {},
FeatureTogglesContentState.TopBarState.ConfigSetup refreshButton = TopBarWithRefreshUM.RefreshButton(
}, isVisible = isCustomSetup,
onRefreshClick = { isCustomSetup = false },
),
),
appVersion = "5.15", appVersion = "5.15",
featureToggles = persistentListOf( featureToggles = persistentListOf(
TesterFeatureToggle(name = "FEATURE_TOGGLE_1", isEnabled = true), TesterFeatureToggle(name = "FEATURE_TOGGLE_1", isEnabled = true),
TesterFeatureToggle(name = "FEATURE_TOGGLE_2", isEnabled = false), TesterFeatureToggle(name = "FEATURE_TOGGLE_2", isEnabled = false),
), ),
onBackClick = {},
onToggleValueChange = { _, _ -> isCustomSetup = true }, onToggleValueChange = { _, _ -> isCustomSetup = true },
onRestartAppClick = {}, onRestartAppClick = {},
), ),

View file

@ -8,6 +8,8 @@ import androidx.lifecycle.viewModelScope
import com.tangem.core.configtoggle.feature.FeatureTogglesManager import com.tangem.core.configtoggle.feature.FeatureTogglesManager
import com.tangem.core.configtoggle.feature.MutableFeatureTogglesManager import com.tangem.core.configtoggle.feature.MutableFeatureTogglesManager
import com.tangem.core.navigation.finisher.AppFinisher import com.tangem.core.navigation.finisher.AppFinisher
import com.tangem.feature.tester.impl.R
import com.tangem.feature.tester.presentation.common.components.appbar.TopBarWithRefreshUM
import com.tangem.feature.tester.presentation.featuretoggles.models.TesterFeatureToggle import com.tangem.feature.tester.presentation.featuretoggles.models.TesterFeatureToggle
import com.tangem.feature.tester.presentation.featuretoggles.state.FeatureTogglesContentState import com.tangem.feature.tester.presentation.featuretoggles.state.FeatureTogglesContentState
import com.tangem.feature.tester.presentation.navigation.InnerTesterRouter import com.tangem.feature.tester.presentation.navigation.InnerTesterRouter
@ -45,22 +47,40 @@ internal class FeatureTogglesViewModel @Inject constructor(
/** Setup navigation state property by router [router] and provides app restart method by [appFinisher] */ /** Setup navigation state property by router [router] and provides app restart method by [appFinisher] */
fun setupInteractions(router: InnerTesterRouter, appFinisher: AppFinisher) { fun setupInteractions(router: InnerTesterRouter, appFinisher: AppFinisher) {
uiState = uiState.copy( uiState = uiState.copy(
onBackClick = router::back, topBar = uiState.topBar.copy(onBackClick = router::back),
onRestartAppClick = appFinisher::restart, onRestartAppClick = appFinisher::restart,
) )
} }
private fun initState(): FeatureTogglesContentState { private fun initState(): FeatureTogglesContentState {
return FeatureTogglesContentState( return FeatureTogglesContentState(
topBarState = getConfigSetupState(), topBar = getConfigSetupState(isPrimarySetup = true),
appVersion = appVersionProvider.versionName, appVersion = appVersionProvider.versionName,
featureToggles = mutableFeatureTogglesManager.getTesterFeatureToggles(), featureToggles = mutableFeatureTogglesManager.getTesterFeatureToggles(),
onToggleValueChange = ::onToggleValueChange, onToggleValueChange = ::onToggleValueChange,
onBackClick = {},
onRestartAppClick = {}, onRestartAppClick = {},
) )
} }
private fun getConfigSetupState(isPrimarySetup: Boolean): TopBarWithRefreshUM {
val isMatchLocalConfig = mutableFeatureTogglesManager.isMatchLocalConfig()
return if (isPrimarySetup) {
TopBarWithRefreshUM(
titleResId = R.string.feature_toggles,
onBackClick = {},
refreshButton = TopBarWithRefreshUM.RefreshButton(
isVisible = false,
onRefreshClick = ::onRefreshClick,
),
)
} else {
uiState.topBar.copy(
refreshButton = uiState.topBar.refreshButton.copy(isVisible = isMatchLocalConfig),
)
}
}
private fun onToggleValueChange(name: String, isEnabled: Boolean) { private fun onToggleValueChange(name: String, isEnabled: Boolean) {
viewModelScope.launch { viewModelScope.launch {
mutableFeatureTogglesManager.changeToggle(name = name, isEnabled = isEnabled) mutableFeatureTogglesManager.changeToggle(name = name, isEnabled = isEnabled)
@ -70,25 +90,17 @@ internal class FeatureTogglesViewModel @Inject constructor(
// delay for smoothly update animations // delay for smoothly update animations
delay(timeMillis = 300) delay(timeMillis = 300)
uiState = uiState.copy(topBarState = getConfigSetupState()) uiState = uiState.copy(topBar = getConfigSetupState(isPrimarySetup = false))
} }
} }
private fun getConfigSetupState(): FeatureTogglesContentState.TopBarState { private fun onRefreshClick() {
return if (mutableFeatureTogglesManager.isMatchLocalConfig()) { viewModelScope.launch {
FeatureTogglesContentState.TopBarState.ConfigSetup mutableFeatureTogglesManager.recoverLocalConfig()
} else {
FeatureTogglesContentState.TopBarState.CustomSetup(
onRecoverClick = {
viewModelScope.launch {
mutableFeatureTogglesManager.recoverLocalConfig()
uiState = uiState.copy( uiState = uiState.copy(
topBarState = getConfigSetupState(), topBar = getConfigSetupState(isPrimarySetup = false),
featureToggles = mutableFeatureTogglesManager.getTesterFeatureToggles(), featureToggles = mutableFeatureTogglesManager.getTesterFeatureToggles(),
)
}
},
) )
} }
} }

View file

@ -2,10 +2,11 @@ package com.tangem.feature.tester.presentation.providers.entity
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import com.tangem.blockchain.common.network.providers.ProviderType import com.tangem.blockchain.common.network.providers.ProviderType
import com.tangem.feature.tester.presentation.common.components.appbar.TopBarWithRefreshUM
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
internal data class BlockchainProvidersUM( internal data class BlockchainProvidersUM(
val onBackClick: () -> Unit, val topBar: TopBarWithRefreshUM,
val blockchainProviders: ImmutableList<ProvidersUM>, val blockchainProviders: ImmutableList<ProvidersUM>,
) { ) {

View file

@ -27,13 +27,13 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEachIndexed import androidx.compose.ui.util.fastForEachIndexed
import com.tangem.core.ui.components.SpacerH8
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.components.rows.RowText import com.tangem.core.ui.components.rows.RowText
import com.tangem.core.ui.extensions.getActiveIconRes import com.tangem.core.ui.extensions.getActiveIconRes
import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.tester.impl.R 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.notification.CustomSetupNotification
import com.tangem.feature.tester.presentation.providers.entity.BlockchainProvidersUM 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.ProviderUM
import com.tangem.feature.tester.presentation.providers.entity.BlockchainProvidersUM.ProvidersUM import com.tangem.feature.tester.presentation.providers.entity.BlockchainProvidersUM.ProvidersUM
@ -50,12 +50,20 @@ internal fun BlockchainProvidersScreen(state: BlockchainProvidersUM) {
.background(TangemTheme.colors.background.primary), .background(TangemTheme.colors.background.primary),
) { ) {
LazyColumn { LazyColumn {
stickyHeader { stickyHeader { TopBarWithRefresh(state = state.topBar) }
AppBarWithBackButton(
onBackClick = state.onBackClick, if (state.topBar.refreshButton.isVisible) {
text = stringResourceSafe(id = R.string.blockchain_providers), item(key = "notification", contentType = "notification") {
containerColor = TangemTheme.colors.background.primary, CustomSetupNotification(
) subtitle = resourceReference(
id = R.string.blockchain_providers_custom_setup_warning_description,
),
modifier = Modifier
.animateItem()
.padding(horizontal = 16.dp)
.padding(bottom = 8.dp),
)
}
} }
items( items(
@ -74,8 +82,8 @@ private fun BlockchainProvidersItem(state: ProvidersUM) {
ExpandableBlockchainRow( ExpandableBlockchainRow(
state = state, state = state,
modifier = Modifier.clickable { isExpanded = !isExpanded },
content = { Providers(state = state, isExpanded = isExpanded) }, content = { Providers(state = state, isExpanded = isExpanded) },
onExpandStateChange = { isExpanded = !isExpanded },
) )
} }
@ -83,25 +91,23 @@ private fun BlockchainProvidersItem(state: ProvidersUM) {
private fun ExpandableBlockchainRow( private fun ExpandableBlockchainRow(
state: ProvidersUM, state: ProvidersUM,
content: @Composable () -> Unit, content: @Composable () -> Unit,
modifier: Modifier = Modifier, onExpandStateChange: () -> Unit,
) { ) {
Column( Column {
modifier = modifier BlockchainRow(state = state, onExpandStateChange = onExpandStateChange)
.fillMaxWidth()
.padding(horizontal = 16.dp),
) {
BlockchainRow(state)
content() content()
} }
} }
@Composable @Composable
private fun BlockchainRow(state: ProvidersUM) { private fun BlockchainRow(state: ProvidersUM, onExpandStateChange: () -> Unit) {
Row( Row(
modifier = Modifier modifier = Modifier
.clickable { onExpandStateChange() }
.padding(horizontal = 16.dp)
.fillMaxWidth() .fillMaxWidth()
.padding(vertical = 16.dp), .padding(vertical = 12.dp),
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
@ -145,11 +151,15 @@ private fun BlockchainRow(state: ProvidersUM) {
private fun Providers(state: ProvidersUM, isExpanded: Boolean) { private fun Providers(state: ProvidersUM, isExpanded: Boolean) {
AnimatedVisibility( AnimatedVisibility(
visible = isExpanded, visible = isExpanded,
modifier = Modifier.padding(horizontal = 16.dp),
enter = fadeIn() + expandVertically(), enter = fadeIn() + expandVertically(),
exit = fadeOut() + shrinkVertically(), exit = fadeOut() + shrinkVertically(),
label = "providers_visibility", label = "providers_visibility",
) { ) {
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { Column(
modifier = Modifier.padding(vertical = 8.dp),
verticalArrangement = Arrangement.spacedBy(12.dp),
) {
state.providers.fastForEachIndexed { index, provider -> state.providers.fastForEachIndexed { index, provider ->
key("${provider.name}_$index") { key("${provider.name}_$index") {
ProviderItem( ProviderItem(
@ -157,8 +167,6 @@ private fun Providers(state: ProvidersUM, isExpanded: Boolean) {
state = provider, state = provider,
onDrop = { prev, new -> state.onDrop(state.blockchainId, prev, new) }, onDrop = { prev, new -> state.onDrop(state.blockchainId, prev, new) },
) )
if (index == state.providers.lastIndex) SpacerH8()
} }
} }
} }

View file

@ -6,6 +6,8 @@ import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.network.providers.ProviderType import com.tangem.blockchain.common.network.providers.ProviderType
import com.tangem.blockchainsdk.providers.BlockchainProvidersTypesManager import com.tangem.blockchainsdk.providers.BlockchainProvidersTypesManager
import com.tangem.blockchainsdk.providers.MutableBlockchainProvidersTypesManager import com.tangem.blockchainsdk.providers.MutableBlockchainProvidersTypesManager
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 import com.tangem.feature.tester.presentation.navigation.InnerTesterRouter
import com.tangem.feature.tester.presentation.providers.entity.BlockchainProvidersUM 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.ProviderUM
@ -26,7 +28,14 @@ internal class BlockchainProvidersViewModel @Inject constructor(
val state: StateFlow<BlockchainProvidersUM> get() = _state.asStateFlow() val state: StateFlow<BlockchainProvidersUM> get() = _state.asStateFlow()
private val _state = MutableStateFlow( private val _state = MutableStateFlow(
value = BlockchainProvidersUM(onBackClick = {}, blockchainProviders = persistentListOf()), value = BlockchainProvidersUM(
topBar = TopBarWithRefreshUM(
titleResId = R.string.blockchain_providers,
onBackClick = {},
refreshButton = TopBarWithRefreshUM.RefreshButton(isVisible = false, onRefreshClick = ::onRefreshClick),
),
blockchainProviders = persistentListOf(),
),
) )
private val manager = blockchainProvidersTypesManager as MutableBlockchainProvidersTypesManager private val manager = blockchainProvidersTypesManager as MutableBlockchainProvidersTypesManager
@ -37,15 +46,24 @@ internal class BlockchainProvidersViewModel @Inject constructor(
fun setupNavigation(router: InnerTesterRouter) { fun setupNavigation(router: InnerTesterRouter) {
_state.update { state -> _state.update { state ->
state.copy(onBackClick = router::back) state.copy(
topBar = state.topBar.copy(onBackClick = router::back),
)
} }
} }
private fun subscribeOnBlockchainProviderTypesUpdates() { private fun subscribeOnBlockchainProviderTypesUpdates() {
manager.get() manager.get()
.onEach { blockchainProviderTypes -> .onEach { blockchainProviderTypes ->
val isChanged = !manager.isMatchWithMerged()
_state.update { state -> _state.update { state ->
state.copy(blockchainProviders = blockchainProviderTypes.toProvidersUM()) state.copy(
topBar = state.topBar.copy(
refreshButton = state.topBar.refreshButton.copy(isVisible = isChanged),
),
blockchainProviders = blockchainProviderTypes.toProvidersUM(),
)
} }
} }
.launchIn(viewModelScope) .launchIn(viewModelScope)
@ -67,6 +85,12 @@ internal class BlockchainProvidersViewModel @Inject constructor(
.toImmutableList() .toImmutableList()
} }
private fun onRefreshClick() {
viewModelScope.launch {
manager.update()
}
}
private fun onDrop(id: String, prev: Int, current: Int) { private fun onDrop(id: String, prev: Int, current: Int) {
val providers = _state.value val providers = _state.value
.blockchainProviders.first { it.blockchainId == id } .blockchainProviders.first { it.blockchainId == id }

View file

@ -2,8 +2,9 @@
<resources> <resources>
<string name="tester_menu" translatable="false">Tester menu</string> <string name="tester_menu" translatable="false">Tester menu</string>
<string name="feature_toggles" translatable="false">Feature toggles</string> <string name="feature_toggles" translatable="false">Feature toggles</string>
<string name="feature_toggles_custom_setup_warning_title" translatable="false">Custom setup</string> <string name="custom_setup_warning_title" translatable="false">Custom setup</string>
<string name="feature_toggles_custom_setup_warning_description" translatable="false">Toggles differs from v%s config</string> <string name="feature_toggles_custom_setup_warning_description" translatable="false">Toggles differs from v%s config</string>
<string name="blockchain_providers_custom_setup_warning_description" translatable="false">Providers differs from release config</string>
<string name="restart_app" translatable="false">Restart app</string> <string name="restart_app" translatable="false">Restart app</string>
<string name="environment_toggles" translatable="false">Environment toggles</string> <string name="environment_toggles" translatable="false">Environment toggles</string>
<string name="tester_actions" translatable="false">Tester actions</string> <string name="tester_actions" translatable="false">Tester actions</string>