Skip to content

Commit

Permalink
Merge branch 'CORE/refactor/improve-composable-handling' into 'main'
Browse files Browse the repository at this point in the history
FCAN-1853 | ComposableFor methods now do a better job restricting implementations

See merge request veepee/offerdiscovery/products/front-mobile/android/link-router!28
  • Loading branch information
Julio Cesar Bueno Cotta committed May 30, 2023
2 parents 6d4e233 + 9fce243 commit 8a11846
Show file tree
Hide file tree
Showing 13 changed files with 54 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import androidx.compose.ui.Modifier
import com.veepee.routes.feature_b.ComposableBNames
import com.veepee.routes.feature_b.FeatureBComposableEvent
import com.veepee.routes.feature_b.FeatureBComposableLink
import com.veepee.vpcore.route.link.compose.ComposableEvent
import com.veepee.vpcore.route.link.compose.ComposableLink
import com.veepee.vpcore.route.link.compose.ComposableNameMapper
import com.veepee.vpcore.route.link.compose.events.LocalLinkRouterEventHandler
Expand All @@ -33,15 +34,15 @@ object FeatureBComposableNameMapper : ComposableNameMapper<ComposableBNames> {

@Composable
override fun Map(
composableLink: ComposableLink<ComposableBNames>,
link: ComposableLink<ComposableBNames, ComposableEvent>,
modifier: Modifier
) {
val handler = LocalLinkRouterEventHandler.current
when (composableLink) {
when (link) {
is FeatureBComposableLink -> BasicText(
composableLink.parameter.message,
link.parameter.message,
modifier.clickable {
handler.publish(FeatureBComposableEvent(composableLink.parameter.message.length))
handler.publish(FeatureBComposableEvent(link.parameter.message.length))
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
package com.veepee.routes.feature_b

import com.veepee.vpcore.route.link.compose.ComposableEvent
import com.veepee.vpcore.route.link.compose.ComposableLinkWithEvent
import com.veepee.vpcore.route.link.compose.ComposableLink
import com.veepee.vpcore.route.link.compose.ComposableName
import com.veepee.vpcore.route.link.compose.ComposableParameter

Expand All @@ -26,7 +26,7 @@ enum class ComposableBNames : ComposableName {

data class FeatureBComposableLink(
override val parameter: FeatureBComposableParameter
) : ComposableLinkWithEvent<ComposableBNames, FeatureBComposableEvent> {
) : ComposableLink<ComposableBNames, FeatureBComposableEvent> {
override val composableName: ComposableBNames = ComposableBNames.ComposableB

constructor(message: String) : this(FeatureBComposableParameter(message))
Expand Down
8 changes: 8 additions & 0 deletions changelog/next/CORE_improve-composable-handling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: ComposableFor methods now do a better job restricting implementations
url: https://jira.vptech.eu/browse/FCAN-1853
author: Julio Cesar Bueno Cotta
---
ComposableFor methods now do a better job restricting implementations that require a ComposableEvent to be used with the version that does not expose a lambda.

A ComposableLink now needs to specify a `ComposableEvent` in it's declaration, if it does not emit any value, we should use `NoComposableEvent` as part of the declaration, this will make the signature match the `ComposableFor` implementation without the event lambda.
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ import com.veepee.vpcore.route.link.Event
import com.veepee.vpcore.route.link.Link
import com.veepee.vpcore.route.link.Parameter

interface ComposableLinkWithEvent<out T : ComposableName, R : ComposableEvent> : ComposableLink<T>
interface ComposableLink<out T : ComposableName> : Link {
interface ComposableLink<out T : ComposableName, out R : ComposableEvent> : Link {
val composableName: T
override val parameter: ComposableParameter?
}
Expand All @@ -29,4 +28,4 @@ interface ComposableParameter : Parameter

interface ComposableEvent : Event

object NoEvent : ComposableEvent
object NoComposableEvent : ComposableEvent
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ import com.veepee.vpcore.route.link.interceptor.ChainFactoryImpl
interface ComposableLinkRouter {

@Composable
fun ComposeFor(composableLink: ComposableLink<ComposableName>, modifier: Modifier)
fun ComposeFor(link: ComposableLink<ComposableName, ComposableEvent>, modifier: Modifier)

@Composable
fun ComposeFor(composableLink: ComposableLink<ComposableName>)
fun ComposeFor(link: ComposableLink<ComposableName, ComposableEvent>)

interface Builder {
fun add(composableLinkInterceptor: ComposableLinkInterceptor): Builder
Expand Down Expand Up @@ -70,7 +70,7 @@ class ComposeLinkRouterBuilder(
@Suppress("UNCHECKED_CAST")
internal class ComposableLinkRouterImpl(
composableNameMappers: Set<ComposableNameMapper<out ComposableName>>,
private val chainFactory: ChainFactory<ComposableNameMapper<out ComposableName>, ComposableLink<ComposableName>>
private val chainFactory: ChainFactory<ComposableNameMapper<out ComposableName>, ComposableLink<ComposableName, ComposableEvent>>
) : ComposableLinkRouter {

private val composableLinkMapper =
Expand All @@ -81,19 +81,19 @@ internal class ComposableLinkRouterImpl(
}.toMap()

@Composable
override fun ComposeFor(composableLink: ComposableLink<ComposableName>) {
ComposeFor(composableLink = composableLink, modifier = Modifier)
override fun ComposeFor(link: ComposableLink<ComposableName, ComposableEvent>) {
ComposeFor(link = link, modifier = Modifier)
}

@Composable
override fun ComposeFor(composableLink: ComposableLink<ComposableName>, modifier: Modifier) {
override fun ComposeFor(link: ComposableLink<ComposableName, ComposableEvent>, modifier: Modifier) {
val chain = chainFactory.create()
val mapper = composableLinkMapper[composableLink.composableName]
?: throw NoComposableNameMapperException(composableLink)
val newComposableLink = chain.next(mapper, composableLink)
if (newComposableLink != composableLink) {
val mapper = composableLinkMapper[link.composableName]
?: throw NoComposableNameMapperException(link)
val newComposableLink = chain.next(mapper, link)
if (newComposableLink != link) {
return ComposeFor(newComposableLink, modifier)
}
mapper.Map(composableLink, modifier)
mapper.Map(link, modifier)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ interface ComposableNameMapper<T : ComposableName> {
val supportedNames: Array<T>

@Composable
fun Map(composableLink: ComposableLink<T>, modifier: Modifier)
fun Map(link: ComposableLink<T, ComposableEvent>, modifier: Modifier)
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,20 @@ fun ComposableLinkRouterContainer(
}

@Composable
fun ComposableFor(link: ComposableLink<ComposableName>, modifier: Modifier = Modifier) {
LocalComposableLinkRouter.current.ComposeFor(composableLink = link, modifier)
fun ComposableFor(link: ComposableLink<ComposableName, NoComposableEvent>, modifier: Modifier = Modifier) {
ComposableFor(link = link, modifier) {}
}

@Composable
inline fun <reified Event : ComposableEvent> ComposableFor(
link: ComposableLinkWithEvent<ComposableName, Event>,
link: ComposableLink<ComposableName, Event>,
modifier: Modifier = Modifier,
noinline onEvent: (Event) -> Unit
) {
LinkRouterEventHandlerContainer(onEvent = onEvent) {
ComposableFor(link = link, modifier = modifier)
}
LinkRouterEventHandlerContainer(
onEvent = onEvent,
content = {
LocalComposableLinkRouter.current.ComposeFor(link = link, modifier)
}
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
*/
package com.veepee.vpcore.route.link.compose

internal class NoComposableNameMapperException(composableLink: ComposableLink<ComposableName>) :
internal class NoComposableNameMapperException(composableLink: ComposableLink<ComposableName, out ComposableEvent>) :
IllegalArgumentException("$composableLink has no registered ComposableNameMapper registered for it.")
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
*/
package com.veepee.vpcore.route.link.compose.chain

import com.veepee.vpcore.route.link.compose.ComposableEvent
import com.veepee.vpcore.route.link.compose.ComposableLink
import com.veepee.vpcore.route.link.compose.ComposableName
import com.veepee.vpcore.route.link.compose.ComposableNameMapper
import com.veepee.vpcore.route.link.interceptor.LinkInterceptor

interface ComposableLinkInterceptor :
LinkInterceptor<ComposableNameMapper<out ComposableName>, ComposableLink<ComposableName>>
LinkInterceptor<ComposableNameMapper<out ComposableName>, ComposableLink<ComposableName, out ComposableEvent>>
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.veepee.vpcore.route.composable.feature.TestComposablesNameMapper
import com.veepee.vpcore.route.composable.route.TestComposableALink
import com.veepee.vpcore.route.composable.route.TestComposableBLink
import com.veepee.vpcore.route.composable.route.TestComposableBParameter
import com.veepee.vpcore.route.link.compose.ComposableEvent
import com.veepee.vpcore.route.link.compose.ComposableFor
import com.veepee.vpcore.route.link.compose.ComposableLink
import com.veepee.vpcore.route.link.compose.ComposableLinkRouterContainer
Expand Down Expand Up @@ -113,10 +114,10 @@ class ComposableLinkRouterTest {
mappers,
ChainFactoryImpl(listOf(object : ComposableLinkInterceptor {
override fun intercept(
chain: Chain<ComposableNameMapper<out ComposableName>, ComposableLink<ComposableName>>,
chain: Chain<ComposableNameMapper<out ComposableName>, ComposableLink<ComposableName, ComposableEvent>>,
mapper: ComposableNameMapper<out ComposableName>,
link: ComposableLink<ComposableName>
): ComposableLink<ComposableName> {
link: ComposableLink<ComposableName, ComposableEvent>
): ComposableLink<ComposableName, ComposableEvent> {
if (link is TestComposableBLink) {
return TestComposableALink()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.veepee.vpcore.route.composable.route.TestComposableALink
import com.veepee.vpcore.route.composable.route.TestComposableBLink
import com.veepee.vpcore.route.composable.route.TestComposableBLinkEvent
import com.veepee.vpcore.route.composable.route.TestComposableName
import com.veepee.vpcore.route.link.compose.ComposableEvent
import com.veepee.vpcore.route.link.compose.ComposableLink
import com.veepee.vpcore.route.link.compose.ComposableNameMapper
import com.veepee.vpcore.route.link.compose.events.LocalLinkRouterEventHandler
Expand All @@ -30,12 +31,12 @@ object TestComposablesNameMapper : ComposableNameMapper<TestComposableName> {
override val supportedNames: Array<TestComposableName> = TestComposableName.values()

@Composable
override fun Map(composableLink: ComposableLink<TestComposableName>, modifier: Modifier) {
override fun Map(link: ComposableLink<TestComposableName, ComposableEvent>, modifier: Modifier) {
val handler = LocalLinkRouterEventHandler.current
when (composableLink) {
when (link) {
is TestComposableALink -> TestComposableA(modifier = modifier)
is TestComposableBLink -> TestComposableB(
composableLink.parameter.message,
link.parameter.message,
modifier = modifier.clickable {
handler.publish(TestComposableBLinkEvent("bar"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
*/
package com.veepee.vpcore.route.composable.route

import com.veepee.vpcore.route.link.compose.ComposableLinkWithEvent
import com.veepee.vpcore.route.link.compose.ComposableLink
import com.veepee.vpcore.route.link.compose.ComposableParameter
import com.veepee.vpcore.route.link.compose.NoEvent
import com.veepee.vpcore.route.link.compose.NoComposableEvent

class TestComposableALink : ComposableLinkWithEvent<TestComposableName, NoEvent> {
class TestComposableALink : ComposableLink<TestComposableName, NoComposableEvent> {
override val composableName: TestComposableName = TestComposableName.TestComposableA
override val parameter: ComposableParameter? = null
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
package com.veepee.vpcore.route.composable.route

import com.veepee.vpcore.route.link.compose.ComposableEvent
import com.veepee.vpcore.route.link.compose.ComposableLinkWithEvent
import com.veepee.vpcore.route.link.compose.ComposableLink
import com.veepee.vpcore.route.link.compose.ComposableParameter

class TestComposableBLink(
override val parameter: TestComposableBParameter
) : ComposableLinkWithEvent<TestComposableName, TestComposableBLinkEvent> {
) : ComposableLink<TestComposableName, TestComposableBLinkEvent> {
override val composableName: TestComposableName = TestComposableName.TestComposableB
}

Expand Down

0 comments on commit 8a11846

Please sign in to comment.