Updated on 2026-08-14
This commit is contained in:
parent
f6a56e1657
commit
36ce94fb22
12 changed files with 318 additions and 3 deletions
|
|
@ -46,7 +46,7 @@ inline fun RowContentContainer(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun RowText(
|
fun RowText(
|
||||||
mainText: String,
|
mainText: String,
|
||||||
secondText: String,
|
secondText: String,
|
||||||
accentMainText: Boolean,
|
accentMainText: Boolean,
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,9 @@ dependencies {
|
||||||
/** Feature Apis */
|
/** Feature Apis */
|
||||||
implementation(projects.features.tester.api)
|
implementation(projects.features.tester.api)
|
||||||
|
|
||||||
|
/* SDK */
|
||||||
|
implementation(deps.tangem.blockchain)
|
||||||
|
|
||||||
/** Other modules */
|
/** Other modules */
|
||||||
implementation(projects.common.routing)
|
implementation(projects.common.routing)
|
||||||
implementation(projects.libs.crypto)
|
implementation(projects.libs.crypto)
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,10 @@ package com.tangem.feature.tester.presentation
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
|
@ -17,6 +19,8 @@ import com.tangem.feature.tester.presentation.actions.TesterActionsScreen
|
||||||
import com.tangem.feature.tester.presentation.actions.TesterActionsViewModel
|
import com.tangem.feature.tester.presentation.actions.TesterActionsViewModel
|
||||||
import com.tangem.feature.tester.presentation.environments.ui.EnvironmentTogglesScreen
|
import com.tangem.feature.tester.presentation.environments.ui.EnvironmentTogglesScreen
|
||||||
import com.tangem.feature.tester.presentation.environments.viewmodels.EnvironmentsTogglesViewModel
|
import com.tangem.feature.tester.presentation.environments.viewmodels.EnvironmentsTogglesViewModel
|
||||||
|
import com.tangem.feature.tester.presentation.excludedblockchains.ExcludedBlockchainsScreen
|
||||||
|
import com.tangem.feature.tester.presentation.excludedblockchains.ExcludedBlockchainsViewModel
|
||||||
import com.tangem.feature.tester.presentation.featuretoggles.ui.FeatureTogglesScreen
|
import com.tangem.feature.tester.presentation.featuretoggles.ui.FeatureTogglesScreen
|
||||||
import com.tangem.feature.tester.presentation.featuretoggles.viewmodels.FeatureTogglesViewModel
|
import com.tangem.feature.tester.presentation.featuretoggles.viewmodels.FeatureTogglesViewModel
|
||||||
import com.tangem.feature.tester.presentation.menu.state.TesterMenuContentState
|
import com.tangem.feature.tester.presentation.menu.state.TesterMenuContentState
|
||||||
|
|
@ -70,6 +74,9 @@ internal class TesterActivity : ComposeActivity() {
|
||||||
onBackClick = { appRouter.pop { finish() } },
|
onBackClick = { appRouter.pop { finish() } },
|
||||||
onFeatureTogglesClick = { innerTesterRouter.open(TesterScreen.FEATURE_TOGGLES) },
|
onFeatureTogglesClick = { innerTesterRouter.open(TesterScreen.FEATURE_TOGGLES) },
|
||||||
onEnvironmentTogglesClick = { innerTesterRouter.open(TesterScreen.ENVIRONMENTS_TOGGLES) },
|
onEnvironmentTogglesClick = { innerTesterRouter.open(TesterScreen.ENVIRONMENTS_TOGGLES) },
|
||||||
|
onExcludedBlockchainsClick = {
|
||||||
|
innerTesterRouter.open(TesterScreen.EXCLUDED_BLOCKCHAINS)
|
||||||
|
},
|
||||||
onTesterActionsClick = { innerTesterRouter.open(TesterScreen.TESTER_ACTIONS) },
|
onTesterActionsClick = { innerTesterRouter.open(TesterScreen.TESTER_ACTIONS) },
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -100,6 +107,15 @@ internal class TesterActivity : ComposeActivity() {
|
||||||
|
|
||||||
TesterActionsScreen(state = viewModel.uiState)
|
TesterActionsScreen(state = viewModel.uiState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
composable(route = TesterScreen.EXCLUDED_BLOCKCHAINS.name) {
|
||||||
|
val viewModel = hiltViewModel<ExcludedBlockchainsViewModel>().apply {
|
||||||
|
setupNavigation(innerTesterRouter, appFinisher)
|
||||||
|
}
|
||||||
|
|
||||||
|
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||||
|
ExcludedBlockchainsScreen(state = state)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,190 @@
|
||||||
|
package com.tangem.feature.tester.presentation.excludedblockchains
|
||||||
|
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material3.FabPosition
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.tangem.blockchain.common.Blockchain
|
||||||
|
import com.tangem.core.ui.components.PrimaryButton
|
||||||
|
import com.tangem.core.ui.components.TangemSwitch
|
||||||
|
import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
||||||
|
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
||||||
|
import com.tangem.core.ui.components.bottomFade
|
||||||
|
import com.tangem.core.ui.components.fields.SearchBar
|
||||||
|
import com.tangem.core.ui.components.fields.entity.SearchBarUM
|
||||||
|
import com.tangem.core.ui.components.notifications.Notification
|
||||||
|
import com.tangem.core.ui.components.notifications.NotificationConfig
|
||||||
|
import com.tangem.core.ui.components.rows.RowContentContainer
|
||||||
|
import com.tangem.core.ui.components.rows.RowText
|
||||||
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
|
import com.tangem.core.ui.extensions.wrappedList
|
||||||
|
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.excludedblockchains.state.BlockchainUM
|
||||||
|
import com.tangem.feature.tester.presentation.excludedblockchains.state.ExcludedBlockchainsScreenUM
|
||||||
|
import com.tangem.feature.tester.presentation.excludedblockchains.state.mapper.toUiModels
|
||||||
|
import kotlinx.collections.immutable.toPersistentList
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun ExcludedBlockchainsScreen(state: ExcludedBlockchainsScreenUM, modifier: Modifier = Modifier) {
|
||||||
|
Scaffold(
|
||||||
|
modifier = modifier,
|
||||||
|
containerColor = TangemTheme.colors.background.primary,
|
||||||
|
topBar = {
|
||||||
|
TangemTopAppBar(
|
||||||
|
title = resourceReference(R.string.excluded_blockchains),
|
||||||
|
startButton = TopAppBarButtonUM.Back(onBackClicked = state.popBack),
|
||||||
|
endButton = TopAppBarButtonUM(
|
||||||
|
iconRes = R.drawable.ic_refresh_24,
|
||||||
|
onIconClicked = state.onRecoverClick,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
floatingActionButtonPosition = FabPosition.Center,
|
||||||
|
floatingActionButton = {
|
||||||
|
PrimaryButton(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
text = "Restart App",
|
||||||
|
onClick = state.onRestartClick,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
content = { paddingValues ->
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier
|
||||||
|
.bottomFade()
|
||||||
|
.padding(paddingValues)
|
||||||
|
.fillMaxSize(),
|
||||||
|
contentPadding = PaddingValues(
|
||||||
|
top = 8.dp,
|
||||||
|
bottom = 96.dp,
|
||||||
|
start = 16.dp,
|
||||||
|
end = 16.dp,
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
item {
|
||||||
|
SearchBar(
|
||||||
|
modifier = Modifier.padding(bottom = 12.dp),
|
||||||
|
state = state.search,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
item {
|
||||||
|
TogglesNotification(
|
||||||
|
modifier = Modifier.padding(vertical = 12.dp),
|
||||||
|
appVersion = state.appVersion,
|
||||||
|
isVisible = state.showRecoverWarning,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
items(
|
||||||
|
items = state.blockchains,
|
||||||
|
key = BlockchainUM::id,
|
||||||
|
) { item ->
|
||||||
|
BlockchainItem(
|
||||||
|
model = item,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun TogglesNotification(appVersion: String, isVisible: Boolean, modifier: Modifier = Modifier) {
|
||||||
|
if (isVisible) {
|
||||||
|
Notification(
|
||||||
|
modifier = modifier,
|
||||||
|
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),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun BlockchainItem(model: BlockchainUM, modifier: Modifier = Modifier) {
|
||||||
|
RowContentContainer(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.heightIn(min = TangemTheme.dimens.size52),
|
||||||
|
icon = {
|
||||||
|
Image(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.Center)
|
||||||
|
.size(TangemTheme.dimens.size22),
|
||||||
|
painter = painterResource(id = model.iconResId),
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
text = {
|
||||||
|
RowText(
|
||||||
|
mainText = model.name,
|
||||||
|
secondText = model.symbol,
|
||||||
|
accentMainText = false,
|
||||||
|
accentSecondText = false,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
action = {
|
||||||
|
TangemSwitch(
|
||||||
|
checked = model.isExcluded,
|
||||||
|
onCheckedChange = model.onExcludedStateChange,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// region Preview
|
||||||
|
@Composable
|
||||||
|
@Preview(showBackground = true, widthDp = 360)
|
||||||
|
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||||
|
private fun Preview_ExcludedBlockchainsScreen(
|
||||||
|
@PreviewParameter(ExcludedBlockchainsScreenPreviewProvider::class) params: ExcludedBlockchainsScreenUM,
|
||||||
|
) {
|
||||||
|
TangemThemePreview {
|
||||||
|
ExcludedBlockchainsScreen(params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ExcludedBlockchainsScreenPreviewProvider : PreviewParameterProvider<ExcludedBlockchainsScreenUM> {
|
||||||
|
override val values: Sequence<ExcludedBlockchainsScreenUM>
|
||||||
|
get() = sequenceOf(
|
||||||
|
ExcludedBlockchainsScreenUM(
|
||||||
|
blockchains = Blockchain.entries.toUiModels(
|
||||||
|
excludedBlockchainsIds = setOf(Blockchain.Ethereum.id, Blockchain.Solana.id),
|
||||||
|
onExcludedStateChange = { _, _ -> },
|
||||||
|
).toPersistentList(),
|
||||||
|
showRecoverWarning = true,
|
||||||
|
appVersion = "1.0.0",
|
||||||
|
search = SearchBarUM(
|
||||||
|
placeholderText = resourceReference(R.string.excluded_blockchains_search_placeholder),
|
||||||
|
query = "",
|
||||||
|
isActive = false,
|
||||||
|
onQueryChange = {},
|
||||||
|
onActiveChange = {},
|
||||||
|
),
|
||||||
|
popBack = {},
|
||||||
|
onRecoverClick = {},
|
||||||
|
onRestartClick = {},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// endregion Preview
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.tangem.feature.tester.presentation.excludedblockchains
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.tangem.core.toggle.blockchain.MutableExcludedBlockchainsManager
|
||||||
|
import com.tangem.core.ui.components.fields.entity.SearchBarUM
|
||||||
|
import com.tangem.core.ui.extensions.stringReference
|
||||||
|
import com.tangem.feature.tester.presentation.excludedblockchains.state.ExcludedBlockchainsScreenUM
|
||||||
|
import com.tangem.feature.tester.presentation.navigation.InnerTesterRouter
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
internal class ExcludedBlockchainsViewModel @Inject constructor(
|
||||||
|
private val excludedBlockchainsManager: MutableExcludedBlockchainsManager,
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
val uiState: MutableStateFlow<ExcludedBlockchainsScreenUM> = MutableStateFlow(
|
||||||
|
value = ExcludedBlockchainsScreenUM(
|
||||||
|
popBack = {},
|
||||||
|
search = SearchBarUM(
|
||||||
|
placeholderText = stringReference(value = "Filter by name or symbol"),
|
||||||
|
query = "",
|
||||||
|
isActive = false,
|
||||||
|
onQueryChange = {},
|
||||||
|
onActiveChange = {},
|
||||||
|
),
|
||||||
|
blockchains = persistentListOf(),
|
||||||
|
onRestartClick = {},
|
||||||
|
onRestoreClick = {},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
fun setupNavigation(router: InnerTesterRouter) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.tangem.feature.tester.presentation.excludedblockchains.state
|
||||||
|
|
||||||
|
internal data class BlockchainUM(
|
||||||
|
val id: String,
|
||||||
|
val name: String,
|
||||||
|
val symbol: String,
|
||||||
|
val iconResId: Int,
|
||||||
|
val isExcluded: Boolean,
|
||||||
|
val onExcludedStateChange: (isExcluded: Boolean) -> Unit,
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.tangem.feature.tester.presentation.excludedblockchains.state
|
||||||
|
|
||||||
|
import com.tangem.core.ui.components.fields.entity.SearchBarUM
|
||||||
|
import kotlinx.collections.immutable.PersistentList
|
||||||
|
|
||||||
|
internal data class ExcludedBlockchainsScreenUM(
|
||||||
|
val popBack: () -> Unit,
|
||||||
|
val search: SearchBarUM,
|
||||||
|
val blockchains: PersistentList<BlockchainUM>,
|
||||||
|
val showRecoverWarning: Boolean,
|
||||||
|
val appVersion: String,
|
||||||
|
val onRecoverClick: () -> Unit,
|
||||||
|
val onRestartClick: () -> Unit,
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.tangem.feature.tester.presentation.excludedblockchains.state.mapper
|
||||||
|
|
||||||
|
import com.tangem.blockchain.common.Blockchain
|
||||||
|
import com.tangem.core.ui.extensions.getActiveIconRes
|
||||||
|
import com.tangem.feature.tester.presentation.excludedblockchains.state.BlockchainUM
|
||||||
|
|
||||||
|
internal fun List<Blockchain>.toUiModels(
|
||||||
|
excludedBlockchainsIds: Set<String>,
|
||||||
|
onExcludedStateChange: (Blockchain, Boolean) -> Unit,
|
||||||
|
): List<BlockchainUM> = mapNotNull { blockchain ->
|
||||||
|
blockchain
|
||||||
|
.takeUnless { it == Blockchain.Unknown || it.isTestnet() }
|
||||||
|
?.toUiModel(
|
||||||
|
isExcluded = blockchain.id in excludedBlockchainsIds,
|
||||||
|
onExcludedStateChange = { isExcluded ->
|
||||||
|
onExcludedStateChange(blockchain, isExcluded)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.sortedBy(BlockchainUM::name)
|
||||||
|
.sortedByDescending(BlockchainUM::isExcluded)
|
||||||
|
|
||||||
|
private fun Blockchain.toUiModel(isExcluded: Boolean, onExcludedStateChange: (Boolean) -> Unit): BlockchainUM =
|
||||||
|
BlockchainUM(
|
||||||
|
id = id,
|
||||||
|
name = name,
|
||||||
|
symbol = currency,
|
||||||
|
iconResId = getActiveIconRes(id),
|
||||||
|
isExcluded = isExcluded,
|
||||||
|
onExcludedStateChange = onExcludedStateChange,
|
||||||
|
)
|
||||||
|
|
@ -12,5 +12,6 @@ data class TesterMenuContentState(
|
||||||
val onBackClick: () -> Unit,
|
val onBackClick: () -> Unit,
|
||||||
val onFeatureTogglesClick: () -> Unit,
|
val onFeatureTogglesClick: () -> Unit,
|
||||||
val onEnvironmentTogglesClick: () -> Unit,
|
val onEnvironmentTogglesClick: () -> Unit,
|
||||||
|
val onExcludedBlockchainsClick: () -> Unit,
|
||||||
val onTesterActionsClick: () -> Unit,
|
val onTesterActionsClick: () -> Unit,
|
||||||
)
|
)
|
||||||
|
|
@ -51,6 +51,12 @@ internal fun TesterMenuScreen(state: TesterMenuContentState) {
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
PrimaryButton(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
text = stringResource(R.string.excluded_blockchains),
|
||||||
|
onClick = state.onExcludedBlockchainsClick,
|
||||||
|
)
|
||||||
|
|
||||||
PrimaryButton(
|
PrimaryButton(
|
||||||
text = stringResource(R.string.environment_toggles),
|
text = stringResource(R.string.environment_toggles),
|
||||||
onClick = state.onEnvironmentTogglesClick,
|
onClick = state.onEnvironmentTogglesClick,
|
||||||
|
|
@ -76,6 +82,7 @@ private fun PreviewTesterMenuScreen() {
|
||||||
onBackClick = {},
|
onBackClick = {},
|
||||||
onFeatureTogglesClick = {},
|
onFeatureTogglesClick = {},
|
||||||
onEnvironmentTogglesClick = {},
|
onEnvironmentTogglesClick = {},
|
||||||
|
onExcludedBlockchainsClick = {},
|
||||||
onTesterActionsClick = {},
|
onTesterActionsClick = {},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -6,5 +6,9 @@ package com.tangem.feature.tester.presentation.navigation
|
||||||
[REDACTED_AUTHOR]
|
[REDACTED_AUTHOR]
|
||||||
*/
|
*/
|
||||||
internal enum class TesterScreen {
|
internal enum class TesterScreen {
|
||||||
MENU, FEATURE_TOGGLES, ENVIRONMENTS_TOGGLES, TESTER_ACTIONS
|
MENU,
|
||||||
|
FEATURE_TOGGLES,
|
||||||
|
ENVIRONMENTS_TOGGLES,
|
||||||
|
TESTER_ACTIONS,
|
||||||
|
EXCLUDED_BLOCKCHAINS,
|
||||||
}
|
}
|
||||||
|
|
@ -3,10 +3,12 @@
|
||||||
<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="feature_toggles_custom_setup_warning_title" translatable="false">Custom setup</string>
|
||||||
<string name="feature_toggles_custom_setup_warning_description" translatable="false">Feature 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="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>
|
||||||
<string name="hide_all_currencies" translatable="false">Hide all currencies</string>
|
<string name="hide_all_currencies" translatable="false">Hide all currencies</string>
|
||||||
<string name="toggle_app_theme" translatable="false">Toggle app theme - %s</string>
|
<string name="toggle_app_theme" translatable="false">Toggle app theme - %s</string>
|
||||||
|
<string name="excluded_blockchains" translatable="false">Excluded blockchains</string>
|
||||||
|
<string name="excluded_blockchains_search_placeholder" translatable="false">Filter by name or symbol</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue