From 59157f5f729fd975d64ade510c288cf5dd70c233 Mon Sep 17 00:00:00 2001 From: Zsolt Kocsi Date: Fri, 23 Aug 2019 17:50:11 +0100 Subject: [PATCH 01/17] Add initial portal implementation --- .../com/badoo/ribs/example/rib/big/Big.kt | 22 +++++++ .../ribs/example/rib/big/BigInteractor.kt | 23 +++++++ .../com/badoo/ribs/example/rib/big/BigNode.kt | 18 ++++++ .../badoo/ribs/example/rib/big/BigRouter.kt | 39 ++++++++++++ .../com/badoo/ribs/example/rib/big/BigView.kt | 60 ++++++++++++++++++ .../example/rib/big/builder/BigBuilder.kt | 27 ++++++++ .../example/rib/big/builder/BigComponent.kt | 26 ++++++++ .../ribs/example/rib/big/builder/BigModule.kt | 54 ++++++++++++++++ .../ribs/example/rib/big/builder/BigScope.kt | 7 +++ .../example/rib/hello_world/HelloWorld.kt | 6 +- .../rib/hello_world/HelloWorldInteractor.kt | 5 +- .../rib/hello_world/HelloWorldRouter.kt | 21 +++++-- .../example/rib/hello_world/HelloWorldView.kt | 9 +++ .../builder/HelloWorldComponent.kt | 3 +- .../hello_world/builder/HelloWorldModule.kt | 5 +- .../com/badoo/ribs/example/rib/small/Small.kt | 19 ++++++ .../ribs/example/rib/small/SmallInteractor.kt | 34 ++++++++++ .../badoo/ribs/example/rib/small/SmallNode.kt | 20 ++++++ .../ribs/example/rib/small/SmallRouter.kt | 36 +++++++++++ .../badoo/ribs/example/rib/small/SmallView.kt | 58 +++++++++++++++++ .../example/rib/small/builder/SmallBuilder.kt | 27 ++++++++ .../rib/small/builder/SmallComponent.kt | 26 ++++++++ .../example/rib/small/builder/SmallModule.kt | 57 +++++++++++++++++ .../example/rib/small/builder/SmallScope.kt | 7 +++ .../rib/switcher/SwitcherInteractor.kt | 8 ++- .../ribs/example/rib/switcher/SwitcherView.kt | 8 +++ .../rib/switcher/builder/SwitcherModule.kt | 22 ++++++- .../rib/switcher/feature/PortalFeature.kt | 62 +++++++++++++++++++ .../src/main/res/layout/rib_big.xml | 28 +++++++++ .../src/main/res/layout/rib_hello_world.xml | 12 +++- .../src/main/res/layout/rib_small.xml | 23 +++++++ .../src/main/res/layout/rib_switcher.xml | 7 +++ .../ribs/android/AndroidPortalRenderer.kt | 23 +++++++ .../java/com/badoo/ribs/android/ViewStack.kt | 30 +++++++++ .../src/main/java/com/badoo/ribs/core/Node.kt | 10 ++- .../main/java/com/badoo/ribs/core/Portal.kt | 26 ++++++++ .../routing/action/CompositeRoutingAction.kt | 8 +-- .../routing/action/DialogRoutingAction.kt | 4 +- .../routing/action/FullScreenRoutingAction.kt | 37 +++++++++++ .../core/routing/action/InvokeOnCleanUp.kt | 3 +- .../core/routing/action/InvokeOnExecute.kt | 3 +- .../ribs/core/routing/action/RoutingAction.kt | 4 +- .../action/single/ActivateAction.kt | 2 +- .../action/single/DeactivateAction.kt | 2 +- .../ribs/customisation/CanProvidePortal.kt | 8 +++ .../configuration/ConfigurationFeatureTest.kt | 34 +++++----- 46 files changed, 928 insertions(+), 45 deletions(-) create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/big/Big.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigInteractor.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigNode.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigRouter.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigView.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigBuilder.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigComponent.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigModule.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/big/builder/BigScope.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/small/Small.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallInteractor.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallNode.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallRouter.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallView.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/small/builder/SmallBuilder.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/small/builder/SmallComponent.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/small/builder/SmallModule.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/small/builder/SmallScope.kt create mode 100644 android/app-example/src/main/java/com/badoo/ribs/example/rib/switcher/feature/PortalFeature.kt create mode 100644 android/app-example/src/main/res/layout/rib_big.xml create mode 100644 android/app-example/src/main/res/layout/rib_small.xml create mode 100644 android/libraries/rib-base/src/main/java/com/badoo/ribs/android/AndroidPortalRenderer.kt create mode 100644 android/libraries/rib-base/src/main/java/com/badoo/ribs/android/ViewStack.kt create mode 100644 android/libraries/rib-base/src/main/java/com/badoo/ribs/core/Portal.kt create mode 100644 android/libraries/rib-base/src/main/java/com/badoo/ribs/core/routing/action/FullScreenRoutingAction.kt create mode 100644 android/libraries/rib-base/src/main/java/com/badoo/ribs/customisation/CanProvidePortal.kt 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..59762c804 --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/Big.kt @@ -0,0 +1,22 @@ +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 +import io.reactivex.ObservableSource +import io.reactivex.Single +import io.reactivex.functions.Consumer + +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..93b5292f1 --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/big/BigView.kt @@ -0,0 +1,60 @@ +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.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( + com.badoo.ribs.customisation.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..7a8d68d79 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,7 @@ 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.* 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 +25,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..9fc7badf3 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 @@ -7,19 +7,30 @@ import com.badoo.ribs.core.routing.action.RoutingAction.Companion.noop import com.badoo.ribs.example.rib.hello_world.HelloWorldRouter.Configuration import kotlinx.android.parcel.Parcelize import android.os.Bundle +import com.badoo.ribs.core.routing.action.AttachRibRoutingAction.Companion.attach +import com.badoo.ribs.example.rib.hello_world.HelloWorldRouter.Configuration.* +import com.badoo.ribs.example.rib.small.builder.SmallBuilder 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..de25cb612 --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallInteractor.kt @@ -0,0 +1,34 @@ +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.example.rib.small.SmallRouter.Configuration +import com.badoo.ribs.example.rib.small.SmallRouter.Configuration.Content +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( + 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 -> router.push(Content.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..df3958869 --- /dev/null +++ b/android/app-example/src/main/java/com/badoo/ribs/example/rib/small/SmallRouter.kt @@ -0,0 +1,36 @@ +package com.badoo.ribs.example.rib.small + +import android.os.Bundle +import android.os.Parcelable +import com.badoo.ribs.core.Portal +import com.badoo.ribs.core.Router +import com.badoo.ribs.core.routing.action.FullScreenRoutingAction.Companion.fullScreen +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 kotlinx.android.parcel.Parcelize + +class SmallRouter( + savedInstanceState: Bundle?, + private val portal: Portal.Sink, + private val bigBuilder: BigBuilder +): Router( + savedInstanceState = savedInstanceState, + initialConfiguration = Content.Default, + permanentParts = emptyList() +) { + sealed class Configuration : Parcelable { + sealed class Content : Configuration() { + @Parcelize object Default : Content() + @Parcelize object ShowBig : Content() + } + } + + override fun resolveConfiguration(configuration: Configuration): RoutingAction = + when (configuration) { + Content.Default -> noop() + Content.ShowBig -> fullScreen(portal) { 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