Settings code cleanup (#1644)

* Settings code cleanup

* Auto formatting using Ktlint

---------

Co-authored-by: Honza <rychnovsky.honza@gmail.com>
This commit is contained in:
Milan 2024-10-23 15:08:02 +02:00 committed by GitHub
parent 5410cc26c2
commit 9d634a2da8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 382 additions and 251 deletions

View File

@ -0,0 +1,51 @@
package co.electriccoin.zcash.ui.design.component
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import co.electriccoin.zcash.ui.design.R
import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
import co.electriccoin.zcash.ui.design.util.StringResource
import co.electriccoin.zcash.ui.design.util.getValue
import co.electriccoin.zcash.ui.design.util.stringRes
@Composable
fun ZashiVersion(
version: StringResource,
modifier: Modifier = Modifier
) {
Column(
modifier = modifier
) {
Image(
modifier = Modifier.align(CenterHorizontally),
painter =
painterResource(id = R.drawable.img_zashi_version),
contentDescription = version.getValue()
)
Spacer(modifier = Modifier.height(16.dp))
Text(
modifier = Modifier.align(CenterHorizontally),
text = version.getValue(),
color = ZashiColors.Text.textTertiary
)
}
}
@PreviewScreens
@Composable
private fun ZashiVersionPreview() =
ZcashTheme {
BlankSurface {
ZashiVersion(version = stringRes("Version"))
}
}

View File

@ -10,6 +10,7 @@ import co.electriccoin.zcash.ui.screen.settings.model.SettingsState
import co.electriccoin.zcash.ui.screen.settings.model.SettingsTroubleshootingState
import co.electriccoin.zcash.ui.screen.settings.model.TroubleshootingItemState
import co.electriccoin.zcash.ui.screen.settings.view.Settings
import kotlinx.collections.immutable.persistentListOf
import java.util.concurrent.atomic.AtomicInteger
class SettingsViewTestSetup(
@ -107,26 +108,46 @@ class SettingsViewTestSetup(
SettingsState(
isLoading = false,
version = stringRes("app_version"),
settingsTroubleshootingState = settingsTroubleshootingState,
debugMenu = settingsTroubleshootingState,
onBack = {
onBackCount.incrementAndGet()
},
onSendUsFeedbackClick = {
onFeedbackCount.incrementAndGet()
},
onAdvancedSettingsClick = {
onAdvancedSettingsCount.incrementAndGet()
},
onAboutUsClick = {
onAboutCount.incrementAndGet()
},
onAddressBookClick = {
onAddressBookCount.incrementAndGet()
},
integrations =
ZashiSettingsListItemState(
stringRes("Integrations"),
R.drawable.ic_settings_integrations,
items =
persistentListOf(
ZashiSettingsListItemState(
text = stringRes(R.string.settings_address_book),
icon = R.drawable.ic_settings_address_book,
onClick = {
onAddressBookCount.incrementAndGet()
},
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_integrations),
icon = R.drawable.ic_settings_integrations,
titleIcons = persistentListOf(R.drawable.ic_integrations_coinbase),
onClick = { },
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_advanced_settings),
icon = R.drawable.ic_advanced_settings,
onClick = {
onAdvancedSettingsCount.incrementAndGet()
},
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_about_us),
icon = R.drawable.ic_settings_info,
onClick = {
onAboutCount.incrementAndGet()
},
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_feedback),
icon = R.drawable.ic_settings_feedback,
onClick = {
onFeedbackCount.incrementAndGet()
},
),
)
),
topAppBarSubTitleState = TopAppBarSubTitleState.None,

View File

@ -55,7 +55,6 @@ val viewModelModule =
AddressBookViewModel(
args = args,
observeAddressBookContacts = get(),
getVersionInfo = get(),
observeContactPicked = get(),
)
}

View File

@ -6,7 +6,6 @@ import co.electriccoin.zcash.ui.design.util.StringResource
data class AddressBookState(
val contacts: List<AddressBookContactState>,
val isLoading: Boolean,
val version: StringResource,
val onBack: () -> Unit,
val scanButton: ButtonState,
val manualButton: ButtonState

View File

@ -146,7 +146,6 @@ private fun PopupContentPreview() =
AddressBookState(
onBack = {},
isLoading = false,
version = stringRes("Version"),
contacts = emptyList(),
scanButton =
ButtonState(

View File

@ -55,7 +55,6 @@ import co.electriccoin.zcash.ui.screen.addressbook.AddressBookTag
import co.electriccoin.zcash.ui.screen.addressbook.model.AddressBookContactState
import co.electriccoin.zcash.ui.screen.addressbook.model.AddressBookState
@Suppress("LongMethod")
@Composable
fun AddressBookView(
state: AddressBookState,
@ -307,7 +306,6 @@ private fun DataPreview() {
state =
AddressBookState(
isLoading = false,
version = stringRes("Version 1.2"),
onBack = {},
contacts =
(1..10).map {
@ -341,7 +339,6 @@ private fun LoadingPreview() {
state =
AddressBookState(
isLoading = true,
version = stringRes("Version 1.2"),
onBack = {},
contacts = emptyList(),
scanButton =
@ -366,7 +363,6 @@ private fun EmptyPreview() {
state =
AddressBookState(
isLoading = false,
version = stringRes("Version 1.2"),
onBack = {},
contacts = emptyList(),
scanButton =

View File

@ -5,7 +5,6 @@ import androidx.lifecycle.viewModelScope
import cash.z.ecc.sdk.ANDROID_STATE_FLOW_TIMEOUT
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.model.AddressBookContact
import co.electriccoin.zcash.ui.common.provider.GetVersionInfoProvider
import co.electriccoin.zcash.ui.common.usecase.ObserveAddressBookContactsUseCase
import co.electriccoin.zcash.ui.common.usecase.ObserveContactPickedUseCase
import co.electriccoin.zcash.ui.design.component.ButtonState
@ -31,12 +30,9 @@ import kotlin.time.Duration.Companion.seconds
class AddressBookViewModel(
observeAddressBookContacts: ObserveAddressBookContactsUseCase,
getVersionInfo: GetVersionInfoProvider,
private val args: AddressBookArgs,
private val observeContactPicked: ObserveContactPickedUseCase
) : ViewModel() {
private val versionInfo = getVersionInfo()
val state =
observeAddressBookContacts()
.map { contacts -> createState(contacts = contacts) }
@ -53,7 +49,6 @@ class AddressBookViewModel(
private fun createState(contacts: List<AddressBookContact>?) =
AddressBookState(
version = stringRes(R.string.address_book_version, versionInfo.versionName),
isLoading = contacts == null,
contacts =
contacts?.map { contact ->

View File

@ -1,10 +0,0 @@
package co.electriccoin.zcash.ui.screen.advancedsettings
data class AdvancedSettingsState(
val onBack: () -> Unit,
val onRecoveryPhraseClick: () -> Unit,
val onExportPrivateDataClick: () -> Unit,
val onChooseServerClick: () -> Unit,
val onCurrencyConversionClick: () -> Unit,
val onDeleteZashiClick: () -> Unit,
)

View File

@ -11,6 +11,7 @@ import co.electriccoin.zcash.ui.common.compose.LocalNavController
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
import co.electriccoin.zcash.ui.screen.advancedsettings.view.AdvancedSettings
import co.electriccoin.zcash.ui.screen.advancedsettings.viewmodel.AdvancedSettingsViewModel
import kotlinx.collections.immutable.toImmutableList
import org.koin.androidx.compose.koinViewModel
@Suppress("LongParameterList")
@ -24,11 +25,18 @@ internal fun WrapAdvancedSettings(
val walletViewModel = koinActivityViewModel<WalletViewModel>()
val viewModel = koinViewModel<AdvancedSettingsViewModel>()
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
val originalState = viewModel.state.collectAsStateWithLifecycle().value
val state =
viewModel.state.collectAsStateWithLifecycle().value.copy(
onDeleteZashiClick = goDeleteWallet,
onExportPrivateDataClick = goExportPrivateData,
onRecoveryPhraseClick = goSeedRecovery
originalState.copy(
deleteButton = originalState.deleteButton.copy(onClick = goDeleteWallet),
items =
originalState.items.mapIndexed { index, item ->
when (index) {
0 -> item.copy(onClick = goSeedRecovery)
1 -> item.copy(onClick = goExportPrivateData)
else -> item
}
}.toImmutableList()
)
BackHandler {

View File

@ -0,0 +1,11 @@
package co.electriccoin.zcash.ui.screen.advancedsettings.model
import co.electriccoin.zcash.ui.design.component.ButtonState
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItemState
import kotlinx.collections.immutable.ImmutableList
data class AdvancedSettingsState(
val onBack: () -> Unit,
val items: ImmutableList<ZashiSettingsListItemState>,
val deleteButton: ButtonState,
)

View File

@ -22,26 +22,29 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.util.fastForEachIndexed
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
import co.electriccoin.zcash.ui.design.component.ButtonState
import co.electriccoin.zcash.ui.design.component.ZashiButton
import co.electriccoin.zcash.ui.design.component.ZashiButtonDefaults
import co.electriccoin.zcash.ui.design.component.ZashiHorizontalDivider
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItem
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItemState
import co.electriccoin.zcash.ui.design.component.ZashiSmallTopAppBar
import co.electriccoin.zcash.ui.design.component.ZashiTopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
import co.electriccoin.zcash.ui.design.theme.dimensions.ZashiDimensions
import co.electriccoin.zcash.ui.design.util.orDark
import co.electriccoin.zcash.ui.screen.advancedsettings.AdvancedSettingsState
import co.electriccoin.zcash.ui.design.util.stringRes
import co.electriccoin.zcash.ui.screen.advancedsettings.AdvancedSettingsTag
import co.electriccoin.zcash.ui.screen.advancedsettings.model.AdvancedSettingsState
import kotlinx.collections.immutable.persistentListOf
// TODO [#1271]: Add AdvancedSettingsView Tests
// TODO [#1271]: https://github.com/Electric-Coin-Company/zashi-android/issues/1271
@Suppress("LongMethod")
@Composable
fun AdvancedSettings(
state: AdvancedSettingsState,
@ -67,66 +70,49 @@ fun AdvancedSettings(
end = 4.dp
),
) {
ZashiSettingsListItem(
text = stringResource(id = R.string.advanced_settings_recovery),
icon = R.drawable.ic_advanced_settings_recovery,
onClick = state.onRecoveryPhraseClick
)
ZashiHorizontalDivider()
ZashiSettingsListItem(
text = stringResource(id = R.string.advanced_settings_export),
icon = R.drawable.ic_advanced_settings_export,
onClick = state.onExportPrivateDataClick
)
ZashiHorizontalDivider()
ZashiSettingsListItem(
text = stringResource(id = R.string.advanced_settings_choose_server),
icon =
R.drawable.ic_advanced_settings_choose_server orDark
R.drawable.ic_advanced_settings_choose_server,
onClick = state.onChooseServerClick
)
ZashiHorizontalDivider()
ZashiSettingsListItem(
text = stringResource(id = R.string.advanced_settings_currency_conversion),
icon =
R.drawable.ic_advanced_settings_currency_conversion orDark
R.drawable.ic_advanced_settings_currency_conversion,
onClick = state.onCurrencyConversionClick
)
Spacer(modifier = Modifier.height(24.dp))
Spacer(modifier = Modifier.weight(1f))
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Image(
painter = painterResource(id = R.drawable.ic_advanced_settings_info),
contentDescription = "",
colorFilter = ColorFilter.tint(ZashiColors.Text.textTertiary)
)
Spacer(modifier = Modifier.width(12.dp))
Text(
text = stringResource(id = R.string.advanced_settings_info),
fontSize = 12.sp,
color = ZashiColors.Text.textTertiary,
)
state.items.fastForEachIndexed { index, item ->
ZashiSettingsListItem(state = item)
if (index != state.items.lastIndex) {
ZashiHorizontalDivider()
}
}
Spacer(modifier = Modifier.height(ZashiDimensions.Spacing.spacingXl))
Spacer(modifier = Modifier.weight(1f))
Info()
Spacer(modifier = Modifier.height(20.dp))
ZashiButton(
modifier =
Modifier
.padding(horizontal = 20.dp)
.fillMaxWidth(),
text = stringResource(R.string.advanced_settings_delete_button),
colors = ZashiButtonDefaults.destructive1Colors(),
onClick = state.onDeleteZashiClick
state = state.deleteButton
)
}
}
}
@Composable
private fun Info() {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Image(
painter = painterResource(id = R.drawable.ic_advanced_settings_info),
contentDescription = "",
colorFilter = ColorFilter.tint(ZashiColors.Text.textTertiary)
)
Spacer(modifier = Modifier.width(12.dp))
Text(
text = stringResource(id = R.string.advanced_settings_info),
fontSize = 12.sp,
color = ZashiColors.Text.textTertiary,
)
}
}
@Composable
private fun AdvancedSettingsTopAppBar(
onBack: () -> Unit,
@ -148,7 +134,6 @@ private fun AdvancedSettingsTopAppBar(
)
}
@Suppress("UnusedPrivateMember")
@PreviewScreens
@Composable
private fun AdvancedSettingsPreview() =
@ -157,11 +142,34 @@ private fun AdvancedSettingsPreview() =
state =
AdvancedSettingsState(
onBack = {},
onRecoveryPhraseClick = {},
onExportPrivateDataClick = {},
onChooseServerClick = {},
onCurrencyConversionClick = {},
onDeleteZashiClick = {},
items =
persistentListOf(
ZashiSettingsListItemState(
text = stringRes(R.string.advanced_settings_recovery),
icon = R.drawable.ic_advanced_settings_recovery,
onClick = {}
),
ZashiSettingsListItemState(
text = stringRes(R.string.advanced_settings_export),
icon = R.drawable.ic_advanced_settings_export,
onClick = {}
),
ZashiSettingsListItemState(
text = stringRes(R.string.advanced_settings_choose_server),
icon = R.drawable.ic_advanced_settings_choose_server,
onClick = {}
),
ZashiSettingsListItemState(
text = stringRes(R.string.advanced_settings_currency_conversion),
icon = R.drawable.ic_advanced_settings_currency_conversion,
onClick = {}
)
),
deleteButton =
ButtonState(
text = stringRes(R.string.advanced_settings_delete_button),
onClick = {}
)
),
topAppBarSubTitleState = TopAppBarSubTitleState.None,
)

View File

@ -3,7 +3,12 @@ package co.electriccoin.zcash.ui.screen.advancedsettings.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import co.electriccoin.zcash.ui.NavigationTargets
import co.electriccoin.zcash.ui.screen.advancedsettings.AdvancedSettingsState
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.design.component.ButtonState
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItemState
import co.electriccoin.zcash.ui.design.util.stringRes
import co.electriccoin.zcash.ui.screen.advancedsettings.model.AdvancedSettingsState
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
@ -14,11 +19,36 @@ class AdvancedSettingsViewModel : ViewModel() {
MutableStateFlow(
AdvancedSettingsState(
onBack = ::onBack,
onRecoveryPhraseClick = {},
onExportPrivateDataClick = {},
onChooseServerClick = ::onChooseServerClick,
onCurrencyConversionClick = ::onCurrencyConversionClick,
onDeleteZashiClick = {},
items =
persistentListOf(
ZashiSettingsListItemState(
text = stringRes(R.string.advanced_settings_recovery),
icon = R.drawable.ic_advanced_settings_recovery,
onClick = {}
),
ZashiSettingsListItemState(
text = stringRes(R.string.advanced_settings_export),
icon = R.drawable.ic_advanced_settings_export,
onClick = {}
),
ZashiSettingsListItemState(
text = stringRes(R.string.advanced_settings_choose_server),
icon =
R.drawable.ic_advanced_settings_choose_server,
onClick = ::onChooseServerClick
),
ZashiSettingsListItemState(
text = stringRes(R.string.advanced_settings_currency_conversion),
icon =
R.drawable.ic_advanced_settings_currency_conversion,
onClick = ::onCurrencyConversionClick
)
),
deleteButton =
ButtonState(
stringRes(R.string.advanced_settings_delete_button),
onClick = {}
)
)
).asStateFlow()

View File

@ -2,10 +2,11 @@ package co.electriccoin.zcash.ui.screen.integrations.model
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItemState
import co.electriccoin.zcash.ui.design.util.StringResource
import kotlinx.collections.immutable.ImmutableList
data class IntegrationsState(
val version: StringResource,
val coinbase: ZashiSettingsListItemState?,
val disabledInfo: StringResource?,
val onBack: () -> Unit,
val items: ImmutableList<ZashiSettingsListItemState>
)

View File

@ -25,20 +25,23 @@ import androidx.compose.ui.unit.sp
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
import co.electriccoin.zcash.ui.design.component.ZashiHorizontalDivider
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItem
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItemState
import co.electriccoin.zcash.ui.design.component.ZashiSmallTopAppBar
import co.electriccoin.zcash.ui.design.component.ZashiTopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.component.ZashiVersion
import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
import co.electriccoin.zcash.ui.design.theme.dimensions.ZashiDimensions
import co.electriccoin.zcash.ui.design.util.StringResource
import co.electriccoin.zcash.ui.design.util.getValue
import co.electriccoin.zcash.ui.design.util.orDark
import co.electriccoin.zcash.ui.design.util.stringRes
import co.electriccoin.zcash.ui.screen.integrations.model.IntegrationsState
import co.electriccoin.zcash.ui.screen.settings.SettingsTag
import kotlinx.collections.immutable.persistentListOf
@Suppress("LongMethod")
@Composable
fun Integrations(
state: IntegrationsState,
@ -56,54 +59,53 @@ fun Integrations(
.verticalScroll(rememberScrollState())
.padding(
top = paddingValues.calculateTopPadding(),
bottom = paddingValues.calculateBottomPadding(),
bottom = paddingValues.calculateBottomPadding() + ZashiDimensions.Spacing.spacing3xl,
start = 4.dp,
end = 4.dp
),
) {
state.coinbase?.let {
ZashiSettingsListItem(state = it)
state.items.forEachIndexed { index, item ->
ZashiSettingsListItem(state = item)
if (index != state.items.lastIndex) {
ZashiHorizontalDivider()
}
}
state.disabledInfo?.let {
Spacer(modifier = Modifier.height(28.dp))
Row(
modifier = Modifier.fillMaxWidth().padding(horizontal = 20.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Image(
painter = painterResource(id = R.drawable.ic_advanced_settings_info),
contentDescription = "",
colorFilter = ColorFilter.tint(ZashiColors.Utility.WarningYellow.utilityOrange700)
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = it.getValue(),
fontSize = 12.sp,
color = ZashiColors.Utility.WarningYellow.utilityOrange700,
)
}
DisabledInfo(it)
}
Spacer(modifier = Modifier.height(ZashiDimensions.Spacing.spacingXl))
Spacer(modifier = Modifier.weight(1f))
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingMin))
Image(
modifier = Modifier.align(CenterHorizontally),
painter =
painterResource(id = R.drawable.ic_settings_zashi orDark R.drawable.ic_settings_zashi),
contentDescription = ""
)
Spacer(modifier = Modifier.height(16.dp))
Text(
modifier = Modifier.align(CenterHorizontally),
text = state.version.getValue(),
color = ZashiColors.Text.textTertiary
)
Spacer(modifier = Modifier.height(20.dp))
ZashiVersion(modifier = Modifier.align(CenterHorizontally), version = state.version)
}
}
}
@Composable
private fun DisabledInfo(it: StringResource) {
Row(
modifier =
Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Image(
painter = painterResource(id = R.drawable.ic_advanced_settings_info),
contentDescription = "",
colorFilter = ColorFilter.tint(ZashiColors.Utility.WarningYellow.utilityOrange700)
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = it.getValue(),
fontSize = 12.sp,
color = ZashiColors.Utility.WarningYellow.utilityOrange700,
)
}
}
@Composable
private fun IntegrationsTopAppBar(
onBack: () -> Unit,
@ -125,25 +127,26 @@ private fun IntegrationsTopAppBar(
)
}
@Suppress("UnusedPrivateMember")
@PreviewScreens
@Composable
private fun IntegrationSettings() {
private fun IntegrationSettings() =
ZcashTheme {
Integrations(
state =
IntegrationsState(
version = stringRes("Version 1.2"),
onBack = {},
coinbase =
ZashiSettingsListItemState(
icon = R.drawable.ic_integrations_coinbase,
text = stringRes("Coinbase"),
subtitle = stringRes("Coinbase subtitle"),
) {},
disabledInfo = stringRes("Disabled info"),
items =
persistentListOf(
ZashiSettingsListItemState(
icon = R.drawable.ic_integrations_coinbase,
text = stringRes("Coinbase"),
subtitle = stringRes("subtitle"),
onClick = {}
)
)
),
topAppBarSubTitleState = TopAppBarSubTitleState.None,
)
}
}

View File

@ -14,6 +14,7 @@ import co.electriccoin.zcash.ui.common.usecase.ObserveWalletStateUseCase
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItemState
import co.electriccoin.zcash.ui.design.util.stringRes
import co.electriccoin.zcash.ui.screen.integrations.model.IntegrationsState
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.WhileSubscribed
@ -44,21 +45,23 @@ class IntegrationsViewModel(
isEnabled.map { isEnabled ->
IntegrationsState(
version = stringRes(R.string.integrations_version, versionInfo.versionName),
coinbase =
ZashiSettingsListItemState(
// Set the wallet currency by app build is more future-proof, although we hide it from the UI
// in the Testnet build
icon = R.drawable.ic_integrations_coinbase,
text = stringRes(R.string.integrations_coinbase, getZcashCurrency.getLocalizedName()),
subtitle =
stringRes(
R.string.integrations_coinbase_subtitle,
getZcashCurrency.getLocalizedName()
),
onClick = ::onBuyWithCoinbaseClicked
).takeIf { isCoinbaseAvailable() },
disabledInfo = stringRes(R.string.integrations_disabled_info).takeIf { isEnabled.not() },
onBack = ::onBack,
items =
listOfNotNull(
ZashiSettingsListItemState(
// Set the wallet currency by app build is more future-proof, although we hide it from
// the UI in the Testnet build
icon = R.drawable.ic_integrations_coinbase,
text = stringRes(R.string.integrations_coinbase, getZcashCurrency.getLocalizedName()),
subtitle =
stringRes(
R.string.integrations_coinbase_subtitle,
getZcashCurrency.getLocalizedName()
),
onClick = ::onBuyWithCoinbaseClicked
).takeIf { isCoinbaseAvailable() }
).toImmutableList()
)
}.stateIn(
scope = viewModelScope,

View File

@ -2,15 +2,12 @@ package co.electriccoin.zcash.ui.screen.settings.model
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItemState
import co.electriccoin.zcash.ui.design.util.StringResource
import kotlinx.collections.immutable.ImmutableList
data class SettingsState(
val isLoading: Boolean,
val version: StringResource,
val settingsTroubleshootingState: SettingsTroubleshootingState?,
val onAddressBookClick: () -> Unit,
val isLoading: Boolean,
val onBack: () -> Unit,
val integrations: ZashiSettingsListItemState,
val onAdvancedSettingsClick: () -> Unit,
val onAboutUsClick: () -> Unit,
val onSendUsFeedbackClick: () -> Unit,
val debugMenu: SettingsTroubleshootingState?,
val items: ImmutableList<ZashiSettingsListItemState>,
)

View File

@ -1,6 +1,5 @@
package co.electriccoin.zcash.ui.screen.settings.view
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
@ -25,7 +24,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import co.electriccoin.zcash.ui.R
@ -37,18 +35,16 @@ import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItem
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItemState
import co.electriccoin.zcash.ui.design.component.ZashiSmallTopAppBar
import co.electriccoin.zcash.ui.design.component.ZashiTopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.component.ZashiVersion
import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
import co.electriccoin.zcash.ui.design.theme.dimensions.ZashiDimensions
import co.electriccoin.zcash.ui.design.util.getValue
import co.electriccoin.zcash.ui.design.util.stringRes
import co.electriccoin.zcash.ui.screen.settings.SettingsTag
import co.electriccoin.zcash.ui.screen.settings.model.SettingsState
import co.electriccoin.zcash.ui.screen.settings.model.SettingsTroubleshootingState
import kotlinx.collections.immutable.persistentListOf
@Suppress("LongMethod")
@Composable
fun Settings(
state: SettingsState,
@ -78,45 +74,15 @@ fun Settings(
end = 4.dp
),
) {
ZashiSettingsListItem(
text = stringResource(id = R.string.settings_address_book),
icon = R.drawable.ic_settings_address_book,
onClick = state.onAddressBookClick
)
ZashiHorizontalDivider()
ZashiSettingsListItem(state = state.integrations)
ZashiHorizontalDivider()
ZashiSettingsListItem(
text = stringResource(id = R.string.settings_advanced_settings),
icon = R.drawable.ic_advanced_settings,
onClick = state.onAdvancedSettingsClick
)
ZashiHorizontalDivider()
ZashiSettingsListItem(
text = stringResource(id = R.string.settings_about_us),
icon = R.drawable.ic_settings_info,
onClick = state.onAboutUsClick
)
ZashiHorizontalDivider()
ZashiSettingsListItem(
text = stringResource(id = R.string.settings_feedback),
icon = R.drawable.ic_settings_feedback,
onClick = state.onSendUsFeedbackClick
)
state.items.forEachIndexed { index, item ->
ZashiSettingsListItem(state = item)
if (index != state.items.lastIndex) {
ZashiHorizontalDivider()
}
}
Spacer(modifier = Modifier.height(ZashiDimensions.Spacing.spacingXl))
Spacer(modifier = Modifier.weight(1f))
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingMin))
Image(
modifier = Modifier.align(CenterHorizontally),
painter =
painterResource(id = R.drawable.ic_settings_zashi),
contentDescription = ""
)
Spacer(modifier = Modifier.height(16.dp))
Text(
modifier = Modifier.align(CenterHorizontally),
text = state.version.getValue(),
color = ZashiColors.Text.textTertiary
)
ZashiVersion(modifier = Modifier.align(CenterHorizontally), version = state.version)
}
}
}
@ -142,8 +108,8 @@ private fun SettingsTopAppBar(
ZashiTopAppBarBackNavigation(onBack = onBack)
},
regularActions = {
if (state.settingsTroubleshootingState != null) {
TroubleshootingMenu(state = state.settingsTroubleshootingState)
if (state.debugMenu != null) {
TroubleshootingMenu(state = state.debugMenu)
}
},
)
@ -224,7 +190,6 @@ private fun AddIcon(enabled: Boolean) {
}
}
@Suppress("UnusedPrivateMember")
@PreviewScreens
@Composable
private fun PreviewSettings() {
@ -234,25 +199,43 @@ private fun PreviewSettings() {
SettingsState(
isLoading = false,
version = stringRes("Version 1.2"),
settingsTroubleshootingState = null,
debugMenu = null,
onBack = {},
onAdvancedSettingsClick = {},
onAboutUsClick = {},
onSendUsFeedbackClick = {},
onAddressBookClick = {},
integrations =
ZashiSettingsListItemState(
icon = R.drawable.ic_settings_integrations,
text = stringRes("Integrations"),
titleIcons = persistentListOf(R.drawable.ic_integrations_coinbase)
) {}
items =
persistentListOf(
ZashiSettingsListItemState(
text = stringRes(R.string.settings_address_book),
icon = R.drawable.ic_settings_address_book,
onClick = { },
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_integrations),
icon = R.drawable.ic_settings_integrations,
onClick = { },
titleIcons = persistentListOf(R.drawable.ic_integrations_coinbase)
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_advanced_settings),
icon = R.drawable.ic_advanced_settings,
onClick = { },
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_about_us),
icon = R.drawable.ic_settings_info,
onClick = { },
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_feedback),
icon = R.drawable.ic_settings_feedback,
onClick = { },
),
),
),
topAppBarSubTitleState = TopAppBarSubTitleState.None,
)
}
}
@Suppress("UnusedPrivateMember")
@PreviewScreens
@Composable
private fun PreviewSettingsLoading() {
@ -262,18 +245,37 @@ private fun PreviewSettingsLoading() {
SettingsState(
isLoading = true,
version = stringRes("Version 1.2"),
settingsTroubleshootingState = null,
debugMenu = null,
onBack = {},
onAdvancedSettingsClick = {},
onAboutUsClick = {},
onSendUsFeedbackClick = {},
onAddressBookClick = {},
integrations =
ZashiSettingsListItemState(
icon = R.drawable.ic_settings_integrations,
text = stringRes("Integrations"),
titleIcons = persistentListOf(R.drawable.ic_integrations_coinbase)
) {}
items =
persistentListOf(
ZashiSettingsListItemState(
text = stringRes(R.string.settings_address_book),
icon = R.drawable.ic_settings_address_book,
onClick = { },
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_integrations),
icon = R.drawable.ic_settings_integrations,
onClick = { },
titleIcons = persistentListOf(R.drawable.ic_integrations_coinbase)
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_advanced_settings),
icon = R.drawable.ic_advanced_settings,
onClick = { },
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_about_us),
icon = R.drawable.ic_settings_info,
onClick = { },
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_feedback),
icon = R.drawable.ic_settings_feedback,
onClick = { },
),
),
),
topAppBarSubTitleState = TopAppBarSubTitleState.None,
)

View File

@ -99,20 +99,38 @@ class SettingsViewModel(
combine(isLoading, troubleshootingState) { isLoading, troubleshootingState ->
SettingsState(
isLoading = isLoading,
version = stringRes(R.string.settings_version, versionInfo.versionName),
settingsTroubleshootingState = troubleshootingState,
debugMenu = troubleshootingState,
onBack = ::onBack,
integrations =
ZashiSettingsListItemState(
text = stringRes(R.string.settings_integrations),
icon = R.drawable.ic_settings_integrations,
onClick = ::onIntegrationsClick,
titleIcons = persistentListOf(R.drawable.ic_integrations_coinbase)
items =
persistentListOf(
ZashiSettingsListItemState(
text = stringRes(R.string.settings_address_book),
icon = R.drawable.ic_settings_address_book,
onClick = ::onAddressBookClick
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_integrations),
icon = R.drawable.ic_settings_integrations,
onClick = ::onIntegrationsClick,
titleIcons = persistentListOf(R.drawable.ic_integrations_coinbase)
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_advanced_settings),
icon = R.drawable.ic_advanced_settings,
onClick = ::onAdvancedSettingsClick
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_about_us),
icon = R.drawable.ic_settings_info,
onClick = ::onAboutUsClick
),
ZashiSettingsListItemState(
text = stringRes(R.string.settings_feedback),
icon = R.drawable.ic_settings_feedback,
onClick = ::onSendUsFeedbackClick
),
),
onAdvancedSettingsClick = ::onAdvancedSettingsClick,
onAboutUsClick = ::onAboutUsClick,
onSendUsFeedbackClick = ::onSendUsFeedbackClick,
onAddressBookClick = ::onAddressBookClick
version = stringRes(R.string.settings_version, versionInfo.versionName)
)
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT), null)