[#634] Stop synchronizer when leaving app
* [#634] Collect flows with lifecycle awareness * [#686] Adopt SDK 1.11.0
This commit is contained in:
parent
ad89309ec1
commit
4f7c10f4b5
|
@ -20,3 +20,4 @@ local.properties
|
||||||
/.idea/artifacts
|
/.idea/artifacts
|
||||||
/.idea/assetWizardSettings.xml
|
/.idea/assetWizardSettings.xml
|
||||||
/.idea/inspectionProfiles/Project_Default.xml
|
/.idea/inspectionProfiles/Project_Default.xml
|
||||||
|
/.idea/androidTestResultsUserPreferences.xml
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
|
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
|
||||||
|
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
|
||||||
</JetCodeStyleSettings>
|
</JetCodeStyleSettings>
|
||||||
<codeStyleSettings language="XML">
|
<codeStyleSettings language="XML">
|
||||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||||
|
|
|
@ -120,7 +120,7 @@ ANDROIDX_COMPOSE_VERSION=1.3.1
|
||||||
ANDROIDX_CONSTRAINTLAYOUT_VERSION=1.0.1
|
ANDROIDX_CONSTRAINTLAYOUT_VERSION=1.0.1
|
||||||
ANDROIDX_CORE_VERSION=1.9.0
|
ANDROIDX_CORE_VERSION=1.9.0
|
||||||
ANDROIDX_ESPRESSO_VERSION=3.5.0
|
ANDROIDX_ESPRESSO_VERSION=3.5.0
|
||||||
ANDROIDX_LIFECYCLE_VERSION=2.5.1
|
ANDROIDX_LIFECYCLE_VERSION=2.6.0-alpha03
|
||||||
ANDROIDX_NAVIGATION_COMPOSE_VERSION=2.5.3
|
ANDROIDX_NAVIGATION_COMPOSE_VERSION=2.5.3
|
||||||
ANDROIDX_PROFILE_INSTALLER_VERSION=1.3.0-alpha02
|
ANDROIDX_PROFILE_INSTALLER_VERSION=1.3.0-alpha02
|
||||||
ANDROIDX_SECURITY_CRYPTO_VERSION=1.1.0-alpha04
|
ANDROIDX_SECURITY_CRYPTO_VERSION=1.1.0-alpha04
|
||||||
|
@ -145,7 +145,7 @@ ZCASH_ANDROID_WALLET_PLUGINS_VERSION=1.0.0
|
||||||
ZCASH_BIP39_VERSION=1.0.4
|
ZCASH_BIP39_VERSION=1.0.4
|
||||||
# TODO [#279]: Revert to stable SDK before app release
|
# TODO [#279]: Revert to stable SDK before app release
|
||||||
# TODO [#279]: https://github.com/zcash/secant-android-wallet/issues/279
|
# TODO [#279]: https://github.com/zcash/secant-android-wallet/issues/279
|
||||||
ZCASH_SDK_VERSION=1.10.0-beta01-SNAPSHOT
|
ZCASH_SDK_VERSION=1.11.0-beta01-SNAPSHOT
|
||||||
ZXING_VERSION=3.5.0
|
ZXING_VERSION=3.5.0
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,7 @@ dependencyResolutionManagement {
|
||||||
library("androidx-core", "androidx.core:core-ktx:$androidxCoreVersion")
|
library("androidx-core", "androidx.core:core-ktx:$androidxCoreVersion")
|
||||||
library("androidx-constraintlayout", "androidx.constraintlayout:constraintlayout-compose:$androidxConstraintLayoutVersion")
|
library("androidx-constraintlayout", "androidx.constraintlayout:constraintlayout-compose:$androidxConstraintLayoutVersion")
|
||||||
library("androidx-lifecycle-livedata", "androidx.lifecycle:lifecycle-livedata-ktx:$androidxLifecycleVersion")
|
library("androidx-lifecycle-livedata", "androidx.lifecycle:lifecycle-livedata-ktx:$androidxLifecycleVersion")
|
||||||
|
library("androidx-lifecycle-compose", "androidx.lifecycle:lifecycle-runtime-compose:$androidxLifecycleVersion")
|
||||||
library("androidx-navigation-compose", "androidx.navigation:navigation-compose:$androidxNavigationComposeVersion")
|
library("androidx-navigation-compose", "androidx.navigation:navigation-compose:$androidxNavigationComposeVersion")
|
||||||
library("androidx-profileinstaller", "androidx.profileinstaller:profileinstaller:$androidxProfileInstallerVersion")
|
library("androidx-profileinstaller", "androidx.profileinstaller:profileinstaller:$androidxProfileInstallerVersion")
|
||||||
library("androidx-security-crypto", "androidx.security:security-crypto-ktx:$androidxSecurityCryptoVersion")
|
library("androidx-security-crypto", "androidx.security:security-crypto-ktx:$androidxSecurityCryptoVersion")
|
||||||
|
@ -236,6 +237,7 @@ dependencyResolutionManagement {
|
||||||
"androidx-activity-compose",
|
"androidx-activity-compose",
|
||||||
"androidx-compose-material-icons-core",
|
"androidx-compose-material-icons-core",
|
||||||
"androidx-compose-material-icons-extended",
|
"androidx-compose-material-icons-extended",
|
||||||
|
"androidx-lifecycle-compose",
|
||||||
"androidx-navigation-compose",
|
"androidx-navigation-compose",
|
||||||
"androidx-viewmodel-compose"
|
"androidx-viewmodel-compose"
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,6 +17,7 @@ import co.electriccoin.zcash.ui.preference.StandardPreferenceSingleton
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.FlowPreview
|
import kotlinx.coroutines.FlowPreview
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
|
@ -86,21 +87,20 @@ class WalletCoordinator(context: Context) {
|
||||||
flowOf(InternalSynchronizerStatus.NoWallet)
|
flowOf(InternalSynchronizerStatus.NoWallet)
|
||||||
} else {
|
} else {
|
||||||
callbackFlow<InternalSynchronizerStatus.Available> {
|
callbackFlow<InternalSynchronizerStatus.Available> {
|
||||||
val synchronizer = synchronizerMutex.withLock {
|
val closeableSynchronizer = synchronizerMutex.withLock {
|
||||||
val synchronizer = Synchronizer.new(
|
Synchronizer.new(
|
||||||
context = context,
|
context = context,
|
||||||
zcashNetwork = persistableWallet.network,
|
zcashNetwork = persistableWallet.network,
|
||||||
lightWalletEndpoint = LightWalletEndpoint.defaultForNetwork(persistableWallet.network),
|
lightWalletEndpoint = LightWalletEndpoint.defaultForNetwork(persistableWallet.network),
|
||||||
birthday = persistableWallet.birthday,
|
birthday = persistableWallet.birthday,
|
||||||
seed = persistableWallet.seedPhrase.toByteArray()
|
seed = persistableWallet.seedPhrase.toByteArray()
|
||||||
)
|
)
|
||||||
synchronizer.start(walletScope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trySend(InternalSynchronizerStatus.Available(synchronizer))
|
trySend(InternalSynchronizerStatus.Available(closeableSynchronizer))
|
||||||
awaitClose {
|
awaitClose {
|
||||||
Twig.info { "Closing flow and stopping synchronizer" }
|
Twig.info { "Closing flow and synchronizer" }
|
||||||
synchronizer.stop()
|
closeableSynchronizer.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,11 +112,9 @@ class WalletCoordinator(context: Context) {
|
||||||
* Note that this synchronizer is closed as soon as it stops being collected. For UI use
|
* Note that this synchronizer is closed as soon as it stops being collected. For UI use
|
||||||
* cases, see [WalletViewModel].
|
* cases, see [WalletViewModel].
|
||||||
*/
|
*/
|
||||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
val synchronizer: StateFlow<Synchronizer?> = synchronizerOrLockoutId
|
val synchronizer: StateFlow<Synchronizer?> = synchronizerOrLockoutId
|
||||||
.flatMapLatest {
|
.flatMapLatest { it }
|
||||||
it
|
|
||||||
}
|
|
||||||
.map {
|
.map {
|
||||||
when (it) {
|
when (it) {
|
||||||
is InternalSynchronizerStatus.Available -> it.synchronizer
|
is InternalSynchronizerStatus.Available -> it.synchronizer
|
||||||
|
|
|
@ -9,13 +9,13 @@ import androidx.annotation.VisibleForTesting
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||||
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import cash.z.ecc.android.sdk.ext.collectWith
|
|
||||||
import co.electriccoin.zcash.ui.common.BindCompLocalProvider
|
import co.electriccoin.zcash.ui.common.BindCompLocalProvider
|
||||||
import co.electriccoin.zcash.ui.design.compat.FontCompat
|
import co.electriccoin.zcash.ui.design.compat.FontCompat
|
||||||
import co.electriccoin.zcash.ui.design.component.ConfigurationOverride
|
import co.electriccoin.zcash.ui.design.component.ConfigurationOverride
|
||||||
|
@ -78,6 +78,7 @@ class MainActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
private fun setupUiContent() {
|
private fun setupUiContent() {
|
||||||
setContent {
|
setContent {
|
||||||
Override(configurationOverrideFlow) {
|
Override(configurationOverrideFlow) {
|
||||||
|
@ -88,7 +89,7 @@ class MainActivity : ComponentActivity() {
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
) {
|
) {
|
||||||
BindCompLocalProvider {
|
BindCompLocalProvider {
|
||||||
val isEnoughSpace by storageCheckViewModel.isEnoughSpace.collectAsState()
|
val isEnoughSpace by storageCheckViewModel.isEnoughSpace.collectAsStateWithLifecycle()
|
||||||
if (isEnoughSpace == false) {
|
if (isEnoughSpace == false) {
|
||||||
WrapNotEnoughSpace()
|
WrapNotEnoughSpace()
|
||||||
} else {
|
} else {
|
||||||
|
@ -98,18 +99,17 @@ class MainActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Force collection to improve performance; sync can start happening while
|
// Force collection to improve performance; sync can start happening while
|
||||||
// the user is going through the backup flow. Don't use eager collection in the view model,
|
// the user is going through the backup flow.
|
||||||
// so that the collection is still tied to UI lifecycle.
|
walletViewModel.synchronizer.collectAsStateWithLifecycle()
|
||||||
walletViewModel.synchronizer.collectWith(lifecycleScope) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun MainContent() {
|
private fun MainContent() {
|
||||||
when (val secretState = walletViewModel.secretState.collectAsState().value) {
|
when (val secretState = walletViewModel.secretState.collectAsStateWithLifecycle().value) {
|
||||||
SecretState.Loading -> {
|
SecretState.Loading -> {
|
||||||
// For now, keep displaying splash screen using condition above.
|
// For now, keep displaying splash screen using condition above.
|
||||||
// In the future, we might consider displaying something different here.
|
// In the future, we might consider displaying something different here.
|
||||||
|
|
|
@ -5,7 +5,8 @@ package co.electriccoin.zcash.ui.screen.address
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
import co.electriccoin.zcash.ui.MainActivity
|
||||||
import co.electriccoin.zcash.ui.screen.address.view.WalletAddresses
|
import co.electriccoin.zcash.ui.screen.address.view.WalletAddresses
|
||||||
import co.electriccoin.zcash.ui.screen.home.viewmodel.WalletViewModel
|
import co.electriccoin.zcash.ui.screen.home.viewmodel.WalletViewModel
|
||||||
|
@ -17,6 +18,7 @@ internal fun MainActivity.WrapWalletAddresses(
|
||||||
WrapWalletAddresses(this, goBack)
|
WrapWalletAddresses(this, goBack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun WrapWalletAddresses(
|
private fun WrapWalletAddresses(
|
||||||
activity: ComponentActivity,
|
activity: ComponentActivity,
|
||||||
|
@ -24,7 +26,8 @@ private fun WrapWalletAddresses(
|
||||||
) {
|
) {
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
|
||||||
val walletAddresses = walletViewModel.addresses.collectAsState().value
|
val walletAddresses = walletViewModel.addresses.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
if (null == walletAddresses) {
|
if (null == walletAddresses) {
|
||||||
// Display loading indicator
|
// Display loading indicator
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -27,7 +27,6 @@ import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
@ -38,6 +37,8 @@ import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Devices
|
import androidx.compose.ui.tooling.preview.Devices
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import cash.z.ecc.sdk.fixture.PersistableWalletFixture
|
import cash.z.ecc.sdk.fixture.PersistableWalletFixture
|
||||||
import cash.z.ecc.sdk.model.PersistableWallet
|
import cash.z.ecc.sdk.model.PersistableWallet
|
||||||
import co.electriccoin.zcash.spackle.model.Index
|
import co.electriccoin.zcash.spackle.model.Index
|
||||||
|
@ -78,7 +79,7 @@ fun ComposablePreview() {
|
||||||
/**
|
/**
|
||||||
* @param onComplete Callback when the user has completed the backup test.
|
* @param onComplete Callback when the user has completed the backup test.
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
fun BackupWallet(
|
fun BackupWallet(
|
||||||
|
@ -89,7 +90,7 @@ fun BackupWallet(
|
||||||
onComplete: () -> Unit,
|
onComplete: () -> Unit,
|
||||||
onChoicesChanged: ((choicesCount: Int) -> Unit)?
|
onChoicesChanged: ((choicesCount: Int) -> Unit)?
|
||||||
) {
|
) {
|
||||||
val currentBackupStage = backupState.current.collectAsState().value
|
val currentBackupStage = backupState.current.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
|
@ -123,6 +124,7 @@ fun BackupWallet(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun BackupMainContent(
|
fun BackupMainContent(
|
||||||
paddingValues: PaddingValues,
|
paddingValues: PaddingValues,
|
||||||
|
@ -138,7 +140,7 @@ fun BackupMainContent(
|
||||||
bottom = paddingValues.calculateBottomPadding()
|
bottom = paddingValues.calculateBottomPadding()
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
when (backupState.current.collectAsState().value) {
|
when (backupState.current.collectAsStateWithLifecycle().value) {
|
||||||
is BackupStage.EducationOverview -> EducationOverview()
|
is BackupStage.EducationOverview -> EducationOverview()
|
||||||
is BackupStage.EducationRecoveryPhrase -> EducationRecoveryPhrase()
|
is BackupStage.EducationRecoveryPhrase -> EducationRecoveryPhrase()
|
||||||
is BackupStage.Seed -> SeedPhrase(wallet)
|
is BackupStage.Seed -> SeedPhrase(wallet)
|
||||||
|
@ -216,6 +218,7 @@ private data class TestChoice(val originalIndex: Index, val word: String)
|
||||||
* - It is possible for the same word to appear twice in the word choices
|
* - It is possible for the same word to appear twice in the word choices
|
||||||
* - The test answer ordering is not randomized, to ensure it can never be in the correct order to start with
|
* - The test answer ordering is not randomized, to ensure it can never be in the correct order to start with
|
||||||
*/
|
*/
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun TestInProgress(
|
private fun TestInProgress(
|
||||||
splitSeedPhrase: List<String>,
|
splitSeedPhrase: List<String>,
|
||||||
|
@ -233,7 +236,7 @@ private fun TestInProgress(
|
||||||
@Suppress("MagicNumber")
|
@Suppress("MagicNumber")
|
||||||
listOf(it[1], it[0], it[3], it[2])
|
listOf(it[1], it[0], it[3], it[2])
|
||||||
}
|
}
|
||||||
val currentSelectedTestChoice = selectedTestChoices.current.collectAsState().value
|
val currentSelectedTestChoice = selectedTestChoices.current.collectAsStateWithLifecycle().value
|
||||||
if (currentSelectedTestChoice.size == testIndices.size) {
|
if (currentSelectedTestChoice.size == testIndices.size) {
|
||||||
if (currentSelectedTestChoice.all { splitSeedPhrase[it.key.value] == it.value }) {
|
if (currentSelectedTestChoice.all { splitSeedPhrase[it.key.value] == it.value }) {
|
||||||
// the user got the test correct
|
// the user got the test correct
|
||||||
|
|
|
@ -5,8 +5,9 @@ package co.electriccoin.zcash.ui.screen.home
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.spackle.EmulatorWtfUtil
|
import co.electriccoin.zcash.spackle.EmulatorWtfUtil
|
||||||
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
|
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
|
||||||
import co.electriccoin.zcash.ui.BuildConfig
|
import co.electriccoin.zcash.ui.BuildConfig
|
||||||
|
@ -34,6 +35,7 @@ internal fun MainActivity.WrapHome(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapHome(
|
internal fun WrapHome(
|
||||||
activity: ComponentActivity,
|
activity: ComponentActivity,
|
||||||
|
@ -49,13 +51,14 @@ internal fun WrapHome(
|
||||||
AppUpdateCheckerImp.new()
|
AppUpdateCheckerImp.new()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val updateAvailable = checkUpdateViewModel.updateInfo.collectAsState().value.let {
|
val updateAvailable = checkUpdateViewModel.updateInfo.collectAsStateWithLifecycle().value.let {
|
||||||
it?.appUpdateInfo != null && it.state == UpdateState.Prepared
|
it?.appUpdateInfo != null && it.state == UpdateState.Prepared
|
||||||
}
|
}
|
||||||
|
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
|
||||||
val walletSnapshot = walletViewModel.walletSnapshot.collectAsState().value
|
val walletSnapshot = walletViewModel.walletSnapshot.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
if (null == walletSnapshot) {
|
if (null == walletSnapshot) {
|
||||||
// Display loading indicator
|
// Display loading indicator
|
||||||
} else {
|
} else {
|
||||||
|
@ -67,9 +70,11 @@ internal fun WrapHome(
|
||||||
!FirebaseTestLabUtil.isFirebaseTestLab(context) &&
|
!FirebaseTestLabUtil.isFirebaseTestLab(context) &&
|
||||||
!EmulatorWtfUtil.isEmulatorWtf(context)
|
!EmulatorWtfUtil.isEmulatorWtf(context)
|
||||||
|
|
||||||
|
val transactionSnapshot = walletViewModel.transactionSnapshot.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
Home(
|
Home(
|
||||||
walletSnapshot,
|
walletSnapshot,
|
||||||
walletViewModel.transactionSnapshot.collectAsState().value,
|
transactionSnapshot,
|
||||||
goScan = goScan,
|
goScan = goScan,
|
||||||
goRequest = goRequest,
|
goRequest = goRequest,
|
||||||
goSend = goSend,
|
goSend = goSend,
|
||||||
|
|
|
@ -7,8 +7,9 @@ import android.content.Context
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.sdk.fixture.SeedPhraseFixture
|
import cash.z.ecc.sdk.fixture.SeedPhraseFixture
|
||||||
import cash.z.ecc.sdk.model.PersistableWallet
|
import cash.z.ecc.sdk.model.PersistableWallet
|
||||||
|
@ -30,6 +31,7 @@ internal fun MainActivity.WrapOnboarding() {
|
||||||
WrapOnboarding(this)
|
WrapOnboarding(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapOnboarding(
|
internal fun WrapOnboarding(
|
||||||
activity: ComponentActivity
|
activity: ComponentActivity
|
||||||
|
@ -46,7 +48,7 @@ internal fun WrapOnboarding(
|
||||||
!EmulatorWtfUtil.isEmulatorWtf(applicationContext)
|
!EmulatorWtfUtil.isEmulatorWtf(applicationContext)
|
||||||
|
|
||||||
// TODO [#383]: https://github.com/zcash/secant-android-wallet/issues/383
|
// TODO [#383]: https://github.com/zcash/secant-android-wallet/issues/383
|
||||||
if (!onboardingViewModel.isImporting.collectAsState().value) {
|
if (!onboardingViewModel.isImporting.collectAsStateWithLifecycle().value) {
|
||||||
Onboarding(
|
Onboarding(
|
||||||
onboardingState = onboardingViewModel.onboardingState,
|
onboardingState = onboardingViewModel.onboardingState,
|
||||||
isDebugMenuEnabled = isDebugMenuEnabled,
|
isDebugMenuEnabled = isDebugMenuEnabled,
|
||||||
|
@ -93,6 +95,7 @@ internal fun WrapOnboarding(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun WrapRestore(activity: ComponentActivity) {
|
private fun WrapRestore(activity: ComponentActivity) {
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
@ -101,7 +104,7 @@ private fun WrapRestore(activity: ComponentActivity) {
|
||||||
|
|
||||||
val applicationContext = LocalContext.current.applicationContext
|
val applicationContext = LocalContext.current.applicationContext
|
||||||
|
|
||||||
when (val completeWordList = restoreViewModel.completeWordList.collectAsState().value) {
|
when (val completeWordList = restoreViewModel.completeWordList.collectAsStateWithLifecycle().value) {
|
||||||
CompleteWordSetState.Loading -> {
|
CompleteWordSetState.Loading -> {
|
||||||
// Although it might perform IO, it should be relatively fast.
|
// Although it might perform IO, it should be relatively fast.
|
||||||
// Consider whether to display indeterminate progress here.
|
// Consider whether to display indeterminate progress here.
|
||||||
|
|
|
@ -24,7 +24,6 @@ import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
@ -36,6 +35,8 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.design.component.Body
|
import co.electriccoin.zcash.ui.design.component.Body
|
||||||
import co.electriccoin.zcash.ui.design.component.GradientSurface
|
import co.electriccoin.zcash.ui.design.component.GradientSurface
|
||||||
|
@ -69,7 +70,7 @@ fun ComposablePreview() {
|
||||||
* @param onImportWallet Callback when the user decides to import an existing wallet.
|
* @param onImportWallet Callback when the user decides to import an existing wallet.
|
||||||
* @param onCreateWallet Callback when the user decides to create a new wallet.
|
* @param onCreateWallet Callback when the user decides to create a new wallet.
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun Onboarding(
|
fun Onboarding(
|
||||||
onboardingState: OnboardingState,
|
onboardingState: OnboardingState,
|
||||||
|
@ -78,7 +79,7 @@ fun Onboarding(
|
||||||
onCreateWallet: () -> Unit,
|
onCreateWallet: () -> Unit,
|
||||||
onFixtureWallet: () -> Unit
|
onFixtureWallet: () -> Unit
|
||||||
) {
|
) {
|
||||||
val currentStage = onboardingState.current.collectAsState().value
|
val currentStage = onboardingState.current.collectAsStateWithLifecycle().value
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
OnboardingTopAppBar(onboardingState, isDebugMenuEnabled, onFixtureWallet)
|
OnboardingTopAppBar(onboardingState, isDebugMenuEnabled, onFixtureWallet)
|
||||||
|
@ -95,13 +96,13 @@ fun Onboarding(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLifecycleComposeApi::class)
|
||||||
private fun OnboardingTopAppBar(
|
private fun OnboardingTopAppBar(
|
||||||
onboardingState: OnboardingState,
|
onboardingState: OnboardingState,
|
||||||
isDebugMenuEnabled: Boolean,
|
isDebugMenuEnabled: Boolean,
|
||||||
onFixtureWallet: () -> Unit
|
onFixtureWallet: () -> Unit
|
||||||
) {
|
) {
|
||||||
val currentStage = onboardingState.current.collectAsState().value
|
val currentStage = onboardingState.current.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = { Text(text = stringResource(id = R.string.app_name)) },
|
title = { Text(text = stringResource(id = R.string.app_name)) },
|
||||||
|
@ -149,6 +150,7 @@ private fun DebugMenu(onFixtureWallet: () -> Unit) {
|
||||||
* @param onImportWallet Callback when the user decides to import an existing wallet.
|
* @param onImportWallet Callback when the user decides to import an existing wallet.
|
||||||
* @param onCreateWallet Callback when the user decides to create a new wallet.
|
* @param onCreateWallet Callback when the user decides to create a new wallet.
|
||||||
*/
|
*/
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun OnboardingMainContent(
|
fun OnboardingMainContent(
|
||||||
paddingValues: PaddingValues,
|
paddingValues: PaddingValues,
|
||||||
|
@ -157,7 +159,7 @@ fun OnboardingMainContent(
|
||||||
Column(
|
Column(
|
||||||
Modifier.padding(top = paddingValues.calculateTopPadding())
|
Modifier.padding(top = paddingValues.calculateTopPadding())
|
||||||
) {
|
) {
|
||||||
val onboardingStage = onboardingState.current.collectAsState().value
|
val onboardingStage = onboardingState.current.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
when (onboardingStage) {
|
when (onboardingStage) {
|
||||||
OnboardingStage.ShieldedByDefault -> ShieldedByDefault(paddingValues)
|
OnboardingStage.ShieldedByDefault -> ShieldedByDefault(paddingValues)
|
||||||
|
|
|
@ -5,7 +5,8 @@ package co.electriccoin.zcash.ui.screen.profile
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import cash.z.ecc.sdk.model.WalletAddresses
|
import cash.z.ecc.sdk.model.WalletAddresses
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
import co.electriccoin.zcash.ui.MainActivity
|
||||||
import co.electriccoin.zcash.ui.screen.home.viewmodel.WalletViewModel
|
import co.electriccoin.zcash.ui.screen.home.viewmodel.WalletViewModel
|
||||||
|
@ -34,6 +35,7 @@ internal fun MainActivity.WrapProfile(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
internal fun WrapProfile(
|
internal fun WrapProfile(
|
||||||
|
@ -47,7 +49,7 @@ internal fun WrapProfile(
|
||||||
onAbout: () -> Unit
|
onAbout: () -> Unit
|
||||||
) {
|
) {
|
||||||
val viewModel by activity.viewModels<WalletViewModel>()
|
val viewModel by activity.viewModels<WalletViewModel>()
|
||||||
val walletAddresses = viewModel.addresses.collectAsState().value
|
val walletAddresses = viewModel.addresses.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
WrapProfile(
|
WrapProfile(
|
||||||
walletAddresses,
|
walletAddresses,
|
||||||
|
|
|
@ -7,7 +7,8 @@ import android.content.Intent
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import cash.z.ecc.sdk.model.ZecRequest
|
import cash.z.ecc.sdk.model.ZecRequest
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
import co.electriccoin.zcash.ui.MainActivity
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
|
@ -22,13 +23,14 @@ internal fun MainActivity.WrapRequest(
|
||||||
WrapRequest(this, goBack)
|
WrapRequest(this, goBack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun WrapRequest(
|
private fun WrapRequest(
|
||||||
activity: ComponentActivity,
|
activity: ComponentActivity,
|
||||||
goBack: () -> Unit
|
goBack: () -> Unit
|
||||||
) {
|
) {
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
val walletAddresses = walletViewModel.addresses.collectAsState().value
|
val walletAddresses = walletViewModel.addresses.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
if (null == walletAddresses) {
|
if (null == walletAddresses) {
|
||||||
// Display loading indicator
|
// Display loading indicator
|
||||||
|
|
|
@ -52,6 +52,8 @@ import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import cash.z.ecc.sdk.model.SeedPhraseValidation
|
import cash.z.ecc.sdk.model.SeedPhraseValidation
|
||||||
import co.electriccoin.zcash.spackle.model.Index
|
import co.electriccoin.zcash.spackle.model.Index
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
|
@ -185,6 +187,7 @@ private fun RestoreTopAppBar(onBack: () -> Unit, onClear: () -> Unit) {
|
||||||
|
|
||||||
// TODO [#672] Implement custom seed phrase pasting for wallet import
|
// TODO [#672] Implement custom seed phrase pasting for wallet import
|
||||||
// TODO [#672] https://github.com/zcash/secant-android-wallet/issues/672
|
// TODO [#672] https://github.com/zcash/secant-android-wallet/issues/672
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Suppress("UNUSED_PARAMETER", "LongParameterList")
|
@Suppress("UNUSED_PARAMETER", "LongParameterList")
|
||||||
@Composable
|
@Composable
|
||||||
private fun RestoreMainContent(
|
private fun RestoreMainContent(
|
||||||
|
@ -195,7 +198,7 @@ private fun RestoreMainContent(
|
||||||
parseResult: ParseResult,
|
parseResult: ParseResult,
|
||||||
paste: () -> String?
|
paste: () -> String?
|
||||||
) {
|
) {
|
||||||
val currentUserWordList = userWordList.current.collectAsState().value
|
val currentUserWordList = userWordList.current.collectAsStateWithLifecycle().value
|
||||||
val scrollState = rememberScrollState()
|
val scrollState = rememberScrollState()
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,10 @@ import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
import co.electriccoin.zcash.ui.MainActivity
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
|
@ -29,6 +30,7 @@ internal fun MainActivity.WrapScanValidator(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun WrapScanValidator(
|
private fun WrapScanValidator(
|
||||||
activity: ComponentActivity,
|
activity: ComponentActivity,
|
||||||
|
@ -37,7 +39,8 @@ private fun WrapScanValidator(
|
||||||
) {
|
) {
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
|
||||||
val synchronizer = walletViewModel.synchronizer.collectAsState().value
|
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
if (synchronizer == null) {
|
if (synchronizer == null) {
|
||||||
// Display loading indicator
|
// Display loading indicator
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,7 +5,8 @@ package co.electriccoin.zcash.ui.screen.seed
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
import co.electriccoin.zcash.ui.MainActivity
|
||||||
import co.electriccoin.zcash.ui.screen.backup.copyToClipboard
|
import co.electriccoin.zcash.ui.screen.backup.copyToClipboard
|
||||||
import co.electriccoin.zcash.ui.screen.home.viewmodel.SecretState
|
import co.electriccoin.zcash.ui.screen.home.viewmodel.SecretState
|
||||||
|
@ -19,6 +20,7 @@ internal fun MainActivity.WrapSeed(
|
||||||
WrapSeed(this, goBack)
|
WrapSeed(this, goBack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun WrapSeed(
|
private fun WrapSeed(
|
||||||
activity: ComponentActivity,
|
activity: ComponentActivity,
|
||||||
|
@ -27,14 +29,15 @@ private fun WrapSeed(
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
|
||||||
val persistableWallet = run {
|
val persistableWallet = run {
|
||||||
val secretState = walletViewModel.secretState.collectAsState().value
|
val secretState = walletViewModel.secretState.collectAsStateWithLifecycle().value
|
||||||
if (secretState is SecretState.Ready) {
|
if (secretState is SecretState.Ready) {
|
||||||
secretState.persistableWallet
|
secretState.persistableWallet
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val synchronizer = walletViewModel.synchronizer.collectAsState().value
|
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
if (null == synchronizer || null == persistableWallet) {
|
if (null == synchronizer || null == persistableWallet) {
|
||||||
// Display loading indicator
|
// Display loading indicator
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,8 +5,9 @@ package co.electriccoin.zcash.ui.screen.send
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import cash.z.ecc.sdk.send
|
import cash.z.ecc.sdk.send
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
import co.electriccoin.zcash.ui.MainActivity
|
||||||
import co.electriccoin.zcash.ui.screen.home.model.spendableBalance
|
import co.electriccoin.zcash.ui.screen.home.model.spendableBalance
|
||||||
|
@ -21,6 +22,7 @@ internal fun MainActivity.WrapSend(
|
||||||
WrapSend(this, goBack)
|
WrapSend(this, goBack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun WrapSend(
|
private fun WrapSend(
|
||||||
activity: ComponentActivity,
|
activity: ComponentActivity,
|
||||||
|
@ -29,9 +31,11 @@ private fun WrapSend(
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
val synchronizer = walletViewModel.synchronizer.collectAsState().value
|
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
|
||||||
val spendableBalance = walletViewModel.walletSnapshot.collectAsState().value?.spendableBalance()
|
|
||||||
val spendingKey = walletViewModel.spendingKey.collectAsState().value
|
val spendableBalance = walletViewModel.walletSnapshot.collectAsStateWithLifecycle().value?.spendableBalance()
|
||||||
|
|
||||||
|
val spendingKey = walletViewModel.spendingKey.collectAsStateWithLifecycle().value
|
||||||
if (null == synchronizer || null == spendableBalance || null == spendingKey) {
|
if (null == synchronizer || null == spendableBalance || null == spendingKey) {
|
||||||
// Display loading indicator
|
// Display loading indicator
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,7 +5,8 @@ package co.electriccoin.zcash.ui.screen.settings
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
import co.electriccoin.zcash.ui.MainActivity
|
||||||
import co.electriccoin.zcash.ui.screen.home.viewmodel.WalletViewModel
|
import co.electriccoin.zcash.ui.screen.home.viewmodel.WalletViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.onboarding.viewmodel.OnboardingViewModel
|
import co.electriccoin.zcash.ui.screen.onboarding.viewmodel.OnboardingViewModel
|
||||||
|
@ -23,6 +24,7 @@ internal fun MainActivity.WrapSettings(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun WrapSettings(
|
private fun WrapSettings(
|
||||||
activity: ComponentActivity,
|
activity: ComponentActivity,
|
||||||
|
@ -31,7 +33,8 @@ private fun WrapSettings(
|
||||||
) {
|
) {
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
|
||||||
val synchronizer = walletViewModel.synchronizer.collectAsState().value
|
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
if (null == synchronizer) {
|
if (null == synchronizer) {
|
||||||
// Display loading indicator
|
// Display loading indicator
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -7,9 +7,10 @@ import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
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.screen.support.model.SupportInfo
|
import co.electriccoin.zcash.ui.screen.support.model.SupportInfo
|
||||||
|
@ -26,13 +27,14 @@ internal fun MainActivity.WrapSupport(
|
||||||
WrapSupport(this, goBack)
|
WrapSupport(this, goBack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapSupport(
|
internal fun WrapSupport(
|
||||||
activity: ComponentActivity,
|
activity: ComponentActivity,
|
||||||
goBack: () -> Unit
|
goBack: () -> Unit
|
||||||
) {
|
) {
|
||||||
val viewModel by activity.viewModels<SupportViewModel>()
|
val viewModel by activity.viewModels<SupportViewModel>()
|
||||||
val supportMessage = viewModel.supportInfo.collectAsState().value
|
val supportMessage = viewModel.supportInfo.collectAsStateWithLifecycle().value
|
||||||
val snackbarHostState = remember { SnackbarHostState() }
|
val snackbarHostState = remember { SnackbarHostState() }
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,10 @@ import androidx.annotation.VisibleForTesting
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
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.screen.home.viewmodel.CheckUpdateViewModel
|
import co.electriccoin.zcash.ui.screen.home.viewmodel.CheckUpdateViewModel
|
||||||
|
@ -26,6 +27,7 @@ internal fun MainActivity.WrapCheckForUpdate() {
|
||||||
WrapCheckForUpdate(this)
|
WrapCheckForUpdate(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun WrapCheckForUpdate(activity: ComponentActivity) {
|
private fun WrapCheckForUpdate(activity: ComponentActivity) {
|
||||||
// TODO [#382]: https://github.com/zcash/secant-android-wallet/issues/382
|
// TODO [#382]: https://github.com/zcash/secant-android-wallet/issues/382
|
||||||
|
@ -38,7 +40,7 @@ private fun WrapCheckForUpdate(activity: ComponentActivity) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val updateInfo = checkUpdateViewModel.updateInfo.collectAsState().value
|
val updateInfo = checkUpdateViewModel.updateInfo.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
updateInfo?.let {
|
updateInfo?.let {
|
||||||
if (it.appUpdateInfo != null && it.state == UpdateState.Prepared) {
|
if (it.appUpdateInfo != null && it.state == UpdateState.Prepared) {
|
||||||
|
@ -53,6 +55,7 @@ private fun WrapCheckForUpdate(activity: ComponentActivity) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun WrapUpdate(
|
private fun WrapUpdate(
|
||||||
activity: ComponentActivity,
|
activity: ComponentActivity,
|
||||||
|
@ -69,7 +72,7 @@ private fun WrapUpdate(
|
||||||
val snackbarHostState = remember { SnackbarHostState() }
|
val snackbarHostState = remember { SnackbarHostState() }
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
val updateInfo = viewModel.updateInfo.collectAsState().value
|
val updateInfo = viewModel.updateInfo.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
when (updateInfo.state) {
|
when (updateInfo.state) {
|
||||||
UpdateState.Done, UpdateState.Canceled -> {
|
UpdateState.Done, UpdateState.Canceled -> {
|
||||||
|
|
|
@ -5,8 +5,9 @@ package co.electriccoin.zcash.ui.screen.warning
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
import co.electriccoin.zcash.ui.MainActivity
|
||||||
import co.electriccoin.zcash.ui.screen.warning.view.NotEnoughSpaceView
|
import co.electriccoin.zcash.ui.screen.warning.view.NotEnoughSpaceView
|
||||||
import co.electriccoin.zcash.ui.screen.warning.viewmodel.StorageCheckViewModel
|
import co.electriccoin.zcash.ui.screen.warning.viewmodel.StorageCheckViewModel
|
||||||
|
@ -16,10 +17,11 @@ fun MainActivity.WrapNotEnoughSpace() {
|
||||||
WrapNotEnoughSpace(this)
|
WrapNotEnoughSpace(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLifecycleComposeApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun WrapNotEnoughSpace(activity: ComponentActivity) {
|
private fun WrapNotEnoughSpace(activity: ComponentActivity) {
|
||||||
val storageCheckViewModel by activity.viewModels<StorageCheckViewModel>()
|
val storageCheckViewModel by activity.viewModels<StorageCheckViewModel>()
|
||||||
val spaceRequiredToContinue by storageCheckViewModel.spaceRequiredToContinueMegabytes.collectAsState()
|
val spaceRequiredToContinue by storageCheckViewModel.spaceRequiredToContinueMegabytes.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
NotEnoughSpaceView(
|
NotEnoughSpaceView(
|
||||||
storageSpaceRequiredGigabytes = storageCheckViewModel.requiredStorageSpaceGigabytes,
|
storageSpaceRequiredGigabytes = storageCheckViewModel.requiredStorageSpaceGigabytes,
|
||||||
|
|
Loading…
Reference in New Issue