Create a LoadingNode to reduce code duplication.
This commit is contained in:
parent
598d4047b0
commit
733ac57928
6 changed files with 53 additions and 48 deletions
|
|
@ -36,7 +36,6 @@ import com.bumble.appyx.navmodel.backstack.operation.pop
|
||||||
import com.bumble.appyx.navmodel.backstack.operation.push
|
import com.bumble.appyx.navmodel.backstack.operation.push
|
||||||
import com.bumble.appyx.navmodel.backstack.operation.replace
|
import com.bumble.appyx.navmodel.backstack.operation.replace
|
||||||
import com.bumble.appyx.navmodel.backstack.operation.singleTop
|
import com.bumble.appyx.navmodel.backstack.operation.singleTop
|
||||||
import dev.zacsweers.metro.AppScope
|
|
||||||
import dev.zacsweers.metro.Assisted
|
import dev.zacsweers.metro.Assisted
|
||||||
import dev.zacsweers.metro.AssistedInject
|
import dev.zacsweers.metro.AssistedInject
|
||||||
import im.vector.app.features.analytics.plan.JoinedRoom
|
import im.vector.app.features.analytics.plan.JoinedRoom
|
||||||
|
|
@ -65,6 +64,7 @@ import io.element.android.features.userprofile.api.UserProfileEntryPoint
|
||||||
import io.element.android.features.verifysession.api.IncomingVerificationEntryPoint
|
import io.element.android.features.verifysession.api.IncomingVerificationEntryPoint
|
||||||
import io.element.android.libraries.architecture.BackstackView
|
import io.element.android.libraries.architecture.BackstackView
|
||||||
import io.element.android.libraries.architecture.BaseFlowNode
|
import io.element.android.libraries.architecture.BaseFlowNode
|
||||||
|
import io.element.android.libraries.architecture.appyx.LoadingNode
|
||||||
import io.element.android.libraries.architecture.createNode
|
import io.element.android.libraries.architecture.createNode
|
||||||
import io.element.android.libraries.architecture.waitForNavTargetAttached
|
import io.element.android.libraries.architecture.waitForNavTargetAttached
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||||
|
|
@ -281,7 +281,7 @@ class LoggedInFlowNode(
|
||||||
|
|
||||||
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
||||||
return when (navTarget) {
|
return when (navTarget) {
|
||||||
NavTarget.Placeholder -> createNode<PlaceholderNode>(buildContext)
|
NavTarget.Placeholder -> createNode<LoadingNode>(buildContext)
|
||||||
NavTarget.LoggedInPermanent -> {
|
NavTarget.LoggedInPermanent -> {
|
||||||
val callback = object : LoggedInNode.Callback {
|
val callback = object : LoggedInNode.Callback {
|
||||||
override fun navigateToNotificationTroubleshoot() {
|
override fun navigateToNotificationTroubleshoot() {
|
||||||
|
|
@ -548,13 +548,6 @@ class LoggedInFlowNode(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ContributesNode(AppScope::class)
|
|
||||||
@AssistedInject
|
|
||||||
class PlaceholderNode(
|
|
||||||
@Assisted buildContext: BuildContext,
|
|
||||||
@Assisted plugins: List<Plugin>,
|
|
||||||
) : Node(buildContext, plugins = plugins)
|
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
private class AttachRoomOperation(
|
private class AttachRoomOperation(
|
||||||
val roomTarget: LoggedInFlowNode.NavTarget.Room,
|
val roomTarget: LoggedInFlowNode.NavTarget.Room,
|
||||||
|
|
|
||||||
|
|
@ -11,15 +11,11 @@ import android.content.Intent
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.compose.animation.core.Spring
|
import androidx.compose.animation.core.Spring
|
||||||
import androidx.compose.animation.core.spring
|
import androidx.compose.animation.core.spring
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.bumble.appyx.core.modality.BuildContext
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
import com.bumble.appyx.core.node.Node
|
import com.bumble.appyx.core.node.Node
|
||||||
import com.bumble.appyx.core.node.node
|
|
||||||
import com.bumble.appyx.core.plugin.Plugin
|
import com.bumble.appyx.core.plugin.Plugin
|
||||||
import com.bumble.appyx.core.state.MutableSavedStateMap
|
import com.bumble.appyx.core.state.MutableSavedStateMap
|
||||||
import com.bumble.appyx.navmodel.backstack.BackStack
|
import com.bumble.appyx.navmodel.backstack.BackStack
|
||||||
|
|
@ -46,12 +42,12 @@ import io.element.android.features.signedout.api.SignedOutEntryPoint
|
||||||
import io.element.android.libraries.accountselect.api.AccountSelectEntryPoint
|
import io.element.android.libraries.accountselect.api.AccountSelectEntryPoint
|
||||||
import io.element.android.libraries.architecture.BackstackView
|
import io.element.android.libraries.architecture.BackstackView
|
||||||
import io.element.android.libraries.architecture.BaseFlowNode
|
import io.element.android.libraries.architecture.BaseFlowNode
|
||||||
|
import io.element.android.libraries.architecture.appyx.LoadingNode
|
||||||
import io.element.android.libraries.architecture.appyx.rememberDelegateTransitionHandler
|
import io.element.android.libraries.architecture.appyx.rememberDelegateTransitionHandler
|
||||||
import io.element.android.libraries.architecture.createNode
|
import io.element.android.libraries.architecture.createNode
|
||||||
import io.element.android.libraries.architecture.waitForChildAttached
|
import io.element.android.libraries.architecture.waitForChildAttached
|
||||||
import io.element.android.libraries.core.uri.ensureProtocol
|
import io.element.android.libraries.core.uri.ensureProtocol
|
||||||
import io.element.android.libraries.deeplink.api.DeeplinkData
|
import io.element.android.libraries.deeplink.api.DeeplinkData
|
||||||
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
|
||||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
|
@ -219,9 +215,10 @@ import timber.log.Timber
|
||||||
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
||||||
return when (navTarget) {
|
return when (navTarget) {
|
||||||
is NavTarget.LoggedInFlow -> {
|
is NavTarget.LoggedInFlow -> {
|
||||||
val matrixClient = matrixSessionCache.getOrNull(navTarget.sessionId) ?: return splashNode(buildContext).also {
|
val matrixClient = matrixSessionCache.getOrNull(navTarget.sessionId)
|
||||||
Timber.w("Couldn't find any session, go through SplashScreen")
|
?: return createNode<LoadingNode>(buildContext).also {
|
||||||
}
|
Timber.w("Couldn't find any session, go through SplashScreen")
|
||||||
|
}
|
||||||
val inputs = LoggedInAppScopeFlowNode.Inputs(matrixClient)
|
val inputs = LoggedInAppScopeFlowNode.Inputs(matrixClient)
|
||||||
val callback = object : LoggedInAppScopeFlowNode.Callback {
|
val callback = object : LoggedInAppScopeFlowNode.Callback {
|
||||||
override fun onOpenBugReport() {
|
override fun onOpenBugReport() {
|
||||||
|
|
@ -252,7 +249,7 @@ import timber.log.Timber
|
||||||
)
|
)
|
||||||
).build()
|
).build()
|
||||||
}
|
}
|
||||||
NavTarget.SplashScreen -> splashNode(buildContext)
|
NavTarget.SplashScreen -> createNode<LoadingNode>(buildContext)
|
||||||
NavTarget.BugReport -> {
|
NavTarget.BugReport -> {
|
||||||
val callback = object : BugReportEntryPoint.Callback {
|
val callback = object : BugReportEntryPoint.Callback {
|
||||||
override fun onDone() {
|
override fun onDone() {
|
||||||
|
|
@ -289,12 +286,6 @@ import timber.log.Timber
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun splashNode(buildContext: BuildContext) = node(buildContext) {
|
|
||||||
Box(modifier = it.fillMaxSize(), contentAlignment = Alignment.Center) {
|
|
||||||
CircularProgressIndicator()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun handleIntent(intent: Intent) {
|
suspend fun handleIntent(intent: Intent) {
|
||||||
val resolvedIntent = intentResolver.resolve(intent) ?: return
|
val resolvedIntent = intentResolver.resolve(intent) ?: return
|
||||||
when (resolvedIntent) {
|
when (resolvedIntent) {
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,7 @@
|
||||||
package io.element.android.features.ftue.impl
|
package io.element.android.features.ftue.impl
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.bumble.appyx.core.modality.BuildContext
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
|
@ -20,7 +17,6 @@ import com.bumble.appyx.core.plugin.Plugin
|
||||||
import com.bumble.appyx.navmodel.backstack.BackStack
|
import com.bumble.appyx.navmodel.backstack.BackStack
|
||||||
import com.bumble.appyx.navmodel.backstack.operation.newRoot
|
import com.bumble.appyx.navmodel.backstack.operation.newRoot
|
||||||
import com.bumble.appyx.navmodel.backstack.operation.replace
|
import com.bumble.appyx.navmodel.backstack.operation.replace
|
||||||
import dev.zacsweers.metro.AppScope
|
|
||||||
import dev.zacsweers.metro.Assisted
|
import dev.zacsweers.metro.Assisted
|
||||||
import dev.zacsweers.metro.AssistedInject
|
import dev.zacsweers.metro.AssistedInject
|
||||||
import io.element.android.annotations.ContributesNode
|
import io.element.android.annotations.ContributesNode
|
||||||
|
|
@ -33,8 +29,8 @@ import io.element.android.features.ftue.impl.state.InternalFtueState
|
||||||
import io.element.android.features.lockscreen.api.LockScreenEntryPoint
|
import io.element.android.features.lockscreen.api.LockScreenEntryPoint
|
||||||
import io.element.android.libraries.architecture.BackstackView
|
import io.element.android.libraries.architecture.BackstackView
|
||||||
import io.element.android.libraries.architecture.BaseFlowNode
|
import io.element.android.libraries.architecture.BaseFlowNode
|
||||||
|
import io.element.android.libraries.architecture.appyx.LoadingNode
|
||||||
import io.element.android.libraries.architecture.createNode
|
import io.element.android.libraries.architecture.createNode
|
||||||
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
|
||||||
import io.element.android.libraries.di.SessionScope
|
import io.element.android.libraries.di.SessionScope
|
||||||
import kotlinx.coroutines.flow.filterIsInstance
|
import kotlinx.coroutines.flow.filterIsInstance
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
|
@ -87,7 +83,7 @@ class FtueFlowNode(
|
||||||
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
||||||
return when (navTarget) {
|
return when (navTarget) {
|
||||||
NavTarget.Placeholder -> {
|
NavTarget.Placeholder -> {
|
||||||
createNode<PlaceholderNode>(buildContext)
|
createNode<LoadingNode>(buildContext)
|
||||||
}
|
}
|
||||||
is NavTarget.SessionVerification -> {
|
is NavTarget.SessionVerification -> {
|
||||||
val callback = object : FtueSessionVerificationFlowNode.Callback {
|
val callback = object : FtueSessionVerificationFlowNode.Callback {
|
||||||
|
|
@ -146,17 +142,3 @@ class FtueFlowNode(
|
||||||
BackstackView()
|
BackstackView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ContributesNode(AppScope::class)
|
|
||||||
@AssistedInject
|
|
||||||
class PlaceholderNode(
|
|
||||||
@Assisted buildContext: BuildContext,
|
|
||||||
@Assisted plugins: List<Plugin>,
|
|
||||||
) : Node(buildContext, plugins = plugins) {
|
|
||||||
@Composable
|
|
||||||
override fun View(modifier: Modifier) {
|
|
||||||
Box(modifier = modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
|
||||||
CircularProgressIndicator()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import androidx.lifecycle.lifecycleScope
|
||||||
import com.bumble.appyx.core.lifecycle.subscribe
|
import com.bumble.appyx.core.lifecycle.subscribe
|
||||||
import com.bumble.appyx.core.modality.BuildContext
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
import com.bumble.appyx.core.node.Node
|
import com.bumble.appyx.core.node.Node
|
||||||
import com.bumble.appyx.core.node.node
|
|
||||||
import com.bumble.appyx.core.plugin.Plugin
|
import com.bumble.appyx.core.plugin.Plugin
|
||||||
import com.bumble.appyx.navmodel.backstack.BackStack
|
import com.bumble.appyx.navmodel.backstack.BackStack
|
||||||
import com.bumble.appyx.navmodel.backstack.operation.newRoot
|
import com.bumble.appyx.navmodel.backstack.operation.newRoot
|
||||||
|
|
@ -28,6 +27,7 @@ import io.element.android.features.lockscreen.impl.setup.pin.SetupPinNode
|
||||||
import io.element.android.features.lockscreen.impl.unlock.PinUnlockNode
|
import io.element.android.features.lockscreen.impl.unlock.PinUnlockNode
|
||||||
import io.element.android.libraries.architecture.BackstackView
|
import io.element.android.libraries.architecture.BackstackView
|
||||||
import io.element.android.libraries.architecture.BaseFlowNode
|
import io.element.android.libraries.architecture.BaseFlowNode
|
||||||
|
import io.element.android.libraries.architecture.appyx.LoadingNode
|
||||||
import io.element.android.libraries.architecture.createNode
|
import io.element.android.libraries.architecture.createNode
|
||||||
import io.element.android.libraries.di.SessionScope
|
import io.element.android.libraries.di.SessionScope
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
|
|
@ -42,7 +42,7 @@ class LockScreenSettingsFlowNode(
|
||||||
private val pinCodeManager: PinCodeManager,
|
private val pinCodeManager: PinCodeManager,
|
||||||
) : BaseFlowNode<LockScreenSettingsFlowNode.NavTarget>(
|
) : BaseFlowNode<LockScreenSettingsFlowNode.NavTarget>(
|
||||||
backstack = BackStack(
|
backstack = BackStack(
|
||||||
initialElement = NavTarget.Unknown,
|
initialElement = NavTarget.Loading,
|
||||||
savedStateMap = buildContext.savedStateMap,
|
savedStateMap = buildContext.savedStateMap,
|
||||||
),
|
),
|
||||||
buildContext = buildContext,
|
buildContext = buildContext,
|
||||||
|
|
@ -50,7 +50,7 @@ class LockScreenSettingsFlowNode(
|
||||||
) {
|
) {
|
||||||
sealed interface NavTarget : Parcelable {
|
sealed interface NavTarget : Parcelable {
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data object Unknown : NavTarget
|
data object Loading : NavTarget
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data object Unlock : NavTarget
|
data object Unlock : NavTarget
|
||||||
|
|
@ -94,6 +94,9 @@ class LockScreenSettingsFlowNode(
|
||||||
|
|
||||||
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
||||||
return when (navTarget) {
|
return when (navTarget) {
|
||||||
|
NavTarget.Loading -> {
|
||||||
|
createNode<LoadingNode>(buildContext)
|
||||||
|
}
|
||||||
NavTarget.Unlock -> {
|
NavTarget.Unlock -> {
|
||||||
val callback = object : PinUnlockNode.Callback {
|
val callback = object : PinUnlockNode.Callback {
|
||||||
override fun onUnlock() {
|
override fun onUnlock() {
|
||||||
|
|
@ -113,7 +116,6 @@ class LockScreenSettingsFlowNode(
|
||||||
}
|
}
|
||||||
createNode<LockScreenSettingsNode>(buildContext, plugins = listOf(callback))
|
createNode<LockScreenSettingsNode>(buildContext, plugins = listOf(callback))
|
||||||
}
|
}
|
||||||
NavTarget.Unknown -> node(buildContext) { }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ dependencies {
|
||||||
api(libs.appyx.core)
|
api(libs.appyx.core)
|
||||||
api(libs.androidx.lifecycle.runtime)
|
api(libs.androidx.lifecycle.runtime)
|
||||||
api(libs.molecule.runtime)
|
api(libs.molecule.runtime)
|
||||||
|
implementation(projects.libraries.designsystem)
|
||||||
|
|
||||||
testCommonDependencies(libs)
|
testCommonDependencies(libs)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||||
|
* Please see LICENSE files in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.architecture.appyx
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.bumble.appyx.core.node.Node
|
||||||
|
import com.bumble.appyx.core.plugin.Plugin
|
||||||
|
import dev.zacsweers.metro.AppScope
|
||||||
|
import dev.zacsweers.metro.Assisted
|
||||||
|
import dev.zacsweers.metro.AssistedInject
|
||||||
|
import io.element.android.annotations.ContributesNode
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
||||||
|
|
||||||
|
@ContributesNode(AppScope::class)
|
||||||
|
@AssistedInject
|
||||||
|
class LoadingNode(
|
||||||
|
@Assisted buildContext: BuildContext,
|
||||||
|
@Assisted plugins: List<Plugin>,
|
||||||
|
) : Node(buildContext, plugins = plugins) {
|
||||||
|
@Composable
|
||||||
|
override fun View(modifier: Modifier) {
|
||||||
|
Box(modifier = modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||||
|
CircularProgressIndicator()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue