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 new file mode 100644 index 000000000..8f4a4e60f --- /dev/null +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiSpacer.kt @@ -0,0 +1,18 @@ +package co.electriccoin.zcash.ui.design.component + +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp + +@Composable +fun VerticalSpacer(height: Dp) { + Spacer(Modifier.height(height)) +} + +@Composable +fun HorizontalSpacer(width: Dp) { + Spacer(Modifier.width(width)) +} diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiYearMonthWheelDatePicker.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiYearMonthWheelDatePicker.kt new file mode 100644 index 000000000..119fc90d9 --- /dev/null +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiYearMonthWheelDatePicker.kt @@ -0,0 +1,292 @@ +package co.electriccoin.zcash.ui.design.component + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyItemScope +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.setValue +import androidx.compose.runtime.snapshotFlow +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.hapticfeedback.HapticFeedbackType +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.LocalHapticFeedback +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import co.electriccoin.zcash.spackle.Twig +import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors +import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography +import kotlinx.coroutines.launch +import java.text.DateFormatSymbols +import java.time.Month +import java.time.Year +import java.time.YearMonth +import kotlin.math.pow + +@Suppress("MagicNumber") +@Composable +fun ZashiYearMonthWheelDatePicker( + modifier: Modifier = Modifier, + verticallyVisibleItems: Int = 3, + startYear: Year = Year.of(2016), + endYear: Year = Year.now(), + selectedYear: YearMonth = YearMonth.now(), + onSelectionChanged: (YearMonth) -> Unit, +) { + val latestOnSelectionChanged by rememberUpdatedState(onSelectionChanged) + var selectedDate by remember { mutableStateOf(selectedYear) } + val months = + listOf( + Month.JANUARY, + Month.FEBRUARY, + Month.MARCH, + Month.APRIL, + Month.MAY, + Month.JUNE, + Month.JULY, + Month.AUGUST, + Month.SEPTEMBER, + Month.OCTOBER, + Month.NOVEMBER, + Month.DECEMBER + ) + val years = (startYear.value..endYear.value).toList() + + LaunchedEffect(selectedDate) { + Twig.debug { "Selection changed: $selectedDate" } + latestOnSelectionChanged(selectedDate) + } + + Box(modifier = modifier) { + Column( + modifier = + Modifier + .fillMaxWidth() + .align(Alignment.Center), + ) { + ZashiHorizontalDivider(color = ZashiColors.Surfaces.bgQuaternary, thickness = .5.dp) + VerticalSpacer(31.dp) + ZashiHorizontalDivider(color = ZashiColors.Surfaces.bgQuaternary, thickness = .5.dp) + } + Row( + horizontalArrangement = Arrangement.Center + ) { + Spacer(Modifier.weight(.5f)) + WheelLazyList( + modifier = Modifier.weight(1f), + selection = maxOf(months.indexOf(selectedDate.month), 0), + itemCount = months.size, + itemVerticalOffset = verticallyVisibleItems, + isInfiniteScroll = true, + onFocusItem = { selectedDate = selectedDate.withMonth(months[it].value) }, + itemContent = { + Text( + text = DateFormatSymbols().months[months[it].value - 1], + textAlign = TextAlign.Center, + modifier = Modifier.fillParentMaxWidth(), + style = ZashiTypography.header6, + color = ZashiColors.Text.textPrimary, + maxLines = 1 + ) + } + ) + WheelLazyList( + modifier = Modifier.weight(.75f), + selection = years.indexOf(selectedDate.year), + itemCount = years.size, + itemVerticalOffset = verticallyVisibleItems, + isInfiniteScroll = false, + onFocusItem = { selectedDate = selectedDate.withYear(years[it]) }, + itemContent = { + Text( + text = years[it].toString(), + textAlign = TextAlign.Center, + modifier = Modifier.fillParentMaxWidth(), + style = ZashiTypography.header6, + color = ZashiColors.Text.textPrimary, + maxLines = 1 + ) + } + ) + Spacer(Modifier.weight(.5f)) + } + } +} + +@Suppress("MagicNumber") +@Composable +private fun WheelLazyList( + itemCount: Int, + selection: Int, + itemVerticalOffset: Int, + onFocusItem: (Int) -> Unit, + isInfiniteScroll: Boolean, + itemContent: @Composable LazyItemScope.(index: Int) -> Unit, + modifier: Modifier = Modifier, +) { + val latestOnFocusItem by rememberUpdatedState(onFocusItem) + val coroutineScope = rememberCoroutineScope() + val haptic = LocalHapticFeedback.current + val count = if (isInfiniteScroll) itemCount else itemCount + 2 * itemVerticalOffset + val rowOffsetCount = maxOf(1, minOf(itemVerticalOffset, 4)) + val rowCount = (rowOffsetCount * 2) + 1 + val startIndex = if (isInfiniteScroll) selection + (itemCount * 1000) - itemVerticalOffset else selection + val state = rememberLazyListState(startIndex) + val itemHeightPx = with(LocalDensity.current) { 27.dp.toPx() } + val height = 32.dp * rowCount + val isScrollInProgress = state.isScrollInProgress + + LaunchedEffect(itemCount) { + coroutineScope.launch { + state.scrollToItem(startIndex) + } + } + + LaunchedEffect(key1 = isScrollInProgress) { + if (!isScrollInProgress) { + calculateIndexToFocus(state, height).let { + val indexToFocus = + if (isInfiniteScroll) { + (it + rowOffsetCount) % itemCount + } else { + ((it + rowOffsetCount) % count) - itemVerticalOffset + } + + latestOnFocusItem(indexToFocus) + + if (state.firstVisibleItemScrollOffset != 0) { + coroutineScope.launch { + state.animateScrollToItem(it, 0) + } + } + } + } + } + + LaunchedEffect(state) { + snapshotFlow { state.firstVisibleItemIndex } + .collect { + haptic.performHapticFeedback(HapticFeedbackType.LongPress) + } + } + Box( + modifier = + modifier + .height(height) + .fillMaxWidth(), + ) { + LazyColumn( + modifier = + Modifier + .height(height) + .fillMaxWidth(), + state = state, + ) { + items(if (isInfiniteScroll) Int.MAX_VALUE else count) { index -> + val (scale, alpha, translationY) = + remember { + derivedStateOf { + val info = state.layoutInfo + val middleOffset = info.viewportSize.height / 2 + val item = info.visibleItemsInfo.firstOrNull { it.index == index } + val scrollOffset = if (item != null) item.offset + item.size / 2 else -1 + val coefficient = calculateCoefficient(middleOffset = middleOffset, offset = scrollOffset) + val scale = calculateScale(coefficient) + val alpha = calculateAlpha(coefficient) + val translationY = + calculateTranslationY( + coefficient = coefficient, + itemHeightPx = itemHeightPx, + middleOffset = middleOffset, + offset = scrollOffset + ) + Triple(scale, alpha, translationY) + } + }.value + + Box( + modifier = + Modifier + .height(height / rowCount) + .fillMaxWidth() + .graphicsLayer { + this.alpha = alpha + this.scaleX = scale + this.scaleY = scale + this.translationY = translationY + }, + contentAlignment = Alignment.Center, + ) { + if (isInfiniteScroll) { + itemContent(index % itemCount) + } else if (index >= rowOffsetCount && index < itemCount + rowOffsetCount) { + itemContent((index - rowOffsetCount) % itemCount) + } + } + } + } + } +} + +@Suppress("MagicNumber") +private fun calculateCoefficient( + middleOffset: Int, + offset: Int +): Float { + val diff = if (middleOffset > offset) middleOffset - offset else offset - middleOffset + return (1f - (diff.toFloat() / middleOffset.toFloat())).coerceAtLeast(0f) +} + +@Suppress("MagicNumber") +private fun calculateScale(coefficient: Float): Float { + return coefficient.coerceAtLeast(.6f) +} + +@Suppress("MagicNumber") +private fun calculateAlpha(coefficient: Float): Float { + return coefficient.pow(1.1f) +} + +@Suppress("MagicNumber") +private fun calculateTranslationY( + coefficient: Float, + itemHeightPx: Float, + middleOffset: Int, + offset: Int +): Float { + // if (coefficient in 0.66f..1f) return 0f + val exponentialCoefficient = 1.2f - 5f.pow(-(coefficient)) + val offsetBy = (1 - exponentialCoefficient) * itemHeightPx + return if (middleOffset > offset) offsetBy else -offsetBy +} + +@Suppress("MagicNumber") +private fun calculateIndexToFocus( + listState: LazyListState, + height: Dp +): Int { + val currentItem = listState.layoutInfo.visibleItemsInfo.firstOrNull() + var index = currentItem?.index ?: 0 + if (currentItem?.offset != 0 && currentItem != null && currentItem.offset <= -height.value * 3 / 10) { + index++ + } + return index +} 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 6be36ab33..a432e2cc4 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 @@ -19,6 +19,7 @@ import co.electriccoin.zcash.ui.screen.integrations.viewmodel.IntegrationsViewMo import co.electriccoin.zcash.ui.screen.qrcode.viewmodel.QrCodeViewModel import co.electriccoin.zcash.ui.screen.receive.viewmodel.ReceiveViewModel import co.electriccoin.zcash.ui.screen.request.viewmodel.RequestViewModel +import co.electriccoin.zcash.ui.screen.restore.date.RestoreBDDateViewModel import co.electriccoin.zcash.ui.screen.restore.height.RestoreBDHeightViewModel import co.electriccoin.zcash.ui.screen.restore.seed.RestoreSeedViewModel import co.electriccoin.zcash.ui.screen.restoresuccess.viewmodel.RestoreSuccessViewModel @@ -156,4 +157,5 @@ val viewModelModule = viewModelOf(::BalanceViewModel) viewModelOf(::HomeViewModel) viewModelOf(::RestoreBDHeightViewModel) + viewModelOf(::RestoreBDDateViewModel) } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/AndroidOnboarding.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/AndroidOnboarding.kt index f1f63637f..f7f842407 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/AndroidOnboarding.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/AndroidOnboarding.kt @@ -29,6 +29,8 @@ import co.electriccoin.zcash.ui.design.animation.ScreenAnimation.popEnterTransit import co.electriccoin.zcash.ui.design.animation.ScreenAnimation.popExitTransition import co.electriccoin.zcash.ui.screen.flexa.FlexaViewModel import co.electriccoin.zcash.ui.screen.onboarding.view.Onboarding +import co.electriccoin.zcash.ui.screen.restore.date.AndroidRestoreBDDate +import co.electriccoin.zcash.ui.screen.restore.date.RestoreBDDate import co.electriccoin.zcash.ui.screen.restore.height.AndroidRestoreBDHeight import co.electriccoin.zcash.ui.screen.restore.height.RestoreBDHeight import co.electriccoin.zcash.ui.screen.restore.seed.AndroidRestoreSeed @@ -101,6 +103,9 @@ fun MainActivity.RestoreNavigation() { composable { AndroidRestoreBDHeight() } + composable { + AndroidRestoreBDDate() + } } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/AndroidRestoreBDDate.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/AndroidRestoreBDDate.kt new file mode 100644 index 000000000..0b6c25f6a --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/AndroidRestoreBDDate.kt @@ -0,0 +1,24 @@ +package co.electriccoin.zcash.ui.screen.restore.date + +import androidx.activity.compose.BackHandler +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import co.electriccoin.zcash.ui.screen.restore.RestoreSeedDialog +import kotlinx.serialization.Serializable +import org.koin.androidx.compose.koinViewModel + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AndroidRestoreBDDate() { + val vm = koinViewModel() + val state by vm.state.collectAsStateWithLifecycle() + val dialogState by vm.dialogState.collectAsStateWithLifecycle() + RestoreBDDateView(state) + BackHandler { state.onBack() } + RestoreSeedDialog(dialogState) +} + +@Serializable +data object RestoreBDDate diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/RestoreBDDateState.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/RestoreBDDateState.kt new file mode 100644 index 000000000..0192cf861 --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/RestoreBDDateState.kt @@ -0,0 +1,10 @@ +package co.electriccoin.zcash.ui.screen.restore.date + +import co.electriccoin.zcash.ui.design.component.ButtonState +import co.electriccoin.zcash.ui.design.component.IconButtonState + +data class RestoreBDDateState( + val next: ButtonState, + val dialogButton: IconButtonState, + val onBack: () -> Unit +) 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 new file mode 100644 index 000000000..45c354f1a --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/RestoreBDDateView.kt @@ -0,0 +1,156 @@ +@file:Suppress("TooManyFunctions") + +package co.electriccoin.zcash.ui.screen.restore.date + +import androidx.compose.foundation.Image +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.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +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.platform.testTag +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.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.ZashiButton +import co.electriccoin.zcash.ui.design.component.ZashiIconButton +import co.electriccoin.zcash.ui.design.component.ZashiSmallTopAppBar +import co.electriccoin.zcash.ui.design.component.ZashiTopAppBarBackNavigation +import co.electriccoin.zcash.ui.design.component.ZashiYearMonthWheelDatePicker +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.orDark +import co.electriccoin.zcash.ui.design.util.scaffoldPadding +import co.electriccoin.zcash.ui.design.util.stringRes + +@Composable +fun RestoreBDDateView(state: RestoreBDDateState) { + BlankBgScaffold( + topBar = { AppBar(state) }, + bottomBar = {}, + content = { padding -> + Content( + state = state, + modifier = + Modifier + .fillMaxSize() + .verticalScroll(rememberScrollState()) + .scaffoldPadding(padding) + ) + } + ) +} + +@Composable +private fun Content( + state: RestoreBDDateState, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier + ) { + Text( + text = stringResource(R.string.restore_bd_date_subtitle), + style = ZashiTypography.header6, + color = ZashiColors.Text.textPrimary, + fontWeight = FontWeight.SemiBold + ) + Spacer(Modifier.height(8.dp)) + Text( + text = stringResource(R.string.restore_bd_date_message), + style = ZashiTypography.textSm, + color = ZashiColors.Text.textPrimary + ) + Spacer(Modifier.height(24.dp)) + + ZashiYearMonthWheelDatePicker( + modifier = Modifier.fillMaxWidth() + ) {} + + Spacer(Modifier.height(24.dp)) + + Spacer(Modifier.weight(1f)) + + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.Center + ) { + Image( + painterResource(R.drawable.ic_info), + contentDescription = "", + colorFilter = ColorFilter.tint(color = ZashiColors.Utility.Indigo.utilityIndigo700) + ) + Spacer(Modifier.width(8.dp)) + Text( + modifier = Modifier.padding(top = 2.dp), + text = stringResource(R.string.restore_bd_date_note), + style = ZashiTypography.textXs, + fontWeight = FontWeight.Medium, + color = ZashiColors.Utility.Indigo.utilityIndigo700 + ) + } + + Spacer(Modifier.height(24.dp)) + + ZashiButton( + state.next, + modifier = Modifier.fillMaxWidth(), + ) + } +} + +@Composable +private fun AppBar(state: RestoreBDDateState) { + ZashiSmallTopAppBar( + title = stringResource(R.string.restore_title), + navigationAction = { + ZashiTopAppBarBackNavigation( + onBack = state.onBack, + modifier = Modifier.testTag(ZashiTopAppBarTags.BACK) + ) + }, + regularActions = { + ZashiIconButton(state.dialogButton, modifier = Modifier.size(40.dp)) + Spacer(Modifier.width(20.dp)) + }, + colors = + ZcashTheme.colors.topAppBarColors orDark + ZcashTheme.colors.topAppBarColors.copyColors( + containerColor = Color.Transparent + ), + ) +} + +@PreviewScreens +@Composable +private fun Preview() = + ZcashTheme { + RestoreBDDateView( + state = + RestoreBDDateState( + next = ButtonState(stringRes("Estimate")) {}, + dialogButton = IconButtonState(R.drawable.ic_restore_dialog) {}, + onBack = {} + ) + ) + } 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 new file mode 100644 index 000000000..0c1a9094b --- /dev/null +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/date/RestoreBDDateViewModel.kt @@ -0,0 +1,63 @@ +package co.electriccoin.zcash.ui.screen.restore.date + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +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.design.component.ButtonState +import co.electriccoin.zcash.ui.design.component.IconButtonState +import co.electriccoin.zcash.ui.design.util.stringRes +import co.electriccoin.zcash.ui.screen.restore.RestoreSeedDialogState +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.WhileSubscribed +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.flow.update + +class RestoreBDDateViewModel( + private val navigationRouter: NavigationRouter +) : ViewModel() { + private val isDialogVisible = MutableStateFlow(false) + + val dialogState = + isDialogVisible + .map { isDialogVisible -> + RestoreSeedDialogState( + ::onCloseDialogClick + ).takeIf { isDialogVisible } + } + .stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT), + initialValue = null + ) + + val state: StateFlow = MutableStateFlow(createState()).asStateFlow() + + private fun createState() = + RestoreBDDateState( + next = ButtonState(stringRes(R.string.restore_bd_height_btn), onClick = ::onEstimateClick), + dialogButton = IconButtonState(icon = R.drawable.ic_info, onClick = ::onInfoButtonClick), + onBack = ::onBack, + ) + + private fun onEstimateClick() { + // do nothing + } + + private fun onBack() { + navigationRouter.back() + } + + private fun onInfoButtonClick() { + isDialogVisible.update { true } + } + + private fun onCloseDialogClick() { + isDialogVisible.update { false } + } +} 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 708566c93..0b279f1a8 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 @@ -10,6 +10,7 @@ import co.electriccoin.zcash.ui.design.component.IconButtonState import co.electriccoin.zcash.ui.design.component.TextFieldState import co.electriccoin.zcash.ui.design.util.stringRes import co.electriccoin.zcash.ui.screen.restore.RestoreSeedDialogState +import co.electriccoin.zcash.ui.screen.restore.date.RestoreBDDate import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -59,7 +60,7 @@ class RestoreBDHeightViewModel( ) private fun onEstimateClick() { - // do nothing + navigationRouter.forward(RestoreBDDate) } private fun onRestoreClick() { 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 f1e3bda13..375e83584 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 @@ -23,7 +23,6 @@ import kotlinx.coroutines.flow.update class RestoreSeedViewModel( private val navigationRouter: NavigationRouter ) : ViewModel() { - @Suppress("MagicNumber") private val seedWords = MutableStateFlow( diff --git a/ui-lib/src/main/res/ui/restore/values/strings.xml b/ui-lib/src/main/res/ui/restore/values/strings.xml index 7206eb999..61827fc28 100644 --- a/ui-lib/src/main/res/ui/restore/values/strings.xml +++ b/ui-lib/src/main/res/ui/restore/values/strings.xml @@ -26,4 +26,10 @@ Enter number Wallet Birthday Height is the point in time when your wallet was created. + First Wallet Transaction + Entering the block height at which your wallet was created reduces the + number of blocks that need to be scanned to recover your wallet. + If you’re not sure, choose an earlier date. + Next +