Home messages business logic, wallet info removed from status bar and general refactoring
This commit is contained in:
parent
2f12bea435
commit
d6d500eaed
|
@ -29,5 +29,7 @@ interface PreferenceProvider {
|
||||||
|
|
||||||
fun observe(key: PreferenceKey): Flow<String?>
|
fun observe(key: PreferenceKey): Flow<String?>
|
||||||
|
|
||||||
|
suspend fun remove(key: PreferenceKey)
|
||||||
|
|
||||||
suspend fun clearPreferences(): Boolean
|
suspend fun clearPreferences(): Boolean
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,6 @@ data class NullableBooleanPreferenceDefault(
|
||||||
preferenceProvider: PreferenceProvider,
|
preferenceProvider: PreferenceProvider,
|
||||||
newValue: Boolean?
|
newValue: Boolean?
|
||||||
) {
|
) {
|
||||||
preferenceProvider.putString(key, newValue.toString())
|
preferenceProvider.putString(key, newValue?.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package co.electriccoin.zcash.preference.model.entry
|
||||||
|
|
||||||
|
import co.electriccoin.zcash.preference.api.PreferenceProvider
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
class TimestampPreferenceDefault(override val key: PreferenceKey): PreferenceDefault<Instant?> {
|
||||||
|
override suspend fun getValue(preferenceProvider: PreferenceProvider) =
|
||||||
|
preferenceProvider.getLong(key)?.let { Instant.ofEpochMilli(it) }
|
||||||
|
|
||||||
|
override suspend fun putValue(
|
||||||
|
preferenceProvider: PreferenceProvider,
|
||||||
|
newValue: Instant?
|
||||||
|
) = preferenceProvider.putLong(key, newValue?.toEpochMilli())
|
||||||
|
}
|
|
@ -22,6 +22,10 @@ class MockPreferenceProvider(
|
||||||
// For the mock implementation, does not support observability of changes
|
// For the mock implementation, does not support observability of changes
|
||||||
override fun observe(key: PreferenceKey): Flow<String?> = flow { emit(getString(key)) }
|
override fun observe(key: PreferenceKey): Flow<String?> = flow { emit(getString(key)) }
|
||||||
|
|
||||||
|
override suspend fun remove(key: PreferenceKey) {
|
||||||
|
map.remove(key.key)
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun clearPreferences(): Boolean {
|
override suspend fun clearPreferences(): Boolean {
|
||||||
map.clear()
|
map.clear()
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -140,6 +140,17 @@ class AndroidPreferenceProvider private constructor(
|
||||||
}.flowOn(dispatcher)
|
}.flowOn(dispatcher)
|
||||||
.map { getString(key) }
|
.map { getString(key) }
|
||||||
|
|
||||||
|
@SuppressLint("ApplySharedPref")
|
||||||
|
override suspend fun remove(key: PreferenceKey) {
|
||||||
|
withContext(dispatcher) {
|
||||||
|
val editor = sharedPreferences.edit()
|
||||||
|
|
||||||
|
editor.remove(key.key)
|
||||||
|
|
||||||
|
editor.commit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
suspend fun newStandard(
|
suspend fun newStandard(
|
||||||
context: Context,
|
context: Context,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package co.electriccoin.zcash.ui.design.component
|
package co.electriccoin.zcash.ui.design.component
|
||||||
|
|
||||||
import androidx.annotation.IntRange
|
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.ProgressIndicatorDefaults
|
import androidx.compose.material3.ProgressIndicatorDefaults
|
||||||
|
@ -36,8 +35,8 @@ fun ZashiCircularProgressIndicator(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ZashiCircularProgressIndicator(
|
fun ZashiCircularProgressIndicatorByPercent(
|
||||||
@IntRange(from = 0, to = 100) progressPercent: Int,
|
progressPercent: Float,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
colors: ZashiCircularProgressIndicatorColors =
|
colors: ZashiCircularProgressIndicatorColors =
|
||||||
LocalZashiCircularProgressIndicatorColors.current
|
LocalZashiCircularProgressIndicatorColors.current
|
||||||
|
|
|
@ -28,8 +28,7 @@ val DarkZashiColorsInternal =
|
||||||
textError = ErrorRed.`300`,
|
textError = ErrorRed.`300`,
|
||||||
textLink = HyperBlue.`300`,
|
textLink = HyperBlue.`300`,
|
||||||
textLight = Shark.`50`,
|
textLight = Shark.`50`,
|
||||||
textLightSupport = Shark.`200`,
|
textLightSupport = Shark.`200`
|
||||||
textOpposite = Base.Bone
|
|
||||||
),
|
),
|
||||||
Btns =
|
Btns =
|
||||||
Btns(
|
Btns(
|
||||||
|
|
|
@ -28,8 +28,7 @@ val LightZashiColorsInternal =
|
||||||
textError = ErrorRed.`500`,
|
textError = ErrorRed.`500`,
|
||||||
textLink = HyperBlue.`500`,
|
textLink = HyperBlue.`500`,
|
||||||
textLight = Gray.`25`,
|
textLight = Gray.`25`,
|
||||||
textLightSupport = Gray.`200`,
|
textLightSupport = Gray.`200`
|
||||||
textOpposite = Base.Bone
|
|
||||||
),
|
),
|
||||||
Btns =
|
Btns =
|
||||||
Btns(
|
Btns(
|
||||||
|
|
|
@ -145,7 +145,7 @@ internal object Indigo {
|
||||||
val `950` = Color(0xFF1F235B)
|
val `950` = Color(0xFF1F235B)
|
||||||
}
|
}
|
||||||
|
|
||||||
object Purple {
|
internal object Purple {
|
||||||
val `25` = Color(0xFFFAFAFF)
|
val `25` = Color(0xFFFAFAFF)
|
||||||
val `50` = Color(0xFFF4F3FF)
|
val `50` = Color(0xFFF4F3FF)
|
||||||
val `100` = Color(0xFFEBE9FE)
|
val `100` = Color(0xFFEBE9FE)
|
||||||
|
|
|
@ -56,8 +56,7 @@ data class Text(
|
||||||
val textError: Color,
|
val textError: Color,
|
||||||
val textLink: Color,
|
val textLink: Color,
|
||||||
val textLight: Color,
|
val textLight: Color,
|
||||||
val textLightSupport: Color,
|
val textLightSupport: Color
|
||||||
val textOpposite: Color
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
|
|
|
@ -3,7 +3,6 @@ package co.electriccoin.zcash.ui.integration.test.screen.scan.view
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||||
import co.electriccoin.zcash.ui.integration.test.common.getPermissionNegativeButtonUiObject
|
import co.electriccoin.zcash.ui.integration.test.common.getPermissionNegativeButtonUiObject
|
||||||
import co.electriccoin.zcash.ui.integration.test.common.getPermissionPositiveButtonUiObject
|
import co.electriccoin.zcash.ui.integration.test.common.getPermissionPositiveButtonUiObject
|
||||||
|
@ -60,7 +59,6 @@ class ScanViewTestSetup(
|
||||||
onScanStateChange = {
|
onScanStateChange = {
|
||||||
scanState.set(it)
|
scanState.set(it)
|
||||||
},
|
},
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
validationResult = ScanValidationState.VALID
|
validationResult = ScanValidationState.VALID
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package co.electriccoin.zcash.ui.screen.about.view
|
||||||
|
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||||
import co.electriccoin.zcash.ui.screen.support.model.ConfigInfo
|
import co.electriccoin.zcash.ui.screen.support.model.ConfigInfo
|
||||||
|
@ -28,7 +27,6 @@ class AboutViewTestSetup(
|
||||||
configInfo = configInfo,
|
configInfo = configInfo,
|
||||||
onPrivacyPolicy = {},
|
onPrivacyPolicy = {},
|
||||||
snackbarHostState = SnackbarHostState(),
|
snackbarHostState = SnackbarHostState(),
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
versionInfo = versionInfo,
|
versionInfo = versionInfo,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package co.electriccoin.zcash.ui.screen.exportdata.view
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
@ -46,7 +45,6 @@ class ExportPrivateDataViewTestSetup(
|
||||||
onConfirm = {
|
onConfirm = {
|
||||||
onConfirmCount.incrementAndGet()
|
onConfirmCount.incrementAndGet()
|
||||||
},
|
},
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package co.electriccoin.zcash.ui.screen.scan.view
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||||
import co.electriccoin.zcash.ui.screen.scan.model.ScanScreenState
|
import co.electriccoin.zcash.ui.screen.scan.model.ScanScreenState
|
||||||
import co.electriccoin.zcash.ui.screen.scan.model.ScanValidationState
|
import co.electriccoin.zcash.ui.screen.scan.model.ScanValidationState
|
||||||
|
@ -30,7 +29,7 @@ class ScanViewBasicTestSetup(
|
||||||
@Suppress("TestFunctionName")
|
@Suppress("TestFunctionName")
|
||||||
fun DefaultContent() {
|
fun DefaultContent() {
|
||||||
Scan(
|
Scan(
|
||||||
validationResult = ScanValidationState.VALID,
|
snackbarHostState = SnackbarHostState(),
|
||||||
onBack = {
|
onBack = {
|
||||||
onBackCount.incrementAndGet()
|
onBackCount.incrementAndGet()
|
||||||
},
|
},
|
||||||
|
@ -40,8 +39,7 @@ class ScanViewBasicTestSetup(
|
||||||
onScanStateChange = {
|
onScanStateChange = {
|
||||||
scanState.set(it)
|
scanState.set(it)
|
||||||
},
|
},
|
||||||
snackbarHostState = SnackbarHostState(),
|
validationResult = ScanValidationState.VALID,
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package co.electriccoin.zcash.ui.screen.settings
|
||||||
|
|
||||||
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.design.component.listitem.ZashiListItemState
|
import co.electriccoin.zcash.ui.design.component.listitem.ZashiListItemState
|
||||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||||
import co.electriccoin.zcash.ui.design.util.stringRes
|
import co.electriccoin.zcash.ui.design.util.stringRes
|
||||||
|
@ -149,7 +148,6 @@ class SettingsViewTestSetup(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import co.electriccoin.zcash.ui.common.datasource.ProposalDataSource
|
||||||
import co.electriccoin.zcash.ui.common.datasource.ProposalDataSourceImpl
|
import co.electriccoin.zcash.ui.common.datasource.ProposalDataSourceImpl
|
||||||
import co.electriccoin.zcash.ui.common.datasource.RestoreTimestampDataSource
|
import co.electriccoin.zcash.ui.common.datasource.RestoreTimestampDataSource
|
||||||
import co.electriccoin.zcash.ui.common.datasource.RestoreTimestampDataSourceImpl
|
import co.electriccoin.zcash.ui.common.datasource.RestoreTimestampDataSourceImpl
|
||||||
|
import co.electriccoin.zcash.ui.common.datasource.WalletBackupDataSource
|
||||||
|
import co.electriccoin.zcash.ui.common.datasource.WalletBackupDataSourceImpl
|
||||||
import co.electriccoin.zcash.ui.common.datasource.ZashiSpendingKeyDataSource
|
import co.electriccoin.zcash.ui.common.datasource.ZashiSpendingKeyDataSource
|
||||||
import co.electriccoin.zcash.ui.common.datasource.ZashiSpendingKeyDataSourceImpl
|
import co.electriccoin.zcash.ui.common.datasource.ZashiSpendingKeyDataSourceImpl
|
||||||
import org.koin.core.module.dsl.singleOf
|
import org.koin.core.module.dsl.singleOf
|
||||||
|
@ -18,4 +20,5 @@ val dataSourceModule =
|
||||||
singleOf(::ZashiSpendingKeyDataSourceImpl) bind ZashiSpendingKeyDataSource::class
|
singleOf(::ZashiSpendingKeyDataSourceImpl) bind ZashiSpendingKeyDataSource::class
|
||||||
singleOf(::ProposalDataSourceImpl) bind ProposalDataSource::class
|
singleOf(::ProposalDataSourceImpl) bind ProposalDataSource::class
|
||||||
singleOf(::RestoreTimestampDataSourceImpl) bind RestoreTimestampDataSource::class
|
singleOf(::RestoreTimestampDataSourceImpl) bind RestoreTimestampDataSource::class
|
||||||
|
singleOf(::WalletBackupDataSourceImpl) bind WalletBackupDataSource::class
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,18 @@ import co.electriccoin.zcash.ui.common.provider.RestoreTimestampStorageProvider
|
||||||
import co.electriccoin.zcash.ui.common.provider.RestoreTimestampStorageProviderImpl
|
import co.electriccoin.zcash.ui.common.provider.RestoreTimestampStorageProviderImpl
|
||||||
import co.electriccoin.zcash.ui.common.provider.SelectedAccountUUIDProvider
|
import co.electriccoin.zcash.ui.common.provider.SelectedAccountUUIDProvider
|
||||||
import co.electriccoin.zcash.ui.common.provider.SelectedAccountUUIDProviderImpl
|
import co.electriccoin.zcash.ui.common.provider.SelectedAccountUUIDProviderImpl
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.ShieldFundsRemindMeCountStorageProvider
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.ShieldFundsRemindMeCountStorageProviderImpl
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.ShieldFundsRemindMeTimestampStorageProvider
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.ShieldFundsRemindMeTimestampStorageProviderImpl
|
||||||
import co.electriccoin.zcash.ui.common.provider.SynchronizerProvider
|
import co.electriccoin.zcash.ui.common.provider.SynchronizerProvider
|
||||||
import co.electriccoin.zcash.ui.common.provider.SynchronizerProviderImpl
|
import co.electriccoin.zcash.ui.common.provider.SynchronizerProviderImpl
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.WalletBackupFlagStorageProvider
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.WalletBackupFlagStorageProviderImpl
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.WalletBackupRemindMeCountStorageProvider
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.WalletBackupRemindMeCountStorageProviderImpl
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.WalletBackupRemindMeTimestampStorageProvider
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.WalletBackupRemindMeTimestampStorageProviderImpl
|
||||||
import org.koin.core.module.dsl.factoryOf
|
import org.koin.core.module.dsl.factoryOf
|
||||||
import org.koin.core.module.dsl.singleOf
|
import org.koin.core.module.dsl.singleOf
|
||||||
import org.koin.dsl.bind
|
import org.koin.dsl.bind
|
||||||
|
@ -30,4 +40,13 @@ val providerModule =
|
||||||
singleOf(::SynchronizerProviderImpl) bind SynchronizerProvider::class
|
singleOf(::SynchronizerProviderImpl) bind SynchronizerProvider::class
|
||||||
singleOf(::ApplicationStateProviderImpl) bind ApplicationStateProvider::class
|
singleOf(::ApplicationStateProviderImpl) bind ApplicationStateProvider::class
|
||||||
factoryOf(::RestoreTimestampStorageProviderImpl) bind RestoreTimestampStorageProvider::class
|
factoryOf(::RestoreTimestampStorageProviderImpl) bind RestoreTimestampStorageProvider::class
|
||||||
|
factoryOf(::ShieldFundsRemindMeCountStorageProviderImpl) bind
|
||||||
|
ShieldFundsRemindMeCountStorageProvider::class
|
||||||
|
factoryOf(::ShieldFundsRemindMeTimestampStorageProviderImpl) bind
|
||||||
|
ShieldFundsRemindMeTimestampStorageProvider::class
|
||||||
|
factoryOf(::WalletBackupRemindMeCountStorageProviderImpl) bind
|
||||||
|
WalletBackupRemindMeCountStorageProvider::class
|
||||||
|
factoryOf(::WalletBackupRemindMeTimestampStorageProviderImpl) bind
|
||||||
|
WalletBackupRemindMeTimestampStorageProvider::class
|
||||||
|
factoryOf(::WalletBackupFlagStorageProviderImpl) bind WalletBackupFlagStorageProvider::class
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import co.electriccoin.zcash.ui.common.usecase.GetCurrentFilteredTransactionsUse
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetCurrentTransactionsUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetCurrentTransactionsUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetExchangeRateUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetExchangeRateUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetFlexaStatusUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetFlexaStatusUseCase
|
||||||
|
import co.electriccoin.zcash.ui.common.usecase.GetHomeMessageUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetKeystoneStatusUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetKeystoneStatusUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetMetadataUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetMetadataUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetPersistableWalletUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetPersistableWalletUseCase
|
||||||
|
@ -37,7 +38,6 @@ import co.electriccoin.zcash.ui.common.usecase.GetTransactionMetadataUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetTransparentAddressUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetTransparentAddressUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetWalletAccountsUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetWalletAccountsUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetWalletRestoringStateUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetWalletRestoringStateUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetWalletStateInformationUseCase
|
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetZashiAccountUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetZashiAccountUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetZashiSpendingKeyUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetZashiSpendingKeyUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.IsCoinbaseAvailableUseCase
|
import co.electriccoin.zcash.ui.common.usecase.IsCoinbaseAvailableUseCase
|
||||||
|
@ -46,7 +46,7 @@ import co.electriccoin.zcash.ui.common.usecase.IsRestoreSuccessDialogVisibleUseC
|
||||||
import co.electriccoin.zcash.ui.common.usecase.MarkTxMemoAsReadUseCase
|
import co.electriccoin.zcash.ui.common.usecase.MarkTxMemoAsReadUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.NavigateToAddressBookUseCase
|
import co.electriccoin.zcash.ui.common.usecase.NavigateToAddressBookUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.NavigateToCoinbaseUseCase
|
import co.electriccoin.zcash.ui.common.usecase.NavigateToCoinbaseUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.NavigateToSeedRecoveryUseCase
|
import co.electriccoin.zcash.ui.common.usecase.NavigateToWalletBackupUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.NavigateToTaxExportUseCase
|
import co.electriccoin.zcash.ui.common.usecase.NavigateToTaxExportUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.ObserveAddressBookContactsUseCase
|
import co.electriccoin.zcash.ui.common.usecase.ObserveAddressBookContactsUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.ObserveClearSendUseCase
|
import co.electriccoin.zcash.ui.common.usecase.ObserveClearSendUseCase
|
||||||
|
@ -62,6 +62,7 @@ import co.electriccoin.zcash.ui.common.usecase.ObserveSynchronizerUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.ObserveTransactionSubmitStateUseCase
|
import co.electriccoin.zcash.ui.common.usecase.ObserveTransactionSubmitStateUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.ObserveZashiAccountUseCase
|
import co.electriccoin.zcash.ui.common.usecase.ObserveZashiAccountUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.OnAddressScannedUseCase
|
import co.electriccoin.zcash.ui.common.usecase.OnAddressScannedUseCase
|
||||||
|
import co.electriccoin.zcash.ui.common.usecase.OnUserSavedWalletBackupUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.OnZip321ScannedUseCase
|
import co.electriccoin.zcash.ui.common.usecase.OnZip321ScannedUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.ParseKeystonePCZTUseCase
|
import co.electriccoin.zcash.ui.common.usecase.ParseKeystonePCZTUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.ParseKeystoneSignInRequestUseCase
|
import co.electriccoin.zcash.ui.common.usecase.ParseKeystoneSignInRequestUseCase
|
||||||
|
@ -69,6 +70,7 @@ import co.electriccoin.zcash.ui.common.usecase.ParseKeystoneUrToZashiAccountsUse
|
||||||
import co.electriccoin.zcash.ui.common.usecase.PersistEndpointUseCase
|
import co.electriccoin.zcash.ui.common.usecase.PersistEndpointUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.PrefillSendUseCase
|
import co.electriccoin.zcash.ui.common.usecase.PrefillSendUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.RefreshFastestServersUseCase
|
import co.electriccoin.zcash.ui.common.usecase.RefreshFastestServersUseCase
|
||||||
|
import co.electriccoin.zcash.ui.common.usecase.RemindWalletBackupLaterUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.RescanBlockchainUseCase
|
import co.electriccoin.zcash.ui.common.usecase.RescanBlockchainUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.ResetInMemoryDataUseCase
|
import co.electriccoin.zcash.ui.common.usecase.ResetInMemoryDataUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.ResetSharedPrefsDataUseCase
|
import co.electriccoin.zcash.ui.common.usecase.ResetSharedPrefsDataUseCase
|
||||||
|
@ -122,7 +124,6 @@ val useCaseModule =
|
||||||
factoryOf(::ShareImageUseCase)
|
factoryOf(::ShareImageUseCase)
|
||||||
factoryOf(::Zip321BuildUriUseCase)
|
factoryOf(::Zip321BuildUriUseCase)
|
||||||
factoryOf(::Zip321ParseUriValidationUseCase)
|
factoryOf(::Zip321ParseUriValidationUseCase)
|
||||||
factoryOf(::GetWalletStateInformationUseCase)
|
|
||||||
factoryOf(::IsCoinbaseAvailableUseCase)
|
factoryOf(::IsCoinbaseAvailableUseCase)
|
||||||
factoryOf(::GetZashiSpendingKeyUseCase)
|
factoryOf(::GetZashiSpendingKeyUseCase)
|
||||||
factoryOf(::ObservePersistableWalletUseCase)
|
factoryOf(::ObservePersistableWalletUseCase)
|
||||||
|
@ -184,8 +185,11 @@ val useCaseModule =
|
||||||
factoryOf(::IsRestoreSuccessDialogVisibleUseCase)
|
factoryOf(::IsRestoreSuccessDialogVisibleUseCase)
|
||||||
factoryOf(::ValidateSeedUseCase)
|
factoryOf(::ValidateSeedUseCase)
|
||||||
factoryOf(::RestoreWalletUseCase)
|
factoryOf(::RestoreWalletUseCase)
|
||||||
factoryOf(::NavigateToSeedRecoveryUseCase)
|
factoryOf(::NavigateToWalletBackupUseCase)
|
||||||
factoryOf(::GetKeystoneStatusUseCase)
|
factoryOf(::GetKeystoneStatusUseCase)
|
||||||
factoryOf(::GetCoinbaseStatusUseCase)
|
factoryOf(::GetCoinbaseStatusUseCase)
|
||||||
factoryOf(::GetFlexaStatusUseCase)
|
factoryOf(::GetFlexaStatusUseCase)
|
||||||
|
factoryOf(::GetHomeMessageUseCase)
|
||||||
|
factoryOf(::OnUserSavedWalletBackupUseCase)
|
||||||
|
factoryOf(::RemindWalletBackupLaterUseCase)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,14 @@ import co.electriccoin.zcash.ui.screen.balances.BalanceViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.chooseserver.ChooseServerViewModel
|
import co.electriccoin.zcash.ui.screen.chooseserver.ChooseServerViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.contact.viewmodel.AddContactViewModel
|
import co.electriccoin.zcash.ui.screen.contact.viewmodel.AddContactViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.contact.viewmodel.UpdateContactViewModel
|
import co.electriccoin.zcash.ui.screen.contact.viewmodel.UpdateContactViewModel
|
||||||
|
import co.electriccoin.zcash.ui.screen.exchangerate.optin.ExchangeRateOptInViewModel
|
||||||
|
import co.electriccoin.zcash.ui.screen.exchangerate.settings.ExchangeRateSettingsViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.feedback.viewmodel.FeedbackViewModel
|
import co.electriccoin.zcash.ui.screen.feedback.viewmodel.FeedbackViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.flexa.FlexaViewModel
|
import co.electriccoin.zcash.ui.screen.flexa.FlexaViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.home.HomeViewModel
|
import co.electriccoin.zcash.ui.screen.home.HomeViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.home.balance.TransparentBalanceInfoViewModel
|
import co.electriccoin.zcash.ui.screen.home.backup.WalletBackupDetailViewModel
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.backup.WalletBackupInfoViewModel
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.transparentbalance.TransparentBalanceInfoViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.integrations.IntegrationsViewModel
|
import co.electriccoin.zcash.ui.screen.integrations.IntegrationsViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.qrcode.viewmodel.QrCodeViewModel
|
import co.electriccoin.zcash.ui.screen.qrcode.viewmodel.QrCodeViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.receive.viewmodel.ReceiveViewModel
|
import co.electriccoin.zcash.ui.screen.receive.viewmodel.ReceiveViewModel
|
||||||
|
@ -24,13 +28,13 @@ import co.electriccoin.zcash.ui.screen.restore.date.RestoreBDDateViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.restore.estimation.RestoreBDEstimationViewModel
|
import co.electriccoin.zcash.ui.screen.restore.estimation.RestoreBDEstimationViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.restore.height.RestoreBDHeightViewModel
|
import co.electriccoin.zcash.ui.screen.restore.height.RestoreBDHeightViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.restore.seed.RestoreSeedViewModel
|
import co.electriccoin.zcash.ui.screen.restore.seed.RestoreSeedViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.restoresuccess.viewmodel.RestoreSuccessViewModel
|
import co.electriccoin.zcash.ui.screen.restoresuccess.RestoreSuccessViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.reviewtransaction.ReviewTransactionViewModel
|
import co.electriccoin.zcash.ui.screen.reviewtransaction.ReviewTransactionViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.scan.Scan
|
import co.electriccoin.zcash.ui.screen.scan.Scan
|
||||||
import co.electriccoin.zcash.ui.screen.scan.viewmodel.ScanViewModel
|
import co.electriccoin.zcash.ui.screen.scan.viewmodel.ScanViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.scankeystone.viewmodel.ScanKeystonePCZTViewModel
|
import co.electriccoin.zcash.ui.screen.scankeystone.viewmodel.ScanKeystonePCZTViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.scankeystone.viewmodel.ScanKeystoneSignInRequestViewModel
|
import co.electriccoin.zcash.ui.screen.scankeystone.viewmodel.ScanKeystoneSignInRequestViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.seed.SeedRecoveryViewModel
|
import co.electriccoin.zcash.ui.screen.walletbackup.WalletBackupViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.selectkeystoneaccount.SelectKeystoneAccount
|
import co.electriccoin.zcash.ui.screen.selectkeystoneaccount.SelectKeystoneAccount
|
||||||
import co.electriccoin.zcash.ui.screen.selectkeystoneaccount.viewmodel.SelectKeystoneAccountViewModel
|
import co.electriccoin.zcash.ui.screen.selectkeystoneaccount.viewmodel.SelectKeystoneAccountViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.send.SendViewModel
|
import co.electriccoin.zcash.ui.screen.send.SendViewModel
|
||||||
|
@ -96,7 +100,7 @@ val viewModelModule =
|
||||||
viewModelOf(::IntegrationsViewModel)
|
viewModelOf(::IntegrationsViewModel)
|
||||||
viewModelOf(::FlexaViewModel)
|
viewModelOf(::FlexaViewModel)
|
||||||
viewModelOf(::SendViewModel)
|
viewModelOf(::SendViewModel)
|
||||||
viewModelOf(::SeedRecoveryViewModel)
|
viewModelOf(::WalletBackupViewModel)
|
||||||
viewModelOf(::FeedbackViewModel)
|
viewModelOf(::FeedbackViewModel)
|
||||||
viewModelOf(::SignKeystoneTransactionViewModel)
|
viewModelOf(::SignKeystoneTransactionViewModel)
|
||||||
viewModelOf(::AccountListViewModel)
|
viewModelOf(::AccountListViewModel)
|
||||||
|
@ -144,4 +148,8 @@ val viewModelModule =
|
||||||
viewModelOf(::RestoreBDDateViewModel)
|
viewModelOf(::RestoreBDDateViewModel)
|
||||||
viewModelOf(::RestoreBDEstimationViewModel)
|
viewModelOf(::RestoreBDEstimationViewModel)
|
||||||
viewModelOf(::TransparentBalanceInfoViewModel)
|
viewModelOf(::TransparentBalanceInfoViewModel)
|
||||||
|
viewModelOf(::WalletBackupInfoViewModel)
|
||||||
|
viewModelOf(::ExchangeRateOptInViewModel)
|
||||||
|
viewModelOf(::ExchangeRateSettingsViewModel)
|
||||||
|
viewModelOf(::WalletBackupDetailViewModel)
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,19 +67,19 @@ import co.electriccoin.zcash.ui.screen.exportdata.WrapExportPrivateData
|
||||||
import co.electriccoin.zcash.ui.screen.feedback.WrapFeedback
|
import co.electriccoin.zcash.ui.screen.feedback.WrapFeedback
|
||||||
import co.electriccoin.zcash.ui.screen.flexa.FlexaViewModel
|
import co.electriccoin.zcash.ui.screen.flexa.FlexaViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.home.AndroidHome
|
import co.electriccoin.zcash.ui.screen.home.AndroidHome
|
||||||
import co.electriccoin.zcash.ui.screen.home.AndroidSeedBackupInfo
|
import co.electriccoin.zcash.ui.screen.home.backup.AndroidWalletBackupInfo
|
||||||
import co.electriccoin.zcash.ui.screen.home.AndroidWalletDisconnectedInfo
|
import co.electriccoin.zcash.ui.screen.home.disconnected.AndroidWalletDisconnectedInfo
|
||||||
import co.electriccoin.zcash.ui.screen.home.AndroidWalletRestoringInfo
|
import co.electriccoin.zcash.ui.screen.home.restoring.AndroidWalletRestoringInfo
|
||||||
import co.electriccoin.zcash.ui.screen.home.AndroidWalletSyncingInfo
|
import co.electriccoin.zcash.ui.screen.home.syncing.AndroidWalletSyncingInfo
|
||||||
import co.electriccoin.zcash.ui.screen.home.AndroidWalletUpdatingInfo
|
import co.electriccoin.zcash.ui.screen.home.updating.AndroidWalletUpdatingInfo
|
||||||
import co.electriccoin.zcash.ui.screen.home.Home
|
import co.electriccoin.zcash.ui.screen.home.Home
|
||||||
import co.electriccoin.zcash.ui.screen.home.SeedBackupInfo
|
import co.electriccoin.zcash.ui.screen.home.backup.SeedBackupInfo
|
||||||
import co.electriccoin.zcash.ui.screen.home.WalletDisconnectedInfo
|
import co.electriccoin.zcash.ui.screen.home.disconnected.WalletDisconnectedInfo
|
||||||
import co.electriccoin.zcash.ui.screen.home.WalletRestoringInfo
|
import co.electriccoin.zcash.ui.screen.home.restoring.WalletRestoringInfo
|
||||||
import co.electriccoin.zcash.ui.screen.home.WalletSyncingInfo
|
import co.electriccoin.zcash.ui.screen.home.syncing.WalletSyncingInfo
|
||||||
import co.electriccoin.zcash.ui.screen.home.WalletUpdatingInfo
|
import co.electriccoin.zcash.ui.screen.home.updating.WalletUpdatingInfo
|
||||||
import co.electriccoin.zcash.ui.screen.home.balance.AndroidTransparentBalanceInfo
|
import co.electriccoin.zcash.ui.screen.home.transparentbalance.AndroidTransparentBalanceInfo
|
||||||
import co.electriccoin.zcash.ui.screen.home.balance.TransparentBalanceInfo
|
import co.electriccoin.zcash.ui.screen.home.transparentbalance.TransparentBalanceInfo
|
||||||
import co.electriccoin.zcash.ui.screen.integrations.AndroidDialogIntegrations
|
import co.electriccoin.zcash.ui.screen.integrations.AndroidDialogIntegrations
|
||||||
import co.electriccoin.zcash.ui.screen.integrations.AndroidIntegrations
|
import co.electriccoin.zcash.ui.screen.integrations.AndroidIntegrations
|
||||||
import co.electriccoin.zcash.ui.screen.integrations.DialogIntegrations
|
import co.electriccoin.zcash.ui.screen.integrations.DialogIntegrations
|
||||||
|
@ -99,10 +99,10 @@ import co.electriccoin.zcash.ui.screen.scankeystone.ScanKeystonePCZTRequest
|
||||||
import co.electriccoin.zcash.ui.screen.scankeystone.ScanKeystoneSignInRequest
|
import co.electriccoin.zcash.ui.screen.scankeystone.ScanKeystoneSignInRequest
|
||||||
import co.electriccoin.zcash.ui.screen.scankeystone.WrapScanKeystonePCZTRequest
|
import co.electriccoin.zcash.ui.screen.scankeystone.WrapScanKeystonePCZTRequest
|
||||||
import co.electriccoin.zcash.ui.screen.scankeystone.WrapScanKeystoneSignInRequest
|
import co.electriccoin.zcash.ui.screen.scankeystone.WrapScanKeystoneSignInRequest
|
||||||
import co.electriccoin.zcash.ui.screen.seed.AndroidSeedRecovery
|
import co.electriccoin.zcash.ui.screen.walletbackup.AndroidWalletBackup
|
||||||
import co.electriccoin.zcash.ui.screen.seed.SeedRecovery
|
import co.electriccoin.zcash.ui.screen.walletbackup.WalletBackup
|
||||||
import co.electriccoin.zcash.ui.screen.seed.backup.AndroidSeedBackup
|
import co.electriccoin.zcash.ui.screen.home.backup.AndroidWalletBackupDetail
|
||||||
import co.electriccoin.zcash.ui.screen.seed.backup.SeedBackup
|
import co.electriccoin.zcash.ui.screen.home.backup.WalletBackupDetail
|
||||||
import co.electriccoin.zcash.ui.screen.selectkeystoneaccount.AndroidSelectKeystoneAccount
|
import co.electriccoin.zcash.ui.screen.selectkeystoneaccount.AndroidSelectKeystoneAccount
|
||||||
import co.electriccoin.zcash.ui.screen.selectkeystoneaccount.SelectKeystoneAccount
|
import co.electriccoin.zcash.ui.screen.selectkeystoneaccount.SelectKeystoneAccount
|
||||||
import co.electriccoin.zcash.ui.screen.send.Send
|
import co.electriccoin.zcash.ui.screen.send.Send
|
||||||
|
@ -227,8 +227,8 @@ internal fun MainActivity.Navigation() {
|
||||||
composable(CHOOSE_SERVER) {
|
composable(CHOOSE_SERVER) {
|
||||||
WrapChooseServer()
|
WrapChooseServer()
|
||||||
}
|
}
|
||||||
composable<SeedRecovery> {
|
composable<WalletBackup> {
|
||||||
AndroidSeedRecovery()
|
AndroidWalletBackup(it.toRoute())
|
||||||
}
|
}
|
||||||
composable(SUPPORT) {
|
composable(SUPPORT) {
|
||||||
// Pop back stack won't be right if we deep link into support
|
// Pop back stack won't be right if we deep link into support
|
||||||
|
@ -410,8 +410,8 @@ internal fun MainActivity.Navigation() {
|
||||||
) {
|
) {
|
||||||
AndroidSeedInfo()
|
AndroidSeedInfo()
|
||||||
}
|
}
|
||||||
composable<SeedBackup> {
|
composable<WalletBackupDetail> {
|
||||||
AndroidSeedBackup(it.toRoute())
|
AndroidWalletBackupDetail(it.toRoute())
|
||||||
}
|
}
|
||||||
dialog<SeedBackupInfo>(
|
dialog<SeedBackupInfo>(
|
||||||
dialogProperties =
|
dialogProperties =
|
||||||
|
@ -420,7 +420,7 @@ internal fun MainActivity.Navigation() {
|
||||||
dismissOnClickOutside = false
|
dismissOnClickOutside = false
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
AndroidSeedBackupInfo()
|
AndroidWalletBackupInfo()
|
||||||
}
|
}
|
||||||
dialog<TransparentBalanceInfo>(
|
dialog<TransparentBalanceInfo>(
|
||||||
dialogProperties =
|
dialogProperties =
|
||||||
|
|
|
@ -8,12 +8,10 @@ import co.electriccoin.zcash.preference.model.entry.BooleanPreferenceDefault
|
||||||
import co.electriccoin.zcash.ui.NavigationRouter
|
import co.electriccoin.zcash.ui.NavigationRouter
|
||||||
import co.electriccoin.zcash.ui.NavigationTargets.SETTINGS
|
import co.electriccoin.zcash.ui.NavigationTargets.SETTINGS
|
||||||
import co.electriccoin.zcash.ui.common.model.KeystoneAccount
|
import co.electriccoin.zcash.ui.common.model.KeystoneAccount
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletAccount
|
import co.electriccoin.zcash.ui.common.model.WalletAccount
|
||||||
import co.electriccoin.zcash.ui.common.model.ZashiAccount
|
import co.electriccoin.zcash.ui.common.model.ZashiAccount
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetSelectedWalletAccountUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetSelectedWalletAccountUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetWalletAccountsUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetWalletAccountsUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetWalletStateInformationUseCase
|
|
||||||
import co.electriccoin.zcash.ui.design.R
|
import co.electriccoin.zcash.ui.design.R
|
||||||
import co.electriccoin.zcash.ui.design.component.IconButtonState
|
import co.electriccoin.zcash.ui.design.component.IconButtonState
|
||||||
import co.electriccoin.zcash.ui.design.util.stringRes
|
import co.electriccoin.zcash.ui.design.util.stringRes
|
||||||
|
@ -33,7 +31,6 @@ import kotlinx.coroutines.launch
|
||||||
class ZashiTopAppBarViewModel(
|
class ZashiTopAppBarViewModel(
|
||||||
getWalletAccountUseCase: GetWalletAccountsUseCase,
|
getWalletAccountUseCase: GetWalletAccountsUseCase,
|
||||||
getSelectedWalletAccount: GetSelectedWalletAccountUseCase,
|
getSelectedWalletAccount: GetSelectedWalletAccountUseCase,
|
||||||
getWalletStateInformation: GetWalletStateInformationUseCase,
|
|
||||||
private val standardPreferenceProvider: StandardPreferenceProvider,
|
private val standardPreferenceProvider: StandardPreferenceProvider,
|
||||||
private val navigationRouter: NavigationRouter,
|
private val navigationRouter: NavigationRouter,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
@ -43,24 +40,21 @@ class ZashiTopAppBarViewModel(
|
||||||
combine(
|
combine(
|
||||||
getSelectedWalletAccount.observe().filterNotNull(),
|
getSelectedWalletAccount.observe().filterNotNull(),
|
||||||
isHideBalances,
|
isHideBalances,
|
||||||
getWalletStateInformation.observe()
|
) { currentAccount, isHideBalances ->
|
||||||
) { currentAccount, isHideBalances, walletState ->
|
createState(currentAccount, isHideBalances)
|
||||||
createState(currentAccount, isHideBalances, walletState)
|
|
||||||
}.stateIn(
|
}.stateIn(
|
||||||
scope = viewModelScope,
|
scope = viewModelScope,
|
||||||
started = SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT),
|
started = SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT),
|
||||||
initialValue =
|
initialValue =
|
||||||
createState(
|
createState(
|
||||||
currentAccount = getWalletAccountUseCase.observe().value?.firstOrNull { it.isSelected },
|
currentAccount = getWalletAccountUseCase.observe().value?.firstOrNull { it.isSelected },
|
||||||
isHideBalances = isHideBalances.value,
|
isHideBalances = isHideBalances.value
|
||||||
topAppBarSubTitleState = getWalletStateInformation.observe().value
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun createState(
|
private fun createState(
|
||||||
currentAccount: WalletAccount?,
|
currentAccount: WalletAccount?,
|
||||||
isHideBalances: Boolean?,
|
isHideBalances: Boolean?
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState
|
|
||||||
) = ZashiMainTopAppBarState(
|
) = ZashiMainTopAppBarState(
|
||||||
accountSwitchState =
|
accountSwitchState =
|
||||||
AccountSwitchState(
|
AccountSwitchState(
|
||||||
|
@ -88,19 +82,7 @@ class ZashiTopAppBarViewModel(
|
||||||
icon = R.drawable.ic_app_bar_settings,
|
icon = R.drawable.ic_app_bar_settings,
|
||||||
onClick = ::onSettingsClicked,
|
onClick = ::onSettingsClicked,
|
||||||
contentDescription = stringRes(co.electriccoin.zcash.ui.R.string.settings_menu_content_description)
|
contentDescription = stringRes(co.electriccoin.zcash.ui.R.string.settings_menu_content_description)
|
||||||
),
|
)
|
||||||
subtitle =
|
|
||||||
when (topAppBarSubTitleState) {
|
|
||||||
TopAppBarSubTitleState.Disconnected ->
|
|
||||||
stringRes(
|
|
||||||
co.electriccoin.zcash.ui.R.string.disconnected_label_new,
|
|
||||||
)
|
|
||||||
TopAppBarSubTitleState.Restoring ->
|
|
||||||
stringRes(
|
|
||||||
co.electriccoin.zcash.ui.R.string.restoring_wallet_label_new,
|
|
||||||
)
|
|
||||||
TopAppBarSubTitleState.None -> null
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun onAccountTypeClicked() = navigationRouter.forward(AccountList)
|
private fun onAccountTypeClicked() = navigationRouter.forward(AccountList)
|
||||||
|
|
|
@ -15,14 +15,12 @@ import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.systemBars
|
import androidx.compose.foundation.layout.systemBars
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
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.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import co.electriccoin.zcash.ui.common.appbar.ZashiMainTopAppBarState.AccountType
|
import co.electriccoin.zcash.ui.common.appbar.ZashiMainTopAppBarState.AccountType
|
||||||
import co.electriccoin.zcash.ui.design.R
|
import co.electriccoin.zcash.ui.design.R
|
||||||
|
@ -32,10 +30,6 @@ import co.electriccoin.zcash.ui.design.component.ZashiSmallTopAppBar
|
||||||
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.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.stringRes
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ZashiTopAppBarWithAccountSelection(
|
fun ZashiTopAppBarWithAccountSelection(
|
||||||
|
@ -61,16 +55,6 @@ fun ZashiTopAppBarWithAccountSelection(
|
||||||
AccountSwitch(state.accountSwitchState)
|
AccountSwitch(state.accountSwitchState)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
if (state.subtitle != null) {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.align(Alignment.BottomCenter),
|
|
||||||
text = state.subtitle.getValue().uppercase(),
|
|
||||||
style = ZashiTypography.textXs,
|
|
||||||
fontWeight = FontWeight.Normal,
|
|
||||||
color = ZashiColors.Text.textQuaternary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,13 +112,9 @@ private fun AccountSwitch(state: AccountSwitchState) {
|
||||||
data class ZashiMainTopAppBarState(
|
data class ZashiMainTopAppBarState(
|
||||||
val accountSwitchState: AccountSwitchState,
|
val accountSwitchState: AccountSwitchState,
|
||||||
val balanceVisibilityButton: IconButtonState,
|
val balanceVisibilityButton: IconButtonState,
|
||||||
val settingsButton: IconButtonState,
|
val settingsButton: IconButtonState
|
||||||
val subtitle: StringResource?
|
|
||||||
) {
|
) {
|
||||||
enum class AccountType {
|
enum class AccountType { ZASHI, KEYSTONE }
|
||||||
ZASHI,
|
|
||||||
KEYSTONE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class AccountSwitchState(
|
data class AccountSwitchState(
|
||||||
|
@ -155,8 +135,7 @@ private fun ZashiMainTopAppBarPreview() =
|
||||||
onAccountTypeClick = {}
|
onAccountTypeClick = {}
|
||||||
),
|
),
|
||||||
balanceVisibilityButton = IconButtonState(R.drawable.ic_app_bar_balances_hide) {},
|
balanceVisibilityButton = IconButtonState(R.drawable.ic_app_bar_balances_hide) {},
|
||||||
settingsButton = IconButtonState(R.drawable.ic_app_bar_settings) {},
|
settingsButton = IconButtonState(R.drawable.ic_app_bar_settings) {}
|
||||||
subtitle = null
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -174,8 +153,7 @@ private fun KeystoneMainTopAppBarPreview() =
|
||||||
onAccountTypeClick = {},
|
onAccountTypeClick = {},
|
||||||
),
|
),
|
||||||
balanceVisibilityButton = IconButtonState(R.drawable.ic_app_bar_balances_hide) {},
|
balanceVisibilityButton = IconButtonState(R.drawable.ic_app_bar_balances_hide) {},
|
||||||
settingsButton = IconButtonState(R.drawable.ic_app_bar_settings) {},
|
settingsButton = IconButtonState(R.drawable.ic_app_bar_settings) {}
|
||||||
subtitle = null
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -193,8 +171,7 @@ private fun MainTopAppBarWithSubtitlePreview() =
|
||||||
onAccountTypeClick = {},
|
onAccountTypeClick = {},
|
||||||
),
|
),
|
||||||
balanceVisibilityButton = IconButtonState(R.drawable.ic_app_bar_balances_hide) {},
|
balanceVisibilityButton = IconButtonState(R.drawable.ic_app_bar_balances_hide) {},
|
||||||
settingsButton = IconButtonState(R.drawable.ic_app_bar_settings) {},
|
settingsButton = IconButtonState(R.drawable.ic_app_bar_settings) {}
|
||||||
subtitle = stringRes("Subtitle")
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ fun ZashiTopAppbar(
|
||||||
) {
|
) {
|
||||||
ZashiSmallTopAppBar(
|
ZashiSmallTopAppBar(
|
||||||
title = title?.getValue(),
|
title = title?.getValue(),
|
||||||
subtitle = state?.subtitle?.getValue(),
|
|
||||||
navigationAction = {
|
navigationAction = {
|
||||||
ZashiTopAppBarBackNavigation(
|
ZashiTopAppBarBackNavigation(
|
||||||
onBack = onBack,
|
onBack = onBack,
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.datasource
|
||||||
|
|
||||||
|
import cash.z.ecc.android.sdk.model.AccountUuid
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.ShieldFundsRemindMeCountStorageProvider
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.ShieldFundsRemindMeTimestampStorageProvider
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import kotlin.time.Duration
|
||||||
|
import kotlin.time.Duration.Companion.days
|
||||||
|
|
||||||
|
interface ShieldFundsRemindMeDataSource {
|
||||||
|
suspend fun observe(forAccount: AccountUuid): Flow<ShieldFundsAvailability>
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShieldFundsRemindMeDataSourceImpl(
|
||||||
|
private val shieldFundsRemindMeCountStorageProvider: ShieldFundsRemindMeCountStorageProvider,
|
||||||
|
private val shieldFundsRemindMeTimestampStorageProvider: ShieldFundsRemindMeTimestampStorageProvider
|
||||||
|
): ShieldFundsRemindMeDataSource {
|
||||||
|
override suspend fun observe(forAccount: AccountUuid): Flow<ShieldFundsAvailability> = combine(
|
||||||
|
shieldFundsRemindMeCountStorageProvider.observe(forAccount),
|
||||||
|
shieldFundsRemindMeTimestampStorageProvider.observe(forAccount)
|
||||||
|
) { count, timestamp ->
|
||||||
|
when {
|
||||||
|
timestamp == null -> ShieldFundsAvailability.Available(1.days)
|
||||||
|
count == 1 -> ShieldFundsAvailability.Available(2.days)
|
||||||
|
count == 2 -> ShieldFundsAvailability.Available(3.days)
|
||||||
|
else -> ShieldFundsAvailability.Unavailable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface ShieldFundsAvailability {
|
||||||
|
data class Available(val nextLockoutDuration: Duration) : ShieldFundsAvailability
|
||||||
|
data object Unavailable : ShieldFundsAvailability
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.datasource
|
||||||
|
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.WalletBackupFlagStorageProvider
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.WalletBackupRemindMeCountStorageProvider
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.WalletBackupRemindMeTimestampStorageProvider
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import java.time.Instant
|
||||||
|
import kotlin.time.Duration
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
|
interface WalletBackupDataSource {
|
||||||
|
fun observe(): Flow<WalletBackupAvailability>
|
||||||
|
|
||||||
|
suspend fun onUserSavedWalletBackup()
|
||||||
|
|
||||||
|
suspend fun remindMeLater()
|
||||||
|
}
|
||||||
|
|
||||||
|
class WalletBackupDataSourceImpl(
|
||||||
|
private val walletBackupFlagStorageProvider: WalletBackupFlagStorageProvider,
|
||||||
|
private val walletBackupRemindMeCountStorageProvider: WalletBackupRemindMeCountStorageProvider,
|
||||||
|
private val walletBackupRemindMeTimestampStorageProvider: WalletBackupRemindMeTimestampStorageProvider
|
||||||
|
) : WalletBackupDataSource {
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
override fun observe(): Flow<WalletBackupAvailability> = combine(
|
||||||
|
walletBackupFlagStorageProvider.observe(),
|
||||||
|
walletBackupRemindMeCountStorageProvider.observe(),
|
||||||
|
walletBackupRemindMeTimestampStorageProvider.observe()
|
||||||
|
) { isBackedUp, count, timestamp ->
|
||||||
|
Triple(isBackedUp, count, timestamp)
|
||||||
|
}.flatMapLatest { (isBackedUp, count, timestamp) ->
|
||||||
|
when {
|
||||||
|
isBackedUp -> flowOf(WalletBackupAvailability.Unavailable)
|
||||||
|
timestamp == null -> flowOf(WalletBackupAvailability.Available(WalletBackupLockoutDuration.ONE_DAY))
|
||||||
|
count == 1 -> calculateNext(
|
||||||
|
lastTimestamp = timestamp,
|
||||||
|
lastLockoutDuration = WalletBackupLockoutDuration.ONE_DAY,
|
||||||
|
nextLockoutDuration = WalletBackupLockoutDuration.TWO_DAYS
|
||||||
|
)
|
||||||
|
|
||||||
|
else -> calculateNext(
|
||||||
|
lastTimestamp = timestamp,
|
||||||
|
lastLockoutDuration = if (count == 2) {
|
||||||
|
WalletBackupLockoutDuration.TWO_DAYS
|
||||||
|
} else {
|
||||||
|
WalletBackupLockoutDuration.THREE_DAYS
|
||||||
|
},
|
||||||
|
nextLockoutDuration = WalletBackupLockoutDuration.THREE_DAYS
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onUserSavedWalletBackup() {
|
||||||
|
walletBackupFlagStorageProvider.store(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun remindMeLater() {
|
||||||
|
val count = walletBackupRemindMeCountStorageProvider.get()
|
||||||
|
val timestamp = Instant.now()
|
||||||
|
walletBackupRemindMeCountStorageProvider.store(count + 1)
|
||||||
|
walletBackupRemindMeTimestampStorageProvider.store(timestamp)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateNext(
|
||||||
|
lastTimestamp: Instant,
|
||||||
|
lastLockoutDuration: WalletBackupLockoutDuration,
|
||||||
|
nextLockoutDuration: WalletBackupLockoutDuration
|
||||||
|
): Flow<WalletBackupAvailability> {
|
||||||
|
val nextAvailableTimestamp = lastTimestamp.plusMillis(lastLockoutDuration.duration.inWholeMilliseconds)
|
||||||
|
val now = Instant.now()
|
||||||
|
return if (nextAvailableTimestamp > now) {
|
||||||
|
flow {
|
||||||
|
val remaining = nextAvailableTimestamp.toEpochMilli() - now.toEpochMilli()
|
||||||
|
emit(WalletBackupAvailability.Unavailable)
|
||||||
|
delay(remaining)
|
||||||
|
emit(WalletBackupAvailability.Available(nextLockoutDuration))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
flowOf(WalletBackupAvailability.Available(nextLockoutDuration))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface WalletBackupAvailability {
|
||||||
|
data class Available(val lockoutDuration: WalletBackupLockoutDuration) : WalletBackupAvailability
|
||||||
|
data object Unavailable : WalletBackupAvailability
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class WalletBackupLockoutDuration(val duration: Duration) {
|
||||||
|
ONE_DAY(10.seconds),
|
||||||
|
TWO_DAYS(20.seconds),
|
||||||
|
THREE_DAYS(30.seconds)
|
||||||
|
}
|
|
@ -19,16 +19,3 @@ data class WalletSnapshot(
|
||||||
val progress: PercentDecimal,
|
val progress: PercentDecimal,
|
||||||
val synchronizerError: SynchronizerError?
|
val synchronizerError: SynchronizerError?
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO [#1370]: WalletSnapshot.canSpend() calculation limitation
|
|
||||||
// TODO [#1370]: https://github.com/Electric-Coin-Company/zashi-android/issues/1370
|
|
||||||
// Note this check is not entirely correct - it does not calculate the resulting fee using the new Proposal API. It's
|
|
||||||
// fine for now, but it's subject to improvement later once we figure out how to handle it in such cases.
|
|
||||||
fun WalletSnapshot.canSpend(amount: Zatoshi): Boolean = spendableBalance() >= amount
|
|
||||||
|
|
||||||
fun WalletSnapshot.totalBalance() = orchardBalance.total + (saplingBalance?.total ?: Zatoshi(0)) + transparentBalance
|
|
||||||
|
|
||||||
// Note that considering both to be spendable is subject to change.
|
|
||||||
// The user experience could be confusing, and in the future we might prefer to ask users
|
|
||||||
// to transfer their balance to the latest balance type to make it spendable.
|
|
||||||
fun WalletSnapshot.spendableBalance() = orchardBalance.available + (saplingBalance?.available ?: Zatoshi(0))
|
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.provider
|
||||||
|
|
||||||
|
import co.electriccoin.zcash.preference.PreferenceHolder
|
||||||
|
import co.electriccoin.zcash.preference.api.PreferenceProvider
|
||||||
|
import co.electriccoin.zcash.preference.model.entry.BooleanPreferenceDefault
|
||||||
|
import co.electriccoin.zcash.preference.model.entry.PreferenceKey
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.emitAll
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
|
|
||||||
|
interface BooleanStorageProvider {
|
||||||
|
suspend fun get(): Boolean
|
||||||
|
|
||||||
|
suspend fun store(flag: Boolean)
|
||||||
|
|
||||||
|
fun observe(): Flow<Boolean>
|
||||||
|
|
||||||
|
suspend fun clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class BaseBooleanStorageProvider(key: PreferenceKey) : BooleanStorageProvider {
|
||||||
|
protected abstract val preferenceHolder: PreferenceHolder
|
||||||
|
|
||||||
|
private val default = BooleanPreferenceDefault(key = key, defaultValue = DEFAULT)
|
||||||
|
|
||||||
|
private suspend fun getPreferenceProvider(): PreferenceProvider = preferenceHolder()
|
||||||
|
|
||||||
|
override suspend fun get(): Boolean = default.getValue(getPreferenceProvider())
|
||||||
|
|
||||||
|
override suspend fun store(flag: Boolean) = default.putValue(getPreferenceProvider(), flag)
|
||||||
|
|
||||||
|
override fun observe(): Flow<Boolean> = flow { emitAll(default.observe(getPreferenceProvider())) }
|
||||||
|
|
||||||
|
override suspend fun clear() = default.putValue(getPreferenceProvider(), DEFAULT)
|
||||||
|
}
|
||||||
|
|
||||||
|
private const val DEFAULT = false
|
|
@ -0,0 +1,37 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.provider
|
||||||
|
|
||||||
|
import co.electriccoin.zcash.preference.PreferenceHolder
|
||||||
|
import co.electriccoin.zcash.preference.api.PreferenceProvider
|
||||||
|
import co.electriccoin.zcash.preference.model.entry.IntegerPreferenceDefault
|
||||||
|
import co.electriccoin.zcash.preference.model.entry.PreferenceKey
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.emitAll
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
|
|
||||||
|
interface IntStorageProvider {
|
||||||
|
suspend fun get(): Int
|
||||||
|
|
||||||
|
suspend fun store(amount: Int)
|
||||||
|
|
||||||
|
fun observe(): Flow<Int>
|
||||||
|
|
||||||
|
suspend fun clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class BaseIntStorageProvider(key: PreferenceKey) : IntStorageProvider {
|
||||||
|
protected abstract val preferenceHolder: PreferenceHolder
|
||||||
|
|
||||||
|
private val default = IntegerPreferenceDefault(key = key, defaultValue = DEFAULT)
|
||||||
|
|
||||||
|
private suspend fun getPreferenceProvider(): PreferenceProvider = preferenceHolder()
|
||||||
|
|
||||||
|
override suspend fun get(): Int = default.getValue(getPreferenceProvider())
|
||||||
|
|
||||||
|
override suspend fun store(amount: Int) = default.putValue(getPreferenceProvider(), amount)
|
||||||
|
|
||||||
|
override fun observe(): Flow<Int> = flow { emitAll(default.observe(getPreferenceProvider())) }
|
||||||
|
|
||||||
|
override suspend fun clear() = default.putValue(getPreferenceProvider(), DEFAULT)
|
||||||
|
}
|
||||||
|
|
||||||
|
private const val DEFAULT = 0
|
|
@ -1,45 +1,10 @@
|
||||||
package co.electriccoin.zcash.ui.common.provider
|
package co.electriccoin.zcash.ui.common.provider
|
||||||
|
|
||||||
import co.electriccoin.zcash.preference.EncryptedPreferenceProvider
|
import co.electriccoin.zcash.preference.EncryptedPreferenceProvider
|
||||||
import co.electriccoin.zcash.preference.api.PreferenceProvider
|
|
||||||
import co.electriccoin.zcash.preference.model.entry.PreferenceDefault
|
|
||||||
import co.electriccoin.zcash.preference.model.entry.PreferenceKey
|
import co.electriccoin.zcash.preference.model.entry.PreferenceKey
|
||||||
import java.time.Instant
|
|
||||||
|
|
||||||
interface RestoreTimestampStorageProvider {
|
interface RestoreTimestampStorageProvider : TimestampStorageProvider
|
||||||
suspend fun get(): Instant?
|
|
||||||
|
|
||||||
suspend fun store(key: Instant)
|
|
||||||
|
|
||||||
suspend fun clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
class RestoreTimestampStorageProviderImpl(
|
class RestoreTimestampStorageProviderImpl(
|
||||||
private val encryptedPreferenceProvider: EncryptedPreferenceProvider
|
override val preferenceHolder: EncryptedPreferenceProvider
|
||||||
) : RestoreTimestampStorageProvider {
|
) : BaseTimestampStorageProvider(PreferenceKey("restore_timestamp")), RestoreTimestampStorageProvider
|
||||||
private val default = RestoreTimestampPreferenceDefault()
|
|
||||||
|
|
||||||
override suspend fun get(): Instant? = default.getValue(encryptedPreferenceProvider())
|
|
||||||
|
|
||||||
override suspend fun store(key: Instant) {
|
|
||||||
default.putValue(encryptedPreferenceProvider(), key)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun clear() {
|
|
||||||
default.putValue(encryptedPreferenceProvider(), null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RestoreTimestampPreferenceDefault : PreferenceDefault<Instant?> {
|
|
||||||
override val key: PreferenceKey = PreferenceKey("restore_timestamp")
|
|
||||||
|
|
||||||
override suspend fun getValue(preferenceProvider: PreferenceProvider) =
|
|
||||||
preferenceProvider.getLong(key)?.let {
|
|
||||||
Instant.ofEpochMilli(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun putValue(
|
|
||||||
preferenceProvider: PreferenceProvider,
|
|
||||||
newValue: Instant?
|
|
||||||
) = preferenceProvider.putLong(key, newValue?.toEpochMilli())
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.provider
|
||||||
|
|
||||||
|
import cash.z.ecc.android.sdk.model.AccountUuid
|
||||||
|
import co.electriccoin.zcash.preference.EncryptedPreferenceProvider
|
||||||
|
import co.electriccoin.zcash.preference.api.PreferenceProvider
|
||||||
|
import co.electriccoin.zcash.preference.model.entry.IntegerPreferenceDefault
|
||||||
|
import co.electriccoin.zcash.preference.model.entry.PreferenceKey
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
interface ShieldFundsRemindMeCountStorageProvider {
|
||||||
|
suspend fun get(forAccount: AccountUuid): Int
|
||||||
|
|
||||||
|
suspend fun store(forAccount: AccountUuid, amount: Int)
|
||||||
|
|
||||||
|
suspend fun observe(forAccount: AccountUuid): Flow<Int>
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShieldFundsRemindMeCountStorageProviderImpl(
|
||||||
|
private val encryptedPreferenceProvider: EncryptedPreferenceProvider
|
||||||
|
) : ShieldFundsRemindMeCountStorageProvider {
|
||||||
|
|
||||||
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
|
private fun getDefault(forAccount: AccountUuid): IntegerPreferenceDefault {
|
||||||
|
val key = PreferenceKey("shield_funds_remind_me_count_${forAccount.value.toHexString()}")
|
||||||
|
return IntegerPreferenceDefault(key = key, defaultValue = 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun get(forAccount: AccountUuid): Int {
|
||||||
|
return getDefault(forAccount).getValue(encryptedPreferenceProvider())
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun store(forAccount: AccountUuid, amount: Int) {
|
||||||
|
getDefault(forAccount).putValue(encryptedPreferenceProvider(), amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun observe(forAccount: AccountUuid): Flow<Int> {
|
||||||
|
return getDefault(forAccount).observe(encryptedPreferenceProvider())
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.provider
|
||||||
|
|
||||||
|
import cash.z.ecc.android.sdk.model.AccountUuid
|
||||||
|
import co.electriccoin.zcash.preference.EncryptedPreferenceProvider
|
||||||
|
import co.electriccoin.zcash.preference.model.entry.TimestampPreferenceDefault
|
||||||
|
import co.electriccoin.zcash.preference.model.entry.PreferenceKey
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
interface ShieldFundsRemindMeTimestampStorageProvider {
|
||||||
|
suspend fun get(forAccount: AccountUuid): Instant?
|
||||||
|
|
||||||
|
suspend fun store(forAccount: AccountUuid, timestamp: Instant)
|
||||||
|
|
||||||
|
suspend fun observe(forAccount: AccountUuid): Flow<Instant?>
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShieldFundsRemindMeTimestampStorageProviderImpl(
|
||||||
|
private val encryptedPreferenceProvider: EncryptedPreferenceProvider
|
||||||
|
) : ShieldFundsRemindMeTimestampStorageProvider {
|
||||||
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
|
private fun getDefault(forAccount: AccountUuid): TimestampPreferenceDefault {
|
||||||
|
val key = PreferenceKey("shield_funds_remind_me_timestamp_${forAccount.value.toHexString()}")
|
||||||
|
return TimestampPreferenceDefault(key = key)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun get(forAccount: AccountUuid): Instant? {
|
||||||
|
return getDefault(forAccount).getValue(encryptedPreferenceProvider())
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun store(forAccount: AccountUuid, timestamp: Instant) {
|
||||||
|
getDefault(forAccount).putValue(encryptedPreferenceProvider(), timestamp)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun observe(forAccount: AccountUuid): Flow<Instant?> {
|
||||||
|
return getDefault(forAccount).observe(encryptedPreferenceProvider())
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,7 +53,7 @@ class SynchronizerProviderImpl(
|
||||||
}.flowOn(Dispatchers.IO)
|
}.flowOn(Dispatchers.IO)
|
||||||
.stateIn(
|
.stateIn(
|
||||||
scope = scope,
|
scope = scope,
|
||||||
started = SharingStarted.WhileSubscribed(Duration.ZERO, Duration.ZERO),
|
started = SharingStarted.Lazily,
|
||||||
initialValue = null
|
initialValue = null
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.provider
|
||||||
|
|
||||||
|
import co.electriccoin.zcash.preference.PreferenceHolder
|
||||||
|
import co.electriccoin.zcash.preference.api.PreferenceProvider
|
||||||
|
import co.electriccoin.zcash.preference.model.entry.PreferenceKey
|
||||||
|
import co.electriccoin.zcash.preference.model.entry.TimestampPreferenceDefault
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.emitAll
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
interface TimestampStorageProvider {
|
||||||
|
suspend fun get(): Instant?
|
||||||
|
|
||||||
|
suspend fun store(timestamp: Instant)
|
||||||
|
|
||||||
|
fun observe(): Flow<Instant?>
|
||||||
|
|
||||||
|
suspend fun clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class BaseTimestampStorageProvider(key: PreferenceKey) : TimestampStorageProvider {
|
||||||
|
protected abstract val preferenceHolder: PreferenceHolder
|
||||||
|
|
||||||
|
private val default = TimestampPreferenceDefault(key)
|
||||||
|
|
||||||
|
private suspend fun getPreferenceProvider(): PreferenceProvider = preferenceHolder()
|
||||||
|
|
||||||
|
override suspend fun get(): Instant? = default.getValue(getPreferenceProvider())
|
||||||
|
|
||||||
|
override suspend fun store(timestamp: Instant) = default.putValue(getPreferenceProvider(), timestamp)
|
||||||
|
|
||||||
|
override fun observe(): Flow<Instant?> = flow { emitAll(default.observe(getPreferenceProvider())) }
|
||||||
|
|
||||||
|
override suspend fun clear() = default.putValue(getPreferenceProvider(), null)
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.provider
|
||||||
|
|
||||||
|
import co.electriccoin.zcash.preference.EncryptedPreferenceProvider
|
||||||
|
import co.electriccoin.zcash.preference.model.entry.PreferenceKey
|
||||||
|
|
||||||
|
interface WalletBackupFlagStorageProvider : BooleanStorageProvider
|
||||||
|
|
||||||
|
class WalletBackupFlagStorageProviderImpl(
|
||||||
|
override val preferenceHolder: EncryptedPreferenceProvider
|
||||||
|
) : BaseBooleanStorageProvider(key = PreferenceKey("wallet_backup_flag")),
|
||||||
|
WalletBackupFlagStorageProvider
|
|
@ -0,0 +1,11 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.provider
|
||||||
|
|
||||||
|
import co.electriccoin.zcash.preference.EncryptedPreferenceProvider
|
||||||
|
import co.electriccoin.zcash.preference.model.entry.PreferenceKey
|
||||||
|
|
||||||
|
interface WalletBackupRemindMeCountStorageProvider : IntStorageProvider
|
||||||
|
|
||||||
|
class WalletBackupRemindMeCountStorageProviderImpl(
|
||||||
|
override val preferenceHolder: EncryptedPreferenceProvider
|
||||||
|
) : BaseIntStorageProvider(key = PreferenceKey("wallet_backup_remind_me_count")),
|
||||||
|
WalletBackupRemindMeCountStorageProvider
|
|
@ -0,0 +1,11 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.provider
|
||||||
|
|
||||||
|
import co.electriccoin.zcash.preference.EncryptedPreferenceProvider
|
||||||
|
import co.electriccoin.zcash.preference.model.entry.PreferenceKey
|
||||||
|
|
||||||
|
interface WalletBackupRemindMeTimestampStorageProvider : TimestampStorageProvider
|
||||||
|
|
||||||
|
class WalletBackupRemindMeTimestampStorageProviderImpl(
|
||||||
|
override val preferenceHolder: EncryptedPreferenceProvider
|
||||||
|
) : BaseTimestampStorageProvider(key = PreferenceKey("wallet_backup_remind_me_timestamp")),
|
||||||
|
WalletBackupRemindMeTimestampStorageProvider
|
|
@ -5,13 +5,11 @@ import cash.z.ecc.sdk.ANDROID_STATE_FLOW_TIMEOUT
|
||||||
import co.electriccoin.zcash.preference.StandardPreferenceProvider
|
import co.electriccoin.zcash.preference.StandardPreferenceProvider
|
||||||
import co.electriccoin.zcash.preference.model.entry.NullableBooleanPreferenceDefault
|
import co.electriccoin.zcash.preference.model.entry.NullableBooleanPreferenceDefault
|
||||||
import co.electriccoin.zcash.spackle.Twig
|
import co.electriccoin.zcash.spackle.Twig
|
||||||
import co.electriccoin.zcash.ui.NavigationRouter
|
|
||||||
import co.electriccoin.zcash.ui.common.provider.SynchronizerProvider
|
import co.electriccoin.zcash.ui.common.provider.SynchronizerProvider
|
||||||
import co.electriccoin.zcash.ui.common.wallet.ExchangeRateState
|
import co.electriccoin.zcash.ui.common.wallet.ExchangeRateState
|
||||||
import co.electriccoin.zcash.ui.common.wallet.RefreshLock
|
import co.electriccoin.zcash.ui.common.wallet.RefreshLock
|
||||||
import co.electriccoin.zcash.ui.common.wallet.StaleLock
|
import co.electriccoin.zcash.ui.common.wallet.StaleLock
|
||||||
import co.electriccoin.zcash.ui.preference.StandardPreferenceKeys
|
import co.electriccoin.zcash.ui.preference.StandardPreferenceKeys
|
||||||
import co.electriccoin.zcash.ui.screen.exchangerate.optin.ExchangeRateOptIn
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
@ -37,26 +35,19 @@ import kotlin.time.Duration.Companion.minutes
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
interface ExchangeRateRepository {
|
interface ExchangeRateRepository {
|
||||||
val isExchangeRateUsdOptedIn: StateFlow<Boolean?>
|
|
||||||
|
|
||||||
val state: StateFlow<ExchangeRateState>
|
val state: StateFlow<ExchangeRateState>
|
||||||
|
|
||||||
fun optInExchangeRateUsd(optIn: Boolean)
|
fun optInExchangeRateUsd(optIn: Boolean)
|
||||||
|
|
||||||
fun dismissOptInExchangeRateUsd()
|
|
||||||
|
|
||||||
fun refreshExchangeRateUsd()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExchangeRateRepositoryImpl(
|
class ExchangeRateRepositoryImpl(
|
||||||
private val synchronizerProvider: SynchronizerProvider,
|
private val synchronizerProvider: SynchronizerProvider,
|
||||||
private val standardPreferenceProvider: StandardPreferenceProvider,
|
private val standardPreferenceProvider: StandardPreferenceProvider,
|
||||||
private val navigationRouter: NavigationRouter,
|
|
||||||
) : ExchangeRateRepository {
|
) : ExchangeRateRepository {
|
||||||
|
|
||||||
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||||
|
|
||||||
override val isExchangeRateUsdOptedIn: StateFlow<Boolean?> =
|
private val isExchangeRateUsdOptedIn = nullableBooleanStateFlow(StandardPreferenceKeys.EXCHANGE_RATE_OPTED_IN)
|
||||||
nullableBooleanStateFlow(StandardPreferenceKeys.EXCHANGE_RATE_OPTED_IN)
|
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
private val exchangeRateUsdInternal =
|
private val exchangeRateUsdInternal =
|
||||||
|
@ -167,17 +158,13 @@ class ExchangeRateRepositoryImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
false -> ExchangeRateState.OptedOut
|
false -> ExchangeRateState.OptedOut
|
||||||
null ->
|
null -> ExchangeRateState.OptIn
|
||||||
ExchangeRateState.OptIn(
|
|
||||||
onDismissClick = ::dismissWidgetOptInExchangeRateUsd,
|
|
||||||
onPrimaryClick = ::showOptInExchangeRateUsd
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return lastExchangeRateUsdValue
|
return lastExchangeRateUsdValue
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun refreshExchangeRateUsd() {
|
private fun refreshExchangeRateUsd() {
|
||||||
refreshExchangeRateUsdInternal()
|
refreshExchangeRateUsdInternal()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,20 +179,8 @@ class ExchangeRateRepositoryImpl(
|
||||||
|
|
||||||
override fun optInExchangeRateUsd(optIn: Boolean) {
|
override fun optInExchangeRateUsd(optIn: Boolean) {
|
||||||
setNullableBooleanPreference(StandardPreferenceKeys.EXCHANGE_RATE_OPTED_IN, optIn)
|
setNullableBooleanPreference(StandardPreferenceKeys.EXCHANGE_RATE_OPTED_IN, optIn)
|
||||||
navigationRouter.back()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dismissOptInExchangeRateUsd() {
|
|
||||||
setNullableBooleanPreference(StandardPreferenceKeys.EXCHANGE_RATE_OPTED_IN, false)
|
|
||||||
navigationRouter.back()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun dismissWidgetOptInExchangeRateUsd() {
|
|
||||||
setNullableBooleanPreference(StandardPreferenceKeys.EXCHANGE_RATE_OPTED_IN, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showOptInExchangeRateUsd() = navigationRouter.forward(ExchangeRateOptIn)
|
|
||||||
|
|
||||||
private fun nullableBooleanStateFlow(default: NullableBooleanPreferenceDefault): StateFlow<Boolean?> =
|
private fun nullableBooleanStateFlow(default: NullableBooleanPreferenceDefault): StateFlow<Boolean?> =
|
||||||
flow {
|
flow {
|
||||||
emitAll(default.observe(standardPreferenceProvider()))
|
emitAll(default.observe(standardPreferenceProvider()))
|
||||||
|
@ -217,7 +192,7 @@ class ExchangeRateRepositoryImpl(
|
||||||
|
|
||||||
private fun setNullableBooleanPreference(
|
private fun setNullableBooleanPreference(
|
||||||
default: NullableBooleanPreferenceDefault,
|
default: NullableBooleanPreferenceDefault,
|
||||||
newState: Boolean
|
newState: Boolean?
|
||||||
) {
|
) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
default.putValue(standardPreferenceProvider(), newState)
|
default.putValue(standardPreferenceProvider(), newState)
|
||||||
|
|
|
@ -20,7 +20,6 @@ import co.electriccoin.zcash.ui.common.datasource.AccountDataSource
|
||||||
import co.electriccoin.zcash.ui.common.datasource.RestoreTimestampDataSource
|
import co.electriccoin.zcash.ui.common.datasource.RestoreTimestampDataSource
|
||||||
import co.electriccoin.zcash.ui.common.model.FastestServersState
|
import co.electriccoin.zcash.ui.common.model.FastestServersState
|
||||||
import co.electriccoin.zcash.ui.common.model.OnboardingState
|
import co.electriccoin.zcash.ui.common.model.OnboardingState
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletAccount
|
import co.electriccoin.zcash.ui.common.model.WalletAccount
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
||||||
|
@ -81,11 +80,6 @@ interface WalletRepository {
|
||||||
*/
|
*/
|
||||||
val walletRestoringState: StateFlow<WalletRestoringState>
|
val walletRestoringState: StateFlow<WalletRestoringState>
|
||||||
|
|
||||||
/**
|
|
||||||
* A flow of the wallet current state information that should be displayed in screens top app bar.
|
|
||||||
*/
|
|
||||||
val walletStateInformation: StateFlow<TopAppBarSubTitleState>
|
|
||||||
|
|
||||||
fun persistWallet(persistableWallet: PersistableWallet)
|
fun persistWallet(persistableWallet: PersistableWallet)
|
||||||
|
|
||||||
fun persistOnboardingState(onboardingState: OnboardingState)
|
fun persistOnboardingState(onboardingState: OnboardingState)
|
||||||
|
@ -228,29 +222,6 @@ class WalletRepositoryImpl(
|
||||||
initialValue = WalletRestoringState.NONE
|
initialValue = WalletRestoringState.NONE
|
||||||
)
|
)
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
override val walletStateInformation: StateFlow<TopAppBarSubTitleState> =
|
|
||||||
synchronizer
|
|
||||||
.filterNotNull()
|
|
||||||
.flatMapLatest { synchronizer ->
|
|
||||||
combine(
|
|
||||||
synchronizer.status,
|
|
||||||
walletRestoringState
|
|
||||||
) { status: Synchronizer.Status?, walletRestoringState: WalletRestoringState ->
|
|
||||||
if (Synchronizer.Status.DISCONNECTED == status) {
|
|
||||||
TopAppBarSubTitleState.Disconnected
|
|
||||||
} else if (WalletRestoringState.RESTORING == walletRestoringState) {
|
|
||||||
TopAppBarSubTitleState.Restoring
|
|
||||||
} else {
|
|
||||||
TopAppBarSubTitleState.None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.stateIn(
|
|
||||||
scope = scope,
|
|
||||||
started = SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT),
|
|
||||||
initialValue = TopAppBarSubTitleState.None
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persists a wallet asynchronously. Clients observe [secretState] to see the side effects.
|
* Persists a wallet asynchronously. Clients observe [secretState] to see the side effects.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.usecase
|
||||||
|
|
||||||
|
import cash.z.ecc.android.sdk.Synchronizer
|
||||||
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
|
import co.electriccoin.zcash.ui.common.datasource.WalletBackupAvailability
|
||||||
|
import co.electriccoin.zcash.ui.common.datasource.WalletBackupDataSource
|
||||||
|
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
||||||
|
import co.electriccoin.zcash.ui.common.repository.ExchangeRateRepository
|
||||||
|
import co.electriccoin.zcash.ui.common.repository.WalletRepository
|
||||||
|
import co.electriccoin.zcash.ui.common.viewmodel.SynchronizerError
|
||||||
|
import co.electriccoin.zcash.ui.common.wallet.ExchangeRateState
|
||||||
|
import co.electriccoin.zcash.ui.util.Quadruple
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.FlowPreview
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import kotlinx.coroutines.flow.debounce
|
||||||
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
|
import kotlinx.coroutines.flow.filterNotNull
|
||||||
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
|
class GetHomeMessageUseCase(
|
||||||
|
private val walletRepository: WalletRepository,
|
||||||
|
private val walletBackupDataSource: WalletBackupDataSource,
|
||||||
|
private val exchangeRateRepository: ExchangeRateRepository,
|
||||||
|
) {
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class)
|
||||||
|
fun observe() = combine(
|
||||||
|
walletRepository.currentWalletSnapshot.filterNotNull(),
|
||||||
|
walletRepository.walletRestoringState,
|
||||||
|
walletBackupDataSource.observe(),
|
||||||
|
exchangeRateRepository.state.map { it == ExchangeRateState.OptIn }.distinctUntilChanged(),
|
||||||
|
) { walletSnapshot, walletStateInformation, backup, isCCAvailable ->
|
||||||
|
Quadruple(walletSnapshot, walletStateInformation, backup, isCCAvailable)
|
||||||
|
}.flatMapLatest { (walletSnapshot, walletStateInformation, backup, isCCAvailable) ->
|
||||||
|
when {
|
||||||
|
walletSnapshot.synchronizerError != null -> {
|
||||||
|
flowOf(HomeMessageData.Error(walletSnapshot.synchronizerError))
|
||||||
|
}
|
||||||
|
|
||||||
|
walletSnapshot.status == Synchronizer.Status.DISCONNECTED -> {
|
||||||
|
flowOf(HomeMessageData.Disconnected)
|
||||||
|
}
|
||||||
|
|
||||||
|
walletSnapshot.status in listOf(
|
||||||
|
Synchronizer.Status.INITIALIZING,
|
||||||
|
Synchronizer.Status.SYNCING,
|
||||||
|
Synchronizer.Status.STOPPED
|
||||||
|
) -> {
|
||||||
|
flow {
|
||||||
|
val progress = walletSnapshot.progress.decimal * 100f
|
||||||
|
val result = when {
|
||||||
|
walletStateInformation == WalletRestoringState.RESTORING -> {
|
||||||
|
HomeMessageData.Restoring(
|
||||||
|
progress = progress,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
HomeMessageData.Syncing(progress = progress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
backup is WalletBackupAvailability.Available -> flowOf(HomeMessageData.Backup)
|
||||||
|
|
||||||
|
isCCAvailable -> flowOf(HomeMessageData.EnableCurrencyConversion)
|
||||||
|
|
||||||
|
else -> flowOf(null)
|
||||||
|
}
|
||||||
|
}.debounce(.5.seconds)
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface HomeMessageData {
|
||||||
|
data object EnableCurrencyConversion : HomeMessageData
|
||||||
|
data class TransparentBalance(val zatoshi: Zatoshi) : HomeMessageData
|
||||||
|
data object Backup : HomeMessageData
|
||||||
|
data object Disconnected : HomeMessageData
|
||||||
|
data class Error(val synchronizerError: SynchronizerError) : HomeMessageData
|
||||||
|
data class Restoring(val progress: Float) : HomeMessageData
|
||||||
|
data class Syncing(val progress: Float) : HomeMessageData
|
||||||
|
data object Updating : HomeMessageData
|
||||||
|
}
|
|
@ -1,9 +0,0 @@
|
||||||
package co.electriccoin.zcash.ui.common.usecase
|
|
||||||
|
|
||||||
import co.electriccoin.zcash.ui.common.repository.WalletRepository
|
|
||||||
|
|
||||||
class GetWalletStateInformationUseCase(
|
|
||||||
private val walletRepository: WalletRepository
|
|
||||||
) {
|
|
||||||
fun observe() = walletRepository.walletStateInformation
|
|
||||||
}
|
|
|
@ -7,13 +7,13 @@ import co.electriccoin.zcash.ui.common.repository.BiometricRequest
|
||||||
import co.electriccoin.zcash.ui.common.repository.BiometricsCancelledException
|
import co.electriccoin.zcash.ui.common.repository.BiometricsCancelledException
|
||||||
import co.electriccoin.zcash.ui.common.repository.BiometricsFailureException
|
import co.electriccoin.zcash.ui.common.repository.BiometricsFailureException
|
||||||
import co.electriccoin.zcash.ui.design.util.stringRes
|
import co.electriccoin.zcash.ui.design.util.stringRes
|
||||||
import co.electriccoin.zcash.ui.screen.seed.SeedRecovery
|
import co.electriccoin.zcash.ui.screen.walletbackup.WalletBackup
|
||||||
|
|
||||||
class NavigateToSeedRecoveryUseCase(
|
class NavigateToWalletBackupUseCase(
|
||||||
private val navigationRouter: NavigationRouter,
|
private val navigationRouter: NavigationRouter,
|
||||||
private val biometricRepository: BiometricRepository
|
private val biometricRepository: BiometricRepository
|
||||||
) {
|
) {
|
||||||
suspend operator fun invoke() {
|
suspend operator fun invoke(isOpenedFromSeedBackupInfo: Boolean) {
|
||||||
try {
|
try {
|
||||||
biometricRepository.requestBiometrics(
|
biometricRepository.requestBiometrics(
|
||||||
BiometricRequest(
|
BiometricRequest(
|
||||||
|
@ -24,7 +24,7 @@ class NavigateToSeedRecoveryUseCase(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
navigationRouter.forward(SeedRecovery)
|
navigationRouter.forward(WalletBackup(isOpenedFromSeedBackupInfo = isOpenedFromSeedBackupInfo))
|
||||||
} catch (_: BiometricsFailureException) {
|
} catch (_: BiometricsFailureException) {
|
||||||
// do nothing
|
// do nothing
|
||||||
} catch (_: BiometricsCancelledException) {
|
} catch (_: BiometricsCancelledException) {
|
|
@ -0,0 +1,14 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.usecase
|
||||||
|
|
||||||
|
import co.electriccoin.zcash.ui.NavigationRouter
|
||||||
|
import co.electriccoin.zcash.ui.common.datasource.WalletBackupDataSource
|
||||||
|
|
||||||
|
class OnUserSavedWalletBackupUseCase(
|
||||||
|
private val navigationRouter: NavigationRouter,
|
||||||
|
private val walletBackupDataSource: WalletBackupDataSource
|
||||||
|
) {
|
||||||
|
suspend operator fun invoke() {
|
||||||
|
walletBackupDataSource.remindMeLater()
|
||||||
|
navigationRouter.backToRoot()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.usecase
|
||||||
|
|
||||||
|
import co.electriccoin.zcash.ui.NavigationRouter
|
||||||
|
import co.electriccoin.zcash.ui.common.datasource.WalletBackupDataSource
|
||||||
|
|
||||||
|
class RemindWalletBackupLaterUseCase(
|
||||||
|
private val navigationRouter: NavigationRouter,
|
||||||
|
private val walletBackupDataSource: WalletBackupDataSource
|
||||||
|
) {
|
||||||
|
suspend operator fun invoke() {
|
||||||
|
walletBackupDataSource.remindMeLater()
|
||||||
|
navigationRouter.backToRoot()
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,6 @@ package co.electriccoin.zcash.ui.common.viewmodel
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import cash.z.ecc.android.sdk.Synchronizer
|
|
||||||
import cash.z.ecc.android.sdk.WalletCoordinator
|
import cash.z.ecc.android.sdk.WalletCoordinator
|
||||||
import cash.z.ecc.android.sdk.WalletInitMode
|
import cash.z.ecc.android.sdk.WalletInitMode
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
|
@ -13,12 +12,10 @@ import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.sdk.type.fromResources
|
import cash.z.ecc.sdk.type.fromResources
|
||||||
import co.electriccoin.zcash.preference.StandardPreferenceProvider
|
import co.electriccoin.zcash.preference.StandardPreferenceProvider
|
||||||
import co.electriccoin.zcash.spackle.Twig
|
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.OnboardingState
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
||||||
import co.electriccoin.zcash.ui.common.provider.GetDefaultServersProvider
|
import co.electriccoin.zcash.ui.common.provider.GetDefaultServersProvider
|
||||||
import co.electriccoin.zcash.ui.common.repository.ExchangeRateRepository
|
|
||||||
import co.electriccoin.zcash.ui.common.repository.WalletRepository
|
import co.electriccoin.zcash.ui.common.repository.WalletRepository
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetSynchronizerUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetSynchronizerUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.IsFlexaAvailableUseCase
|
import co.electriccoin.zcash.ui.common.usecase.IsFlexaAvailableUseCase
|
||||||
|
@ -44,39 +41,19 @@ class WalletViewModel(
|
||||||
application: Application,
|
application: Application,
|
||||||
private val walletCoordinator: WalletCoordinator,
|
private val walletCoordinator: WalletCoordinator,
|
||||||
private val walletRepository: WalletRepository,
|
private val walletRepository: WalletRepository,
|
||||||
private val exchangeRateRepository: ExchangeRateRepository,
|
|
||||||
private val standardPreferenceProvider: StandardPreferenceProvider,
|
private val standardPreferenceProvider: StandardPreferenceProvider,
|
||||||
private val getAvailableServers: GetDefaultServersProvider,
|
private val getAvailableServers: GetDefaultServersProvider,
|
||||||
private val resetInMemoryData: ResetInMemoryDataUseCase,
|
private val resetInMemoryData: ResetInMemoryDataUseCase,
|
||||||
private val resetSharedPrefsData: ResetSharedPrefsDataUseCase,
|
private val resetSharedPrefsData: ResetSharedPrefsDataUseCase,
|
||||||
private val isFlexaAvailable: IsFlexaAvailableUseCase,
|
private val isFlexaAvailable: IsFlexaAvailableUseCase,
|
||||||
private val getSynchronizer: GetSynchronizerUseCase,
|
private val getSynchronizer: GetSynchronizerUseCase,
|
||||||
private val navigationRouter: NavigationRouter,
|
|
||||||
) : AndroidViewModel(application) {
|
) : AndroidViewModel(application) {
|
||||||
val synchronizer = walletRepository.synchronizer
|
val synchronizer = walletRepository.synchronizer
|
||||||
|
|
||||||
val walletStateInformation = walletRepository.walletStateInformation
|
|
||||||
|
|
||||||
val secretState: StateFlow<SecretState> = walletRepository.secretState
|
val secretState: StateFlow<SecretState> = walletRepository.secretState
|
||||||
|
|
||||||
val currentWalletSnapshot: StateFlow<WalletSnapshot?> = walletRepository.currentWalletSnapshot
|
val currentWalletSnapshot: StateFlow<WalletSnapshot?> = walletRepository.currentWalletSnapshot
|
||||||
|
|
||||||
val isExchangeRateUsdOptedIn = exchangeRateRepository.isExchangeRateUsdOptedIn
|
|
||||||
|
|
||||||
val exchangeRateUsd = exchangeRateRepository.state
|
|
||||||
|
|
||||||
fun optInExchangeRateUsd(optIn: Boolean) {
|
|
||||||
exchangeRateRepository.optInExchangeRateUsd(optIn)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun dismissOptInExchangeRateUsd() {
|
|
||||||
navigationRouter.back()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onSkipClick() {
|
|
||||||
navigationRouter.back()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun persistNewWalletAndRestoringState(state: WalletRestoringState) {
|
fun persistNewWalletAndRestoringState(state: WalletRestoringState) {
|
||||||
val application = getApplication<Application>()
|
val application = getApplication<Application>()
|
||||||
|
|
||||||
|
@ -259,5 +236,3 @@ sealed class SynchronizerError {
|
||||||
override fun getStackTrace(limit: Int?): String? = null
|
override fun getStackTrace(limit: Int?): String? = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Synchronizer.Status.isSynced() = this == Synchronizer.Status.SYNCED
|
|
||||||
|
|
|
@ -13,10 +13,7 @@ sealed interface ExchangeRateState {
|
||||||
val onRefresh: () -> Unit,
|
val onRefresh: () -> Unit,
|
||||||
) : ExchangeRateState
|
) : ExchangeRateState
|
||||||
|
|
||||||
data class OptIn(
|
data object OptIn : ExchangeRateState
|
||||||
val onDismissClick: () -> Unit = {},
|
|
||||||
val onPrimaryClick: () -> Unit = {}
|
|
||||||
) : ExchangeRateState
|
|
||||||
|
|
||||||
data object OptedOut : ExchangeRateState
|
data object OptedOut : ExchangeRateState
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ object ZashiMainTopAppBarStateFixture {
|
||||||
) = ZashiMainTopAppBarState(
|
) = ZashiMainTopAppBarState(
|
||||||
accountSwitchState = accountSwitchState,
|
accountSwitchState = accountSwitchState,
|
||||||
balanceVisibilityButton = balanceVisibilityButton,
|
balanceVisibilityButton = balanceVisibilityButton,
|
||||||
settingsButton = settingsButton,
|
settingsButton = settingsButton
|
||||||
subtitle = null
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,4 +16,8 @@ data class PersistableWalletPreferenceDefault(
|
||||||
preferenceProvider: PreferenceProvider,
|
preferenceProvider: PreferenceProvider,
|
||||||
newValue: PersistableWallet?
|
newValue: PersistableWallet?
|
||||||
) = preferenceProvider.putString(key, newValue?.toJson()?.toString())
|
) = preferenceProvider.putString(key, newValue?.toJson()?.toString())
|
||||||
|
|
||||||
|
suspend fun remove(preferenceProvider: PreferenceProvider) {
|
||||||
|
preferenceProvider.remove(key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,10 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|
||||||
import co.electriccoin.zcash.configuration.api.ConfigurationProvider
|
import co.electriccoin.zcash.configuration.api.ConfigurationProvider
|
||||||
import co.electriccoin.zcash.di.koinActivityViewModel
|
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
|
||||||
import co.electriccoin.zcash.ui.screen.about.util.WebBrowserUtil
|
import co.electriccoin.zcash.ui.screen.about.util.WebBrowserUtil
|
||||||
import co.electriccoin.zcash.ui.screen.about.view.About
|
import co.electriccoin.zcash.ui.screen.about.view.About
|
||||||
import co.electriccoin.zcash.ui.screen.support.model.ConfigInfo
|
import co.electriccoin.zcash.ui.screen.support.model.ConfigInfo
|
||||||
|
@ -26,9 +23,6 @@ import org.koin.compose.koinInject
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapAbout(goBack: () -> Unit) {
|
internal fun WrapAbout(goBack: () -> Unit) {
|
||||||
val activity = LocalActivity.current
|
val activity = LocalActivity.current
|
||||||
val walletViewModel = koinActivityViewModel<WalletViewModel>()
|
|
||||||
|
|
||||||
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
|
||||||
|
|
||||||
BackHandler {
|
BackHandler {
|
||||||
goBack()
|
goBack()
|
||||||
|
@ -49,7 +43,6 @@ internal fun WrapAbout(goBack: () -> Unit) {
|
||||||
|
|
||||||
About(
|
About(
|
||||||
onBack = goBack,
|
onBack = goBack,
|
||||||
versionInfo = versionInfo,
|
|
||||||
configInfo = configInfo,
|
configInfo = configInfo,
|
||||||
onPrivacyPolicy = {
|
onPrivacyPolicy = {
|
||||||
openPrivacyPolicyInWebBrowser(
|
openPrivacyPolicyInWebBrowser(
|
||||||
|
@ -59,7 +52,7 @@ internal fun WrapAbout(goBack: () -> Unit) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
snackbarHostState = snackbarHostState,
|
snackbarHostState = snackbarHostState,
|
||||||
topAppBarSubTitleState = walletState,
|
versionInfo = versionInfo,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiSmallTopAppBar
|
import co.electriccoin.zcash.ui.design.component.ZashiSmallTopAppBar
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiTopAppBarBackNavigation
|
import co.electriccoin.zcash.ui.design.component.ZashiTopAppBarBackNavigation
|
||||||
|
@ -48,13 +47,11 @@ import co.electriccoin.zcash.ui.fixture.VersionInfoFixture
|
||||||
import co.electriccoin.zcash.ui.screen.support.model.ConfigInfo
|
import co.electriccoin.zcash.ui.screen.support.model.ConfigInfo
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@Suppress("LongParameterList")
|
|
||||||
fun About(
|
fun About(
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
configInfo: ConfigInfo,
|
configInfo: ConfigInfo,
|
||||||
onPrivacyPolicy: () -> Unit,
|
onPrivacyPolicy: () -> Unit,
|
||||||
snackbarHostState: SnackbarHostState,
|
snackbarHostState: SnackbarHostState,
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState,
|
|
||||||
versionInfo: VersionInfo,
|
versionInfo: VersionInfo,
|
||||||
) {
|
) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
|
@ -63,7 +60,6 @@ fun About(
|
||||||
onBack = onBack,
|
onBack = onBack,
|
||||||
versionInfo = versionInfo,
|
versionInfo = versionInfo,
|
||||||
configInfo = configInfo,
|
configInfo = configInfo,
|
||||||
subTitleState = topAppBarSubTitleState,
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
snackbarHost = { SnackbarHost(snackbarHostState) },
|
snackbarHost = { SnackbarHost(snackbarHostState) },
|
||||||
|
@ -85,16 +81,9 @@ fun About(
|
||||||
private fun AboutTopAppBar(
|
private fun AboutTopAppBar(
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
versionInfo: VersionInfo,
|
versionInfo: VersionInfo,
|
||||||
configInfo: ConfigInfo,
|
configInfo: ConfigInfo
|
||||||
subTitleState: TopAppBarSubTitleState
|
|
||||||
) {
|
) {
|
||||||
ZashiSmallTopAppBar(
|
ZashiSmallTopAppBar(
|
||||||
subtitle =
|
|
||||||
when (subTitleState) {
|
|
||||||
TopAppBarSubTitleState.Disconnected -> stringResource(id = R.string.disconnected_label)
|
|
||||||
TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label)
|
|
||||||
TopAppBarSubTitleState.None -> null
|
|
||||||
},
|
|
||||||
title = stringResource(id = R.string.about_title),
|
title = stringResource(id = R.string.about_title),
|
||||||
navigationAction = {
|
navigationAction = {
|
||||||
ZashiTopAppBarBackNavigation(onBack = onBack)
|
ZashiTopAppBarBackNavigation(onBack = onBack)
|
||||||
|
@ -198,7 +187,6 @@ private fun AboutPreview() =
|
||||||
configInfo = ConfigInfoFixture.new(),
|
configInfo = ConfigInfoFixture.new(),
|
||||||
onPrivacyPolicy = {},
|
onPrivacyPolicy = {},
|
||||||
snackbarHostState = SnackbarHostState(),
|
snackbarHostState = SnackbarHostState(),
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
versionInfo = VersionInfoFixture.new(),
|
versionInfo = VersionInfoFixture.new(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,6 @@ import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.di.koinActivityViewModel
|
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
|
||||||
import co.electriccoin.zcash.ui.screen.addressbook.view.AddressBookView
|
import co.electriccoin.zcash.ui.screen.addressbook.view.AddressBookView
|
||||||
import co.electriccoin.zcash.ui.screen.addressbook.viewmodel.AddressBookViewModel
|
import co.electriccoin.zcash.ui.screen.addressbook.viewmodel.AddressBookViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.addressbook.viewmodel.SelectRecipientViewModel
|
import co.electriccoin.zcash.ui.screen.addressbook.viewmodel.SelectRecipientViewModel
|
||||||
|
@ -23,9 +21,7 @@ internal fun WrapAddressBook(args: AddressBookArgs) {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun WrapAddressBook() {
|
private fun WrapAddressBook() {
|
||||||
val walletViewModel = koinActivityViewModel<WalletViewModel>()
|
|
||||||
val viewModel = koinViewModel<AddressBookViewModel>()
|
val viewModel = koinViewModel<AddressBookViewModel>()
|
||||||
val walletState by walletViewModel.walletStateInformation.collectAsStateWithLifecycle()
|
|
||||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
BackHandler {
|
BackHandler {
|
||||||
|
@ -34,15 +30,12 @@ private fun WrapAddressBook() {
|
||||||
|
|
||||||
AddressBookView(
|
AddressBookView(
|
||||||
state = state,
|
state = state,
|
||||||
topAppBarSubTitleState = walletState,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun WrapSelectRecipient() {
|
private fun WrapSelectRecipient() {
|
||||||
val walletViewModel = koinActivityViewModel<WalletViewModel>()
|
|
||||||
val viewModel = koinViewModel<SelectRecipientViewModel>()
|
val viewModel = koinViewModel<SelectRecipientViewModel>()
|
||||||
val walletState by walletViewModel.walletStateInformation.collectAsStateWithLifecycle()
|
|
||||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
BackHandler {
|
BackHandler {
|
||||||
|
@ -51,7 +44,6 @@ private fun WrapSelectRecipient() {
|
||||||
|
|
||||||
AddressBookView(
|
AddressBookView(
|
||||||
state = state,
|
state = state,
|
||||||
topAppBarSubTitleState = walletState,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@ import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.IntOffset
|
import androidx.compose.ui.unit.IntOffset
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
|
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
|
||||||
import co.electriccoin.zcash.ui.design.component.ButtonState
|
import co.electriccoin.zcash.ui.design.component.ButtonState
|
||||||
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
|
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
|
||||||
|
@ -67,14 +66,12 @@ import co.electriccoin.zcash.ui.screen.addressbook.model.AddressBookState
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AddressBookView(
|
fun AddressBookView(
|
||||||
state: AddressBookState,
|
state: AddressBookState
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState
|
|
||||||
) {
|
) {
|
||||||
BlankBgScaffold(
|
BlankBgScaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
AddressBookTopAppBar(
|
AddressBookTopAppBar(
|
||||||
onBack = state.onBack,
|
onBack = state.onBack,
|
||||||
subTitleState = topAppBarSubTitleState,
|
|
||||||
state = state
|
state = state
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -322,17 +319,10 @@ private fun AddContactButton(
|
||||||
@Composable
|
@Composable
|
||||||
private fun AddressBookTopAppBar(
|
private fun AddressBookTopAppBar(
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
subTitleState: TopAppBarSubTitleState,
|
|
||||||
state: AddressBookState,
|
state: AddressBookState,
|
||||||
) {
|
) {
|
||||||
ZashiSmallTopAppBar(
|
ZashiSmallTopAppBar(
|
||||||
title = state.title.getValue(),
|
title = state.title.getValue(),
|
||||||
subtitle =
|
|
||||||
when (subTitleState) {
|
|
||||||
TopAppBarSubTitleState.Disconnected -> stringResource(id = R.string.disconnected_label)
|
|
||||||
TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label)
|
|
||||||
TopAppBarSubTitleState.None -> null
|
|
||||||
},
|
|
||||||
modifier = Modifier.testTag(AddressBookTag.TOP_APP_BAR),
|
modifier = Modifier.testTag(AddressBookTag.TOP_APP_BAR),
|
||||||
showTitleLogo = true,
|
showTitleLogo = true,
|
||||||
navigationAction = {
|
navigationAction = {
|
||||||
|
@ -382,7 +372,6 @@ private fun AddressBookDataPreview() {
|
||||||
),
|
),
|
||||||
title = stringRes("Address book")
|
title = stringRes("Address book")
|
||||||
),
|
),
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -447,7 +436,6 @@ private fun SelectRecipientDataPreview() {
|
||||||
),
|
),
|
||||||
title = stringRes("Select Recipient")
|
title = stringRes("Select Recipient")
|
||||||
),
|
),
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -472,7 +460,6 @@ private fun LoadingPreview() {
|
||||||
),
|
),
|
||||||
title = stringRes("Select Recipient")
|
title = stringRes("Select Recipient")
|
||||||
),
|
),
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -497,7 +484,6 @@ private fun EmptyAddressBookPreview() {
|
||||||
),
|
),
|
||||||
title = stringRes("Address Book")
|
title = stringRes("Address Book")
|
||||||
),
|
),
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -535,7 +521,6 @@ private fun EmptySelectRecipientPreview() {
|
||||||
),
|
),
|
||||||
title = stringRes("Select Recipient")
|
title = stringRes("Select Recipient")
|
||||||
),
|
),
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.compose.ui.util.fastForEachIndexed
|
import androidx.compose.ui.util.fastForEachIndexed
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
|
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
|
||||||
import co.electriccoin.zcash.ui.design.component.ButtonState
|
import co.electriccoin.zcash.ui.design.component.ButtonState
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiButton
|
import co.electriccoin.zcash.ui.design.component.ZashiButton
|
||||||
|
@ -47,13 +46,11 @@ import kotlinx.collections.immutable.persistentListOf
|
||||||
@Composable
|
@Composable
|
||||||
fun AdvancedSettings(
|
fun AdvancedSettings(
|
||||||
state: AdvancedSettingsState,
|
state: AdvancedSettingsState,
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState,
|
|
||||||
) {
|
) {
|
||||||
BlankBgScaffold(
|
BlankBgScaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
AdvancedSettingsTopAppBar(
|
AdvancedSettingsTopAppBar(
|
||||||
onBack = state.onBack,
|
onBack = state.onBack,
|
||||||
subTitleState = topAppBarSubTitleState,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
|
@ -114,17 +111,10 @@ private fun Info() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun AdvancedSettingsTopAppBar(
|
private fun AdvancedSettingsTopAppBar(
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit
|
||||||
subTitleState: TopAppBarSubTitleState
|
|
||||||
) {
|
) {
|
||||||
ZashiSmallTopAppBar(
|
ZashiSmallTopAppBar(
|
||||||
title = stringResource(id = R.string.advanced_settings_title),
|
title = stringResource(id = R.string.advanced_settings_title),
|
||||||
subtitle =
|
|
||||||
when (subTitleState) {
|
|
||||||
TopAppBarSubTitleState.Disconnected -> stringResource(id = R.string.disconnected_label)
|
|
||||||
TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label)
|
|
||||||
TopAppBarSubTitleState.None -> null
|
|
||||||
},
|
|
||||||
modifier = Modifier.testTag(AdvancedSettingsTag.ADVANCED_SETTINGS_TOP_APP_BAR),
|
modifier = Modifier.testTag(AdvancedSettingsTag.ADVANCED_SETTINGS_TOP_APP_BAR),
|
||||||
showTitleLogo = true,
|
showTitleLogo = true,
|
||||||
navigationAction = {
|
navigationAction = {
|
||||||
|
@ -170,6 +160,5 @@ private fun AdvancedSettingsPreview() =
|
||||||
onClick = {}
|
onClick = {}
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,12 @@ 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.WalletRestoringState
|
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetWalletRestoringStateUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetWalletRestoringStateUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.NavigateToSeedRecoveryUseCase
|
import co.electriccoin.zcash.ui.common.usecase.NavigateToWalletBackupUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.NavigateToTaxExportUseCase
|
import co.electriccoin.zcash.ui.common.usecase.NavigateToTaxExportUseCase
|
||||||
import co.electriccoin.zcash.ui.design.component.ButtonState
|
import co.electriccoin.zcash.ui.design.component.ButtonState
|
||||||
import co.electriccoin.zcash.ui.design.component.listitem.ZashiListItemState
|
import co.electriccoin.zcash.ui.design.component.listitem.ZashiListItemState
|
||||||
import co.electriccoin.zcash.ui.design.util.stringRes
|
import co.electriccoin.zcash.ui.design.util.stringRes
|
||||||
import co.electriccoin.zcash.ui.screen.exchangerate.optin.ExchangeRateOptIn
|
import co.electriccoin.zcash.ui.screen.exchangerate.settings.ExchangeRateSettings
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
@ -26,7 +26,7 @@ class AdvancedSettingsViewModel(
|
||||||
getWalletRestoringState: GetWalletRestoringStateUseCase,
|
getWalletRestoringState: GetWalletRestoringStateUseCase,
|
||||||
private val navigationRouter: NavigationRouter,
|
private val navigationRouter: NavigationRouter,
|
||||||
private val navigateToTaxExport: NavigateToTaxExportUseCase,
|
private val navigateToTaxExport: NavigateToTaxExportUseCase,
|
||||||
private val navigateToSeedRecovery: NavigateToSeedRecoveryUseCase
|
private val navigateToSeedRecovery: NavigateToWalletBackupUseCase
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
val state: StateFlow<AdvancedSettingsState> =
|
val state: StateFlow<AdvancedSettingsState> =
|
||||||
getWalletRestoringState
|
getWalletRestoringState
|
||||||
|
@ -89,7 +89,7 @@ class AdvancedSettingsViewModel(
|
||||||
|
|
||||||
private fun onChooseServerClick() = navigationRouter.forward(NavigationTargets.CHOOSE_SERVER)
|
private fun onChooseServerClick() = navigationRouter.forward(NavigationTargets.CHOOSE_SERVER)
|
||||||
|
|
||||||
private fun onCurrencyConversionClick() = navigationRouter.forward(ExchangeRateOptIn)
|
private fun onCurrencyConversionClick() = navigationRouter.forward(ExchangeRateSettings)
|
||||||
|
|
||||||
private fun onTaxExportClick() =
|
private fun onTaxExportClick() =
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
@ -98,6 +98,6 @@ class AdvancedSettingsViewModel(
|
||||||
|
|
||||||
private fun onSeedRecoveryClick() =
|
private fun onSeedRecoveryClick() =
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
navigateToSeedRecovery()
|
navigateToSeedRecovery(isOpenedFromSeedBackupInfo = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@ package co.electriccoin.zcash.ui.screen.advancedsettings
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.di.koinActivityViewModel
|
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import org.koin.androidx.compose.koinViewModel
|
import org.koin.androidx.compose.koinViewModel
|
||||||
|
|
||||||
|
@ -15,9 +13,7 @@ internal fun WrapAdvancedSettings(
|
||||||
goDeleteWallet: () -> Unit,
|
goDeleteWallet: () -> Unit,
|
||||||
goExportPrivateData: () -> Unit,
|
goExportPrivateData: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val walletViewModel = koinActivityViewModel<WalletViewModel>()
|
|
||||||
val viewModel = koinViewModel<AdvancedSettingsViewModel>()
|
val viewModel = koinViewModel<AdvancedSettingsViewModel>()
|
||||||
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
|
||||||
val originalState = viewModel.state.collectAsStateWithLifecycle().value
|
val originalState = viewModel.state.collectAsStateWithLifecycle().value
|
||||||
val state =
|
val state =
|
||||||
originalState.copy(
|
originalState.copy(
|
||||||
|
@ -38,6 +34,5 @@ internal fun WrapAdvancedSettings(
|
||||||
|
|
||||||
AdvancedSettings(
|
AdvancedSettings(
|
||||||
state = state,
|
state = state,
|
||||||
topAppBarSubTitleState = walletState,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,17 +6,13 @@ import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.di.koinActivityViewModel
|
|
||||||
import co.electriccoin.zcash.ui.common.compose.LocalNavController
|
import co.electriccoin.zcash.ui.common.compose.LocalNavController
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
|
||||||
import org.koin.androidx.compose.koinViewModel
|
import org.koin.androidx.compose.koinViewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapChooseServer() {
|
internal fun WrapChooseServer() {
|
||||||
val navController = LocalNavController.current
|
val navController = LocalNavController.current
|
||||||
val walletViewModel = koinActivityViewModel<WalletViewModel>()
|
|
||||||
val viewModel = koinViewModel<ChooseServerViewModel>()
|
val viewModel = koinViewModel<ChooseServerViewModel>()
|
||||||
val walletState by walletViewModel.walletStateInformation.collectAsStateWithLifecycle()
|
|
||||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
BackHandler {
|
BackHandler {
|
||||||
|
@ -32,6 +28,5 @@ internal fun WrapChooseServer() {
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
topAppBarSubTitleState = walletState,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.design.R.drawable
|
import co.electriccoin.zcash.ui.design.R.drawable
|
||||||
import co.electriccoin.zcash.ui.design.component.AlertDialogState
|
import co.electriccoin.zcash.ui.design.component.AlertDialogState
|
||||||
import co.electriccoin.zcash.ui.design.component.AppAlertDialog
|
import co.electriccoin.zcash.ui.design.component.AppAlertDialog
|
||||||
|
@ -78,7 +77,6 @@ import co.electriccoin.zcash.ui.design.util.stringRes
|
||||||
@Composable
|
@Composable
|
||||||
fun ChooseServerView(
|
fun ChooseServerView(
|
||||||
state: ChooseServerState?,
|
state: ChooseServerState?,
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState,
|
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
) {
|
) {
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
|
@ -91,7 +89,6 @@ fun ChooseServerView(
|
||||||
topBar = {
|
topBar = {
|
||||||
ChooseServerTopAppBar(
|
ChooseServerTopAppBar(
|
||||||
onBack = onBack,
|
onBack = onBack,
|
||||||
subTitleState = topAppBarSubTitleState,
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
|
@ -208,17 +205,10 @@ fun ChooseServerBottomBar(saveButtonState: ButtonState) {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ChooseServerTopAppBar(
|
private fun ChooseServerTopAppBar(
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit
|
||||||
subTitleState: TopAppBarSubTitleState
|
|
||||||
) {
|
) {
|
||||||
ZashiSmallTopAppBar(
|
ZashiSmallTopAppBar(
|
||||||
title = stringResource(id = R.string.choose_server_title),
|
title = stringResource(id = R.string.choose_server_title),
|
||||||
subtitle =
|
|
||||||
when (subTitleState) {
|
|
||||||
TopAppBarSubTitleState.Disconnected -> stringResource(id = R.string.disconnected_label)
|
|
||||||
TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label)
|
|
||||||
TopAppBarSubTitleState.None -> null
|
|
||||||
},
|
|
||||||
modifier = Modifier.testTag(CHOOSE_SERVER_TOP_APP_BAR),
|
modifier = Modifier.testTag(CHOOSE_SERVER_TOP_APP_BAR),
|
||||||
showTitleLogo = true,
|
showTitleLogo = true,
|
||||||
navigationAction = {
|
navigationAction = {
|
||||||
|
@ -535,7 +525,6 @@ private fun ChooseServerPreview(
|
||||||
dialogState = dialogState
|
dialogState = dialogState
|
||||||
),
|
),
|
||||||
onBack = {},
|
onBack = {},
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,6 @@ import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.di.koinActivityViewModel
|
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
|
||||||
import co.electriccoin.zcash.ui.screen.contact.view.ContactView
|
import co.electriccoin.zcash.ui.screen.contact.view.ContactView
|
||||||
import co.electriccoin.zcash.ui.screen.contact.viewmodel.AddContactViewModel
|
import co.electriccoin.zcash.ui.screen.contact.viewmodel.AddContactViewModel
|
||||||
import org.koin.androidx.compose.koinViewModel
|
import org.koin.androidx.compose.koinViewModel
|
||||||
|
@ -15,9 +13,7 @@ import org.koin.core.parameter.parametersOf
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapAddContact(address: String?) {
|
internal fun WrapAddContact(address: String?) {
|
||||||
val walletViewModel = koinActivityViewModel<WalletViewModel>()
|
|
||||||
val viewModel = koinViewModel<AddContactViewModel> { parametersOf(address) }
|
val viewModel = koinViewModel<AddContactViewModel> { parametersOf(address) }
|
||||||
val walletState by walletViewModel.walletStateInformation.collectAsStateWithLifecycle()
|
|
||||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
BackHandler {
|
BackHandler {
|
||||||
|
@ -27,7 +23,6 @@ internal fun WrapAddContact(address: String?) {
|
||||||
state?.let {
|
state?.let {
|
||||||
ContactView(
|
ContactView(
|
||||||
state = it,
|
state = it,
|
||||||
topAppBarSubTitleState = walletState,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,6 @@ import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.di.koinActivityViewModel
|
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
|
||||||
import co.electriccoin.zcash.ui.screen.contact.view.ContactView
|
import co.electriccoin.zcash.ui.screen.contact.view.ContactView
|
||||||
import co.electriccoin.zcash.ui.screen.contact.viewmodel.UpdateContactViewModel
|
import co.electriccoin.zcash.ui.screen.contact.viewmodel.UpdateContactViewModel
|
||||||
import org.koin.androidx.compose.koinViewModel
|
import org.koin.androidx.compose.koinViewModel
|
||||||
|
@ -15,9 +13,7 @@ import org.koin.core.parameter.parametersOf
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapUpdateContact(contactAddress: String) {
|
internal fun WrapUpdateContact(contactAddress: String) {
|
||||||
val walletViewModel = koinActivityViewModel<WalletViewModel>()
|
|
||||||
val viewModel = koinViewModel<UpdateContactViewModel> { parametersOf(contactAddress) }
|
val viewModel = koinViewModel<UpdateContactViewModel> { parametersOf(contactAddress) }
|
||||||
val walletState by walletViewModel.walletStateInformation.collectAsStateWithLifecycle()
|
|
||||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
BackHandler {
|
BackHandler {
|
||||||
|
@ -27,7 +23,6 @@ internal fun WrapUpdateContact(contactAddress: String) {
|
||||||
state?.let {
|
state?.let {
|
||||||
ContactView(
|
ContactView(
|
||||||
state = it,
|
state = it,
|
||||||
topAppBarSubTitleState = walletState,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.input.KeyboardCapitalization
|
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
|
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
|
||||||
import co.electriccoin.zcash.ui.design.component.ButtonState
|
import co.electriccoin.zcash.ui.design.component.ButtonState
|
||||||
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
|
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
|
||||||
|
@ -37,12 +36,11 @@ import co.electriccoin.zcash.ui.screen.contact.model.ContactState
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ContactView(
|
fun ContactView(
|
||||||
state: ContactState,
|
state: ContactState
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState
|
|
||||||
) {
|
) {
|
||||||
BlankBgScaffold(
|
BlankBgScaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
ContactTopAppBar(onBack = state.onBack, subTitleState = topAppBarSubTitleState, state = state)
|
ContactTopAppBar(onBack = state.onBack, state = state)
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
if (state.isLoading) {
|
if (state.isLoading) {
|
||||||
|
@ -129,17 +127,10 @@ private fun ContactViewInternal(
|
||||||
@Composable
|
@Composable
|
||||||
private fun ContactTopAppBar(
|
private fun ContactTopAppBar(
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
subTitleState: TopAppBarSubTitleState,
|
|
||||||
state: ContactState
|
state: ContactState
|
||||||
) {
|
) {
|
||||||
ZashiSmallTopAppBar(
|
ZashiSmallTopAppBar(
|
||||||
title = state.title.getValue(),
|
title = state.title.getValue(),
|
||||||
subtitle =
|
|
||||||
when (subTitleState) {
|
|
||||||
TopAppBarSubTitleState.Disconnected -> stringResource(id = R.string.disconnected_label)
|
|
||||||
TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label)
|
|
||||||
TopAppBarSubTitleState.None -> null
|
|
||||||
},
|
|
||||||
modifier = Modifier.testTag(ContactTag.TOP_APP_BAR),
|
modifier = Modifier.testTag(ContactTag.TOP_APP_BAR),
|
||||||
showTitleLogo = true,
|
showTitleLogo = true,
|
||||||
navigationAction = {
|
navigationAction = {
|
||||||
|
@ -169,7 +160,6 @@ private fun DataPreview() {
|
||||||
text = stringRes("Negative"),
|
text = stringRes("Negative"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +185,6 @@ private fun LoadingPreview() {
|
||||||
text = stringRes("Add New Contact"),
|
text = stringRes("Add New Contact"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.di.koinActivityViewModel
|
import co.electriccoin.zcash.di.koinActivityViewModel
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
import co.electriccoin.zcash.ui.MainActivity
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.deletewallet.view.DeleteWallet
|
import co.electriccoin.zcash.ui.screen.deletewallet.view.DeleteWallet
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -22,15 +21,11 @@ internal fun MainActivity.WrapDeleteWallet(
|
||||||
onConfirm: () -> Unit,
|
onConfirm: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val walletViewModel = koinActivityViewModel<WalletViewModel>()
|
val walletViewModel = koinActivityViewModel<WalletViewModel>()
|
||||||
|
|
||||||
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
|
||||||
|
|
||||||
WrapDeleteWallet(
|
WrapDeleteWallet(
|
||||||
activity = this,
|
activity = this,
|
||||||
goBack = goBack,
|
goBack = goBack,
|
||||||
topAppBarSubTitleState = walletState,
|
onConfirm = onConfirm,
|
||||||
walletViewModel = walletViewModel,
|
walletViewModel = walletViewModel
|
||||||
onConfirm = onConfirm
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +34,6 @@ internal fun WrapDeleteWallet(
|
||||||
activity: Activity,
|
activity: Activity,
|
||||||
goBack: () -> Unit,
|
goBack: () -> Unit,
|
||||||
onConfirm: () -> Unit,
|
onConfirm: () -> Unit,
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState,
|
|
||||||
walletViewModel: WalletViewModel,
|
walletViewModel: WalletViewModel,
|
||||||
) {
|
) {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
@ -69,6 +63,5 @@ internal fun WrapDeleteWallet(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
topAppBarSubTitleState = topAppBarSubTitleState,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.design.MINIMAL_WEIGHT
|
import co.electriccoin.zcash.ui.design.MINIMAL_WEIGHT
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiButton
|
import co.electriccoin.zcash.ui.design.component.ZashiButton
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiButtonDefaults
|
import co.electriccoin.zcash.ui.design.component.ZashiButtonDefaults
|
||||||
|
@ -43,7 +42,6 @@ private fun ExportPrivateDataPreview() =
|
||||||
snackbarHostState = SnackbarHostState(),
|
snackbarHostState = SnackbarHostState(),
|
||||||
onBack = {},
|
onBack = {},
|
||||||
onConfirm = {},
|
onConfirm = {},
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,13 +50,11 @@ fun DeleteWallet(
|
||||||
snackbarHostState: SnackbarHostState,
|
snackbarHostState: SnackbarHostState,
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
onConfirm: () -> Unit,
|
onConfirm: () -> Unit,
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState,
|
|
||||||
) {
|
) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
DeleteWalletDataTopAppBar(
|
DeleteWalletDataTopAppBar(
|
||||||
onBack = onBack,
|
onBack = onBack,
|
||||||
subTitleState = topAppBarSubTitleState,
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
snackbarHost = { SnackbarHost(snackbarHostState) },
|
snackbarHost = { SnackbarHost(snackbarHostState) },
|
||||||
|
@ -76,17 +72,10 @@ fun DeleteWallet(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun DeleteWalletDataTopAppBar(
|
private fun DeleteWalletDataTopAppBar(
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit
|
||||||
subTitleState: TopAppBarSubTitleState
|
|
||||||
) {
|
) {
|
||||||
ZashiSmallTopAppBar(
|
ZashiSmallTopAppBar(
|
||||||
title = stringResource(R.string.delete_wallet_title),
|
title = stringResource(R.string.delete_wallet_title),
|
||||||
subtitle =
|
|
||||||
when (subTitleState) {
|
|
||||||
TopAppBarSubTitleState.Disconnected -> stringResource(id = R.string.disconnected_label)
|
|
||||||
TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label)
|
|
||||||
TopAppBarSubTitleState.None -> null
|
|
||||||
},
|
|
||||||
navigationAction = {
|
navigationAction = {
|
||||||
ZashiTopAppBarBackNavigation(
|
ZashiTopAppBarBackNavigation(
|
||||||
onBack = onBack
|
onBack = onBack
|
||||||
|
|
|
@ -1,26 +1,18 @@
|
||||||
package co.electriccoin.zcash.ui.screen.exchangerate.optin
|
package co.electriccoin.zcash.ui.screen.exchangerate.optin
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.activity.viewModels
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
import androidx.compose.runtime.getValue
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import org.koin.androidx.compose.koinViewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AndroidExchangeRateOptIn() {
|
fun AndroidExchangeRateOptIn() {
|
||||||
val activity = LocalActivity.current
|
val viewModel = koinViewModel<ExchangeRateOptInViewModel>()
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||||
|
BackHandler { state.onBack() }
|
||||||
BackHandler {
|
ExchangeRateOptInView(state = state)
|
||||||
walletViewModel.dismissOptInExchangeRateUsd()
|
|
||||||
}
|
|
||||||
|
|
||||||
ExchangeRateOptIn(
|
|
||||||
onEnableClick = { walletViewModel.optInExchangeRateUsd(true) },
|
|
||||||
onDismiss = { walletViewModel.dismissOptInExchangeRateUsd() },
|
|
||||||
onSkipClick = { walletViewModel.onSkipClick() }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package co.electriccoin.zcash.ui.screen.exchangerate.optin
|
||||||
|
|
||||||
|
data class ExchangeRateOptInState(
|
||||||
|
val onEnableClick: () -> Unit,
|
||||||
|
val onBack: () -> Unit,
|
||||||
|
val onSkipClick: () -> Unit,
|
||||||
|
)
|
|
@ -29,13 +29,9 @@ import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography
|
||||||
import co.electriccoin.zcash.ui.screen.exchangerate.BaseExchangeRateOptIn
|
import co.electriccoin.zcash.ui.screen.exchangerate.BaseExchangeRateOptIn
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ExchangeRateOptIn(
|
fun ExchangeRateOptInView(state: ExchangeRateOptInState) {
|
||||||
onEnableClick: () -> Unit,
|
|
||||||
onSkipClick: () -> Unit,
|
|
||||||
onDismiss: () -> Unit,
|
|
||||||
) {
|
|
||||||
BaseExchangeRateOptIn(
|
BaseExchangeRateOptIn(
|
||||||
onDismiss = onDismiss,
|
onDismiss = state.onBack,
|
||||||
content = {
|
content = {
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
Text(
|
Text(
|
||||||
|
@ -61,7 +57,7 @@ fun ExchangeRateOptIn(
|
||||||
footer = {
|
footer = {
|
||||||
ZashiTextButton(
|
ZashiTextButton(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
onClick = onSkipClick,
|
onClick = state.onSkipClick,
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.exchange_rate_opt_in_skip),
|
text = stringResource(R.string.exchange_rate_opt_in_skip),
|
||||||
|
@ -72,7 +68,7 @@ fun ExchangeRateOptIn(
|
||||||
ZashiButton(
|
ZashiButton(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
text = stringResource(R.string.exchange_rate_opt_in_enable),
|
text = stringResource(R.string.exchange_rate_opt_in_enable),
|
||||||
onClick = onEnableClick,
|
onClick = state.onEnableClick,
|
||||||
colors = ZashiButtonDefaults.primaryColors()
|
colors = ZashiButtonDefaults.primaryColors()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -118,6 +114,12 @@ private fun InfoItem(
|
||||||
private fun CurrencyConversionOptInPreview() =
|
private fun CurrencyConversionOptInPreview() =
|
||||||
ZcashTheme {
|
ZcashTheme {
|
||||||
BlankSurface {
|
BlankSurface {
|
||||||
ExchangeRateOptIn(onEnableClick = {}, onDismiss = {}, onSkipClick = {})
|
ExchangeRateOptInView(
|
||||||
|
state = ExchangeRateOptInState(
|
||||||
|
onEnableClick = {},
|
||||||
|
onBack = {},
|
||||||
|
onSkipClick = {},
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package co.electriccoin.zcash.ui.screen.exchangerate.optin
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import co.electriccoin.zcash.ui.NavigationRouter
|
||||||
|
import co.electriccoin.zcash.ui.common.repository.ExchangeRateRepository
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
|
||||||
|
class ExchangeRateOptInViewModel(
|
||||||
|
private val exchangeRateRepository: ExchangeRateRepository,
|
||||||
|
private val navigationRouter: NavigationRouter
|
||||||
|
): ViewModel() {
|
||||||
|
val state: StateFlow<ExchangeRateOptInState> = MutableStateFlow(
|
||||||
|
ExchangeRateOptInState(
|
||||||
|
onBack = ::dismissOptInExchangeRateUsd,
|
||||||
|
onEnableClick = ::optInExchangeRateUsd,
|
||||||
|
onSkipClick = ::onSkipClick
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun onSkipClick() {
|
||||||
|
exchangeRateRepository.optInExchangeRateUsd(false)
|
||||||
|
navigationRouter.back()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun optInExchangeRateUsd() {
|
||||||
|
exchangeRateRepository.optInExchangeRateUsd(true)
|
||||||
|
navigationRouter.back()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun dismissOptInExchangeRateUsd() {
|
||||||
|
navigationRouter.back()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,30 +1,18 @@
|
||||||
package co.electriccoin.zcash.ui.screen.exchangerate.settings
|
package co.electriccoin.zcash.ui.screen.exchangerate.settings
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.activity.viewModels
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
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
|
import kotlinx.serialization.Serializable
|
||||||
|
import org.koin.androidx.compose.koinViewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AndroidExchangeRateSettings() {
|
fun AndroidExchangeRateSettings() {
|
||||||
val activity = LocalActivity.current
|
val viewModel = koinViewModel<ExchangeRateSettingsViewModel>()
|
||||||
val navController = LocalNavController.current
|
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
BackHandler { state.onDismiss() }
|
||||||
val isOptedIn = walletViewModel.isExchangeRateUsdOptedIn.collectAsStateWithLifecycle().value ?: false
|
ExchangeRateSettingsView(state = state)
|
||||||
|
|
||||||
BackHandler {
|
|
||||||
navController.popBackStack()
|
|
||||||
}
|
|
||||||
|
|
||||||
ExchangeRateSettings(
|
|
||||||
isOptedIn = isOptedIn,
|
|
||||||
onSaveClick = { walletViewModel.optInExchangeRateUsd(it) },
|
|
||||||
onDismiss = { navController.popBackStack() }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package co.electriccoin.zcash.ui.screen.exchangerate.settings
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class ExchangeRateSettingsState(
|
||||||
|
val isOptedIn: Boolean,
|
||||||
|
val onSaveClick: (optIn: Boolean) -> Unit,
|
||||||
|
val onDismiss: () -> Unit,
|
||||||
|
)
|
|
@ -37,21 +37,17 @@ import co.electriccoin.zcash.ui.screen.exchangerate.BaseExchangeRateOptIn
|
||||||
import co.electriccoin.zcash.ui.screen.exchangerate.SecondaryCard
|
import co.electriccoin.zcash.ui.screen.exchangerate.SecondaryCard
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ExchangeRateSettings(
|
fun ExchangeRateSettingsView(state: ExchangeRateSettingsState) {
|
||||||
isOptedIn: Boolean,
|
var isOptInSelected by remember(state.isOptedIn) { mutableStateOf(state.isOptedIn) }
|
||||||
onDismiss: () -> Unit,
|
|
||||||
onSaveClick: (Boolean) -> Unit
|
|
||||||
) {
|
|
||||||
var isOptInSelected by remember(isOptedIn) { mutableStateOf(isOptedIn) }
|
|
||||||
|
|
||||||
val isButtonDisabled by remember {
|
val isButtonDisabled by remember {
|
||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
(isOptedIn && isOptInSelected) || (!isOptedIn && !isOptInSelected)
|
(state.isOptedIn && isOptInSelected) || (!state.isOptedIn && !isOptInSelected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseExchangeRateOptIn(
|
BaseExchangeRateOptIn(
|
||||||
onDismiss = onDismiss,
|
onDismiss = state.onDismiss,
|
||||||
content = {
|
content = {
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
Text(
|
Text(
|
||||||
|
@ -82,7 +78,7 @@ fun ExchangeRateSettings(
|
||||||
ZashiButton(
|
ZashiButton(
|
||||||
text = stringResource(R.string.exchange_rate_opt_in_save),
|
text = stringResource(R.string.exchange_rate_opt_in_save),
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
onClick = { onSaveClick(isOptInSelected) },
|
onClick = { state.onSaveClick(isOptInSelected) },
|
||||||
enabled = !isButtonDisabled,
|
enabled = !isButtonDisabled,
|
||||||
colors = ZashiButtonDefaults.primaryColors()
|
colors = ZashiButtonDefaults.primaryColors()
|
||||||
)
|
)
|
||||||
|
@ -187,6 +183,12 @@ private val Unchecked: Int
|
||||||
private fun SettingsExchangeRateOptInPreview() =
|
private fun SettingsExchangeRateOptInPreview() =
|
||||||
ZcashTheme {
|
ZcashTheme {
|
||||||
BlankSurface {
|
BlankSurface {
|
||||||
ExchangeRateSettings(isOptedIn = true, onDismiss = {}, onSaveClick = {})
|
ExchangeRateSettingsView(
|
||||||
|
state = ExchangeRateSettingsState(
|
||||||
|
isOptedIn = true,
|
||||||
|
onSaveClick = {},
|
||||||
|
onDismiss = {}
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package co.electriccoin.zcash.ui.screen.exchangerate.settings
|
||||||
|
|
||||||
|
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.common.repository.ExchangeRateRepository
|
||||||
|
import co.electriccoin.zcash.ui.common.wallet.ExchangeRateState
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.WhileSubscribed
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
|
||||||
|
class ExchangeRateSettingsViewModel(
|
||||||
|
private val exchangeRateRepository: ExchangeRateRepository,
|
||||||
|
private val navigationRouter: NavigationRouter,
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
val state = exchangeRateRepository.state
|
||||||
|
.map {
|
||||||
|
createState(it)
|
||||||
|
}
|
||||||
|
.stateIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT),
|
||||||
|
initialValue = createState(exchangeRateRepository.state.value)
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun createState(it: ExchangeRateState) =
|
||||||
|
ExchangeRateSettingsState(
|
||||||
|
isOptedIn = it is ExchangeRateState.OptIn,
|
||||||
|
onSaveClick = ::onOptInExchangeRateUsdClick,
|
||||||
|
onDismiss = ::onBack
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun onBack() {
|
||||||
|
navigationRouter.back()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onOptInExchangeRateUsdClick(optInt: Boolean) {
|
||||||
|
exchangeRateRepository.optInExchangeRateUsd(optIn = optInt)
|
||||||
|
navigationRouter.back()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,126 +0,0 @@
|
||||||
package co.electriccoin.zcash.ui.screen.exchangerate.widget
|
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
|
||||||
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.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
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 androidx.compose.ui.unit.sp
|
|
||||||
import co.electriccoin.zcash.ui.R
|
|
||||||
import co.electriccoin.zcash.ui.common.wallet.ExchangeRateState
|
|
||||||
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiButton
|
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiButtonDefaults
|
|
||||||
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.screen.exchangerate.SecondaryCard
|
|
||||||
|
|
||||||
@Suppress("LongMethod")
|
|
||||||
@Composable
|
|
||||||
fun StyledExchangeOptIn(
|
|
||||||
state: ExchangeRateState.OptIn,
|
|
||||||
modifier: Modifier = Modifier
|
|
||||||
) {
|
|
||||||
SecondaryCard(
|
|
||||||
modifier = modifier,
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.padding(start = 20.dp, bottom = 20.dp)
|
|
||||||
) {
|
|
||||||
Row {
|
|
||||||
Image(
|
|
||||||
modifier = Modifier.padding(top = 20.dp),
|
|
||||||
painter = painterResource(Icon),
|
|
||||||
contentDescription = null
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.width(12.dp))
|
|
||||||
Column(
|
|
||||||
verticalArrangement = Arrangement.Center
|
|
||||||
) {
|
|
||||||
Spacer(modifier = Modifier.height(22.dp))
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.exchange_rate_opt_in_title),
|
|
||||||
color = ZashiColors.Text.textTertiary,
|
|
||||||
fontSize = 14.sp,
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.height(2.dp))
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.exchange_rate_opt_in_subtitle),
|
|
||||||
color = ZashiColors.Text.textPrimary,
|
|
||||||
fontSize = 16.sp,
|
|
||||||
style = ZcashTheme.extendedTypography.restoringTopAppBarStyle,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
|
||||||
IconButton(
|
|
||||||
modifier = Modifier.padding(top = 4.dp, end = 8.dp),
|
|
||||||
onClick = state.onDismissClick,
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(R.drawable.ic_exchange_rate_unavailable_dialog_close),
|
|
||||||
contentDescription = null,
|
|
||||||
tint = ZashiColors.HintTooltips.defaultFg
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
|
||||||
ZashiButton(
|
|
||||||
modifier =
|
|
||||||
Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(end = 20.dp),
|
|
||||||
onClick = state.onPrimaryClick,
|
|
||||||
colors = ZashiButtonDefaults.tertiaryColors(),
|
|
||||||
text = stringResource(R.string.exchange_rate_opt_in_primary_btn),
|
|
||||||
) { scope ->
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.exchange_rate_opt_in_primary_btn),
|
|
||||||
style =
|
|
||||||
ZcashTheme.typography.primary.titleSmall
|
|
||||||
.copy(fontWeight = FontWeight.SemiBold),
|
|
||||||
fontSize = 14.sp
|
|
||||||
)
|
|
||||||
scope.Loading()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val Icon: Int
|
|
||||||
@DrawableRes
|
|
||||||
@Composable
|
|
||||||
get() =
|
|
||||||
if (isSystemInDarkTheme()) {
|
|
||||||
R.drawable.ic_exchange_rate_opt_in
|
|
||||||
} else {
|
|
||||||
R.drawable.ic_exchange_rate_opt_in_light
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UnusedPrivateMember")
|
|
||||||
@Composable
|
|
||||||
@PreviewScreens
|
|
||||||
private fun ExchangeRateOptInPreview() =
|
|
||||||
ZcashTheme {
|
|
||||||
BlankSurface {
|
|
||||||
StyledExchangeOptIn(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
state = ExchangeRateState.OptIn(onDismissClick = {})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,7 +14,6 @@ import cash.z.ecc.sdk.type.fromResources
|
||||||
import co.electriccoin.zcash.di.koinActivityViewModel
|
import co.electriccoin.zcash.di.koinActivityViewModel
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
||||||
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
|
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
|
||||||
|
@ -34,13 +33,10 @@ internal fun WrapExportPrivateData(
|
||||||
|
|
||||||
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
|
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
|
||||||
|
|
||||||
WrapExportPrivateData(
|
WrapExportPrivateData(
|
||||||
goBack = goBack,
|
goBack = goBack,
|
||||||
onShare = onConfirm,
|
onShare = onConfirm,
|
||||||
synchronizer = synchronizer,
|
synchronizer = synchronizer,
|
||||||
topAppBarSubTitleState = walletState,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +45,6 @@ internal fun WrapExportPrivateData(
|
||||||
goBack: () -> Unit,
|
goBack: () -> Unit,
|
||||||
onShare: () -> Unit,
|
onShare: () -> Unit,
|
||||||
synchronizer: Synchronizer?,
|
synchronizer: Synchronizer?,
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState,
|
|
||||||
) {
|
) {
|
||||||
val activity = LocalActivity.current
|
val activity = LocalActivity.current
|
||||||
|
|
||||||
|
@ -85,7 +80,6 @@ internal fun WrapExportPrivateData(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
topAppBarSubTitleState = topAppBarSubTitleState,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiButton
|
import co.electriccoin.zcash.ui.design.component.ZashiButton
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiCheckbox
|
import co.electriccoin.zcash.ui.design.component.ZashiCheckbox
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiSmallTopAppBar
|
import co.electriccoin.zcash.ui.design.component.ZashiSmallTopAppBar
|
||||||
|
@ -38,13 +37,11 @@ fun ExportPrivateData(
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
onAgree: (Boolean) -> Unit,
|
onAgree: (Boolean) -> Unit,
|
||||||
onConfirm: () -> Unit,
|
onConfirm: () -> Unit,
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState,
|
|
||||||
) {
|
) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
ExportPrivateDataTopAppBar(
|
ExportPrivateDataTopAppBar(
|
||||||
onBack = onBack,
|
onBack = onBack,
|
||||||
subTitleState = topAppBarSubTitleState,
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
snackbarHost = { SnackbarHost(snackbarHostState) },
|
snackbarHost = { SnackbarHost(snackbarHostState) },
|
||||||
|
@ -63,17 +60,10 @@ fun ExportPrivateData(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ExportPrivateDataTopAppBar(
|
private fun ExportPrivateDataTopAppBar(
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit
|
||||||
subTitleState: TopAppBarSubTitleState
|
|
||||||
) {
|
) {
|
||||||
ZashiSmallTopAppBar(
|
ZashiSmallTopAppBar(
|
||||||
title = stringResource(R.string.export_data_title),
|
title = stringResource(R.string.export_data_title),
|
||||||
subtitle =
|
|
||||||
when (subTitleState) {
|
|
||||||
TopAppBarSubTitleState.Disconnected -> stringResource(id = R.string.disconnected_label)
|
|
||||||
TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label)
|
|
||||||
TopAppBarSubTitleState.None -> null
|
|
||||||
},
|
|
||||||
navigationAction = {
|
navigationAction = {
|
||||||
ZashiTopAppBarBackNavigation(onBack = onBack)
|
ZashiTopAppBarBackNavigation(onBack = onBack)
|
||||||
},
|
},
|
||||||
|
@ -137,6 +127,5 @@ private fun ExportPrivateDataPreview() =
|
||||||
onBack = {},
|
onBack = {},
|
||||||
onAgree = {},
|
onAgree = {},
|
||||||
onConfirm = {},
|
onConfirm = {},
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.di.koinActivityViewModel
|
|
||||||
import co.electriccoin.zcash.ui.common.compose.LocalNavController
|
import co.electriccoin.zcash.ui.common.compose.LocalNavController
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
|
||||||
import co.electriccoin.zcash.ui.design.component.AppAlertDialog
|
import co.electriccoin.zcash.ui.design.component.AppAlertDialog
|
||||||
import co.electriccoin.zcash.ui.screen.feedback.view.FeedbackView
|
import co.electriccoin.zcash.ui.screen.feedback.view.FeedbackView
|
||||||
import co.electriccoin.zcash.ui.screen.feedback.viewmodel.FeedbackViewModel
|
import co.electriccoin.zcash.ui.screen.feedback.viewmodel.FeedbackViewModel
|
||||||
|
@ -18,33 +16,15 @@ import org.koin.androidx.compose.koinViewModel
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapFeedback() {
|
internal fun WrapFeedback() {
|
||||||
val navController = LocalNavController.current
|
val navController = LocalNavController.current
|
||||||
val walletViewModel = koinActivityViewModel<WalletViewModel>()
|
|
||||||
val viewModel = koinViewModel<FeedbackViewModel>()
|
val viewModel = koinViewModel<FeedbackViewModel>()
|
||||||
|
|
||||||
val walletState by walletViewModel.walletStateInformation.collectAsStateWithLifecycle()
|
|
||||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||||
val dialogState by viewModel.dialogState.collectAsStateWithLifecycle()
|
val dialogState by viewModel.dialogState.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
viewModel.onBackNavigationCommand.collect {
|
viewModel.onBackNavigationCommand.collect {
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BackHandler(enabled = state != null) { state?.onBack?.invoke() }
|
||||||
BackHandler {
|
state?.let { FeedbackView(state = it) }
|
||||||
state?.onBack?.invoke()
|
dialogState?.let { AppAlertDialog(state = it) }
|
||||||
}
|
|
||||||
|
|
||||||
state?.let {
|
|
||||||
FeedbackView(
|
|
||||||
state = it,
|
|
||||||
topAppBarSubTitleState = walletState
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
dialogState?.let {
|
|
||||||
AppAlertDialog(
|
|
||||||
state = it
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,6 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
||||||
import co.electriccoin.zcash.ui.design.component.ButtonState
|
import co.electriccoin.zcash.ui.design.component.ButtonState
|
||||||
import co.electriccoin.zcash.ui.design.component.TextFieldState
|
import co.electriccoin.zcash.ui.design.component.TextFieldState
|
||||||
|
@ -56,13 +55,11 @@ import co.electriccoin.zcash.ui.screen.feedback.model.FeedbackState
|
||||||
@Composable
|
@Composable
|
||||||
fun FeedbackView(
|
fun FeedbackView(
|
||||||
state: FeedbackState,
|
state: FeedbackState,
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState,
|
|
||||||
) {
|
) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
SupportTopAppBar(
|
SupportTopAppBar(
|
||||||
state = state,
|
state = state,
|
||||||
subTitleState = topAppBarSubTitleState,
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
|
@ -75,16 +72,9 @@ fun FeedbackView(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun SupportTopAppBar(
|
private fun SupportTopAppBar(
|
||||||
state: FeedbackState,
|
state: FeedbackState
|
||||||
subTitleState: TopAppBarSubTitleState
|
|
||||||
) {
|
) {
|
||||||
ZashiSmallTopAppBar(
|
ZashiSmallTopAppBar(
|
||||||
subtitle =
|
|
||||||
when (subTitleState) {
|
|
||||||
TopAppBarSubTitleState.Disconnected -> stringResource(id = R.string.disconnected_label)
|
|
||||||
TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label)
|
|
||||||
TopAppBarSubTitleState.None -> null
|
|
||||||
},
|
|
||||||
title = stringResource(id = R.string.support_header),
|
title = stringResource(id = R.string.support_header),
|
||||||
navigationAction = {
|
navigationAction = {
|
||||||
ZashiTopAppBarBackNavigation(onBack = state.onBack)
|
ZashiTopAppBarBackNavigation(onBack = state.onBack)
|
||||||
|
@ -258,7 +248,6 @@ private fun Preview() =
|
||||||
onSelected = {}
|
onSelected = {}
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,14 @@ import co.electriccoin.zcash.ui.screen.balances.BalanceViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.restoresuccess.WrapRestoreSuccess
|
import co.electriccoin.zcash.ui.screen.restoresuccess.WrapRestoreSuccess
|
||||||
import co.electriccoin.zcash.ui.screen.transactionhistory.widget.TransactionHistoryWidgetViewModel
|
import co.electriccoin.zcash.ui.screen.transactionhistory.widget.TransactionHistoryWidgetViewModel
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import org.koin.androidx.compose.koinViewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun AndroidHome() {
|
internal fun AndroidHome() {
|
||||||
val topAppBarViewModel = koinActivityViewModel<ZashiTopAppBarViewModel>()
|
val topAppBarViewModel = koinActivityViewModel<ZashiTopAppBarViewModel>()
|
||||||
val balanceViewModel = koinActivityViewModel<BalanceViewModel>()
|
val balanceViewModel = koinViewModel<BalanceViewModel>()
|
||||||
val homeViewModel = koinActivityViewModel<HomeViewModel>()
|
val homeViewModel = koinViewModel<HomeViewModel>()
|
||||||
val transactionHistoryWidgetViewModel = koinActivityViewModel<TransactionHistoryWidgetViewModel>()
|
val transactionHistoryWidgetViewModel = koinViewModel<TransactionHistoryWidgetViewModel>()
|
||||||
val restoreDialogState by homeViewModel.restoreDialogState.collectAsStateWithLifecycle()
|
val restoreDialogState by homeViewModel.restoreDialogState.collectAsStateWithLifecycle()
|
||||||
val appBarState by topAppBarViewModel.state.collectAsStateWithLifecycle()
|
val appBarState by topAppBarViewModel.state.collectAsStateWithLifecycle()
|
||||||
val balanceState by balanceViewModel.state.collectAsStateWithLifecycle()
|
val balanceState by balanceViewModel.state.collectAsStateWithLifecycle()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home.messages
|
package co.electriccoin.zcash.ui.screen.home
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.core.CubicBezierEasing
|
import androidx.compose.animation.core.CubicBezierEasing
|
||||||
|
@ -35,6 +35,22 @@ import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.zIndex
|
import androidx.compose.ui.zIndex
|
||||||
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
|
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.backup.WalletBackupMessage
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.backup.WalletBackupMessageState
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.currency.EnableCurrencyConversionMessage
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.currency.EnableCurrencyConversionMessageState
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.disconnected.WalletDisconnectedMessage
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.disconnected.WalletDisconnectedMessageState
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.error.WalletErrorMessage
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.error.WalletErrorMessageState
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.restoring.WalletRestoringMessage
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.restoring.WalletRestoringMessageState
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.syncing.WalletSyncingMessage
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.syncing.WalletSyncingMessageState
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.transparentbalance.TransparentBalanceMessage
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.transparentbalance.TransparentBalanceMessageState
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.updating.WalletUpdatingMessage
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.updating.WalletUpdatingMessageState
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
import kotlin.time.Duration.Companion.milliseconds
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
@ -112,10 +128,10 @@ fun HomeMessage(
|
||||||
contentPadding = contentPadding
|
contentPadding = contentPadding
|
||||||
)
|
)
|
||||||
|
|
||||||
is TransparentBalanceDetectedMessageState ->
|
is TransparentBalanceMessageState ->
|
||||||
TransparentBalanceDetectedMessage(
|
TransparentBalanceMessage(
|
||||||
innerModifier = innerModifier,
|
innerModifier = innerModifier,
|
||||||
state = normalizedState as TransparentBalanceDetectedMessageState,
|
state = normalizedState as TransparentBalanceMessageState,
|
||||||
contentPadding = contentPadding
|
contentPadding = contentPadding
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -203,7 +219,7 @@ fun HomeMessage(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed interface HomeMessageState
|
interface HomeMessageState
|
||||||
|
|
||||||
@Suppress("MagicNumber")
|
@Suppress("MagicNumber")
|
||||||
@Composable
|
@Composable
|
|
@ -1,4 +1,4 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home.messages
|
package co.electriccoin.zcash.ui.screen.home
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
|
@ -24,8 +24,6 @@ import co.electriccoin.zcash.ui.design.component.LocalZashiCircularProgressIndic
|
||||||
import co.electriccoin.zcash.ui.design.component.VerticalSpacer
|
import co.electriccoin.zcash.ui.design.component.VerticalSpacer
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiButtonDefaults
|
import co.electriccoin.zcash.ui.design.component.ZashiButtonDefaults
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiCircularProgressIndicatorDefaults
|
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.ZashiDarkColors
|
||||||
import co.electriccoin.zcash.ui.design.theme.colors.ZashiLightColors
|
import co.electriccoin.zcash.ui.design.theme.colors.ZashiLightColors
|
||||||
import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography
|
import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography
|
||||||
|
@ -47,11 +45,11 @@ fun HomeMessageWrapper(
|
||||||
innerModifier = innerModifier,
|
innerModifier = innerModifier,
|
||||||
) {
|
) {
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalContentColor provides ZashiColors.Text.textOpposite,
|
LocalContentColor provides ZashiLightColors.Utility.Purple.utilityPurple50,
|
||||||
LocalZashiCircularProgressIndicatorColors provides
|
LocalZashiCircularProgressIndicatorColors provides
|
||||||
ZashiCircularProgressIndicatorDefaults.colors(
|
ZashiCircularProgressIndicatorDefaults.colors(
|
||||||
progressColor = ZashiColors.Text.textOpposite,
|
progressColor = ZashiLightColors.Utility.Purple.utilityPurple50,
|
||||||
trackColor = Purple.`400`
|
trackColor = ZashiLightColors.Utility.Purple.utilityPurple400
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
start()
|
start()
|
||||||
|
@ -63,7 +61,7 @@ fun HomeMessageWrapper(
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalTextStyle provides
|
LocalTextStyle provides
|
||||||
ZashiTypography.textSm.copy(
|
ZashiTypography.textSm.copy(
|
||||||
color = ZashiColors.Text.textOpposite,
|
color = ZashiLightColors.Utility.Purple.utilityPurple50,
|
||||||
fontWeight = FontWeight.Medium
|
fontWeight = FontWeight.Medium
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
|
@ -73,7 +71,7 @@ fun HomeMessageWrapper(
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalTextStyle provides
|
LocalTextStyle provides
|
||||||
ZashiTypography.textXs.copy(
|
ZashiTypography.textXs.copy(
|
||||||
color = Purple.`200`,
|
color = ZashiLightColors.Utility.Purple.utilityPurple200,
|
||||||
fontWeight = FontWeight.Medium
|
fontWeight = FontWeight.Medium
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
|
@ -106,10 +104,11 @@ private fun Container(
|
||||||
Modifier
|
Modifier
|
||||||
.background(
|
.background(
|
||||||
Brush.verticalGradient(
|
Brush.verticalGradient(
|
||||||
0f to Purple.`500`,
|
0f to ZashiLightColors.Utility.Purple.utilityPurple500,
|
||||||
1f to Purple.`900`,
|
1f to ZashiLightColors.Utility.Purple.utilityPurple900,
|
||||||
)
|
)
|
||||||
).clickable(onClick = onClick)
|
)
|
||||||
|
.clickable(onClick = onClick)
|
||||||
.padding(contentPadding),
|
.padding(contentPadding),
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
|
@ -1,7 +1,6 @@
|
||||||
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,
|
||||||
|
@ -11,6 +10,6 @@ data class HomeState(
|
||||||
val message: HomeMessageState?
|
val message: HomeMessageState?
|
||||||
)
|
)
|
||||||
|
|
||||||
data class HomeRestoreDialogState(
|
data class HomeRestoreSuccessDialogState(
|
||||||
val onClick: () -> Unit
|
val onClick: () -> Unit
|
||||||
)
|
)
|
||||||
|
|
|
@ -32,8 +32,7 @@ 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.error.WalletErrorMessageState
|
||||||
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.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
|
||||||
|
|
|
@ -2,7 +2,6 @@ package co.electriccoin.zcash.ui.screen.home
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
|
||||||
import cash.z.ecc.sdk.ANDROID_STATE_FLOW_TIMEOUT
|
import cash.z.ecc.sdk.ANDROID_STATE_FLOW_TIMEOUT
|
||||||
import co.electriccoin.zcash.ui.NavigationRouter
|
import co.electriccoin.zcash.ui.NavigationRouter
|
||||||
import co.electriccoin.zcash.ui.NavigationTargets
|
import co.electriccoin.zcash.ui.NavigationTargets
|
||||||
|
@ -11,115 +10,61 @@ 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.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.GetHomeMessageUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetSelectedWalletAccountUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetSelectedWalletAccountUseCase
|
||||||
|
import co.electriccoin.zcash.ui.common.usecase.HomeMessageData
|
||||||
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.exchangerate.optin.ExchangeRateOptIn
|
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.backup.SeedBackupInfo
|
||||||
import co.electriccoin.zcash.ui.screen.home.messages.EnableCurrencyConversionMessageState
|
import co.electriccoin.zcash.ui.screen.home.currency.EnableCurrencyConversionMessageState
|
||||||
import co.electriccoin.zcash.ui.screen.home.messages.HomeMessageState
|
import co.electriccoin.zcash.ui.screen.home.transparentbalance.TransparentBalanceMessageState
|
||||||
import co.electriccoin.zcash.ui.screen.home.messages.TransparentBalanceDetectedMessageState
|
import co.electriccoin.zcash.ui.screen.home.backup.WalletBackupMessageState
|
||||||
import co.electriccoin.zcash.ui.screen.home.messages.WalletBackupMessageState
|
import co.electriccoin.zcash.ui.screen.home.disconnected.WalletDisconnectedInfo
|
||||||
import co.electriccoin.zcash.ui.screen.home.messages.WalletDisconnectedMessageState
|
import co.electriccoin.zcash.ui.screen.home.disconnected.WalletDisconnectedMessageState
|
||||||
import co.electriccoin.zcash.ui.screen.home.messages.WalletErrorMessageState
|
import co.electriccoin.zcash.ui.screen.home.error.WalletErrorMessageState
|
||||||
import co.electriccoin.zcash.ui.screen.home.messages.WalletRestoringMessageState
|
import co.electriccoin.zcash.ui.screen.home.restoring.WalletRestoringMessageState
|
||||||
import co.electriccoin.zcash.ui.screen.home.messages.WalletSyncingMessageState
|
import co.electriccoin.zcash.ui.screen.home.syncing.WalletSyncingMessageState
|
||||||
import co.electriccoin.zcash.ui.screen.home.messages.WalletUpdatingMessageState
|
import co.electriccoin.zcash.ui.screen.home.updating.WalletUpdatingMessageState
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.restoring.WalletRestoringInfo
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.syncing.WalletSyncingInfo
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.transparentbalance.TransparentBalanceInfo
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.updating.WalletUpdatingInfo
|
||||||
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.home.backup.WalletBackupDetail
|
||||||
import co.electriccoin.zcash.ui.screen.send.Send
|
import co.electriccoin.zcash.ui.screen.send.Send
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.WhileSubscribed
|
import kotlinx.coroutines.flow.WhileSubscribed
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.flow
|
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.time.Duration.Companion.seconds
|
|
||||||
|
|
||||||
class HomeViewModel(
|
class HomeViewModel(
|
||||||
|
getHomeMessage: GetHomeMessageUseCase,
|
||||||
getVersionInfoProvider: GetVersionInfoProvider,
|
getVersionInfoProvider: GetVersionInfoProvider,
|
||||||
getSelectedWalletAccountUseCase: GetSelectedWalletAccountUseCase,
|
getSelectedWalletAccountUseCase: GetSelectedWalletAccountUseCase,
|
||||||
private val navigationRouter: NavigationRouter,
|
private val navigationRouter: NavigationRouter,
|
||||||
private val isRestoreSuccessDialogVisible: IsRestoreSuccessDialogVisibleUseCase,
|
private val isRestoreSuccessDialogVisible: IsRestoreSuccessDialogVisibleUseCase,
|
||||||
private val navigateToCoinbase: NavigateToCoinbaseUseCase
|
private val navigateToCoinbase: NavigateToCoinbaseUseCase,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
@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
|
private val messageState = getHomeMessage
|
||||||
|
.observe()
|
||||||
while (true) {
|
.map { createMessageState(it) }
|
||||||
emit(states[index])
|
.stateIn(
|
||||||
delay(3.seconds)
|
scope = viewModelScope,
|
||||||
if (index == states.lastIndex) {
|
started = SharingStarted.WhileSubscribed(),
|
||||||
emit(null)
|
initialValue = null
|
||||||
delay(10.seconds)
|
)
|
||||||
index = 0
|
|
||||||
} else {
|
|
||||||
index += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val isRestoreDialogVisible: Flow<Boolean?> =
|
private val isRestoreDialogVisible: Flow<Boolean?> =
|
||||||
isRestoreSuccessDialogVisible
|
isRestoreSuccessDialogVisible
|
||||||
|
@ -130,10 +75,10 @@ class HomeViewModel(
|
||||||
initialValue = null
|
initialValue = null
|
||||||
)
|
)
|
||||||
|
|
||||||
val restoreDialogState: StateFlow<HomeRestoreDialogState?> =
|
val restoreDialogState: StateFlow<HomeRestoreSuccessDialogState?> =
|
||||||
isRestoreDialogVisible
|
isRestoreDialogVisible
|
||||||
.map { isVisible ->
|
.map { isVisible ->
|
||||||
HomeRestoreDialogState(
|
HomeRestoreSuccessDialogState(
|
||||||
onClick = ::onRestoreDialogSeenClick
|
onClick = ::onRestoreDialogSeenClick
|
||||||
).takeIf { isVisible == true }
|
).takeIf { isVisible == true }
|
||||||
}.stateIn(
|
}.stateIn(
|
||||||
|
@ -203,6 +148,48 @@ class HomeViewModel(
|
||||||
message = messageState
|
message = messageState
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private fun createMessageState(it: HomeMessageData?) = when (it) {
|
||||||
|
is HomeMessageData.Backup -> WalletBackupMessageState(
|
||||||
|
onClick = ::onWalletBackupMessageClick,
|
||||||
|
onButtonClick = ::onWalletBackupMessageButtonClick,
|
||||||
|
)
|
||||||
|
|
||||||
|
HomeMessageData.Disconnected -> WalletDisconnectedMessageState(
|
||||||
|
onClick = ::onWalletDisconnectedMessageClick
|
||||||
|
)
|
||||||
|
|
||||||
|
HomeMessageData.EnableCurrencyConversion -> EnableCurrencyConversionMessageState(
|
||||||
|
onClick = ::onEnableCurrencyConversionClick,
|
||||||
|
onButtonClick = ::onEnableCurrencyConversionClick
|
||||||
|
)
|
||||||
|
|
||||||
|
is HomeMessageData.Error -> WalletErrorMessageState(
|
||||||
|
onClick = { onWalletErrorMessageClick(it) }
|
||||||
|
)
|
||||||
|
|
||||||
|
is HomeMessageData.Restoring -> WalletRestoringMessageState(
|
||||||
|
progress = it.progress,
|
||||||
|
onClick = ::onWalletRestoringMessageClick
|
||||||
|
)
|
||||||
|
|
||||||
|
is HomeMessageData.Syncing -> WalletSyncingMessageState(
|
||||||
|
progress = it.progress,
|
||||||
|
onClick = ::onWalletSyncingMessageClick
|
||||||
|
)
|
||||||
|
|
||||||
|
is HomeMessageData.TransparentBalance -> TransparentBalanceMessageState(
|
||||||
|
subtitle = stringRes(zatoshi = it.zatoshi),
|
||||||
|
onClick = ::onTransparentBalanceMessageClick,
|
||||||
|
onButtonClick = ::onTransparentBalanceMessageButtonClick,
|
||||||
|
)
|
||||||
|
|
||||||
|
HomeMessageData.Updating -> WalletUpdatingMessageState(
|
||||||
|
onClick = ::onWalletUpdatingMessageClick
|
||||||
|
)
|
||||||
|
|
||||||
|
null -> null
|
||||||
|
}
|
||||||
|
|
||||||
private fun onRestoreDialogSeenClick() =
|
private fun onRestoreDialogSeenClick() =
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
isRestoreSuccessDialogVisible.setSeen()
|
isRestoreSuccessDialogVisible.setSeen()
|
||||||
|
@ -232,4 +219,61 @@ class HomeViewModel(
|
||||||
private fun onRequestClick() {
|
private fun onRequestClick() {
|
||||||
navigationRouter.forward("${NavigationTargets.REQUEST}/${ReceiveAddressType.Unified.ordinal}")
|
navigationRouter.forward("${NavigationTargets.REQUEST}/${ReceiveAddressType.Unified.ordinal}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onWalletUpdatingMessageClick() {
|
||||||
|
navigationRouter.forward(WalletUpdatingInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onWalletSyncingMessageClick() {
|
||||||
|
navigationRouter.forward(WalletSyncingInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onWalletRestoringMessageClick() {
|
||||||
|
navigationRouter.forward(WalletRestoringInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onEnableCurrencyConversionClick() {
|
||||||
|
navigationRouter.forward(ExchangeRateOptIn)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onWalletDisconnectedMessageClick() {
|
||||||
|
navigationRouter.forward(WalletDisconnectedInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onWalletBackupMessageClick() {
|
||||||
|
navigationRouter.forward(SeedBackupInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onWalletBackupMessageButtonClick() {
|
||||||
|
navigationRouter.forward(WalletBackupDetail(false))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onTransparentBalanceMessageClick() {
|
||||||
|
navigationRouter.forward(TransparentBalanceInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onTransparentBalanceMessageButtonClick(): Nothing {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onWalletErrorMessageClick(homeMessageData: HomeMessageData.Error): Nothing {
|
||||||
|
// statusText =
|
||||||
|
// context.getString(
|
||||||
|
// R.string.balances_status_error_simple,
|
||||||
|
// context.getString(R.string.app_name)
|
||||||
|
// )
|
||||||
|
// statusAction =
|
||||||
|
// StatusAction.Error(
|
||||||
|
// details =
|
||||||
|
// context.getString(
|
||||||
|
// R.string.balances_status_error_dialog_cause,
|
||||||
|
// walletSnapshot.synchronizerError.getCauseMessage()
|
||||||
|
// ?: context.getString(R.string.balances_status_error_dialog_cause_unknown),
|
||||||
|
// walletSnapshot.synchronizerError.getStackTrace(limit = STACKTRACE_LIMIT)
|
||||||
|
// ?: context.getString(R.string.balances_status_error_dialog_stacktrace_unknown)
|
||||||
|
// ),
|
||||||
|
// fullStackTrace = walletSnapshot.synchronizerError.getStackTrace(limit = null)
|
||||||
|
// )
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package co.electriccoin.zcash.ui.screen.home.backup
|
||||||
|
|
||||||
|
import androidx.activity.compose.BackHandler
|
||||||
|
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
|
||||||
|
import org.koin.core.parameter.parametersOf
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AndroidWalletBackupDetail(args: WalletBackupDetail) {
|
||||||
|
val viewModel = koinViewModel<WalletBackupDetailViewModel> { parametersOf(args) }
|
||||||
|
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||||
|
BackHandler { state.onBack() }
|
||||||
|
WalletBackupDetailView(state = state)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class WalletBackupDetail(
|
||||||
|
val isOpenedFromSeedBackupInfo: Boolean
|
||||||
|
)
|
|
@ -0,0 +1,19 @@
|
||||||
|
package co.electriccoin.zcash.ui.screen.home.backup
|
||||||
|
|
||||||
|
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 AndroidWalletBackupInfo() {
|
||||||
|
val viewModel = koinViewModel<WalletBackupInfoViewModel>()
|
||||||
|
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||||
|
WalletBackupInfoView(state = state)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
object SeedBackupInfo
|
|
@ -0,0 +1,10 @@
|
||||||
|
package co.electriccoin.zcash.ui.screen.home.backup
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class WalletBackupDetailState(
|
||||||
|
val onBack: () -> Unit,
|
||||||
|
val onNextClick: () -> Unit,
|
||||||
|
val onInfoClick: () -> Unit,
|
||||||
|
)
|
|
@ -1,4 +1,4 @@
|
||||||
package co.electriccoin.zcash.ui.screen.seed.backup
|
package co.electriccoin.zcash.ui.screen.home.backup
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
|
@ -20,7 +20,6 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.design.component.ButtonState
|
import co.electriccoin.zcash.ui.design.component.ButtonState
|
||||||
import co.electriccoin.zcash.ui.design.component.HorizontalSpacer
|
import co.electriccoin.zcash.ui.design.component.HorizontalSpacer
|
||||||
import co.electriccoin.zcash.ui.design.component.IconButtonState
|
import co.electriccoin.zcash.ui.design.component.IconButtonState
|
||||||
|
@ -38,12 +37,11 @@ import co.electriccoin.zcash.ui.design.util.scaffoldPadding
|
||||||
import co.electriccoin.zcash.ui.design.util.stringRes
|
import co.electriccoin.zcash.ui.design.util.stringRes
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SeedBackupView(
|
fun WalletBackupDetailView(
|
||||||
state: SeedBackupState,
|
state: WalletBackupDetailState,
|
||||||
appBarState: TopAppBarSubTitleState,
|
|
||||||
) {
|
) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = { AppBar(state = state, subTitleState = appBarState) }
|
topBar = { AppBar(state = state) }
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
Content(
|
Content(
|
||||||
modifier = Modifier.scaffoldPadding(paddingValues),
|
modifier = Modifier.scaffoldPadding(paddingValues),
|
||||||
|
@ -54,18 +52,11 @@ fun SeedBackupView(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun AppBar(
|
private fun AppBar(
|
||||||
state: SeedBackupState,
|
state: WalletBackupDetailState,
|
||||||
subTitleState: TopAppBarSubTitleState,
|
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
ZashiSmallTopAppBar(
|
ZashiSmallTopAppBar(
|
||||||
title = stringResource(R.string.wallet_backup_title),
|
title = stringResource(R.string.wallet_backup_title),
|
||||||
subtitle =
|
|
||||||
when (subTitleState) {
|
|
||||||
TopAppBarSubTitleState.Disconnected -> stringResource(id = R.string.disconnected_label)
|
|
||||||
TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label)
|
|
||||||
TopAppBarSubTitleState.None -> null
|
|
||||||
},
|
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
navigationAction = {
|
navigationAction = {
|
||||||
ZashiTopAppBarBackNavigation(onBack = state.onBack)
|
ZashiTopAppBarBackNavigation(onBack = state.onBack)
|
||||||
|
@ -85,7 +76,7 @@ private fun AppBar(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Content(
|
private fun Content(
|
||||||
state: SeedBackupState,
|
state: WalletBackupDetailState,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
|
@ -202,10 +193,9 @@ private fun Item(
|
||||||
@PreviewScreens
|
@PreviewScreens
|
||||||
private fun Preview() =
|
private fun Preview() =
|
||||||
ZcashTheme {
|
ZcashTheme {
|
||||||
SeedBackupView(
|
WalletBackupDetailView(
|
||||||
appBarState = TopAppBarSubTitleState.None,
|
|
||||||
state =
|
state =
|
||||||
SeedBackupState(
|
WalletBackupDetailState(
|
||||||
onBack = {},
|
onBack = {},
|
||||||
onNextClick = {},
|
onNextClick = {},
|
||||||
onInfoClick = {}
|
onInfoClick = {}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package co.electriccoin.zcash.ui.screen.home.backup
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import co.electriccoin.zcash.ui.NavigationRouter
|
||||||
|
import co.electriccoin.zcash.ui.common.usecase.NavigateToWalletBackupUseCase
|
||||||
|
import co.electriccoin.zcash.ui.screen.restore.info.SeedInfo
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class WalletBackupDetailViewModel(
|
||||||
|
private val args: WalletBackupDetail,
|
||||||
|
private val navigationRouter: NavigationRouter,
|
||||||
|
private val navigateToWalletBackup: NavigateToWalletBackupUseCase
|
||||||
|
) : ViewModel() {
|
||||||
|
val state = MutableStateFlow(
|
||||||
|
WalletBackupDetailState(
|
||||||
|
onBack = ::onBack,
|
||||||
|
onNextClick = ::onNextClick,
|
||||||
|
onInfoClick = ::onInfoClick
|
||||||
|
)
|
||||||
|
).asStateFlow()
|
||||||
|
|
||||||
|
private fun onNextClick() =
|
||||||
|
viewModelScope.launch {
|
||||||
|
navigateToWalletBackup(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onInfoClick() {
|
||||||
|
navigationRouter.forward(SeedInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onBack() {
|
||||||
|
if (args.isOpenedFromSeedBackupInfo) {
|
||||||
|
navigationRouter.replace(SeedBackupInfo)
|
||||||
|
} else {
|
||||||
|
navigationRouter.back()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package co.electriccoin.zcash.ui.screen.home.backup
|
||||||
|
|
||||||
|
import co.electriccoin.zcash.ui.design.component.ButtonState
|
||||||
|
import co.electriccoin.zcash.ui.design.component.ModalBottomSheetState
|
||||||
|
|
||||||
|
data class WalletBackupInfoState(
|
||||||
|
override val onBack: () -> Unit,
|
||||||
|
val primaryButton: ButtonState,
|
||||||
|
val secondaryButton: ButtonState
|
||||||
|
) : ModalBottomSheetState
|
|
@ -1,4 +1,4 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home
|
package co.electriccoin.zcash.ui.screen.home.backup
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
@ -13,7 +13,6 @@ import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import co.electriccoin.zcash.ui.NavigationRouter
|
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.design.component.ButtonState
|
import co.electriccoin.zcash.ui.design.component.ButtonState
|
||||||
import co.electriccoin.zcash.ui.design.component.Spacer
|
import co.electriccoin.zcash.ui.design.component.Spacer
|
||||||
|
@ -27,30 +26,16 @@ 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.ZashiColors
|
||||||
import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography
|
import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography
|
||||||
import co.electriccoin.zcash.ui.design.util.stringRes
|
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)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun AndroidSeedBackupInfo() {
|
fun WalletBackupInfoView(
|
||||||
val navigationRouter = koinInject<NavigationRouter>()
|
state: WalletBackupInfoState?,
|
||||||
Content(
|
|
||||||
onBack = { navigationRouter.back() },
|
|
||||||
onPositiveClick = { navigationRouter.replace(SeedBackup(true)) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
private fun Content(
|
|
||||||
onBack: () -> Unit,
|
|
||||||
onPositiveClick: () -> Unit,
|
|
||||||
sheetState: SheetState = rememberScreenModalBottomSheetState(),
|
sheetState: SheetState = rememberScreenModalBottomSheetState(),
|
||||||
) {
|
) {
|
||||||
ZashiScreenModalBottomSheet(
|
ZashiScreenModalBottomSheet(
|
||||||
sheetState = sheetState,
|
sheetState = sheetState,
|
||||||
onDismissRequest = onBack
|
state = state
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier =
|
modifier =
|
||||||
|
@ -101,21 +86,13 @@ private fun Content(
|
||||||
Spacer(32.dp)
|
Spacer(32.dp)
|
||||||
ZashiButton(
|
ZashiButton(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
state =
|
state = it.secondaryButton,
|
||||||
ButtonState(
|
|
||||||
text = stringRes(R.string.general_remind_me_later),
|
|
||||||
onClick = onBack
|
|
||||||
),
|
|
||||||
colors = ZashiButtonDefaults.secondaryColors()
|
colors = ZashiButtonDefaults.secondaryColors()
|
||||||
)
|
)
|
||||||
Spacer(4.dp)
|
Spacer(4.dp)
|
||||||
ZashiButton(
|
ZashiButton(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
state =
|
state = it.primaryButton
|
||||||
ButtonState(
|
|
||||||
text = stringRes(R.string.general_ok),
|
|
||||||
onClick = onPositiveClick
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,11 +103,17 @@ private fun Content(
|
||||||
@Composable
|
@Composable
|
||||||
private fun Preview() =
|
private fun Preview() =
|
||||||
ZcashTheme {
|
ZcashTheme {
|
||||||
Content(
|
WalletBackupInfoView(
|
||||||
onBack = {},
|
WalletBackupInfoState(
|
||||||
onPositiveClick = {}
|
onBack = {},
|
||||||
|
secondaryButton = ButtonState(
|
||||||
|
text = stringRes(R.string.general_remind_me_later),
|
||||||
|
onClick = {}
|
||||||
|
),
|
||||||
|
primaryButton = ButtonState(
|
||||||
|
text = stringRes(R.string.general_ok),
|
||||||
|
onClick = {}
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
|
||||||
object SeedBackupInfo
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package co.electriccoin.zcash.ui.screen.home.backup
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import co.electriccoin.zcash.ui.NavigationRouter
|
||||||
|
import co.electriccoin.zcash.ui.R
|
||||||
|
import co.electriccoin.zcash.ui.common.usecase.RemindWalletBackupLaterUseCase
|
||||||
|
import co.electriccoin.zcash.ui.design.component.ButtonState
|
||||||
|
import co.electriccoin.zcash.ui.design.util.stringRes
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class WalletBackupInfoViewModel(
|
||||||
|
private val navigationRouter: NavigationRouter,
|
||||||
|
private val remindWalletBackupLater: RemindWalletBackupLaterUseCase
|
||||||
|
) : ViewModel() {
|
||||||
|
val state: StateFlow<WalletBackupInfoState?> = MutableStateFlow(
|
||||||
|
WalletBackupInfoState(
|
||||||
|
onBack = ::onBack,
|
||||||
|
secondaryButton = ButtonState(
|
||||||
|
text = stringRes(R.string.general_remind_me_later),
|
||||||
|
onClick = ::onRemindMeLaterClick
|
||||||
|
),
|
||||||
|
primaryButton = ButtonState(
|
||||||
|
text = stringRes(R.string.general_ok),
|
||||||
|
onClick = ::onPrimaryClick
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun onPrimaryClick() {
|
||||||
|
navigationRouter.replace(WalletBackupDetail(true))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onRemindMeLaterClick() = viewModelScope.launch { remindWalletBackupLater() }
|
||||||
|
|
||||||
|
private fun onBack() = navigationRouter.back()
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home.messages
|
package co.electriccoin.zcash.ui.screen.home.backup
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
@ -7,7 +7,6 @@ import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
@ -20,6 +19,8 @@ import co.electriccoin.zcash.ui.design.component.ZashiButton
|
||||||
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.util.stringRes
|
import co.electriccoin.zcash.ui.design.util.stringRes
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.HomeMessageState
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.HomeMessageWrapper
|
||||||
|
|
||||||
@Suppress("ModifierNaming")
|
@Suppress("ModifierNaming")
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -34,7 +35,6 @@ fun WalletBackupMessage(
|
||||||
onClick = state.onClick,
|
onClick = state.onClick,
|
||||||
start = {
|
start = {
|
||||||
Image(
|
Image(
|
||||||
modifier = Modifier.align(Alignment.Top),
|
|
||||||
painter = painterResource(R.drawable.ic_warning_triangle),
|
painter = painterResource(R.drawable.ic_warning_triangle),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
colorFilter = ColorFilter.tint(LocalContentColor.current)
|
colorFilter = ColorFilter.tint(LocalContentColor.current)
|
|
@ -1,4 +1,4 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home.messages
|
package co.electriccoin.zcash.ui.screen.home.currency
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.material3.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
@ -19,6 +18,8 @@ import co.electriccoin.zcash.ui.design.component.ZashiButton
|
||||||
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.util.stringRes
|
import co.electriccoin.zcash.ui.design.util.stringRes
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.HomeMessageState
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.HomeMessageWrapper
|
||||||
|
|
||||||
@Suppress("ModifierNaming")
|
@Suppress("ModifierNaming")
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -33,7 +34,6 @@ fun EnableCurrencyConversionMessage(
|
||||||
onClick = state.onClick,
|
onClick = state.onClick,
|
||||||
start = {
|
start = {
|
||||||
Image(
|
Image(
|
||||||
modifier = Modifier.align(Alignment.Top),
|
|
||||||
painter = painterResource(R.drawable.ic_message_currency_conversion),
|
painter = painterResource(R.drawable.ic_message_currency_conversion),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
colorFilter = ColorFilter.tint(LocalContentColor.current)
|
colorFilter = ColorFilter.tint(LocalContentColor.current)
|
|
@ -1,4 +1,4 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home
|
package co.electriccoin.zcash.ui.screen.home.disconnected
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
|
@ -1,11 +1,10 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home.messages
|
package co.electriccoin.zcash.ui.screen.home.disconnected
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.material3.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
@ -15,6 +14,8 @@ import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
||||||
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.screen.home.HomeMessageState
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.HomeMessageWrapper
|
||||||
|
|
||||||
@Suppress("ModifierNaming")
|
@Suppress("ModifierNaming")
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -29,7 +30,6 @@ fun WalletDisconnectedMessage(
|
||||||
onClick = state.onClick,
|
onClick = state.onClick,
|
||||||
start = {
|
start = {
|
||||||
Image(
|
Image(
|
||||||
modifier = Modifier.align(Alignment.Top),
|
|
||||||
painter = painterResource(R.drawable.ic_message_disconnected),
|
painter = painterResource(R.drawable.ic_message_disconnected),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
colorFilter = ColorFilter.tint(LocalContentColor.current)
|
colorFilter = ColorFilter.tint(LocalContentColor.current)
|
|
@ -1,11 +1,10 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home.messages
|
package co.electriccoin.zcash.ui.screen.home.error
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.material3.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
@ -15,6 +14,8 @@ import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
||||||
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.screen.home.HomeMessageState
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.HomeMessageWrapper
|
||||||
|
|
||||||
@Suppress("ModifierNaming")
|
@Suppress("ModifierNaming")
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -29,7 +30,6 @@ fun WalletErrorMessage(
|
||||||
onClick = state.onClick,
|
onClick = state.onClick,
|
||||||
start = {
|
start = {
|
||||||
Image(
|
Image(
|
||||||
modifier = Modifier.align(Alignment.Top),
|
|
||||||
painter = painterResource(R.drawable.ic_warning_triangle),
|
painter = painterResource(R.drawable.ic_warning_triangle),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
colorFilter = ColorFilter.tint(LocalContentColor.current)
|
colorFilter = ColorFilter.tint(LocalContentColor.current)
|
|
@ -1,4 +1,4 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home
|
package co.electriccoin.zcash.ui.screen.home.restoring
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
@ -1,7 +1,6 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home.messages
|
package co.electriccoin.zcash.ui.screen.home.restoring
|
||||||
|
|
||||||
import androidx.annotation.IntRange
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.animation.core.animateIntAsState
|
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
|
@ -13,9 +12,11 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiCircularProgressIndicator
|
import co.electriccoin.zcash.ui.design.component.ZashiCircularProgressIndicatorByPercent
|
||||||
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.screen.home.HomeMessageState
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.HomeMessageWrapper
|
||||||
|
|
||||||
@Suppress("ModifierNaming")
|
@Suppress("ModifierNaming")
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -29,7 +30,7 @@ fun WalletRestoringMessage(
|
||||||
contentPadding = contentPadding,
|
contentPadding = contentPadding,
|
||||||
onClick = state.onClick,
|
onClick = state.onClick,
|
||||||
start = {
|
start = {
|
||||||
ZashiCircularProgressIndicator(
|
ZashiCircularProgressIndicatorByPercent(
|
||||||
modifier = Modifier.size(20.dp),
|
modifier = Modifier.size(20.dp),
|
||||||
progressPercent = state.progress,
|
progressPercent = state.progress,
|
||||||
)
|
)
|
||||||
|
@ -49,7 +50,7 @@ fun WalletRestoringMessage(
|
||||||
}
|
}
|
||||||
|
|
||||||
class WalletRestoringMessageState(
|
class WalletRestoringMessageState(
|
||||||
@IntRange(from = 0, to = 100) val progress: Int,
|
val progress: Float,
|
||||||
val onClick: () -> Unit
|
val onClick: () -> Unit
|
||||||
) : HomeMessageState
|
) : HomeMessageState
|
||||||
|
|
||||||
|
@ -57,7 +58,7 @@ class WalletRestoringMessageState(
|
||||||
@Composable
|
@Composable
|
||||||
private fun Preview() =
|
private fun Preview() =
|
||||||
ZcashTheme {
|
ZcashTheme {
|
||||||
val progress by animateIntAsState(50, label = "progress", animationSpec = tween(10000))
|
val progress by animateFloatAsState(50f, label = "progress", animationSpec = tween(10000))
|
||||||
|
|
||||||
BlankSurface {
|
BlankSurface {
|
||||||
WalletRestoringMessage(
|
WalletRestoringMessage(
|
|
@ -1,4 +1,4 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home
|
package co.electriccoin.zcash.ui.screen.home.syncing
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
@ -1,7 +1,6 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home.messages
|
package co.electriccoin.zcash.ui.screen.home.syncing
|
||||||
|
|
||||||
import androidx.annotation.IntRange
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.animation.core.animateIntAsState
|
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
|
@ -13,9 +12,11 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiCircularProgressIndicator
|
import co.electriccoin.zcash.ui.design.component.ZashiCircularProgressIndicatorByPercent
|
||||||
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.screen.home.HomeMessageState
|
||||||
|
import co.electriccoin.zcash.ui.screen.home.HomeMessageWrapper
|
||||||
|
|
||||||
@Suppress("ModifierNaming")
|
@Suppress("ModifierNaming")
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -29,7 +30,7 @@ fun WalletSyncingMessage(
|
||||||
contentPadding = contentPadding,
|
contentPadding = contentPadding,
|
||||||
onClick = state.onClick,
|
onClick = state.onClick,
|
||||||
start = {
|
start = {
|
||||||
ZashiCircularProgressIndicator(
|
ZashiCircularProgressIndicatorByPercent(
|
||||||
modifier = Modifier.size(20.dp),
|
modifier = Modifier.size(20.dp),
|
||||||
progressPercent = state.progress,
|
progressPercent = state.progress,
|
||||||
)
|
)
|
||||||
|
@ -49,7 +50,7 @@ fun WalletSyncingMessage(
|
||||||
}
|
}
|
||||||
|
|
||||||
class WalletSyncingMessageState(
|
class WalletSyncingMessageState(
|
||||||
@IntRange(from = 0, to = 100) val progress: Int,
|
val progress: Float,
|
||||||
val onClick: () -> Unit
|
val onClick: () -> Unit
|
||||||
) : HomeMessageState
|
) : HomeMessageState
|
||||||
|
|
||||||
|
@ -57,7 +58,7 @@ class WalletSyncingMessageState(
|
||||||
@Composable
|
@Composable
|
||||||
private fun Preview() =
|
private fun Preview() =
|
||||||
ZcashTheme {
|
ZcashTheme {
|
||||||
val progress by animateIntAsState(50, label = "progress", animationSpec = tween(10000))
|
val progress by animateFloatAsState(50f, label = "progress", animationSpec = tween(10000))
|
||||||
|
|
||||||
BlankSurface {
|
BlankSurface {
|
||||||
WalletSyncingMessage(
|
WalletSyncingMessage(
|
|
@ -1,4 +1,4 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home.balance
|
package co.electriccoin.zcash.ui.screen.home.transparentbalance
|
||||||
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
|
@ -1,4 +1,4 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home.balance
|
package co.electriccoin.zcash.ui.screen.home.transparentbalance
|
||||||
|
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
import co.electriccoin.zcash.ui.design.component.ButtonState
|
import co.electriccoin.zcash.ui.design.component.ButtonState
|
|
@ -1,4 +1,4 @@
|
||||||
package co.electriccoin.zcash.ui.screen.home.balance
|
package co.electriccoin.zcash.ui.screen.home.transparentbalance
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue