Wallet backup message

This commit is contained in:
Milan Cerovsky 2025-04-01 13:06:24 +02:00
parent 9cd31dfee4
commit 0209bec72b
12 changed files with 390 additions and 220 deletions

View File

@ -551,8 +551,8 @@ val DarkZashiColorsInternal =
utilityEspresso600 = Espresso.`300`, utilityEspresso600 = Espresso.`300`,
utilityEspresso500 = Espresso.`400`, utilityEspresso500 = Espresso.`400`,
utilityEspresso200 = Espresso.`700`, utilityEspresso200 = Espresso.`700`,
utilityEspresso50 = Espresso.`900`, utilityEspresso50 = Espresso.`950`,
utilityEspresso100 = Espresso.`800`, utilityEspresso100 = Espresso.`900`,
utilityEspresso400 = Espresso.`500`, utilityEspresso400 = Espresso.`500`,
utilityEspresso300 = Espresso.`600`, utilityEspresso300 = Espresso.`600`,
utilityEspresso900 = Espresso.`50`, utilityEspresso900 = Espresso.`50`,

View File

@ -1,6 +1,7 @@
package co.electriccoin.zcash.ui.screen.home package co.electriccoin.zcash.ui.screen.home
import co.electriccoin.zcash.ui.design.component.BigIconButtonState import co.electriccoin.zcash.ui.design.component.BigIconButtonState
import co.electriccoin.zcash.ui.screen.home.messages.HomeMessageState
data class HomeState( data class HomeState(
val firstButton: BigIconButtonState, val firstButton: BigIconButtonState,
@ -10,11 +11,6 @@ data class HomeState(
val message: HomeMessageState? val message: HomeMessageState?
) )
data class HomeMessageState(
val text: String,
val onClick: () -> Unit
)
data class HomeRestoreDialogState( data class HomeRestoreDialogState(
val onClick: () -> Unit val onClick: () -> Unit
) )

View File

@ -1,13 +1,5 @@
package co.electriccoin.zcash.ui.screen.home package co.electriccoin.zcash.ui.screen.home
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -18,9 +10,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -28,20 +18,8 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.ClipOp
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.DefaultShadowColor
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.addOutline
import androidx.compose.ui.graphics.drawscope.clipPath
import androidx.compose.ui.platform.testTag import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.appbar.ZashiMainTopAppBarState import co.electriccoin.zcash.ui.common.appbar.ZashiMainTopAppBarState
import co.electriccoin.zcash.ui.common.appbar.ZashiTopAppBarWithAccountSelection import co.electriccoin.zcash.ui.common.appbar.ZashiTopAppBarWithAccountSelection
@ -50,13 +28,14 @@ import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
import co.electriccoin.zcash.ui.design.component.ZashiBigIconButton import co.electriccoin.zcash.ui.design.component.ZashiBigIconButton
import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
import co.electriccoin.zcash.ui.design.util.scaffoldPadding import co.electriccoin.zcash.ui.design.util.scaffoldPadding
import co.electriccoin.zcash.ui.design.util.stringRes import co.electriccoin.zcash.ui.design.util.stringRes
import co.electriccoin.zcash.ui.fixture.BalanceStateFixture import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.fixture.ZashiMainTopAppBarStateFixture import co.electriccoin.zcash.ui.fixture.ZashiMainTopAppBarStateFixture
import co.electriccoin.zcash.ui.screen.balances.BalanceState import co.electriccoin.zcash.ui.screen.balances.BalanceState
import co.electriccoin.zcash.ui.screen.balances.BalanceWidget 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.HomeMessageState
import co.electriccoin.zcash.ui.screen.transactionhistory.widget.TransactionHistoryWidgetState 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.TransactionHistoryWidgetStateFixture
import co.electriccoin.zcash.ui.screen.transactionhistory.widget.createTransactionHistoryWidgets import co.electriccoin.zcash.ui.screen.transactionhistory.widget.createTransactionHistoryWidgets
@ -110,7 +89,7 @@ private fun Content(
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge)) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge))
NavButtons(paddingValues, state) NavButtons(paddingValues, state)
Spacer(Modifier.height(16.dp)) Spacer(Modifier.height(16.dp))
Message(state.message) HomeMessage(state.message)
LazyColumn( LazyColumn(
modifier = modifier =
Modifier Modifier
@ -125,112 +104,6 @@ private fun Content(
} }
} }
@Composable
private fun Message(state: HomeMessageState?) {
val cutoutHeight = 16.dp
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)
)
Box(
modifier = Modifier
.background(Color.Gray)
.clickable(onClick = { normalizedState?.onClick?.invoke() })
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(cutoutHeight)
.zIndex(2f)
.bottomOnlyShadow(
elevation = 2.dp,
shape = RoundedCornerShape(bottomStart = 32.dp, bottomEnd = 32.dp),
backgroundColor = ZashiColors.Surfaces.bgPrimary
)
,
)
Box(
modifier = Modifier
.fillMaxWidth()
.height(cutoutHeight)
.zIndex(1f)
.align(Alignment.BottomCenter)
.topOnlyShadow(
elevation = 2.dp,
shape = RoundedCornerShape(topStart = bottomCornerSize, topEnd = bottomCornerSize),
backgroundColor = ZashiColors.Surfaces.bgPrimary
),
)
}
LaunchedEffect(state) {
if (state != null) {
normalizedState = state
isVisible = true
} else {
isVisible = false
delay(350)
normalizedState = null
}
}
}
private fun Modifier.bottomOnlyShadow(
elevation: Dp,
shape: Shape,
backgroundColor: Color,
clip: Boolean = elevation > 0.dp,
ambientColor: Color = DefaultShadowColor,
spotColor: Color = DefaultShadowColor,
): Modifier = this
.drawWithCache {
// bottom shadow offset in Px based on elevation
val bottomOffsetPx = elevation.toPx()
// Adjust the size to extend the bottom by the bottom shadow offset
val adjustedSize = Size(size.width, size.height + bottomOffsetPx)
val outline = shape.createOutline(adjustedSize, layoutDirection, this)
val path = Path().apply { addOutline(outline) }
onDrawWithContent {
clipPath(path, ClipOp.Intersect) {
this@onDrawWithContent.drawContent()
}
}
}
.shadow(elevation, shape, clip, ambientColor, spotColor)
.background(
backgroundColor,
shape
)
private fun Modifier.topOnlyShadow(
elevation: Dp,
shape: Shape,
backgroundColor: Color,
clip: Boolean = elevation > 0.dp,
ambientColor: Color = DefaultShadowColor,
spotColor: Color = DefaultShadowColor,
): Modifier = this
.drawWithCache {
// Adjust the size to extend the bottom by the bottom shadow offset
val adjustedSize = Size(size.width, size.height)
val outline = shape.createOutline(adjustedSize, layoutDirection, this)
val path = Path().apply { addOutline(outline) }
onDrawWithContent {
clipPath(path, ClipOp.Intersect) {
this@onDrawWithContent.drawContent()
}
}
}
.shadow(elevation, shape, clip, ambientColor, spotColor)
.background(
backgroundColor,
shape
)
@Composable @Composable
private fun NavButtons( private fun NavButtons(
paddingValues: PaddingValues, paddingValues: PaddingValues,
@ -301,18 +174,7 @@ private fun Preview() {
icon = R.drawable.ic_warning, icon = R.drawable.ic_warning,
onClick = {} onClick = {}
), ),
message = HomeMessageState( message = null.takeIf { isHomeMessageStateVisible }
text = "Test string",
onClick = {
isHomeMessageStateVisible = !isHomeMessageStateVisible
if (!isHomeMessageStateVisible) {
scope.launch {
delay(1000)
isHomeMessageStateVisible = true
}
}
}
).takeIf { isHomeMessageStateVisible }
) )
) )
} }

View File

@ -8,17 +8,20 @@ import co.electriccoin.zcash.ui.NavigationTargets
import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.model.DistributionDimension import co.electriccoin.zcash.ui.common.model.DistributionDimension
import co.electriccoin.zcash.ui.common.model.KeystoneAccount import co.electriccoin.zcash.ui.common.model.KeystoneAccount
import co.electriccoin.zcash.ui.common.model.WalletAccount
import co.electriccoin.zcash.ui.common.provider.GetVersionInfoProvider import co.electriccoin.zcash.ui.common.provider.GetVersionInfoProvider
import co.electriccoin.zcash.ui.common.usecase.GetSelectedWalletAccountUseCase import co.electriccoin.zcash.ui.common.usecase.GetSelectedWalletAccountUseCase
import co.electriccoin.zcash.ui.common.usecase.IsRestoreSuccessDialogVisibleUseCase import co.electriccoin.zcash.ui.common.usecase.IsRestoreSuccessDialogVisibleUseCase
import co.electriccoin.zcash.ui.common.usecase.NavigateToCoinbaseUseCase import co.electriccoin.zcash.ui.common.usecase.NavigateToCoinbaseUseCase
import co.electriccoin.zcash.ui.design.component.BigIconButtonState import co.electriccoin.zcash.ui.design.component.BigIconButtonState
import co.electriccoin.zcash.ui.design.util.stringRes import co.electriccoin.zcash.ui.design.util.stringRes
import co.electriccoin.zcash.ui.screen.home.messages.WalletBackupMessageState
import co.electriccoin.zcash.ui.screen.integrations.DialogIntegrations import co.electriccoin.zcash.ui.screen.integrations.DialogIntegrations
import co.electriccoin.zcash.ui.screen.receive.Receive import co.electriccoin.zcash.ui.screen.receive.Receive
import co.electriccoin.zcash.ui.screen.receive.model.ReceiveAddressType import co.electriccoin.zcash.ui.screen.receive.model.ReceiveAddressType
import co.electriccoin.zcash.ui.screen.scan.Scan import co.electriccoin.zcash.ui.screen.scan.Scan
import co.electriccoin.zcash.ui.screen.scan.ScanFlow 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 co.electriccoin.zcash.ui.screen.send.Send
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@ -28,7 +31,6 @@ import kotlinx.coroutines.flow.WhileSubscribed
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class HomeViewModel( class HomeViewModel(
@ -64,7 +66,18 @@ class HomeViewModel(
val state: StateFlow<HomeState?> = val state: StateFlow<HomeState?> =
combine(getSelectedWalletAccountUseCase.observe(), isMessageVisible) { selectedAccount, isMessageVisible -> combine(getSelectedWalletAccountUseCase.observe(), isMessageVisible) { selectedAccount, isMessageVisible ->
HomeState( createState(getVersionInfoProvider, selectedAccount, isMessageVisible)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT),
initialValue = null
)
private fun createState(
getVersionInfoProvider: GetVersionInfoProvider,
selectedAccount: WalletAccount?,
isMessageVisible: Boolean
) = HomeState(
firstButton = firstButton =
BigIconButtonState( BigIconButtonState(
text = stringRes("Receive"), text = stringRes("Receive"),
@ -106,20 +119,18 @@ class HomeViewModel(
onClick = ::onMoreButtonClick, onClick = ::onMoreButtonClick,
) )
}, },
message = HomeMessageState( message = createWalletBackupMessageState().takeIf { isMessageVisible }
text = "Test string",
onClick = {
this@HomeViewModel.isMessageVisible.update { !it }
}
).takeIf { isMessageVisible }
)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT),
initialValue = null
) )
fun onRestoreDialogSeenClick() = private fun createWalletBackupMessageState(): WalletBackupMessageState {
return WalletBackupMessageState(
onClick = {
navigationRouter.forward(SeedBackup)
}
)
}
private fun onRestoreDialogSeenClick() =
viewModelScope.launch { viewModelScope.launch {
isRestoreSuccessDialogVisible.setSeen() isRestoreSuccessDialogVisible.setSeen()
} }

View File

@ -0,0 +1,162 @@
package co.electriccoin.zcash.ui.screen.home.messages
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandIn
import androidx.compose.animation.shrinkOut
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.ClipOp
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.DefaultShadowColor
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.addOutline
import androidx.compose.ui.graphics.drawscope.clipPath
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
import kotlinx.coroutines.delay
@Composable
fun HomeMessage(state: HomeMessageState?) {
val cutoutHeight = 16.dp
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)
)
Box(
modifier = Modifier
.background(Color.Gray)
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(cutoutHeight)
.zIndex(2f)
.bottomOnlyShadow(
elevation = 2.dp,
shape = RoundedCornerShape(bottomStart = 32.dp, bottomEnd = 32.dp),
backgroundColor = ZashiColors.Surfaces.bgPrimary
),
)
AnimatedVisibility(
modifier = Modifier
.fillMaxWidth()
.zIndex(0f),
visible = isVisible,
enter = expandIn(animationSpec = tween(350)),
exit = shrinkOut(animationSpec = tween(350))
) {
when (normalizedState) {
is WalletBackupMessageState -> WalletBackupMessage(
state = normalizedState as WalletBackupMessageState,
contentPadding = PaddingValues(
vertical = cutoutHeight
)
)
null -> {
// do nothing
}
}
}
Box(
modifier = Modifier
.fillMaxWidth()
.height(cutoutHeight)
.zIndex(1f)
.align(Alignment.BottomCenter)
.topOnlyShadow(
elevation = 2.dp,
shape = RoundedCornerShape(topStart = bottomCornerSize, topEnd = bottomCornerSize),
backgroundColor = ZashiColors.Surfaces.bgPrimary
),
)
}
LaunchedEffect(state) {
if (state != null) {
normalizedState = state
isVisible = true
} else {
isVisible = false
delay(350)
normalizedState = null
}
}
}
private fun Modifier.bottomOnlyShadow(
elevation: Dp,
shape: Shape,
backgroundColor: Color,
clip: Boolean = elevation > 0.dp,
ambientColor: Color = DefaultShadowColor,
spotColor: Color = DefaultShadowColor,
): Modifier = this
.drawWithCache {
// bottom shadow offset in Px based on elevation
val bottomOffsetPx = elevation.toPx()
// Adjust the size to extend the bottom by the bottom shadow offset
val adjustedSize = Size(size.width, size.height + bottomOffsetPx)
val outline = shape.createOutline(adjustedSize, layoutDirection, this)
val path = Path().apply { addOutline(outline) }
onDrawWithContent {
clipPath(path, ClipOp.Intersect) {
this@onDrawWithContent.drawContent()
}
}
}
.shadow(elevation, shape, clip, ambientColor, spotColor)
.background(
backgroundColor,
shape
)
private fun Modifier.topOnlyShadow(
elevation: Dp,
shape: Shape,
backgroundColor: Color,
clip: Boolean = elevation > 0.dp,
ambientColor: Color = DefaultShadowColor,
spotColor: Color = DefaultShadowColor,
): Modifier = this
.drawWithCache {
// Adjust the size to extend the bottom by the bottom shadow offset
val adjustedSize = Size(size.width, size.height)
val outline = shape.createOutline(adjustedSize, layoutDirection, this)
val path = Path().apply { addOutline(outline) }
onDrawWithContent {
clipPath(path, ClipOp.Intersect) {
this@onDrawWithContent.drawContent()
}
}
}
.shadow(elevation, shape, clip, ambientColor, spotColor)
.background(
backgroundColor,
shape
)

View File

@ -0,0 +1,3 @@
package co.electriccoin.zcash.ui.screen.home.messages
sealed interface HomeMessageState

View File

@ -0,0 +1,37 @@
package co.electriccoin.zcash.ui.screen.home.messages
import androidx.compose.foundation.layout.Box
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.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
@Composable
fun HomeMessageWrapper(
color: Color,
contentPadding: PaddingValues,
content: @Composable RowScope.() -> Unit,
) {
Surface(
color = color,
) {
Box(
modifier = Modifier.padding(contentPadding)
) {
Row(
modifier = Modifier.padding(
horizontal = 16.dp,
vertical = 14.dp
),
verticalAlignment = Alignment.CenterVertically,
content = content
)
}
}
}

View File

@ -0,0 +1,81 @@
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.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
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.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
@Composable
fun WalletBackupMessage(state: WalletBackupMessageState, contentPadding: PaddingValues) {
HomeMessageWrapper(
color = ZashiColors.Utility.Espresso.utilityEspresso100,
contentPadding = contentPadding,
) {
Image(
painter = painterResource(R.drawable.ic_warning_triangle),
contentDescription = null
)
HorizontalSpacer(16.dp)
Column(
modifier = Modifier.weight(1f)
) {
Text(
stringResource(R.string.home_message_backup_required_title),
style = ZashiTypography.textSm,
fontWeight = FontWeight.Medium,
color = ZashiColors.Utility.Espresso.utilityEspresso900
)
VerticalSpacer(2.dp)
Text(
text = stringResource(R.string.home_message_backup_required_subtitle),
style = ZashiTypography.textXs,
fontWeight = FontWeight.Medium,
color = ZashiColors.Utility.Espresso.utilityEspresso700
)
}
ZashiButton(
modifier = Modifier.height(36.dp),
state = ButtonState(
onClick = state.onClick,
text = stringRes("Start")
)
)
}
}
@Immutable
data class WalletBackupMessageState(
val onClick: () -> Unit,
) : HomeMessageState
@PreviewScreens
@Composable
private fun Preview() = ZcashTheme {
BlankSurface {
WalletBackupMessage(
state = WalletBackupMessageState(
onClick = {}
),
contentPadding = PaddingValues()
)
}
}

View File

@ -6,6 +6,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.window.DialogWindowProvider import androidx.compose.ui.window.DialogWindowProvider
@ -21,7 +22,6 @@ import org.koin.compose.koinInject
fun AndroidSeedInfo() { fun AndroidSeedInfo() {
val parent = LocalView.current.parent val parent = LocalView.current.parent
val navigationRouter = koinInject<NavigationRouter>() val navigationRouter = koinInject<NavigationRouter>()
val scope = rememberCoroutineScope()
SideEffect { SideEffect {
(parent as? DialogWindowProvider)?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) (parent as? DialogWindowProvider)?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
@ -40,21 +40,8 @@ fun AndroidSeedInfo() {
SeedInfoView( SeedInfoView(
sheetState = sheetState, sheetState = sheetState,
state = state = remember { SeedInfoState(onBack = { navigationRouter.back() }) },
SeedInfoState( onDismissRequest = { navigationRouter.back() }
onBack = {
scope.launch {
// sheetState.hide()
navigationRouter.back()
}
}
),
onDismissRequest = {
scope.launch {
// sheetState.hide()
navigationRouter.back()
}
}
) )
LaunchedEffect(Unit) { LaunchedEffect(Unit) {

View File

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M10,7.5V10.833M10,14.167H10.009M8.846,3.243L1.992,15.082C1.612,15.739 1.422,16.067 1.45,16.336C1.474,16.571 1.598,16.785 1.789,16.924C2.008,17.083 2.387,17.083 3.146,17.083H16.854C17.613,17.083 17.992,17.083 18.212,16.924C18.403,16.785 18.526,16.571 18.55,16.336C18.578,16.067 18.388,15.739 18.008,15.082L11.154,3.243C10.775,2.589 10.586,2.262 10.339,2.152C10.123,2.056 9.877,2.056 9.662,2.152C9.414,2.262 9.225,2.589 8.846,3.243Z"
android:strokeLineJoin="round"
android:strokeWidth="1.66667"
android:fillColor="#00000000"
android:strokeColor="#EBE9E9"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M10,7.5V10.833M10,14.167H10.009M8.846,3.243L1.992,15.082C1.612,15.739 1.422,16.067 1.45,16.336C1.474,16.572 1.598,16.785 1.789,16.924C2.008,17.083 2.387,17.083 3.146,17.083H16.854C17.613,17.083 17.992,17.083 18.212,16.924C18.403,16.785 18.526,16.572 18.55,16.336C18.578,16.067 18.388,15.739 18.008,15.082L11.154,3.243C10.775,2.589 10.586,2.262 10.339,2.152C10.123,2.056 9.877,2.056 9.662,2.152C9.414,2.262 9.225,2.589 8.846,3.243Z"
android:strokeLineJoin="round"
android:strokeWidth="1.66667"
android:fillColor="#00000000"
android:strokeColor="#332424"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="home_message_backup_required_title">Wallet Backup Required</string>
<string name="home_message_backup_required_subtitle">Prevent potential loss of funds</string>
</resources>