diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/app/RootActivity.kt b/android/app-example/src/main/java/com/badoo/ribs/example/app/RootActivity.kt index 2f4f91d14..cc443f959 100644 --- a/android/app-example/src/main/java/com/badoo/ribs/example/app/RootActivity.kt +++ b/android/app-example/src/main/java/com/badoo/ribs/example/app/RootActivity.kt @@ -6,6 +6,11 @@ import android.view.ViewGroup import com.badoo.ribs.android.ActivityStarter import com.badoo.ribs.android.PermissionRequester import com.badoo.ribs.android.RibActivity +import com.badoo.ribs.core.routing.action.AttachRibRoutingAction.Companion.attach +import com.badoo.ribs.core.routing.action.RoutingAction +import com.badoo.ribs.core.routing.portal.Portal +import com.badoo.ribs.core.routing.portal.PortalBuilder +import com.badoo.ribs.core.routing.portal.PortalNode import com.badoo.ribs.customisation.RibCustomisationDirectory import com.badoo.ribs.dialog.DialogLauncher import com.badoo.ribs.example.R @@ -16,6 +21,7 @@ import com.badoo.ribs.example.rib.switcher.builder.SwitcherBuilder import com.badoo.ribs.example.util.CoffeeMachine import com.badoo.ribs.example.util.StupidCoffeeMachine import io.reactivex.Observable +import io.reactivex.Single import io.reactivex.functions.BiFunction /** The sample app's single activity */ @@ -29,16 +35,31 @@ class RootActivity : RibActivity() { override val rootViewGroup: ViewGroup get() = findViewById(R.id.root) - private lateinit var workflowRoot: Switcher.Workflow + private lateinit var workflowRoot: Portal.Workflow - override fun createRib(savedInstanceState: Bundle?): SwitcherNode = - SwitcherBuilder( - object : Switcher.Dependency { - override fun ribCustomisation(): RibCustomisationDirectory = AppRibCustomisations - override fun activityStarter(): ActivityStarter = activityStarter - override fun permissionRequester(): PermissionRequester = permissionRequester - override fun dialogLauncher(): DialogLauncher = this@RootActivity - override fun coffeeMachine(): CoffeeMachine = StupidCoffeeMachine() + override fun createRib(savedInstanceState: Bundle?): PortalNode = + PortalBuilder( + object : Portal.Dependency { + override fun defaultRoutingAction(): (Portal.OtherSide) -> RoutingAction = { portal -> + attach { buildSwitcherNode(portal, it) } + } + + private fun buildSwitcherNode(portal: Portal.OtherSide, savedInstanceState: Bundle?): SwitcherNode { + return SwitcherBuilder( + object : Switcher.Dependency { + override fun ribCustomisation(): RibCustomisationDirectory = + AppRibCustomisations + + override fun activityStarter(): ActivityStarter = activityStarter + override fun permissionRequester(): PermissionRequester = + permissionRequester + + override fun dialogLauncher(): DialogLauncher = this@RootActivity + override fun coffeeMachine(): CoffeeMachine = StupidCoffeeMachine() + override fun portal(): Portal.OtherSide = portal + } + ).build(savedInstanceState) + } } ).build(savedInstanceState).also { workflowRoot = it @@ -59,19 +80,19 @@ class RootActivity : RibActivity() { } private fun executeWorkflow1(): Observable<*> = - workflowRoot - .attachHelloWorld() + switcher() + .flatMap { it.attachHelloWorld()} .toObservable() @SuppressWarnings("OptionalUnit") private fun executeWorkflow2(): Observable<*> = Observable.combineLatest( - workflowRoot - .doSomethingAndStayOnThisNode() + switcher() + .flatMap { it.doSomethingAndStayOnThisNode() } .toObservable(), - workflowRoot - .waitForHelloWorld() + switcher() + .flatMap { it.waitForHelloWorld() } .flatMap { it.somethingSomethingDarkSide() } .toObservable(), @@ -79,7 +100,13 @@ class RootActivity : RibActivity() { ) private fun executeTestCrash(): Observable<*> = - (rootNode as Switcher.Workflow) - .testCrash() + switcher() + .flatMap { it.testCrash() } .toObservable() + + @Suppress("UNCHECKED_CAST") + private fun switcher() = + Single + .just(workflowRoot) + .flatMap { it.showDefault() as Single } } diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/Big.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/Big.kt new file mode 100644 index 000000000..6edf1bcac --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/Big.kt @@ -0,0 +1,19 @@ +package com.badoo.ribs.example.rib.big + +import com.badoo.ribs.core.Rib +import com.badoo.ribs.customisation.CanProvidePortal +import com.badoo.ribs.customisation.CanProvideRibCustomisation +import com.badoo.ribs.customisation.RibCustomisation + +interface Big : Rib { + + interface Dependency : + CanProvideRibCustomisation, + CanProvidePortal + + class Customisation( + val viewFactory: BigView.Factory = BigViewImpl.Factory() + ) : RibCustomisation + + interface Workflow +} diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigInteractor.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigInteractor.kt new file mode 100644 index 000000000..a44a0b87b --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigInteractor.kt @@ -0,0 +1,23 @@ +package com.badoo.ribs.example.rib.big + +import android.arch.lifecycle.Lifecycle +import android.os.Bundle +import com.badoo.ribs.core.Interactor +import com.badoo.ribs.core.Router +import com.badoo.ribs.example.rib.big.BigRouter.Configuration +import com.badoo.ribs.example.rib.big.BigRouter.Configuration.Content +import com.badoo.ribs.example.rib.big.BigRouter.Configuration.Overlay + +class BigInteractor( + savedInstanceState: Bundle?, + router: Router +) : Interactor( + savedInstanceState = savedInstanceState, + router = router, + disposables = null +) { + + override fun onViewCreated(view: BigView, viewLifecycle: Lifecycle) { + view.accept(BigView.ViewModel("My id: " + id.replace("${BigInteractor::class.java.name}.", ""))) + } +} diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigNode.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigNode.kt new file mode 100644 index 000000000..e72d9f008 --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigNode.kt @@ -0,0 +1,18 @@ +package com.badoo.ribs.example.rib.big + +import android.os.Bundle +import android.view.ViewGroup +import com.badoo.ribs.core.Node + +class BigNode( + savedInstanceState: Bundle?, + viewFactory: ((ViewGroup) -> BigView?)?, + private val router: BigRouter, + private val interactor: BigInteractor +) : Node( + savedInstanceState = savedInstanceState, + identifier = object : Big {}, + viewFactory = viewFactory, + router = router, + interactor = interactor +), Big.Workflow diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigRouter.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigRouter.kt new file mode 100644 index 000000000..b505216b9 --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigRouter.kt @@ -0,0 +1,39 @@ +package com.badoo.ribs.example.rib.big + +import android.os.Bundle +import android.os.Parcelable +import com.badoo.ribs.core.Router +import com.badoo.ribs.core.routing.action.AttachRibRoutingAction.Companion.attach +import com.badoo.ribs.core.routing.action.RoutingAction +import com.badoo.ribs.core.routing.action.RoutingAction.Companion.noop +import com.badoo.ribs.example.rib.big.BigRouter.Configuration +import com.badoo.ribs.example.rib.big.BigRouter.Configuration.Content +import com.badoo.ribs.example.rib.big.BigRouter.Configuration.Overlay +import com.badoo.ribs.example.rib.big.BigRouter.Configuration.Permanent +import com.badoo.ribs.example.rib.small.builder.SmallBuilder +import kotlinx.android.parcel.Parcelize + +class BigRouter( + savedInstanceState: Bundle?, + private val smallBuilder: SmallBuilder +): Router( + savedInstanceState = savedInstanceState, + initialConfiguration = Content.Default, + permanentParts = listOf(Permanent.Small) +) { + sealed class Configuration : Parcelable { + sealed class Permanent : Configuration() { + @Parcelize object Small : Permanent() + } + sealed class Content : Configuration() { + @Parcelize object Default : Content() + } + sealed class Overlay : Configuration() + } + + override fun resolveConfiguration(configuration: Configuration): RoutingAction = + when (configuration) { + Permanent.Small -> attach { smallBuilder.build(it) } + Content.Default -> noop() + } +} diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigView.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigView.kt new file mode 100644 index 000000000..4d3b7c166 --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigView.kt @@ -0,0 +1,61 @@ +package com.badoo.ribs.example.rib.big + +import android.support.annotation.LayoutRes +import android.view.ViewGroup +import android.widget.TextView +import com.badoo.ribs.core.Rib +import com.badoo.ribs.core.view.RibView +import com.badoo.ribs.core.view.ViewFactory +import com.badoo.ribs.customisation.inflate +import com.badoo.ribs.example.R +import com.badoo.ribs.example.rib.big.BigView.Event +import com.badoo.ribs.example.rib.big.BigView.ViewModel +import com.badoo.ribs.example.rib.small.Small +import com.jakewharton.rxrelay2.PublishRelay +import io.reactivex.ObservableSource +import io.reactivex.functions.Consumer + +interface BigView : RibView, + ObservableSource, + Consumer { + + sealed class Event + + data class ViewModel( + val text: String + ) + + interface Factory : ViewFactory +} + + +class BigViewImpl private constructor( + override val androidView: ViewGroup, + private val events: PublishRelay = PublishRelay.create() +) : BigView, + ObservableSource by events, + Consumer { + + class Factory( + @LayoutRes private val layoutRes: Int = R.layout.rib_big + ) : BigView.Factory { + override fun invoke(deps: Nothing?): (ViewGroup) -> BigView = { + BigViewImpl( + inflate(it, layoutRes) + ) + } + } + + private val idText = androidView.findViewById(R.id.big_id) + private val smallContainer = androidView.findViewById(R.id.small_container) + + override fun accept(vm: ViewModel) { + idText.text = vm.text + } + + override fun getParentViewForChild(child: Rib): ViewGroup? = + when (child) { + is Small -> smallContainer + else -> null + } +} diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigBuilder.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigBuilder.kt new file mode 100644 index 000000000..a2f154d3b --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigBuilder.kt @@ -0,0 +1,27 @@ +package com.badoo.ribs.example.rib.big.builder + +import android.os.Bundle +import com.badoo.ribs.core.Builder +import com.badoo.ribs.customisation.customisationsBranchFor +import com.badoo.ribs.customisation.getOrDefault +import com.badoo.ribs.example.rib.big.Big +import com.badoo.ribs.example.rib.big.BigNode + +class BigBuilder( + dependency: Big.Dependency +) : Builder() { + + override val dependency : Big.Dependency = object : Big.Dependency by dependency { + override fun ribCustomisation() = dependency.customisationsBranchFor(Big::class) + } + + fun build(savedInstanceState: Bundle?): BigNode = + DaggerBigComponent + .factory() + .create( + dependency = dependency, + customisation = dependency.getOrDefault(Big.Customisation()), + savedInstanceState = savedInstanceState + ) + .node() +} diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigComponent.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigComponent.kt new file mode 100644 index 000000000..487af388d --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigComponent.kt @@ -0,0 +1,26 @@ +package com.badoo.ribs.example.rib.big.builder + +import android.os.Bundle +import com.badoo.ribs.example.rib.big.Big +import com.badoo.ribs.example.rib.big.BigNode +import com.badoo.ribs.example.rib.small.Small +import dagger.BindsInstance + +@BigScope +@dagger.Component( + modules = [BigModule::class], + dependencies = [Big.Dependency::class] +) +internal interface BigComponent : Small.Dependency { + + @dagger.Component.Factory + interface Factory { + fun create( + dependency: Big.Dependency, + @BindsInstance customisation: Big.Customisation, + @BindsInstance savedInstanceState: Bundle? + ): BigComponent + } + + fun node(): BigNode +} diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigModule.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigModule.kt new file mode 100644 index 000000000..7720efc1b --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigModule.kt @@ -0,0 +1,54 @@ +@file:SuppressWarnings("LongParameterList", "LongMethod") +package com.badoo.ribs.example.rib.big.builder + +import android.os.Bundle +import com.badoo.ribs.example.rib.big.Big +import com.badoo.ribs.example.rib.big.BigInteractor +import com.badoo.ribs.example.rib.big.BigNode +import com.badoo.ribs.example.rib.big.BigRouter +import com.badoo.ribs.example.rib.small.builder.SmallBuilder +import dagger.Provides + +@dagger.Module +internal object BigModule { + + @BigScope + @Provides + @JvmStatic + internal fun router( + // pass component to child rib builders, or remove if there are none + component: BigComponent, + savedInstanceState: Bundle? + ): BigRouter = + BigRouter( + savedInstanceState = savedInstanceState, + smallBuilder = SmallBuilder(component) + ) + + @BigScope + @Provides + @JvmStatic + internal fun interactor( + savedInstanceState: Bundle?, + router: BigRouter + ): BigInteractor = + BigInteractor( + savedInstanceState = savedInstanceState, + router = router + ) + + @BigScope + @Provides + @JvmStatic + internal fun node( + savedInstanceState: Bundle?, + customisation: Big.Customisation, + router: BigRouter, + interactor: BigInteractor + ) : BigNode = BigNode( + savedInstanceState = savedInstanceState, + viewFactory = customisation.viewFactory(null), + router = router, + interactor = interactor + ) +} diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigScope.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigScope.kt new file mode 100644 index 000000000..ca558f739 --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigScope.kt @@ -0,0 +1,7 @@ +package com.badoo.ribs.example.rib.big.builder + +import javax.inject.Scope + +@Scope +@Retention(AnnotationRetention.RUNTIME) +internal annotation class BigScope diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorld.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorld.kt index 7eba94732..0f96eea71 100644 --- a/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorld.kt +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorld.kt @@ -2,6 +2,7 @@ package com.badoo.ribs.example.rib.hello_world import com.badoo.ribs.android.CanProvideActivityStarter import com.badoo.ribs.core.Rib +import com.badoo.ribs.customisation.CanProvidePortal import com.badoo.ribs.customisation.CanProvideRibCustomisation import com.badoo.ribs.customisation.RibCustomisation import io.reactivex.ObservableSource @@ -10,7 +11,10 @@ import io.reactivex.functions.Consumer interface HelloWorld : Rib { - interface Dependency : CanProvideActivityStarter, CanProvideRibCustomisation { + interface Dependency : + CanProvideActivityStarter, + CanProvideRibCustomisation, + CanProvidePortal { fun helloWorldInput(): ObservableSource fun helloWorldOutput(): Consumer } diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorldInteractor.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorldInteractor.kt index 69f6f6280..5243dac99 100644 --- a/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorldInteractor.kt +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorldInteractor.kt @@ -12,6 +12,8 @@ import com.badoo.ribs.core.Interactor import com.badoo.ribs.core.Router import com.badoo.ribs.example.app.OtherActivity import com.badoo.ribs.example.rib.hello_world.HelloWorldRouter.Configuration +import com.badoo.ribs.example.rib.hello_world.HelloWorldRouter.Configuration.Content +import com.badoo.ribs.example.rib.hello_world.HelloWorldRouter.Configuration.Permanent import com.badoo.ribs.example.rib.hello_world.HelloWorldView.ViewModel import com.badoo.ribs.example.rib.hello_world.analytics.HelloWorldAnalytics import com.badoo.ribs.example.rib.hello_world.feature.HelloWorldFeature @@ -24,12 +26,12 @@ import io.reactivex.functions.Consumer class HelloWorldInteractor( savedInstanceState: Bundle?, - router: Router, + router: Router, private val input: ObservableSource, private val output: Consumer, private val feature: HelloWorldFeature, private val activityStarter: ActivityStarter -) : Interactor( +) : Interactor( savedInstanceState = savedInstanceState, router = router, disposables = feature diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorldRouter.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorldRouter.kt index dd79f2e12..8f286ba85 100644 --- a/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorldRouter.kt +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorldRouter.kt @@ -1,25 +1,37 @@ package com.badoo.ribs.example.rib.hello_world +import android.os.Bundle import android.os.Parcelable import com.badoo.ribs.core.Router +import com.badoo.ribs.core.routing.action.AttachRibRoutingAction.Companion.attach import com.badoo.ribs.core.routing.action.RoutingAction import com.badoo.ribs.core.routing.action.RoutingAction.Companion.noop import com.badoo.ribs.example.rib.hello_world.HelloWorldRouter.Configuration +import com.badoo.ribs.example.rib.hello_world.HelloWorldRouter.Configuration.Content +import com.badoo.ribs.example.rib.hello_world.HelloWorldRouter.Configuration.Permanent +import com.badoo.ribs.example.rib.small.builder.SmallBuilder import kotlinx.android.parcel.Parcelize -import android.os.Bundle class HelloWorldRouter( - savedInstanceState: Bundle? -): Router( + savedInstanceState: Bundle?, + private val smallBuilder: SmallBuilder +): Router( savedInstanceState = savedInstanceState, - initialConfiguration = Configuration.Default + initialConfiguration = Content.Default, + permanentParts = listOf(Permanent.Small) ) { sealed class Configuration : Parcelable { - @Parcelize object Default : Configuration() + sealed class Permanent : Configuration() { + @Parcelize object Small : Permanent() + } + sealed class Content : Configuration() { + @Parcelize object Default : Content() + } } override fun resolveConfiguration(configuration: Configuration): RoutingAction = when (configuration) { - Configuration.Default -> noop() + Permanent.Small -> attach { smallBuilder.build(it) } + Content.Default -> noop() } } diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorldView.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorldView.kt index 111f64b19..4ccd8277b 100644 --- a/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorldView.kt +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/HelloWorldView.kt @@ -3,12 +3,14 @@ package com.badoo.ribs.example.rib.hello_world import android.support.annotation.LayoutRes import android.view.ViewGroup import android.widget.TextView +import com.badoo.ribs.core.Rib import com.badoo.ribs.core.view.RibView import com.badoo.ribs.core.view.ViewFactory import com.badoo.ribs.customisation.inflate import com.badoo.ribs.example.R import com.badoo.ribs.example.rib.hello_world.HelloWorldView.Event import com.badoo.ribs.example.rib.hello_world.HelloWorldView.ViewModel +import com.badoo.ribs.example.rib.small.Small import com.jakewharton.rxrelay2.PublishRelay import io.reactivex.ObservableSource import io.reactivex.functions.Consumer @@ -47,6 +49,7 @@ class HelloWorldViewImpl private constructor( private val text: TextView = androidView.findViewById(R.id.hello_debug) private val launchButton: TextView = androidView.findViewById(R.id.hello_button_launch) + private val smallContainer: ViewGroup = androidView.findViewById(R.id.small_container) init { launchButton.setOnClickListener { events.accept(Event.ButtonClicked) } @@ -55,4 +58,10 @@ class HelloWorldViewImpl private constructor( override fun accept(vm: ViewModel) { text.text = vm.text } + + override fun getParentViewForChild(child: Rib): ViewGroup? = + when (child) { + is Small -> smallContainer + else -> null + } } diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/builder/HelloWorldComponent.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/builder/HelloWorldComponent.kt index 2d351c37e..e33f73237 100644 --- a/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/builder/HelloWorldComponent.kt +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/builder/HelloWorldComponent.kt @@ -3,6 +3,7 @@ package com.badoo.ribs.example.rib.hello_world.builder import android.os.Bundle import com.badoo.ribs.example.rib.hello_world.HelloWorld import com.badoo.ribs.example.rib.hello_world.HelloWorldNode +import com.badoo.ribs.example.rib.small.Small import dagger.BindsInstance @@ -11,7 +12,7 @@ import dagger.BindsInstance modules = [HelloWorldModule::class], dependencies = [HelloWorld.Dependency::class] ) -internal interface HelloWorldComponent { +internal interface HelloWorldComponent : Small.Dependency { @dagger.Component.Factory interface Factory { diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/builder/HelloWorldModule.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/builder/HelloWorldModule.kt index 05c8ca429..44192ef8f 100644 --- a/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/builder/HelloWorldModule.kt +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/hello_world/builder/HelloWorldModule.kt @@ -9,6 +9,7 @@ import com.badoo.ribs.example.rib.hello_world.HelloWorldInteractor import com.badoo.ribs.example.rib.hello_world.HelloWorldNode import com.badoo.ribs.example.rib.hello_world.HelloWorldRouter import com.badoo.ribs.example.rib.hello_world.feature.HelloWorldFeature +import com.badoo.ribs.example.rib.small.builder.SmallBuilder import dagger.Provides import io.reactivex.ObservableSource import io.reactivex.functions.Consumer @@ -20,10 +21,12 @@ internal object HelloWorldModule { @Provides @JvmStatic internal fun router( + component: HelloWorldComponent, savedInstanceState: Bundle? ): HelloWorldRouter = HelloWorldRouter( - savedInstanceState = savedInstanceState + savedInstanceState = savedInstanceState, + smallBuilder = SmallBuilder(component) ) @HelloWorldScope diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/Small.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/Small.kt new file mode 100644 index 000000000..b6ac795e4 --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/Small.kt @@ -0,0 +1,19 @@ +package com.badoo.ribs.example.rib.small + +import com.badoo.ribs.core.Rib +import com.badoo.ribs.customisation.CanProvidePortal +import com.badoo.ribs.customisation.CanProvideRibCustomisation +import com.badoo.ribs.customisation.RibCustomisation + +interface Small : Rib { + + interface Dependency : + CanProvideRibCustomisation, + CanProvidePortal + + class Customisation( + val viewFactory: SmallView.Factory = SmallViewImpl.Factory() + ) : RibCustomisation + + interface Workflow +} diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallInteractor.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallInteractor.kt new file mode 100644 index 000000000..92ddcc4d6 --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallInteractor.kt @@ -0,0 +1,37 @@ +package com.badoo.ribs.example.rib.small + +import android.arch.lifecycle.Lifecycle +import android.os.Bundle +import com.badoo.mvicore.android.lifecycle.createDestroy +import com.badoo.ribs.core.Interactor +import com.badoo.ribs.core.Router +import com.badoo.ribs.core.routing.portal.Portal +import com.badoo.ribs.example.rib.small.SmallRouter.Configuration +import com.badoo.ribs.example.rib.small.SmallRouter.Configuration.Content +import com.badoo.ribs.example.rib.small.SmallRouter.Configuration.FullScreen +import com.badoo.ribs.example.rib.small.SmallView.Event +import com.badoo.ribs.example.rib.small.SmallView.ViewModel +import io.reactivex.functions.Consumer + +class SmallInteractor( + portal: Portal.OtherSide, + savedInstanceState: Bundle?, + router: Router +) : Interactor( + savedInstanceState = savedInstanceState, + router = router, + disposables = null +) { + override fun onViewCreated(view: SmallView, viewLifecycle: Lifecycle) { + view.accept(ViewModel("My id: " + id.replace("${SmallInteractor::class.java.name}.", ""))) + viewLifecycle.createDestroy { + bind(view to viewEventConsumer) + } + } + + private val viewEventConsumer: Consumer = Consumer { + when (it) { + Event.OpenBigClicked -> portal.showRemote(router, FullScreen.ShowBig) + } + } +} diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallNode.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallNode.kt new file mode 100644 index 000000000..6caf443f5 --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallNode.kt @@ -0,0 +1,20 @@ +package com.badoo.ribs.example.rib.small + +import android.os.Bundle +import android.view.ViewGroup +import com.badoo.ribs.core.Node + +class SmallNode( + savedInstanceState: Bundle?, + viewFactory: ((ViewGroup) -> SmallView?)?, + private val router: SmallRouter, + private val interactor: SmallInteractor +) : Node( + savedInstanceState = savedInstanceState, + identifier = object : Small {}, + viewFactory = viewFactory, + router = router, + interactor = interactor +), Small.Workflow { + +} diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallRouter.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallRouter.kt new file mode 100644 index 000000000..3f3f0cb83 --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallRouter.kt @@ -0,0 +1,37 @@ +package com.badoo.ribs.example.rib.small + +import android.os.Bundle +import android.os.Parcelable +import com.badoo.ribs.core.Router +import com.badoo.ribs.core.routing.action.AnchoredAttachRoutingAction.Companion.anchor +import com.badoo.ribs.core.routing.action.RoutingAction +import com.badoo.ribs.core.routing.action.RoutingAction.Companion.noop +import com.badoo.ribs.example.rib.big.builder.BigBuilder +import com.badoo.ribs.example.rib.small.SmallRouter.Configuration +import com.badoo.ribs.example.rib.small.SmallRouter.Configuration.Content +import com.badoo.ribs.example.rib.small.SmallRouter.Configuration.FullScreen +import kotlinx.android.parcel.Parcelize + +class SmallRouter( + savedInstanceState: Bundle?, + private val bigBuilder: BigBuilder +): Router( + savedInstanceState = savedInstanceState, + initialConfiguration = Content.Default, + permanentParts = emptyList() +) { + sealed class Configuration : Parcelable { + sealed class Content : Configuration() { + @Parcelize object Default : Content() + } + sealed class FullScreen : Configuration() { + @Parcelize object ShowBig : FullScreen() + } + } + + override fun resolveConfiguration(configuration: Configuration): RoutingAction = + when (configuration) { + Content.Default -> noop() + FullScreen.ShowBig -> anchor(node) { bigBuilder.build(it) } + } +} diff --git a/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallView.kt b/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallView.kt new file mode 100644 index 000000000..cd3be80f8 --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallView.kt @@ -0,0 +1,58 @@ +package com.badoo.ribs.example.rib.small + +import android.support.annotation.LayoutRes +import android.view.ViewGroup +import android.widget.Button +import android.widget.TextView +import com.badoo.ribs.core.view.RibView +import com.badoo.ribs.core.view.ViewFactory +import com.badoo.ribs.example.R +import com.badoo.ribs.example.rib.small.SmallView.Event +import com.badoo.ribs.example.rib.small.SmallView.ViewModel +import com.jakewharton.rxrelay2.PublishRelay +import io.reactivex.ObservableSource +import io.reactivex.functions.Consumer + +interface SmallView : RibView, + ObservableSource, + Consumer { + + sealed class Event { + object OpenBigClicked : Event() + } + + data class ViewModel( + val text: String + ) + + interface Factory : ViewFactory +} + + +class SmallViewImpl private constructor( + override val androidView: ViewGroup, + private val events: PublishRelay = PublishRelay.create() +) : SmallView, + ObservableSource by events { + + class Factory( + @LayoutRes private val layoutRes: Int = R.layout.rib_small + ) : SmallView.Factory { + override fun invoke(deps: Nothing?): (ViewGroup) -> SmallView = { + SmallViewImpl( + com.badoo.ribs.customisation.inflate(it, layoutRes) + ) + } + } + + private val idText = androidView.findViewById(R.id.small_id) + private val openBigButton = androidView.findViewById