diff --git a/.gitignore b/.gitignore
index 0fd2c046..0e7888c4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,4 @@ local.properties
/.idea/artifacts
/.idea/assetWizardSettings.xml
/.idea/inspectionProfiles/Project_Default.xml
+/.idea/androidTestResultsUserPreferences.xml
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 4725ed8b..35827e30 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -6,6 +6,8 @@
+
+
diff --git a/gradle.properties b/gradle.properties
index 90f53a5a..16504abc 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -120,7 +120,7 @@ ANDROIDX_COMPOSE_VERSION=1.3.1
ANDROIDX_CONSTRAINTLAYOUT_VERSION=1.0.1
ANDROIDX_CORE_VERSION=1.9.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_PROFILE_INSTALLER_VERSION=1.3.0-alpha02
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
# TODO [#279]: Revert to stable SDK before app release
# 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
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 6bdc88e6..b9223fe2 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -173,6 +173,7 @@ dependencyResolutionManagement {
library("androidx-core", "androidx.core:core-ktx:$androidxCoreVersion")
library("androidx-constraintlayout", "androidx.constraintlayout:constraintlayout-compose:$androidxConstraintLayoutVersion")
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-profileinstaller", "androidx.profileinstaller:profileinstaller:$androidxProfileInstallerVersion")
library("androidx-security-crypto", "androidx.security:security-crypto-ktx:$androidxSecurityCryptoVersion")
@@ -236,6 +237,7 @@ dependencyResolutionManagement {
"androidx-activity-compose",
"androidx-compose-material-icons-core",
"androidx-compose-material-icons-extended",
+ "androidx-lifecycle-compose",
"androidx-navigation-compose",
"androidx-viewmodel-compose"
)
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/global/WalletCoordinator.kt b/ui-lib/src/main/java/co/electriccoin/zcash/global/WalletCoordinator.kt
index 9c5f64d0..64c60b00 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/global/WalletCoordinator.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/global/WalletCoordinator.kt
@@ -17,6 +17,7 @@ import co.electriccoin.zcash.ui.preference.StandardPreferenceSingleton
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.awaitClose
@@ -86,21 +87,20 @@ class WalletCoordinator(context: Context) {
flowOf(InternalSynchronizerStatus.NoWallet)
} else {
callbackFlow {
- val synchronizer = synchronizerMutex.withLock {
- val synchronizer = Synchronizer.new(
+ val closeableSynchronizer = synchronizerMutex.withLock {
+ Synchronizer.new(
context = context,
zcashNetwork = persistableWallet.network,
lightWalletEndpoint = LightWalletEndpoint.defaultForNetwork(persistableWallet.network),
birthday = persistableWallet.birthday,
seed = persistableWallet.seedPhrase.toByteArray()
)
- synchronizer.start(walletScope)
}
- trySend(InternalSynchronizerStatus.Available(synchronizer))
+ trySend(InternalSynchronizerStatus.Available(closeableSynchronizer))
awaitClose {
- Twig.info { "Closing flow and stopping synchronizer" }
- synchronizer.stop()
+ Twig.info { "Closing flow and synchronizer" }
+ 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
* cases, see [WalletViewModel].
*/
- @OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+ @OptIn(ExperimentalCoroutinesApi::class)
val synchronizer: StateFlow = synchronizerOrLockoutId
- .flatMapLatest {
- it
- }
+ .flatMapLatest { it }
.map {
when (it) {
is InternalSynchronizerStatus.Available -> it.synchronizer
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/MainActivity.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/MainActivity.kt
index de377e0d..4e49dbce 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/MainActivity.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/MainActivity.kt
@@ -9,13 +9,13 @@ import androidx.annotation.VisibleForTesting
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
+import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavHostController
-import cash.z.ecc.android.sdk.ext.collectWith
import co.electriccoin.zcash.ui.common.BindCompLocalProvider
import co.electriccoin.zcash.ui.design.compat.FontCompat
import co.electriccoin.zcash.ui.design.component.ConfigurationOverride
@@ -78,6 +78,7 @@ class MainActivity : ComponentActivity() {
}
}
+ @OptIn(ExperimentalLifecycleComposeApi::class)
private fun setupUiContent() {
setContent {
Override(configurationOverrideFlow) {
@@ -88,7 +89,7 @@ class MainActivity : ComponentActivity() {
.fillMaxHeight()
) {
BindCompLocalProvider {
- val isEnoughSpace by storageCheckViewModel.isEnoughSpace.collectAsState()
+ val isEnoughSpace by storageCheckViewModel.isEnoughSpace.collectAsStateWithLifecycle()
if (isEnoughSpace == false) {
WrapNotEnoughSpace()
} else {
@@ -98,18 +99,17 @@ class MainActivity : ComponentActivity() {
}
}
}
- }
- // 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,
- // so that the collection is still tied to UI lifecycle.
- walletViewModel.synchronizer.collectWith(lifecycleScope) {
+ // Force collection to improve performance; sync can start happening while
+ // the user is going through the backup flow.
+ walletViewModel.synchronizer.collectAsStateWithLifecycle()
}
}
+ @OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
private fun MainContent() {
- when (val secretState = walletViewModel.secretState.collectAsState().value) {
+ when (val secretState = walletViewModel.secretState.collectAsStateWithLifecycle().value) {
SecretState.Loading -> {
// For now, keep displaying splash screen using condition above.
// In the future, we might consider displaying something different here.
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/address/AndroidWalletAddresses.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/address/AndroidWalletAddresses.kt
index f22e5310..ce7ffc26 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/address/AndroidWalletAddresses.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/address/AndroidWalletAddresses.kt
@@ -5,7 +5,8 @@ package co.electriccoin.zcash.ui.screen.address
import androidx.activity.ComponentActivity
import androidx.activity.viewModels
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.screen.address.view.WalletAddresses
import co.electriccoin.zcash.ui.screen.home.viewmodel.WalletViewModel
@@ -17,6 +18,7 @@ internal fun MainActivity.WrapWalletAddresses(
WrapWalletAddresses(this, goBack)
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
private fun WrapWalletAddresses(
activity: ComponentActivity,
@@ -24,7 +26,8 @@ private fun WrapWalletAddresses(
) {
val walletViewModel by activity.viewModels()
- val walletAddresses = walletViewModel.addresses.collectAsState().value
+ val walletAddresses = walletViewModel.addresses.collectAsStateWithLifecycle().value
+
if (null == walletAddresses) {
// Display loading indicator
} else {
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/backup/view/BackupView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/backup/view/BackupView.kt
index c4b66878..df1f3b8b 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/backup/view/BackupView.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/backup/view/BackupView.kt
@@ -27,7 +27,6 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
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.tooling.preview.Devices
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.model.PersistableWallet
import co.electriccoin.zcash.spackle.model.Index
@@ -78,7 +79,7 @@ fun ComposablePreview() {
/**
* @param onComplete Callback when the user has completed the backup test.
*/
-@OptIn(ExperimentalMaterial3Api::class)
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalLifecycleComposeApi::class)
@Composable
@Suppress("LongParameterList")
fun BackupWallet(
@@ -89,7 +90,7 @@ fun BackupWallet(
onComplete: () -> Unit,
onChoicesChanged: ((choicesCount: Int) -> Unit)?
) {
- val currentBackupStage = backupState.current.collectAsState().value
+ val currentBackupStage = backupState.current.collectAsStateWithLifecycle().value
Scaffold(
topBar = {
@@ -123,6 +124,7 @@ fun BackupWallet(
}
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
fun BackupMainContent(
paddingValues: PaddingValues,
@@ -138,7 +140,7 @@ fun BackupMainContent(
bottom = paddingValues.calculateBottomPadding()
)
) {
- when (backupState.current.collectAsState().value) {
+ when (backupState.current.collectAsStateWithLifecycle().value) {
is BackupStage.EducationOverview -> EducationOverview()
is BackupStage.EducationRecoveryPhrase -> EducationRecoveryPhrase()
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
* - The test answer ordering is not randomized, to ensure it can never be in the correct order to start with
*/
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
private fun TestInProgress(
splitSeedPhrase: List,
@@ -233,7 +236,7 @@ private fun TestInProgress(
@Suppress("MagicNumber")
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.all { splitSeedPhrase[it.key.value] == it.value }) {
// the user got the test correct
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidHome.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidHome.kt
index 57c273f3..210cd202 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidHome.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/home/AndroidHome.kt
@@ -5,8 +5,9 @@ package co.electriccoin.zcash.ui.screen.home
import androidx.activity.ComponentActivity
import androidx.activity.viewModels
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.collectAsState
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.FirebaseTestLabUtil
import co.electriccoin.zcash.ui.BuildConfig
@@ -34,6 +35,7 @@ internal fun MainActivity.WrapHome(
)
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
internal fun WrapHome(
activity: ComponentActivity,
@@ -49,13 +51,14 @@ internal fun WrapHome(
AppUpdateCheckerImp.new()
)
}
- val updateAvailable = checkUpdateViewModel.updateInfo.collectAsState().value.let {
+ val updateAvailable = checkUpdateViewModel.updateInfo.collectAsStateWithLifecycle().value.let {
it?.appUpdateInfo != null && it.state == UpdateState.Prepared
}
val walletViewModel by activity.viewModels()
- val walletSnapshot = walletViewModel.walletSnapshot.collectAsState().value
+ val walletSnapshot = walletViewModel.walletSnapshot.collectAsStateWithLifecycle().value
+
if (null == walletSnapshot) {
// Display loading indicator
} else {
@@ -67,9 +70,11 @@ internal fun WrapHome(
!FirebaseTestLabUtil.isFirebaseTestLab(context) &&
!EmulatorWtfUtil.isEmulatorWtf(context)
+ val transactionSnapshot = walletViewModel.transactionSnapshot.collectAsStateWithLifecycle().value
+
Home(
walletSnapshot,
- walletViewModel.transactionSnapshot.collectAsState().value,
+ transactionSnapshot,
goScan = goScan,
goRequest = goRequest,
goSend = goSend,
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/AndroidOnboarding.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/AndroidOnboarding.kt
index 3637368d..9d2d4849 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/AndroidOnboarding.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/AndroidOnboarding.kt
@@ -7,8 +7,9 @@ import android.content.Context
import androidx.activity.ComponentActivity
import androidx.activity.viewModels
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.collectAsState
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.sdk.fixture.SeedPhraseFixture
import cash.z.ecc.sdk.model.PersistableWallet
@@ -30,6 +31,7 @@ internal fun MainActivity.WrapOnboarding() {
WrapOnboarding(this)
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
internal fun WrapOnboarding(
activity: ComponentActivity
@@ -46,7 +48,7 @@ internal fun WrapOnboarding(
!EmulatorWtfUtil.isEmulatorWtf(applicationContext)
// TODO [#383]: https://github.com/zcash/secant-android-wallet/issues/383
- if (!onboardingViewModel.isImporting.collectAsState().value) {
+ if (!onboardingViewModel.isImporting.collectAsStateWithLifecycle().value) {
Onboarding(
onboardingState = onboardingViewModel.onboardingState,
isDebugMenuEnabled = isDebugMenuEnabled,
@@ -93,6 +95,7 @@ internal fun WrapOnboarding(
}
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
private fun WrapRestore(activity: ComponentActivity) {
val walletViewModel by activity.viewModels()
@@ -101,7 +104,7 @@ private fun WrapRestore(activity: ComponentActivity) {
val applicationContext = LocalContext.current.applicationContext
- when (val completeWordList = restoreViewModel.completeWordList.collectAsState().value) {
+ when (val completeWordList = restoreViewModel.completeWordList.collectAsStateWithLifecycle().value) {
CompleteWordSetState.Loading -> {
// Although it might perform IO, it should be relatively fast.
// Consider whether to display indeterminate progress here.
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/view/OnboardingView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/view/OnboardingView.kt
index 28bacb4b..02463f89 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/view/OnboardingView.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/view/OnboardingView.kt
@@ -24,7 +24,6 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
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.stringResource
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.design.component.Body
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 onCreateWallet Callback when the user decides to create a new wallet.
*/
-@OptIn(ExperimentalMaterial3Api::class)
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalLifecycleComposeApi::class)
@Composable
fun Onboarding(
onboardingState: OnboardingState,
@@ -78,7 +79,7 @@ fun Onboarding(
onCreateWallet: () -> Unit,
onFixtureWallet: () -> Unit
) {
- val currentStage = onboardingState.current.collectAsState().value
+ val currentStage = onboardingState.current.collectAsStateWithLifecycle().value
Scaffold(
topBar = {
OnboardingTopAppBar(onboardingState, isDebugMenuEnabled, onFixtureWallet)
@@ -95,13 +96,13 @@ fun Onboarding(
}
@Composable
-@OptIn(ExperimentalMaterial3Api::class)
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalLifecycleComposeApi::class)
private fun OnboardingTopAppBar(
onboardingState: OnboardingState,
isDebugMenuEnabled: Boolean,
onFixtureWallet: () -> Unit
) {
- val currentStage = onboardingState.current.collectAsState().value
+ val currentStage = onboardingState.current.collectAsStateWithLifecycle().value
TopAppBar(
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 onCreateWallet Callback when the user decides to create a new wallet.
*/
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
fun OnboardingMainContent(
paddingValues: PaddingValues,
@@ -157,7 +159,7 @@ fun OnboardingMainContent(
Column(
Modifier.padding(top = paddingValues.calculateTopPadding())
) {
- val onboardingStage = onboardingState.current.collectAsState().value
+ val onboardingStage = onboardingState.current.collectAsStateWithLifecycle().value
when (onboardingStage) {
OnboardingStage.ShieldedByDefault -> ShieldedByDefault(paddingValues)
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/profile/AndroidProfile.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/profile/AndroidProfile.kt
index 1253dc7c..cc61d4d2 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/profile/AndroidProfile.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/profile/AndroidProfile.kt
@@ -5,7 +5,8 @@ package co.electriccoin.zcash.ui.screen.profile
import androidx.activity.ComponentActivity
import androidx.activity.viewModels
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 co.electriccoin.zcash.ui.MainActivity
import co.electriccoin.zcash.ui.screen.home.viewmodel.WalletViewModel
@@ -34,6 +35,7 @@ internal fun MainActivity.WrapProfile(
)
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
@Suppress("LongParameterList")
internal fun WrapProfile(
@@ -47,7 +49,7 @@ internal fun WrapProfile(
onAbout: () -> Unit
) {
val viewModel by activity.viewModels()
- val walletAddresses = viewModel.addresses.collectAsState().value
+ val walletAddresses = viewModel.addresses.collectAsStateWithLifecycle().value
WrapProfile(
walletAddresses,
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/request/AndroidRequest.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/request/AndroidRequest.kt
index fbbc5949..9cae5d95 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/request/AndroidRequest.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/request/AndroidRequest.kt
@@ -7,7 +7,8 @@ import android.content.Intent
import androidx.activity.ComponentActivity
import androidx.activity.viewModels
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 co.electriccoin.zcash.ui.MainActivity
import co.electriccoin.zcash.ui.R
@@ -22,13 +23,14 @@ internal fun MainActivity.WrapRequest(
WrapRequest(this, goBack)
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
private fun WrapRequest(
activity: ComponentActivity,
goBack: () -> Unit
) {
val walletViewModel by activity.viewModels()
- val walletAddresses = walletViewModel.addresses.collectAsState().value
+ val walletAddresses = walletViewModel.addresses.collectAsStateWithLifecycle().value
if (null == walletAddresses) {
// Display loading indicator
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/view/RestoreView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/view/RestoreView.kt
index 7e2bd101..acf24cd3 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/view/RestoreView.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/view/RestoreView.kt
@@ -52,6 +52,8 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
import cash.z.ecc.sdk.model.SeedPhraseValidation
import co.electriccoin.zcash.spackle.model.Index
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] https://github.com/zcash/secant-android-wallet/issues/672
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Suppress("UNUSED_PARAMETER", "LongParameterList")
@Composable
private fun RestoreMainContent(
@@ -195,7 +198,7 @@ private fun RestoreMainContent(
parseResult: ParseResult,
paste: () -> String?
) {
- val currentUserWordList = userWordList.current.collectAsState().value
+ val currentUserWordList = userWordList.current.collectAsStateWithLifecycle().value
val scrollState = rememberScrollState()
val scope = rememberCoroutineScope()
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/AndroidScan.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/AndroidScan.kt
index 6c9f76e0..48e1aa4a 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/AndroidScan.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/scan/AndroidScan.kt
@@ -6,9 +6,10 @@ import androidx.activity.ComponentActivity
import androidx.activity.viewModels
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
+import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import co.electriccoin.zcash.ui.MainActivity
import co.electriccoin.zcash.ui.R
@@ -29,6 +30,7 @@ internal fun MainActivity.WrapScanValidator(
)
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
private fun WrapScanValidator(
activity: ComponentActivity,
@@ -37,7 +39,8 @@ private fun WrapScanValidator(
) {
val walletViewModel by activity.viewModels()
- val synchronizer = walletViewModel.synchronizer.collectAsState().value
+ val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
+
if (synchronizer == null) {
// Display loading indicator
} else {
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/AndroidSeed.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/AndroidSeed.kt
index 6f3cee2c..92a2c37a 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/AndroidSeed.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/seed/AndroidSeed.kt
@@ -5,7 +5,8 @@ package co.electriccoin.zcash.ui.screen.seed
import androidx.activity.ComponentActivity
import androidx.activity.viewModels
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.screen.backup.copyToClipboard
import co.electriccoin.zcash.ui.screen.home.viewmodel.SecretState
@@ -19,6 +20,7 @@ internal fun MainActivity.WrapSeed(
WrapSeed(this, goBack)
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
private fun WrapSeed(
activity: ComponentActivity,
@@ -27,14 +29,15 @@ private fun WrapSeed(
val walletViewModel by activity.viewModels()
val persistableWallet = run {
- val secretState = walletViewModel.secretState.collectAsState().value
+ val secretState = walletViewModel.secretState.collectAsStateWithLifecycle().value
if (secretState is SecretState.Ready) {
secretState.persistableWallet
} else {
null
}
}
- val synchronizer = walletViewModel.synchronizer.collectAsState().value
+ val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
+
if (null == synchronizer || null == persistableWallet) {
// Display loading indicator
} else {
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/send/AndroidSend.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/send/AndroidSend.kt
index 3cdf9b4f..2e467351 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/send/AndroidSend.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/send/AndroidSend.kt
@@ -5,8 +5,9 @@ package co.electriccoin.zcash.ui.screen.send
import androidx.activity.ComponentActivity
import androidx.activity.viewModels
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.rememberCoroutineScope
+import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
import cash.z.ecc.sdk.send
import co.electriccoin.zcash.ui.MainActivity
import co.electriccoin.zcash.ui.screen.home.model.spendableBalance
@@ -21,6 +22,7 @@ internal fun MainActivity.WrapSend(
WrapSend(this, goBack)
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
private fun WrapSend(
activity: ComponentActivity,
@@ -29,9 +31,11 @@ private fun WrapSend(
val walletViewModel by activity.viewModels()
val scope = rememberCoroutineScope()
- val synchronizer = walletViewModel.synchronizer.collectAsState().value
- val spendableBalance = walletViewModel.walletSnapshot.collectAsState().value?.spendableBalance()
- val spendingKey = walletViewModel.spendingKey.collectAsState().value
+ val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
+
+ val spendableBalance = walletViewModel.walletSnapshot.collectAsStateWithLifecycle().value?.spendableBalance()
+
+ val spendingKey = walletViewModel.spendingKey.collectAsStateWithLifecycle().value
if (null == synchronizer || null == spendableBalance || null == spendingKey) {
// Display loading indicator
} else {
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/AndroidSettings.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/AndroidSettings.kt
index 188bad40..b1cdccfd 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/AndroidSettings.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/AndroidSettings.kt
@@ -5,7 +5,8 @@ package co.electriccoin.zcash.ui.screen.settings
import androidx.activity.ComponentActivity
import androidx.activity.viewModels
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.screen.home.viewmodel.WalletViewModel
import co.electriccoin.zcash.ui.screen.onboarding.viewmodel.OnboardingViewModel
@@ -23,6 +24,7 @@ internal fun MainActivity.WrapSettings(
)
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
private fun WrapSettings(
activity: ComponentActivity,
@@ -31,7 +33,8 @@ private fun WrapSettings(
) {
val walletViewModel by activity.viewModels()
- val synchronizer = walletViewModel.synchronizer.collectAsState().value
+ val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
+
if (null == synchronizer) {
// Display loading indicator
} else {
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/support/AndroidSupport.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/support/AndroidSupport.kt
index 865d632f..47e304de 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/support/AndroidSupport.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/support/AndroidSupport.kt
@@ -7,9 +7,10 @@ import androidx.activity.ComponentActivity
import androidx.activity.viewModels
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
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.R
import co.electriccoin.zcash.ui.screen.support.model.SupportInfo
@@ -26,13 +27,14 @@ internal fun MainActivity.WrapSupport(
WrapSupport(this, goBack)
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
internal fun WrapSupport(
activity: ComponentActivity,
goBack: () -> Unit
) {
val viewModel by activity.viewModels()
- val supportMessage = viewModel.supportInfo.collectAsState().value
+ val supportMessage = viewModel.supportInfo.collectAsStateWithLifecycle().value
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AndroidUpdate.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AndroidUpdate.kt
index 1c65176f..44094c7f 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AndroidUpdate.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AndroidUpdate.kt
@@ -7,9 +7,10 @@ import androidx.annotation.VisibleForTesting
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
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.R
import co.electriccoin.zcash.ui.screen.home.viewmodel.CheckUpdateViewModel
@@ -26,6 +27,7 @@ internal fun MainActivity.WrapCheckForUpdate() {
WrapCheckForUpdate(this)
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
private fun WrapCheckForUpdate(activity: ComponentActivity) {
// 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 {
if (it.appUpdateInfo != null && it.state == UpdateState.Prepared) {
@@ -53,6 +55,7 @@ private fun WrapCheckForUpdate(activity: ComponentActivity) {
}
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
private fun WrapUpdate(
activity: ComponentActivity,
@@ -69,7 +72,7 @@ private fun WrapUpdate(
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
- val updateInfo = viewModel.updateInfo.collectAsState().value
+ val updateInfo = viewModel.updateInfo.collectAsStateWithLifecycle().value
when (updateInfo.state) {
UpdateState.Done, UpdateState.Canceled -> {
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/AndroidNotEnoughSpace.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/AndroidNotEnoughSpace.kt
index 843c4413..95d647ce 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/AndroidNotEnoughSpace.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/AndroidNotEnoughSpace.kt
@@ -5,8 +5,9 @@ package co.electriccoin.zcash.ui.screen.warning
import androidx.activity.ComponentActivity
import androidx.activity.viewModels
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.collectAsState
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.screen.warning.view.NotEnoughSpaceView
import co.electriccoin.zcash.ui.screen.warning.viewmodel.StorageCheckViewModel
@@ -16,10 +17,11 @@ fun MainActivity.WrapNotEnoughSpace() {
WrapNotEnoughSpace(this)
}
+@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
private fun WrapNotEnoughSpace(activity: ComponentActivity) {
val storageCheckViewModel by activity.viewModels()
- val spaceRequiredToContinue by storageCheckViewModel.spaceRequiredToContinueMegabytes.collectAsState()
+ val spaceRequiredToContinue by storageCheckViewModel.spaceRequiredToContinueMegabytes.collectAsStateWithLifecycle()
NotEnoughSpaceView(
storageSpaceRequiredGigabytes = storageCheckViewModel.requiredStorageSpaceGigabytes,