Cleanup nodes (#5358)
* Remove unused NavTarget.Empty * Let SpaceEntryPoint.Inputs implement NodeInputs. * Small cleanup * Small cleanup * Method can be private. * Simplify code * Rename to follow naming convention * Rename Node to follow naming convention * Add Konsist test. * Remove useless line of code.
This commit is contained in:
commit
fecb8cb0be
13 changed files with 42 additions and 50 deletions
|
|
@ -37,16 +37,7 @@ class ChangeRolesNode(
|
||||||
) : NodeInputs
|
) : NodeInputs
|
||||||
|
|
||||||
private val inputs: Inputs = inputs()
|
private val inputs: Inputs = inputs()
|
||||||
|
private val presenter = presenterFactory.create(inputs.listType.toRoomMemberRole())
|
||||||
private val presenter = presenterFactory.run {
|
|
||||||
val role = when (inputs.listType) {
|
|
||||||
ChangeRoomMemberRolesListType.Admins -> RoomMember.Role.Admin
|
|
||||||
ChangeRoomMemberRolesListType.Moderators -> RoomMember.Role.Moderator
|
|
||||||
ChangeRoomMemberRolesListType.SelectNewOwnersWhenLeaving -> RoomMember.Role.Owner(isCreator = false)
|
|
||||||
}
|
|
||||||
create(role)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val stateFlow = launchMolecule { presenter.present() }
|
private val stateFlow = launchMolecule { presenter.present() }
|
||||||
|
|
||||||
suspend fun waitForRoleChanged() {
|
suspend fun waitForRoleChanged() {
|
||||||
|
|
@ -63,3 +54,9 @@ class ChangeRolesNode(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ChangeRoomMemberRolesListType.toRoomMemberRole() = when (this) {
|
||||||
|
ChangeRoomMemberRolesListType.Admins -> RoomMember.Role.Admin
|
||||||
|
ChangeRoomMemberRolesListType.Moderators -> RoomMember.Role.Moderator
|
||||||
|
ChangeRoomMemberRolesListType.SelectNewOwnersWhenLeaving -> RoomMember.Role.Owner(isCreator = false)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,16 +39,13 @@ class ChangeRoomMemberRolesRootNode(
|
||||||
roomComponentFactory: RoomComponentFactory,
|
roomComponentFactory: RoomComponentFactory,
|
||||||
) : ParentNode<ChangeRoomMemberRolesRootNode.NavTarget>(
|
) : ParentNode<ChangeRoomMemberRolesRootNode.NavTarget>(
|
||||||
navModel = PermanentNavModel(
|
navModel = PermanentNavModel(
|
||||||
navTargets = setOf(NavTarget.Root),
|
navTargets = setOf(NavTarget),
|
||||||
savedStateMap = buildContext.savedStateMap,
|
savedStateMap = buildContext.savedStateMap,
|
||||||
),
|
),
|
||||||
buildContext = buildContext,
|
buildContext = buildContext,
|
||||||
plugins = plugins,
|
plugins = plugins,
|
||||||
), DependencyInjectionGraphOwner, ChangeRoomMemberRolesEntryPoint.NodeProxy {
|
), DependencyInjectionGraphOwner, ChangeRoomMemberRolesEntryPoint.NodeProxy {
|
||||||
sealed interface NavTarget : Parcelable {
|
@Parcelize object NavTarget : Parcelable
|
||||||
@Parcelize
|
|
||||||
object Root : NavTarget
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Inputs(
|
data class Inputs(
|
||||||
val joinedRoom: JoinedRoom,
|
val joinedRoom: JoinedRoom,
|
||||||
|
|
@ -60,14 +57,10 @@ class ChangeRoomMemberRolesRootNode(
|
||||||
override val graph = roomComponentFactory.create(inputs.joinedRoom)
|
override val graph = roomComponentFactory.create(inputs.joinedRoom)
|
||||||
|
|
||||||
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
||||||
return when (navTarget) {
|
return createNode<ChangeRolesNode>(
|
||||||
NavTarget.Root -> {
|
buildContext = buildContext,
|
||||||
createNode<ChangeRolesNode>(
|
plugins = listOf(ChangeRolesNode.Inputs(listType = inputs.listType)),
|
||||||
buildContext = buildContext,
|
)
|
||||||
plugins = listOf(ChangeRolesNode.Inputs(listType = inputs.listType)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ class HomeFlowNode(
|
||||||
stateFlow.value.roomListState.eventSink(RoomListEvents.LeaveRoom(roomId, needsConfirmation = false))
|
stateFlow.value.roomListState.eventSink(RoomListEvents.LeaveRoom(roomId, needsConfirmation = false))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun rootNode(buildContext: BuildContext): Node {
|
private fun rootNode(buildContext: BuildContext): Node {
|
||||||
return node(buildContext) { modifier ->
|
return node(buildContext) { modifier ->
|
||||||
val state by stateFlow.collectAsState()
|
val state by stateFlow.collectAsState()
|
||||||
val activity = requireNotNull(LocalActivity.current)
|
val activity = requireNotNull(LocalActivity.current)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,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.core.plugin.plugins
|
import com.bumble.appyx.core.plugin.plugins
|
||||||
import com.bumble.appyx.navmodel.backstack.BackStack
|
import com.bumble.appyx.navmodel.backstack.BackStack
|
||||||
|
|
@ -126,9 +125,6 @@ class MessagesFlowNode(
|
||||||
plugins = plugins
|
plugins = plugins
|
||||||
) {
|
) {
|
||||||
sealed interface NavTarget : Parcelable {
|
sealed interface NavTarget : Parcelable {
|
||||||
@Parcelize
|
|
||||||
data object Empty : NavTarget
|
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class Messages(val focusedEventId: EventId?) : NavTarget
|
data class Messages(val focusedEventId: EventId?) : NavTarget
|
||||||
|
|
||||||
|
|
@ -399,9 +395,6 @@ class MessagesFlowNode(
|
||||||
}
|
}
|
||||||
createNode<PinnedMessagesListNode>(buildContext, plugins = listOf(callback))
|
createNode<PinnedMessagesListNode>(buildContext, plugins = listOf(callback))
|
||||||
}
|
}
|
||||||
NavTarget.Empty -> {
|
|
||||||
node(buildContext) {}
|
|
||||||
}
|
|
||||||
NavTarget.KnockRequestsList -> {
|
NavTarget.KnockRequestsList -> {
|
||||||
knockRequestsListEntryPoint.createNode(this, buildContext)
|
knockRequestsListEntryPoint.createNode(this, buildContext)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,7 @@ class ChangeRoomPermissionsNode(
|
||||||
) : NodeInputs, Parcelable
|
) : NodeInputs, Parcelable
|
||||||
|
|
||||||
private val inputs: Inputs = inputs()
|
private val inputs: Inputs = inputs()
|
||||||
|
private val presenter = presenterFactory.create(inputs.section)
|
||||||
private val presenter = presenterFactory.run {
|
|
||||||
create(inputs.section)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun View(modifier: Modifier) {
|
override fun View(modifier: Modifier) {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ 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.plugin.Plugin
|
import com.bumble.appyx.core.plugin.Plugin
|
||||||
import io.element.android.libraries.architecture.FeatureEntryPoint
|
import io.element.android.libraries.architecture.FeatureEntryPoint
|
||||||
|
import io.element.android.libraries.architecture.NodeInputs
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
|
||||||
interface SpaceEntryPoint : FeatureEntryPoint {
|
interface SpaceEntryPoint : FeatureEntryPoint {
|
||||||
|
|
@ -27,7 +28,7 @@ interface SpaceEntryPoint : FeatureEntryPoint {
|
||||||
|
|
||||||
data class Inputs(
|
data class Inputs(
|
||||||
val roomId: RoomId
|
val roomId: RoomId
|
||||||
) : Plugin
|
) : NodeInputs
|
||||||
|
|
||||||
interface Callback : Plugin {
|
interface Callback : Plugin {
|
||||||
fun onOpenRoom(roomId: RoomId)
|
fun onOpenRoom(roomId: RoomId)
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import dev.zacsweers.metro.Assisted
|
||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Inject
|
||||||
import io.element.android.annotations.ContributesNode
|
import io.element.android.annotations.ContributesNode
|
||||||
import io.element.android.features.space.api.SpaceEntryPoint
|
import io.element.android.features.space.api.SpaceEntryPoint
|
||||||
|
import io.element.android.libraries.architecture.inputs
|
||||||
import io.element.android.libraries.di.SessionScope
|
import io.element.android.libraries.di.SessionScope
|
||||||
|
|
||||||
@ContributesNode(SessionScope::class)
|
@ContributesNode(SessionScope::class)
|
||||||
|
|
@ -25,7 +26,7 @@ class SpaceNode(
|
||||||
@Assisted plugins: List<Plugin>,
|
@Assisted plugins: List<Plugin>,
|
||||||
presenterFactory: SpacePresenter.Factory,
|
presenterFactory: SpacePresenter.Factory,
|
||||||
) : Node(buildContext, plugins = plugins) {
|
) : Node(buildContext, plugins = plugins) {
|
||||||
private val inputs = plugins.filterIsInstance<SpaceEntryPoint.Inputs>().single()
|
private val inputs: SpaceEntryPoint.Inputs = inputs()
|
||||||
private val callback = plugins.filterIsInstance<SpaceEntryPoint.Callback>().single()
|
private val callback = plugins.filterIsInstance<SpaceEntryPoint.Callback>().single()
|
||||||
private val presenter = presenterFactory.create(inputs)
|
private val presenter = presenterFactory.create(inputs)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import dev.zacsweers.metro.AppScope
|
||||||
import dev.zacsweers.metro.ContributesBinding
|
import dev.zacsweers.metro.ContributesBinding
|
||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Inject
|
||||||
import io.element.android.features.viewfolder.api.ViewFolderEntryPoint
|
import io.element.android.features.viewfolder.api.ViewFolderEntryPoint
|
||||||
import io.element.android.features.viewfolder.impl.root.ViewFolderRootNode
|
import io.element.android.features.viewfolder.impl.root.ViewFolderFlowNode
|
||||||
import io.element.android.libraries.architecture.createNode
|
import io.element.android.libraries.architecture.createNode
|
||||||
|
|
||||||
@ContributesBinding(AppScope::class)
|
@ContributesBinding(AppScope::class)
|
||||||
|
|
@ -25,7 +25,7 @@ class DefaultViewFolderEntryPoint : ViewFolderEntryPoint {
|
||||||
|
|
||||||
return object : ViewFolderEntryPoint.NodeBuilder {
|
return object : ViewFolderEntryPoint.NodeBuilder {
|
||||||
override fun params(params: ViewFolderEntryPoint.Params): ViewFolderEntryPoint.NodeBuilder {
|
override fun params(params: ViewFolderEntryPoint.Params): ViewFolderEntryPoint.NodeBuilder {
|
||||||
plugins += ViewFolderRootNode.Inputs(params.rootPath)
|
plugins += ViewFolderFlowNode.Inputs(params.rootPath)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ class DefaultViewFolderEntryPoint : ViewFolderEntryPoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun build(): Node {
|
override fun build(): Node {
|
||||||
return parentNode.createNode<ViewFolderRootNode>(buildContext, plugins)
|
return parentNode.createNode<ViewFolderFlowNode>(buildContext, plugins)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,10 @@ import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@ContributesNode(AppScope::class)
|
@ContributesNode(AppScope::class)
|
||||||
@Inject
|
@Inject
|
||||||
class ViewFolderRootNode(
|
class ViewFolderFlowNode(
|
||||||
@Assisted buildContext: BuildContext,
|
@Assisted buildContext: BuildContext,
|
||||||
@Assisted plugins: List<Plugin>,
|
@Assisted plugins: List<Plugin>,
|
||||||
) : BaseFlowNode<ViewFolderRootNode.NavTarget>(
|
) : BaseFlowNode<ViewFolderFlowNode.NavTarget>(
|
||||||
backstack = BackStack(
|
backstack = BackStack(
|
||||||
initialElement = NavTarget.Root,
|
initialElement = NavTarget.Root,
|
||||||
savedStateMap = buildContext.savedStateMap,
|
savedStateMap = buildContext.savedStateMap,
|
||||||
|
|
@ -287,7 +287,6 @@ class RustMatrixClient(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getRoom(roomId: RoomId): BaseRoom? = withContext(sessionDispatcher) {
|
override suspend fun getRoom(roomId: RoomId): BaseRoom? = withContext(sessionDispatcher) {
|
||||||
innerClient.rooms()
|
|
||||||
roomFactory.getBaseRoom(roomId)
|
roomFactory.getBaseRoom(roomId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import dev.zacsweers.metro.ContributesBinding
|
||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Inject
|
||||||
import io.element.android.libraries.architecture.createNode
|
import io.element.android.libraries.architecture.createNode
|
||||||
import io.element.android.libraries.mediaviewer.api.MediaGalleryEntryPoint
|
import io.element.android.libraries.mediaviewer.api.MediaGalleryEntryPoint
|
||||||
import io.element.android.libraries.mediaviewer.impl.gallery.root.MediaGalleryRootNode
|
import io.element.android.libraries.mediaviewer.impl.gallery.root.MediaGalleryFlowNode
|
||||||
|
|
||||||
@ContributesBinding(AppScope::class)
|
@ContributesBinding(AppScope::class)
|
||||||
@Inject
|
@Inject
|
||||||
|
|
@ -30,7 +30,7 @@ class DefaultMediaGalleryEntryPoint : MediaGalleryEntryPoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun build(): Node {
|
override fun build(): Node {
|
||||||
return parentNode.createNode<MediaGalleryRootNode>(buildContext, plugins)
|
return parentNode.createNode<MediaGalleryFlowNode>(buildContext, plugins)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,11 +41,11 @@ import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@ContributesNode(RoomScope::class)
|
@ContributesNode(RoomScope::class)
|
||||||
@Inject
|
@Inject
|
||||||
class MediaGalleryRootNode(
|
class MediaGalleryFlowNode(
|
||||||
@Assisted buildContext: BuildContext,
|
@Assisted buildContext: BuildContext,
|
||||||
@Assisted plugins: List<Plugin>,
|
@Assisted plugins: List<Plugin>,
|
||||||
private val mediaViewerEntryPoint: MediaViewerEntryPoint
|
private val mediaViewerEntryPoint: MediaViewerEntryPoint
|
||||||
) : BaseFlowNode<MediaGalleryRootNode.NavTarget>(
|
) : BaseFlowNode<MediaGalleryFlowNode.NavTarget>(
|
||||||
backstack = BackStack(
|
backstack = BackStack(
|
||||||
initialElement = NavTarget.Root,
|
initialElement = NavTarget.Root,
|
||||||
savedStateMap = buildContext.savedStateMap,
|
savedStateMap = buildContext.savedStateMap,
|
||||||
|
|
@ -87,11 +87,11 @@ class MediaGalleryRootNode(
|
||||||
NavTarget.Root -> {
|
NavTarget.Root -> {
|
||||||
val callback = object : MediaGalleryNode.Callback {
|
val callback = object : MediaGalleryNode.Callback {
|
||||||
override fun onBackClick() {
|
override fun onBackClick() {
|
||||||
this@MediaGalleryRootNode.onBackClick()
|
this@MediaGalleryFlowNode.onBackClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewInTimeline(eventId: EventId) {
|
override fun onViewInTimeline(eventId: EventId) {
|
||||||
this@MediaGalleryRootNode.onViewInTimeline(eventId)
|
this@MediaGalleryFlowNode.onViewInTimeline(eventId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemClick(item: MediaItem.Event) {
|
override fun onItemClick(item: MediaItem.Event) {
|
||||||
|
|
@ -122,7 +122,7 @@ class MediaGalleryRootNode(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewInTimeline(eventId: EventId) {
|
override fun onViewInTimeline(eventId: EventId) {
|
||||||
this@MediaGalleryRootNode.onViewInTimeline(eventId)
|
this@MediaGalleryFlowNode.onViewInTimeline(eventId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mediaViewerEntryPoint.nodeBuilder(this, buildContext)
|
mediaViewerEntryPoint.nodeBuilder(this, buildContext)
|
||||||
|
|
@ -20,6 +20,7 @@ import com.lemonappdev.konsist.api.ext.list.withoutName
|
||||||
import com.lemonappdev.konsist.api.ext.list.withoutNameStartingWith
|
import com.lemonappdev.konsist.api.ext.list.withoutNameStartingWith
|
||||||
import com.lemonappdev.konsist.api.verify.assertEmpty
|
import com.lemonappdev.konsist.api.verify.assertEmpty
|
||||||
import com.lemonappdev.konsist.api.verify.assertTrue
|
import com.lemonappdev.konsist.api.verify.assertTrue
|
||||||
|
import io.element.android.libraries.architecture.BaseFlowNode
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
@ -44,6 +45,16 @@ class KonsistClassNameTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Classes extending 'BaseFlowNode' should have 'FlowNode' suffix`() {
|
||||||
|
Konsist.scopeFromProject()
|
||||||
|
.classes()
|
||||||
|
.withAllParentsOf(BaseFlowNode::class)
|
||||||
|
.assertTrue {
|
||||||
|
it.name.endsWith("FlowNode")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Classes extending 'PreviewParameterProvider' name MUST end with 'Provider' and MUST contain provided class name`() {
|
fun `Classes extending 'PreviewParameterProvider' name MUST end with 'Provider' and MUST contain provided class name`() {
|
||||||
Konsist.scopeFromProduction()
|
Konsist.scopeFromProduction()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue