[Architecture] Introduce EntryPoint and use createNode for ParentNode too

This commit is contained in:
ganfra 2023-03-02 12:33:18 +01:00
parent 1ec629c304
commit da92113e43
54 changed files with 674 additions and 164 deletions

View file

@ -0,0 +1,21 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.features.login.api
import io.element.android.libraries.architecture.EntryPoint
interface LoginEntryPoint : EntryPoint

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.features.login.implementation
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.features.login.api.LoginEntryPoint
import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope
import javax.inject.Inject
@ContributesBinding(AppScope::class)
class DefaultLoginEntryPoint @Inject constructor() : LoginEntryPoint {
override fun node(parentNode: Node, buildContext: BuildContext, plugins: List<Plugin>): Node {
return parentNode.createNode<LoginFlowNode>(buildContext, plugins)
}
}

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login
package io.element.android.features.login.implementation
import android.os.Parcelable
import androidx.compose.runtime.Composable
@ -23,30 +23,39 @@ import com.bumble.appyx.core.composable.Children
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.push
import io.element.android.features.login.changeserver.ChangeServerNode
import io.element.android.features.login.root.LoginRootNode
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.login.implementation.changeserver.ChangeServerNode
import io.element.android.features.login.implementation.root.LoginRootNode
import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler
import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope
import kotlinx.parcelize.Parcelize
@ContributesNode(AppScope::class)
class LoginFlowNode(
buildContext: BuildContext,
private val backstack: BackStack<NavTarget> = BackStack(
initialElement = NavTarget.Root,
savedStateMap = buildContext.savedStateMap,
),
plugins: List<Plugin>,
private val backstack: BackStack<NavTarget>,
) : ParentNode<LoginFlowNode.NavTarget>(
navModel = backstack,
buildContext = buildContext
buildContext = buildContext,
plugins = plugins,
) {
private val loginRootCallback = object : LoginRootNode.Callback {
override fun onChangeHomeServer() {
backstack.push(NavTarget.ChangeServer)
}
}
@AssistedInject
constructor(@Assisted buildContext: BuildContext, @Assisted plugins: List<Plugin>) : this(
buildContext = buildContext,
plugins = plugins,
backstack = BackStack(
initialElement = NavTarget.Root,
savedStateMap = buildContext.savedStateMap,
),
)
sealed interface NavTarget : Parcelable {
@Parcelize
@ -58,7 +67,14 @@ class LoginFlowNode(
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
return when (navTarget) {
NavTarget.Root -> createNode<LoginRootNode>(buildContext, plugins = listOf(loginRootCallback))
NavTarget.Root -> {
val callback = object : LoginRootNode.Callback {
override fun onChangeHomeServer() {
backstack.push(NavTarget.ChangeServer)
}
}
createNode<LoginRootNode>(buildContext, plugins = listOf(callback))
}
NavTarget.ChangeServer -> createNode<ChangeServerNode>(buildContext)
}
}

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.changeserver
package io.element.android.features.login.implementation.changeserver
sealed interface ChangeServerEvents {
data class SetServer(val server: String) : ChangeServerEvents

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.changeserver
package io.element.android.features.login.implementation.changeserver
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.changeserver
package io.element.android.features.login.implementation.changeserver
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.changeserver
package io.element.android.features.login.implementation.changeserver
import io.element.android.libraries.architecture.Async

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.changeserver
package io.element.android.features.login.implementation.changeserver
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.architecture.Async

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.changeserver
package io.element.android.features.login.implementation.changeserver
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
@ -46,7 +46,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.element.android.features.login.R
import io.element.android.features.login.error.changeServerError
import io.element.android.features.login.implementation.error.changeServerError
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.designsystem.components.form.textFieldState
import io.element.android.libraries.designsystem.preview.ElementPreviewDark

View file

@ -14,11 +14,11 @@
* limitations under the License.
*/
package io.element.android.features.login.error
package io.element.android.features.login.implementation.error
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import io.element.android.features.login.root.LoginFormState
import io.element.android.features.login.implementation.root.LoginFormState
import io.element.android.libraries.core.uri.isValidUrl
import io.element.android.libraries.ui.strings.R as StringR

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.root
package io.element.android.features.login.implementation.root
sealed interface LoginRootEvents {
object RefreshHomeServer : LoginRootEvents

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.root
package io.element.android.features.login.implementation.root
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.root
package io.element.android.features.login.implementation.root
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.root
package io.element.android.features.login.implementation.root
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -48,7 +48,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.element.android.features.login.error.loginError
import io.element.android.features.login.implementation.error.loginError
import io.element.android.libraries.designsystem.components.form.textFieldState
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.root
package io.element.android.features.login.implementation.root
import android.os.Parcelable
import io.element.android.libraries.matrix.core.SessionId

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.root
package io.element.android.features.login.implementation.root
fun aLoginRootState() = LoginRootState(
homeserver = "",