[#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/assetWizardSettings.xml
|
||||
/.idea/inspectionProfiles/Project_Default.xml
|
||||
/.idea/androidTestResultsUserPreferences.xml
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
|
||||
</JetCodeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
|
|
@ -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<InternalSynchronizerStatus.Available> {
|
||||
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<Synchronizer?> = synchronizerOrLockoutId
|
||||
.flatMapLatest {
|
||||
it
|
||||
}
|
||||
.flatMapLatest { it }
|
||||
.map {
|
||||
when (it) {
|
||||
is InternalSynchronizerStatus.Available -> it.synchronizer
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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<WalletViewModel>()
|
||||
|
||||
val walletAddresses = walletViewModel.addresses.collectAsState().value
|
||||
val walletAddresses = walletViewModel.addresses.collectAsStateWithLifecycle().value
|
||||
|
||||
if (null == walletAddresses) {
|
||||
// Display loading indicator
|
||||
} else {
|
||||
|
|
|
@ -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<String>,
|
||||
|
@ -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
|
||||
|
|
|
@ -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<WalletViewModel>()
|
||||
|
||||
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,
|
||||
|
|
|
@ -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<WalletViewModel>()
|
||||
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<WalletViewModel>()
|
||||
val walletAddresses = viewModel.addresses.collectAsState().value
|
||||
val walletAddresses = viewModel.addresses.collectAsStateWithLifecycle().value
|
||||
|
||||
WrapProfile(
|
||||
walletAddresses,
|
||||
|
|
|
@ -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<WalletViewModel>()
|
||||
val walletAddresses = walletViewModel.addresses.collectAsState().value
|
||||
val walletAddresses = walletViewModel.addresses.collectAsStateWithLifecycle().value
|
||||
|
||||
if (null == walletAddresses) {
|
||||
// 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.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()
|
||||
|
||||
|
|
|
@ -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<WalletViewModel>()
|
||||
|
||||
val synchronizer = walletViewModel.synchronizer.collectAsState().value
|
||||
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
|
||||
|
||||
if (synchronizer == null) {
|
||||
// Display loading indicator
|
||||
} else {
|
||||
|
|
|
@ -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<WalletViewModel>()
|
||||
|
||||
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 {
|
||||
|
|
|
@ -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<WalletViewModel>()
|
||||
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 {
|
||||
|
|
|
@ -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<WalletViewModel>()
|
||||
|
||||
val synchronizer = walletViewModel.synchronizer.collectAsState().value
|
||||
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
|
||||
|
||||
if (null == synchronizer) {
|
||||
// Display loading indicator
|
||||
} else {
|
||||
|
|
|
@ -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<SupportViewModel>()
|
||||
val supportMessage = viewModel.supportInfo.collectAsState().value
|
||||
val supportMessage = viewModel.supportInfo.collectAsStateWithLifecycle().value
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
|
|
|
@ -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 -> {
|
||||
|
|
|
@ -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<StorageCheckViewModel>()
|
||||
val spaceRequiredToContinue by storageCheckViewModel.spaceRequiredToContinueMegabytes.collectAsState()
|
||||
val spaceRequiredToContinue by storageCheckViewModel.spaceRequiredToContinueMegabytes.collectAsStateWithLifecycle()
|
||||
|
||||
NotEnoughSpaceView(
|
||||
storageSpaceRequiredGigabytes = storageCheckViewModel.requiredStorageSpaceGigabytes,
|
||||
|
|
Loading…
Reference in New Issue