diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiBigIconButton.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiBigIconButton.kt index 86b8e9782..08bdf63b4 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiBigIconButton.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiBigIconButton.kt @@ -1,56 +1,77 @@ package co.electriccoin.zcash.ui.design.component import androidx.annotation.DrawableRes -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Icon import androidx.compose.material3.Surface import androidx.compose.material3.Text -import androidx.compose.material3.ripple 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.Brush +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.res.painterResource -import androidx.compose.ui.semantics.Role import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import co.electriccoin.zcash.ui.design.R +import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens +import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography import co.electriccoin.zcash.ui.design.util.StringResource import co.electriccoin.zcash.ui.design.util.getValue +import co.electriccoin.zcash.ui.design.util.orDark +import co.electriccoin.zcash.ui.design.util.stringRes +@Suppress("MagicNumber") @Composable fun ZashiBigIconButton( state: BigIconButtonState, modifier: Modifier = Modifier, ) { + val darkBgGradient = + Brush.verticalGradient( + 0f to ZashiColors.Surfaces.strokeSecondary, + .66f to ZashiColors.Surfaces.strokeSecondary.copy(alpha = 0.5f), + 1f to ZashiColors.Surfaces.strokeSecondary.copy(alpha = 0.25f), + ) + + val darkBorderGradient = + Brush.verticalGradient( + 0f to ZashiColors.Surfaces.strokePrimary, + 1f to ZashiColors.Surfaces.strokePrimary.copy(alpha = 0f), + ) + + val backgroundModifier = + Modifier.background(ZashiColors.Surfaces.bgPrimary) orDark + Modifier.background(darkBgGradient) + Surface( - modifier = - modifier, - shape = RoundedCornerShape(16.dp), - color = ZashiColors.Surfaces.bgSecondary + modifier = modifier, + onClick = state.onClick, + color = ZashiColors.Surfaces.bgPrimary, + shape = RoundedCornerShape(22.dp), + border = + BorderStroke(.5.dp, ZashiColors.Utility.Gray.utilityGray100) orDark + BorderStroke(.5.dp, darkBorderGradient), + shadowElevation = 2.dp orDark 4.dp ) { Column( - modifier = - Modifier - .clickable( - indication = ripple(), - interactionSource = remember { MutableInteractionSource() }, - onClick = state.onClick, - role = Role.Button, - ).padding(16.dp), - horizontalAlignment = Alignment.CenterHorizontally + modifier = backgroundModifier.padding(16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center ) { - Icon( + Image( painter = painterResource(state.icon), contentDescription = state.text.getValue(), - tint = ZashiColors.Text.textPrimary + colorFilter = ColorFilter.tint(ZashiColors.Text.textPrimary) ) Spacer(Modifier.height(4.dp)) Text( @@ -68,3 +89,17 @@ data class BigIconButtonState( @DrawableRes val icon: Int, val onClick: () -> Unit, ) + +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + ZashiBigIconButton( + state = + BigIconButtonState( + text = stringRes("Text"), + icon = R.drawable.ic_reveal, + onClick = {} + ) + ) + } diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiBulletText.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiBulletText.kt new file mode 100644 index 000000000..0f00b285b --- /dev/null +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiBulletText.kt @@ -0,0 +1,54 @@ +package co.electriccoin.zcash.ui.design.component + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.text.ParagraphStyle +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.rememberTextMeasurer +import androidx.compose.ui.text.style.TextIndent +import androidx.compose.ui.text.withStyle +import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors +import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography + +@Composable +fun ZashiBulletText( + vararg bulletText: String, + modifier: Modifier = Modifier, + style: TextStyle = ZashiTypography.textSm, + fontWeight: FontWeight = FontWeight.Normal, + color: Color = ZashiColors.Text.textPrimary, +) { + val normalizedStyle = style.copy(fontWeight = fontWeight) + val bulletString = remember { "\u2022 " } + val bulletTextMeasurer = rememberTextMeasurer() + val bulletStringWidth = + remember(normalizedStyle, bulletTextMeasurer) { + bulletTextMeasurer.measure(text = bulletString, style = normalizedStyle).size.width + } + val bulletRestLine = with(LocalDensity.current) { bulletStringWidth.toSp() } + val bulletParagraphStyle = ParagraphStyle(textIndent = TextIndent(restLine = bulletRestLine)) + Text( + modifier = modifier, + text = + buildAnnotatedString { + withStyle(style = bulletParagraphStyle) { + bulletText.forEachIndexed { index, string -> + if (index != 0) { + appendLine() + } + append(bulletString) + append(string) + } + } + }, + style = style, + fontWeight = fontWeight, + color = color, + ) +} diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiButton.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiButton.kt index 2419d7e1e..490f43f18 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiButton.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiButton.kt @@ -18,6 +18,7 @@ import androidx.compose.material3.LocalContentColor import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable +import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter @@ -31,6 +32,7 @@ import co.electriccoin.zcash.ui.design.R import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors +import co.electriccoin.zcash.ui.design.theme.colors.ZashiColorsInternal import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography import co.electriccoin.zcash.ui.design.util.StringResource import co.electriccoin.zcash.ui.design.util.getValue @@ -42,7 +44,7 @@ fun ZashiButton( style: TextStyle = ZashiButtonDefaults.style, shape: Shape = ZashiButtonDefaults.shape, contentPadding: PaddingValues = ZashiButtonDefaults.contentPadding, - colors: ZashiButtonColors = ZashiButtonDefaults.primaryColors(), + colors: ZashiButtonColors = LocalZashiButtonColors.current ?: ZashiButtonDefaults.primaryColors(), content: @Composable RowScope.(ZashiButtonScope) -> Unit = ZashiButtonDefaults.content ) { ZashiButton( @@ -74,7 +76,7 @@ fun ZashiButton( style: TextStyle = ZashiButtonDefaults.style, shape: Shape = ZashiButtonDefaults.shape, contentPadding: PaddingValues = ZashiButtonDefaults.contentPadding, - colors: ZashiButtonColors = ZashiButtonDefaults.primaryColors(), + colors: ZashiButtonColors = LocalZashiButtonColors.current ?: ZashiButtonDefaults.primaryColors(), content: @Composable RowScope.(ZashiButtonScope) -> Unit = ZashiButtonDefaults.content ) { val scope = @@ -180,10 +182,11 @@ object ZashiButtonDefaults { @Composable fun primaryColors( - containerColor: Color = ZashiColors.Btns.Primary.btnPrimaryBg, - contentColor: Color = ZashiColors.Btns.Primary.btnPrimaryFg, - disabledContainerColor: Color = ZashiColors.Btns.Primary.btnPrimaryBgDisabled, - disabledContentColor: Color = ZashiColors.Btns.Primary.btnBoldFgDisabled, + source: ZashiColorsInternal = ZashiColors, + containerColor: Color = source.Btns.Primary.btnPrimaryBg, + contentColor: Color = source.Btns.Primary.btnPrimaryFg, + disabledContainerColor: Color = source.Btns.Primary.btnPrimaryBgDisabled, + disabledContentColor: Color = source.Btns.Primary.btnBoldFgDisabled, ) = ZashiButtonColors( containerColor = containerColor, contentColor = contentColor, @@ -195,11 +198,12 @@ object ZashiButtonDefaults { @Composable fun secondaryColors( - containerColor: Color = ZashiColors.Btns.Secondary.btnSecondaryBg, - contentColor: Color = ZashiColors.Btns.Secondary.btnSecondaryFg, + source: ZashiColorsInternal = ZashiColors, + containerColor: Color = source.Btns.Secondary.btnSecondaryBg, + contentColor: Color = source.Btns.Secondary.btnSecondaryFg, borderColor: Color = Color.Unspecified, - disabledContainerColor: Color = ZashiColors.Btns.Secondary.btnSecondaryBgDisabled, - disabledContentColor: Color = ZashiColors.Btns.Secondary.btnSecondaryFg, + disabledContainerColor: Color = source.Btns.Secondary.btnSecondaryBgDisabled, + disabledContentColor: Color = source.Btns.Secondary.btnSecondaryFg, ) = ZashiButtonColors( containerColor = containerColor, contentColor = contentColor, @@ -211,10 +215,11 @@ object ZashiButtonDefaults { @Composable fun tertiaryColors( - containerColor: Color = ZashiColors.Btns.Tertiary.btnTertiaryBg, - contentColor: Color = ZashiColors.Btns.Tertiary.btnTertiaryFg, - disabledContainerColor: Color = ZashiColors.Btns.Tertiary.btnTertiaryBgDisabled, - disabledContentColor: Color = ZashiColors.Btns.Tertiary.btnTertiaryFgDisabled, + source: ZashiColorsInternal = ZashiColors, + containerColor: Color = source.Btns.Tertiary.btnTertiaryBg, + contentColor: Color = source.Btns.Tertiary.btnTertiaryFg, + disabledContainerColor: Color = source.Btns.Tertiary.btnTertiaryBgDisabled, + disabledContentColor: Color = source.Btns.Tertiary.btnTertiaryFgDisabled, ) = ZashiButtonColors( containerColor = containerColor, contentColor = contentColor, @@ -226,11 +231,12 @@ object ZashiButtonDefaults { @Composable fun destructive1Colors( - containerColor: Color = ZashiColors.Btns.Destructive1.btnDestroy1Bg, - contentColor: Color = ZashiColors.Btns.Destructive1.btnDestroy1Fg, - borderColor: Color = ZashiColors.Btns.Destructive1.btnDestroy1Border, - disabledContainerColor: Color = ZashiColors.Btns.Destructive1.btnDestroy1BgDisabled, - disabledContentColor: Color = ZashiColors.Btns.Destructive1.btnDestroy1FgDisabled, + source: ZashiColorsInternal = ZashiColors, + containerColor: Color = source.Btns.Destructive1.btnDestroy1Bg, + contentColor: Color = source.Btns.Destructive1.btnDestroy1Fg, + borderColor: Color = source.Btns.Destructive1.btnDestroy1Border, + disabledContainerColor: Color = source.Btns.Destructive1.btnDestroy1BgDisabled, + disabledContentColor: Color = source.Btns.Destructive1.btnDestroy1FgDisabled, ) = ZashiButtonColors( containerColor = containerColor, contentColor = contentColor, @@ -242,11 +248,12 @@ object ZashiButtonDefaults { @Composable fun destructive2Colors( - containerColor: Color = ZashiColors.Btns.Destructive2.btnDestroy2Bg, - contentColor: Color = ZashiColors.Btns.Destructive2.btnDestroy2Fg, + source: ZashiColorsInternal = ZashiColors, + containerColor: Color = source.Btns.Destructive2.btnDestroy2Bg, + contentColor: Color = source.Btns.Destructive2.btnDestroy2Fg, borderColor: Color = Color.Unspecified, - disabledContainerColor: Color = ZashiColors.Btns.Destructive2.btnDestroy2BgDisabled, - disabledContentColor: Color = ZashiColors.Btns.Destructive2.btnDestroy2FgDisabled, + disabledContainerColor: Color = source.Btns.Destructive2.btnDestroy2BgDisabled, + disabledContentColor: Color = source.Btns.Destructive2.btnDestroy2FgDisabled, ) = ZashiButtonColors( containerColor = containerColor, contentColor = contentColor, @@ -286,6 +293,12 @@ private fun ZashiButtonColors.toButtonColors() = disabledContentColor = disabledContentColor, ) +@Suppress("CompositionLocalAllowlist") +val LocalZashiButtonColors = + compositionLocalOf { + null + } + @PreviewScreens @Composable private fun PrimaryPreview() = diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiCard.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiCard.kt index 2206c712c..307bcedd5 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiCard.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiCard.kt @@ -1,18 +1,24 @@ package co.electriccoin.zcash.ui.design.component +import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.padding import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.isSpecified import androidx.compose.ui.unit.dp import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors @Composable fun ZashiCard( modifier: Modifier = Modifier, + borderColor: Color = Color.Unspecified, + contentPadding: PaddingValues = PaddingValues(24.dp), content: @Composable ColumnScope.() -> Unit, ) { Card( @@ -22,9 +28,15 @@ fun ZashiCard( containerColor = ZashiColors.Surfaces.bgSecondary, contentColor = ZashiColors.Text.textTertiary ), + border = + if (borderColor.isSpecified) { + BorderStroke(1.dp, borderColor) + } else { + null + } ) { Column( - Modifier.padding(24.dp) + Modifier.padding(contentPadding) ) { content() } diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiCircularProgressIndicator.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiCircularProgressIndicator.kt new file mode 100644 index 000000000..4ffabc87a --- /dev/null +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiCircularProgressIndicator.kt @@ -0,0 +1,71 @@ +package co.electriccoin.zcash.ui.design.component + +import androidx.annotation.IntRange +import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.ProgressIndicatorDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.compositionLocalOf +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors + +@Composable +fun ZashiCircularProgressIndicator( + progress: Float, + modifier: Modifier = Modifier, + colors: ZashiCircularProgressIndicatorColors = + LocalZashiCircularProgressIndicatorColors.current + ?: ZashiCircularProgressIndicatorDefaults.colors() +) { + val animatedProgress by animateFloatAsState( + progress, + animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec + ) + CircularProgressIndicator( + modifier = modifier, + color = colors.progressColor, + trackColor = colors.trackColor, + progress = { animatedProgress }, + gapSize = 0.dp, + strokeWidth = 3.dp + ) +} + +@Composable +fun ZashiCircularProgressIndicator( + @IntRange(from = 0, to = 100) progressPercent: Int, + modifier: Modifier = Modifier, + colors: ZashiCircularProgressIndicatorColors = + LocalZashiCircularProgressIndicatorColors.current + ?: ZashiCircularProgressIndicatorDefaults.colors() +) { + ZashiCircularProgressIndicator( + progress = progressPercent / 100f, + modifier = modifier, + colors = colors + ) +} + +@Immutable +data class ZashiCircularProgressIndicatorColors( + val progressColor: Color, + val trackColor: Color +) + +@Suppress("CompositionLocalAllowlist") +val LocalZashiCircularProgressIndicatorColors = compositionLocalOf { null } + +object ZashiCircularProgressIndicatorDefaults { + @Composable + fun colors( + progressColor: Color = ZashiColors.Utility.Purple.utilityPurple400, + trackColor: Color = ZashiColors.Utility.Purple.utilityPurple50 + ) = ZashiCircularProgressIndicatorColors( + progressColor = progressColor, + trackColor = trackColor + ) +} diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiInfoText.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiInfoText.kt new file mode 100644 index 000000000..d8d0d3d3f --- /dev/null +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiInfoText.kt @@ -0,0 +1,46 @@ +package co.electriccoin.zcash.ui.design.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Row +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import co.electriccoin.zcash.ui.design.R +import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors +import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography + +@Composable +fun ZashiInfoText( + text: String, + modifier: Modifier = Modifier, + color: Color = ZashiColors.Text.textTertiary, + style: TextStyle = ZashiTypography.textXs, + textAlign: TextAlign = TextAlign.Start, +) { + Row( + modifier = modifier, + ) { + Image( + modifier = Modifier, + painter = painterResource(R.drawable.ic_info), + contentDescription = null, + colorFilter = ColorFilter.tint(color) + ) + HorizontalSpacer(8.dp) + Text( + modifier = + Modifier + .weight(1f), + text = text, + textAlign = textAlign, + style = style, + color = color + ) + } +} diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiScreenModalBottomSheet.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiScreenModalBottomSheet.kt index b2bae7adc..449b96ce7 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiScreenModalBottomSheet.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiScreenModalBottomSheet.kt @@ -1,13 +1,25 @@ package co.electriccoin.zcash.ui.design.component +import android.view.WindowManager import androidx.activity.compose.BackHandler +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.systemBars +import androidx.compose.foundation.layout.windowInsetsBottomHeight import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SheetState import androidx.compose.material3.SheetValue +import androidx.compose.material3.SheetValue.Expanded import androidx.compose.material3.SheetValue.Hidden import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.platform.LocalView +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.DialogWindowProvider import co.electriccoin.zcash.ui.design.LocalSheetStateManager @OptIn(ExperimentalMaterial3Api::class) @@ -15,29 +27,64 @@ import co.electriccoin.zcash.ui.design.LocalSheetStateManager fun ZashiScreenModalBottomSheet( state: T?, sheetState: SheetState = rememberScreenModalBottomSheetState(), + content: @Composable (state: T) -> Unit = {}, +) { + val parent = LocalView.current.parent + SideEffect { + (parent as? DialogWindowProvider)?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) + (parent as? DialogWindowProvider)?.window?.setDimAmount(0f) + } + + state?.let { + ZashiModalBottomSheet( + sheetState = sheetState, + content = { + BackHandler { + it.onBack() + } + content(it) + Spacer(24.dp) + androidx.compose.foundation.layout.Spacer( + modifier = Modifier.windowInsetsBottomHeight(WindowInsets.systemBars), + ) + + LaunchedEffect(Unit) { + sheetState.show() + } + }, + onDismissRequest = it.onBack + ) + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ZashiScreenModalBottomSheet( + onDismissRequest: () -> Unit, + sheetState: SheetState = rememberScreenModalBottomSheetState(), content: @Composable () -> Unit = {}, ) { - ZashiModalBottomSheet( + ZashiScreenModalBottomSheet( + state = + remember(onDismissRequest) { + object : ModalBottomSheetState { + override val onBack: () -> Unit = { + onDismissRequest() + } + } + }, sheetState = sheetState, content = { - BackHandler(state != null) { - state?.onBack?.invoke() - } content() }, - onDismissRequest = { state?.onBack?.invoke() } ) - - LaunchedEffect(Unit) { - sheetState.show() - } } @Composable @ExperimentalMaterial3Api fun rememberScreenModalBottomSheetState( - initialValue: SheetValue = Hidden, - skipHiddenState: Boolean = false, + initialValue: SheetValue = if (LocalInspectionMode.current) Expanded else Hidden, + skipHiddenState: Boolean = LocalInspectionMode.current, skipPartiallyExpanded: Boolean = true, confirmValueChange: (SheetValue) -> Boolean = { true }, ): SheetState { diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiSpacer.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiSpacer.kt index ba9d960d5..5185480b3 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiSpacer.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiSpacer.kt @@ -10,21 +10,31 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.Dp @Composable -fun VerticalSpacer(height: Dp) { +fun ColumnScope.Spacer(height: Dp) { Spacer(Modifier.height(height)) } @Composable -fun ColumnScope.VerticalSpacer(weight: Float) { +fun ColumnScope.Spacer(weight: Float) { Spacer(Modifier.weight(weight)) } @Composable -fun RowScope.VerticalSpacer(weight: Float) { +fun RowScope.Spacer(weight: Float) { Spacer(Modifier.weight(weight)) } +@Composable +fun RowScope.Spacer(width: Dp) { + Spacer(Modifier.width(width)) +} + @Composable fun HorizontalSpacer(width: Dp) { Spacer(Modifier.width(width)) } + +@Composable +fun VerticalSpacer(height: Dp) { + Spacer(Modifier.height(height)) +} diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/DarkZashiColors.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/DarkZashiColors.kt index 2669f34e6..d738d5fa2 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/DarkZashiColors.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/DarkZashiColors.kt @@ -28,7 +28,8 @@ val DarkZashiColorsInternal = textError = ErrorRed.`300`, textLink = HyperBlue.`300`, textLight = Shark.`50`, - textLightSupport = Shark.`200` + textLightSupport = Shark.`200`, + textOpposite = Base.Bone ), Btns = Btns( @@ -543,7 +544,8 @@ val DarkZashiColorsInternal = utilityPurple50 = Purple.`950`, utilityPurple100 = Purple.`900`, utilityPurple400 = Purple.`600`, - utilityPurple300 = Purple.`700` + utilityPurple300 = Purple.`700`, + utilityPurple900 = Purple.`50` ), Espresso = UtilityEspresso( @@ -555,8 +557,9 @@ val DarkZashiColorsInternal = utilityEspresso100 = Espresso.`900`, utilityEspresso400 = Espresso.`500`, utilityEspresso300 = Espresso.`600`, + utilityEspresso800 = Espresso.`100`, utilityEspresso900 = Espresso.`50`, - utilityEspresso800 = Espresso.`100` + utilityEspresso950 = Espresso.`25` ) ), Transparent = diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/LightZashiColors.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/LightZashiColors.kt index 1ef3d5a31..993c76bb5 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/LightZashiColors.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/LightZashiColors.kt @@ -28,7 +28,8 @@ val LightZashiColorsInternal = textError = ErrorRed.`500`, textLink = HyperBlue.`500`, textLight = Gray.`25`, - textLightSupport = Gray.`200` + textLightSupport = Gray.`200`, + textOpposite = Base.Bone ), Btns = Btns( @@ -543,7 +544,8 @@ val LightZashiColorsInternal = utilityPurple50 = Purple.`50`, utilityPurple100 = Purple.`100`, utilityPurple400 = Purple.`400`, - utilityPurple300 = Purple.`300` + utilityPurple300 = Purple.`300`, + utilityPurple900 = Purple.`900` ), Espresso = UtilityEspresso( @@ -556,7 +558,8 @@ val LightZashiColorsInternal = utilityEspresso400 = Espresso.`400`, utilityEspresso300 = Espresso.`300`, utilityEspresso900 = Espresso.`900`, - utilityEspresso800 = Espresso.`800` + utilityEspresso800 = Espresso.`800`, + utilityEspresso950 = Espresso.`950` ) ), Transparent = diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/ZashiColorPalette.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/ZashiColorPalette.kt index c096dc887..ac5cdeca0 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/ZashiColorPalette.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/ZashiColorPalette.kt @@ -145,7 +145,7 @@ internal object Indigo { val `950` = Color(0xFF1F235B) } -internal object Purple { +object Purple { val `25` = Color(0xFFFAFAFF) val `50` = Color(0xFFF4F3FF) val `100` = Color(0xFFEBE9FE) diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/ZashiColors.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/ZashiColors.kt index c651c2bcf..d4edf7b7c 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/ZashiColors.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/ZashiColors.kt @@ -8,5 +8,17 @@ import androidx.compose.runtime.staticCompositionLocalOf val ZashiColors: ZashiColorsInternal @Composable get() = LocalZashiColors.current +val ZashiLightColors: ZashiColorsInternal + @Composable get() = LocalLightZashiColors.current + +val ZashiDarkColors: ZashiColorsInternal + @Composable get() = LocalDarkZashiColors.current + @Suppress("CompositionLocalAllowlist") internal val LocalZashiColors = staticCompositionLocalOf { error("no colors specified") } + +@Suppress("CompositionLocalAllowlist") +internal val LocalLightZashiColors = staticCompositionLocalOf { LightZashiColorsInternal } + +@Suppress("CompositionLocalAllowlist") +internal val LocalDarkZashiColors = staticCompositionLocalOf { DarkZashiColorsInternal } diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/ZashiColorsInternal.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/ZashiColorsInternal.kt index 0b2253202..3305dea8b 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/ZashiColorsInternal.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/colors/ZashiColorsInternal.kt @@ -56,7 +56,8 @@ data class Text( val textError: Color, val textLink: Color, val textLight: Color, - val textLightSupport: Color + val textLightSupport: Color, + val textOpposite: Color ) @Immutable @@ -647,7 +648,8 @@ data class UtilityPurple( val utilityPurple50: Color, val utilityPurple100: Color, val utilityPurple400: Color, - val utilityPurple300: Color + val utilityPurple300: Color, + val utilityPurple900: Color ) @Immutable @@ -661,6 +663,7 @@ data class UtilityEspresso( val utilityEspresso400: Color, val utilityEspresso300: Color, val utilityEspresso900: Color, + val utilityEspresso950: Color, val utilityEspresso800: Color ) diff --git a/ui-lib/src/main/res/ui/common/drawable-night/ic_info.xml b/ui-design-lib/src/main/res/ui/common/drawable-night/ic_info.xml similarity index 100% rename from ui-lib/src/main/res/ui/common/drawable-night/ic_info.xml rename to ui-design-lib/src/main/res/ui/common/drawable-night/ic_info.xml diff --git a/ui-lib/src/main/res/ui/common/drawable/ic_info.xml b/ui-design-lib/src/main/res/ui/common/drawable/ic_info.xml similarity index 100% rename from ui-lib/src/main/res/ui/common/drawable/ic_info.xml rename to ui-design-lib/src/main/res/ui/common/drawable/ic_info.xml diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/di/ViewModelModule.kt b/ui-lib/src/main/java/co/electriccoin/zcash/di/ViewModelModule.kt index 3a10ad105..80fa808b1 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/di/ViewModelModule.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/di/ViewModelModule.kt @@ -15,6 +15,7 @@ import co.electriccoin.zcash.ui.screen.contact.viewmodel.UpdateContactViewModel import co.electriccoin.zcash.ui.screen.feedback.viewmodel.FeedbackViewModel import co.electriccoin.zcash.ui.screen.flexa.FlexaViewModel import co.electriccoin.zcash.ui.screen.home.HomeViewModel +import co.electriccoin.zcash.ui.screen.home.balance.TransparentBalanceInfoViewModel import co.electriccoin.zcash.ui.screen.integrations.IntegrationsViewModel import co.electriccoin.zcash.ui.screen.qrcode.viewmodel.QrCodeViewModel import co.electriccoin.zcash.ui.screen.receive.viewmodel.ReceiveViewModel @@ -142,4 +143,5 @@ val viewModelModule = viewModelOf(::RestoreBDHeightViewModel) viewModelOf(::RestoreBDDateViewModel) viewModelOf(::RestoreBDEstimationViewModel) + viewModelOf(::TransparentBalanceInfoViewModel) } 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 1b3280182..59e1129fd 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 @@ -26,13 +26,11 @@ import co.electriccoin.zcash.ui.NavigationTargets.ABOUT import co.electriccoin.zcash.ui.NavigationTargets.ADVANCED_SETTINGS import co.electriccoin.zcash.ui.NavigationTargets.CHOOSE_SERVER import co.electriccoin.zcash.ui.NavigationTargets.DELETE_WALLET -import co.electriccoin.zcash.ui.NavigationTargets.EXCHANGE_RATE_OPT_IN import co.electriccoin.zcash.ui.NavigationTargets.EXPORT_PRIVATE_DATA import co.electriccoin.zcash.ui.NavigationTargets.NOT_ENOUGH_SPACE import co.electriccoin.zcash.ui.NavigationTargets.QR_CODE import co.electriccoin.zcash.ui.NavigationTargets.REQUEST import co.electriccoin.zcash.ui.NavigationTargets.SETTINGS -import co.electriccoin.zcash.ui.NavigationTargets.SETTINGS_EXCHANGE_RATE_OPT_IN import co.electriccoin.zcash.ui.NavigationTargets.SUPPORT import co.electriccoin.zcash.ui.NavigationTargets.WHATS_NEW import co.electriccoin.zcash.ui.common.compose.LocalNavController @@ -62,12 +60,26 @@ import co.electriccoin.zcash.ui.screen.contact.WrapUpdateContact import co.electriccoin.zcash.ui.screen.deletewallet.WrapDeleteWallet import co.electriccoin.zcash.ui.screen.disconnected.WrapDisconnected import co.electriccoin.zcash.ui.screen.exchangerate.optin.AndroidExchangeRateOptIn -import co.electriccoin.zcash.ui.screen.exchangerate.settings.AndroidSettingsExchangeRateOptIn +import co.electriccoin.zcash.ui.screen.exchangerate.optin.ExchangeRateOptIn +import co.electriccoin.zcash.ui.screen.exchangerate.settings.AndroidExchangeRateSettings +import co.electriccoin.zcash.ui.screen.exchangerate.settings.ExchangeRateSettings import co.electriccoin.zcash.ui.screen.exportdata.WrapExportPrivateData import co.electriccoin.zcash.ui.screen.feedback.WrapFeedback import co.electriccoin.zcash.ui.screen.flexa.FlexaViewModel import co.electriccoin.zcash.ui.screen.home.AndroidHome +import co.electriccoin.zcash.ui.screen.home.AndroidSeedBackupInfo +import co.electriccoin.zcash.ui.screen.home.AndroidWalletDisconnectedInfo +import co.electriccoin.zcash.ui.screen.home.AndroidWalletRestoringInfo +import co.electriccoin.zcash.ui.screen.home.AndroidWalletSyncingInfo +import co.electriccoin.zcash.ui.screen.home.AndroidWalletUpdatingInfo import co.electriccoin.zcash.ui.screen.home.Home +import co.electriccoin.zcash.ui.screen.home.SeedBackupInfo +import co.electriccoin.zcash.ui.screen.home.WalletDisconnectedInfo +import co.electriccoin.zcash.ui.screen.home.WalletRestoringInfo +import co.electriccoin.zcash.ui.screen.home.WalletSyncingInfo +import co.electriccoin.zcash.ui.screen.home.WalletUpdatingInfo +import co.electriccoin.zcash.ui.screen.home.balance.AndroidTransparentBalanceInfo +import co.electriccoin.zcash.ui.screen.home.balance.TransparentBalanceInfo import co.electriccoin.zcash.ui.screen.integrations.AndroidDialogIntegrations import co.electriccoin.zcash.ui.screen.integrations.AndroidIntegrations import co.electriccoin.zcash.ui.screen.integrations.DialogIntegrations @@ -248,11 +260,11 @@ internal fun MainActivity.Navigation() { dialog { AndroidDialogIntegrations() } - composable(EXCHANGE_RATE_OPT_IN) { + composable { AndroidExchangeRateOptIn() } - composable(SETTINGS_EXCHANGE_RATE_OPT_IN) { - AndroidSettingsExchangeRateOptIn() + composable { + AndroidExchangeRateSettings() } composable { WrapScanKeystoneSignInRequest() @@ -399,7 +411,61 @@ internal fun MainActivity.Navigation() { AndroidSeedInfo() } composable { - AndroidSeedBackup() + AndroidSeedBackup(it.toRoute()) + } + dialog( + dialogProperties = + DialogProperties( + dismissOnBackPress = false, + dismissOnClickOutside = false + ) + ) { + AndroidSeedBackupInfo() + } + dialog( + dialogProperties = + DialogProperties( + dismissOnBackPress = false, + dismissOnClickOutside = false + ) + ) { + AndroidTransparentBalanceInfo() + } + dialog( + dialogProperties = + DialogProperties( + dismissOnBackPress = false, + dismissOnClickOutside = false + ) + ) { + AndroidWalletDisconnectedInfo() + } + dialog( + dialogProperties = + DialogProperties( + dismissOnBackPress = false, + dismissOnClickOutside = false + ) + ) { + AndroidWalletRestoringInfo() + } + dialog( + dialogProperties = + DialogProperties( + dismissOnBackPress = false, + dismissOnClickOutside = false + ) + ) { + AndroidWalletSyncingInfo() + } + dialog( + dialogProperties = + DialogProperties( + dismissOnBackPress = false, + dismissOnClickOutside = false + ) + ) { + AndroidWalletUpdatingInfo() } } } @@ -524,14 +590,12 @@ object NavigationTargets { const val ABOUT = "about" const val ADVANCED_SETTINGS = "advanced_settings" const val DELETE_WALLET = "delete_wallet" - const val EXCHANGE_RATE_OPT_IN = "exchange_rate_opt_in" const val EXPORT_PRIVATE_DATA = "export_private_data" const val CHOOSE_SERVER = "choose_server" const val NOT_ENOUGH_SPACE = "not_enough_space" const val QR_CODE = "qr_code" const val REQUEST = "request" const val SETTINGS = "settings" - const val SETTINGS_EXCHANGE_RATE_OPT_IN = "settings_exchange_rate_opt_in" const val SUPPORT = "support" const val WHATS_NEW = "whats_new" } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/repository/ExchangeRateRepository.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/repository/ExchangeRateRepository.kt index 54d4861f8..8aae89f22 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/repository/ExchangeRateRepository.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/repository/ExchangeRateRepository.kt @@ -6,12 +6,12 @@ import co.electriccoin.zcash.preference.StandardPreferenceProvider import co.electriccoin.zcash.preference.model.entry.NullableBooleanPreferenceDefault import co.electriccoin.zcash.spackle.Twig import co.electriccoin.zcash.ui.NavigationRouter -import co.electriccoin.zcash.ui.NavigationTargets.EXCHANGE_RATE_OPT_IN import co.electriccoin.zcash.ui.common.provider.SynchronizerProvider import co.electriccoin.zcash.ui.common.wallet.ExchangeRateState import co.electriccoin.zcash.ui.common.wallet.RefreshLock import co.electriccoin.zcash.ui.common.wallet.StaleLock import co.electriccoin.zcash.ui.preference.StandardPreferenceKeys +import co.electriccoin.zcash.ui.screen.exchangerate.optin.ExchangeRateOptIn import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -204,7 +204,7 @@ class ExchangeRateRepositoryImpl( setNullableBooleanPreference(StandardPreferenceKeys.EXCHANGE_RATE_OPTED_IN, false) } - private fun showOptInExchangeRateUsd() = navigationRouter.forward(EXCHANGE_RATE_OPT_IN) + private fun showOptInExchangeRateUsd() = navigationRouter.forward(ExchangeRateOptIn) private fun nullableBooleanStateFlow(default: NullableBooleanPreferenceDefault): StateFlow = flow { diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/viewmodel/WalletViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/viewmodel/WalletViewModel.kt index da9ab7d40..0b6b0e00f 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/viewmodel/WalletViewModel.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/viewmodel/WalletViewModel.kt @@ -13,6 +13,7 @@ import cash.z.ecc.android.sdk.model.ZcashNetwork import cash.z.ecc.sdk.type.fromResources import co.electriccoin.zcash.preference.StandardPreferenceProvider import co.electriccoin.zcash.spackle.Twig +import co.electriccoin.zcash.ui.NavigationRouter import co.electriccoin.zcash.ui.common.model.OnboardingState import co.electriccoin.zcash.ui.common.model.WalletRestoringState import co.electriccoin.zcash.ui.common.model.WalletSnapshot @@ -50,6 +51,7 @@ class WalletViewModel( private val resetSharedPrefsData: ResetSharedPrefsDataUseCase, private val isFlexaAvailable: IsFlexaAvailableUseCase, private val getSynchronizer: GetSynchronizerUseCase, + private val navigationRouter: NavigationRouter, ) : AndroidViewModel(application) { val synchronizer = walletRepository.synchronizer @@ -68,7 +70,11 @@ class WalletViewModel( } fun dismissOptInExchangeRateUsd() { - exchangeRateRepository.dismissOptInExchangeRateUsd() + navigationRouter.back() + } + + fun onSkipClick() { + navigationRouter.back() } fun persistNewWalletAndRestoringState(state: WalletRestoringState) { diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/AndroidAccountList.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/AndroidAccountList.kt index 5ad2019c4..ee5b47031 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/AndroidAccountList.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/AndroidAccountList.kt @@ -1,12 +1,8 @@ package co.electriccoin.zcash.ui.screen.accountlist -import android.view.WindowManager import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue -import androidx.compose.ui.platform.LocalView -import androidx.compose.ui.window.DialogWindowProvider import androidx.lifecycle.compose.collectAsStateWithLifecycle import co.electriccoin.zcash.ui.screen.accountlist.view.AccountListView import co.electriccoin.zcash.ui.screen.accountlist.viewmodel.AccountListViewModel @@ -17,12 +13,5 @@ import org.koin.androidx.compose.koinViewModel fun AndroidAccountList() { val viewModel = koinViewModel() val state by viewModel.state.collectAsStateWithLifecycle() - val parent = LocalView.current.parent - SideEffect { - (parent as? DialogWindowProvider)?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) - (parent as? DialogWindowProvider)?.window?.setDimAmount(0f) - } - state?.let { - AccountListView(it) - } + AccountListView(state) } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/view/AccountListView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/view/AccountListView.kt index f9c984afc..5d4e55cd9 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/view/AccountListView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/view/AccountListView.kt @@ -7,12 +7,9 @@ import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.systemBars -import androidx.compose.foundation.layout.windowInsetsBottomHeight import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ExperimentalMaterial3Api @@ -55,14 +52,14 @@ import kotlinx.collections.immutable.persistentListOf @Composable @OptIn(ExperimentalMaterial3Api::class) internal fun AccountListView( - state: AccountListState, + state: AccountListState?, sheetState: SheetState = rememberScreenModalBottomSheetState(), ) { ZashiScreenModalBottomSheet( state = state, sheetState = sheetState, content = { - BottomSheetContent(state) + BottomSheetContent(it) }, ) } @@ -121,8 +118,6 @@ private fun BottomSheetContent(state: AccountListState) { ) ) } - Spacer(modifier = Modifier.height(24.dp)) - Spacer(modifier = Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/advancedsettings/AdvancedSettingsViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/advancedsettings/AdvancedSettingsViewModel.kt index c1ddea9c0..f61af2d44 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/advancedsettings/AdvancedSettingsViewModel.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/advancedsettings/AdvancedSettingsViewModel.kt @@ -13,6 +13,7 @@ import co.electriccoin.zcash.ui.common.usecase.NavigateToTaxExportUseCase import co.electriccoin.zcash.ui.design.component.ButtonState import co.electriccoin.zcash.ui.design.component.listitem.ZashiListItemState import co.electriccoin.zcash.ui.design.util.stringRes +import co.electriccoin.zcash.ui.screen.exchangerate.optin.ExchangeRateOptIn import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -88,7 +89,7 @@ class AdvancedSettingsViewModel( private fun onChooseServerClick() = navigationRouter.forward(NavigationTargets.CHOOSE_SERVER) - private fun onCurrencyConversionClick() = navigationRouter.forward(NavigationTargets.SETTINGS_EXCHANGE_RATE_OPT_IN) + private fun onCurrencyConversionClick() = navigationRouter.forward(ExchangeRateOptIn) private fun onTaxExportClick() = viewModelScope.launch { diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/optin/AndroidExchangeRateOptIn.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/optin/AndroidExchangeRateOptIn.kt index 70f70e62b..25ab78e85 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/optin/AndroidExchangeRateOptIn.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/optin/AndroidExchangeRateOptIn.kt @@ -5,6 +5,7 @@ import androidx.activity.viewModels import androidx.compose.runtime.Composable import co.electriccoin.zcash.ui.common.compose.LocalActivity import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel +import kotlinx.serialization.Serializable @Composable fun AndroidExchangeRateOptIn() { @@ -16,7 +17,11 @@ fun AndroidExchangeRateOptIn() { } ExchangeRateOptIn( - onEnabledClick = { walletViewModel.optInExchangeRateUsd(true) }, - onDismiss = { walletViewModel.dismissOptInExchangeRateUsd() } + onEnableClick = { walletViewModel.optInExchangeRateUsd(true) }, + onDismiss = { walletViewModel.dismissOptInExchangeRateUsd() }, + onSkipClick = { walletViewModel.onSkipClick() } ) } + +@Serializable +object ExchangeRateOptIn diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/optin/ExchangeRateOptIn.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/optin/ExchangeRateOptIn.kt index 57cd639f5..3694b31a7 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/optin/ExchangeRateOptIn.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/optin/ExchangeRateOptIn.kt @@ -30,7 +30,8 @@ import co.electriccoin.zcash.ui.screen.exchangerate.BaseExchangeRateOptIn @Composable fun ExchangeRateOptIn( - onEnabledClick: () -> Unit, + onEnableClick: () -> Unit, + onSkipClick: () -> Unit, onDismiss: () -> Unit, ) { BaseExchangeRateOptIn( @@ -58,15 +59,9 @@ fun ExchangeRateOptIn( ) }, footer = { - ZashiButton( - modifier = Modifier.fillMaxWidth(), - text = stringResource(R.string.exchange_rate_opt_in_enable), - onClick = onEnabledClick, - colors = ZashiButtonDefaults.primaryColors() - ) ZashiTextButton( modifier = Modifier.fillMaxWidth(), - onClick = onDismiss, + onClick = onSkipClick, ) { Text( text = stringResource(R.string.exchange_rate_opt_in_skip), @@ -74,6 +69,12 @@ fun ExchangeRateOptIn( fontWeight = FontWeight.SemiBold ) } + ZashiButton( + modifier = Modifier.fillMaxWidth(), + text = stringResource(R.string.exchange_rate_opt_in_enable), + onClick = onEnableClick, + colors = ZashiButtonDefaults.primaryColors() + ) } ) } @@ -117,6 +118,6 @@ private fun InfoItem( private fun CurrencyConversionOptInPreview() = ZcashTheme { BlankSurface { - ExchangeRateOptIn(onEnabledClick = {}, onDismiss = {}) + ExchangeRateOptIn(onEnableClick = {}, onDismiss = {}, onSkipClick = {}) } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/settings/AndroidSettingsExchangeRateOptIn.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/settings/AndroidExchangeRateSettings.kt similarity index 86% rename from ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/settings/AndroidSettingsExchangeRateOptIn.kt rename to ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/settings/AndroidExchangeRateSettings.kt index acde33b2a..e8154a8d5 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/settings/AndroidSettingsExchangeRateOptIn.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/settings/AndroidExchangeRateSettings.kt @@ -7,9 +7,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import co.electriccoin.zcash.ui.common.compose.LocalActivity import co.electriccoin.zcash.ui.common.compose.LocalNavController import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel +import kotlinx.serialization.Serializable @Composable -fun AndroidSettingsExchangeRateOptIn() { +fun AndroidExchangeRateSettings() { val activity = LocalActivity.current val navController = LocalNavController.current val walletViewModel by activity.viewModels() @@ -19,9 +20,12 @@ fun AndroidSettingsExchangeRateOptIn() { navController.popBackStack() } - SettingsExchangeRateOptIn( + ExchangeRateSettings( isOptedIn = isOptedIn, onSaveClick = { walletViewModel.optInExchangeRateUsd(it) }, onDismiss = { navController.popBackStack() } ) } + +@Serializable +object ExchangeRateSettings diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/settings/SettingsExchangeRateOptIn.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/settings/ExchangeRateSettings.kt similarity index 98% rename from ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/settings/SettingsExchangeRateOptIn.kt rename to ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/settings/ExchangeRateSettings.kt index 25bea385a..23b094c43 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/settings/SettingsExchangeRateOptIn.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/exchangerate/settings/ExchangeRateSettings.kt @@ -37,7 +37,7 @@ import co.electriccoin.zcash.ui.screen.exchangerate.BaseExchangeRateOptIn import co.electriccoin.zcash.ui.screen.exchangerate.SecondaryCard @Composable -fun SettingsExchangeRateOptIn( +fun ExchangeRateSettings( isOptedIn: Boolean, onDismiss: () -> Unit, onSaveClick: (Boolean) -> Unit @@ -187,6 +187,6 @@ private val Unchecked: Int private fun SettingsExchangeRateOptInPreview() = ZcashTheme { BlankSurface { - SettingsExchangeRateOptIn(isOptedIn = true, onDismiss = {}, onSaveClick = {}) + ExchangeRateSettings(isOptedIn = true, onDismiss = {}, onSaveClick = {}) } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidSeedBackupInfo.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidSeedBackupInfo.kt new file mode 100644 index 000000000..c0069dfac --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidSeedBackupInfo.kt @@ -0,0 +1,136 @@ +package co.electriccoin.zcash.ui.screen.home + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.SheetState +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import co.electriccoin.zcash.ui.NavigationRouter +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.design.component.ButtonState +import co.electriccoin.zcash.ui.design.component.Spacer +import co.electriccoin.zcash.ui.design.component.ZashiBulletText +import co.electriccoin.zcash.ui.design.component.ZashiButton +import co.electriccoin.zcash.ui.design.component.ZashiButtonDefaults +import co.electriccoin.zcash.ui.design.component.ZashiScreenModalBottomSheet +import co.electriccoin.zcash.ui.design.component.rememberScreenModalBottomSheetState +import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens +import co.electriccoin.zcash.ui.design.theme.ZcashTheme +import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors +import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography +import co.electriccoin.zcash.ui.design.util.stringRes +import co.electriccoin.zcash.ui.screen.seed.backup.SeedBackup +import kotlinx.serialization.Serializable +import org.koin.compose.koinInject + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AndroidSeedBackupInfo() { + val navigationRouter = koinInject() + Content( + onBack = { navigationRouter.back() }, + onPositiveClick = { navigationRouter.replace(SeedBackup(true)) } + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun Content( + onBack: () -> Unit, + onPositiveClick: () -> Unit, + sheetState: SheetState = rememberScreenModalBottomSheetState(), +) { + ZashiScreenModalBottomSheet( + sheetState = sheetState, + onDismissRequest = onBack + ) { + Column( + modifier = + Modifier + .padding(horizontal = 24.dp) + ) { + Image( + painter = painterResource(R.drawable.ic_info_backup), + contentDescription = null + ) + Spacer(12.dp) + Text( + stringResource(R.string.home_info_backup_title), + color = ZashiColors.Text.textPrimary, + style = ZashiTypography.textXl, + fontWeight = FontWeight.SemiBold + ) + Spacer(12.dp) + Text( + stringResource(R.string.home_info_backup_subtitle_1), + color = ZashiColors.Text.textTertiary, + style = ZashiTypography.textMd + ) + Spacer(12.dp) + Text( + stringResource(R.string.home_info_backup_subtitle_2), + color = ZashiColors.Text.textTertiary, + style = ZashiTypography.textMd + ) + Spacer(12.dp) + ZashiBulletText( + stringResource(R.string.home_info_backup_bullet_1), + stringResource(R.string.home_info_backup_bullet_2), + color = ZashiColors.Text.textTertiary + ) + Spacer(12.dp) + Text( + stringResource(R.string.home_info_backup_message_1), + color = ZashiColors.Text.textTertiary, + style = ZashiTypography.textMd + ) + Spacer(24.dp) + Text( + stringResource(R.string.home_info_backup_message_2), + color = ZashiColors.Text.textTertiary, + style = ZashiTypography.textMd + ) + Spacer(32.dp) + ZashiButton( + modifier = Modifier.fillMaxWidth(), + state = + ButtonState( + text = stringRes(R.string.general_remind_me_later), + onClick = onBack + ), + colors = ZashiButtonDefaults.secondaryColors() + ) + Spacer(4.dp) + ZashiButton( + modifier = Modifier.fillMaxWidth(), + state = + ButtonState( + text = stringRes(R.string.general_ok), + onClick = onPositiveClick + ) + ) + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + Content( + onBack = {}, + onPositiveClick = {} + ) + } + +@Serializable +object SeedBackupInfo diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidWalletDisconnectedInfo.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidWalletDisconnectedInfo.kt new file mode 100644 index 000000000..831e742cc --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidWalletDisconnectedInfo.kt @@ -0,0 +1,96 @@ +package co.electriccoin.zcash.ui.screen.home + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.SheetState +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import co.electriccoin.zcash.ui.NavigationRouter +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.design.component.ButtonState +import co.electriccoin.zcash.ui.design.component.Spacer +import co.electriccoin.zcash.ui.design.component.ZashiButton +import co.electriccoin.zcash.ui.design.component.ZashiScreenModalBottomSheet +import co.electriccoin.zcash.ui.design.component.rememberScreenModalBottomSheetState +import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens +import co.electriccoin.zcash.ui.design.theme.ZcashTheme +import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors +import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography +import co.electriccoin.zcash.ui.design.util.stringRes +import kotlinx.serialization.Serializable +import org.koin.compose.koinInject + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AndroidWalletDisconnectedInfo() { + val navigationRouter = koinInject() + Content( + onBack = { navigationRouter.back() } + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun Content( + onBack: () -> Unit, + sheetState: SheetState = rememberScreenModalBottomSheetState(), +) { + ZashiScreenModalBottomSheet( + sheetState = sheetState, + onDismissRequest = onBack + ) { + Column( + modifier = + Modifier + .padding(horizontal = 24.dp) + ) { + Image( + painter = painterResource(R.drawable.ic_info_wallet_disconnected), + contentDescription = null + ) + Spacer(12.dp) + Text( + stringResource(R.string.home_info_disconnected_title), + color = ZashiColors.Text.textPrimary, + style = ZashiTypography.textXl, + fontWeight = FontWeight.SemiBold + ) + Spacer(12.dp) + Text( + stringResource(R.string.home_info_disconnected_subtitle), + color = ZashiColors.Text.textTertiary, + style = ZashiTypography.textMd + ) + Spacer(32.dp) + ZashiButton( + modifier = Modifier.fillMaxWidth(), + state = + ButtonState( + text = stringRes(R.string.general_ok), + onClick = onBack + ) + ) + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + Content( + onBack = {}, + ) + } + +@Serializable +object WalletDisconnectedInfo diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidWalletRestoringInfo.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidWalletRestoringInfo.kt new file mode 100644 index 000000000..013f49f8d --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidWalletRestoringInfo.kt @@ -0,0 +1,101 @@ +package co.electriccoin.zcash.ui.screen.home + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.SheetState +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import co.electriccoin.zcash.ui.NavigationRouter +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.design.component.ButtonState +import co.electriccoin.zcash.ui.design.component.Spacer +import co.electriccoin.zcash.ui.design.component.ZashiBulletText +import co.electriccoin.zcash.ui.design.component.ZashiButton +import co.electriccoin.zcash.ui.design.component.ZashiInfoText +import co.electriccoin.zcash.ui.design.component.ZashiScreenModalBottomSheet +import co.electriccoin.zcash.ui.design.component.rememberScreenModalBottomSheetState +import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens +import co.electriccoin.zcash.ui.design.theme.ZcashTheme +import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors +import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography +import co.electriccoin.zcash.ui.design.util.stringRes +import kotlinx.serialization.Serializable +import org.koin.compose.koinInject + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AndroidWalletRestoringInfo() { + val navigationRouter = koinInject() + Content( + onBack = { navigationRouter.back() } + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun Content( + onBack: () -> Unit, + sheetState: SheetState = rememberScreenModalBottomSheetState(), +) { + ZashiScreenModalBottomSheet( + sheetState = sheetState, + onDismissRequest = onBack + ) { + Column( + modifier = + Modifier + .padding(horizontal = 24.dp) + ) { + Text( + stringResource(R.string.home_info_restoring_title), + color = ZashiColors.Text.textPrimary, + style = ZashiTypography.textXl, + fontWeight = FontWeight.SemiBold + ) + Spacer(12.dp) + Text( + stringResource(R.string.home_info_restoring_message), + color = ZashiColors.Text.textTertiary, + style = ZashiTypography.textMd + ) + Spacer(12.dp) + ZashiBulletText( + stringResource(R.string.home_info_restoring_bullet_1), + stringResource(R.string.home_info_restoring_bullet_2), + color = ZashiColors.Text.textTertiary + ) + Spacer(32.dp) + ZashiInfoText( + stringResource(R.string.home_info_restoring_note), + ) + Spacer(24.dp) + ZashiButton( + modifier = Modifier.fillMaxWidth(), + state = + ButtonState( + text = stringRes(R.string.general_ok), + onClick = onBack + ) + ) + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + Content( + onBack = {}, + ) + } + +@Serializable +object WalletRestoringInfo diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidWalletSyncingInfo.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidWalletSyncingInfo.kt new file mode 100644 index 000000000..7fc94ffb6 --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidWalletSyncingInfo.kt @@ -0,0 +1,89 @@ +package co.electriccoin.zcash.ui.screen.home + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.SheetState +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import co.electriccoin.zcash.ui.NavigationRouter +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.design.component.ButtonState +import co.electriccoin.zcash.ui.design.component.Spacer +import co.electriccoin.zcash.ui.design.component.ZashiButton +import co.electriccoin.zcash.ui.design.component.ZashiScreenModalBottomSheet +import co.electriccoin.zcash.ui.design.component.rememberScreenModalBottomSheetState +import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens +import co.electriccoin.zcash.ui.design.theme.ZcashTheme +import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors +import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography +import co.electriccoin.zcash.ui.design.util.stringRes +import kotlinx.serialization.Serializable +import org.koin.compose.koinInject + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AndroidWalletSyncingInfo() { + val navigationRouter = koinInject() + Content( + onBack = { navigationRouter.back() } + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun Content( + onBack: () -> Unit, + sheetState: SheetState = rememberScreenModalBottomSheetState(), +) { + ZashiScreenModalBottomSheet( + sheetState = sheetState, + onDismissRequest = onBack + ) { + Column( + modifier = + Modifier + .padding(horizontal = 24.dp) + ) { + Text( + stringResource(R.string.home_info_syncing_title), + color = ZashiColors.Text.textPrimary, + style = ZashiTypography.textXl, + fontWeight = FontWeight.SemiBold + ) + Spacer(12.dp) + Text( + stringResource(R.string.home_info_syncing_message), + color = ZashiColors.Text.textTertiary, + style = ZashiTypography.textMd + ) + Spacer(32.dp) + ZashiButton( + modifier = Modifier.fillMaxWidth(), + state = + ButtonState( + text = stringRes(R.string.general_ok), + onClick = onBack + ) + ) + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + Content( + onBack = {}, + ) + } + +@Serializable +object WalletSyncingInfo diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidWalletUpdatingInfo.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidWalletUpdatingInfo.kt new file mode 100644 index 000000000..3358f4045 --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidWalletUpdatingInfo.kt @@ -0,0 +1,89 @@ +package co.electriccoin.zcash.ui.screen.home + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.SheetState +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import co.electriccoin.zcash.ui.NavigationRouter +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.design.component.ButtonState +import co.electriccoin.zcash.ui.design.component.Spacer +import co.electriccoin.zcash.ui.design.component.ZashiButton +import co.electriccoin.zcash.ui.design.component.ZashiScreenModalBottomSheet +import co.electriccoin.zcash.ui.design.component.rememberScreenModalBottomSheetState +import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens +import co.electriccoin.zcash.ui.design.theme.ZcashTheme +import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors +import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography +import co.electriccoin.zcash.ui.design.util.stringRes +import kotlinx.serialization.Serializable +import org.koin.compose.koinInject + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AndroidWalletUpdatingInfo() { + val navigationRouter = koinInject() + Content( + onBack = { navigationRouter.back() } + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun Content( + onBack: () -> Unit, + sheetState: SheetState = rememberScreenModalBottomSheetState(), +) { + ZashiScreenModalBottomSheet( + sheetState = sheetState, + onDismissRequest = onBack + ) { + Column( + modifier = + Modifier + .padding(horizontal = 24.dp) + ) { + Text( + stringResource(R.string.home_info_updating_title), + color = ZashiColors.Text.textPrimary, + style = ZashiTypography.textXl, + fontWeight = FontWeight.SemiBold + ) + Spacer(12.dp) + Text( + stringResource(R.string.home_info_updating_message), + color = ZashiColors.Text.textTertiary, + style = ZashiTypography.textMd + ) + Spacer(32.dp) + ZashiButton( + modifier = Modifier.fillMaxWidth(), + state = + ButtonState( + text = stringRes(R.string.general_ok), + onClick = onBack + ) + ) + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + Content( + onBack = {}, + ) + } + +@Serializable +object WalletUpdatingInfo diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/HomeView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/HomeView.kt index c2548d208..65eb9a356 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/HomeView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/HomeView.kt @@ -6,8 +6,10 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.runtime.Composable @@ -15,6 +17,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp +import androidx.compose.ui.zIndex import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.common.appbar.ZashiMainTopAppBarState import co.electriccoin.zcash.ui.common.appbar.ZashiTopAppBarWithAccountSelection @@ -30,6 +33,7 @@ import co.electriccoin.zcash.ui.fixture.ZashiMainTopAppBarStateFixture import co.electriccoin.zcash.ui.screen.balances.BalanceState import co.electriccoin.zcash.ui.screen.balances.BalanceWidget import co.electriccoin.zcash.ui.screen.home.messages.HomeMessage +import co.electriccoin.zcash.ui.screen.home.messages.WalletErrorMessageState import co.electriccoin.zcash.ui.screen.transactionhistory.widget.TransactionHistoryWidgetState import co.electriccoin.zcash.ui.screen.transactionhistory.widget.TransactionHistoryWidgetStateFixture import co.electriccoin.zcash.ui.screen.transactionhistory.widget.createTransactionHistoryWidgets @@ -78,10 +82,21 @@ private fun Content( ), balanceState = balanceState, ) - Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge)) - NavButtons(paddingValues, state) - Spacer(Modifier.height(16.dp)) - HomeMessage(state.message) + NavButtons( + modifier = + Modifier + .zIndex(1f) + .offset(y = 8.dp), + paddingValues = paddingValues, + state = state + ) + Spacer(Modifier.height(2.dp)) + HomeMessage( + modifier = + Modifier + .zIndex(0f), + state = state.message + ) LazyColumn( modifier = Modifier @@ -96,19 +111,22 @@ private fun Content( } } +@Suppress("MagicNumber") @Composable private fun NavButtons( paddingValues: PaddingValues, - state: HomeState + state: HomeState, + modifier: Modifier = Modifier ) { Row( - modifier = Modifier.scaffoldPadding(paddingValues, top = 0.dp, bottom = 0.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp) + modifier = modifier.scaffoldPadding(paddingValues, top = 0.dp, bottom = 0.dp), + horizontalArrangement = Arrangement.spacedBy(9.dp) ) { ZashiBigIconButton( modifier = Modifier .weight(1f) + .aspectRatio(1.06f) .testTag(HomeTags.RECEIVE), state = state.firstButton, ) @@ -116,15 +134,22 @@ private fun NavButtons( modifier = Modifier .weight(1f) + .aspectRatio(1.06f) .testTag(HomeTags.SEND), state = state.secondButton, ) ZashiBigIconButton( - modifier = Modifier.weight(1f), + modifier = + Modifier + .aspectRatio(1.06f) + .weight(1f), state = state.thirdButton, ) ZashiBigIconButton( - modifier = Modifier.weight(1f), + modifier = + Modifier + .aspectRatio(1.06f) + .weight(1f), state = state.fourthButton, ) } @@ -164,7 +189,7 @@ private fun Preview() { icon = R.drawable.ic_warning, onClick = {} ), - message = null + message = WalletErrorMessageState(onClick = {}) ) ) } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/HomeViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/HomeViewModel.kt index e2bbb5b5c..e24dd3567 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/HomeViewModel.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/HomeViewModel.kt @@ -2,6 +2,7 @@ package co.electriccoin.zcash.ui.screen.home import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import cash.z.ecc.android.sdk.model.Zatoshi import cash.z.ecc.sdk.ANDROID_STATE_FLOW_TIMEOUT import co.electriccoin.zcash.ui.NavigationRouter import co.electriccoin.zcash.ui.NavigationTargets @@ -15,7 +16,17 @@ import co.electriccoin.zcash.ui.common.usecase.IsRestoreSuccessDialogVisibleUseC import co.electriccoin.zcash.ui.common.usecase.NavigateToCoinbaseUseCase import co.electriccoin.zcash.ui.design.component.BigIconButtonState import co.electriccoin.zcash.ui.design.util.stringRes +import co.electriccoin.zcash.ui.screen.exchangerate.optin.ExchangeRateOptIn +import co.electriccoin.zcash.ui.screen.home.balance.TransparentBalanceInfo +import co.electriccoin.zcash.ui.screen.home.messages.EnableCurrencyConversionMessageState +import co.electriccoin.zcash.ui.screen.home.messages.HomeMessageState +import co.electriccoin.zcash.ui.screen.home.messages.TransparentBalanceDetectedMessageState import co.electriccoin.zcash.ui.screen.home.messages.WalletBackupMessageState +import co.electriccoin.zcash.ui.screen.home.messages.WalletDisconnectedMessageState +import co.electriccoin.zcash.ui.screen.home.messages.WalletErrorMessageState +import co.electriccoin.zcash.ui.screen.home.messages.WalletRestoringMessageState +import co.electriccoin.zcash.ui.screen.home.messages.WalletSyncingMessageState +import co.electriccoin.zcash.ui.screen.home.messages.WalletUpdatingMessageState import co.electriccoin.zcash.ui.screen.integrations.DialogIntegrations import co.electriccoin.zcash.ui.screen.receive.Receive import co.electriccoin.zcash.ui.screen.receive.model.ReceiveAddressType @@ -23,15 +34,17 @@ import co.electriccoin.zcash.ui.screen.scan.Scan import co.electriccoin.zcash.ui.screen.scan.ScanFlow import co.electriccoin.zcash.ui.screen.seed.backup.SeedBackup import co.electriccoin.zcash.ui.screen.send.Send +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.WhileSubscribed import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch +import kotlin.time.Duration.Companion.seconds class HomeViewModel( getVersionInfoProvider: GetVersionInfoProvider, @@ -40,7 +53,73 @@ class HomeViewModel( private val isRestoreSuccessDialogVisible: IsRestoreSuccessDialogVisibleUseCase, private val navigateToCoinbase: NavigateToCoinbaseUseCase ) : ViewModel() { - private val isMessageVisible = MutableStateFlow(true) + @Suppress("MagicNumber") + private val messageState = + flow { + val states = + listOf( + WalletErrorMessageState( + onClick = {} + ), + WalletDisconnectedMessageState(onClick = { + navigationRouter.forward(WalletDisconnectedInfo) + }), + WalletRestoringMessageState(progress = 0, onClick = { + navigationRouter.forward(WalletRestoringInfo) + }), + WalletRestoringMessageState(progress = 100, onClick = { + navigationRouter.forward(WalletRestoringInfo) + }), + WalletSyncingMessageState(progress = 0, onClick = { + navigationRouter.forward(WalletSyncingInfo) + }), + WalletSyncingMessageState(progress = 100, onClick = { + navigationRouter.forward(WalletSyncingInfo) + }), + WalletUpdatingMessageState(onClick = { + navigationRouter.forward(WalletUpdatingInfo) + }), + WalletBackupMessageState( + onClick = { + navigationRouter.forward(SeedBackupInfo) + }, + onButtonClick = { + navigationRouter.forward(SeedBackup(false)) + } + ), + TransparentBalanceDetectedMessageState( + subtitle = stringRes(zatoshi = Zatoshi(1000)), + onClick = { + navigationRouter.forward(TransparentBalanceInfo) + }, + onButtonClick = { + // navigationRouter.forward(TransparentBalanceInfo) + }, + ), + EnableCurrencyConversionMessageState( + onClick = { + navigationRouter.forward(ExchangeRateOptIn) + }, + onButtonClick = { + navigationRouter.forward(ExchangeRateOptIn) + }, + ) + ) + + var index = 0 + + while (true) { + emit(states[index]) + delay(3.seconds) + if (index == states.lastIndex) { + emit(null) + delay(10.seconds) + index = 0 + } else { + index += 1 + } + } + } private val isRestoreDialogVisible: Flow = isRestoreSuccessDialogVisible @@ -64,8 +143,11 @@ class HomeViewModel( ) val state: StateFlow = - combine(getSelectedWalletAccountUseCase.observe(), isMessageVisible) { selectedAccount, isMessageVisible -> - createState(getVersionInfoProvider, selectedAccount, isMessageVisible) + combine( + getSelectedWalletAccountUseCase.observe(), + messageState + ) { selectedAccount, messageState -> + createState(getVersionInfoProvider, selectedAccount, messageState) }.stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT), @@ -75,7 +157,7 @@ class HomeViewModel( private fun createState( getVersionInfoProvider: GetVersionInfoProvider, selectedAccount: WalletAccount?, - isMessageVisible: Boolean + messageState: HomeMessageState? ) = HomeState( firstButton = BigIconButtonState( @@ -118,16 +200,9 @@ class HomeViewModel( onClick = ::onMoreButtonClick, ) }, - message = createWalletBackupMessageState().takeIf { isMessageVisible } + message = messageState ) - private fun createWalletBackupMessageState(): WalletBackupMessageState = - WalletBackupMessageState( - onClick = { - navigationRouter.forward(SeedBackup) - } - ) - private fun onRestoreDialogSeenClick() = viewModelScope.launch { isRestoreSuccessDialogVisible.setSeen() diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/balance/AndroidTransparentBalanceInfo.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/balance/AndroidTransparentBalanceInfo.kt new file mode 100644 index 000000000..8f6cc6f38 --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/balance/AndroidTransparentBalanceInfo.kt @@ -0,0 +1,19 @@ +package co.electriccoin.zcash.ui.screen.home.balance + +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import kotlinx.serialization.Serializable +import org.koin.androidx.compose.koinViewModel + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AndroidTransparentBalanceInfo() { + val vm = koinViewModel() + val state by vm.state.collectAsStateWithLifecycle() + state?.let { TransparentBalanceInfoView(it) } +} + +@Serializable +object TransparentBalanceInfo diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/balance/TransparentBalanceInfoState.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/balance/TransparentBalanceInfoState.kt new file mode 100644 index 000000000..e8174b285 --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/balance/TransparentBalanceInfoState.kt @@ -0,0 +1,12 @@ +package co.electriccoin.zcash.ui.screen.home.balance + +import cash.z.ecc.android.sdk.model.Zatoshi +import co.electriccoin.zcash.ui.design.component.ButtonState +import co.electriccoin.zcash.ui.design.component.ModalBottomSheetState + +data class TransparentBalanceInfoState( + val transparentAmount: Zatoshi, + override val onBack: () -> Unit, + val primaryButton: ButtonState, + val secondaryButton: ButtonState +) : ModalBottomSheetState diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/balance/TransparentBalanceInfoView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/balance/TransparentBalanceInfoView.kt new file mode 100644 index 000000000..d0bf0be45 --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/balance/TransparentBalanceInfoView.kt @@ -0,0 +1,152 @@ +package co.electriccoin.zcash.ui.screen.home.balance + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.SheetState +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import cash.z.ecc.android.sdk.model.Zatoshi +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.design.component.ButtonState +import co.electriccoin.zcash.ui.design.component.Spacer +import co.electriccoin.zcash.ui.design.component.ZashiButton +import co.electriccoin.zcash.ui.design.component.ZashiButtonDefaults +import co.electriccoin.zcash.ui.design.component.ZashiCard +import co.electriccoin.zcash.ui.design.component.ZashiScreenModalBottomSheet +import co.electriccoin.zcash.ui.design.component.rememberScreenModalBottomSheetState +import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens +import co.electriccoin.zcash.ui.design.theme.ZcashTheme +import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors +import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography +import co.electriccoin.zcash.ui.design.util.getValue +import co.electriccoin.zcash.ui.design.util.stringRes + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun TransparentBalanceInfoView( + state: TransparentBalanceInfoState?, + sheetState: SheetState = rememberScreenModalBottomSheetState(), +) { + ZashiScreenModalBottomSheet( + sheetState = sheetState, + state = state, + ) { + Content(it) + } +} + +@Composable +private fun Content(state: TransparentBalanceInfoState) { + Column( + modifier = + Modifier + .padding(horizontal = 24.dp) + ) { + Image( + painter = painterResource(R.drawable.ic_info_shield), + contentDescription = null + ) + Spacer(12.dp) + Text( + stringResource(R.string.home_info_transparent_title), + color = ZashiColors.Text.textPrimary, + style = ZashiTypography.textXl, + fontWeight = FontWeight.SemiBold + ) + Spacer(12.dp) + Text( + stringResource(R.string.home_info_transparent_subtitle), + color = ZashiColors.Text.textTertiary, + style = ZashiTypography.textMd + ) + Spacer(24.dp) + Text( + stringResource(R.string.home_info_transparent_message), + color = ZashiColors.Text.textTertiary, + style = ZashiTypography.textMd + ) + Spacer(32.dp) + ZashiCard( + modifier = Modifier.fillMaxWidth(), + contentPadding = + PaddingValues( + horizontal = 20.dp, + vertical = 12.dp + ), + borderColor = ZashiColors.Surfaces.strokeSecondary + ) { + Row( + verticalAlignment = Alignment.CenterVertically + ) { + Text( + stringResource(R.string.home_info_transparent_subheader), + color = ZashiColors.Text.textPrimary, + style = ZashiTypography.textMd, + fontWeight = FontWeight.Medium + ) + Spacer(4.dp) + Image( + painter = painterResource(R.drawable.ic_transparent_small), + contentDescription = null + ) + } + Spacer(4.dp) + Text( + text = + stringResource( + R.string.home_message_transparent_balance_subtitle, + stringRes(state.transparentAmount).getValue() + ), + color = ZashiColors.Text.textPrimary, + style = ZashiTypography.textXl, + fontWeight = FontWeight.SemiBold + ) + } + Spacer(24.dp) + ZashiButton( + modifier = Modifier.fillMaxWidth(), + state = state.secondaryButton, + colors = ZashiButtonDefaults.secondaryColors() + ) + Spacer(4.dp) + ZashiButton( + modifier = Modifier.fillMaxWidth(), + state = state.primaryButton + ) + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + TransparentBalanceInfoView( + state = + TransparentBalanceInfoState( + onBack = {}, + primaryButton = + ButtonState( + text = stringRes("Remind me later"), + onClick = {} + ), + secondaryButton = + ButtonState( + text = stringRes("Shield"), + onClick = {} + ), + transparentAmount = Zatoshi(0) + ) + ) + } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/balance/TransparentBalanceInfoViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/balance/TransparentBalanceInfoViewModel.kt new file mode 100644 index 000000000..767031a22 --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/balance/TransparentBalanceInfoViewModel.kt @@ -0,0 +1,45 @@ +package co.electriccoin.zcash.ui.screen.home.balance + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import cash.z.ecc.android.sdk.model.Zatoshi +import cash.z.ecc.sdk.ANDROID_STATE_FLOW_TIMEOUT +import co.electriccoin.zcash.ui.NavigationRouter +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.common.usecase.GetSelectedWalletAccountUseCase +import co.electriccoin.zcash.ui.design.component.ButtonState +import co.electriccoin.zcash.ui.design.util.stringRes +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.WhileSubscribed +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn + +class TransparentBalanceInfoViewModel( + getSelectedWalletAccount: GetSelectedWalletAccountUseCase, + private val navigationRouter: NavigationRouter +) : ViewModel() { + val state: StateFlow = + getSelectedWalletAccount + .observe() + .map { + TransparentBalanceInfoState( + onBack = { navigationRouter.back() }, + primaryButton = + ButtonState( + onClick = { navigationRouter.back() }, + text = stringRes(R.string.home_info_transparent_balance_shield) + ), + secondaryButton = + ButtonState( + onClick = { navigationRouter.back() }, + text = stringRes(R.string.general_remind_me_later) + ), + transparentAmount = it?.transparent?.balance ?: Zatoshi(0) + ) + }.stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT), + initialValue = null + ) +} diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/EnableCurrencyConversionMessage.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/EnableCurrencyConversionMessage.kt new file mode 100644 index 000000000..4ccaee1e9 --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/EnableCurrencyConversionMessage.kt @@ -0,0 +1,84 @@ +package co.electriccoin.zcash.ui.screen.home.messages + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.height +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.Text +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.unit.dp +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.design.component.BlankSurface +import co.electriccoin.zcash.ui.design.component.ButtonState +import co.electriccoin.zcash.ui.design.component.ZashiButton +import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens +import co.electriccoin.zcash.ui.design.theme.ZcashTheme +import co.electriccoin.zcash.ui.design.util.stringRes + +@Suppress("ModifierNaming") +@Composable +fun EnableCurrencyConversionMessage( + contentPadding: PaddingValues, + state: EnableCurrencyConversionMessageState, + innerModifier: Modifier = Modifier, +) { + HomeMessageWrapper( + innerModifier = innerModifier, + contentPadding = contentPadding, + onClick = state.onClick, + start = { + Image( + modifier = Modifier.align(Alignment.Top), + painter = painterResource(R.drawable.ic_message_currency_conversion), + contentDescription = null, + colorFilter = ColorFilter.tint(LocalContentColor.current) + ) + }, + title = { + Text( + stringResource(R.string.home_message_currency_conversion_title) + ) + }, + subtitle = { + Text( + text = stringResource(R.string.home_message_currency_conversion_subtitle), + ) + }, + end = { + ZashiButton( + modifier = Modifier.height(36.dp), + state = + ButtonState( + onClick = state.onButtonClick, + text = stringRes(stringResource(R.string.home_message_currency_conversion_button)) + ) + ) + } + ) +} + +class EnableCurrencyConversionMessageState( + val onClick: () -> Unit, + val onButtonClick: () -> Unit, +) : HomeMessageState + +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + BlankSurface { + EnableCurrencyConversionMessage( + state = + EnableCurrencyConversionMessageState( + onClick = {}, + onButtonClick = {} + ), + contentPadding = PaddingValues() + ) + } + } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/HomeMessage.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/HomeMessage.kt index 26ee697a4..f65d163f2 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/HomeMessage.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/HomeMessage.kt @@ -1,6 +1,8 @@ package co.electriccoin.zcash.ui.screen.home.messages import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.CubicBezierEasing +import androidx.compose.animation.core.TweenSpec import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.tween import androidx.compose.animation.expandIn @@ -34,53 +36,122 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors import kotlinx.coroutines.delay +import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds -@Suppress("MagicNumber") +@Suppress("MagicNumber", "CyclomaticComplexMethod") @Composable -fun HomeMessage(state: HomeMessageState?) { - val cutoutHeight = 16.dp +fun HomeMessage( + state: HomeMessageState?, + modifier: Modifier = Modifier +) { var normalizedState: HomeMessageState? by remember { mutableStateOf(state) } var isVisible by remember { mutableStateOf(state != null) } val bottomCornerSize by animateDpAsState( - if (isVisible) cutoutHeight else 0.dp, - animationSpec = tween(350) + targetValue = if (isVisible) BOTTOM_CUTOUT_HEIGHT_DP.dp else 0.dp, + animationSpec = animationSpec() + ) + val bottomHeight by animateDpAsState( + targetValue = if (isVisible) BOTTOM_CUTOUT_HEIGHT_DP.dp else TOP_CUTOUT_HEIGHT_DP.dp, + animationSpec = + animationSpec( + delay = if (isVisible) null else 250.milliseconds + ) ) Box( - modifier = - Modifier - .background(Color.Gray) + modifier = modifier ) { Box( modifier = Modifier .fillMaxWidth() - .height(cutoutHeight) + .height(TOP_CUTOUT_HEIGHT_DP.dp) .zIndex(2f) .bottomOnlyShadow( elevation = 2.dp, - shape = RoundedCornerShape(bottomStart = 32.dp, bottomEnd = 32.dp), + shape = + RoundedCornerShape( + bottomStart = TOP_CUTOUT_HEIGHT_DP.dp, + bottomEnd = TOP_CUTOUT_HEIGHT_DP.dp + ), backgroundColor = ZashiColors.Surfaces.bgPrimary ), ) - AnimatedVisibility( modifier = Modifier .fillMaxWidth() .zIndex(0f), visible = isVisible, - enter = expandIn(animationSpec = tween(350)), - exit = shrinkOut(animationSpec = tween(350)) + enter = + expandIn( + animationSpec = animationSpec(), + expandFrom = Alignment.TopEnd + ), + exit = + shrinkOut( + animationSpec = animationSpec(), + shrinkTowards = Alignment.TopEnd + ) ) { + val contentPadding = PaddingValues(top = TOP_CUTOUT_HEIGHT_DP.dp, bottom = BOTTOM_CUTOUT_HEIGHT_DP.dp) + val innerModifier = Modifier when (normalizedState) { is WalletBackupMessageState -> WalletBackupMessage( + innerModifier = innerModifier, state = normalizedState as WalletBackupMessageState, - contentPadding = - PaddingValues( - vertical = cutoutHeight - ) + contentPadding = contentPadding + ) + + is EnableCurrencyConversionMessageState -> + EnableCurrencyConversionMessage( + innerModifier = innerModifier, + state = normalizedState as EnableCurrencyConversionMessageState, + contentPadding = contentPadding + ) + + is TransparentBalanceDetectedMessageState -> + TransparentBalanceDetectedMessage( + innerModifier = innerModifier, + state = normalizedState as TransparentBalanceDetectedMessageState, + contentPadding = contentPadding + ) + + is WalletDisconnectedMessageState -> + WalletDisconnectedMessage( + innerModifier = innerModifier, + state = normalizedState as WalletDisconnectedMessageState, + contentPadding = contentPadding + ) + + is WalletRestoringMessageState -> + WalletRestoringMessage( + innerModifier = innerModifier, + state = normalizedState as WalletRestoringMessageState, + contentPadding = contentPadding + ) + + is WalletSyncingMessageState -> + WalletSyncingMessage( + innerModifier = innerModifier, + state = normalizedState as WalletSyncingMessageState, + contentPadding = contentPadding + ) + + is WalletUpdatingMessageState -> + WalletUpdatingMessage( + innerModifier = innerModifier, + state = normalizedState as WalletUpdatingMessageState, + contentPadding = contentPadding + ) + + is WalletErrorMessageState -> + WalletErrorMessage( + innerModifier = innerModifier, + state = normalizedState as WalletErrorMessageState, + contentPadding = contentPadding ) null -> { @@ -93,7 +164,7 @@ fun HomeMessage(state: HomeMessageState?) { modifier = Modifier .fillMaxWidth() - .height(cutoutHeight) + .height(bottomHeight) .zIndex(1f) .align(Alignment.BottomCenter) .topOnlyShadow( @@ -105,17 +176,51 @@ fun HomeMessage(state: HomeMessageState?) { } LaunchedEffect(state) { - if (state != null) { - normalizedState = state - isVisible = true - } else { - isVisible = false - delay(350) - normalizedState = null + when { + normalizedState == null -> { + normalizedState = state + isVisible = state != null + } + + state == null -> { + isVisible = false + delay(ANIMATION_DURATION_MS.milliseconds) + normalizedState = null + } + + normalizedState!!::class == state::class -> { + normalizedState = state + isVisible = true + } + + else -> { + isVisible = false + delay(ANIMATION_DURATION_BETWEEN_MESSAGES_MS.milliseconds) + normalizedState = state + isVisible = true + } } } } +sealed interface HomeMessageState + +@Suppress("MagicNumber") +@Composable +private fun animationSpec(delay: Duration? = null): TweenSpec { + val delayMs = delay?.inWholeMilliseconds?.toInt() ?: 0 + return tween( + durationMillis = ANIMATION_DURATION_MS - delayMs, + easing = CubicBezierEasing(0.6f, 0.1f, 0.3f, 0.9f), + delayMillis = delayMs + ) +} + +private const val ANIMATION_DURATION_MS = 850 +private const val ANIMATION_DURATION_BETWEEN_MESSAGES_MS = 1000 +private const val TOP_CUTOUT_HEIGHT_DP = 32 +private const val BOTTOM_CUTOUT_HEIGHT_DP = 24 + private fun Modifier.bottomOnlyShadow( elevation: Dp, shape: Shape, diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/HomeMessageState.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/HomeMessageState.kt deleted file mode 100644 index 8fc1524eb..000000000 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/HomeMessageState.kt +++ /dev/null @@ -1,3 +0,0 @@ -package co.electriccoin.zcash.ui.screen.home.messages - -sealed interface HomeMessageState diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/HomeMessageWrapper.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/HomeMessageWrapper.kt index b0b8115bb..cc1fc4466 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/HomeMessageWrapper.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/HomeMessageWrapper.kt @@ -1,38 +1,125 @@ package co.electriccoin.zcash.ui.screen.home.messages +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Surface +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.LocalTextStyle import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import co.electriccoin.zcash.ui.design.component.HorizontalSpacer +import co.electriccoin.zcash.ui.design.component.LocalZashiButtonColors +import co.electriccoin.zcash.ui.design.component.LocalZashiCircularProgressIndicatorColors +import co.electriccoin.zcash.ui.design.component.VerticalSpacer +import co.electriccoin.zcash.ui.design.component.ZashiButtonDefaults +import co.electriccoin.zcash.ui.design.component.ZashiCircularProgressIndicatorDefaults +import co.electriccoin.zcash.ui.design.theme.colors.Purple +import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors +import co.electriccoin.zcash.ui.design.theme.colors.ZashiDarkColors +import co.electriccoin.zcash.ui.design.theme.colors.ZashiLightColors +import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography +@Suppress("ModifierNaming", "ModifierWithoutDefault") @Composable fun HomeMessageWrapper( - color: Color, + innerModifier: Modifier, contentPadding: PaddingValues, - content: @Composable RowScope.() -> Unit, + onClick: () -> Unit, + start: @Composable RowScope.() -> Unit, + title: @Composable () -> Unit, + subtitle: @Composable () -> Unit, + end: (@Composable () -> Unit)?, ) { - Surface( - color = color, + Container( + contentPadding = contentPadding, + onClick = onClick, + innerModifier = innerModifier, ) { - Box( - modifier = Modifier.padding(contentPadding) + CompositionLocalProvider( + LocalContentColor provides ZashiColors.Text.textOpposite, + LocalZashiCircularProgressIndicatorColors provides + ZashiCircularProgressIndicatorDefaults.colors( + progressColor = ZashiColors.Text.textOpposite, + trackColor = Purple.`400` + ) ) { - Row( - modifier = - Modifier.padding( - horizontal = 16.dp, - vertical = 14.dp + start() + } + HorizontalSpacer(16.dp) + Column( + modifier = Modifier.weight(1f) + ) { + CompositionLocalProvider( + LocalTextStyle provides + ZashiTypography.textSm.copy( + color = ZashiColors.Text.textOpposite, + fontWeight = FontWeight.Medium ), - verticalAlignment = Alignment.CenterVertically, - content = content - ) + ) { + title() + } + VerticalSpacer(2.dp) + CompositionLocalProvider( + LocalTextStyle provides + ZashiTypography.textXs.copy( + color = Purple.`200`, + fontWeight = FontWeight.Medium + ), + ) { + subtitle() + } + } + if (end != null) { + CompositionLocalProvider( + LocalZashiButtonColors provides + ZashiButtonDefaults.primaryColors( + if (isSystemInDarkTheme()) ZashiLightColors else ZashiDarkColors + ) + ) { + end() + } } } } + +@Suppress("ModifierNaming", "ModifierWithoutDefault") +@Composable +private fun Container( + innerModifier: Modifier, + contentPadding: PaddingValues, + onClick: () -> Unit, + content: @Composable (RowScope.() -> Unit), +) { + Box( + modifier = + Modifier + .background( + Brush.verticalGradient( + 0f to Purple.`500`, + 1f to Purple.`900`, + ) + ).clickable(onClick = onClick) + .padding(contentPadding), + ) { + Row( + modifier = + innerModifier.padding( + horizontal = 16.dp, + vertical = 18.dp + ), + verticalAlignment = Alignment.CenterVertically, + content = content + ) + } +} diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/TransparentBalanceDetectedMessage.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/TransparentBalanceDetectedMessage.kt new file mode 100644 index 000000000..c53bef232 --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/TransparentBalanceDetectedMessage.kt @@ -0,0 +1,93 @@ +package co.electriccoin.zcash.ui.screen.home.messages + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.height +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.Text +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.unit.dp +import cash.z.ecc.android.sdk.model.Zatoshi +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.design.component.BlankSurface +import co.electriccoin.zcash.ui.design.component.ButtonState +import co.electriccoin.zcash.ui.design.component.ZashiButton +import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens +import co.electriccoin.zcash.ui.design.theme.ZcashTheme +import co.electriccoin.zcash.ui.design.util.StringResource +import co.electriccoin.zcash.ui.design.util.getValue +import co.electriccoin.zcash.ui.design.util.stringRes + +@Suppress("ModifierNaming") +@Composable +fun TransparentBalanceDetectedMessage( + contentPadding: PaddingValues, + state: TransparentBalanceDetectedMessageState, + innerModifier: Modifier = Modifier, +) { + HomeMessageWrapper( + innerModifier = innerModifier, + contentPadding = contentPadding, + onClick = state.onClick, + start = { + Image( + modifier = Modifier.align(Alignment.Top), + painter = painterResource(R.drawable.ic_message_transparent_balance), + contentDescription = null, + colorFilter = ColorFilter.tint(LocalContentColor.current) + ) + }, + title = { + Text( + stringResource(R.string.home_message_transparent_balance_title), + ) + }, + subtitle = { + Text( + text = state.subtitle.getValue(), + ) + }, + end = { + ZashiButton( + modifier = Modifier.height(36.dp), + state = + ButtonState( + onClick = state.onButtonClick, + text = stringRes(stringResource(R.string.home_message_transparent_balance_button)) + ) + ) + } + ) +} + +class TransparentBalanceDetectedMessageState( + val subtitle: StringResource, + val onClick: () -> Unit, + val onButtonClick: () -> Unit, +) : HomeMessageState + +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + BlankSurface { + TransparentBalanceDetectedMessage( + state = + TransparentBalanceDetectedMessageState( + subtitle = + stringRes( + R.string.home_message_transparent_balance_subtitle, + stringRes(Zatoshi(10000)) + ), + onClick = {}, + onButtonClick = {} + ), + contentPadding = PaddingValues() + ) + } + } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletBackupMessageState.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletBackupMessage.kt similarity index 55% rename from ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletBackupMessageState.kt rename to ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletBackupMessage.kt index f16c3493a..1bae703ec 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletBackupMessageState.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletBackupMessage.kt @@ -1,74 +1,72 @@ package co.electriccoin.zcash.ui.screen.home.messages import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.height +import androidx.compose.material3.LocalContentColor import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable +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.font.FontWeight import androidx.compose.ui.unit.dp import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.design.component.BlankSurface import co.electriccoin.zcash.ui.design.component.ButtonState -import co.electriccoin.zcash.ui.design.component.HorizontalSpacer -import co.electriccoin.zcash.ui.design.component.VerticalSpacer import co.electriccoin.zcash.ui.design.component.ZashiButton import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens import co.electriccoin.zcash.ui.design.theme.ZcashTheme -import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors -import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography import co.electriccoin.zcash.ui.design.util.stringRes +@Suppress("ModifierNaming") @Composable fun WalletBackupMessage( state: WalletBackupMessageState, - contentPadding: PaddingValues + contentPadding: PaddingValues, + innerModifier: Modifier = Modifier, ) { HomeMessageWrapper( - color = ZashiColors.Utility.Espresso.utilityEspresso100, + innerModifier = innerModifier, contentPadding = contentPadding, - ) { - Image( - painter = painterResource(R.drawable.ic_warning_triangle), - contentDescription = null - ) - HorizontalSpacer(16.dp) - Column( - modifier = Modifier.weight(1f) - ) { + onClick = state.onClick, + start = { + Image( + modifier = Modifier.align(Alignment.Top), + painter = painterResource(R.drawable.ic_warning_triangle), + contentDescription = null, + colorFilter = ColorFilter.tint(LocalContentColor.current) + ) + }, + title = { Text( stringResource(R.string.home_message_backup_required_title), - style = ZashiTypography.textSm, - fontWeight = FontWeight.Medium, - color = ZashiColors.Utility.Espresso.utilityEspresso900 ) - VerticalSpacer(2.dp) + }, + subtitle = { Text( text = stringResource(R.string.home_message_backup_required_subtitle), - style = ZashiTypography.textXs, - fontWeight = FontWeight.Medium, - color = ZashiColors.Utility.Espresso.utilityEspresso700 + ) + }, + end = { + ZashiButton( + modifier = Modifier.height(36.dp), + state = + ButtonState( + onClick = state.onButtonClick, + text = stringRes(R.string.home_message_backup_required_button) + ) ) } - ZashiButton( - modifier = Modifier.height(36.dp), - state = - ButtonState( - onClick = state.onClick, - text = stringRes("Start") - ) - ) - } + ) } @Immutable data class WalletBackupMessageState( val onClick: () -> Unit, + val onButtonClick: () -> Unit, ) : HomeMessageState @PreviewScreens @@ -79,7 +77,8 @@ private fun Preview() = WalletBackupMessage( state = WalletBackupMessageState( - onClick = {} + onClick = {}, + onButtonClick = {} ), contentPadding = PaddingValues() ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletDisconnectedMessage.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletDisconnectedMessage.kt new file mode 100644 index 000000000..61c1f12f0 --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletDisconnectedMessage.kt @@ -0,0 +1,69 @@ +package co.electriccoin.zcash.ui.screen.home.messages + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.Text +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.unit.dp +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.design.component.BlankSurface +import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens +import co.electriccoin.zcash.ui.design.theme.ZcashTheme + +@Suppress("ModifierNaming") +@Composable +fun WalletDisconnectedMessage( + contentPadding: PaddingValues, + state: WalletDisconnectedMessageState, + innerModifier: Modifier = Modifier, +) { + HomeMessageWrapper( + innerModifier = innerModifier, + contentPadding = contentPadding, + onClick = state.onClick, + start = { + Image( + modifier = Modifier.align(Alignment.Top), + painter = painterResource(R.drawable.ic_message_disconnected), + contentDescription = null, + colorFilter = ColorFilter.tint(LocalContentColor.current) + ) + }, + title = { + Text( + stringResource(R.string.home_message_wallet_disconnected_title), + ) + }, + subtitle = { + Text( + text = stringResource(R.string.home_message_wallet_disconnected_subtitle), + ) + }, + end = null + ) +} + +class WalletDisconnectedMessageState( + val onClick: () -> Unit +) : HomeMessageState + +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + BlankSurface { + WalletDisconnectedMessage( + contentPadding = PaddingValues(16.dp), + state = + WalletDisconnectedMessageState( + onClick = {} + ) + ) + } + } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletErrorMessage.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletErrorMessage.kt new file mode 100644 index 000000000..d56e5c1fa --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletErrorMessage.kt @@ -0,0 +1,69 @@ +package co.electriccoin.zcash.ui.screen.home.messages + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.Text +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.unit.dp +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.design.component.BlankSurface +import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens +import co.electriccoin.zcash.ui.design.theme.ZcashTheme + +@Suppress("ModifierNaming") +@Composable +fun WalletErrorMessage( + contentPadding: PaddingValues, + state: WalletErrorMessageState, + innerModifier: Modifier = Modifier, +) { + HomeMessageWrapper( + innerModifier = innerModifier, + contentPadding = contentPadding, + onClick = state.onClick, + start = { + Image( + modifier = Modifier.align(Alignment.Top), + painter = painterResource(R.drawable.ic_warning_triangle), + contentDescription = null, + colorFilter = ColorFilter.tint(LocalContentColor.current) + ) + }, + title = { + Text( + stringResource(R.string.home_message_error_title), + ) + }, + subtitle = { + Text( + text = stringResource(R.string.home_message_error_subtitle), + ) + }, + end = null + ) +} + +class WalletErrorMessageState( + val onClick: () -> Unit +) : HomeMessageState + +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + BlankSurface { + WalletErrorMessage( + contentPadding = PaddingValues(16.dp), + state = + WalletErrorMessageState( + onClick = {} + ) + ) + } + } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletRestoringMessage.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletRestoringMessage.kt new file mode 100644 index 000000000..a710a29ad --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletRestoringMessage.kt @@ -0,0 +1,72 @@ +package co.electriccoin.zcash.ui.screen.home.messages + +import androidx.annotation.IntRange +import androidx.compose.animation.core.animateIntAsState +import androidx.compose.animation.core.tween +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.design.component.BlankSurface +import co.electriccoin.zcash.ui.design.component.ZashiCircularProgressIndicator +import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens +import co.electriccoin.zcash.ui.design.theme.ZcashTheme + +@Suppress("ModifierNaming") +@Composable +fun WalletRestoringMessage( + contentPadding: PaddingValues, + state: WalletRestoringMessageState, + innerModifier: Modifier = Modifier, +) { + HomeMessageWrapper( + innerModifier = innerModifier, + contentPadding = contentPadding, + onClick = state.onClick, + start = { + ZashiCircularProgressIndicator( + modifier = Modifier.size(20.dp), + progressPercent = state.progress, + ) + }, + title = { + Text( + text = stringResource(R.string.home_message_restoring_title, state.progress), + ) + }, + subtitle = { + Text( + text = stringResource(R.string.home_message_restoring_subtitle), + ) + }, + end = null + ) +} + +class WalletRestoringMessageState( + @IntRange(from = 0, to = 100) val progress: Int, + val onClick: () -> Unit +) : HomeMessageState + +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + val progress by animateIntAsState(50, label = "progress", animationSpec = tween(10000)) + + BlankSurface { + WalletRestoringMessage( + contentPadding = PaddingValues(16.dp), + state = + WalletRestoringMessageState( + progress = progress, + onClick = {} + ) + ) + } + } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletSyncingMessage.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletSyncingMessage.kt new file mode 100644 index 000000000..41cab1d51 --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletSyncingMessage.kt @@ -0,0 +1,72 @@ +package co.electriccoin.zcash.ui.screen.home.messages + +import androidx.annotation.IntRange +import androidx.compose.animation.core.animateIntAsState +import androidx.compose.animation.core.tween +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.design.component.BlankSurface +import co.electriccoin.zcash.ui.design.component.ZashiCircularProgressIndicator +import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens +import co.electriccoin.zcash.ui.design.theme.ZcashTheme + +@Suppress("ModifierNaming") +@Composable +fun WalletSyncingMessage( + contentPadding: PaddingValues, + state: WalletSyncingMessageState, + innerModifier: Modifier = Modifier, +) { + HomeMessageWrapper( + innerModifier = innerModifier, + contentPadding = contentPadding, + onClick = state.onClick, + start = { + ZashiCircularProgressIndicator( + modifier = Modifier.size(20.dp), + progressPercent = state.progress, + ) + }, + title = { + Text( + text = stringResource(R.string.home_message_syncing_title, state.progress), + ) + }, + subtitle = { + Text( + text = stringResource(R.string.home_message_syncing_subtitle), + ) + }, + end = null + ) +} + +class WalletSyncingMessageState( + @IntRange(from = 0, to = 100) val progress: Int, + val onClick: () -> Unit +) : HomeMessageState + +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + val progress by animateIntAsState(50, label = "progress", animationSpec = tween(10000)) + + BlankSurface { + WalletSyncingMessage( + contentPadding = PaddingValues(16.dp), + state = + WalletSyncingMessageState( + progress = progress, + onClick = {} + ) + ) + } + } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletUpdatingMessage.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletUpdatingMessage.kt new file mode 100644 index 000000000..65bc5c785 --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/messages/WalletUpdatingMessage.kt @@ -0,0 +1,69 @@ +package co.electriccoin.zcash.ui.screen.home.messages + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import co.electriccoin.zcash.ui.R +import co.electriccoin.zcash.ui.design.component.BlankSurface +import co.electriccoin.zcash.ui.design.component.LottieProgress +import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens +import co.electriccoin.zcash.ui.design.theme.ZcashTheme + +@Suppress("ModifierNaming") +@Composable +fun WalletUpdatingMessage( + contentPadding: PaddingValues, + state: WalletUpdatingMessageState, + innerModifier: Modifier = Modifier, +) { + HomeMessageWrapper( + innerModifier = innerModifier, + contentPadding = contentPadding, + onClick = state.onClick, + start = { + LottieProgress( + modifier = + Modifier + .size(20.dp) + .align(Alignment.Top), + size = 20.dp, + loadingRes = co.electriccoin.zcash.ui.design.R.raw.lottie_loading_white + ) + }, + title = { + Text( + stringResource(R.string.home_message_wallet_updating_title), + ) + }, + subtitle = { + Text( + text = stringResource(R.string.home_message_wallet_updating_subtitle), + ) + }, + end = null + ) +} + +class WalletUpdatingMessageState( + val onClick: () -> Unit +) : HomeMessageState + +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + BlankSurface { + WalletUpdatingMessage( + contentPadding = PaddingValues(16.dp), + state = + WalletUpdatingMessageState( + onClick = {} + ) + ) + } + } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/AndroidDialogIntegrations.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/AndroidDialogIntegrations.kt index e212dce51..36596142e 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/AndroidDialogIntegrations.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/AndroidDialogIntegrations.kt @@ -1,12 +1,8 @@ package co.electriccoin.zcash.ui.screen.integrations -import android.view.WindowManager import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue -import androidx.compose.ui.platform.LocalView -import androidx.compose.ui.window.DialogWindowProvider import androidx.lifecycle.compose.collectAsStateWithLifecycle import kotlinx.serialization.Serializable import org.koin.androidx.compose.koinViewModel @@ -15,20 +11,9 @@ import org.koin.core.parameter.parametersOf @OptIn(ExperimentalMaterial3Api::class) @Composable fun AndroidDialogIntegrations() { - val parent = LocalView.current.parent val viewModel = koinViewModel { parametersOf(true) } val state by viewModel.state.collectAsStateWithLifecycle() - - SideEffect { - (parent as? DialogWindowProvider)?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) - (parent as? DialogWindowProvider)?.window?.setDimAmount(0f) - } - - state?.let { - IntegrationsDialogView( - state = it, - ) - } + IntegrationsDialogView(state) } @Serializable diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsDialogView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsDialogView.kt index a3c95ac1b..f421eef0f 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsDialogView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsDialogView.kt @@ -5,12 +5,9 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.systemBars -import androidx.compose.foundation.layout.windowInsetsBottomHeight import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SheetState import androidx.compose.material3.SheetValue @@ -39,14 +36,14 @@ import kotlinx.collections.immutable.persistentListOf @Composable @OptIn(ExperimentalMaterial3Api::class) internal fun IntegrationsDialogView( - state: IntegrationsState, + state: IntegrationsState?, sheetState: SheetState = rememberScreenModalBottomSheetState(), ) { ZashiScreenModalBottomSheet( state = state, sheetState = sheetState, content = { - BottomSheetContent(state) + BottomSheetContent(it) }, ) } @@ -73,7 +70,7 @@ fun BottomSheetContent(state: IntegrationsState) { ) { Image( modifier = Modifier, - painter = painterResource(R.drawable.ic_info), + painter = painterResource(co.electriccoin.zcash.ui.design.R.drawable.ic_info), contentDescription = null, colorFilter = ColorFilter.tint(ZashiColors.Text.textTertiary) ) @@ -86,10 +83,6 @@ fun BottomSheetContent(state: IntegrationsState) { color = ZashiColors.Text.textTertiary ) } - - Spacer(modifier = Modifier.height(16.dp)) - - Spacer(modifier = Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/RestoreBDDateView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/RestoreBDDateView.kt index e63cd37af..e7a74eeb0 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/RestoreBDDateView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/RestoreBDDateView.kt @@ -97,7 +97,7 @@ private fun Content( horizontalArrangement = Arrangement.Center ) { Image( - painterResource(R.drawable.ic_info), + painterResource(co.electriccoin.zcash.ui.design.R.drawable.ic_info), contentDescription = "", colorFilter = ColorFilter.tint(color = ZashiColors.Utility.Indigo.utilityIndigo700) ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/RestoreBDDateViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/RestoreBDDateViewModel.kt index 5a2079473..0397265cd 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/RestoreBDDateViewModel.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/RestoreBDDateViewModel.kt @@ -20,7 +20,11 @@ class RestoreBDDateViewModel( private fun createState() = RestoreBDDateState( next = ButtonState(stringRes(R.string.restore_bd_height_btn), onClick = ::onEstimateClick), - dialogButton = IconButtonState(icon = R.drawable.ic_info, onClick = ::onInfoButtonClick), + dialogButton = + IconButtonState( + icon = co.electriccoin.zcash.ui.design.R.drawable.ic_info, + onClick = ::onInfoButtonClick, + ), onBack = ::onBack, ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/estimation/RestoreBDEstimationView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/estimation/RestoreBDEstimationView.kt index 321941f8d..90ce99b55 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/estimation/RestoreBDEstimationView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/estimation/RestoreBDEstimationView.kt @@ -25,6 +25,7 @@ import co.electriccoin.zcash.ui.common.appbar.ZashiTopAppBarTags import co.electriccoin.zcash.ui.design.component.BlankBgScaffold import co.electriccoin.zcash.ui.design.component.ButtonState import co.electriccoin.zcash.ui.design.component.IconButtonState +import co.electriccoin.zcash.ui.design.component.Spacer import co.electriccoin.zcash.ui.design.component.VerticalSpacer import co.electriccoin.zcash.ui.design.component.ZashiButton import co.electriccoin.zcash.ui.design.component.ZashiButtonDefaults @@ -94,7 +95,7 @@ private fun Content( colors = ZashiButtonDefaults.tertiaryColors() ) VerticalSpacer(24.dp) - VerticalSpacer(1f) + Spacer(1f) ZashiButton( state = state.restore, modifier = Modifier.fillMaxWidth(), diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/estimation/RestoreBDEstimationViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/estimation/RestoreBDEstimationViewModel.kt index 59bae604b..116b8e465 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/estimation/RestoreBDEstimationViewModel.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/estimation/RestoreBDEstimationViewModel.kt @@ -18,7 +18,11 @@ class RestoreBDEstimationViewModel( private fun createState() = RestoreBDEstimationState( - dialogButton = IconButtonState(icon = R.drawable.ic_info, onClick = ::onInfoButtonClick), + dialogButton = + IconButtonState( + icon = co.electriccoin.zcash.ui.design.R.drawable.ic_info, + onClick = ::onInfoButtonClick, + ), onBack = ::onBack, text = stringRes("123456"), copy = ButtonState(stringRes(R.string.restore_bd_estimation_copy), icon = R.drawable.ic_copy) {}, diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/height/RestoreBDHeightViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/height/RestoreBDHeightViewModel.kt index d4daae956..42457d6d3 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/height/RestoreBDHeightViewModel.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/height/RestoreBDHeightViewModel.kt @@ -52,7 +52,11 @@ class RestoreBDHeightViewModel( return RestoreBDHeightState( onBack = ::onBack, - dialogButton = IconButtonState(icon = R.drawable.ic_info, onClick = ::onInfoButtonClick), + dialogButton = + IconButtonState( + icon = co.electriccoin.zcash.ui.design.R.drawable.ic_info, + onClick = ::onInfoButtonClick, + ), restore = ButtonState( stringRes(R.string.restore_bd_restore_btn), diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/info/AndroidSeedInfo.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/info/AndroidSeedInfo.kt index de7bdb20b..1f8583a87 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/info/AndroidSeedInfo.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/info/AndroidSeedInfo.kt @@ -1,12 +1,8 @@ package co.electriccoin.zcash.ui.screen.restore.info -import android.view.WindowManager import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.remember -import androidx.compose.ui.platform.LocalView -import androidx.compose.ui.window.DialogWindowProvider import co.electriccoin.zcash.ui.NavigationRouter import kotlinx.serialization.Serializable import org.koin.compose.koinInject @@ -14,14 +10,7 @@ import org.koin.compose.koinInject @OptIn(ExperimentalMaterial3Api::class) @Composable fun AndroidSeedInfo() { - val parent = LocalView.current.parent val navigationRouter = koinInject() - - SideEffect { - (parent as? DialogWindowProvider)?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) - (parent as? DialogWindowProvider)?.window?.setDimAmount(0f) - } - SeedInfoView( state = remember { SeedInfoState(onBack = { navigationRouter.back() }) }, ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/info/SeedInfoView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/info/SeedInfoView.kt index 0ec12f507..88adefbfd 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/info/SeedInfoView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/info/SeedInfoView.kt @@ -4,13 +4,10 @@ import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.layout.width -import androidx.compose.foundation.layout.windowInsetsBottomHeight import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SheetState import androidx.compose.material3.SheetValue @@ -38,14 +35,14 @@ import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography @Composable @OptIn(ExperimentalMaterial3Api::class) internal fun SeedInfoView( - state: SeedInfoState, + state: SeedInfoState?, sheetState: SheetState = rememberScreenModalBottomSheetState(), ) { ZashiScreenModalBottomSheet( state = state, sheetState = sheetState, content = { - Content(state) + Content(it) }, ) } @@ -92,9 +89,6 @@ private fun Content(state: SeedInfoState) { text = stringResource(R.string.restore_dialog_button), onClick = state.onBack ) - - Spacer(modifier = Modifier.height(24.dp)) - Spacer(modifier = Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) } } @@ -102,7 +96,7 @@ private fun Content(state: SeedInfoState) { private fun Info(text: AnnotatedString) { Row { Image( - painterResource(R.drawable.ic_info), + painterResource(co.electriccoin.zcash.ui.design.R.drawable.ic_info), contentDescription = "" ) Spacer(Modifier.width(8.dp)) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/seed/RestoreSeedViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/seed/RestoreSeedViewModel.kt index c992ec6d5..d1ac290e2 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/seed/RestoreSeedViewModel.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/seed/RestoreSeedViewModel.kt @@ -128,7 +128,11 @@ class RestoreSeedViewModel( } ), onBack = ::onBack, - dialogButton = IconButtonState(icon = R.drawable.ic_info, onClick = ::onInfoButtonClick), + dialogButton = + IconButtonState( + icon = co.electriccoin.zcash.ui.design.R.drawable.ic_info, + onClick = ::onInfoButtonClick + ), nextButton = ButtonState( text = stringRes(R.string.restore_button), diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/SeedRecoveryView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/SeedRecoveryView.kt index 476597114..ebb1f8022 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/SeedRecoveryView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/SeedRecoveryView.kt @@ -43,6 +43,7 @@ import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState import co.electriccoin.zcash.ui.design.component.ButtonState import co.electriccoin.zcash.ui.design.component.IconButtonState import co.electriccoin.zcash.ui.design.component.SeedTextState +import co.electriccoin.zcash.ui.design.component.Spacer import co.electriccoin.zcash.ui.design.component.VerticalSpacer import co.electriccoin.zcash.ui.design.component.ZashiButton import co.electriccoin.zcash.ui.design.component.ZashiIconButton @@ -145,7 +146,7 @@ private fun SeedRecoveryMainContent( BDSecret(modifier = Modifier.fillMaxWidth(), state = state.birthday) - VerticalSpacer(1f) + Spacer(1f) ZashiButton( state = state.button, @@ -301,7 +302,7 @@ private fun RevealedPreview() = info = IconButtonState( onClick = {}, - icon = R.drawable.ic_info + icon = co.electriccoin.zcash.ui.design.R.drawable.ic_info ), onBack = {} ) @@ -337,7 +338,7 @@ private fun HiddenPreview() = info = IconButtonState( onClick = {}, - icon = R.drawable.ic_info + icon = co.electriccoin.zcash.ui.design.R.drawable.ic_info ), onBack = {} ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/backup/AndroidSeedBackup.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/backup/AndroidSeedBackup.kt index 715286869..154bb8c90 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/backup/AndroidSeedBackup.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/backup/AndroidSeedBackup.kt @@ -8,20 +8,27 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import co.electriccoin.zcash.di.koinActivityViewModel import co.electriccoin.zcash.ui.NavigationRouter import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel +import co.electriccoin.zcash.ui.screen.home.SeedBackupInfo import co.electriccoin.zcash.ui.screen.restore.info.SeedInfo import co.electriccoin.zcash.ui.screen.seed.SeedRecovery import kotlinx.serialization.Serializable import org.koin.compose.koinInject @Composable -fun AndroidSeedBackup() { +fun AndroidSeedBackup(args: SeedBackup) { val viewModel = koinActivityViewModel() val appBarState by viewModel.walletStateInformation.collectAsStateWithLifecycle() val navigationRouter = koinInject() val state = remember { SeedBackupState( - onBack = { navigationRouter.back() }, + onBack = { + if (args.isOpenedFromSeedBackupInfo) { + navigationRouter.replace(SeedBackupInfo) + } else { + navigationRouter.back() + } + }, onNextClick = { navigationRouter.replace(SeedRecovery) }, onInfoClick = { navigationRouter.forward(SeedInfo) } ) @@ -38,4 +45,6 @@ fun AndroidSeedBackup() { } @Serializable -object SeedBackup +data class SeedBackup( + val isOpenedFromSeedBackupInfo: Boolean +) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/backup/SeedBackupView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/backup/SeedBackupView.kt index bbf4df4f1..5c5ceb0fd 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/backup/SeedBackupView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/backup/SeedBackupView.kt @@ -24,6 +24,7 @@ import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState import co.electriccoin.zcash.ui.design.component.ButtonState import co.electriccoin.zcash.ui.design.component.HorizontalSpacer import co.electriccoin.zcash.ui.design.component.IconButtonState +import co.electriccoin.zcash.ui.design.component.Spacer import co.electriccoin.zcash.ui.design.component.VerticalSpacer import co.electriccoin.zcash.ui.design.component.ZashiButton import co.electriccoin.zcash.ui.design.component.ZashiIconButton @@ -136,12 +137,12 @@ private fun Content( VerticalSpacer(20.dp) - VerticalSpacer(1f) + Spacer(1f) Row { HorizontalSpacer(20.dp) Image( - painter = painterResource(R.drawable.ic_info), + painter = painterResource(co.electriccoin.zcash.ui.design.R.drawable.ic_info), contentDescription = null, colorFilter = ColorFilter.tint(ZashiColors.Utility.WarningYellow.utilityOrange700) ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/AndroidTransactionFilters.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/AndroidTransactionFilters.kt index d5b8d600a..571e4a52e 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/AndroidTransactionFilters.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/AndroidTransactionFilters.kt @@ -1,12 +1,8 @@ package co.electriccoin.zcash.ui.screen.transactionfilters -import android.view.WindowManager import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue -import androidx.compose.ui.platform.LocalView -import androidx.compose.ui.window.DialogWindowProvider import androidx.lifecycle.compose.collectAsStateWithLifecycle import co.electriccoin.zcash.ui.screen.transactionfilters.view.TransactionFiltersView import co.electriccoin.zcash.ui.screen.transactionfilters.viewmodel.TransactionFiltersViewModel @@ -17,13 +13,6 @@ import org.koin.androidx.compose.koinViewModel fun AndroidTransactionFiltersList() { val viewModel = koinViewModel() val state by viewModel.state.collectAsStateWithLifecycle() - val parent = LocalView.current.parent - - SideEffect { - (parent as? DialogWindowProvider)?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) - (parent as? DialogWindowProvider)?.window?.setDimAmount(0f) - } - TransactionFiltersView( state = state, ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/view/TransactionFiltersView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/view/TransactionFiltersView.kt index c07314513..c4330f418 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/view/TransactionFiltersView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/view/TransactionFiltersView.kt @@ -10,12 +10,9 @@ import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.systemBars -import androidx.compose.foundation.layout.windowInsetsBottomHeight import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.verticalScroll @@ -153,11 +150,7 @@ private fun BottomSheetContent(state: TransactionFiltersState?) { colors = ZashiButtonDefaults.primaryColors() ) } - - Spacer(modifier = Modifier.height(24.dp)) } - - Spacer(modifier = Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/AndroidTransactionNote.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/AndroidTransactionNote.kt index 223087877..564c271ab 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/AndroidTransactionNote.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/AndroidTransactionNote.kt @@ -1,12 +1,8 @@ package co.electriccoin.zcash.ui.screen.transactionnote -import android.view.WindowManager import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue -import androidx.compose.ui.platform.LocalView -import androidx.compose.ui.window.DialogWindowProvider import androidx.lifecycle.compose.collectAsStateWithLifecycle import co.electriccoin.zcash.ui.screen.transactionnote.view.TransactionNoteView import co.electriccoin.zcash.ui.screen.transactionnote.viewmodel.TransactionNoteViewModel @@ -18,12 +14,5 @@ import org.koin.core.parameter.parametersOf fun AndroidTransactionNote(transactionNote: TransactionNote) { val viewModel = koinViewModel { parametersOf(transactionNote) } val state by viewModel.state.collectAsStateWithLifecycle() - val parent = LocalView.current.parent - - SideEffect { - (parent as? DialogWindowProvider)?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) - (parent as? DialogWindowProvider)?.window?.setDimAmount(0f) - } - TransactionNoteView(state = state) } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/view/TransactionNoteView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/view/TransactionNoteView.kt index 212ad7fa8..39a0b9bcd 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/view/TransactionNoteView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/view/TransactionNoteView.kt @@ -4,12 +4,9 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.systemBars -import androidx.compose.foundation.layout.windowInsetsBottomHeight import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SheetState import androidx.compose.material3.SheetValue @@ -39,14 +36,14 @@ import co.electriccoin.zcash.ui.screen.transactionnote.model.TransactionNoteStat @Composable @OptIn(ExperimentalMaterial3Api::class) internal fun TransactionNoteView( - state: TransactionNoteState, + state: TransactionNoteState?, sheetState: SheetState = rememberScreenModalBottomSheetState(), ) { ZashiScreenModalBottomSheet( state = state, sheetState = sheetState, content = { - BottomSheetContent(state) + BottomSheetContent(it) }, ) } @@ -121,10 +118,6 @@ private fun BottomSheetContent(state: TransactionNoteState) { ) } } - - Spacer(modifier = Modifier.height(24.dp)) - - Spacer(modifier = Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) } } diff --git a/ui-lib/src/main/res/ui/common/values-es/strings.xml b/ui-lib/src/main/res/ui/common/values-es/strings.xml index a9519301a..e6a6f748a 100644 --- a/ui-lib/src/main/res/ui/common/values-es/strings.xml +++ b/ui-lib/src/main/res/ui/common/values-es/strings.xml @@ -26,4 +26,7 @@ Ignorar + + OK + Remind me later diff --git a/ui-lib/src/main/res/ui/common/values/strings.xml b/ui-lib/src/main/res/ui/common/values/strings.xml index 95fdd0c00..dbdd725c5 100644 --- a/ui-lib/src/main/res/ui/common/values/strings.xml +++ b/ui-lib/src/main/res/ui/common/values/strings.xml @@ -27,4 +27,7 @@ Ignore + + OK + Remind me later diff --git a/ui-lib/src/main/res/ui/exchange_rate/values-es/strings.xml b/ui-lib/src/main/res/ui/exchange_rate/values-es/strings.xml index 287746faa..e5778cbff 100644 --- a/ui-lib/src/main/res/ui/exchange_rate/values-es/strings.xml +++ b/ui-lib/src/main/res/ui/exchange_rate/values-es/strings.xml @@ -13,7 +13,7 @@ Habilitar Guardar cambios - Omitir por ahora + Skip Nota para los más conscientes de la privacidad: Debido a que obtenemos la tasa de conversión de los intercambios, un intercambio podría ver que la tasa de cambio fue consultada antes de que ocurriera una transacción. Habilitar diff --git a/ui-lib/src/main/res/ui/exchange_rate/values/strings.xml b/ui-lib/src/main/res/ui/exchange_rate/values/strings.xml index fb6411b45..df0c60f53 100644 --- a/ui-lib/src/main/res/ui/exchange_rate/values/strings.xml +++ b/ui-lib/src/main/res/ui/exchange_rate/values/strings.xml @@ -15,7 +15,7 @@ Enable Save changes - Skip for now + Skip Note for the super privacy-conscious: Because we pull the conversion rate from exchanges, an exchange might be able to see that the exchange rate was queried before a transaction occurred. diff --git a/ui-lib/src/main/res/ui/home/drawable-night/ic_info_backup.xml b/ui-lib/src/main/res/ui/home/drawable-night/ic_info_backup.xml new file mode 100644 index 000000000..effecc2a4 --- /dev/null +++ b/ui-lib/src/main/res/ui/home/drawable-night/ic_info_backup.xml @@ -0,0 +1,16 @@ + + + + diff --git a/ui-lib/src/main/res/ui/home/drawable-night/ic_info_shield.xml b/ui-lib/src/main/res/ui/home/drawable-night/ic_info_shield.xml new file mode 100644 index 000000000..d77e54a38 --- /dev/null +++ b/ui-lib/src/main/res/ui/home/drawable-night/ic_info_shield.xml @@ -0,0 +1,16 @@ + + + + diff --git a/ui-lib/src/main/res/ui/home/drawable-night/ic_info_wallet_disconnected.xml b/ui-lib/src/main/res/ui/home/drawable-night/ic_info_wallet_disconnected.xml new file mode 100644 index 000000000..501c35098 --- /dev/null +++ b/ui-lib/src/main/res/ui/home/drawable-night/ic_info_wallet_disconnected.xml @@ -0,0 +1,16 @@ + + + + diff --git a/ui-lib/src/main/res/ui/home/drawable-night/ic_transparent_small.xml b/ui-lib/src/main/res/ui/home/drawable-night/ic_transparent_small.xml new file mode 100644 index 000000000..55d1f222b --- /dev/null +++ b/ui-lib/src/main/res/ui/home/drawable-night/ic_transparent_small.xml @@ -0,0 +1,13 @@ + + + diff --git a/ui-lib/src/main/res/ui/home/drawable/ic_info_backup.xml b/ui-lib/src/main/res/ui/home/drawable/ic_info_backup.xml new file mode 100644 index 000000000..bb2f82b2e --- /dev/null +++ b/ui-lib/src/main/res/ui/home/drawable/ic_info_backup.xml @@ -0,0 +1,16 @@ + + + + diff --git a/ui-lib/src/main/res/ui/home/drawable/ic_info_shield.xml b/ui-lib/src/main/res/ui/home/drawable/ic_info_shield.xml new file mode 100644 index 000000000..045fbc998 --- /dev/null +++ b/ui-lib/src/main/res/ui/home/drawable/ic_info_shield.xml @@ -0,0 +1,16 @@ + + + + diff --git a/ui-lib/src/main/res/ui/home/drawable/ic_info_wallet_disconnected.xml b/ui-lib/src/main/res/ui/home/drawable/ic_info_wallet_disconnected.xml new file mode 100644 index 000000000..f0dbdee6e --- /dev/null +++ b/ui-lib/src/main/res/ui/home/drawable/ic_info_wallet_disconnected.xml @@ -0,0 +1,16 @@ + + + + diff --git a/ui-lib/src/main/res/ui/home/drawable/ic_message_currency_conversion.xml b/ui-lib/src/main/res/ui/home/drawable/ic_message_currency_conversion.xml new file mode 100644 index 000000000..ad3f32a98 --- /dev/null +++ b/ui-lib/src/main/res/ui/home/drawable/ic_message_currency_conversion.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/ui-lib/src/main/res/ui/home/drawable/ic_message_disconnected.xml b/ui-lib/src/main/res/ui/home/drawable/ic_message_disconnected.xml new file mode 100644 index 000000000..60141ba6c --- /dev/null +++ b/ui-lib/src/main/res/ui/home/drawable/ic_message_disconnected.xml @@ -0,0 +1,13 @@ + + + diff --git a/ui-lib/src/main/res/ui/home/drawable/ic_message_transparent_balance.xml b/ui-lib/src/main/res/ui/home/drawable/ic_message_transparent_balance.xml new file mode 100644 index 000000000..51cdf1874 --- /dev/null +++ b/ui-lib/src/main/res/ui/home/drawable/ic_message_transparent_balance.xml @@ -0,0 +1,13 @@ + + + diff --git a/ui-lib/src/main/res/ui/home/drawable/ic_transparent_small.xml b/ui-lib/src/main/res/ui/home/drawable/ic_transparent_small.xml new file mode 100644 index 000000000..c5b5a438a --- /dev/null +++ b/ui-lib/src/main/res/ui/home/drawable/ic_transparent_small.xml @@ -0,0 +1,13 @@ + + + diff --git a/ui-lib/src/main/res/ui/home/values-es/strings.xml b/ui-lib/src/main/res/ui/home/values-es/strings.xml index ec3396ab2..6dea31e3c 100644 --- a/ui-lib/src/main/res/ui/home/values-es/strings.xml +++ b/ui-lib/src/main/res/ui/home/values-es/strings.xml @@ -1,11 +1,61 @@ - Wallet Backup Required - Prevent potential loss of funds Receive Send Scan Request Buy More + Wallet Backup Required + Prevent potential loss of funds + Start + Wallet Disconnected + Check your connection and reload Zashi + %s ZEC + Transparent Balance Detected + Shield + Currency Conversion + Enable to display USD values + Start + Updating Balance… + Waiting for last transaction to process + Restoring Wallet • %d%% Complete + Keep Zashi open on active phone screen + Syncing • %d%% Complete + Your wallet is getting updated + Error encountered while syncing + Attempting to resolve + Backup Required + Prevent potential loss of funds by securely backing up your wallet. + Back up access to your funds by backing up: + Secret Recovery Phrase (a unique set of 24 words in a precise + order) + Wallet Birthday Height (block height at which your wallet was + created) + In case you lose access to the app or to your device, knowing the Secret + Recovery Phrase is the only way to recover your funds. We cannot see it and cannot help you recover it. + Anyone with access to your Secret Recovery Phrase will have full control + of your wallet, so keep it secure and never show it to anyone. + Shield + Always Shield Transparent Funds + To protect user privacy, Zashi doesn\'t support spending transparent + ZEC. Tap the \"Shield\" button below to make your transparent funds spendable and your total Zashi balance private. + This will create a shielding in-wallet transaction, consolidating your + transparent and shielded funds. (Typical fee: .001 ZEC) + Transparent + Wallet Disconnected + You appear to be offline. Please restore your internet connection + to use Zashi wallet. + Wallet Restore in Progress + Zashi is scanning the blockchain to retrieve your transactions. Older + wallets can take hours to restore. Follow these steps to prevent interruption: + Keep the Zashi app open on an active phone screen. + To prevent your phone screen from going dark, turn off power-saving + mode and keep your phone plugged in. + Funds cannot be spent until your wallet is restored. + Wallet Sync in Progress + Zashi is scanning the blockchain for your latest transactions to make sure + your balances are displayed correctly. Keep the Zashi app open on an active phone screen to avoid interruptions. + Updating Balance + Your last transaction is getting mined and confirmed. \ No newline at end of file diff --git a/ui-lib/src/main/res/ui/home/values/strings.xml b/ui-lib/src/main/res/ui/home/values/strings.xml index ec3396ab2..6dea31e3c 100644 --- a/ui-lib/src/main/res/ui/home/values/strings.xml +++ b/ui-lib/src/main/res/ui/home/values/strings.xml @@ -1,11 +1,61 @@ - Wallet Backup Required - Prevent potential loss of funds Receive Send Scan Request Buy More + Wallet Backup Required + Prevent potential loss of funds + Start + Wallet Disconnected + Check your connection and reload Zashi + %s ZEC + Transparent Balance Detected + Shield + Currency Conversion + Enable to display USD values + Start + Updating Balance… + Waiting for last transaction to process + Restoring Wallet • %d%% Complete + Keep Zashi open on active phone screen + Syncing • %d%% Complete + Your wallet is getting updated + Error encountered while syncing + Attempting to resolve + Backup Required + Prevent potential loss of funds by securely backing up your wallet. + Back up access to your funds by backing up: + Secret Recovery Phrase (a unique set of 24 words in a precise + order) + Wallet Birthday Height (block height at which your wallet was + created) + In case you lose access to the app or to your device, knowing the Secret + Recovery Phrase is the only way to recover your funds. We cannot see it and cannot help you recover it. + Anyone with access to your Secret Recovery Phrase will have full control + of your wallet, so keep it secure and never show it to anyone. + Shield + Always Shield Transparent Funds + To protect user privacy, Zashi doesn\'t support spending transparent + ZEC. Tap the \"Shield\" button below to make your transparent funds spendable and your total Zashi balance private. + This will create a shielding in-wallet transaction, consolidating your + transparent and shielded funds. (Typical fee: .001 ZEC) + Transparent + Wallet Disconnected + You appear to be offline. Please restore your internet connection + to use Zashi wallet. + Wallet Restore in Progress + Zashi is scanning the blockchain to retrieve your transactions. Older + wallets can take hours to restore. Follow these steps to prevent interruption: + Keep the Zashi app open on an active phone screen. + To prevent your phone screen from going dark, turn off power-saving + mode and keep your phone plugged in. + Funds cannot be spent until your wallet is restored. + Wallet Sync in Progress + Zashi is scanning the blockchain for your latest transactions to make sure + your balances are displayed correctly. Keep the Zashi app open on an active phone screen to avoid interruptions. + Updating Balance + Your last transaction is getting mined and confirmed. \ No newline at end of file