First implementation of using Node/Presenter/UI on RoomList (no DI)

This commit is contained in:
ganfra 2023-01-03 19:51:04 +01:00
parent e176a41ecf
commit 1509d82f3f
13 changed files with 326 additions and 230 deletions

View file

@ -41,7 +41,7 @@ class MainActivity : NodeComponentActivity(), DaggerComponentOwner {
NodeHost(integrationPoint = appyxIntegrationPoint) {
RootFlowNode(
buildContext = it,
daggerComponentOwner = this,
appComponentOwner = this,
matrix = appBindings.matrix(),
sessionComponentsOwner = appBindings.sessionComponentsOwner()
)

View file

@ -4,6 +4,7 @@ import android.os.Parcelable
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.bumble.appyx.core.composable.Children
import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode
@ -12,14 +13,18 @@ import com.bumble.appyx.navmodel.backstack.operation.pop
import com.bumble.appyx.navmodel.backstack.operation.push
import io.element.android.x.core.di.viewModelSupportNode
import io.element.android.x.features.messages.MessagesScreen
import io.element.android.x.features.roomlist.RoomListScreen
import io.element.android.x.features.roomlist.RoomListNode
import io.element.android.x.features.roomlist.RoomListPresenter
import io.element.android.x.matrix.MatrixClient
import io.element.android.x.matrix.core.RoomId
import io.element.android.x.matrix.core.SessionId
import kotlinx.parcelize.Parcelize
import timber.log.Timber
class LoggedInFlowNode(
buildContext: BuildContext,
val sessionId: SessionId,
private val matrixClient: MatrixClient,
private val backstack: BackStack<NavTarget> = BackStack(
initialElement = NavTarget.RoomList,
savedStateMap = buildContext.savedStateMap,
@ -29,6 +34,13 @@ class LoggedInFlowNode(
buildContext = buildContext
) {
init {
lifecycle.subscribe(
onCreate = { Timber.v("OnCreate") },
onDestroy = { Timber.v("OnDestroy") }
)
}
sealed interface NavTarget : Parcelable {
@Parcelize
object RoomList : NavTarget
@ -39,11 +51,12 @@ class LoggedInFlowNode(
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
return when (navTarget) {
NavTarget.RoomList -> viewModelSupportNode(buildContext) {
RoomListScreen(
onRoomClicked = { backstack.push(NavTarget.Messages(it)) }
)
}
NavTarget.RoomList -> RoomListNode(
buildContext = buildContext,
presenter = RoomListPresenter(matrixClient),
onRoomClicked = {
backstack.push(NavTarget.Messages(it))
})
is NavTarget.Messages -> viewModelSupportNode(buildContext) {
MessagesScreen(
roomId = navTarget.roomId.value,

View file

@ -4,6 +4,7 @@ import android.os.Parcelable
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.bumble.appyx.core.composable.Children
import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode
@ -13,6 +14,7 @@ import io.element.android.x.core.di.viewModelSupportNode
import io.element.android.x.features.login.node.LoginFlowNode
import io.element.android.x.features.onboarding.OnBoardingScreen
import kotlinx.parcelize.Parcelize
import timber.log.Timber
class NotLoggedInFlowNode(
buildContext: BuildContext,
@ -25,6 +27,13 @@ class NotLoggedInFlowNode(
buildContext = buildContext
) {
init {
lifecycle.subscribe(
onCreate = { Timber.v("OnCreate") },
onDestroy = { Timber.v("OnDestroy") }
)
}
sealed interface NavTarget : Parcelable {
@Parcelize
object OnBoarding : NavTarget

View file

@ -25,6 +25,7 @@ import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.node.node
import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.newRoot
import com.bumble.appyx.navmodel.backstack.operation.replace
import io.element.android.x.BuildConfig
import io.element.android.x.component.ShowkaseButton
@ -61,7 +62,7 @@ class RootFlowNode(
initialElement = NavTarget.SplashScreen,
savedStateMap = buildContext.savedStateMap,
),
private val daggerComponentOwner: DaggerComponentOwner,
private val appComponentOwner: DaggerComponentOwner,
private val matrix: Matrix,
private val sessionComponentsOwner: SessionComponentsOwner,
) :
@ -71,23 +72,32 @@ class RootFlowNode(
plugins = listOf(SessionComponentsOwnerInteractor(sessionComponentsOwner)),
),
DaggerComponentOwner by daggerComponentOwner {
DaggerComponentOwner by appComponentOwner {
init {
Timber.v("Init")
lifecycle.subscribe(
onCreate = { Timber.v("OnCreate") },
onDestroy = { Timber.v("OnDestroy") }
)
}
init {
matrix.isLoggedIn()
.distinctUntilChanged()
.onEach { isLoggedIn ->
Timber.v("IsLoggedIn")
if (isLoggedIn) {
val matrixClient = matrix.restoreSession()
if (matrixClient == null) {
backstack.replace(NavTarget.NotLoggedInFlow)
backstack.newRoot(NavTarget.NotLoggedInFlow)
} else {
matrixClient.startSync()
sessionComponentsOwner.create(matrixClient)
backstack.replace(NavTarget.LoggedInFlow(matrixClient.sessionId))
backstack.newRoot(NavTarget.LoggedInFlow(matrixClient.sessionId))
}
} else {
backstack.replace(NavTarget.NotLoggedInFlow)
backstack.newRoot(NavTarget.NotLoggedInFlow)
}
}
.launchIn(lifecycleScope)
@ -124,7 +134,10 @@ class RootFlowNode(
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
return when (navTarget) {
is NavTarget.LoggedInFlow -> LoggedInFlowNode(buildContext, navTarget.sessionId)
is NavTarget.LoggedInFlow -> {
val matrixClient = sessionComponentsOwner.activeSessionComponent!!.matrixClient()
LoggedInFlowNode(buildContext, navTarget.sessionId, matrixClient)
}
NavTarget.NotLoggedInFlow -> NotLoggedInFlowNode(buildContext)
NavTarget.SplashScreen -> node(buildContext) {
Box(modifier = it.fillMaxSize(), contentAlignment = Alignment.Center) {