Activity Compose Composition Strategy handling

This commit is contained in:
Milan Cerovsky 2024-08-19 16:12:15 +02:00
parent 2df5990238
commit be8ed7a8ad
2 changed files with 77 additions and 3 deletions

View File

@ -4,7 +4,6 @@ import android.annotation.SuppressLint
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.os.SystemClock
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.annotation.VisibleForTesting
@ -29,6 +28,7 @@ import cash.z.ecc.sdk.type.fromResources
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
import co.electriccoin.zcash.spackle.Twig
import co.electriccoin.zcash.ui.common.compose.BindCompLocalProvider
import co.electriccoin.zcash.ui.common.extension.setContentCompat
import co.electriccoin.zcash.ui.common.model.OnboardingState
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.common.viewmodel.AuthenticationUIState
@ -126,8 +126,7 @@ class MainActivity : FragmentActivity() {
// including IME animations, and go edge-to-edge.
// This also sets up the initial system bar style based on the platform theme
enableEdgeToEdge()
setContent {
setContentCompat {
Override(configurationOverrideFlow) {
ZcashTheme {
BlankSurface(
@ -160,6 +159,7 @@ class MainActivity : FragmentActivity() {
Twig.debug { "Authentication initial state" }
// Wait for the state update
}
AuthenticationUIState.NotRequired -> {
Twig.debug { "App access authentication NOT required - welcome animation only" }
if (animateAppAccess) {
@ -173,6 +173,7 @@ class MainActivity : FragmentActivity() {
}
}
}
AuthenticationUIState.Required -> {
Twig.debug { "App access authentication required" }
@ -198,12 +199,14 @@ class MainActivity : FragmentActivity() {
useCase = AuthenticationUseCase.AppAccess
)
}
AuthenticationUIState.SupportedRequired -> {
Twig.debug { "Authentication support required" }
WrapSupport(
goBack = { finish() }
)
}
AuthenticationUIState.Successful -> {
Twig.debug { "Authentication successful - entering the app" }
// No action is needed - the main app content is laid out now
@ -229,6 +232,7 @@ class MainActivity : FragmentActivity() {
SecretState.None -> {
WrapOnboarding()
}
is SecretState.NeedsWarning -> {
WrapSecurityWarning(
onBack = { walletViewModel.persistOnboardingState(OnboardingState.NONE) },
@ -249,15 +253,18 @@ class MainActivity : FragmentActivity() {
}
)
}
is SecretState.NeedsBackup -> {
WrapNewWalletRecovery(
secretState.persistableWallet,
onBackupComplete = { walletViewModel.persistOnboardingState(OnboardingState.READY) }
)
}
is SecretState.Ready -> {
Navigation()
}
else -> {
error("Unhandled secret state: $secretState")
}

View File

@ -0,0 +1,67 @@
package co.electriccoin.zcash.ui.common.extension
import android.view.ViewGroup
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionContext
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.lifecycle.findViewTreeLifecycleOwner
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import androidx.lifecycle.setViewTreeLifecycleOwner
import androidx.lifecycle.setViewTreeViewModelStoreOwner
import androidx.savedstate.findViewTreeSavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
/**
* Same like [ComponentActivity.setContent] but allows for addition of [ViewCompositionStrategy].
*/
fun ComponentActivity.setContentCompat(
viewCompositionStrategy: ViewCompositionStrategy = ViewCompositionStrategy.DisposeOnDetachedFromWindow,
parent: CompositionContext? = null,
content: @Composable () -> Unit
) {
val existingComposeView =
window.decorView
.findViewById<ViewGroup>(android.R.id.content)
.getChildAt(0) as? ComposeView
if (existingComposeView != null) {
with(existingComposeView) {
setParentCompositionContext(parent)
setContent(content)
}
} else {
ComposeView(this).apply {
// Set content and parent **before** setContentView
// to have ComposeView create the composition on attach
setViewCompositionStrategy(viewCompositionStrategy)
setParentCompositionContext(parent)
setContent(content)
// Set the view tree owners before setting the content view so that the inflation process
// and attach listeners will see them already present
setOwners()
setContentView(
this,
ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
)
}
}
}
private fun ComponentActivity.setOwners() {
val decorView = window.decorView
if (decorView.findViewTreeLifecycleOwner() == null) {
decorView.setViewTreeLifecycleOwner(this)
}
if (decorView.findViewTreeViewModelStoreOwner() == null) {
decorView.setViewTreeViewModelStoreOwner(this)
}
if (decorView.findViewTreeSavedStateRegistryOwner() == null) {
decorView.setViewTreeSavedStateRegistryOwner(this)
}
}