[#948] Updated Settings screen UI
* [#948] Updated Settings screen UI * [#948] Crash fix on settings screen * Center button UI components text So the text aligns with the center when the button is displayed on a very small device or, e.g., when the system accessibility text size increase feature is used. * Keep button spacing When rotated to landscape, the weighted spacing disappears. But we ideally want buttons to have all the same spacing around them in this scenario. * Kotlin code style * Move previous settings option to overflow - As the new design prescribes no debug/test options in the settings screen, we moved these useful actions into the only troubleshooting menu in the app bar. - Tests added * Add UI tests * Text in all caps in the components Rather than enforcing all caps in translations. --------- Co-authored-by: Honza <rychnovsky.honza@gmail.com>
This commit is contained in:
parent
3b1d42528d
commit
705386e031
|
@ -9,8 +9,7 @@
|
|||
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||
|
@ -126,6 +125,7 @@
|
|||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
|
||||
<option name="LINE_COMMENT_ADD_SPACE" value="true" />
|
||||
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
|
||||
|
|
|
@ -21,6 +21,7 @@ import androidx.compose.ui.graphics.PaintingStyle
|
|||
import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
@ -79,7 +80,12 @@ fun PrimaryButton(
|
|||
),
|
||||
onClick = onClick,
|
||||
) {
|
||||
Text(text = text, color = textColor, style = MaterialTheme.typography.labelLarge)
|
||||
Text(
|
||||
style = ZcashTheme.extendedTypography.buttonText,
|
||||
textAlign = TextAlign.Center,
|
||||
text = text.uppercase(),
|
||||
color = textColor
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +113,8 @@ fun SecondaryButton(
|
|||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
text = text,
|
||||
textAlign = TextAlign.Center,
|
||||
text = text.uppercase(),
|
||||
color = MaterialTheme.colorScheme.onSecondary
|
||||
)
|
||||
}
|
||||
|
@ -132,7 +139,12 @@ fun NavigationButton(
|
|||
),
|
||||
colors = buttonColors(containerColor = MaterialTheme.colorScheme.secondary)
|
||||
) {
|
||||
Text(style = MaterialTheme.typography.labelLarge, text = text, color = MaterialTheme.colorScheme.onSecondary)
|
||||
Text(
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
textAlign = TextAlign.Center,
|
||||
text = text,
|
||||
color = MaterialTheme.colorScheme.onSecondary
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,6 +173,7 @@ fun TertiaryButton(
|
|||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
textAlign = TextAlign.Center,
|
||||
text = text,
|
||||
color = ZcashTheme.colors.onTertiary
|
||||
)
|
||||
|
@ -189,6 +202,7 @@ fun DangerousButton(
|
|||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
textAlign = TextAlign.Center,
|
||||
text = text,
|
||||
color = ZcashTheme.colors.onDangerous
|
||||
)
|
||||
|
|
|
@ -30,6 +30,7 @@ data class ExtendedColors(
|
|||
val disabledButtonColor: Color,
|
||||
val disabledButtonTextColor: Color,
|
||||
val buttonShadowColor: Color,
|
||||
val screenTitleColor: Color,
|
||||
) {
|
||||
@Composable
|
||||
fun surfaceGradient() = Brush.verticalGradient(
|
||||
|
|
|
@ -59,6 +59,9 @@ internal object Dark {
|
|||
val disabledButtonTextColor = Color(0xFFDDDDDD)
|
||||
|
||||
val buttonShadowColor = Color(0xFFFFFFFF)
|
||||
|
||||
// to be added later for dark theme
|
||||
val screenTitleColor = Color.Unspecified
|
||||
}
|
||||
|
||||
internal object Light {
|
||||
|
@ -115,6 +118,8 @@ internal object Light {
|
|||
val disabledButtonColor = Color(0xFFB7B7B7)
|
||||
val disabledButtonTextColor = Color(0xFFDDDDDD)
|
||||
val buttonShadowColor = Color(0xFF000000)
|
||||
|
||||
val screenTitleColor = Color(0xFF040404)
|
||||
}
|
||||
|
||||
internal val DarkColorPalette = darkColorScheme(
|
||||
|
@ -162,7 +167,7 @@ internal val DarkExtendedColorPalette = ExtendedColors(
|
|||
disabledButtonColor = Dark.disabledButtonColor,
|
||||
reference = Dark.reference,
|
||||
buttonShadowColor = Dark.buttonShadowColor,
|
||||
|
||||
screenTitleColor = Dark.screenTitleColor
|
||||
)
|
||||
|
||||
internal val LightExtendedColorPalette = ExtendedColors(
|
||||
|
@ -187,7 +192,8 @@ internal val LightExtendedColorPalette = ExtendedColors(
|
|||
disabledButtonTextColor = Light.disabledButtonTextColor,
|
||||
disabledButtonColor = Light.disabledButtonColor,
|
||||
reference = Light.reference,
|
||||
buttonShadowColor = Light.buttonShadowColor
|
||||
buttonShadowColor = Light.buttonShadowColor,
|
||||
screenTitleColor = Light.screenTitleColor,
|
||||
)
|
||||
|
||||
@Suppress("CompositionLocalAllowlist")
|
||||
|
@ -215,5 +221,6 @@ internal val LocalExtendedColors = staticCompositionLocalOf {
|
|||
disabledButtonColor = Color.Unspecified,
|
||||
reference = Color.Unspecified,
|
||||
buttonShadowColor = Color.Unspecified,
|
||||
screenTitleColor = Color.Unspecified,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -49,6 +49,11 @@ internal val PrimaryTypography = Typography(
|
|||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 30.sp
|
||||
),
|
||||
titleSmall = TextStyle(
|
||||
fontFamily = InterFontFamily,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 14.sp
|
||||
),
|
||||
bodyLarge = TextStyle(
|
||||
fontFamily = InterFontFamily,
|
||||
fontWeight = FontWeight.Normal,
|
||||
|
@ -99,7 +104,8 @@ data class Typography(
|
|||
data class ExtendedTypography(
|
||||
val chipIndex: TextStyle,
|
||||
val listItem: TextStyle,
|
||||
val zecBalance: TextStyle
|
||||
val zecBalance: TextStyle,
|
||||
val buttonText: TextStyle,
|
||||
)
|
||||
|
||||
@Suppress("CompositionLocalAllowlist")
|
||||
|
@ -125,6 +131,9 @@ val LocalExtendedTypography = staticCompositionLocalOf {
|
|||
fontFamily = Zboto,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 30.sp
|
||||
)
|
||||
),
|
||||
buttonText = PrimaryTypography.bodySmall.copy(
|
||||
fontSize = 14.sp
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
package co.electriccoin.zcash.ui.screen.settings
|
||||
|
||||
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||
import co.electriccoin.zcash.ui.screen.settings.model.TroubleshootingParameters
|
||||
import co.electriccoin.zcash.ui.screen.settings.view.Settings
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
class SettingsViewTestSetup(
|
||||
private val composeTestRule: ComposeContentTestRule,
|
||||
private val troubleshootingParameters: TroubleshootingParameters
|
||||
) {
|
||||
private val onBackCount = AtomicInteger(0)
|
||||
private val onBackupCount = AtomicInteger(0)
|
||||
private val onDocumentationCount = AtomicInteger(0)
|
||||
private val onPrivacyPolicyCount = AtomicInteger(0)
|
||||
private val onFeedbackCount = AtomicInteger(0)
|
||||
private val onAboutCount = AtomicInteger(0)
|
||||
private val onRescanCount = AtomicInteger(0)
|
||||
private val onBackgroundSyncChangedCount = AtomicInteger(0)
|
||||
private val onKeepScreenOnChangedCount = AtomicInteger(0)
|
||||
private val onAnalyticsChangedCount = AtomicInteger(0)
|
||||
|
||||
fun getBackCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onBackCount.get()
|
||||
}
|
||||
|
||||
fun getBackupCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onBackupCount.get()
|
||||
}
|
||||
|
||||
fun getDocumentationCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onDocumentationCount.get()
|
||||
}
|
||||
|
||||
fun getPrivacyPolicyCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onPrivacyPolicyCount.get()
|
||||
}
|
||||
|
||||
fun getFeedbackCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onFeedbackCount.get()
|
||||
}
|
||||
|
||||
fun getAboutCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onAboutCount.get()
|
||||
}
|
||||
|
||||
fun getRescanCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onRescanCount.get()
|
||||
}
|
||||
|
||||
fun getBackgroundSyncCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onBackgroundSyncChangedCount.get()
|
||||
}
|
||||
|
||||
fun getKeepScreenOnSyncCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onKeepScreenOnChangedCount.get()
|
||||
}
|
||||
|
||||
fun getAnalyticsCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onAnalyticsChangedCount.get()
|
||||
}
|
||||
|
||||
init {
|
||||
composeTestRule.setContent {
|
||||
ZcashTheme {
|
||||
Settings(
|
||||
troubleshootingParameters = troubleshootingParameters,
|
||||
onBack = {
|
||||
onBackCount.incrementAndGet()
|
||||
},
|
||||
onBackup = {
|
||||
onBackupCount.incrementAndGet()
|
||||
},
|
||||
onDocumentation = {
|
||||
onDocumentationCount.incrementAndGet()
|
||||
},
|
||||
onPrivacyPolicy = {
|
||||
onPrivacyPolicyCount.incrementAndGet()
|
||||
},
|
||||
onFeedback = {
|
||||
onFeedbackCount.incrementAndGet()
|
||||
},
|
||||
onAbout = {
|
||||
onAboutCount.incrementAndGet()
|
||||
},
|
||||
onRescanWallet = {
|
||||
onRescanCount.incrementAndGet()
|
||||
},
|
||||
onBackgroundSyncSettingsChanged = {
|
||||
onBackgroundSyncChangedCount.incrementAndGet()
|
||||
},
|
||||
onKeepScreenOnDuringSyncSettingsChanged = {
|
||||
onKeepScreenOnChangedCount.incrementAndGet()
|
||||
},
|
||||
onAnalyticsSettingsChanged = {
|
||||
onAnalyticsChangedCount.incrementAndGet()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package co.electriccoin.zcash.ui.screen.settings.fixture
|
||||
|
||||
import co.electriccoin.zcash.ui.screen.settings.model.TroubleshootingParameters
|
||||
|
||||
internal object TroubleshootingParametersFixture {
|
||||
internal const val ENABLED = false
|
||||
internal const val BACKGROUND_SYNC_ENABLED = false
|
||||
internal const val KEEP_SCREEN_ON_DURING_SYNC_ENABLED = false
|
||||
internal const val ANALYTICS_ENABLED = false
|
||||
internal const val RESCAN_ENABLED = false
|
||||
|
||||
fun new(
|
||||
isEnabled: Boolean = ENABLED,
|
||||
isBackgroundSyncEnabled: Boolean = BACKGROUND_SYNC_ENABLED,
|
||||
isKeepScreenOnDuringSyncEnabled: Boolean = KEEP_SCREEN_ON_DURING_SYNC_ENABLED,
|
||||
isAnalyticsEnabled: Boolean = ANALYTICS_ENABLED,
|
||||
isRescanEnabled: Boolean = RESCAN_ENABLED,
|
||||
) = TroubleshootingParameters(
|
||||
isEnabled,
|
||||
isBackgroundSyncEnabled,
|
||||
isKeepScreenOnDuringSyncEnabled,
|
||||
isAnalyticsEnabled,
|
||||
isRescanEnabled
|
||||
)
|
||||
}
|
|
@ -3,34 +3,31 @@ package co.electriccoin.zcash.ui.screen.settings.view
|
|||
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.test.filters.MediumTest
|
||||
import co.electriccoin.zcash.configuration.model.map.StringConfiguration
|
||||
import androidx.test.filters.SmallTest
|
||||
import co.electriccoin.zcash.test.UiTestPrerequisites
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.configuration.ConfigurationEntries
|
||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||
import co.electriccoin.zcash.ui.screen.settings.SettingsTag
|
||||
import co.electriccoin.zcash.ui.screen.settings.SettingsViewTestSetup
|
||||
import co.electriccoin.zcash.ui.screen.settings.fixture.TroubleshootingParametersFixture
|
||||
import co.electriccoin.zcash.ui.test.getStringResource
|
||||
import kotlinx.collections.immutable.toPersistentMap
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class SettingsViewTest : UiTestPrerequisites() {
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun back() = runTest {
|
||||
val testSetup = TestSetup(composeTestRule)
|
||||
fun on_back_test() {
|
||||
val testSetup = SettingsViewTestSetup(composeTestRule, TroubleshootingParametersFixture.new())
|
||||
|
||||
assertEquals(0, testSetup.getOnBackCount())
|
||||
assertEquals(0, testSetup.getBackCount())
|
||||
|
||||
composeTestRule.onNodeWithContentDescription(
|
||||
getStringResource(R.string.settings_back_content_description)
|
||||
|
@ -38,141 +35,208 @@ class SettingsViewTest : UiTestPrerequisites() {
|
|||
it.performClick()
|
||||
}
|
||||
|
||||
assertEquals(1, testSetup.getOnBackCount())
|
||||
assertEquals(1, testSetup.getBackCount())
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun rescan() = runTest {
|
||||
val testSetup = TestSetup(composeTestRule)
|
||||
fun on_feedback_test() {
|
||||
val testSetup = SettingsViewTestSetup(composeTestRule, TroubleshootingParametersFixture.new())
|
||||
|
||||
if (ConfigurationEntries.IS_RESCAN_ENABLED.getValue(
|
||||
StringConfiguration(emptyMap<String, String>().toPersistentMap(), null)
|
||||
assertEquals(0, testSetup.getFeedbackCount())
|
||||
|
||||
composeTestRule.onNodeWithText(
|
||||
getStringResource(R.string.settings_send_us_feedback)
|
||||
).also {
|
||||
it.performClick()
|
||||
}
|
||||
|
||||
assertEquals(1, testSetup.getFeedbackCount())
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun on_backup_test() {
|
||||
val testSetup = SettingsViewTestSetup(composeTestRule, TroubleshootingParametersFixture.new())
|
||||
|
||||
assertEquals(0, testSetup.getBackupCount())
|
||||
|
||||
composeTestRule.onNodeWithText(
|
||||
getStringResource(R.string.settings_backup_wallet)
|
||||
).also {
|
||||
it.performClick()
|
||||
}
|
||||
|
||||
assertEquals(1, testSetup.getBackupCount())
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun on_documentation_test() {
|
||||
val testSetup = SettingsViewTestSetup(composeTestRule, TroubleshootingParametersFixture.new())
|
||||
|
||||
assertEquals(0, testSetup.getDocumentationCount())
|
||||
|
||||
composeTestRule.onNodeWithText(
|
||||
getStringResource(R.string.settings_documentation)
|
||||
).also {
|
||||
it.performClick()
|
||||
}
|
||||
|
||||
assertEquals(1, testSetup.getDocumentationCount())
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun on_privacy_policy_test() {
|
||||
val testSetup = SettingsViewTestSetup(composeTestRule, TroubleshootingParametersFixture.new())
|
||||
|
||||
assertEquals(0, testSetup.getPrivacyPolicyCount())
|
||||
|
||||
composeTestRule.onNodeWithText(
|
||||
getStringResource(R.string.settings_privacy_policy)
|
||||
).also {
|
||||
it.performClick()
|
||||
}
|
||||
|
||||
assertEquals(1, testSetup.getPrivacyPolicyCount())
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun on_about_test() {
|
||||
val testSetup = SettingsViewTestSetup(composeTestRule, TroubleshootingParametersFixture.new())
|
||||
|
||||
assertEquals(0, testSetup.getAboutCount())
|
||||
|
||||
composeTestRule.onNodeWithText(
|
||||
getStringResource(R.string.settings_about)
|
||||
).also {
|
||||
it.performClick()
|
||||
}
|
||||
|
||||
assertEquals(1, testSetup.getAboutCount())
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
fun troubleshooting_menu_visible_test() {
|
||||
SettingsViewTestSetup(composeTestRule, TroubleshootingParametersFixture.new(isEnabled = true))
|
||||
|
||||
composeTestRule.onNodeWithTag(SettingsTag.TROUBLESHOOTING_MENU).also {
|
||||
it.assertExists()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
fun troubleshooting_menu_not_visible_test() {
|
||||
SettingsViewTestSetup(composeTestRule, TroubleshootingParametersFixture.new(isEnabled = false))
|
||||
|
||||
composeTestRule.onNodeWithTag(SettingsTag.TROUBLESHOOTING_MENU).also {
|
||||
it.assertDoesNotExist()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun troubleshooting_rescan_test() {
|
||||
val testSetup = SettingsViewTestSetup(
|
||||
composeTestRule,
|
||||
TroubleshootingParametersFixture.new(
|
||||
isEnabled = true,
|
||||
isRescanEnabled = true
|
||||
)
|
||||
) {
|
||||
assertEquals(0, testSetup.getRescanCount())
|
||||
)
|
||||
|
||||
composeTestRule.onNodeWithContentDescription(
|
||||
getStringResource(R.string.settings_overflow_content_description)
|
||||
).also {
|
||||
it.performClick()
|
||||
}
|
||||
assertEquals(0, testSetup.getRescanCount())
|
||||
|
||||
composeTestRule.onNodeWithText(getStringResource(R.string.settings_rescan)).also {
|
||||
it.performClick()
|
||||
}
|
||||
composeTestRule.openTroubleshootingMenu()
|
||||
|
||||
assertEquals(1, testSetup.getRescanCount())
|
||||
composeTestRule.onNodeWithText(getStringResource(R.string.settings_troubleshooting_rescan)).also {
|
||||
it.performClick()
|
||||
}
|
||||
|
||||
assertEquals(1, testSetup.getRescanCount())
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun toggle_background_sync() = runTest {
|
||||
val testSetup = TestSetup(composeTestRule)
|
||||
fun troubleshooting_background_sync_test() {
|
||||
val testSetup = SettingsViewTestSetup(
|
||||
composeTestRule,
|
||||
TroubleshootingParametersFixture.new(
|
||||
isEnabled = true,
|
||||
isBackgroundSyncEnabled = true
|
||||
)
|
||||
)
|
||||
|
||||
assertEquals(0, testSetup.getBackgroundSyncToggleCount())
|
||||
assertEquals(0, testSetup.getBackgroundSyncCount())
|
||||
|
||||
composeTestRule.onNodeWithText(getStringResource(R.string.settings_enable_background_sync)).also {
|
||||
composeTestRule.openTroubleshootingMenu()
|
||||
|
||||
composeTestRule.onNodeWithText(
|
||||
getStringResource(R.string.settings_troubleshooting_enable_background_sync)
|
||||
).also {
|
||||
it.performClick()
|
||||
}
|
||||
|
||||
assertEquals(1, testSetup.getBackgroundSyncToggleCount())
|
||||
assertEquals(1, testSetup.getBackgroundSyncCount())
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun toggle_keep_screen_on() = runTest {
|
||||
val testSetup = TestSetup(composeTestRule)
|
||||
fun troubleshooting_keep_screen_on_during_sync_test() {
|
||||
val testSetup = SettingsViewTestSetup(
|
||||
composeTestRule,
|
||||
TroubleshootingParametersFixture.new(
|
||||
isEnabled = true,
|
||||
isKeepScreenOnDuringSyncEnabled = true
|
||||
)
|
||||
)
|
||||
|
||||
assertEquals(0, testSetup.getKeepScreenOnSyncToggleCount())
|
||||
assertEquals(0, testSetup.getKeepScreenOnSyncCount())
|
||||
|
||||
composeTestRule.onNodeWithText(getStringResource(R.string.settings_enable_keep_screen_on)).also {
|
||||
composeTestRule.openTroubleshootingMenu()
|
||||
|
||||
composeTestRule.onNodeWithText(
|
||||
getStringResource(R.string.settings_troubleshooting_enable_keep_screen_on)
|
||||
).also {
|
||||
it.performClick()
|
||||
}
|
||||
|
||||
assertEquals(1, testSetup.getKeepScreenOnSyncToggleCount())
|
||||
assertEquals(1, testSetup.getKeepScreenOnSyncCount())
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun toggle_analytics() = runTest {
|
||||
val testSetup = TestSetup(composeTestRule)
|
||||
fun troubleshooting_analytics_test() {
|
||||
val testSetup = SettingsViewTestSetup(
|
||||
composeTestRule,
|
||||
TroubleshootingParametersFixture.new(
|
||||
isEnabled = true,
|
||||
isAnalyticsEnabled = true
|
||||
)
|
||||
)
|
||||
|
||||
assertEquals(0, testSetup.getAnalyticsToggleCount())
|
||||
assertEquals(0, testSetup.getAnalyticsCount())
|
||||
|
||||
composeTestRule.onNodeWithText(getStringResource(R.string.settings_enable_analytics)).also {
|
||||
composeTestRule.openTroubleshootingMenu()
|
||||
|
||||
composeTestRule.onNodeWithText(
|
||||
getStringResource(R.string.settings_troubleshooting_enable_analytics)
|
||||
).also {
|
||||
it.performClick()
|
||||
}
|
||||
|
||||
assertEquals(1, testSetup.getAnalyticsToggleCount())
|
||||
}
|
||||
|
||||
private class TestSetup(private val composeTestRule: ComposeContentTestRule) {
|
||||
|
||||
private val onBackCount = AtomicInteger(0)
|
||||
private val onBackupCount = AtomicInteger(0)
|
||||
private val onRescanCount = AtomicInteger(0)
|
||||
private val onBackgroundSyncChangedCount = AtomicInteger(0)
|
||||
private val onKeepScreenOnChangedCount = AtomicInteger(0)
|
||||
private val onAnalyticsChangedCount = AtomicInteger(0)
|
||||
|
||||
fun getOnBackCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onBackCount.get()
|
||||
}
|
||||
|
||||
fun getBackupCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onBackupCount.get()
|
||||
}
|
||||
|
||||
fun getRescanCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onRescanCount.get()
|
||||
}
|
||||
|
||||
fun getBackgroundSyncToggleCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onBackgroundSyncChangedCount.get()
|
||||
}
|
||||
|
||||
fun getKeepScreenOnSyncToggleCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onKeepScreenOnChangedCount.get()
|
||||
}
|
||||
|
||||
fun getAnalyticsToggleCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onAnalyticsChangedCount.get()
|
||||
}
|
||||
|
||||
init {
|
||||
composeTestRule.setContent {
|
||||
ZcashTheme {
|
||||
Settings(
|
||||
isBackgroundSyncEnabled = true,
|
||||
isKeepScreenOnDuringSyncEnabled = true,
|
||||
isAnalyticsEnabled = true,
|
||||
isRescanEnabled = true,
|
||||
onBack = {
|
||||
onBackCount.incrementAndGet()
|
||||
},
|
||||
onRescanWallet = {
|
||||
onRescanCount.incrementAndGet()
|
||||
},
|
||||
onBackgroundSyncSettingsChanged = {
|
||||
onBackgroundSyncChangedCount.incrementAndGet()
|
||||
},
|
||||
onIsKeepScreenOnDuringSyncSettingsChanged = {
|
||||
onKeepScreenOnChangedCount.incrementAndGet()
|
||||
},
|
||||
onAnalyticsSettingsChanged = {
|
||||
onAnalyticsChangedCount.incrementAndGet()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
assertEquals(1, testSetup.getAnalyticsCount())
|
||||
}
|
||||
}
|
||||
|
||||
fun ComposeContentTestRule.openTroubleshootingMenu() {
|
||||
onNodeWithContentDescription(
|
||||
getStringResource(R.string.settings_troubleshooting_menu_content_description)
|
||||
).also {
|
||||
it.performClick()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,12 @@ import androidx.activity.ComponentActivity
|
|||
import androidx.activity.viewModels
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import co.electriccoin.zcash.ui.BuildConfig
|
||||
import co.electriccoin.zcash.ui.MainActivity
|
||||
import co.electriccoin.zcash.ui.configuration.ConfigurationEntries
|
||||
import co.electriccoin.zcash.ui.configuration.RemoteConfig
|
||||
import co.electriccoin.zcash.ui.screen.home.viewmodel.WalletViewModel
|
||||
import co.electriccoin.zcash.ui.screen.settings.model.TroubleshootingParameters
|
||||
import co.electriccoin.zcash.ui.screen.settings.view.Settings
|
||||
import co.electriccoin.zcash.ui.screen.settings.viewmodel.SettingsViewModel
|
||||
|
||||
|
@ -45,18 +47,26 @@ private fun WrapSettings(
|
|||
// Display loading indicator
|
||||
} else {
|
||||
Settings(
|
||||
isBackgroundSyncEnabled = isBackgroundSyncEnabled,
|
||||
isKeepScreenOnDuringSyncEnabled = isKeepScreenOnWhileSyncing,
|
||||
isAnalyticsEnabled = isAnalyticsEnabled,
|
||||
isRescanEnabled = ConfigurationEntries.IS_RESCAN_ENABLED.getValue(RemoteConfig.current),
|
||||
TroubleshootingParameters(
|
||||
isEnabled = BuildConfig.DEBUG,
|
||||
isBackgroundSyncEnabled = isBackgroundSyncEnabled,
|
||||
isKeepScreenOnDuringSyncEnabled = isKeepScreenOnWhileSyncing,
|
||||
isAnalyticsEnabled = isAnalyticsEnabled,
|
||||
isRescanEnabled = ConfigurationEntries.IS_RESCAN_ENABLED.getValue(RemoteConfig.current),
|
||||
),
|
||||
onBack = goBack,
|
||||
onBackup = {},
|
||||
onDocumentation = {},
|
||||
onPrivacyPolicy = {},
|
||||
onFeedback = {},
|
||||
onAbout = {},
|
||||
onRescanWallet = {
|
||||
walletViewModel.rescanBlockchain()
|
||||
},
|
||||
onBackgroundSyncSettingsChanged = {
|
||||
settingsViewModel.setBackgroundSyncEnabled(it)
|
||||
},
|
||||
onIsKeepScreenOnDuringSyncSettingsChanged = {
|
||||
onKeepScreenOnDuringSyncSettingsChanged = {
|
||||
settingsViewModel.setKeepScreenOnWhileSyncing(it)
|
||||
},
|
||||
onAnalyticsSettingsChanged = {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package co.electriccoin.zcash.ui.screen.settings
|
||||
|
||||
/**
|
||||
* These are only used for automated testing.
|
||||
*/
|
||||
object SettingsTag {
|
||||
const val TROUBLESHOOTING_MENU = "troubleshooting_menu"
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package co.electriccoin.zcash.ui.screen.settings.model
|
||||
|
||||
data class TroubleshootingParameters(
|
||||
val isEnabled: Boolean,
|
||||
val isBackgroundSyncEnabled: Boolean,
|
||||
val isKeepScreenOnDuringSyncEnabled: Boolean,
|
||||
val isAnalyticsEnabled: Boolean,
|
||||
val isRescanEnabled: Boolean,
|
||||
)
|
|
@ -1,7 +1,12 @@
|
|||
package co.electriccoin.zcash.ui.screen.settings.view
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
|
@ -9,6 +14,9 @@ import androidx.compose.foundation.verticalScroll
|
|||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material.icons.outlined.Cancel
|
||||
import androidx.compose.material.icons.outlined.CheckCircle
|
||||
import androidx.compose.material3.CenterAlignedTopAppBar
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
|
@ -16,35 +24,47 @@ import androidx.compose.material3.Icon
|
|||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.design.MINIMAL_WEIGHT
|
||||
import co.electriccoin.zcash.ui.design.component.GradientSurface
|
||||
import co.electriccoin.zcash.ui.design.component.SwitchWithLabel
|
||||
import co.electriccoin.zcash.ui.design.component.PrimaryButton
|
||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme.dimens
|
||||
import co.electriccoin.zcash.ui.screen.settings.SettingsTag
|
||||
import co.electriccoin.zcash.ui.screen.settings.model.TroubleshootingParameters
|
||||
|
||||
@Preview("Settings")
|
||||
@Composable
|
||||
private fun PreviewSettings() {
|
||||
ZcashTheme(darkTheme = true) {
|
||||
ZcashTheme(darkTheme = false) {
|
||||
GradientSurface {
|
||||
Settings(
|
||||
isBackgroundSyncEnabled = true,
|
||||
isKeepScreenOnDuringSyncEnabled = true,
|
||||
isAnalyticsEnabled = true,
|
||||
isRescanEnabled = true,
|
||||
TroubleshootingParameters(
|
||||
isEnabled = false,
|
||||
isBackgroundSyncEnabled = false,
|
||||
isKeepScreenOnDuringSyncEnabled = false,
|
||||
isAnalyticsEnabled = false,
|
||||
isRescanEnabled = false
|
||||
),
|
||||
onBack = {},
|
||||
onBackup = {},
|
||||
onDocumentation = {},
|
||||
onPrivacyPolicy = {},
|
||||
onFeedback = {},
|
||||
onAbout = {},
|
||||
onRescanWallet = {},
|
||||
onBackgroundSyncSettingsChanged = {},
|
||||
onIsKeepScreenOnDuringSyncSettingsChanged = {},
|
||||
onKeepScreenOnDuringSyncSettingsChanged = {},
|
||||
onAnalyticsSettingsChanged = {}
|
||||
)
|
||||
}
|
||||
|
@ -54,81 +74,134 @@ private fun PreviewSettings() {
|
|||
@Composable
|
||||
@Suppress("LongParameterList")
|
||||
fun Settings(
|
||||
isBackgroundSyncEnabled: Boolean,
|
||||
isKeepScreenOnDuringSyncEnabled: Boolean,
|
||||
isAnalyticsEnabled: Boolean,
|
||||
isRescanEnabled: Boolean,
|
||||
troubleshootingParameters: TroubleshootingParameters,
|
||||
onBack: () -> Unit,
|
||||
onBackup: () -> Unit,
|
||||
onDocumentation: () -> Unit,
|
||||
onPrivacyPolicy: () -> Unit,
|
||||
onFeedback: () -> Unit,
|
||||
onAbout: () -> Unit,
|
||||
onRescanWallet: () -> Unit,
|
||||
onBackgroundSyncSettingsChanged: (Boolean) -> Unit,
|
||||
onIsKeepScreenOnDuringSyncSettingsChanged: (Boolean) -> Unit,
|
||||
onKeepScreenOnDuringSyncSettingsChanged: (Boolean) -> Unit,
|
||||
onAnalyticsSettingsChanged: (Boolean) -> Unit
|
||||
) {
|
||||
Scaffold(topBar = {
|
||||
SettingsTopAppBar(
|
||||
isRescanEnabled = isRescanEnabled,
|
||||
troubleshootingParameters = troubleshootingParameters,
|
||||
onBackgroundSyncSettingsChanged = onBackgroundSyncSettingsChanged,
|
||||
onKeepScreenOnDuringSyncSettingsChanged = onKeepScreenOnDuringSyncSettingsChanged,
|
||||
onAnalyticsSettingsChanged = onAnalyticsSettingsChanged,
|
||||
onRescanWallet = onRescanWallet,
|
||||
onBack = onBack,
|
||||
onRescanWallet = onRescanWallet
|
||||
)
|
||||
}) { paddingValues ->
|
||||
SettingsMainContent(
|
||||
isBackgroundSyncEnabled = isBackgroundSyncEnabled,
|
||||
isKeepScreenOnDuringSyncEnabled = isKeepScreenOnDuringSyncEnabled,
|
||||
isAnalyticsEnabled = isAnalyticsEnabled,
|
||||
onBackgroundSyncSettingsChanged = onBackgroundSyncSettingsChanged,
|
||||
onIsKeepScreenOnDuringSyncSettingsChanged = onIsKeepScreenOnDuringSyncSettingsChanged,
|
||||
onAnalyticsSettingsChanged = onAnalyticsSettingsChanged,
|
||||
modifier = Modifier
|
||||
.verticalScroll(
|
||||
rememberScrollState()
|
||||
)
|
||||
.padding(
|
||||
top = paddingValues.calculateTopPadding() + dimens.spacingDefault,
|
||||
bottom = paddingValues.calculateTopPadding() + dimens.spacingDefault,
|
||||
start = dimens.spacingDefault,
|
||||
end = dimens.spacingDefault
|
||||
)
|
||||
top = paddingValues.calculateTopPadding() + dimens.spacingHuge,
|
||||
bottom = paddingValues.calculateBottomPadding() + dimens.spacingHuge,
|
||||
start = dimens.spacingHuge,
|
||||
end = dimens.spacingHuge
|
||||
),
|
||||
onBackup = onBackup,
|
||||
onDocumentation = onDocumentation,
|
||||
onPrivacyPolicy = onPrivacyPolicy,
|
||||
onFeedback = onFeedback,
|
||||
onAbout = onAbout,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Suppress("LongParameterList")
|
||||
private fun SettingsTopAppBar(
|
||||
isRescanEnabled: Boolean,
|
||||
troubleshootingParameters: TroubleshootingParameters,
|
||||
onBackgroundSyncSettingsChanged: (Boolean) -> Unit,
|
||||
onKeepScreenOnDuringSyncSettingsChanged: (Boolean) -> Unit,
|
||||
onAnalyticsSettingsChanged: (Boolean) -> Unit,
|
||||
onRescanWallet: () -> Unit,
|
||||
onBack: () -> Unit,
|
||||
onRescanWallet: () -> Unit
|
||||
) {
|
||||
TopAppBar(
|
||||
title = { Text(text = stringResource(id = R.string.settings_header)) },
|
||||
CenterAlignedTopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.settings_header).uppercase(),
|
||||
style = ZcashTheme.typography.primary.titleSmall,
|
||||
color = ZcashTheme.colors.screenTitleColor
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
onClick = onBack
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.ArrowBack,
|
||||
contentDescription = stringResource(R.string.settings_back_content_description)
|
||||
IconButton(
|
||||
onClick = onBack
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.ArrowBack,
|
||||
contentDescription = stringResource(R.string.settings_back_content_description)
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = stringResource(id = R.string.settings_back).uppercase(),
|
||||
style = ZcashTheme.typography.primary.bodyMedium
|
||||
)
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
if (isRescanEnabled) {
|
||||
TroubleshootingMenu(onRescanWallet)
|
||||
if (troubleshootingParameters.isEnabled) {
|
||||
TroubleshootingMenu(
|
||||
troubleshootingParameters,
|
||||
onBackgroundSyncSettingsChanged,
|
||||
onKeepScreenOnDuringSyncSettingsChanged,
|
||||
onAnalyticsSettingsChanged,
|
||||
onRescanWallet
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add icon to Troubleshooting menu. No content description, as this is debug only menu.
|
||||
*/
|
||||
@Composable
|
||||
private fun AddIcon(enabled: Boolean) {
|
||||
if (enabled) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.CheckCircle,
|
||||
contentDescription = null
|
||||
)
|
||||
} else {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Cancel,
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TroubleshootingMenu(
|
||||
troubleshootParams: TroubleshootingParameters,
|
||||
onBackgroundSyncSettingsChanged: (Boolean) -> Unit,
|
||||
onKeepScreenOnDuringSyncSettingsChanged: (Boolean) -> Unit,
|
||||
onAnalyticsSettingsChanged: (Boolean) -> Unit,
|
||||
onRescanWallet: () -> Unit
|
||||
) {
|
||||
Column {
|
||||
Column(
|
||||
modifier = Modifier.testTag(SettingsTag.TROUBLESHOOTING_MENU)
|
||||
) {
|
||||
var expanded by rememberSaveable { mutableStateOf(false) }
|
||||
IconButton(onClick = { expanded = true }) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.MoreVert,
|
||||
contentDescription = stringResource(id = R.string.settings_overflow_content_description)
|
||||
contentDescription = stringResource(id = R.string.settings_troubleshooting_menu_content_description)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -137,12 +210,41 @@ private fun TroubleshootingMenu(
|
|||
onDismissRequest = { expanded = false }
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringResource(id = R.string.settings_rescan)) },
|
||||
text = { Text(stringResource(id = R.string.settings_troubleshooting_enable_background_sync)) },
|
||||
onClick = {
|
||||
onRescanWallet()
|
||||
onBackgroundSyncSettingsChanged(!troubleshootParams.isBackgroundSyncEnabled)
|
||||
expanded = false
|
||||
}
|
||||
},
|
||||
leadingIcon = { AddIcon(troubleshootParams.isBackgroundSyncEnabled) }
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringResource(id = R.string.settings_troubleshooting_enable_keep_screen_on)) },
|
||||
onClick = {
|
||||
onKeepScreenOnDuringSyncSettingsChanged(!troubleshootParams.isKeepScreenOnDuringSyncEnabled)
|
||||
expanded = false
|
||||
},
|
||||
leadingIcon = { AddIcon(troubleshootParams.isKeepScreenOnDuringSyncEnabled) }
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringResource(id = R.string.settings_troubleshooting_enable_analytics)) },
|
||||
onClick = {
|
||||
onAnalyticsSettingsChanged(!troubleshootParams.isAnalyticsEnabled)
|
||||
expanded = false
|
||||
},
|
||||
leadingIcon = { AddIcon(troubleshootParams.isAnalyticsEnabled) }
|
||||
)
|
||||
// isRescanEnabled means if this feature should be visible, not whether it is enabled as in the case of
|
||||
// the previous booleans
|
||||
if (troubleshootParams.isRescanEnabled) {
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringResource(id = R.string.settings_troubleshooting_rescan)) },
|
||||
onClick = {
|
||||
onRescanWallet()
|
||||
expanded = false
|
||||
},
|
||||
leadingIcon = { AddIcon(true) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -150,35 +252,77 @@ private fun TroubleshootingMenu(
|
|||
@Composable
|
||||
@Suppress("LongParameterList")
|
||||
private fun SettingsMainContent(
|
||||
isBackgroundSyncEnabled: Boolean,
|
||||
isKeepScreenOnDuringSyncEnabled: Boolean,
|
||||
isAnalyticsEnabled: Boolean,
|
||||
onBackgroundSyncSettingsChanged: (Boolean) -> Unit,
|
||||
onIsKeepScreenOnDuringSyncSettingsChanged: (Boolean) -> Unit,
|
||||
onAnalyticsSettingsChanged: (Boolean) -> Unit,
|
||||
onBackup: () -> Unit,
|
||||
onDocumentation: () -> Unit,
|
||||
onPrivacyPolicy: () -> Unit,
|
||||
onFeedback: () -> Unit,
|
||||
onAbout: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
SwitchWithLabel(
|
||||
label = stringResource(id = R.string.settings_enable_background_sync),
|
||||
state = isBackgroundSyncEnabled,
|
||||
onStateChange = { onBackgroundSyncSettingsChanged(!isBackgroundSyncEnabled) }
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxHeight()
|
||||
.fillMaxWidth()
|
||||
.then(modifier),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
PrimaryButton(
|
||||
onClick = onBackup,
|
||||
text = stringResource(R.string.settings_backup_wallet),
|
||||
outerPaddingValues = PaddingValues(
|
||||
horizontal = dimens.spacingNone,
|
||||
vertical = dimens.spacingSmall
|
||||
),
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(dimens.spacingXlarge))
|
||||
Spacer(modifier = Modifier.height(dimens.spacingDefault))
|
||||
|
||||
SwitchWithLabel(
|
||||
label = stringResource(id = R.string.settings_enable_keep_screen_on),
|
||||
state = isKeepScreenOnDuringSyncEnabled,
|
||||
onStateChange = { onIsKeepScreenOnDuringSyncSettingsChanged(!isKeepScreenOnDuringSyncEnabled) }
|
||||
PrimaryButton(
|
||||
onClick = onFeedback,
|
||||
text = stringResource(R.string.settings_send_us_feedback),
|
||||
outerPaddingValues = PaddingValues(
|
||||
horizontal = dimens.spacingNone,
|
||||
vertical = dimens.spacingSmall
|
||||
),
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(dimens.spacingXlarge))
|
||||
Spacer(modifier = Modifier.height(dimens.spacingDefault))
|
||||
|
||||
SwitchWithLabel(
|
||||
label = stringResource(id = R.string.settings_enable_analytics),
|
||||
state = isAnalyticsEnabled,
|
||||
onStateChange = { onAnalyticsSettingsChanged(!isAnalyticsEnabled) }
|
||||
PrimaryButton(
|
||||
onClick = onPrivacyPolicy,
|
||||
text = stringResource(R.string.settings_privacy_policy),
|
||||
outerPaddingValues = PaddingValues(
|
||||
horizontal = dimens.spacingNone,
|
||||
vertical = dimens.spacingSmall
|
||||
),
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(dimens.spacingDefault))
|
||||
|
||||
PrimaryButton(
|
||||
onClick = onDocumentation,
|
||||
text = stringResource(R.string.settings_documentation),
|
||||
outerPaddingValues = PaddingValues(
|
||||
horizontal = dimens.spacingNone,
|
||||
vertical = dimens.spacingSmall
|
||||
),
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(dimens.spacingDefault))
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
.weight(MINIMAL_WEIGHT)
|
||||
)
|
||||
|
||||
PrimaryButton(
|
||||
onClick = onAbout,
|
||||
text = stringResource(R.string.settings_about),
|
||||
outerPaddingValues = PaddingValues(
|
||||
horizontal = dimens.spacingNone,
|
||||
vertical = dimens.spacingSmall
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
<resources>
|
||||
<string name="settings_header">Settings</string>
|
||||
<string name="settings_back">Back</string>
|
||||
<string name="settings_back_content_description">Back</string>
|
||||
|
||||
<string name="settings_overflow_content_description">Additional settings</string>
|
||||
<string name="settings_rescan">Rescan blockchain</string>
|
||||
<string name="settings_enable_background_sync">Background sync</string>
|
||||
<string name="settings_enable_keep_screen_on">Keep screen on during sync</string>
|
||||
<string name="settings_enable_analytics">Report crashes</string>
|
||||
<string name="settings_troubleshooting_menu_content_description">Additional settings</string>
|
||||
<string name="settings_troubleshooting_rescan">Rescan blockchain</string>
|
||||
<string name="settings_troubleshooting_enable_background_sync">Background sync</string>
|
||||
<string name="settings_troubleshooting_enable_keep_screen_on">Keep screen on during sync</string>
|
||||
<string name="settings_troubleshooting_enable_analytics">Report crashes</string>
|
||||
|
||||
<string name="settings_backup_wallet">Backup wallet</string>
|
||||
<string name="settings_documentation">Documentation</string>
|
||||
<string name="settings_privacy_policy">Privacy policy</string>
|
||||
<string name="settings_send_us_feedback">Send us feedback</string>
|
||||
<string name="settings_about">About</string>
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue