From 987595eaa2a843172849fd6cf72b893fac5c84df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Honza=20Rychnovsk=C3=BD?= Date: Wed, 19 Jun 2024 14:09:28 +0200 Subject: [PATCH] [#1011] Dark mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [#1011] Rework buttons design system * [#1011] Dark mode in Onboarding screen * [#1011] Welcome animation dark mode * [#1011] SecurityWarning screen dark mode + Proper coloring of the labeled checkbox across the app * [#1011] NewWalletRecovery dark mode + Chip and ChipGrid coloring + Navigation button and Dialog coloring + NewWalletRecovery screen button copy update * [#1011] RestoreView dark mode + Chip components coloring * [#1011] RestoreView.Birthday dark mode + Fix Primary/Secondary colors * [#1011] Settings screen dark mode - Fix TopAppBar colors in dark mode * [#1011] Support screen dark mode * Fix static code analysis warnings * [#1011] About screen dark mode * [#1011] ChooseServer screen dark mode + LabeledRadioButton coloring - Closes #1410 * [#1011] AppAlertDialog dark mode * [#1011] Not Enough Free Space screen dark mode - Screen redesigned to align with latest design specifications - Added Go To System Settings and Go To App Settings buttons to the screen - Closes #1337 - Few unused resources removed * [#1011] App Update screen dark mode * [#1011] Balances screen dark mode + dividers’ color review * [#1011] Receive screen dark mode * [#1011] Send.Form screen dark mode * [#1011] Send.Confirmation screen dark mode * [#1011] Send.MultipleTrxError screen dark mode * [#1011] Scan screen dark mode * [#1011] TransactionHistory screen dark mode * Changelog update * Address review comments --- CHANGELOG.md | 4 + .../ui/design/component/BubbleMessage.kt | 2 +- .../zcash/ui/design/component/Button.kt | 204 +++++++++++----- .../zcash/ui/design/component/Checkbox.kt | 112 ++++++--- .../zcash/ui/design/component/Chip.kt | 57 +++-- .../zcash/ui/design/component/ChipGrid.kt | 25 +- .../ui/design/component/CommonComponents.kt | 16 ++ .../zcash/ui/design/component/Dialog.kt | 70 ++++++ .../zcash/ui/design/component/PagerTabs.kt | 8 +- .../zcash/ui/design/component/RadioButton.kt | 49 +++- .../zcash/ui/design/component/Text.kt | 42 ++-- .../zcash/ui/design/component/TextField.kt | 7 +- .../zcash/ui/design/component/TopAppBar.kt | 24 ++ .../ui/design/component/WelcomeAnimation.kt | 3 + .../zcash/ui/design/theme/Dimens.kt | 2 +- .../zcash/ui/design/theme/ExtendedColors.kt | 26 ++- .../ui/design/theme/internal/ButtonColors.kt | 123 ++++++++++ .../zcash/ui/design/theme/internal/Color.kt | 218 ++++++++++-------- .../design/theme/internal/TopAppBarColors.kt | 4 +- .../ui/design/theme/internal/Typography.kt | 9 +- .../ui/screen/scan/util/SettingsUtilTest.kt | 1 + .../co/electriccoin/zcash/ui/MainActivity.kt | 11 +- .../co/electriccoin/zcash/ui/Navigation.kt | 19 +- .../common/compose/SynchronizationStatus.kt | 5 +- .../zcash/ui/screen/about/view/AboutView.kt | 10 +- .../ui/screen/account/view/AccountView.kt | 2 +- .../ui/screen/account/view/HistoryView.kt | 46 ++-- .../authentication/view/AuthenticationView.kt | 32 ++- .../ui/screen/balances/view/BalancesView.kt | 25 +- .../chooseserver/view/ChooseServerView.kt | 121 ++++++---- .../zcash/ui/screen/debug/view/DesignGuide.kt | 3 - .../deletewallet/view/DeleteWalletView.kt | 23 +- .../disconnected/view/DisconnectedView.kt | 5 +- .../exportdata/view/ExportPrivateDataView.kt | 30 ++- .../zcash/ui/screen/home/view/HomeView.kt | 2 +- .../view/NewWalletRecoveryView.kt | 19 +- .../screen/onboarding/view/OnboardingView.kt | 25 +- .../util/AndroidQrCodeImageGenerator.kt | 2 + .../screen/receive/util/JvmQrCodeGenerator.kt | 12 +- .../ui/screen/receive/view/ReceiveView.kt | 76 ++++-- .../ui/screen/restore/view/RestoreView.kt | 100 ++++++-- .../zcash/ui/screen/scan/AndroidScan.kt | 4 +- .../ui/screen/scan/util/QrCodeAnalyzer.kt | 4 +- .../zcash/ui/screen/scan/view/ScanView.kt | 22 +- .../view/SecurityWarningView.kt | 46 ++-- .../seedrecovery/view/SeedRecoveryView.kt | 3 - .../zcash/ui/screen/send/view/SendView.kt | 17 +- .../view/SendConfirmationView.kt | 157 +++++++++++-- .../ui/screen/support/view/SupportView.kt | 25 +- .../ui/screen/update/AppUpdateCheckerMock.kt | 2 +- .../zcash/ui/screen/update/view/UpdateView.kt | 72 +++++- .../screen/warning/AndroidNotEnoughSpace.kt | 82 ++++++- .../screen/warning/view/NotEnoughSpaceView.kt | 198 ++++++++++++---- .../viewmodel/StorageCheckViewModel.kt | 8 + .../ui/{screen/scan => }/util/SettingsUtil.kt | 13 +- .../drawable-night/ic_trx_collapse.xml | 15 ++ .../drawable-night/ic_help_question_mark.xml | 14 ++ .../res/ui/choose_server/values/strings.xml | 7 +- .../ui/common/drawable-night/zashi_logo.webp | Bin 708 -> 0 bytes .../drawable/ic_zashi_logo_sign_warn.xml} | 0 .../res/ui/common/drawable/zashi_logo.webp | Bin 3730 -> 0 bytes .../drawable/zashi_logo_sign.xml | 0 .../ui/new_wallet_recovery/values/strings.xml | 2 +- .../main/res/ui/onboarding/values/strings.xml | 2 +- .../receive/drawable/ic_adjust_brightness.xml | 2 +- .../drawable/ic_alert_circle_fill.xml | 9 - .../src/main/res/ui/update/values/strings.xml | 6 +- .../ui/warning/drawable/not_enough_space.xml | 12 - .../main/res/ui/warning/values/strings.xml | 18 +- 69 files changed, 1705 insertions(+), 609 deletions(-) create mode 100644 ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/ButtonColors.kt rename ui-lib/src/main/java/co/electriccoin/zcash/ui/{screen/scan => }/util/SettingsUtil.kt (71%) create mode 100644 ui-lib/src/main/res/ui/account/drawable-night/ic_trx_collapse.xml create mode 100644 ui-lib/src/main/res/ui/balances/drawable-night/ic_help_question_mark.xml delete mode 100644 ui-lib/src/main/res/ui/common/drawable-night/zashi_logo.webp rename ui-lib/src/main/res/ui/{update/drawable/ic_zashi_logo_update_required.xml => common/drawable/ic_zashi_logo_sign_warn.xml} (100%) delete mode 100644 ui-lib/src/main/res/ui/common/drawable/zashi_logo.webp rename ui-lib/src/main/res/ui/{send_confirmation => common}/drawable/zashi_logo_sign.xml (100%) delete mode 100644 ui-lib/src/main/res/ui/send_confirmation/drawable/ic_alert_circle_fill.xml delete mode 100644 ui-lib/src/main/res/ui/warning/drawable/not_enough_space.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index a3afdcf7..ea4fbd69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ directly impact users rather than highlighting other key architectural updates.* ### Added - New bubble message style for the Send and Transaction history item text components - Display all messages within the transaction history record when it is expanded +- The Dark mode is now officially supported by the entire app UI + +### Changed +- The Not Enough Free Space screen UI has been slightly refactored to align with the latest design guidelines ## [1.1.1 (660)] - 2024-06-05 diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/BubbleMessage.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/BubbleMessage.kt index 1fe1a663..1d82f90e 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/BubbleMessage.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/BubbleMessage.kt @@ -32,7 +32,7 @@ private const val COMPONENT_MIN_WIDTH = ARROW_WIDTH * 3 @Composable private fun BubbleWithTextPreview() { ZcashTheme { - BubbleMessage(backgroundColor = ZcashTheme.colors.dividerColor) { + BubbleMessage(backgroundColor = ZcashTheme.colors.primaryDividerColor) { Text( text = "TextTextTextText", fontSize = 16.sp, diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Button.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Button.kt index c9e82623..6b32ffa7 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Button.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Button.kt @@ -2,6 +2,7 @@ package co.electriccoin.zcash.ui.design.component import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.tween +import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.gestures.awaitFirstDown import androidx.compose.foundation.gestures.waitForUpOrCancellation @@ -11,13 +12,13 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults.buttonColors import androidx.compose.material3.CircularProgressIndicator -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -42,6 +43,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.constraintlayout.compose.ConstraintLayout import co.electriccoin.zcash.ui.design.theme.ZcashTheme +import co.electriccoin.zcash.ui.design.theme.internal.ButtonColors @Preview @Composable @@ -49,11 +51,59 @@ private fun ButtonComposablePreview() { ZcashTheme(forceDarkMode = false) { BlankSurface { Column(Modifier.padding(ZcashTheme.dimens.spacingDefault)) { - PrimaryButton(onClick = { }, text = "Primary") - PrimaryButton(onClick = { }, text = "Primary...", showProgressBar = true) - PrimaryButton(onClick = { }, text = "Primary Small", minHeight = ZcashTheme.dimens.buttonHeightSmall) - SecondaryButton(onClick = { }, text = "Secondary") - NavigationButton(onClick = { }, text = "Navigation") + Column( + modifier = + Modifier + .background(color = Color.Gray) + .padding(all = 24.dp) + ) { + PrimaryButton(onClick = { }, text = "Primary Basic") + PrimaryButton(onClick = { }, text = "Primary Disabled", enabled = false) + SecondaryButton(onClick = { }, text = "Secondary Basic") + SecondaryButton(onClick = { }, text = "Secondary Disabled", enabled = false) + } + + Spacer(modifier = Modifier.height(24.dp)) + + PrimaryButton(onClick = { }, text = "Primary loading", showProgressBar = true) + + Spacer(modifier = Modifier.height(24.dp)) + + @Suppress("MagicNumber") + Row { + PrimaryButton(onClick = { }, text = "Button 1", modifier = Modifier.weight(0.5f)) + Spacer(modifier = Modifier.width(24.dp)) + PrimaryButton(onClick = { }, text = "Button 2", modifier = Modifier.weight(0.5f)) + } + } + } + } +} + +@Preview +@Composable +private fun ButtonComposableDarkPreview() { + ZcashTheme(forceDarkMode = true) { + BlankSurface { + Column(Modifier.padding(ZcashTheme.dimens.spacingDefault)) { + Column( + modifier = + Modifier + .background(color = Color.Gray) + .padding(all = 24.dp) + ) { + PrimaryButton(onClick = { }, text = "Primary Basic") + PrimaryButton(onClick = { }, text = "Primary Disabled", enabled = false) + SecondaryButton(onClick = { }, text = "Secondary Basic") + SecondaryButton(onClick = { }, text = "Secondary Disabled", enabled = false) + } + + Spacer(modifier = Modifier.height(24.dp)) + + PrimaryButton(onClick = { }, text = "Primary loading", showProgressBar = true) + + Spacer(modifier = Modifier.height(24.dp)) + @Suppress("MagicNumber") Row { PrimaryButton(onClick = { }, text = "Button 1", modifier = Modifier.weight(0.5f)) @@ -75,8 +125,7 @@ fun PrimaryButton( minHeight: Dp = ZcashTheme.dimens.buttonHeight, enabled: Boolean = true, showProgressBar: Boolean = false, - buttonColor: Color = MaterialTheme.colorScheme.primary, - textColor: Color = MaterialTheme.colorScheme.onPrimary, + buttonColors: ButtonColors = ZcashTheme.colors.primaryButtonColors, textStyle: TextStyle = ZcashTheme.extendedTypography.buttonText, outerPaddingValues: PaddingValues = PaddingValues( @@ -94,37 +143,66 @@ fun PrimaryButton( Modifier .padding(outerPaddingValues) .shadow( - contentColor = textColor, - strokeColor = buttonColor, + contentColor = + if (enabled) { + buttonColors.shadowColor + } else { + buttonColors.disabledShadowColor + }, + strokeColor = + if (enabled) { + buttonColors.shadowStrokeColor + } else { + buttonColors.shadowDisabledStrokeColor + }, strokeWidth = 1.dp, offsetX = ZcashTheme.dimens.buttonShadowOffsetX, offsetY = ZcashTheme.dimens.buttonShadowOffsetY, spread = ZcashTheme.dimens.buttonShadowSpread, ) - .translationClick( - // + 6dp to exactly cover the bottom shadow - translationX = ZcashTheme.dimens.buttonShadowOffsetX + 6.dp, - translationY = ZcashTheme.dimens.buttonShadowOffsetX + 6.dp + .then( + if (enabled) { + Modifier.translationClick( + // + 6dp to exactly cover the bottom shadow + translationX = ZcashTheme.dimens.buttonShadowOffsetX + 6.dp, + translationY = ZcashTheme.dimens.buttonShadowOffsetX + 6.dp + ) + } else { + Modifier + } ) .defaultMinSize(minWidth, minHeight) - .border(1.dp, Color.Black) + .border( + width = 1.dp, + color = + if (enabled) { + buttonColors.strokeColor + } else { + buttonColors.disabledStrokeColor + } + ) ), colors = buttonColors( - containerColor = buttonColor, - disabledContainerColor = ZcashTheme.colors.disabledButtonColor, - disabledContentColor = ZcashTheme.colors.disabledButtonTextColor + containerColor = buttonColors.containerColor, + disabledContainerColor = buttonColors.disabledContainerColor, + disabledContentColor = buttonColors.disabledContainerColor, ), onClick = onClick, ) { - ConstraintLayout { + ConstraintLayout(modifier = Modifier.fillMaxWidth()) { val (title, spacer, progress) = createRefs() Text( style = textStyle, textAlign = TextAlign.Center, text = text.uppercase(), - color = textColor, + color = + if (enabled) { + buttonColors.textColor + } else { + buttonColors.disabledTextColor + }, modifier = Modifier.constrainAs(title) { top.linkTo(parent.top) @@ -165,7 +243,7 @@ fun PrimaryButton( } @Composable -@Suppress("LongParameterList") +@Suppress("LongParameterList", "LongMethod") fun SecondaryButton( onClick: () -> Unit, text: String, @@ -173,8 +251,7 @@ fun SecondaryButton( minWidth: Dp = ZcashTheme.dimens.buttonWidth, minHeight: Dp = ZcashTheme.dimens.buttonHeight, enabled: Boolean = true, - buttonColor: Color = MaterialTheme.colorScheme.secondary, - textColor: Color = MaterialTheme.colorScheme.onSecondary, + buttonColors: ButtonColors = ZcashTheme.colors.secondaryButtonColors, outerPaddingValues: PaddingValues = PaddingValues( horizontal = ZcashTheme.dimens.spacingNone, @@ -191,27 +268,51 @@ fun SecondaryButton( Modifier .padding(outerPaddingValues) .shadow( - contentColor = textColor, - strokeColor = buttonColor, + contentColor = + if (enabled) { + buttonColors.shadowColor + } else { + buttonColors.disabledShadowColor + }, + strokeColor = + if (enabled) { + buttonColors.shadowStrokeColor + } else { + buttonColors.shadowDisabledStrokeColor + }, strokeWidth = 1.dp, offsetX = ZcashTheme.dimens.buttonShadowOffsetX, offsetY = ZcashTheme.dimens.buttonShadowOffsetY, spread = ZcashTheme.dimens.buttonShadowSpread, ) - .translationClick( - // + 6dp to exactly cover the bottom shadow - translationX = ZcashTheme.dimens.buttonShadowOffsetX + 6.dp, - translationY = ZcashTheme.dimens.buttonShadowOffsetX + 6.dp + .then( + if (enabled) { + Modifier.translationClick( + // + 6dp to exactly cover the bottom shadow + translationX = ZcashTheme.dimens.buttonShadowOffsetX + 6.dp, + translationY = ZcashTheme.dimens.buttonShadowOffsetX + 6.dp + ) + } else { + Modifier + } ) .defaultMinSize(minWidth, minHeight) .fillMaxWidth() - .border(1.dp, Color.Black) + .border( + width = 1.dp, + color = + if (enabled) { + buttonColors.strokeColor + } else { + buttonColors.disabledStrokeColor + } + ) ), colors = buttonColors( - containerColor = buttonColor, - disabledContainerColor = ZcashTheme.colors.disabledButtonColor, - disabledContentColor = ZcashTheme.colors.disabledButtonTextColor + containerColor = buttonColors.containerColor, + disabledContainerColor = buttonColors.disabledContainerColor, + disabledContentColor = buttonColors.disabledContainerColor ), onClick = onClick, ) { @@ -219,37 +320,12 @@ fun SecondaryButton( style = ZcashTheme.extendedTypography.buttonText, textAlign = TextAlign.Center, text = text.uppercase(), - color = textColor - ) - } -} - -@Composable -fun NavigationButton( - onClick: () -> Unit, - text: String, - modifier: Modifier = Modifier, - outerPaddingValues: PaddingValues = - PaddingValues( - horizontal = ZcashTheme.dimens.spacingNone, - vertical = ZcashTheme.dimens.spacingSmall - ), -) { - Button( - shape = RectangleShape, - onClick = onClick, - modifier = - modifier.then( - Modifier - .padding(outerPaddingValues) - ), - colors = buttonColors(containerColor = MaterialTheme.colorScheme.secondary) - ) { - Text( - style = MaterialTheme.typography.labelLarge, - textAlign = TextAlign.Center, - text = text, - color = MaterialTheme.colorScheme.onSecondary + color = + if (enabled) { + buttonColors.textColor + } else { + buttonColors.disabledTextColor + } ) } } diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Checkbox.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Checkbox.kt index 531f7dcf..8c23332e 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Checkbox.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Checkbox.kt @@ -1,15 +1,19 @@ package co.electriccoin.zcash.ui.design.component +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.text.ClickableText +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Checkbox +import androidx.compose.material3.CheckboxDefaults +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.tooling.preview.Preview @@ -17,60 +21,102 @@ import co.electriccoin.zcash.ui.design.theme.ZcashTheme @Preview @Composable -private fun ComposablePreview() { - val checkBoxState = remember { mutableStateOf(false) } +private fun LabeledCheckboxPreview() { ZcashTheme(forceDarkMode = false) { - CheckBox( - onCheckedChange = { checkBoxState.value = it }, - text = "test", - checked = checkBoxState.value, - checkBoxTestTag = null - ) + BlankSurface { + Row { + LabeledCheckBox( + onCheckedChange = {}, + text = "Checkbox", + checked = false + ) + LabeledCheckBox( + onCheckedChange = {}, + text = "Checkbox", + checked = true + ) + } + } + } +} + +@Preview +@Composable +private fun LabeledCheckboxDarkPreview() { + ZcashTheme(forceDarkMode = true) { + BlankSurface { + Row { + LabeledCheckBox( + onCheckedChange = {}, + text = "Checkbox", + checked = false + ) + LabeledCheckBox( + onCheckedChange = {}, + text = "Checkbox", + checked = true + ) + } + } } } @Composable -fun CheckBox( +fun LabeledCheckBox( onCheckedChange: (Boolean) -> Unit, text: String, modifier: Modifier = Modifier, checked: Boolean = false, checkBoxTestTag: String? = null ) { + val (checkedState, setCheckedState) = rememberSaveable { mutableStateOf(checked) } + Row( verticalAlignment = Alignment.CenterVertically, - modifier = modifier - ) { - val checkBoxModifier = - Modifier - .padding( - top = ZcashTheme.dimens.spacingTiny, - bottom = ZcashTheme.dimens.spacingTiny, - end = ZcashTheme.dimens.spacingTiny - ) - .then( - if (checkBoxTestTag != null) { - Modifier.testTag(checkBoxTestTag) - } else { - Modifier + modifier = + modifier.then( + Modifier + .wrapContentSize() + .clip(RoundedCornerShape(ZcashTheme.dimens.regularRippleEffectCorner)) + .clickable { + setCheckedState(!checkedState) + onCheckedChange(!checkedState) } - ) - val (checkedState, setCheckedState) = rememberSaveable { mutableStateOf(checked) } + // Setting just the end padding, the start one is taken from the checkbox + .padding(end = ZcashTheme.dimens.spacingMid) + ) + ) { Checkbox( checked = checkedState, + colors = + CheckboxDefaults.colors( + checkedColor = ZcashTheme.colors.secondaryColor, + uncheckedColor = ZcashTheme.colors.secondaryColor, + checkmarkColor = ZcashTheme.colors.primaryColor, + ), onCheckedChange = { setCheckedState(it) onCheckedChange(it) }, enabled = true, - modifier = checkBoxModifier + modifier = + Modifier + .padding( + top = ZcashTheme.dimens.spacingTiny, + bottom = ZcashTheme.dimens.spacingTiny, + end = ZcashTheme.dimens.spacingTiny + ) + .then( + if (checkBoxTestTag != null) { + Modifier.testTag(checkBoxTestTag) + } else { + Modifier + } + ) ) - ClickableText( - onClick = { - setCheckedState(!checkedState) - onCheckedChange(!checkedState) - }, + Text( text = AnnotatedString(text), + color = ZcashTheme.colors.textPrimary, style = ZcashTheme.extendedTypography.checkboxText ) } diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Chip.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Chip.kt index e5ba26e5..75c38c67 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Chip.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Chip.kt @@ -2,16 +2,19 @@ package co.electriccoin.zcash.ui.design.component import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import co.electriccoin.zcash.spackle.model.Index import co.electriccoin.zcash.ui.design.theme.ZcashTheme @@ -19,7 +22,9 @@ import co.electriccoin.zcash.ui.design.theme.ZcashTheme @Composable private fun ComposableChipPreview() { ZcashTheme(forceDarkMode = false) { - Chip("route") + Box(modifier = Modifier.padding(all = 12.dp)) { + Chip("route") + } } } @@ -27,7 +32,9 @@ private fun ComposableChipPreview() { @Composable private fun ComposableChipIndexedPreview() { ZcashTheme(forceDarkMode = false) { - ChipIndexed(Index(0), "edict") + Box(modifier = Modifier.padding(all = 12.dp)) { + ChipIndexed(Index(0), "edict") + } } } @@ -35,7 +42,12 @@ private fun ComposableChipIndexedPreview() { @Composable private fun ComposableLongChipPreview() { ZcashTheme(forceDarkMode = false) { - ChipIndexed(Index(1), "a_very_long_seed_word_that_does_not_fit_into_the_chip_and_thus_needs_to_be_truncated") + Box(modifier = Modifier.padding(all = 12.dp)) { + ChipIndexed( + Index(1), + "a_very_long_seed_word_that_does_not_fit_into_the_chip_and_thus_needs_to_be_truncated" + ) + } } } @@ -43,7 +55,19 @@ private fun ComposableLongChipPreview() { @Composable private fun ComposableChipOnSurfacePreview() { ZcashTheme(forceDarkMode = false) { - ChipOnSurface("ribbon") + Box(modifier = Modifier.padding(all = 12.dp)) { + ChipOnSurface({}, "ribbon") + } + } +} + +@Preview +@Composable +private fun ComposableChipOnSurfaceDarkPreview() { + ZcashTheme(forceDarkMode = true) { + Box(modifier = Modifier.padding(all = 12.dp)) { + ChipOnSurface({}, "ribbon") + } } } @@ -55,7 +79,7 @@ fun Chip( Text( text = text, style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSecondary, + color = ZcashTheme.colors.textPrimary, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = modifier.then(Modifier.testTag(CommonTag.CHIP)) @@ -71,7 +95,7 @@ fun ChipIndexed( Text( text = "${index.value + 1}. $text", style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSecondary, + color = ZcashTheme.colors.textPrimary, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = modifier.then(Modifier.testTag(CommonTag.CHIP)) @@ -80,11 +104,12 @@ fun ChipIndexed( @Composable fun ChipOnSurface( + onClick: () -> Unit, text: String, - modifier: Modifier = Modifier + modifier: Modifier = Modifier, ) { Surface( - shape = RectangleShape, + shape = RoundedCornerShape(size = ZcashTheme.dimens.regularRippleEffectCorner), modifier = modifier .padding(horizontal = ZcashTheme.dimens.spacingTiny) @@ -92,20 +117,22 @@ fun ChipOnSurface( border = BorderStroke( width = ZcashTheme.dimens.chipStroke, - color = ZcashTheme.colors.layoutStroke - ) - ), - color = MaterialTheme.colorScheme.secondary, + color = ZcashTheme.colors.layoutStrokeSecondary + ), + shape = RoundedCornerShape(size = ZcashTheme.dimens.regularRippleEffectCorner), + ) + .clickable { onClick() }, + color = ZcashTheme.colors.primaryColor, shadowElevation = ZcashTheme.dimens.chipShadowElevation, ) { Text( text = text, style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSecondary, + color = ZcashTheme.colors.textPrimary, modifier = Modifier .padding( - vertical = ZcashTheme.dimens.spacingSmall, + vertical = ZcashTheme.dimens.spacingMid, horizontal = ZcashTheme.dimens.spacingDefault ) .testTag(CommonTag.CHIP) diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ChipGrid.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ChipGrid.kt index 4ddcae91..5bc2ca6b 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ChipGrid.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ChipGrid.kt @@ -26,12 +26,27 @@ const val CHIP_GRID_COLUMN_SIZE = 12 @Preview @Composable -private fun ComposablePreview() { +private fun ChipGridPreview() { ZcashTheme(forceDarkMode = false) { - ChipGrid( - SeedPhrase.new(WalletFixture.Alice.seedPhrase).split.toPersistentList(), - onGridClick = {} - ) + BlankSurface { + ChipGrid( + SeedPhrase.new(WalletFixture.Alice.seedPhrase).split.toPersistentList(), + onGridClick = {} + ) + } + } +} + +@Preview +@Composable +private fun ChipGridDarkPreview() { + ZcashTheme(forceDarkMode = true) { + BlankSurface { + ChipGrid( + SeedPhrase.new(WalletFixture.Alice.seedPhrase).split.toPersistentList(), + onGridClick = {} + ) + } } } diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/CommonComponents.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/CommonComponents.kt index cd421802..d9ba7711 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/CommonComponents.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/CommonComponents.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview @@ -27,6 +28,19 @@ private fun TopScreenLogoRegularComposablePreview() { } } +@Preview +@Composable +private fun TopScreenLogoRegularDarkComposablePreview() { + ZcashTheme(forceDarkMode = true) { + BlankSurface { + TopScreenLogoTitle( + title = "Test screen title", + logoContentDescription = "Test logo content description" + ) + } + } +} + @Preview @Composable private fun TopScreenLogoLongComposablePreview() { @@ -49,6 +63,7 @@ fun TopScreenLogoTitle( Column(modifier = modifier) { Image( painter = painterResource(id = R.drawable.zashi_logo_without_text), + colorFilter = ColorFilter.tint(color = ZcashTheme.colors.secondaryColor), contentDescription = logoContentDescription, modifier = Modifier.fillMaxWidth() ) @@ -57,6 +72,7 @@ fun TopScreenLogoTitle( Text( text = title, + color = ZcashTheme.colors.textPrimary, style = ZcashTheme.typography.secondary.headlineMedium, maxLines = 2, overflow = TextOverflow.Ellipsis, diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Dialog.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Dialog.kt index f85120c0..edba23cc 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Dialog.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Dialog.kt @@ -1,14 +1,19 @@ package co.electriccoin.zcash.ui.design.component import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.CornerSize import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults.buttonColors import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.window.DialogProperties @@ -30,6 +35,20 @@ private fun LightAlertDialogComposablePreview() { } } +@Preview +@Composable +private fun NoButtonAlertDialogComposablePreview() { + ZcashTheme(forceDarkMode = false) { + AppAlertDialog( + title = "Light popup", + text = + "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Temporibus autem quibusdam et aut " + + "officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et " + + "molestiae non recusandae. Duis condimentum augue id magna semper rutrum.", + ) + } +} + @Preview @Composable private fun DarkAlertDialogComposablePreview() { @@ -40,6 +59,8 @@ private fun DarkAlertDialogComposablePreview() { "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Temporibus autem quibusdam et aut " + "officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et " + "molestiae non recusandae. Duis condimentum augue id magna semper rutrum.", + confirmButtonText = "OK", + dismissButtonText = "Cancel" ) } } @@ -86,6 +107,8 @@ fun AppAlertDialog( text = text, icon = icon?.let { { Icon(imageVector = icon, null) } }, properties = properties, + titleContentColor = ZcashTheme.colors.textPrimary, + textContentColor = ZcashTheme.colors.textPrimary, modifier = modifier, ) } @@ -117,3 +140,50 @@ fun AppAlertDialog( onDismissButtonClick = onDismissButtonClick ) } + +@Preview +@Composable +private fun NavigationButtonPreview() { + ZcashTheme(forceDarkMode = false) { + NavigationButton( + onClick = {}, + text = "Test button", + ) + } +} + +@Preview +@Composable +private fun NavigationButtonDarkPreview() { + ZcashTheme(forceDarkMode = true) { + NavigationButton( + onClick = {}, + text = "Dark button", + ) + } +} + +@Composable +private fun NavigationButton( + onClick: () -> Unit, + text: String, + modifier: Modifier = Modifier, + outerPaddingValues: PaddingValues = + PaddingValues( + horizontal = ZcashTheme.dimens.spacingNone, + vertical = ZcashTheme.dimens.spacingSmall + ), +) { + Button( + onClick = onClick, + modifier = modifier.padding(outerPaddingValues), + colors = buttonColors(containerColor = ZcashTheme.colors.primaryColor) + ) { + Text( + style = MaterialTheme.typography.labelLarge, + textAlign = TextAlign.Center, + text = text, + color = ZcashTheme.colors.textPrimary + ) + } +} diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/PagerTabs.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/PagerTabs.kt index f211cefd..9472e127 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/PagerTabs.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/PagerTabs.kt @@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.pager.PagerState import androidx.compose.foundation.pager.rememberPagerState -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Tab import androidx.compose.material3.TabRow import androidx.compose.material3.Text @@ -64,10 +63,7 @@ fun PagerTabs( onTabSelected: (index: Int) -> Unit = {}, ) { TabRow( - modifier = - modifier - .padding(horizontal = ZcashTheme.dimens.screenHorizontalSpacingBig) - .border(ZcashTheme.dimens.spacingTiny, ZcashTheme.colors.layoutStroke), + modifier = modifier.border(ZcashTheme.dimens.spacingTiny, ZcashTheme.colors.layoutStroke), selectedTabIndex = pagerState.currentPage, divider = {}, indicator = {}, @@ -118,7 +114,7 @@ private fun PagerTab( .fillMaxWidth() .padding(horizontal = ZcashTheme.dimens.spacingXtiny), text = title, - color = if (selected) ZcashTheme.colors.textCommon else MaterialTheme.colorScheme.onPrimary, + color = if (selected) ZcashTheme.colors.textPrimary else ZcashTheme.colors.textSecondary, style = ZcashTheme.extendedTypography.restoringTopAppBarStyle, textAlign = TextAlign.Center, maxLines = 2, diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/RadioButton.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/RadioButton.kt index 1ad27d5d..7267402d 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/RadioButton.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/RadioButton.kt @@ -19,14 +19,43 @@ import co.electriccoin.zcash.ui.design.theme.ZcashTheme @Preview @Composable -private fun ComposablePreview() { +private fun RadioButtonPreview() { ZcashTheme(forceDarkMode = false) { - RadioButton( - text = "test", - selected = true, - onClick = {}, - modifier = Modifier - ) + BlankBgColumn { + RadioButton( + text = "test", + selected = false, + onClick = {}, + modifier = Modifier + ) + RadioButton( + text = "test", + selected = true, + onClick = {}, + modifier = Modifier + ) + } + } +} + +@Preview +@Composable +private fun RadioButtonDarkPreview() { + ZcashTheme(forceDarkMode = true) { + BlankBgColumn { + RadioButton( + text = "Dark test", + selected = false, + onClick = {}, + modifier = Modifier + ) + RadioButton( + text = "Dark test", + selected = true, + onClick = {}, + modifier = Modifier + ) + } } } @@ -59,14 +88,14 @@ fun RadioButton( onClick = onClick, colors = RadioButtonDefaults.colors( - selectedColor = ZcashTheme.colors.radioButtonColor, - unselectedColor = ZcashTheme.colors.radioButtonColor, + selectedColor = ZcashTheme.colors.secondaryColor, + unselectedColor = ZcashTheme.colors.secondaryColor, ) ) Text( text = text, style = ZcashTheme.extendedTypography.radioButton, - color = ZcashTheme.colors.radioButtonTextColor, + color = ZcashTheme.colors.textPrimary, modifier = Modifier.padding( top = 16.dp, diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Text.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Text.kt index e945f170..f7a91a1a 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Text.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Text.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.buildAnnotatedString @@ -93,14 +94,14 @@ fun Header( text: String, modifier: Modifier = Modifier, textAlign: TextAlign = TextAlign.Start, - color: Color = ZcashTheme.colors.onBackgroundHeader, + color: Color = ZcashTheme.colors.textPrimary, ) { Text( text = text, color = color, textAlign = textAlign, modifier = modifier, - style = ZcashTheme.typography.secondary.headlineLarge, + style = ZcashTheme.typography.primary.headlineLarge, ) } @@ -109,7 +110,7 @@ fun SubHeader( text: String, modifier: Modifier = Modifier, textAlign: TextAlign = TextAlign.Start, - color: Color = ZcashTheme.colors.onBackgroundHeader, + color: Color = ZcashTheme.colors.textPrimary, ) { Text( text = text, @@ -129,7 +130,7 @@ fun BodySmall( overflow: TextOverflow = TextOverflow.Clip, textAlign: TextAlign = TextAlign.Start, textFontWeight: FontWeight = FontWeight.Normal, - color: Color = MaterialTheme.colorScheme.onBackground, + color: Color = ZcashTheme.colors.textPrimary, ) { Text( text = text, @@ -152,7 +153,7 @@ fun Body( overflow: TextOverflow = TextOverflow.Clip, textAlign: TextAlign = TextAlign.Start, textFontWeight: FontWeight = FontWeight.Normal, - color: Color = MaterialTheme.colorScheme.onBackground, + color: Color = ZcashTheme.colors.textPrimary, ) { Text( text = text, @@ -174,7 +175,7 @@ fun TitleLarge( maxLines: Int = Int.MAX_VALUE, overflow: TextOverflow = TextOverflow.Clip, textAlign: TextAlign = TextAlign.Start, - color: Color = MaterialTheme.colorScheme.onBackground, + color: Color = ZcashTheme.colors.textPrimary, ) { Text( text = text, @@ -196,7 +197,7 @@ fun Small( maxLines: Int = Int.MAX_VALUE, overflow: TextOverflow = TextOverflow.Clip, textAlign: TextAlign = TextAlign.Start, - color: Color = MaterialTheme.colorScheme.onBackground, + color: Color = ZcashTheme.colors.textPrimary, ) { Text( text = text, @@ -218,7 +219,7 @@ fun Tiny( maxLines: Int = Int.MAX_VALUE, overflow: TextOverflow = TextOverflow.Clip, textAlign: TextAlign = TextAlign.Start, - color: Color = MaterialTheme.colorScheme.onBackground, + color: Color = ZcashTheme.colors.textPrimary, ) { Text( text = text, @@ -234,15 +235,16 @@ fun Tiny( @Composable @Suppress("LongParameterList") fun TextWithIcon( - text: String, iconVector: ImageVector, + text: String, modifier: Modifier = Modifier, iconContentDescription: String? = null, + iconTintColor: Color? = null, maxLines: Int = Int.MAX_VALUE, overflow: TextOverflow = TextOverflow.Clip, textAlign: TextAlign = TextAlign.Start, style: TextStyle = LocalTextStyle.current, - color: Color = MaterialTheme.colorScheme.onBackground, + color: Color = ZcashTheme.colors.textPrimary, ) { Row( modifier = @@ -251,10 +253,18 @@ fun TextWithIcon( .then(modifier), verticalAlignment = Alignment.CenterVertically ) { - Image( - imageVector = iconVector, - contentDescription = iconContentDescription - ) + if (iconTintColor != null) { + Image( + imageVector = iconVector, + colorFilter = ColorFilter.tint(color = iconTintColor), + contentDescription = iconContentDescription, + ) + } else { + Image( + imageVector = iconVector, + contentDescription = iconContentDescription + ) + } Spacer(modifier = Modifier.padding(3.dp)) @@ -402,7 +412,7 @@ fun BodyWithFiatCurrencySymbol( Text( text = amount, style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onBackground, + color = ZcashTheme.colors.textPrimary, modifier = modifier ) } @@ -443,7 +453,7 @@ fun NavigationTabText( }, maxLines = 1, overflow = TextOverflow.Visible, - color = ZcashTheme.colors.textCommon, + color = ZcashTheme.colors.textPrimary, modifier = Modifier .clip(RoundedCornerShape(ZcashTheme.dimens.regularRippleEffectCorner)) diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/TextField.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/TextField.kt index d19eb4e8..cb0f985f 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/TextField.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/TextField.kt @@ -50,9 +50,10 @@ fun FormTextField( keyboardOptions: KeyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), colors: TextFieldColors = TextFieldDefaults.colors( - focusedContainerColor = ZcashTheme.colors.backgroundColor, - unfocusedContainerColor = ZcashTheme.colors.backgroundColor, - disabledContainerColor = ZcashTheme.colors.textDisabled, + cursorColor = ZcashTheme.colors.textPrimary, + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + disabledContainerColor = Color.Transparent, errorContainerColor = Color.Transparent, focusedIndicatorColor = Color.Transparent, unfocusedIndicatorColor = Color.Transparent, diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/TopAppBar.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/TopAppBar.kt index f381a6b1..7c384a44 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/TopAppBar.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/TopAppBar.kt @@ -56,6 +56,16 @@ private fun TopAppBarTextComposablePreview() { } } +@Preview +@Composable +private fun TopAppBarTextDarkComposablePreview() { + ZcashTheme(forceDarkMode = true) { + BlankSurface { + SmallTopAppBar(titleText = "Screen A", backText = "Back") + } + } +} + @Preview @Composable private fun TopAppBarTextRestoringComposablePreview() { @@ -108,6 +118,20 @@ private fun TopAppBarLogoRestoringComposablePreview() { } } +@Preview +@Composable +private fun TopAppBarLogoRestoringDarkComposablePreview() { + ZcashTheme(forceDarkMode = true) { + BlankSurface { + SmallTopAppBar( + showTitleLogo = true, + backText = "Back", + subTitle = "[RESTORING YOUR WALLET…]" + ) + } + } +} + @Preview @Composable private fun TopAppBarRegularMenuComposablePreview() { diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/WelcomeAnimation.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/WelcomeAnimation.kt index 97445989..3278dad3 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/WelcomeAnimation.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/WelcomeAnimation.kt @@ -24,6 +24,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.painter.ColorPainter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource @@ -68,6 +69,7 @@ fun WelcomeAnimationAutostart( private const val LOGO_RELATIVE_LOCATION = 0.2f @Composable +@Suppress("LongMethod") fun WelcomeAnimation( animationState: Boolean, modifier: Modifier = Modifier, @@ -111,6 +113,7 @@ fun WelcomeAnimation( Image( painter = painterResource(id = R.drawable.chart_line), contentScale = ContentScale.FillBounds, + colorFilter = ColorFilter.tint(color = ZcashTheme.colors.welcomeAnimationColor), contentDescription = null, ) } diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/Dimens.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/Dimens.kt index 673815db..3ce180b4 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/Dimens.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/Dimens.kt @@ -84,7 +84,7 @@ private val defaultDimens = buttonHeightSmall = 38.dp, gridCellSize = 14.dp, gridLineWidth = 1.dp, - chipShadowElevation = 4.dp, + chipShadowElevation = 2.dp, chipStroke = 0.5.dp, circularScreenProgressWidth = 48.dp, circularMidProgressWidth = 22.dp, diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/ExtendedColors.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/ExtendedColors.kt index 0a9aa04d..7e2c3907 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/ExtendedColors.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/ExtendedColors.kt @@ -2,19 +2,22 @@ package co.electriccoin.zcash.ui.design.theme import androidx.compose.runtime.Immutable import androidx.compose.ui.graphics.Color +import co.electriccoin.zcash.ui.design.theme.internal.ButtonColors import co.electriccoin.zcash.ui.design.theme.internal.TopAppBarColors @Immutable data class ExtendedColors( + val primaryColor: Color, + val secondaryColor: Color, val backgroundColor: Color, val gridColor: Color, - val onBackgroundHeader: Color, val circularProgressBarSmall: Color, val circularProgressBarSmallDark: Color, val circularProgressBarScreen: Color, val linearProgressBarTrack: Color, val linearProgressBarBackground: Color, - val textCommon: Color, + val textPrimary: Color, + val textSecondary: Color, val textDescription: Color, val textDisabled: Color, val textFieldHint: Color, @@ -22,22 +25,27 @@ data class ExtendedColors( val textFieldFrame: Color, val textDescriptionDark: Color, val layoutStroke: Color, + val layoutStrokeSecondary: Color, val overlay: Color, + val overlayProgressBar: Color, val reference: Color, - val disabledButtonColor: Color, - val disabledButtonTextColor: Color, + val primaryButtonColors: ButtonColors, + val secondaryButtonColors: ButtonColors, + val tertiaryButtonColors: ButtonColors, val welcomeAnimationColor: Color, val complementaryColor: Color, - val dividerColor: Color, - val darkDividerColor: Color, + val primaryDividerColor: Color, + val secondaryDividerColor: Color, + val tertiaryDividerColor: Color, val panelBackgroundColor: Color, + val panelBackgroundColorActive: Color, val cameraDisabledBackgroundColor: Color, val cameraDisabledFrameColor: Color, - val radioButtonColor: Color, - val radioButtonTextColor: Color, val historyBackgroundColor: Color, + val historyMessageBubbleColor: Color, + val historyMessageBubbleStrokeColor: Color, val historyRedColor: Color, val historySyncingColor: Color, val topAppBarColors: TopAppBarColors, - val transparentTopAppBarColors: TopAppBarColors + val transparentTopAppBarColors: TopAppBarColors, ) diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/ButtonColors.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/ButtonColors.kt new file mode 100644 index 00000000..9b6ea4e4 --- /dev/null +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/ButtonColors.kt @@ -0,0 +1,123 @@ +@file:Suppress("MagicNumber") + +package co.electriccoin.zcash.ui.design.theme.internal + +import androidx.compose.runtime.Immutable +import androidx.compose.ui.graphics.Color + +@Immutable +interface ButtonColors { + val containerColor: Color + val disabledContainerColor: Color + val shadowColor: Color + val disabledShadowColor: Color + val textColor: Color + val disabledTextColor: Color + val strokeColor: Color + val disabledStrokeColor: Color + val shadowStrokeColor: Color + val shadowDisabledStrokeColor: Color +} + +@Immutable +internal data class DefaultButtonColors( + override val containerColor: Color = Color.Unspecified, + override val disabledContainerColor: Color = Color.Unspecified, + override val shadowColor: Color = Color.Unspecified, + override val disabledShadowColor: Color = Color.Unspecified, + override val textColor: Color = Color.Unspecified, + override val disabledTextColor: Color = Color.Unspecified, + override val strokeColor: Color = Color.Unspecified, + override val disabledStrokeColor: Color = Color.Unspecified, + override val shadowStrokeColor: Color = Color.Unspecified, + override val shadowDisabledStrokeColor: Color = Color.Unspecified, +) : ButtonColors + +// LIGHT THEME BUTTONS: + +@Immutable +internal data class LightPrimaryButtonColors( + override val containerColor: Color = Color(0xFF000000), + override val disabledContainerColor: Color = Color(0xFFB7B7B7), + override val shadowColor: Color = Color(0xFFFFFFFF), + override val disabledShadowColor: Color = Color(0xFFFFFFFF), + override val textColor: Color = Color(0xFFFFFFFF), + override val disabledTextColor: Color = Color(0xFFDDDDDD), + override val strokeColor: Color = Color(0xFF000000), + override val disabledStrokeColor: Color = Color(0xFF000000), + override val shadowStrokeColor: Color = Color(0xFF000000), + override val shadowDisabledStrokeColor: Color = Color(0xFF000000), +) : ButtonColors + +@Immutable +internal data class LightSecondaryButtonColors( + override val containerColor: Color = Color(0xFFFFFFFF), + override val disabledContainerColor: Color = Color(0xFFFFFFFF), + override val shadowColor: Color = Color(0xFF000000), + override val disabledShadowColor: Color = Color(0xFFFFFFFF), + override val textColor: Color = Color(0xFF000000), + override val disabledTextColor: Color = Color(0xFFDDDDDD), + override val strokeColor: Color = Color(0xFF000000), + override val disabledStrokeColor: Color = Color(0xFF000000), + override val shadowStrokeColor: Color = Color(0xFFE6E7E8), + override val shadowDisabledStrokeColor: Color = Color(0xFF000000), +) : ButtonColors + +// Currently the same as Light-Primary version +@Immutable +internal data class LightTertiaryButtonColors( + override val containerColor: Color = Color(0xFF000000), + override val disabledContainerColor: Color = Color(0xFFB7B7B7), + override val shadowColor: Color = Color(0xFFFFFFFF), + override val disabledShadowColor: Color = Color(0xFFFFFFFF), + override val textColor: Color = Color(0xFFFFFFFF), + override val disabledTextColor: Color = Color(0xFFDDDDDD), + override val strokeColor: Color = Color(0xFF000000), + override val disabledStrokeColor: Color = Color(0xFF000000), + override val shadowStrokeColor: Color = Color(0xFF000000), + override val shadowDisabledStrokeColor: Color = Color(0xFF000000), +) : ButtonColors + +// DARK THEME BUTTONS: + +@Immutable +internal data class DarkPrimaryButtonColors( + override val containerColor: Color = Color(0xFF181716), + override val disabledContainerColor: Color = Color(0xFF4D4D4D), + override val shadowColor: Color = Color(0xFF181716), + override val disabledShadowColor: Color = Color(0xFF181716), + override val textColor: Color = Color(0xFFFFFFFF), + override val disabledTextColor: Color = Color(0xFFFFFFFF), + override val strokeColor: Color = Color(0xFFFFFFFF), + override val disabledStrokeColor: Color = Color(0xFFFFFFFF), + override val shadowStrokeColor: Color = Color(0xFFFFFFFF), + override val shadowDisabledStrokeColor: Color = Color(0xFFFFFFFF), +) : ButtonColors + +@Immutable +internal data class DarkSecondaryButtonColors( + override val containerColor: Color = Color(0xFF181716), + override val disabledContainerColor: Color = Color(0xFFFFFFFF), + override val shadowColor: Color = Color(0xFF4D4D4D), + override val disabledShadowColor: Color = Color(0xFFFFFFFF), + override val textColor: Color = Color(0xFFFFFFFF), + override val disabledTextColor: Color = Color(0xFFB7B7B7), + override val strokeColor: Color = Color(0xFFFFFFFF), + override val disabledStrokeColor: Color = Color(0xFF000000), + override val shadowStrokeColor: Color = Color(0xFFFFFFFF), + override val shadowDisabledStrokeColor: Color = Color(0xFF000000), +) : ButtonColors + +@Immutable +internal data class DarkTertiaryButtonColors( + override val containerColor: Color = Color(0xFFFFFFFF), + override val disabledContainerColor: Color = Color(0xFFFFFFFF), + override val shadowColor: Color = Color(0xFF000000), + override val disabledShadowColor: Color = Color(0xFFFFFFFF), + override val textColor: Color = Color(0xFF000000), + override val disabledTextColor: Color = Color(0xFFDDDDDD), + override val strokeColor: Color = Color(0xFF000000), + override val disabledStrokeColor: Color = Color(0xFF000000), + override val shadowStrokeColor: Color = Color(0xFFE6E7E8), + override val shadowDisabledStrokeColor: Color = Color(0xFF000000), +) : ButtonColors diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Color.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Color.kt index 5e38fb47..01e09187 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Color.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Color.kt @@ -8,108 +8,111 @@ import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.graphics.Color import co.electriccoin.zcash.ui.design.theme.ExtendedColors -// TODO [#998]: Check and enhance screen dark mode -// TODO [#998]: https://github.com/Electric-Coin-Company/zashi-android/issues/998 - internal object Dark { - val backgroundColor = Color(0xFF231F20) + val primaryColor = Color(0xFF231F20) + val secondaryColor = Color(0xFFFFFFFF) + + val backgroundColor = primaryColor val gridColor = Color(0xFF272727) - val textHeaderOnBackground = Color(0xFFFFFFFF) - val textBodyOnBackground = Color(0xFFFFFFFF) - val textPrimaryButton = Color(0xFF000000) - val textSecondaryButton = Color(0xFF000000) - val textCommon = Color(0xFFFFFFFF) - val textDisabled = Color(0xFFB7B7B7) - val textFieldFrame = Color(0xFF231F20) - val textFieldWarning = Color(0xFFF40202) + val textPrimary = secondaryColor + val textSecondary = primaryColor + val textDisabled = Color(0xFF4D4D4D) + val textFieldFrame = Color(0xFFFFFFFF) + val textFieldWarning = Color(0xFFFE5858) val textFieldHint = Color(0xFFB7B7B7) - val textDescription = Color(0xFF777777) - val textDescriptionDark = Color(0xFF4D4D4D) + val textDescription = Color(0xFFC1C1C1) + val textDescriptionDark = Color(0xFFFFFFFF) + val reference = Color(0xFFFFFFFF) - val welcomeAnimationColor = Color(0xFF231F20) + val welcomeAnimationColor = Color(0xFF181716) val complementaryColor = Color(0xFFF4B728) - val dividerColor = Color(0xFFDDDDDD) - val darkDividerColor = Color(0xFF000000) + + val primaryDividerColor = Color(0xFF4D4D4D) + val secondaryDividerColor = Color(0xFFFFFFFF) + val tertiaryDividerColor = Color(0xFF4D4D4D) + + val panelBackgroundColor = Color(0xFF262324) + val panelBackgroundColorActive = Color(0xFF000000) + val layoutStroke = Color(0xFFFFFFFF) - val panelBackgroundColor = Color(0xFFF6F6F6) - val cameraDisabledBackgroundColor = Color(0xFF5E5C5C) - val cameraDisabledFrameColor = Color(0xFFFFFFFF) + val layoutStrokeSecondary = Color(0xFFDDDDDD) + val cameraDisabledBackgroundColor = Color(0xFF000000) + val cameraDisabledFrameColor = Color(0xFF5E5C5C) - val primaryButton = Color(0xFFFFFFFF) - val secondaryButton = Color(0xFFFFFFFF) + val primaryButtonColors = DarkPrimaryButtonColors() + val secondaryButtonColors = DarkSecondaryButtonColors() + val tertiaryButtonColors = DarkTertiaryButtonColors() - val radioButtonColor = Color(0xFF070707) - val radioButtonTextColor = Color(0xFF4E4E4E) - - val circularProgressBarSmall = Color(0xFF8B8A8A) - val circularProgressBarSmallDark = textBodyOnBackground + val circularProgressBarSmall = Color(0xFFFFFFFF) + val circularProgressBarSmallDark = Color(0xFFFFFFFF) val circularProgressBarScreen = Color(0xFFFFFFFF) - val linearProgressBarTrack = Color(0xFFD9D9D9) + val linearProgressBarTrack = Color(0xFFDDDDDD) val linearProgressBarBackground = complementaryColor val overlay = Color(0x22000000) + val overlayProgressBar = Color(0xFFFFFFFF) - val reference = Color(0xFFFFFFFF) - - val disabledButtonColor = Color(0xFFB7B7B7) - val disabledButtonTextColor = Color(0xFFDDDDDD) - - val historyBackgroundColor = Color(0xFFF6F6F6) + val historyBackgroundColor = Color(0xFF262324) val historyRedColor = textFieldWarning - val historySyncingColor = panelBackgroundColor + val historySyncingColor = Color(0xFF181716) + val historyMessageBubbleColor = Color(0xFF000000) + val historyMessageBubbleStrokeColor = Color(0xFF000000) val topAppBarColors = DarkTopAppBarColors() val transparentTopAppBarColors = TransparentTopAppBarColors() } internal object Light { - val backgroundColor = Color(0xFFFFFFFF) + val primaryColor = Color(0xFFFFFFFF) + val secondaryColor = Color(0xFF000000) + + val backgroundColor = primaryColor val gridColor = Color(0xFFFBFBFB) - val textHeaderOnBackground = Color(0xFF000000) - val textBodyOnBackground = Color(0xFF000000) - val textPrimaryButton = Color(0xFFFFFFFF) - val textSecondaryButton = Color(0xFF000000) - val textCommon = Color(0xFF000000) + val textPrimary = secondaryColor + val textSecondary = primaryColor val textDisabled = Color(0xFFB7B7B7) - val textFieldFrame = Color(0xFF231F20) + val textFieldFrame = Color(0xFF000000) val textFieldWarning = Color(0xFFF40202) val textFieldHint = Color(0xFFB7B7B7) val textDescription = Color(0xFF777777) val textDescriptionDark = Color(0xFF4D4D4D) + val reference = Color(0xFF000000) val welcomeAnimationColor = Color(0xFF231F20) val complementaryColor = Color(0xFFF4B728) - val dividerColor = Color(0xFFDDDDDD) - val darkDividerColor = Color(0xFF000000) - val layoutStroke = Color(0xFF000000) + + val primaryDividerColor = Color(0xFFDDDDDD) + val secondaryDividerColor = Color(0xFF000000) + val tertiaryDividerColor = Color(0xFF000000) + val panelBackgroundColor = Color(0xFFEBEBEB) + val panelBackgroundColorActive = Color(0xFFFFFFFF) + + val layoutStroke = Color(0xFF000000) + val layoutStrokeSecondary = Color(0xFFDDDDDD) val cameraDisabledBackgroundColor = Color(0xFF5E5C5C) val cameraDisabledFrameColor = Color(0xFFFFFFFF) - val primaryButton = Color(0xFF000000) - val secondaryButton = Color(0xFFFFFFFF) - - val radioButtonColor = Color(0xFF070707) - val radioButtonTextColor = Color(0xFF4E4E4E) + val primaryButtonColors = LightPrimaryButtonColors() + val secondaryButtonColors = LightSecondaryButtonColors() + val tertiaryButtonColors = LightTertiaryButtonColors() val circularProgressBarSmall = Color(0xFF8B8A8A) + val circularProgressBarSmallDark = textPrimary val circularProgressBarScreen = Color(0xFF000000) - val circularProgressBarSmallDark = textBodyOnBackground - val linearProgressBarTrack = Color(0xFFD9D9D9) + val linearProgressBarTrack = Color(0xFFDDDDDD) val linearProgressBarBackground = complementaryColor val overlay = Color(0x22000000) - - val reference = Color(0xFF000000) - - val disabledButtonColor = Color(0xFFB7B7B7) - val disabledButtonTextColor = Color(0xFFDDDDDD) + val overlayProgressBar = Color(0xFFFFFFFF) val historyBackgroundColor = Color(0xFFF6F6F6) val historyRedColor = textFieldWarning - val historySyncingColor = panelBackgroundColor + val historySyncingColor = Color(0xFFEBEBEB) + val historyMessageBubbleColor = Color(0xFFDDDDDD) + val historyMessageBubbleStrokeColor = Color(0xFF000000) val topAppBarColors = LightTopAppBarColors() val transparentTopAppBarColors = TransparentTopAppBarColors() @@ -117,39 +120,43 @@ internal object Light { internal val DarkColorPalette = darkColorScheme( - primary = Dark.primaryButton, - secondary = Dark.secondaryButton, - onPrimary = Dark.textPrimaryButton, - onSecondary = Dark.textSecondaryButton, + // Our colors intentionally use a different naming than the ones from MaterialTheme + primary = Dark.textPrimary, + secondary = Dark.secondaryColor, + onPrimary = Dark.textPrimary, + onSecondary = Dark.textSecondary, surface = Dark.backgroundColor, - onSurface = Dark.textBodyOnBackground, + onSurface = Dark.textPrimary, background = Dark.backgroundColor, - onBackground = Dark.textBodyOnBackground, + onBackground = Dark.textPrimary, ) internal val LightColorPalette = lightColorScheme( - primary = Light.primaryButton, - secondary = Light.secondaryButton, - onPrimary = Light.textPrimaryButton, - onSecondary = Light.textSecondaryButton, + // Our colors intentionally use a different naming than the ones from MaterialTheme + primary = Light.textPrimary, + secondary = Light.secondaryColor, + onPrimary = Light.textPrimary, + onSecondary = Light.textSecondary, surface = Light.backgroundColor, - onSurface = Light.textBodyOnBackground, + onSurface = Light.textPrimary, background = Light.backgroundColor, - onBackground = Light.textBodyOnBackground, + onBackground = Light.textPrimary, ) internal val DarkExtendedColorPalette = ExtendedColors( + primaryColor = Dark.primaryColor, + secondaryColor = Dark.secondaryColor, backgroundColor = Dark.backgroundColor, gridColor = Dark.gridColor, - onBackgroundHeader = Dark.textHeaderOnBackground, circularProgressBarSmall = Dark.circularProgressBarSmall, circularProgressBarSmallDark = Dark.circularProgressBarSmallDark, circularProgressBarScreen = Dark.circularProgressBarScreen, linearProgressBarTrack = Dark.linearProgressBarTrack, linearProgressBarBackground = Dark.linearProgressBarBackground, - textCommon = Dark.textCommon, + textPrimary = Dark.textPrimary, + textSecondary = Dark.textSecondary, textDisabled = Dark.textDisabled, textFieldFrame = Dark.textFieldFrame, textFieldWarning = Dark.textFieldWarning, @@ -157,37 +164,44 @@ internal val DarkExtendedColorPalette = textDescription = Dark.textDescription, textDescriptionDark = Dark.textDescriptionDark, layoutStroke = Dark.layoutStroke, + layoutStrokeSecondary = Dark.layoutStrokeSecondary, overlay = Dark.overlay, - disabledButtonTextColor = Dark.disabledButtonTextColor, - disabledButtonColor = Dark.disabledButtonColor, + overlayProgressBar = Dark.overlayProgressBar, reference = Dark.reference, welcomeAnimationColor = Dark.welcomeAnimationColor, complementaryColor = Dark.complementaryColor, - dividerColor = Dark.dividerColor, - darkDividerColor = Dark.darkDividerColor, + primaryDividerColor = Dark.primaryDividerColor, + secondaryDividerColor = Dark.secondaryDividerColor, + tertiaryDividerColor = Dark.tertiaryDividerColor, panelBackgroundColor = Dark.panelBackgroundColor, + panelBackgroundColorActive = Dark.panelBackgroundColorActive, cameraDisabledBackgroundColor = Dark.cameraDisabledBackgroundColor, cameraDisabledFrameColor = Dark.cameraDisabledFrameColor, - radioButtonColor = Dark.radioButtonColor, - radioButtonTextColor = Dark.radioButtonTextColor, historyBackgroundColor = Dark.historyBackgroundColor, historyRedColor = Dark.historyRedColor, historySyncingColor = Dark.historySyncingColor, + historyMessageBubbleColor = Dark.historyMessageBubbleColor, + historyMessageBubbleStrokeColor = Dark.historyMessageBubbleStrokeColor, topAppBarColors = Dark.topAppBarColors, - transparentTopAppBarColors = Dark.transparentTopAppBarColors + transparentTopAppBarColors = Dark.transparentTopAppBarColors, + primaryButtonColors = Dark.primaryButtonColors, + secondaryButtonColors = Dark.secondaryButtonColors, + tertiaryButtonColors = Dark.tertiaryButtonColors, ) internal val LightExtendedColorPalette = ExtendedColors( + primaryColor = Light.primaryColor, + secondaryColor = Light.secondaryColor, backgroundColor = Light.backgroundColor, gridColor = Light.gridColor, - onBackgroundHeader = Light.textHeaderOnBackground, circularProgressBarScreen = Light.circularProgressBarScreen, circularProgressBarSmall = Light.circularProgressBarSmall, circularProgressBarSmallDark = Light.circularProgressBarSmallDark, linearProgressBarTrack = Light.linearProgressBarTrack, linearProgressBarBackground = Light.linearProgressBarBackground, - textCommon = Light.textCommon, + textPrimary = Light.textPrimary, + textSecondary = Light.textSecondary, textDisabled = Light.textDisabled, textFieldFrame = Light.textFieldFrame, textFieldWarning = Light.textFieldWarning, @@ -195,39 +209,46 @@ internal val LightExtendedColorPalette = textDescription = Light.textDescription, textDescriptionDark = Light.textDescriptionDark, layoutStroke = Light.layoutStroke, + layoutStrokeSecondary = Light.layoutStrokeSecondary, overlay = Light.overlay, - disabledButtonTextColor = Light.disabledButtonTextColor, - disabledButtonColor = Light.disabledButtonColor, + overlayProgressBar = Light.overlayProgressBar, reference = Light.reference, welcomeAnimationColor = Light.welcomeAnimationColor, complementaryColor = Light.complementaryColor, - dividerColor = Light.dividerColor, - darkDividerColor = Light.darkDividerColor, + primaryDividerColor = Light.primaryDividerColor, + secondaryDividerColor = Light.secondaryDividerColor, + tertiaryDividerColor = Light.tertiaryDividerColor, panelBackgroundColor = Light.panelBackgroundColor, + panelBackgroundColorActive = Light.panelBackgroundColorActive, cameraDisabledBackgroundColor = Light.cameraDisabledBackgroundColor, cameraDisabledFrameColor = Light.cameraDisabledFrameColor, - radioButtonColor = Light.radioButtonColor, - radioButtonTextColor = Light.radioButtonTextColor, historyBackgroundColor = Light.historyBackgroundColor, historyRedColor = Light.historyRedColor, historySyncingColor = Light.historySyncingColor, + historyMessageBubbleColor = Light.historyMessageBubbleColor, + historyMessageBubbleStrokeColor = Light.historyMessageBubbleStrokeColor, topAppBarColors = Light.topAppBarColors, - transparentTopAppBarColors = Light.transparentTopAppBarColors + transparentTopAppBarColors = Light.transparentTopAppBarColors, + primaryButtonColors = Light.primaryButtonColors, + secondaryButtonColors = Light.secondaryButtonColors, + tertiaryButtonColors = Light.tertiaryButtonColors, ) @Suppress("CompositionLocalAllowlist") internal val LocalExtendedColors = staticCompositionLocalOf { ExtendedColors( + primaryColor = Color.Unspecified, + secondaryColor = Color.Unspecified, backgroundColor = Color.Unspecified, gridColor = Color.Unspecified, - onBackgroundHeader = Color.Unspecified, circularProgressBarScreen = Color.Unspecified, circularProgressBarSmall = Color.Unspecified, circularProgressBarSmallDark = Color.Unspecified, linearProgressBarTrack = Color.Unspecified, linearProgressBarBackground = Color.Unspecified, - textCommon = Color.Unspecified, + textPrimary = Color.Unspecified, + textSecondary = Color.Unspecified, textDisabled = Color.Unspecified, textFieldHint = Color.Unspecified, textFieldWarning = Color.Unspecified, @@ -235,23 +256,28 @@ internal val LocalExtendedColors = textDescription = Color.Unspecified, textDescriptionDark = Color.Unspecified, layoutStroke = Color.Unspecified, + layoutStrokeSecondary = Color.Unspecified, overlay = Color.Unspecified, - disabledButtonTextColor = Color.Unspecified, - disabledButtonColor = Color.Unspecified, + overlayProgressBar = Color.Unspecified, reference = Color.Unspecified, welcomeAnimationColor = Color.Unspecified, complementaryColor = Color.Unspecified, - dividerColor = Color.Unspecified, - darkDividerColor = Color.Unspecified, + primaryDividerColor = Color.Unspecified, + secondaryDividerColor = Color.Unspecified, + tertiaryDividerColor = Color.Unspecified, panelBackgroundColor = Color.Unspecified, + panelBackgroundColorActive = Color.Unspecified, cameraDisabledBackgroundColor = Color.Unspecified, cameraDisabledFrameColor = Color.Unspecified, - radioButtonColor = Color.Unspecified, - radioButtonTextColor = Color.Unspecified, historyBackgroundColor = Color.Unspecified, historyRedColor = Color.Unspecified, historySyncingColor = Color.Unspecified, + historyMessageBubbleColor = Color.Unspecified, + historyMessageBubbleStrokeColor = Color.Unspecified, topAppBarColors = DefaultTopAppBarColors(), transparentTopAppBarColors = DefaultTopAppBarColors(), + primaryButtonColors = DefaultButtonColors(), + secondaryButtonColors = DefaultButtonColors(), + tertiaryButtonColors = DefaultButtonColors(), ) } diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/TopAppBarColors.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/TopAppBarColors.kt index 853a58a4..36b68e28 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/TopAppBarColors.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/TopAppBarColors.kt @@ -81,10 +81,10 @@ internal data class LightTopAppBarColors( @Immutable internal data class DarkTopAppBarColors( - override val containerColor: Color = Color(0xFF000000), + override val containerColor: Color = Color(0xFF231F20), override val navigationColor: Color = Color(0xFFFFFFFF), override val titleColor: Color = Color(0xFFFFFFFF), - override val subTitleColor: Color = Color(0xFF8A8888), + override val subTitleColor: Color = Color(0xFFFFFFFF), override val actionColor: Color = Color(0xFFFFFFFF), ) : TopAppBarColors { override fun copyColors( diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Typography.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Typography.kt index ee80a01a..7b9308db 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Typography.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Typography.kt @@ -57,8 +57,8 @@ internal val PrimaryTypography = headlineLarge = TextStyle( fontFamily = InterFontFamily, - fontWeight = FontWeight.SemiBold, - fontSize = 30.sp + fontWeight = FontWeight.Bold, + fontSize = 22.sp ), titleSmall = TextStyle( @@ -194,7 +194,6 @@ data class ExtendedTypography( val transactionItemStyles: TransactionItemTextStyles, val restoringTopAppBarStyle: TextStyle, val deleteWalletWarnStyle: TextStyle, - val updateTitleStyle: TextStyle, ) @Suppress("CompositionLocalAllowlist") @@ -379,9 +378,5 @@ val LocalExtendedTypography = PrimaryTypography.bodyLarge.copy( fontWeight = FontWeight.Bold ), - updateTitleStyle = - PrimaryTypography.titleLarge.copy( - fontWeight = FontWeight.Bold - ) ) } diff --git a/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/scan/util/SettingsUtilTest.kt b/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/scan/util/SettingsUtilTest.kt index 027d19ba..3eb57523 100644 --- a/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/scan/util/SettingsUtilTest.kt +++ b/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/scan/util/SettingsUtilTest.kt @@ -4,6 +4,7 @@ import android.content.Intent import android.provider.Settings import androidx.test.filters.SmallTest import co.electriccoin.zcash.ui.test.getAppContext +import co.electriccoin.zcash.ui.util.SettingsUtil import org.junit.Test import kotlin.test.assertContains import kotlin.test.assertEquals diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/MainActivity.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/MainActivity.kt index 2081fcbd..4304e242 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/MainActivity.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/MainActivity.kt @@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.lifecycle.Lifecycle @@ -50,7 +49,6 @@ import co.electriccoin.zcash.ui.screen.onboarding.WrapOnboarding import co.electriccoin.zcash.ui.screen.onboarding.persistExistingWalletWithSeedPhrase import co.electriccoin.zcash.ui.screen.securitywarning.WrapSecurityWarning import co.electriccoin.zcash.ui.screen.support.WrapSupport -import co.electriccoin.zcash.ui.screen.warning.WrapNotEnoughSpace import co.electriccoin.zcash.ui.screen.warning.viewmodel.StorageCheckViewModel import co.electriccoin.zcash.work.WorkIds import kotlinx.coroutines.delay @@ -68,7 +66,6 @@ class MainActivity : AppCompatActivity() { val walletViewModel by viewModels() - @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) val storageCheckViewModel by viewModels() internal val authenticationViewModel by viewModels { @@ -138,13 +135,7 @@ class MainActivity : AppCompatActivity() { .fillMaxHeight() ) { BindCompLocalProvider { - val isEnoughSpace by storageCheckViewModel.isEnoughSpace.collectAsStateWithLifecycle() - if (isEnoughSpace == false) { - WrapNotEnoughSpace() - } else { - MainContent() - } - + MainContent() AuthenticationForAppAccess() } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigation.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigation.kt index d9f26822..ed0d22e2 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigation.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigation.kt @@ -1,6 +1,7 @@ package co.electriccoin.zcash.ui import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.lifecycle.LifecycleCoroutineScope @@ -29,6 +30,7 @@ import co.electriccoin.zcash.ui.NavigationTargets.CHOOSE_SERVER import co.electriccoin.zcash.ui.NavigationTargets.DELETE_WALLET import co.electriccoin.zcash.ui.NavigationTargets.EXPORT_PRIVATE_DATA import co.electriccoin.zcash.ui.NavigationTargets.HOME +import co.electriccoin.zcash.ui.NavigationTargets.NOT_ENOUGH_SPACE import co.electriccoin.zcash.ui.NavigationTargets.SCAN import co.electriccoin.zcash.ui.NavigationTargets.SEED_RECOVERY import co.electriccoin.zcash.ui.NavigationTargets.SEND_CONFIRMATION @@ -60,6 +62,7 @@ import co.electriccoin.zcash.ui.screen.sendconfirmation.model.SendConfirmationSt import co.electriccoin.zcash.ui.screen.settings.WrapSettings import co.electriccoin.zcash.ui.screen.support.WrapSupport import co.electriccoin.zcash.ui.screen.update.WrapCheckForUpdate +import co.electriccoin.zcash.ui.screen.warning.WrapNotEnoughSpace import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.launch @@ -247,6 +250,12 @@ internal fun MainActivity.Navigation() { ) } } + composable(NOT_ENOUGH_SPACE) { + WrapNotEnoughSpace( + goPrevious = { navController.popBackStackJustOnce(NOT_ENOUGH_SPACE) }, + goSettings = { navController.navigateJustOnce(SETTINGS) } + ) + } } } @@ -291,11 +300,15 @@ private fun MainActivity.NavigationHome( }, ) + val isEnoughSpace by storageCheckViewModel.isEnoughSpace.collectAsStateWithLifecycle() + val sdkStatus = walletViewModel.walletSnapshot.collectAsStateWithLifecycle().value?.status - if (Synchronizer.Status.DISCONNECTED == sdkStatus) { + if (isEnoughSpace == false) { + Twig.info { "Not enough free space" } + navController.navigateJustOnce(NOT_ENOUGH_SPACE) + } else if (Synchronizer.Status.DISCONNECTED == sdkStatus) { Twig.info { "Disconnected state received from Synchronizer" } - WrapDisconnected( goChooseServer = { navController.navigateJustOnce(CHOOSE_SERVER) @@ -305,6 +318,7 @@ private fun MainActivity.NavigationHome( } ) } else if (ConfigurationEntries.IS_APP_UPDATE_CHECK_ENABLED.getValue(RemoteConfig.current)) { + Twig.info { "App update available" } WrapCheckForUpdate() } } @@ -421,6 +435,7 @@ object NavigationTargets { const val EXPORT_PRIVATE_DATA = "export_private_data" const val HOME = "home" const val CHOOSE_SERVER = "choose_server" + const val NOT_ENOUGH_SPACE = "not_enough_space" const val SCAN = "scan" const val SEED_RECOVERY = "seed_recovery" const val SEND_CONFIRMATION = "send_confirmation" diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/compose/SynchronizationStatus.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/compose/SynchronizationStatus.kt index e4f2a3b6..0d86f9ab 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/compose/SynchronizationStatus.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/compose/SynchronizationStatus.kt @@ -113,7 +113,10 @@ fun StatusDialog( Column( Modifier.verticalScroll(rememberScrollState()) ) { - Text(text = statusAction.details) + Text( + text = statusAction.details, + color = ZcashTheme.colors.textPrimary, + ) } }, confirmButtonText = stringResource(id = R.string.balances_status_dialog_button), diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/about/view/AboutView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/about/view/AboutView.kt index 2f516ff3..4a653562 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/about/view/AboutView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/about/view/AboutView.kt @@ -28,6 +28,7 @@ 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.graphics.ColorFilter import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -183,14 +184,17 @@ fun AboutMainContent( ) { Image( painter = painterResource(id = co.electriccoin.zcash.ui.design.R.drawable.zashi_logo_without_text), + colorFilter = ColorFilter.tint(color = ZcashTheme.colors.secondaryColor), contentDescription = null, - Modifier - .height(ZcashTheme.dimens.inScreenZcashLogoHeight) - .width(ZcashTheme.dimens.inScreenZcashLogoWidth) + modifier = + Modifier + .height(ZcashTheme.dimens.inScreenZcashLogoHeight) + .width(ZcashTheme.dimens.inScreenZcashLogoWidth) ) Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingDefault)) Image( painter = painterResource(id = co.electriccoin.zcash.ui.design.R.drawable.zashi_text_logo), + colorFilter = ColorFilter.tint(color = ZcashTheme.colors.secondaryColor), contentDescription = null, modifier = Modifier.height(ZcashTheme.dimens.inScreenZcashTextLogoHeight) ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/account/view/AccountView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/account/view/AccountView.kt index 9d267afe..befc4c8b 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/account/view/AccountView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/account/view/AccountView.kt @@ -188,7 +188,7 @@ private fun AccountMainContent( .padding(horizontal = ZcashTheme.dimens.screenHorizontalSpacingRegular) ) - Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingUpLarge)) + Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge)) HistoryContainer( onStatusClick = onStatusClick, diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/account/view/HistoryView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/account/view/HistoryView.kt index 5eff9441..34827d12 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/account/view/HistoryView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/account/view/HistoryView.kt @@ -3,6 +3,7 @@ package co.electriccoin.zcash.ui.screen.account.view import androidx.compose.animation.animateContentSize +import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -27,6 +28,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.pluralStringResource @@ -197,7 +199,7 @@ private fun EmptyTransactionHistory() { textAlign = TextAlign.Center, text = stringResource(id = R.string.account_history_empty), style = ZcashTheme.extendedTypography.transactionItemStyles.titleRegular, - color = ZcashTheme.colors.textCommon, + color = ZcashTheme.colors.textPrimary, maxLines = 1, overflow = TextOverflow.Ellipsis ) @@ -220,7 +222,7 @@ private fun HistoryList( ) HorizontalDivider( - color = ZcashTheme.colors.dividerColor, + color = ZcashTheme.colors.primaryDividerColor, thickness = DividerDefaults.Thickness, modifier = Modifier.padding(horizontal = ZcashTheme.dimens.spacingDefault) ) @@ -359,7 +361,9 @@ private fun HistoryItem( ) { Image( imageVector = typeIcon, - contentDescription = typeText + colorFilter = ColorFilter.tint(color = ZcashTheme.colors.secondaryColor), + contentDescription = typeText, + modifier = Modifier.padding(top = ZcashTheme.dimens.spacingTiny) ) Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingDefault)) @@ -449,7 +453,7 @@ private fun HistoryItemCollapsedMainPart( if (transaction.overview.isSentTransaction) { ZcashTheme.colors.historyRedColor } else { - ZcashTheme.colors.textCommon + ZcashTheme.colors.textPrimary } } @@ -546,7 +550,7 @@ private fun HistoryItemExpandedAddressPart( Text( text = recipient.addressValue, style = ZcashTheme.extendedTypography.transactionItemStyles.content, - color = ZcashTheme.colors.textCommon, + color = ZcashTheme.colors.textPrimary, modifier = Modifier .fillMaxWidth(EXPANDED_ADDRESS_WIDTH_RATIO) @@ -559,6 +563,7 @@ private fun HistoryItemExpandedAddressPart( style = ZcashTheme.extendedTypography.transactionItemStyles.content, color = ZcashTheme.colors.textDescription, iconVector = ImageVector.vectorResource(R.drawable.ic_trx_copy), + iconTintColor = ZcashTheme.colors.secondaryColor, modifier = Modifier .clip(RoundedCornerShape(ZcashTheme.dimens.regularRippleEffectCorner)) @@ -608,7 +613,7 @@ private fun HistoryItemExpandedPart( count = transaction.messages!!.size ), style = ZcashTheme.extendedTypography.transactionItemStyles.contentMedium, - color = ZcashTheme.colors.textCommon + color = ZcashTheme.colors.textPrimary ) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall)) @@ -632,7 +637,7 @@ private fun HistoryItemExpandedPart( Text( text = stringResource(id = R.string.account_history_item_no_message), style = ZcashTheme.extendedTypography.transactionItemStyles.contentItalic, - color = ZcashTheme.colors.textCommon, + color = ZcashTheme.colors.textPrimary, modifier = Modifier.fillMaxWidth(EXPANDED_TRANSACTION_WIDTH_RATIO) ) @@ -708,7 +713,7 @@ private fun HistoryItemTransactionIdPart( Text( text = txIdString, style = ZcashTheme.extendedTypography.transactionItemStyles.content, - color = ZcashTheme.colors.textCommon, + color = ZcashTheme.colors.textPrimary, modifier = Modifier .fillMaxWidth(EXPANDED_TRANSACTION_WIDTH_RATIO) @@ -722,6 +727,7 @@ private fun HistoryItemTransactionIdPart( style = ZcashTheme.extendedTypography.transactionItemStyles.content, color = ZcashTheme.colors.textDescription, iconVector = ImageVector.vectorResource(R.drawable.ic_trx_copy), + iconTintColor = ZcashTheme.colors.secondaryColor, modifier = Modifier .clip(RoundedCornerShape(ZcashTheme.dimens.regularRippleEffectCorner)) @@ -825,20 +831,27 @@ private fun HistoryItemMessagePart( textColor = ZcashTheme.colors.historyRedColor } else { textStyle = ZcashTheme.extendedTypography.transactionItemStyles.content - textColor = ZcashTheme.colors.textCommon + textColor = ZcashTheme.colors.textPrimary } Column(modifier = modifier.then(Modifier.fillMaxWidth())) { - val (messageBackground, arrowAlignment) = - if (state.isSendType()) { - Color.Transparent to BubbleArrowAlignment.BottomLeft - } else { - ZcashTheme.colors.dividerColor to BubbleArrowAlignment.BottomRight - } + val bubbleBackgroundColor: Color + val bubbleStroke: BorderStroke + val arrowAlignment: BubbleArrowAlignment + if (state.isSendType()) { + bubbleBackgroundColor = Color.Transparent + bubbleStroke = BorderStroke(1.dp, ZcashTheme.colors.textFieldFrame) + arrowAlignment = BubbleArrowAlignment.BottomLeft + } else { + bubbleBackgroundColor = ZcashTheme.colors.historyMessageBubbleColor + bubbleStroke = BorderStroke(1.dp, ZcashTheme.colors.historyMessageBubbleStrokeColor) + arrowAlignment = BubbleArrowAlignment.BottomRight + } BubbleMessage( modifier = Modifier.fillMaxWidth(), - backgroundColor = messageBackground, + backgroundColor = bubbleBackgroundColor, + borderStroke = bubbleStroke, arrowAlignment = arrowAlignment ) { Text( @@ -856,6 +869,7 @@ private fun HistoryItemMessagePart( style = ZcashTheme.extendedTypography.transactionItemStyles.content, color = ZcashTheme.colors.textDescription, iconVector = ImageVector.vectorResource(R.drawable.ic_trx_copy), + iconTintColor = ZcashTheme.colors.secondaryColor, modifier = Modifier .clip(RoundedCornerShape(ZcashTheme.dimens.regularRippleEffectCorner)) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/authentication/view/AuthenticationView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/authentication/view/AuthenticationView.kt index 9b9b23a0..ddae3f1e 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/authentication/view/AuthenticationView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/authentication/view/AuthenticationView.kt @@ -30,9 +30,9 @@ private fun PreviewAppAccessAuthentication() { } } -@Preview("Error Authentication") +@Preview @Composable -private fun PreviewErrorAuthentication() { +private fun ErrorAuthenticationPreview() { ZcashTheme(forceDarkMode = false) { BlankSurface { AuthenticationErrorDialog( @@ -45,6 +45,21 @@ private fun PreviewErrorAuthentication() { } } +@Preview +@Composable +private fun ErrorAuthenticationDarkPreview() { + ZcashTheme(forceDarkMode = true) { + BlankSurface { + AuthenticationErrorDialog( + onDismiss = {}, + onRetry = {}, + onSupport = {}, + reason = AuthenticationResult.Error(errorCode = -1, errorMessage = "Test Error Message") + ) + } + } +} + @Composable fun AppAccessAuthentication( welcomeAnimVisibility: Boolean, @@ -69,7 +84,10 @@ fun AuthenticationErrorDialog( Column( Modifier.verticalScroll(rememberScrollState()) ) { - Text(text = stringResource(id = R.string.authentication_error_text)) + Text( + text = stringResource(id = R.string.authentication_error_text), + color = ZcashTheme.colors.textPrimary, + ) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault)) @@ -80,7 +98,8 @@ fun AuthenticationErrorDialog( reason.errorCode, reason.errorMessage, ), - fontStyle = FontStyle.Italic + fontStyle = FontStyle.Italic, + color = ZcashTheme.colors.textPrimary, ) } }, @@ -102,7 +121,10 @@ fun AuthenticationFailedDialog( title = stringResource(id = R.string.authentication_failed_title), text = { Column(Modifier.verticalScroll(rememberScrollState())) { - Text(text = stringResource(id = R.string.authentication_failed_text)) + Text( + text = stringResource(id = R.string.authentication_failed_text), + color = ZcashTheme.colors.textPrimary, + ) } }, confirmButtonText = stringResource(id = R.string.authentication_failed_button_retry), diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/balances/view/BalancesView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/balances/view/BalancesView.kt index b6414fb2..1bdda332 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/balances/view/BalancesView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/balances/view/BalancesView.kt @@ -36,7 +36,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag @@ -88,7 +87,7 @@ import co.electriccoin.zcash.ui.screen.balances.model.ShieldState import co.electriccoin.zcash.ui.screen.balances.model.StatusAction import co.electriccoin.zcash.ui.screen.balances.model.WalletDisplayValues -@Preview("Balances") +@Preview @Composable private fun ComposableBalancesPreview() { ZcashTheme(forceDarkMode = false) { @@ -112,10 +111,10 @@ private fun ComposableBalancesPreview() { } } -@Preview("BalancesShieldFailure") +@Preview @Composable -private fun ComposableBalancesShieldFailurePreview() { - ZcashTheme(forceDarkMode = false) { +private fun ComposableBalancesShieldDarkPreview() { + ZcashTheme(forceDarkMode = true) { Balances( balanceState = BalanceStateFixture.new(), isFiatConversionEnabled = false, @@ -234,14 +233,18 @@ fun ShieldingErrorDialog( Column( Modifier.verticalScroll(rememberScrollState()) ) { - Text(text = stringResource(id = R.string.balances_shielding_dialog_error_text)) + Text( + text = stringResource(id = R.string.balances_shielding_dialog_error_text), + color = ZcashTheme.colors.textPrimary, + ) if (reason.isNotEmpty()) { Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault)) Text( text = reason, - fontStyle = FontStyle.Italic + fontStyle = FontStyle.Italic, + color = ZcashTheme.colors.textPrimary, ) } } @@ -308,10 +311,10 @@ private fun BalancesMainContent( onReferenceClick = {} ) - Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingUpLarge)) + Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge)) HorizontalDivider( - color = ZcashTheme.colors.darkDividerColor, + color = ZcashTheme.colors.tertiaryDividerColor, thickness = ZcashTheme.dimens.divider ) @@ -490,7 +493,7 @@ fun TransparentBalanceHelpPanel(onHideHelpPanel: () -> Unit) { modifier = Modifier .padding(all = ZcashTheme.dimens.spacingDefault) - .background(color = Color.White) + .background(color = ZcashTheme.colors.panelBackgroundColorActive) .fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally ) { @@ -592,7 +595,7 @@ fun SpendableBalanceRow(walletSnapshot: WalletSnapshot) { ZcashTheme.extendedTypography.balanceSingleStyles.first, ZcashTheme.extendedTypography.balanceSingleStyles.second ), - textColor = ZcashTheme.colors.textCommon + textColor = ZcashTheme.colors.textPrimary ) Spacer(modifier = Modifier.width(12.dp)) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/chooseserver/view/ChooseServerView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/chooseserver/view/ChooseServerView.kt index c2d7e78d..9d7993ed 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/chooseserver/view/ChooseServerView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/chooseserver/view/ChooseServerView.kt @@ -107,7 +107,7 @@ fun ChooseServer( options[CUSTOM_SERVER_OPTION_INDEX].run { if (options[CUSTOM_SERVER_OPTION_INDEX].isValid()) { stringResource( - R.string.choose_server_textfield_value, + R.string.choose_server_full_server_name, options[CUSTOM_SERVER_OPTION_INDEX].host, options[CUSTOM_SERVER_OPTION_INDEX].port ) @@ -194,7 +194,7 @@ fun ChooseServerBottomBar( ) { HorizontalDivider( thickness = DividerDefaults.Thickness, - color = ZcashTheme.colors.dividerColor + color = ZcashTheme.colors.primaryDividerColor ) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall)) @@ -239,6 +239,8 @@ private fun ChooseServerTopAppBar( ) } +// When changing the following constants, be aware that they should not be the same +const val DEFAULT_SERVER_OPTION_INDEX = 0 const val CUSTOM_SERVER_OPTION_INDEX = 1 @Composable @@ -269,7 +271,7 @@ private fun ChooseServerMainContent( @OptIn(ExperimentalFoundationApi::class) @Composable -@Suppress("LongParameterList") +@Suppress("LongParameterList", "LongMethod") fun ServerList( options: ImmutableList, customServerValue: String, @@ -282,59 +284,84 @@ fun ServerList( options.forEachIndexed { index, endpoint -> val isSelected = index == selectedOption - if (index == CUSTOM_SERVER_OPTION_INDEX) { - Column( - modifier = Modifier.animateContentSize() - ) { + when (index) { + DEFAULT_SERVER_OPTION_INDEX -> { LabeledRadioButton( endpoint = endpoint, changeClick = { setSelectedOption(index) }, - name = stringResource(id = R.string.choose_server_custom), + name = + stringResource( + id = R.string.choose_server_default_label, + stringResource( + id = R.string.choose_server_full_server_name, + endpoint.host, + endpoint.port + ) + ), selected = isSelected, modifier = Modifier.fillMaxWidth() ) - - if (isSelected) { - val focusManager = LocalFocusManager.current - - Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall)) - - FormTextField( - value = customServerValue, - onValueChange = { - setCustomServerValue(it) - }, - placeholder = { - Text(text = stringResource(R.string.choose_server_textfield_hint)) - }, - keyboardActions = - KeyboardActions( - onDone = { - focusManager.clearFocus(true) - } - ), - keyboardOptions = - KeyboardOptions( - keyboardType = KeyboardType.Uri, - imeAction = ImeAction.Done - ), - modifier = - Modifier - .fillMaxWidth() - .padding(horizontal = ZcashTheme.dimens.spacingSmall) + } + CUSTOM_SERVER_OPTION_INDEX -> { + Column( + modifier = Modifier.animateContentSize() + ) { + LabeledRadioButton( + endpoint = endpoint, + changeClick = { setSelectedOption(index) }, + name = stringResource(id = R.string.choose_server_custom), + selected = isSelected, + modifier = Modifier.fillMaxWidth() ) - Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall)) + if (isSelected) { + val focusManager = LocalFocusManager.current + + Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall)) + + FormTextField( + value = customServerValue, + onValueChange = { + setCustomServerValue(it) + }, + placeholder = { + Text(text = stringResource(R.string.choose_server_textfield_hint)) + }, + keyboardActions = + KeyboardActions( + onDone = { + focusManager.clearFocus(true) + } + ), + keyboardOptions = + KeyboardOptions( + keyboardType = KeyboardType.Uri, + imeAction = ImeAction.Done + ), + modifier = + Modifier + .fillMaxWidth() + .padding(horizontal = ZcashTheme.dimens.spacingSmall) + ) + + Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall)) + } } } - } else { - LabeledRadioButton( - endpoint = endpoint, - changeClick = { setSelectedOption(index) }, - name = stringResource(id = R.string.choose_server_textfield_value, endpoint.host, endpoint.port), - selected = isSelected, - modifier = Modifier.fillMaxWidth() - ) + else -> { + LabeledRadioButton( + endpoint = endpoint, + changeClick = { setSelectedOption(index) }, + name = + stringResource( + id = R.string.choose_server_full_server_name, + endpoint.host, + endpoint.port + ), + selected = isSelected, + modifier = Modifier.fillMaxWidth() + ) + } } } } @@ -357,7 +384,7 @@ fun LabeledRadioButton( text = name, selected = selected, onClick = { changeClick(endpoint) }, - modifier = modifier + modifier = modifier, ) } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/debug/view/DesignGuide.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/debug/view/DesignGuide.kt index 0c770c68..ad080b26 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/debug/view/DesignGuide.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/debug/view/DesignGuide.kt @@ -10,7 +10,6 @@ import co.electriccoin.zcash.ui.design.component.BlankSurface import co.electriccoin.zcash.ui.design.component.Body import co.electriccoin.zcash.ui.design.component.ChipIndexed import co.electriccoin.zcash.ui.design.component.Header -import co.electriccoin.zcash.ui.design.component.NavigationButton import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.SecondaryButton import co.electriccoin.zcash.ui.design.theme.ZcashTheme @@ -31,8 +30,6 @@ fun DesignGuide() { Column { Header(text = "H1") Body(text = "body") - NavigationButton(onClick = { }, text = "Back") - NavigationButton(onClick = { }, text = "Next") PrimaryButton(onClick = { }, text = "Primary button", outerPaddingValues = PaddingValues(24.dp)) SecondaryButton(onClick = { }, text = "Secondary button", outerPaddingValues = PaddingValues(24.dp)) ChipIndexed(Index(1), "edict") diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/deletewallet/view/DeleteWalletView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/deletewallet/view/DeleteWalletView.kt index d37fa65a..ae0a2220 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/deletewallet/view/DeleteWalletView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/deletewallet/view/DeleteWalletView.kt @@ -1,6 +1,7 @@ package co.electriccoin.zcash.ui.screen.deletewallet.view import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize @@ -23,9 +24,9 @@ import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState import co.electriccoin.zcash.ui.design.MINIMAL_WEIGHT import co.electriccoin.zcash.ui.design.component.Body -import co.electriccoin.zcash.ui.design.component.CheckBox import co.electriccoin.zcash.ui.design.component.GridBgScaffold import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar +import co.electriccoin.zcash.ui.design.component.LabeledCheckBox import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.TopScreenLogoTitle import co.electriccoin.zcash.ui.design.theme.ZcashTheme @@ -129,17 +130,15 @@ private fun DeleteWalletContent( Spacer(Modifier.height(ZcashTheme.dimens.spacingDefault)) val checkedState = rememberSaveable { mutableStateOf(false) } - CheckBox( - modifier = - Modifier - .align(Alignment.Start) - .fillMaxWidth(), - checked = checkedState.value, - onCheckedChange = { - checkedState.value = it - }, - text = stringResource(R.string.delete_wallet_acknowledge), - ) + Row(Modifier.fillMaxWidth()) { + LabeledCheckBox( + checked = checkedState.value, + onCheckedChange = { + checkedState.value = it + }, + text = stringResource(R.string.delete_wallet_acknowledge), + ) + } Spacer( modifier = diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/disconnected/view/DisconnectedView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/disconnected/view/DisconnectedView.kt index 0d47a201..47f7f957 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/disconnected/view/DisconnectedView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/disconnected/view/DisconnectedView.kt @@ -48,7 +48,10 @@ fun ServerDisconnectedDialog( Column( Modifier.verticalScroll(rememberScrollState()) ) { - Text(text = stringResource(id = R.string.server_disconnected_dialog_message)) + Text( + text = stringResource(id = R.string.server_disconnected_dialog_message), + color = ZcashTheme.colors.textPrimary, + ) } }, confirmButtonText = stringResource(id = R.string.server_disconnected_dialog_switch_btn), diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exportdata/view/ExportPrivateDataView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exportdata/view/ExportPrivateDataView.kt index cdb5394e..c9b992ee 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exportdata/view/ExportPrivateDataView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exportdata/view/ExportPrivateDataView.kt @@ -1,6 +1,7 @@ package co.electriccoin.zcash.ui.screen.exportdata.view import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize @@ -25,9 +26,9 @@ import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState import co.electriccoin.zcash.ui.design.MINIMAL_WEIGHT import co.electriccoin.zcash.ui.design.component.Body -import co.electriccoin.zcash.ui.design.component.CheckBox import co.electriccoin.zcash.ui.design.component.GridBgScaffold import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar +import co.electriccoin.zcash.ui.design.component.LabeledCheckBox import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.TopScreenLogoTitle import co.electriccoin.zcash.ui.design.theme.ZcashTheme @@ -46,9 +47,6 @@ private fun ExportPrivateDataPreview() { } } -// TODO [#998]: Check and enhance screen dark mode -// TODO [#998]: https://github.com/Electric-Coin-Company/zashi-android/issues/998 - @Composable fun ExportPrivateData( snackbarHostState: SnackbarHostState, @@ -134,19 +132,17 @@ private fun ExportPrivateDataContent( Spacer(Modifier.height(ZcashTheme.dimens.spacingDefault)) val checkedState = rememberSaveable { mutableStateOf(false) } - CheckBox( - modifier = - Modifier - .align(Alignment.Start) - .fillMaxWidth(), - checked = checkedState.value, - onCheckedChange = { - checkedState.value = it - onAgree(it) - }, - text = stringResource(R.string.export_data_agree), - checkBoxTestTag = ExportPrivateDataScreenTag.AGREE_CHECKBOX_TAG - ) + Row(Modifier.fillMaxWidth()) { + LabeledCheckBox( + checked = checkedState.value, + onCheckedChange = { + checkedState.value = it + onAgree(it) + }, + text = stringResource(R.string.export_data_agree), + checkBoxTestTag = ExportPrivateDataScreenTag.AGREE_CHECKBOX_TAG + ) + } Spacer( modifier = diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/view/HomeView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/view/HomeView.kt index 6a5b0324..72ff9130 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/view/HomeView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/view/HomeView.kt @@ -173,7 +173,7 @@ fun HomeContent( ) { HorizontalDivider( thickness = DividerDefaults.Thickness, - color = ZcashTheme.colors.dividerColor + color = ZcashTheme.colors.primaryDividerColor ) TabRow( selectedTabIndex = pagerState.currentPage, diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/newwalletrecovery/view/NewWalletRecoveryView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/newwalletrecovery/view/NewWalletRecoveryView.kt index b605db67..56c3a1e2 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/newwalletrecovery/view/NewWalletRecoveryView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/newwalletrecovery/view/NewWalletRecoveryView.kt @@ -52,9 +52,9 @@ import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.fixture.VersionInfoFixture import kotlinx.collections.immutable.toPersistentList -@Preview(name = "NewWalletRecovery") +@Preview @Composable -private fun ComposablePreview() { +private fun NewWalletRecoveryPreview() { ZcashTheme(forceDarkMode = false) { NewWalletRecovery( PersistableWalletFixture.new(), @@ -66,8 +66,19 @@ private fun ComposablePreview() { } } -// TODO [#998]: Check and enhance screen dark mode -// TODO [#998]: https://github.com/Electric-Coin-Company/zashi-android/issues/998 +@Preview +@Composable +private fun NewWalletRecoveryDarkPreview() { + ZcashTheme(forceDarkMode = true) { + NewWalletRecovery( + PersistableWalletFixture.new(), + onSeedCopy = {}, + onBirthdayCopy = {}, + onComplete = {}, + versionInfo = VersionInfoFixture.new(), + ) + } +} /** * @param onComplete Callback when the user has confirmed viewing the seed phrase. diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/view/OnboardingView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/view/OnboardingView.kt index ebc0356e..6c6ff8c6 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/view/OnboardingView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/view/OnboardingView.kt @@ -17,6 +17,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign @@ -43,8 +44,18 @@ private fun OnboardingComposablePreview() { } } -// TODO [#998]: Check and enhance screen dark mode -// TODO [#998]: https://github.com/Electric-Coin-Company/zashi-android/issues/998 +@Preview("Onboarding") +@Composable +private fun OnboardingComposableDarkPreview() { + ZcashTheme(forceDarkMode = true) { + Onboarding( + isDebugMenuEnabled = true, + onImportWallet = {}, + onCreateWallet = {}, + onFixtureWallet = {} + ) + } +} // TODO [#1001]: Screens in landscape mode // TODO [#1001]: https://github.com/Electric-Coin-Company/zashi-android/issues/1001 @@ -108,16 +119,18 @@ private fun OnboardingMainContent( } Image( - painterResource(id = co.electriccoin.zcash.ui.design.R.drawable.zashi_logo_without_text), - stringResource(R.string.zcash_logo_content_description), + painter = painterResource(id = co.electriccoin.zcash.ui.design.R.drawable.zashi_logo_without_text), + colorFilter = ColorFilter.tint(color = ZcashTheme.colors.secondaryColor), + contentDescription = stringResource(R.string.zcash_logo_content_description), modifier = imageModifier ) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault)) Image( - painterResource(id = co.electriccoin.zcash.ui.design.R.drawable.zashi_text_logo), - "" + painter = painterResource(id = co.electriccoin.zcash.ui.design.R.drawable.zashi_text_logo), + colorFilter = ColorFilter.tint(color = ZcashTheme.colors.secondaryColor), + contentDescription = null, ) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingUpLarge)) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/receive/util/AndroidQrCodeImageGenerator.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/receive/util/AndroidQrCodeImageGenerator.kt index 3f1b60e4..312eceb8 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/receive/util/AndroidQrCodeImageGenerator.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/receive/util/AndroidQrCodeImageGenerator.kt @@ -17,6 +17,8 @@ object AndroidQrCodeImageGenerator : QrCodeImageGenerator { } } +// TODO [#1473]: Dark mode QR codes for Receive screen +// TODO [#1473]: https://github.com/Electric-Coin-Company/zashi-android/issues/1473 private fun BooleanArray.toBlackAndWhiteColorArray() = IntArray(size) { if (this[it]) { diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/receive/util/JvmQrCodeGenerator.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/receive/util/JvmQrCodeGenerator.kt index b487099a..0a99af9c 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/receive/util/JvmQrCodeGenerator.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/receive/util/JvmQrCodeGenerator.kt @@ -1,14 +1,24 @@ package co.electriccoin.zcash.ui.screen.receive.util import com.google.zxing.BarcodeFormat +import com.google.zxing.EncodeHintType import com.google.zxing.qrcode.QRCodeWriter +const val QR_CODE_IMAGE_MARGIN_IN_PIXELS = 2 + object JvmQrCodeGenerator : QrCodeGenerator { override fun generate( data: String, sizePixels: Int ): BooleanArray { - val bitMatrix = QRCodeWriter().encode(data, BarcodeFormat.QR_CODE, sizePixels, sizePixels) + val bitMatrix = + QRCodeWriter().encode( + data, + BarcodeFormat.QR_CODE, + sizePixels, + sizePixels, + mapOf(EncodeHintType.MARGIN to QR_CODE_IMAGE_MARGIN_IN_PIXELS) + ) return BooleanArray(sizePixels * sizePixels).apply { var booleanArrayPosition = 0 diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/receive/view/ReceiveView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/receive/view/ReceiveView.kt index 648af646..4a55c31c 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/receive/view/ReceiveView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/receive/view/ReceiveView.kt @@ -16,6 +16,7 @@ import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -28,6 +29,8 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalDensity @@ -61,6 +64,40 @@ import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.runBlocking import kotlin.math.roundToInt +@Preview +@Composable +private fun ReceivePreview() = + ZcashTheme(forceDarkMode = false) { + Receive( + screenBrightnessState = ScreenBrightnessState.NORMAL, + walletAddress = runBlocking { WalletAddressesFixture.new() }, + snackbarHostState = SnackbarHostState(), + onSettings = {}, + onAdjustBrightness = {}, + onAddrCopyToClipboard = {}, + onQrImageShare = {}, + versionInfo = VersionInfoFixture.new(), + topAppBarSubTitleState = TopAppBarSubTitleState.None, + ) + } + +@Preview +@Composable +private fun ReceiveDarkPreview() = + ZcashTheme(forceDarkMode = true) { + Receive( + screenBrightnessState = ScreenBrightnessState.NORMAL, + walletAddress = runBlocking { WalletAddressesFixture.new() }, + snackbarHostState = SnackbarHostState(), + onSettings = {}, + onAdjustBrightness = {}, + onAddrCopyToClipboard = {}, + onQrImageShare = {}, + versionInfo = VersionInfoFixture.new(), + topAppBarSubTitleState = TopAppBarSubTitleState.None, + ) + } + @Suppress("LongParameterList") @Composable fun Receive( @@ -139,7 +176,8 @@ private fun ReceiveTopAppBar( ) { Image( imageVector = ImageVector.vectorResource(id = R.drawable.ic_adjust_brightness), - contentDescription = stringResource(R.string.receive_brightness_content_description) + colorFilter = ColorFilter.tint(color = ZcashTheme.colors.secondaryColor), + contentDescription = stringResource(R.string.receive_brightness_content_description), ) } } @@ -180,7 +218,10 @@ private fun ReceiveContents( Spacer(Modifier.height(ZcashTheme.dimens.spacingDefault)) PagerTabs( - modifier = Modifier.fillMaxWidth(), + modifier = + Modifier + .padding(horizontal = ZcashTheme.dimens.screenHorizontalSpacingRegular) + .fillMaxWidth(), pagerState = pagerState, tabs = state.map { @@ -265,11 +306,11 @@ private fun ColumnScope.QrCode( is WalletAddress.Transparent -> R.string.receive_transparent_content_description } ), - modifier = Modifier.align(Alignment.CenterHorizontally), + modifier = + Modifier + .align(Alignment.CenterHorizontally), ) - Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingTiny)) - Text( text = walletAddress.address, style = ZcashTheme.extendedTypography.addressStyle, @@ -278,13 +319,15 @@ private fun ColumnScope.QrCode( modifier = Modifier .align(Alignment.CenterHorizontally) + .clip(RoundedCornerShape(ZcashTheme.dimens.regularRippleEffectCorner)) .clickable { onAddressCopyToClipboard(walletAddress.address) } - .padding(horizontal = ZcashTheme.dimens.spacingLarge) + .padding( + horizontal = ZcashTheme.dimens.spacingLarge, + vertical = ZcashTheme.dimens.spacingSmall + ) .fillMaxWidth(), ) - Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall)) - Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center @@ -346,21 +389,4 @@ private fun QrCode( ) } -@Preview -@Composable -private fun ComposablePreview() = - ZcashTheme(forceDarkMode = false) { - Receive( - screenBrightnessState = ScreenBrightnessState.NORMAL, - walletAddress = runBlocking { WalletAddressesFixture.new() }, - snackbarHostState = SnackbarHostState(), - onSettings = {}, - onAdjustBrightness = {}, - onAddrCopyToClipboard = {}, - onQrImageShare = {}, - versionInfo = VersionInfoFixture.new(), - topAppBarSubTitleState = TopAppBarSubTitleState.None, - ) - } - private val DEFAULT_QR_CODE_SIZE = 320.dp diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/view/RestoreView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/view/RestoreView.kt index 308054b9..3ae44102 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/view/RestoreView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/view/RestoreView.kt @@ -6,7 +6,6 @@ import androidx.compose.animation.animateContentSize import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.border -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues @@ -21,10 +20,10 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextField @@ -45,7 +44,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalSoftwareKeyboardController @@ -86,9 +84,9 @@ import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.persistentHashSetOf import kotlinx.coroutines.launch -@Preview("Restore Seed") +@Preview @Composable -private fun PreviewRestoreSeed() { +private fun RestoreSeedPreview() { ZcashTheme(forceDarkMode = false) { RestoreWallet( ZcashNetwork.Mainnet, @@ -116,9 +114,39 @@ private fun PreviewRestoreSeed() { } } -@Preview("Restore Seed Birthday") +@Preview @Composable -private fun PreviewRestoreBirthday() { +private fun RestoreSeedDarkPreview() { + ZcashTheme(forceDarkMode = true) { + RestoreWallet( + ZcashNetwork.Mainnet, + restoreState = RestoreState(RestoreStage.Seed), + completeWordList = + persistentHashSetOf( + "abandon", + "ability", + "able", + "about", + "above", + "absent", + "absorb", + "abstract", + "rib", + "ribbon" + ), + userWordList = WordList(listOf("abandon", "absorb")), + restoreHeight = null, + setRestoreHeight = {}, + onBack = {}, + paste = { "" }, + onFinished = {} + ) + } +} + +@Preview +@Composable +private fun RestoreBirthdayPreview() { ZcashTheme(forceDarkMode = false) { RestoreWallet( ZcashNetwork.Mainnet, @@ -146,6 +174,36 @@ private fun PreviewRestoreBirthday() { } } +@Preview +@Composable +private fun RestoreBirthdayDarkPreview() { + ZcashTheme(forceDarkMode = true) { + RestoreWallet( + ZcashNetwork.Mainnet, + restoreState = RestoreState(RestoreStage.Birthday), + completeWordList = + persistentHashSetOf( + "abandon", + "ability", + "able", + "about", + "above", + "absent", + "absorb", + "abstract", + "rib", + "ribbon" + ), + userWordList = WordList(listOf("abandon", "absorb")), + restoreHeight = null, + setRestoreHeight = {}, + onBack = {}, + paste = { "" }, + onFinished = {} + ) + } +} + /** * Note that the restore review doesn't allow the user to go back once the seed is entered correctly. * @@ -527,13 +585,14 @@ private fun SeedGridWithText( isError = parseResult is ParseResult.Warn, colors = TextFieldDefaults.colors( - focusedContainerColor = Color.Transparent, - unfocusedContainerColor = Color.Transparent, + cursorColor = ZcashTheme.colors.textPrimary, disabledContainerColor = Color.Transparent, + disabledIndicatorColor = Color.Transparent, errorContainerColor = Color.Transparent, + focusedContainerColor = Color.Transparent, focusedIndicatorColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, unfocusedIndicatorColor = Color.Transparent, - disabledIndicatorColor = Color.Transparent ) ) } @@ -619,10 +678,8 @@ private fun Autocomplete( items(it) { ChipOnSurface( text = it, - modifier = - Modifier - .testTag(RestoreTag.AUTOCOMPLETE_ITEM) - .clickable { onSuggestionSelected(it) } + onClick = { onSuggestionSelected(it) }, + modifier = Modifier.testTag(RestoreTag.AUTOCOMPLETE_ITEM) ) } } @@ -636,21 +693,23 @@ private fun Warn( ) { if (parseResult is ParseResult.Warn) { Surface( + shape = RoundedCornerShape(size = ZcashTheme.dimens.tinyRippleEffectCorner), modifier = modifier.then( Modifier.border( border = BorderStroke( width = ZcashTheme.dimens.chipStroke, - color = ZcashTheme.colors.layoutStroke - ) + color = ZcashTheme.colors.layoutStrokeSecondary + ), + shape = RoundedCornerShape(size = ZcashTheme.dimens.tinyRippleEffectCorner), ) ), - shape = RectangleShape, - color = MaterialTheme.colorScheme.secondary, + color = ZcashTheme.colors.primaryColor, shadowElevation = ZcashTheme.dimens.chipShadowElevation ) { Text( + color = ZcashTheme.colors.textPrimary, modifier = Modifier .fillMaxWidth() @@ -709,11 +768,12 @@ private fun RestoreBirthdayMainContent( }, colors = TextFieldDefaults.colors( + cursorColor = ZcashTheme.colors.textPrimary, focusedContainerColor = Color.Transparent, unfocusedContainerColor = Color.Transparent, - disabledContainerColor = ZcashTheme.colors.textDisabled, + disabledContainerColor = Color.Transparent, errorContainerColor = Color.Transparent, - focusedIndicatorColor = ZcashTheme.colors.darkDividerColor, + focusedIndicatorColor = ZcashTheme.colors.secondaryDividerColor, unfocusedIndicatorColor = Color.Transparent, disabledIndicatorColor = Color.Transparent ), diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/AndroidScan.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/AndroidScan.kt index c4262db6..e382aea1 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/AndroidScan.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/AndroidScan.kt @@ -18,8 +18,8 @@ import co.electriccoin.zcash.ui.common.model.SerializableAddress import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator -import co.electriccoin.zcash.ui.screen.scan.util.SettingsUtil import co.electriccoin.zcash.ui.screen.scan.view.Scan +import co.electriccoin.zcash.ui.util.SettingsUtil import kotlinx.coroutines.launch @Composable @@ -80,7 +80,7 @@ fun WrapScan( context.startActivity(SettingsUtil.newSettingsIntent(context.packageName)) }.onFailure { // This case should not really happen, as the Settings app should be available on every - // Android device, but we need to handle it somehow. + // Android device, but rather handle it. scope.launch { snackbarHostState.showSnackbar( message = context.getString(R.string.scan_settings_open_failed) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/util/QrCodeAnalyzer.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/util/QrCodeAnalyzer.kt index d83c5ae5..b036ac10 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/util/QrCodeAnalyzer.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/util/QrCodeAnalyzer.kt @@ -29,7 +29,7 @@ class QrCodeAnalyzer( if (image.format in supportedImageFormats) { val bytes = image.planes.first().buffer.toByteArray() - Twig.debug { + Twig.verbose { "Scan result: " + "Frame: $framePosition, " + "Info: ${image.imageInfo}, " + @@ -62,7 +62,7 @@ class QrCodeAnalyzer( (binaryBmp.height * 0.4).toInt() ) - Twig.debug { + Twig.verbose { "Scan result cropped: " + "Image width: ${binaryBitmapCropped.width}, " + "Image height: ${binaryBitmapCropped.height}" diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/view/ScanView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/view/ScanView.kt index 912ff793..286ca5ea 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/view/ScanView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/view/ScanView.kt @@ -80,9 +80,9 @@ import kotlinx.coroutines.flow.flow import kotlinx.coroutines.guava.await import kotlin.math.roundToInt -@Preview("Scan") +@Preview @Composable -private fun PreviewScan() { +private fun ScanPreview() { ZcashTheme(forceDarkMode = false) { BlankSurface { Scan( @@ -98,6 +98,24 @@ private fun PreviewScan() { } } +@Preview +@Composable +private fun ScanDarkPreview() { + ZcashTheme(forceDarkMode = true) { + BlankSurface { + Scan( + snackbarHostState = SnackbarHostState(), + onBack = {}, + onScanned = {}, + onOpenSettings = {}, + onScanStateChanged = {}, + topAppBarSubTitleState = TopAppBarSubTitleState.None, + addressValidationResult = AddressType.Transparent, + ) + } + } +} + @OptIn(ExperimentalPermissionsApi::class) @Composable @Suppress("LongParameterList", "UnusedMaterial3ScaffoldPaddingParameter") diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/securitywarning/view/SecurityWarningView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/securitywarning/view/SecurityWarningView.kt index f2db7242..a17cefb0 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/securitywarning/view/SecurityWarningView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/securitywarning/view/SecurityWarningView.kt @@ -1,6 +1,7 @@ package co.electriccoin.zcash.ui.screen.securitywarning.view import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize @@ -24,15 +25,15 @@ import androidx.compose.ui.tooling.preview.Preview import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.common.model.VersionInfo import co.electriccoin.zcash.ui.design.MINIMAL_WEIGHT -import co.electriccoin.zcash.ui.design.component.CheckBox import co.electriccoin.zcash.ui.design.component.GridBgScaffold import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar +import co.electriccoin.zcash.ui.design.component.LabeledCheckBox import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.TopScreenLogoTitle import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.fixture.VersionInfoFixture -@Preview("Security Warning") +@Preview @Composable private fun SecurityWarningPreview() { ZcashTheme(forceDarkMode = false) { @@ -45,11 +46,20 @@ private fun SecurityWarningPreview() { } } -// TODO [#998]: Check and enhance screen dark mode -// TODO [#998]: https://github.com/Electric-Coin-Company/zashi-android/issues/998 +@Preview +@Composable +private fun SecurityWarningDarkPreview() { + ZcashTheme(forceDarkMode = true) { + SecurityWarning( + versionInfo = VersionInfoFixture.new(), + onBack = {}, + onAcknowledged = {}, + onConfirm = {}, + ) + } +} @Composable -@Suppress("LongParameterList") fun SecurityWarning( versionInfo: VersionInfo, onBack: () -> Unit, @@ -111,19 +121,17 @@ private fun SecurityWarningContent( Spacer(Modifier.height(ZcashTheme.dimens.spacingLarge)) val checkedState = rememberSaveable { mutableStateOf(false) } - CheckBox( - modifier = - Modifier - .align(Alignment.Start) - .fillMaxWidth(), - checked = checkedState.value, - onCheckedChange = { - checkedState.value = it - onAcknowledged(it) - }, - text = stringResource(R.string.security_warning_acknowledge), - checkBoxTestTag = SecurityScreenTag.ACKNOWLEDGE_CHECKBOX_TAG - ) + Row(Modifier.fillMaxWidth()) { + LabeledCheckBox( + checked = checkedState.value, + onCheckedChange = { + checkedState.value = it + onAcknowledged(it) + }, + text = stringResource(R.string.security_warning_acknowledge), + checkBoxTestTag = SecurityScreenTag.ACKNOWLEDGE_CHECKBOX_TAG + ) + } Spacer( modifier = @@ -148,6 +156,7 @@ fun SecurityWarningContentText(versionInfo: VersionInfo) { Column { Text( text = stringResource(id = R.string.security_warning_text, versionInfo.versionName), + color = ZcashTheme.colors.textPrimary, style = ZcashTheme.extendedTypography.securityWarningText ) @@ -164,6 +173,7 @@ fun SecurityWarningContentText(versionInfo: VersionInfo) { } append(textPart2) }, + color = ZcashTheme.colors.textPrimary, style = ZcashTheme.extendedTypography.footnote, modifier = Modifier.fillMaxWidth() ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seedrecovery/view/SeedRecoveryView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seedrecovery/view/SeedRecoveryView.kt index d7dfd0c3..684eda73 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seedrecovery/view/SeedRecoveryView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seedrecovery/view/SeedRecoveryView.kt @@ -70,9 +70,6 @@ private fun ComposablePreview() { } } -// TODO [#998]: Check and enhance screen dark mode -// TODO [#998]: https://github.com/Electric-Coin-Company/zashi-android/issues/998 - /** * @param onDone Callback when the user has confirmed viewing the seed phrase. */ diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/send/view/SendView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/send/view/SendView.kt index 92c75baf..11497939 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/send/view/SendView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/send/view/SendView.kt @@ -326,7 +326,7 @@ private fun SendForm( onReferenceClick = goBalances ) - Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingUpLarge)) + Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge)) // TODO [#1256]: Consider Send.Form TextFields scrolling // TODO [#1256]: https://github.com/Electric-Coin-Company/zashi-android/issues/1256 @@ -535,7 +535,8 @@ fun SendFormAddressTextField( content = { Icon( painter = painterResource(id = R.drawable.qr_code_icon), - contentDescription = stringResource(R.string.send_scan_content_description) + contentDescription = stringResource(R.string.send_scan_content_description), + tint = ZcashTheme.colors.secondaryColor, ) } ) @@ -680,7 +681,7 @@ fun SendFormMemoTextField( contentDescription = null, tint = if (isMemoFieldAvailable) { - ZcashTheme.colors.textCommon + ZcashTheme.colors.textPrimary } else { ZcashTheme.colors.textDisabled } @@ -692,7 +693,7 @@ fun SendFormMemoTextField( text = stringResource(id = R.string.send_memo_label), color = if (isMemoFieldAvailable) { - ZcashTheme.colors.textCommon + ZcashTheme.colors.textPrimary } else { ZcashTheme.colors.textDisabled } @@ -806,13 +807,17 @@ private fun SendFailure( Column( Modifier.verticalScroll(rememberScrollState()) ) { - Text(text = stringResource(id = R.string.send_dialog_error_text)) + Text( + text = stringResource(id = R.string.send_dialog_error_text), + color = ZcashTheme.colors.textPrimary, + ) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault)) Text( text = reason, - fontStyle = FontStyle.Italic + fontStyle = FontStyle.Italic, + color = ZcashTheme.colors.textPrimary, ) } }, diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/sendconfirmation/view/SendConfirmationView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/sendconfirmation/view/SendConfirmationView.kt index 2ced0bcd..9f277a0c 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/sendconfirmation/view/SendConfirmationView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/sendconfirmation/view/SendConfirmationView.kt @@ -4,7 +4,6 @@ package co.electriccoin.zcash.ui.screen.sendconfirmation.view import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -17,7 +16,6 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Icon import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text @@ -25,6 +23,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource @@ -50,6 +49,7 @@ import co.electriccoin.zcash.ui.design.component.Body import co.electriccoin.zcash.ui.design.component.BubbleArrowAlignment import co.electriccoin.zcash.ui.design.component.BubbleMessage import co.electriccoin.zcash.ui.design.component.PrimaryButton +import co.electriccoin.zcash.ui.design.component.SecondaryButton import co.electriccoin.zcash.ui.design.component.Small import co.electriccoin.zcash.ui.design.component.SmallTopAppBar import co.electriccoin.zcash.ui.design.component.StyledBalance @@ -59,8 +59,101 @@ import co.electriccoin.zcash.ui.screen.sendconfirmation.SendConfirmationTag import co.electriccoin.zcash.ui.screen.sendconfirmation.model.SendConfirmationStage import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.runBlocking +@Preview +@Composable +private fun SendConfirmationPreview() { + ZcashTheme(forceDarkMode = false) { + SendConfirmation( + snackbarHostState = SnackbarHostState(), + zecSend = + ZecSend( + destination = runBlocking { WalletAddressFixture.sapling() }, + amount = ZatoshiFixture.new(), + memo = MemoFixture.new(), + proposal = null, + ), + onConfirmation = {}, + onBack = {}, + stage = SendConfirmationStage.Confirmation, + topAppBarSubTitleState = TopAppBarSubTitleState.None, + onContactSupport = {}, + submissionResults = emptyList().toImmutableList() + ) + } +} + +@Preview +@Composable +private fun SendConfirmationDarkPreview() { + ZcashTheme(forceDarkMode = true) { + SendConfirmation( + snackbarHostState = SnackbarHostState(), + zecSend = + ZecSend( + destination = runBlocking { WalletAddressFixture.sapling() }, + amount = ZatoshiFixture.new(), + memo = MemoFixture.new(), + proposal = null, + ), + onConfirmation = {}, + onBack = {}, + stage = SendConfirmationStage.Confirmation, + topAppBarSubTitleState = TopAppBarSubTitleState.None, + onContactSupport = {}, + submissionResults = emptyList().toImmutableList() + ) + } +} + +@Preview +@Composable +private fun SendMultipleErrorPreview() { + ZcashTheme(forceDarkMode = false) { + SendConfirmation( + snackbarHostState = SnackbarHostState(), + zecSend = + ZecSend( + destination = runBlocking { WalletAddressFixture.sapling() }, + amount = ZatoshiFixture.new(), + memo = MemoFixture.new(), + proposal = null, + ), + onConfirmation = {}, + onBack = {}, + stage = SendConfirmationStage.MultipleTrxFailure, + topAppBarSubTitleState = TopAppBarSubTitleState.None, + onContactSupport = {}, + submissionResults = emptyList().toImmutableList() + ) + } +} + +@Preview +@Composable +private fun SendMultipleErrorDarkPreview() { + ZcashTheme(forceDarkMode = true) { + SendConfirmation( + snackbarHostState = SnackbarHostState(), + zecSend = + ZecSend( + destination = runBlocking { WalletAddressFixture.sapling() }, + amount = ZatoshiFixture.new(), + memo = MemoFixture.new(), + proposal = null, + ), + onConfirmation = {}, + onBack = {}, + stage = SendConfirmationStage.MultipleTrxFailure, + topAppBarSubTitleState = TopAppBarSubTitleState.None, + onContactSupport = {}, + submissionResults = emptyList().toImmutableList() + ) + } +} + @Composable @Preview("SendConfirmation") private fun PreviewSendConfirmation() { @@ -80,9 +173,9 @@ private fun PreviewSendConfirmation() { } } +@Preview @Composable -@Preview("SendMultipleTransactionFailure") -private fun PreviewSendMultipleTransactionFailure() { +private fun SendMultipleTransactionFailurePreview() { ZcashTheme(forceDarkMode = false) { @Suppress("MagicNumber") MultipleSubmissionFailure( @@ -107,6 +200,33 @@ private fun PreviewSendMultipleTransactionFailure() { } } +@Preview +@Composable +private fun SendMultipleTransactionFailureDarkPreview() { + ZcashTheme(forceDarkMode = true) { + @Suppress("MagicNumber") + MultipleSubmissionFailure( + onContactSupport = {}, + // Rework this into a test fixture + submissionResults = + persistentListOf( + TransactionSubmitResult.Failure( + FirstClassByteArray("test_transaction_id_1".toByteArray()), + true, + 123, + "test transaction id failure" + ), + TransactionSubmitResult.NotAttempted( + FirstClassByteArray("test_transaction_id_2".toByteArray()) + ), + TransactionSubmitResult.NotAttempted( + FirstClassByteArray("test_transaction_id_3".toByteArray()) + ) + ) + ) + } +} + // TODO [#1260]: Cover Send screens UI with tests // TODO [#1260]: https://github.com/Electric-Coin-Company/zashi-android/issues/1260 @@ -337,6 +457,7 @@ fun SendConfirmationActionButtons( enabled = !isSending, showProgressBar = isSending, minHeight = ZcashTheme.dimens.buttonHeightSmall, + buttonColors = ZcashTheme.colors.tertiaryButtonColors, modifier = Modifier .testTag(SendConfirmationTag.SEND_CONFIRMATION_SEND_BUTTON) @@ -345,7 +466,7 @@ fun SendConfirmationActionButtons( Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingLarge)) - PrimaryButton( + SecondaryButton( text = stringResource(R.string.send_confirmation_back_button), onClick = onBack, enabled = !isSending, @@ -386,14 +507,18 @@ private fun SendFailure( Column( Modifier.verticalScroll(rememberScrollState()) ) { - Text(text = stringResource(id = R.string.send_confirmation_dialog_error_text)) + Text( + text = stringResource(id = R.string.send_confirmation_dialog_error_text), + color = ZcashTheme.colors.textPrimary, + ) if (!reason.isNullOrEmpty()) { Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault)) Text( text = reason, - fontStyle = FontStyle.Italic + fontStyle = FontStyle.Italic, + color = ZcashTheme.colors.textPrimary, ) } } @@ -418,19 +543,11 @@ fun MultipleSubmissionFailure( ) { Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall)) - Box( - contentAlignment = Alignment.BottomEnd - ) { - Image( - imageVector = ImageVector.vectorResource(R.drawable.zashi_logo_sign), - contentDescription = null, - ) - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_alert_circle_fill), - contentDescription = null, - modifier = Modifier.padding(bottom = ZcashTheme.dimens.spacingMid) - ) - } + Image( + imageVector = ImageVector.vectorResource(R.drawable.ic_zashi_logo_sign_warn), + colorFilter = ColorFilter.tint(color = ZcashTheme.colors.secondaryColor), + contentDescription = null, + ) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingBig)) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/support/view/SupportView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/support/view/SupportView.kt index 6eabaeab..e131b658 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/support/view/SupportView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/support/view/SupportView.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource @@ -39,9 +40,9 @@ import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.theme.ZcashTheme -@Preview("Support") +@Preview @Composable -private fun PreviewSupport() { +private fun SupportPreview() { ZcashTheme(forceDarkMode = false) { BlankSurface { Support( @@ -56,6 +57,23 @@ private fun PreviewSupport() { } } +@Preview +@Composable +private fun SupportDarkPreview() { + ZcashTheme(forceDarkMode = true) { + BlankSurface { + Support( + isShowingDialog = false, + setShowDialog = {}, + onBack = {}, + onSend = {}, + snackbarHostState = SnackbarHostState(), + topAppBarSubTitleState = TopAppBarSubTitleState.None, + ) + } + } +} + @Preview("Support-Popup") @Composable private fun PreviewSupportPopup() { @@ -152,6 +170,7 @@ private fun SupportMainContent( Image( imageVector = ImageVector.vectorResource(R.drawable.zashi_logo_sign), + colorFilter = ColorFilter.tint(color = ZcashTheme.colors.secondaryColor), contentDescription = null, ) @@ -185,6 +204,8 @@ private fun SupportMainContent( Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge)) + // TODO [#1467]: Support screen - keep button above keyboard + // TODO [#1467]: https://github.com/Electric-Coin-Company/zashi-android/issues/1467 PrimaryButton( onClick = { setShowDialog(true) }, text = stringResource(id = R.string.support_send), diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AppUpdateCheckerMock.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AppUpdateCheckerMock.kt index 9b0477fd..9ebaa421 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AppUpdateCheckerMock.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AppUpdateCheckerMock.kt @@ -83,7 +83,7 @@ class AppUpdateCheckerMock private constructor() : AppUpdateChecker { ): Flow = flow { // To simulate a real-world situation - delay(2000.milliseconds) + delay(4000.milliseconds) emit(Activity.RESULT_OK) } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/view/UpdateView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/view/UpdateView.kt index 2bf26824..62918082 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/view/UpdateView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/view/UpdateView.kt @@ -2,11 +2,14 @@ package co.electriccoin.zcash.ui.screen.update.view import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -19,8 +22,10 @@ import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource @@ -32,6 +37,7 @@ import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.design.component.Body import co.electriccoin.zcash.ui.design.component.GridBgScaffold import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar +import co.electriccoin.zcash.ui.design.component.Header import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.Reference import co.electriccoin.zcash.ui.design.theme.ZcashTheme @@ -40,9 +46,9 @@ import co.electriccoin.zcash.ui.screen.update.UpdateTag import co.electriccoin.zcash.ui.screen.update.model.UpdateInfo import co.electriccoin.zcash.ui.screen.update.model.UpdateState -@Preview("Update") +@Preview @Composable -private fun PreviewUpdate() { +private fun UpdatePreview() { ZcashTheme(forceDarkMode = false) { Update( snackbarHostState = SnackbarHostState(), @@ -54,6 +60,48 @@ private fun PreviewUpdate() { } } +@Preview +@Composable +private fun UpdateRequiredPreview() { + ZcashTheme(forceDarkMode = false) { + Update( + snackbarHostState = SnackbarHostState(), + UpdateInfoFixture.new(force = true), + onDownload = {}, + onLater = {}, + onReference = {} + ) + } +} + +@Preview +@Composable +private fun UpdateAvailableDarkPreview() { + ZcashTheme(forceDarkMode = true) { + Update( + snackbarHostState = SnackbarHostState(), + UpdateInfoFixture.new(appUpdateInfo = null), + onDownload = {}, + onLater = {}, + onReference = {} + ) + } +} + +@Preview +@Composable +private fun UpdateRequiredDarkPreview() { + ZcashTheme(forceDarkMode = true) { + Update( + snackbarHostState = SnackbarHostState(), + UpdateInfoFixture.new(force = true), + onDownload = {}, + onLater = {}, + onReference = {} + ) + } +} + @Composable fun Update( snackbarHostState: SnackbarHostState, @@ -101,14 +149,17 @@ fun UpdateOverlayRunning(updateInfo: UpdateInfo) { if (updateInfo.state == UpdateState.Running) { Column( Modifier - .background(ZcashTheme.colors.overlay.copy(0.5f)) - .fillMaxWidth() - .fillMaxHeight() + .background(ZcashTheme.colors.overlay.copy(0.65f)) + .fillMaxSize() + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null // Set indication to null to disable ripple effect + ) {} .testTag(UpdateTag.PROGRESSBAR_DOWNLOADING), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { - CircularProgressIndicator() + CircularProgressIndicator(color = ZcashTheme.colors.overlayProgressBar) } } } @@ -143,7 +194,7 @@ private fun UpdateBottomAppBar( ) { HorizontalDivider( thickness = DividerDefaults.Thickness, - color = ZcashTheme.colors.dividerColor + color = ZcashTheme.colors.primaryDividerColor ) Column( @@ -176,6 +227,7 @@ private fun UpdateBottomAppBar( textAlign = TextAlign.Center, style = ZcashTheme.typography.primary.bodyLarge, fontWeight = FontWeight.SemiBold, + color = ZcashTheme.colors.textPrimary, modifier = Modifier .padding(all = ZcashTheme.dimens.spacingDefault) @@ -227,23 +279,23 @@ private fun UpdateContent( Image( imageVector = if (updateInfo.isForce) { - ImageVector.vectorResource(R.drawable.ic_zashi_logo_update_required) + ImageVector.vectorResource(R.drawable.ic_zashi_logo_sign_warn) } else { ImageVector.vectorResource(R.drawable.ic_zashi_logo_update_available) }, + colorFilter = ColorFilter.tint(color = ZcashTheme.colors.secondaryColor), contentDescription = null ) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingBig)) - Text( + Header( text = if (updateInfo.isForce) { stringResource(id = R.string.update_title_required) } else { stringResource(id = R.string.update_title_available, appName) }, - style = ZcashTheme.extendedTypography.updateTitleStyle, textAlign = TextAlign.Center ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/AndroidNotEnoughSpace.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/AndroidNotEnoughSpace.kt index 0983d04d..b5d789d5 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/AndroidNotEnoughSpace.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/AndroidNotEnoughSpace.kt @@ -2,27 +2,85 @@ package co.electriccoin.zcash.ui.screen.warning -import androidx.activity.ComponentActivity +import androidx.activity.compose.BackHandler import androidx.activity.viewModels +import androidx.compose.material3.SnackbarHostState import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.platform.LocalContext import androidx.lifecycle.compose.collectAsStateWithLifecycle import co.electriccoin.zcash.ui.MainActivity +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState +import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel import co.electriccoin.zcash.ui.screen.warning.view.NotEnoughSpaceView import co.electriccoin.zcash.ui.screen.warning.viewmodel.StorageCheckViewModel +import co.electriccoin.zcash.ui.util.SettingsUtil +import kotlinx.coroutines.launch @Composable -fun MainActivity.WrapNotEnoughSpace() { - WrapNotEnoughSpace(this) -} +fun MainActivity.WrapNotEnoughSpace( + goPrevious: () -> Unit, + goSettings: () -> Unit +) { + val walletViewModel by viewModels() -@Composable -private fun WrapNotEnoughSpace(activity: ComponentActivity) { - val storageCheckViewModel by activity.viewModels() - val spaceRequiredToContinue by storageCheckViewModel.spaceRequiredToContinueMegabytes.collectAsStateWithLifecycle() + val storageCheckViewModel by viewModels() - NotEnoughSpaceView( - storageSpaceRequiredGigabytes = storageCheckViewModel.requiredStorageSpaceGigabytes, - spaceRequiredToContinueMegabytes = spaceRequiredToContinue ?: 0 + val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value + + val isEnoughFreeSpace = storageCheckViewModel.isEnoughSpace.collectAsStateWithLifecycle().value + if (isEnoughFreeSpace == true) { + goPrevious() + } + + val requiredStorageSpaceGigabytes = storageCheckViewModel.requiredStorageSpaceGigabytes + val spaceAvailableMegabytes = storageCheckViewModel.spaceAvailableMegabytes.collectAsStateWithLifecycle() + + BackHandler { + finish() + } + + WrapNotEnoughFreeSpace( + goSettings = goSettings, + spaceAvailableMegabytes = spaceAvailableMegabytes.value ?: 0, + requiredStorageSpaceGigabytes = requiredStorageSpaceGigabytes, + walletState = walletState, + ) +} + +@Composable +private fun WrapNotEnoughFreeSpace( + goSettings: () -> Unit, + requiredStorageSpaceGigabytes: Int, + spaceAvailableMegabytes: Int, + walletState: TopAppBarSubTitleState, +) { + val context = LocalContext.current + + val scope = rememberCoroutineScope() + + val snackbarHostState = remember { SnackbarHostState() } + + NotEnoughSpaceView( + onSettings = goSettings, + onSystemSettings = { + runCatching { + context.startActivity(SettingsUtil.newStorageSettingsIntent()) + }.onFailure { + // This case should not really happen, as the Settings app should be available on every + // Android device, but we rather handle it. + scope.launch { + snackbarHostState.showSnackbar( + message = context.getString(R.string.not_enough_space_settings_open_failed) + ) + } + } + }, + snackbarHostState = snackbarHostState, + storageSpaceRequiredGigabytes = requiredStorageSpaceGigabytes, + spaceAvailableMegabytes = spaceAvailableMegabytes, + topAppBarSubTitleState = walletState, ) } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/view/NotEnoughSpaceView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/view/NotEnoughSpaceView.kt index a31a73d6..4f069a97 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/view/NotEnoughSpaceView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/view/NotEnoughSpaceView.kt @@ -1,77 +1,193 @@ package co.electriccoin.zcash.ui.screen.warning.view import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.SnackbarHostState import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState +import co.electriccoin.zcash.ui.common.test.CommonTag +import co.electriccoin.zcash.ui.design.MINIMAL_WEIGHT import co.electriccoin.zcash.ui.design.component.Body -import co.electriccoin.zcash.ui.design.component.GridBgColumn +import co.electriccoin.zcash.ui.design.component.GridBgScaffold import co.electriccoin.zcash.ui.design.component.Header -import co.electriccoin.zcash.ui.design.component.Small +import co.electriccoin.zcash.ui.design.component.PrimaryButton +import co.electriccoin.zcash.ui.design.component.SmallTopAppBar import co.electriccoin.zcash.ui.design.theme.ZcashTheme -@Preview("NotEnoughSpace") +@Preview @Composable private fun NotEnoughSpacePreview() { ZcashTheme(forceDarkMode = false) { NotEnoughSpaceView( + onSettings = {}, + onSystemSettings = {}, + snackbarHostState = SnackbarHostState(), + spaceAvailableMegabytes = 300, storageSpaceRequiredGigabytes = 1, - spaceRequiredToContinueMegabytes = 300 + topAppBarSubTitleState = TopAppBarSubTitleState.None, + ) + } +} + +@Preview +@Composable +private fun NotEnoughSpaceDarkPreview() { + ZcashTheme(forceDarkMode = true) { + NotEnoughSpaceView( + onSettings = {}, + onSystemSettings = {}, + snackbarHostState = SnackbarHostState(), + spaceAvailableMegabytes = 300, + storageSpaceRequiredGigabytes = 1, + topAppBarSubTitleState = TopAppBarSubTitleState.None, ) } } @Composable +@Suppress("LongParameterList") fun NotEnoughSpaceView( + onSettings: () -> Unit, + onSystemSettings: () -> Unit, + spaceAvailableMegabytes: Int, storageSpaceRequiredGigabytes: Int, - spaceRequiredToContinueMegabytes: Int + topAppBarSubTitleState: TopAppBarSubTitleState, + snackbarHostState: SnackbarHostState, ) { - GridBgColumn( - Modifier - .fillMaxSize() - .padding(ZcashTheme.dimens.screenHorizontalSpacingRegular) - .verticalScroll( - rememberScrollState() - ), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - ) { - Image( - painter = painterResource(id = R.drawable.not_enough_space), - contentDescription = null, - modifier = Modifier.fillMaxWidth() - ) - - Spacer(Modifier.height(ZcashTheme.dimens.spacingUpLarge)) - - Header(text = stringResource(id = R.string.not_enough_space_title)) - - Spacer(Modifier.height(ZcashTheme.dimens.spacingUpLarge)) - - Body( - text = stringResource(id = R.string.not_enough_space_description, storageSpaceRequiredGigabytes), - textAlign = TextAlign.Center - ) - - Spacer(Modifier.height(ZcashTheme.dimens.spacingHuge)) - - Small( - text = stringResource(id = R.string.space_required_to_continue, spaceRequiredToContinueMegabytes), - textAlign = TextAlign.Center, - modifier = Modifier.fillMaxWidth() + GridBgScaffold( + topBar = { + NotEnoughSpaceTopAppBar( + onSettings = onSettings, + subTitleState = topAppBarSubTitleState, + ) + }, + snackbarHost = { SnackbarHost(snackbarHostState) }, + ) { paddingValues -> + NotEnoughSpaceMainContent( + onSystemSettings = onSystemSettings, + spaceRequiredToContinueMegabytes = spaceAvailableMegabytes, + storageSpaceRequiredGigabytes = storageSpaceRequiredGigabytes, + modifier = + Modifier + .padding( + top = paddingValues.calculateTopPadding(), + bottom = paddingValues.calculateBottomPadding(), + start = ZcashTheme.dimens.screenHorizontalSpacingBig, + end = ZcashTheme.dimens.screenHorizontalSpacingBig + ) ) } } + +@Composable +private fun NotEnoughSpaceTopAppBar( + onSettings: () -> Unit, + subTitleState: TopAppBarSubTitleState +) { + SmallTopAppBar( + subTitle = + when (subTitleState) { + TopAppBarSubTitleState.Disconnected -> stringResource(id = R.string.disconnected_label) + TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label) + TopAppBarSubTitleState.None -> null + }, + titleText = stringResource(id = R.string.not_enough_space_title).uppercase(), + hamburgerMenuActions = { + IconButton( + onClick = onSettings, + modifier = Modifier.testTag(CommonTag.SETTINGS_TOP_BAR_BUTTON) + ) { + Icon( + painter = painterResource(id = co.electriccoin.zcash.ui.design.R.drawable.hamburger_menu_icon), + contentDescription = stringResource(id = R.string.settings_menu_content_description) + ) + } + } + ) +} + +@Composable +private fun NotEnoughSpaceMainContent( + onSystemSettings: () -> Unit, + spaceRequiredToContinueMegabytes: Int, + storageSpaceRequiredGigabytes: Int, + modifier: Modifier = Modifier +) { + Column( + modifier = + modifier.then( + Modifier + .fillMaxHeight() + .verticalScroll( + rememberScrollState() + ) + ), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingBig)) + + Image( + painter = painterResource(id = R.drawable.ic_zashi_logo_sign_warn), + colorFilter = ColorFilter.tint(color = ZcashTheme.colors.secondaryColor), + contentDescription = null, + ) + + Spacer(Modifier.height(ZcashTheme.dimens.spacingBig)) + + Header( + text = + stringResource( + id = R.string.not_enough_space_description_1, + stringResource(id = R.string.app_name), + storageSpaceRequiredGigabytes, + spaceRequiredToContinueMegabytes + ), + textAlign = TextAlign.Center + ) + + Spacer(Modifier.height(ZcashTheme.dimens.spacingLarge)) + + Body( + text = + stringResource( + id = R.string.not_enough_space_description_2, + stringResource(id = R.string.app_name) + ), + textAlign = TextAlign.Center + ) + + Spacer( + modifier = + Modifier + .fillMaxHeight() + .weight(MINIMAL_WEIGHT) + ) + + Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault)) + + PrimaryButton( + onClick = onSystemSettings, + text = stringResource(R.string.not_enough_space_system_settings_btn), + ) + + Spacer(Modifier.height(ZcashTheme.dimens.spacingHuge)) + } +} diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/viewmodel/StorageCheckViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/viewmodel/StorageCheckViewModel.kt index 81123af8..26955780 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/viewmodel/StorageCheckViewModel.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/viewmodel/StorageCheckViewModel.kt @@ -29,4 +29,12 @@ class StorageCheckViewModel : ViewModel() { SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT), null ) + + val spaceAvailableMegabytes = + flow { emit(StorageChecker.checkAvailableStorageMegabytes()) } + .stateIn( + viewModelScope, + SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT), + null + ) } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/util/SettingsUtil.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/util/SettingsUtil.kt similarity index 71% rename from ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/util/SettingsUtil.kt rename to ui-lib/src/main/java/co/electriccoin/zcash/ui/util/SettingsUtil.kt index e282c186..20f51850 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/util/SettingsUtil.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/util/SettingsUtil.kt @@ -1,4 +1,4 @@ -package co.electriccoin.zcash.ui.screen.scan.util +package co.electriccoin.zcash.ui.util import android.content.Intent import android.net.Uri @@ -26,4 +26,15 @@ object SettingsUtil { flags = FLAGS } } + + /** + * Returns an intent to the system Storage Settings page. + * + * @return Intent for launching the system Settings app + */ + internal fun newStorageSettingsIntent(): Intent { + return Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS).apply { + flags = FLAGS + } + } } diff --git a/ui-lib/src/main/res/ui/account/drawable-night/ic_trx_collapse.xml b/ui-lib/src/main/res/ui/account/drawable-night/ic_trx_collapse.xml new file mode 100644 index 00000000..da78aac2 --- /dev/null +++ b/ui-lib/src/main/res/ui/account/drawable-night/ic_trx_collapse.xml @@ -0,0 +1,15 @@ + + + + diff --git a/ui-lib/src/main/res/ui/balances/drawable-night/ic_help_question_mark.xml b/ui-lib/src/main/res/ui/balances/drawable-night/ic_help_question_mark.xml new file mode 100644 index 00000000..b88e1867 --- /dev/null +++ b/ui-lib/src/main/res/ui/balances/drawable-night/ic_help_question_mark.xml @@ -0,0 +1,14 @@ + + + + diff --git a/ui-lib/src/main/res/ui/choose_server/values/strings.xml b/ui-lib/src/main/res/ui/choose_server/values/strings.xml index 5a54c532..70467845 100644 --- a/ui-lib/src/main/res/ui/choose_server/values/strings.xml +++ b/ui-lib/src/main/res/ui/choose_server/values/strings.xml @@ -3,10 +3,13 @@ Back Server + default: %1$s custom : - %1$s:%2$d + + %1$s: + %2$d + <hostname>:<port> Save diff --git a/ui-lib/src/main/res/ui/common/drawable-night/zashi_logo.webp b/ui-lib/src/main/res/ui/common/drawable-night/zashi_logo.webp deleted file mode 100644 index 4cca14acc8c63274a18bd5c5eb3815d43a280598..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 708 zcmV;#0z3UuNk&Gz0ssJ4MM6+kP&iDm0ssInufb~&4>14pKmYR|@Sx*rTXeB`5e1!T zJ+pYz3Wz;QyslZ|hAnZ&^a^j#qryPT z3f-Ydcq}K-0!9$10WAq20!1MK+X>u&=>>iOdK7pA)GROnYy}5QZ?Ah`M0?ExE!nF9 zK(U7iU^#mUz!10{-rf%YrobBjOJD-{O<*|SL$KE!S`=s=JqXl*;i5pqga8umcp~r` zH;EsR@LJ&BqQvY0F9pUYk0j7Pqban45fw6)7pMt@LTp)~hY=NqpI%{NL-Ag-#H~k( zG`&KN8;b3xA~F6-67zGAxNj$ME0Fw{B`P%<-%5<~Mq;KRv7*NIU4rONpk_3Mme9OF zEvO3Ez6OO6A<;6T0*EIPE4-E%>7_(1KS*GIt1*j47Xd|<$Z#4>K6XUUsKiMB zRV7J}c~lncBW@cGs{rVvQK2Ty>J!N++4GCdp!qbQjrDx>|lP zSs5fFD(SI(W0a^2Rsihq2-_K=MCF=rs~xy z=p>VwMt4C}V*uzDfpuh56a9iD(8+9O6rdgs*dpD~%zp=lRs!1L0W5{;G41U5s0GYq zh5_hD=mEnJ$v-m&!-$6J@hPD(%xtJVsEn&%MpNU0bawhNBPu_TVFfFLWSJ2-NN;L| qN6yOp8<}K*rF`tX$!Kf)W0Bt8DuaZnbk&&cT+$ub(b!l2e_=OXEjiTy diff --git a/ui-lib/src/main/res/ui/update/drawable/ic_zashi_logo_update_required.xml b/ui-lib/src/main/res/ui/common/drawable/ic_zashi_logo_sign_warn.xml similarity index 100% rename from ui-lib/src/main/res/ui/update/drawable/ic_zashi_logo_update_required.xml rename to ui-lib/src/main/res/ui/common/drawable/ic_zashi_logo_sign_warn.xml diff --git a/ui-lib/src/main/res/ui/common/drawable/zashi_logo.webp b/ui-lib/src/main/res/ui/common/drawable/zashi_logo.webp deleted file mode 100644 index 991e928373d1ea4f061853c9886f54401c59ed26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3730 zcmV;D4sG#LNk&GB4gdgGMM6+kP&iC}4gdfzufb~&_a`Js`2SsVgn*z#lH$eW;1ApW z#ZCPGyJse8YN=4_w#B83FAhtw?hAJ*>u$KS?t-)K&I@-|kTu+0t4OiBrpe6n@lPku znY`XM&$lI_{}TYe|NZ{=``_<>zyJOI_xs=Pf4~3z{`dRe?|;Al|KFE`M~4ZPm~U5g zw+j^{pYVL%LlP+%d|kWxMw%i}lt=4`uFgyrCvbf3A#xp?)KC&7NZd|TOX{wXL81iB zuF{cjZm6XjdIbv-OuSR~R`;)}spO+Jk{Ah??I|4>ma(N=z42BHS%e^X9lO{b&a4AW zyD%k6grM;sY)=BDsK-vY>n>!)3J~-xaxV)3(DcP(s@~DpCO+f`OWiXS0CL*GLRPz_ zSCHsH@KUD_Erxg*mlB+&Xe?Fumh$Q?ef zq|$HO3kj)fk-E%j2ne`mRSCQEQMz3`0CTF#A2R_69lb}Rb1#Pph@khWqtd3pv@`T6mANDsP}V8`+0DnV30@DxaK)bLO}bK zW$gAB={BJN+x+UvEVBT)>-q{RTbwS51VsMC&Uci|0wPBos8P?&jgtiek`A#y6U_sh zj~!9z#Iq3sLC(lkKMwH$pyN%%@A5 ztDP`_JiV&yX~_p6Q_I=rmIu{2;s6ofYK5)Mv%gxVZB53zv^rEAAYu>gZ)#TjS9PvM z5x_snF0~Q}=#%UDK{hA$M|ai2FaXU?)eR8|(y(f6ZlD=$_psYfC;(tvNh?GGl*R6w zLybwD_tNzT0-*aeol-;sqQ0ksmPX`3SJ>GMcun(^w-X9Ty{K(S7&)4-A3`p2cM;h0YlD5~Cyb=t93H#_R(SWwO>dJ5c={s4~BSGMI4En8> zeish%=$r1>9JcP~wM%0aaEJBTS;4M<*h)CS{t_!1J@gXg_m;sccUW0W?yoa!5Rl#%`5dbmSB$wFl&A^+oq=3_@f$Sznlnxsf@nB&h@hCgbmzXuHJgTjST`b@WBf9M;p`+ z9Jr;HN|v;T&*g&!c%(eCLQcN{I6Onf9bx`nummk^WAE7 z+jILFD|j;rws+KhiGm}1VU2eAU@5EqsG9Au^h8 zVnnQJ!+;QYZB<a2r-egvYgSGG4Zkyw7*lHB?$=xjs3BjJo~36843DW+Ziq)7n<$A3K#F}} zmxn5MO>}w*`G#!|5*dILaPPO*nLBrSx>66F?`VU>1^`FzB~|1(|8}E#$~xK@Dmnnf z&puv9uJ1CPK-W8^V+07KCQqEKquU#X1c&{|w%7#-fWV;}ib*~C)PxGk5F`^h_xs;Z@yPTc zkKO&R5jJ-Av`2@wi!wMUk^<+A->(H zIp6%9bG@`?k9sn7wUI$7qSCLHF@9mv1AyY1S+Qes9LFOX zaZWQ~19|uS7F};hDRDmfUpRT5>MPgNlCe&=$-67lH%i*n)3s!P8nBk3T@XIZ>wBTfSA`A#+*j zlff3wIP&#E$%G6SSH*C%k`|sLAC^p$EgNN}ul`Jeap^naW}gO{Vejy1F(aR<56MYvSsvB@I{{u3 z-^(^o@SqHfMt+<5=6nY;!Zwo8ZzMyZAFK7)yRtU~wA)b2!Se63!>X~(`ohdFk1{>& zVabekRfcj?4GpNI`s#3S2R?Yi+pf0IwPc{!%uM-PkL?bEnXi)J%KIe)@+#8n#s_)m z86EeArm%8MRo*83E4^T5^l@YKU9f@Hgy!rF3REySV3M7H!=bYKlhLftI7VFs#i1` zrY7Ii(Y|nVt+#Q7t@WmEPE(B7l5Mb@G73rmvtV-`Bi-E2r?_%jaYbzPM(p_1I0Htl zp@w^zUS0}Jb?(q%9|SLAJg#RXp0KqXM6RnVv)aYmEG&5r=~qvY&FOVrr(ztsxOiwy zFpuLCE+S&r|M+xTMyyqpdELvpFqo>m%XCg9Lf*qw-iQa&-3Ew=d1@-ote)KOt^ms^ z@DI{2>jHB_E|Bgw67amnLyvRaTV%{@#o;do2Aa00bI)GAdiBZ7%*-4za@43%;~zL; zh1g#reb);%lZKM6mIj>~sR!s4+Wf5|K^eYC!;ne?bYVQ|ESV>Gk;fNAmCrdWB4vuE zr+pD()^l#1iixOiJIg~m19=d;UG)hSJ+4?oeXf%Jxh61KK18|~6Lc_B<#9LVLhQ$N zKB1C(ETNzsq+j=>WL6uG-nWuo#~dD-#fR`|msMZTs$dJqKEtEO)<(i)c_Ha)L!s~Z zfopdJACR{AvM+9C7(4sR&fS0SIdu5==`)uu=U*wjb;o0Mbju_C!Y-0oX@~VLqo-7Li*aPFnw%|-kwRL zyiTg%VJ}HW0N6V}|J_NKDYQMn&@>oUHdq_>X|;N6cd~iwNx!awQ{$l%HWL6TIJVXJ zMSol@(TwBj~Df+h5p)c&L;;Rm}c%0ivU;9LX+0qQnSM;WA z9st?dZ1H6t3bA&Sr)#{NONZ$Ve<7d$8S4`ON~gUXs>Rdk3hBEiN#^w{^Id7C0VT;0 z(Bz=E>p_-I;41REGZ5x4q<_J;4GjMy-54f&`#r$Qu}!b>l6McxkG!ULcI(bPN6utl zEvodGkmulWPIl9=w#L#_J@$%ht zt@!>bkGm&_V_`Xw_FI&p=u*AnL9lSb)|2=3E6wc#z`2Ta52V2Gvpj5>%}b+I8W9oO z(b7<{-tUnXj{HOghsi}90kpZIqrGP{*5nok9Z1oUo9*vdCXnvQNDIgLE&1B@oCE|O*85vAK^j-iK_3Hf zOw1wfs%`zlBrgF!=~O;0TQ~Akl|H+X0-%4Hj`|eLj5@({B@FV6axz-GZRYeDGiJ=4 zKY!7!dY-SHux`={$mgphz_C=*Ip5k8yv|cI0@B=CLqr}`RaHjyS=p{JQLt{DUz5+> zqXDFzBi+v(=Cm*6V4pbPTv2C?w|c{f5O}v@CRX_FSQ>yVRY%K!x#8GS%lcXnWIozWF1U-;vPU%-Y9pJZOzVTgkZvY(&b+i{@ zc0x7>{Zj%UH(7c`Gr}%?*eno6Eva)3K%VQ?xz^n@e9m(v9`%*(Z(rdnT-e42<5o0nG9vfU7h@Ed`50+c zcdlGKv47XL@A{hJF29j?_Q>DAu75GC-rXN>-nsYKg@Rj^>VMt-MV;eDWVBCm+-|v6F|NZ{=``_<>zyJS_ZM;fiQ~&?~ diff --git a/ui-lib/src/main/res/ui/send_confirmation/drawable/zashi_logo_sign.xml b/ui-lib/src/main/res/ui/common/drawable/zashi_logo_sign.xml similarity index 100% rename from ui-lib/src/main/res/ui/send_confirmation/drawable/zashi_logo_sign.xml rename to ui-lib/src/main/res/ui/common/drawable/zashi_logo_sign.xml diff --git a/ui-lib/src/main/res/ui/new_wallet_recovery/values/strings.xml b/ui-lib/src/main/res/ui/new_wallet_recovery/values/strings.xml index c4e18078..f4f9e724 100644 --- a/ui-lib/src/main/res/ui/new_wallet_recovery/values/strings.xml +++ b/ui-lib/src/main/res/ui/new_wallet_recovery/values/strings.xml @@ -5,7 +5,7 @@ place you trust and never share it with anyone! Wallet birthday height: %1$d - I got it! + I\'ve saved it Tap to Copy Zcash Seed Phrase Zcash Wallet Birthday diff --git a/ui-lib/src/main/res/ui/onboarding/values/strings.xml b/ui-lib/src/main/res/ui/onboarding/values/strings.xml index 76055a79..12996ab2 100644 --- a/ui-lib/src/main/res/ui/onboarding/values/strings.xml +++ b/ui-lib/src/main/res/ui/onboarding/values/strings.xml @@ -1,5 +1,5 @@ - zcash-ui + zashi-ui A no-frills wallet for sending and receiving Zcash (ZEC) diff --git a/ui-lib/src/main/res/ui/receive/drawable/ic_adjust_brightness.xml b/ui-lib/src/main/res/ui/receive/drawable/ic_adjust_brightness.xml index f9b01537..e8f9a4d0 100644 --- a/ui-lib/src/main/res/ui/receive/drawable/ic_adjust_brightness.xml +++ b/ui-lib/src/main/res/ui/receive/drawable/ic_adjust_brightness.xml @@ -20,7 +20,7 @@ android:fillColor="#000000"/> + android:fillColor="#000000"/> diff --git a/ui-lib/src/main/res/ui/send_confirmation/drawable/ic_alert_circle_fill.xml b/ui-lib/src/main/res/ui/send_confirmation/drawable/ic_alert_circle_fill.xml deleted file mode 100644 index ae99fb25..00000000 --- a/ui-lib/src/main/res/ui/send_confirmation/drawable/ic_alert_circle_fill.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/ui-lib/src/main/res/ui/update/values/strings.xml b/ui-lib/src/main/res/ui/update/values/strings.xml index 8176d254..c1c76fbb 100644 --- a/ui-lib/src/main/res/ui/update/values/strings.xml +++ b/ui-lib/src/main/res/ui/update/values/strings.xml @@ -2,14 +2,14 @@ Update available Update required - %1$s here. + %1$s here. It\'s not you, it\'s me. - There is a required update for %1$s that makes major + There is a required update for %1$s that makes major improvements to performance and/or security. - There is a new version of %1$s that makes minor updates to + There is a new version of %1$s that makes minor updates to improve performance and/or security.\n\nPlease take a moment to update to the latest version. Learn more about this update here. diff --git a/ui-lib/src/main/res/ui/warning/drawable/not_enough_space.xml b/ui-lib/src/main/res/ui/warning/drawable/not_enough_space.xml deleted file mode 100644 index f72f3602..00000000 --- a/ui-lib/src/main/res/ui/warning/drawable/not_enough_space.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/ui-lib/src/main/res/ui/warning/values/strings.xml b/ui-lib/src/main/res/ui/warning/values/strings.xml index 91d629d6..be521ee2 100644 --- a/ui-lib/src/main/res/ui/warning/values/strings.xml +++ b/ui-lib/src/main/res/ui/warning/values/strings.xml @@ -1,9 +1,15 @@ - Not enough space! - You need approximately - %1$d Gbyte of space while synchronizing the Zcash blockchain, but only 300 Mbyte once done. Syncing - will stay paused until more space is available. - ~%1$d Mbyte - required to continue + Not enough free space + + %1$s requires at least + %2$d GB of space to operate but there is only + %3$d MB available. + + + Go to your device settings and make more space available if you wish to use the + %1$s app. + + System settings + Unable to launch Settings app.