├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── ci.yml ├── .gitignore ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── build.gradle ├── detekt.yml ├── documentation ├── about │ ├── evolution-of-ribs.md │ └── your-application-as-a-tree.md ├── android │ ├── dialogs.md │ ├── launching-activities.md │ └── permission-requests.md ├── barebone.md ├── basics │ ├── nodes.md │ ├── plugins.md │ └── terminology.md ├── experimental │ ├── jetpack-compose.md │ └── portals.md ├── extras │ ├── minimal-reactive-api.md │ └── tooling.md ├── hello-world │ ├── business-logic.md │ ├── hello-world.md │ └── view.md ├── index.md ├── our-approach │ └── unopinionated.md ├── ourapproach.md ├── reuse │ ├── build-time-dependencies.md │ └── customisations.md ├── setup │ ├── deps.md │ └── integrationpoint.md ├── testing │ ├── compatibility.md │ ├── integration-tests.md │ ├── preparations.md │ └── unit-tests.md ├── transitions │ ├── custom-transitions.md │ ├── transitions-quick-start.md │ └── transitions-reversal.md └── tree-structure-101 │ ├── back-stack.md │ ├── childaware-api.md │ ├── communication-between-nodes.md │ ├── deep-link-workflows.md │ ├── happy-little-trees.md │ ├── lifecycle.md │ ├── permanent-parts.md │ ├── providing-dependencies.md │ ├── resolving-routing.md │ └── routing.md ├── gradle.properties ├── gradle ├── code-coverage.gradle ├── dependencies.gradle ├── gradle-mvn-push.gradle ├── utils.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── internal └── junitextensions │ ├── build.gradle │ └── src │ └── main │ ├── java │ └── com │ │ └── badoo │ │ └── ribs │ │ └── internal │ │ └── junitextensions │ │ └── AndroidXArchCoreExtension.kt │ └── resources │ └── META-INF │ └── services │ └── org.junit.jupiter.api.extension.Extension ├── jitpack.yml ├── libraries ├── rib-base-test-activity │ ├── build.gradle │ ├── detekt-baseline.xml │ ├── gradle.properties │ ├── lint-baseline.xml │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── badoo │ │ │ └── ribs │ │ │ └── test │ │ │ ├── AutoLaunchRibsRuleTest.kt │ │ │ ├── ManualLaunchRibsRuleTest.kt │ │ │ ├── RibsRuleTestBase.kt │ │ │ ├── Utils.kt │ │ │ ├── sample │ │ │ ├── SampleBuilder.kt │ │ │ ├── SampleNode.kt │ │ │ ├── SampleRib.kt │ │ │ └── SampleView.kt │ │ │ └── view │ │ │ ├── AutoLaunchRibsViewRuleTest.kt │ │ │ ├── ManualLaunchRibsViewRuleTest.kt │ │ │ └── RibsViewRuleTestBase.kt │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── badoo │ │ │ └── ribs │ │ │ ├── compatibility.kt │ │ │ └── test │ │ │ ├── RibTestActivity.kt │ │ │ ├── RibsRule.kt │ │ │ └── view │ │ │ ├── RibsViewActivity.kt │ │ │ └── RibsViewRule.kt │ │ └── res │ │ └── layout │ │ └── rib_test.xml ├── rib-base-test-rx3 │ ├── .gitignore │ ├── build.gradle │ ├── detekt-baseline.xml │ ├── gradle.properties │ ├── lint-baseline.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── badoo │ │ ├── common │ │ └── ribs │ │ │ └── rx3 │ │ │ └── InteractorTestHelper.kt │ │ └── ribs │ │ └── test │ │ └── rx3 │ │ └── view │ │ └── RibViewStub.kt ├── rib-base-test │ ├── .gitignore │ ├── build.gradle │ ├── detekt-baseline.xml │ ├── gradle.properties │ ├── lint-baseline.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── badoo │ │ └── ribs │ │ └── test │ │ ├── BaseConnectableNodeTest.kt │ │ ├── BaseNodeConnectorTest.kt │ │ ├── CustomisationExt.kt │ │ ├── Empty.kt │ │ ├── InteractorTestHelper.kt │ │ ├── RibTestHelper.kt │ │ ├── RibTestHelperExt.kt │ │ ├── assert.kt │ │ ├── builder │ │ ├── RibBuilderStub.kt │ │ └── RibBuilderStubExt.kt │ │ ├── integrationpoint │ │ ├── TestActivityStarter.kt │ │ ├── TestIntegrationPoint.kt │ │ ├── TestPermissionRequester.kt │ │ └── TestRibDialogLauncher.kt │ │ ├── interactor │ │ └── RibInteractorTestHelper.kt │ │ ├── node │ │ ├── RibNodeStub.kt │ │ └── RibNodeTestHelper.kt │ │ ├── router │ │ ├── BackStackExt.kt │ │ └── RibRouterTestHelper.kt │ │ └── view │ │ └── RibViewStub.kt ├── rib-base │ ├── README.md │ ├── build.gradle │ ├── detekt-baseline.xml │ ├── gradle.properties │ ├── lint-baseline.xml │ └── src │ │ ├── androidTest │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── badoo │ │ │ └── ribs │ │ │ ├── android │ │ │ ├── ActivityStarterTest.kt │ │ │ ├── dialogkeyboard │ │ │ │ └── AlertDialogKeyboardTest.kt │ │ │ └── lifecycle │ │ │ │ ├── BaseNodesTest.kt │ │ │ │ ├── InitialNodesStateTest.kt │ │ │ │ ├── PushOneTest.kt │ │ │ │ ├── PushTwoPopOneDefaultTest.kt │ │ │ │ ├── PushTwoPopOnePauseAfterPopTest.kt │ │ │ │ ├── PushTwoPopOnePauseBeforePopTest.kt │ │ │ │ ├── PushTwoPopOnePauseBeforePushTest.kt │ │ │ │ ├── PushTwoPopOnePauseBetweenPushesTest.kt │ │ │ │ ├── PushTwoPopOnePauseTest.kt │ │ │ │ ├── PushTwoPopOneStopAfterPopTest.kt │ │ │ │ ├── PushTwoPopOneStopBeforePopTest.kt │ │ │ │ ├── PushTwoPopOneStopBeforePushTest.kt │ │ │ │ ├── PushTwoPopOneStopBetweenPushesTest.kt │ │ │ │ ├── PushTwoPopOneStopStartResumeTest.kt │ │ │ │ ├── PushTwoPopOneStopStartTest.kt │ │ │ │ ├── PushTwoPopOneStopTest.kt │ │ │ │ ├── PushTwoPopOneTest.kt │ │ │ │ ├── PushTwoTest.kt │ │ │ │ ├── RestartActivityNodesStateTest.kt │ │ │ │ ├── RetainedInstanceStoreTest.kt │ │ │ │ ├── RootNodeLifecycleTest.kt │ │ │ │ ├── helper │ │ │ │ ├── ExpectedState.kt │ │ │ │ └── NodeState.kt │ │ │ │ └── transition │ │ │ │ ├── ReplaceTwoWithTransitionTest.kt │ │ │ │ └── TransitionBaseNodeTest.kt │ │ │ └── test │ │ │ └── util │ │ │ ├── AndroidTestUtils.kt │ │ │ ├── NoOpDialogLauncher.kt │ │ │ ├── OtherActivity.kt │ │ │ ├── RxTestUtils.kt │ │ │ ├── TestActivity.kt │ │ │ ├── TestRequestCodeClient.kt │ │ │ └── ribs │ │ │ ├── TestNode.kt │ │ │ ├── TestRibDialog.kt │ │ │ ├── child │ │ │ ├── TestChild.kt │ │ │ ├── TestChildInteractor.kt │ │ │ ├── TestChildRouter.kt │ │ │ ├── TestChildView.kt │ │ │ └── builder │ │ │ │ └── TestChildBuilder.kt │ │ │ └── root │ │ │ ├── TestRoot.kt │ │ │ ├── TestRootInteractor.kt │ │ │ ├── TestRootRouter.kt │ │ │ ├── TestRootView.kt │ │ │ └── builder │ │ │ └── TestRootBuilder.kt │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ ├── android │ │ │ │ ├── AndroidRibViewHost.kt │ │ │ │ ├── Lifecycle.kt │ │ │ │ ├── RibActivity.kt │ │ │ │ ├── RibFragment.kt │ │ │ │ ├── activitystarter │ │ │ │ │ ├── ActivityBoundary.kt │ │ │ │ │ ├── ActivityResultHandler.kt │ │ │ │ │ ├── ActivityStarter.kt │ │ │ │ │ ├── ActivityStarterHost.kt │ │ │ │ │ └── CanProvideActivityStarter.kt │ │ │ │ ├── dialog │ │ │ │ │ ├── AlertDialogLauncher.kt │ │ │ │ │ ├── CanProvideDialogLauncher.kt │ │ │ │ │ ├── Dialog.kt │ │ │ │ │ ├── DialogExtensions.kt │ │ │ │ │ ├── DialogLauncher.kt │ │ │ │ │ ├── RibFactory.kt │ │ │ │ │ └── routing │ │ │ │ │ │ └── resolution │ │ │ │ │ │ └── DialogResolution.kt │ │ │ │ ├── integrationpoint │ │ │ │ │ ├── ActivityIntegrationPoint.kt │ │ │ │ │ ├── FloatingIntegrationPoint.kt │ │ │ │ │ ├── FragmentIntegrationPoint.kt │ │ │ │ │ └── IntegrationPoint.kt │ │ │ │ ├── permissionrequester │ │ │ │ │ ├── CanProvidePermissionRequester.kt │ │ │ │ │ ├── PermissionRequestBoundary.kt │ │ │ │ │ ├── PermissionRequestResultHandler.kt │ │ │ │ │ ├── PermissionRequester.kt │ │ │ │ │ └── PermissionRequesterHost.kt │ │ │ │ ├── requestcode │ │ │ │ │ ├── RequestCodeBasedEventStream.kt │ │ │ │ │ ├── RequestCodeBasedEventStreamImpl.kt │ │ │ │ │ ├── RequestCodeClient.kt │ │ │ │ │ ├── RequestCodeDoesntFitInMask.kt │ │ │ │ │ └── RequestCodeRegistry.kt │ │ │ │ └── text │ │ │ │ │ └── Text.kt │ │ │ │ ├── annotation │ │ │ │ ├── ExperimentalApi.kt │ │ │ │ └── OutdatedDocumentation.kt │ │ │ │ ├── builder │ │ │ │ ├── Builder.kt │ │ │ │ └── SimpleBuilder.kt │ │ │ │ ├── clienthelper │ │ │ │ ├── childaware │ │ │ │ │ ├── Callbacks.kt │ │ │ │ │ ├── ChildAware.kt │ │ │ │ │ ├── ChildAwareCallbackInfo.kt │ │ │ │ │ ├── ChildAwareExt.kt │ │ │ │ │ ├── ChildAwareImpl.kt │ │ │ │ │ ├── ChildAwareScope.kt │ │ │ │ │ └── LifecycleExt.kt │ │ │ │ ├── connector │ │ │ │ │ ├── Connectable.kt │ │ │ │ │ └── NodeConnector.kt │ │ │ │ └── interactor │ │ │ │ │ └── Interactor.kt │ │ │ │ ├── core │ │ │ │ ├── Node.kt │ │ │ │ ├── Rib.kt │ │ │ │ ├── customisation │ │ │ │ │ ├── MutableRibCustomisationDirectory.kt │ │ │ │ │ ├── RibCustomisation.kt │ │ │ │ │ ├── RibCustomisationDirectory.kt │ │ │ │ │ ├── RibCustomisationDirectoryImpl.kt │ │ │ │ │ └── RibCustomisationExtensions.kt │ │ │ │ ├── exception │ │ │ │ │ └── RootNodeAttachedAsChildException.kt │ │ │ │ ├── lifecycle │ │ │ │ │ ├── CappedLifecycle.kt │ │ │ │ │ ├── LifecycleManager.kt │ │ │ │ │ └── MinimumCombinedLifecycle.kt │ │ │ │ ├── modality │ │ │ │ │ ├── ActivationMode.kt │ │ │ │ │ ├── AncestryInfo.kt │ │ │ │ │ ├── BuildContext.kt │ │ │ │ │ └── BuildParams.kt │ │ │ │ ├── plugin │ │ │ │ │ ├── NodeAwareImpl.kt │ │ │ │ │ ├── Plugin.kt │ │ │ │ │ └── RibAwareImpl.kt │ │ │ │ └── view │ │ │ │ │ ├── AndroidRibView.kt │ │ │ │ │ ├── AndroidRibView2.kt │ │ │ │ │ ├── RibView.kt │ │ │ │ │ ├── ViewFactory.kt │ │ │ │ │ └── ViewFactoryBuilder.kt │ │ │ │ ├── minimal │ │ │ │ ├── README.md │ │ │ │ ├── reactive │ │ │ │ │ ├── Cancellable.kt │ │ │ │ │ ├── CompositeCancellable.kt │ │ │ │ │ ├── Emitter.kt │ │ │ │ │ ├── Operators.kt │ │ │ │ │ ├── Relay.kt │ │ │ │ │ └── Source.kt │ │ │ │ └── state │ │ │ │ │ ├── SavedState.kt │ │ │ │ │ └── Store.kt │ │ │ │ ├── routing │ │ │ │ ├── Routing.kt │ │ │ │ ├── activator │ │ │ │ │ ├── ChildActivator.kt │ │ │ │ │ ├── DefaultChildActivator.kt │ │ │ │ │ ├── RoutingActivator.kt │ │ │ │ │ └── UnhandledChildActivator.kt │ │ │ │ ├── history │ │ │ │ │ ├── RoutingHistory.kt │ │ │ │ │ ├── RoutingHistoryDiffer.kt │ │ │ │ │ └── RoutingHistoryElement.kt │ │ │ │ ├── resolution │ │ │ │ │ ├── ChildResolution.kt │ │ │ │ │ ├── CompositeResolution.kt │ │ │ │ │ ├── InvokeOnCleanUp.kt │ │ │ │ │ ├── InvokeOnExecute.kt │ │ │ │ │ ├── Resolution.kt │ │ │ │ │ └── RibFactory.kt │ │ │ │ ├── resolver │ │ │ │ │ └── RoutingResolver.kt │ │ │ │ ├── router │ │ │ │ │ ├── Router.kt │ │ │ │ │ └── RouterByDelegate.kt │ │ │ │ ├── source │ │ │ │ │ ├── RoutingSource.kt │ │ │ │ │ ├── RoutingSourceDiffer.kt │ │ │ │ │ ├── backstack │ │ │ │ │ │ ├── BackStack.kt │ │ │ │ │ │ ├── Elements.kt │ │ │ │ │ │ ├── Ext.kt │ │ │ │ │ │ └── operation │ │ │ │ │ │ │ ├── NewRoot.kt │ │ │ │ │ │ │ ├── Pop.kt │ │ │ │ │ │ │ ├── Push.kt │ │ │ │ │ │ │ ├── PushOverlay.kt │ │ │ │ │ │ │ ├── Remove.kt │ │ │ │ │ │ │ ├── Replace.kt │ │ │ │ │ │ │ └── SingleTop.kt │ │ │ │ │ └── impl │ │ │ │ │ │ ├── Combined.kt │ │ │ │ │ │ ├── Empty.kt │ │ │ │ │ │ ├── Permanent.kt │ │ │ │ │ │ └── Pool.kt │ │ │ │ ├── state │ │ │ │ │ ├── Pool.kt │ │ │ │ │ ├── RoutingContext.kt │ │ │ │ │ ├── action │ │ │ │ │ │ ├── ActionExecutionParams.kt │ │ │ │ │ │ ├── TransactionExecutionParams.kt │ │ │ │ │ │ ├── multi │ │ │ │ │ │ │ ├── PoolAction.kt │ │ │ │ │ │ │ ├── SaveInstanceStateAction.kt │ │ │ │ │ │ │ ├── SleepAction.kt │ │ │ │ │ │ │ └── WakeUpAction.kt │ │ │ │ │ │ └── single │ │ │ │ │ │ │ ├── ActionFactory.kt │ │ │ │ │ │ │ ├── ActivateAction.kt │ │ │ │ │ │ │ ├── AddAction.kt │ │ │ │ │ │ │ ├── DeactivateAction.kt │ │ │ │ │ │ │ ├── Ext.kt │ │ │ │ │ │ │ ├── RemoveAction.kt │ │ │ │ │ │ │ ├── ReversibleAction.kt │ │ │ │ │ │ │ ├── ReversibleActionFactory.kt │ │ │ │ │ │ │ ├── ReversibleActionPair.kt │ │ │ │ │ │ │ └── RoutingTransitionAction.kt │ │ │ │ │ ├── changeset │ │ │ │ │ │ ├── RoutingChangeset.kt │ │ │ │ │ │ ├── RoutingCommand.kt │ │ │ │ │ │ └── TransitionDescriptor.kt │ │ │ │ │ ├── exception │ │ │ │ │ │ ├── CommandExecutionException.kt │ │ │ │ │ │ └── KeyNotFoundInPoolException.kt │ │ │ │ │ └── feature │ │ │ │ │ │ ├── Actor.kt │ │ │ │ │ │ ├── EffectEmitter.kt │ │ │ │ │ │ ├── InternalTransactionConsumer.kt │ │ │ │ │ │ ├── OngoingTransition.kt │ │ │ │ │ │ ├── PendingTransition.kt │ │ │ │ │ │ ├── PendingTransitionFactory.kt │ │ │ │ │ │ ├── RoutingStatePool.kt │ │ │ │ │ │ ├── Transaction.kt │ │ │ │ │ │ └── state │ │ │ │ │ │ ├── SavedState.kt │ │ │ │ │ │ └── WorkingState.kt │ │ │ │ └── transition │ │ │ │ │ ├── Transition.kt │ │ │ │ │ ├── TransitionDirection.kt │ │ │ │ │ ├── TransitionElement.kt │ │ │ │ │ ├── TransitionPair.kt │ │ │ │ │ ├── effect │ │ │ │ │ ├── Gravity.kt │ │ │ │ │ ├── fade │ │ │ │ │ │ └── Fade.kt │ │ │ │ │ ├── helper │ │ │ │ │ │ ├── AnimationContainer.kt │ │ │ │ │ │ ├── EndValues.kt │ │ │ │ │ │ └── ReverseHolder.kt │ │ │ │ │ ├── sharedelement │ │ │ │ │ │ └── SharedElementTransition.kt │ │ │ │ │ └── slide │ │ │ │ │ │ ├── Slide.kt │ │ │ │ │ │ ├── SlideCalculations.kt │ │ │ │ │ │ └── SlideValueAnimator.kt │ │ │ │ │ ├── handler │ │ │ │ │ ├── CrossFader.kt │ │ │ │ │ ├── Defaults.kt │ │ │ │ │ ├── SharedElements.kt │ │ │ │ │ ├── Slider.kt │ │ │ │ │ ├── TabSwitcher.kt │ │ │ │ │ └── TransitionHandler.kt │ │ │ │ │ └── progress │ │ │ │ │ ├── MultiProgressEvaluator.kt │ │ │ │ │ ├── ProgressEvaluator.kt │ │ │ │ │ └── SingleProgressEvaluator.kt │ │ │ │ ├── store │ │ │ │ ├── RetainedInstanceStore.kt │ │ │ │ ├── RetainedInstanceStoreExt.kt │ │ │ │ └── RetainedInstanceStoreImpl.kt │ │ │ │ └── util │ │ │ │ └── RIBs.kt │ │ └── res │ │ │ └── layout │ │ │ └── debug_controls_host.xml │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── badoo │ │ │ └── ribs │ │ │ ├── android │ │ │ └── requestcode │ │ │ │ ├── RequestCodeBasedEventStreamImplTest.kt │ │ │ │ └── RequestCodeRegistryTest.kt │ │ │ ├── clienthelper │ │ │ ├── childaware │ │ │ │ └── ChildAwareImplTest.kt │ │ │ └── connector │ │ │ │ ├── ConnectableNodeTest.kt │ │ │ │ └── NodeConnectorTest.kt │ │ │ ├── core │ │ │ ├── NodeBackPressHandlingTest.kt │ │ │ ├── NodePluginAndroidLifecycleAwareTest.kt │ │ │ ├── NodePluginNodeAwareTest.kt │ │ │ ├── NodePluginNodeLifecycleAwareTest.kt │ │ │ ├── NodePluginRibAwareTest.kt │ │ │ ├── NodePluginSavesInstanceStateTest.kt │ │ │ ├── NodePluginSubtreeChangeAwareTest.kt │ │ │ ├── NodePluginSubtreeViewChangeAwareTest.kt │ │ │ ├── NodePluginSystemAwareTest.kt │ │ │ ├── NodePluginTest.kt │ │ │ ├── NodePluginViewAwareTest.kt │ │ │ ├── NodePluginViewLifecycleAwareTest.kt │ │ │ ├── NodeTest.kt │ │ │ ├── RouterTest.kt │ │ │ ├── helper │ │ │ │ ├── AnyConfiguration.kt │ │ │ │ ├── TestBuildParams.kt │ │ │ │ ├── TestBuilder.kt │ │ │ │ ├── TestInteractor.kt │ │ │ │ ├── TestNode.kt │ │ │ │ ├── TestNode2.kt │ │ │ │ ├── TestRib.kt │ │ │ │ ├── TestRouter.kt │ │ │ │ ├── TestView.kt │ │ │ │ ├── TestViewFactory.kt │ │ │ │ └── connectable │ │ │ │ │ ├── ConnectableTestNode.kt │ │ │ │ │ └── ConnectableTestRib.kt │ │ │ └── lifecycle │ │ │ │ ├── CappedLifecycleTest.kt │ │ │ │ ├── LifecycleManagerTest.kt │ │ │ │ ├── MinimumCombinedLifecycleTest.kt │ │ │ │ └── TestLifecycle.kt │ │ │ ├── minimal │ │ │ ├── reactive │ │ │ │ ├── CombineLatestTest.kt │ │ │ │ └── DistinctUntilChangedTest.kt │ │ │ └── state │ │ │ │ └── StoreTest.kt │ │ │ ├── routing │ │ │ ├── source │ │ │ │ ├── backstack │ │ │ │ │ └── BackStackTest.kt │ │ │ │ └── impl │ │ │ │ │ └── PoolTest.kt │ │ │ ├── state │ │ │ │ ├── BackStackDiffingIntegrationTest.kt │ │ │ │ ├── BackStackFeatureTest.kt │ │ │ │ ├── DifferTest.kt │ │ │ │ ├── RoutingContextTest.kt │ │ │ │ ├── RoutingStatePoolTest.kt │ │ │ │ └── feature │ │ │ │ │ ├── ActorTest.kt │ │ │ │ │ ├── OngoingTransitionTest.kt │ │ │ │ │ ├── PendingTransitionTest.kt │ │ │ │ │ ├── RoutingStatePoolTest.kt │ │ │ │ │ ├── TestRoutingStatePool.kt │ │ │ │ │ └── operation │ │ │ │ │ ├── BackStackOperationHelper.kt │ │ │ │ │ ├── NewRootTest.kt │ │ │ │ │ ├── PopTest.kt │ │ │ │ │ ├── PushOverlayTest.kt │ │ │ │ │ ├── PushTest.kt │ │ │ │ │ ├── RemoveTest.kt │ │ │ │ │ ├── ReplaceTest.kt │ │ │ │ │ └── SingleTopTest.kt │ │ │ └── transition │ │ │ │ └── progress │ │ │ │ └── MultiProgressEvaluatorTest.kt │ │ │ └── store │ │ │ └── RetainedInstanceStoreTest.kt │ │ └── resources │ │ └── mockito-extensions │ │ └── org.mockito.plugins.MockMaker ├── rib-compose │ ├── .gitignore │ ├── build.gradle │ ├── consumer-rules.pro │ ├── detekt-baseline.xml │ ├── gradle.properties │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── badoo │ │ └── ribs │ │ └── compose │ │ ├── ComposeChildHost.kt │ │ ├── ComposeRibView.kt │ │ └── ComposeView.kt ├── rib-debug-utils │ ├── build.gradle │ ├── detekt-baseline.xml │ ├── gradle.properties │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── badoo │ │ │ └── ribs │ │ │ ├── core │ │ │ └── plugin │ │ │ │ └── utils │ │ │ │ ├── debug │ │ │ │ ├── AbstractDebugControls.kt │ │ │ │ ├── DebugControls.kt │ │ │ │ ├── DebugControlsHost.kt │ │ │ │ └── GrowthDirection.kt │ │ │ │ ├── logger │ │ │ │ ├── Logger.kt │ │ │ │ └── LoggingPolicy.kt │ │ │ │ └── memoryleak │ │ │ │ └── LeakDetector.kt │ │ │ └── debug │ │ │ └── TreePrinter.kt │ │ └── res │ │ └── layout │ │ └── debug_root.xml ├── rib-mvicore │ ├── build.gradle │ ├── detekt-baseline.xml │ ├── gradle.properties │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── badoo │ │ └── ribs │ │ └── mvicore │ │ └── ChildAwareExt.kt ├── rib-portal-rx3 │ ├── .gitignore │ ├── build.gradle │ ├── consumer-rules.pro │ ├── detekt-baseline.xml │ ├── gradle.properties │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── badoo │ │ └── ribs │ │ └── portal │ │ └── rx3 │ │ ├── Rx3Portal.kt │ │ ├── Rx3PortalBuilder.kt │ │ └── Rx3PortalNode.kt ├── rib-portal │ ├── .gitignore │ ├── build.gradle │ ├── consumer-rules.pro │ ├── detekt-baseline.xml │ ├── gradle.properties │ ├── proguard-rules.pro │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── badoo │ │ │ └── ribs │ │ │ └── portal │ │ │ ├── CanProvidePortal.kt │ │ │ ├── Portal.kt │ │ │ ├── PortalBuilder.kt │ │ │ ├── PortalInteractor.kt │ │ │ ├── PortalNode.kt │ │ │ └── PortalRouter.kt │ │ └── test │ │ └── java │ │ └── com │ │ └── badoo │ │ └── ribs │ │ └── portal │ │ ├── PortalRouterTest.kt │ │ ├── TestNode.kt │ │ └── TestRouter.kt └── rib-rx3 │ ├── .gitignore │ ├── build.gradle │ ├── consumer-rules.pro │ ├── detekt-baseline.xml │ ├── gradle.properties │ ├── lint-baseline.xml │ ├── proguard-rules.pro │ └── src │ ├── main │ └── java │ │ └── com │ │ └── badoo │ │ └── ribs │ │ └── rx3 │ │ ├── Disposables.kt │ │ ├── adapter │ │ └── Rx3.kt │ │ ├── clienthelper │ │ └── connector │ │ │ ├── Connectable.kt │ │ │ └── NodeConnector.kt │ │ └── workflows │ │ ├── RxWorkflowActivity.kt │ │ └── RxWorkflowNode.kt │ └── test │ ├── java │ └── com │ │ └── badoo │ │ └── ribs │ │ └── rx3 │ │ ├── DisposablePluginTest.kt │ │ ├── clienthelper │ │ └── conector │ │ │ ├── Rx3ConnectableNodeTest.kt │ │ │ ├── Rx3NodeConnectorTest.kt │ │ │ └── helpers │ │ │ ├── AnyConfiguration.kt │ │ │ ├── Rx3ConnectableTestNode.kt │ │ │ ├── Rx3ConnectableTestRib.kt │ │ │ └── TestBuildParams.kt │ │ └── workflows │ │ └── WorkflowTest.kt │ └── resources │ └── mockito-extensions │ └── org.mockito.plugins.MockMaker ├── samples ├── app │ ├── customisations-demo │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── detekt-baseline.xml │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── androidTest │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── customisations │ │ │ │ └── app │ │ │ │ └── CustomisationsParentTest.kt │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── customisations │ │ │ │ └── app │ │ │ │ ├── AppCustomisations.kt │ │ │ │ └── CustomisationsActivity.kt │ │ │ └── res │ │ │ ├── layout │ │ │ ├── activity_customisations.xml │ │ │ ├── rib_customisation_child1.xml │ │ │ ├── rib_customisation_child1_child1.xml │ │ │ ├── rib_customisation_child1_child2.xml │ │ │ ├── rib_customisation_child2.xml │ │ │ └── rib_customisation_parent.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── gallery │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── gallery │ │ │ │ ├── RootActivity.kt │ │ │ │ ├── composable │ │ │ │ └── ButtonList.kt │ │ │ │ └── rib │ │ │ │ ├── android │ │ │ │ ├── container │ │ │ │ │ ├── AndroidContainer.kt │ │ │ │ │ ├── AndroidContainerBuilder.kt │ │ │ │ │ ├── AndroidContainerInteractor.kt │ │ │ │ │ ├── AndroidContainerNode.kt │ │ │ │ │ ├── AndroidContainerView.kt │ │ │ │ │ └── routing │ │ │ │ │ │ ├── AndroidContainerChildBuilders.kt │ │ │ │ │ │ └── AndroidContainerRouter.kt │ │ │ │ └── picker │ │ │ │ │ ├── AndroidPicker.kt │ │ │ │ │ ├── AndroidPickerBuilder.kt │ │ │ │ │ ├── AndroidPickerInteractor.kt │ │ │ │ │ ├── AndroidPickerNode.kt │ │ │ │ │ ├── AndroidPickerView.kt │ │ │ │ │ └── mapper │ │ │ │ │ └── ViewEventToOutput.kt │ │ │ │ ├── communication │ │ │ │ ├── container │ │ │ │ │ ├── CommunicationContainer.kt │ │ │ │ │ ├── CommunicationContainerBuilder.kt │ │ │ │ │ ├── CommunicationContainerInteractor.kt │ │ │ │ │ ├── CommunicationContainerNode.kt │ │ │ │ │ ├── CommunicationContainerView.kt │ │ │ │ │ └── routing │ │ │ │ │ │ ├── CommunicationContainerChildBuilders.kt │ │ │ │ │ │ └── CommunicationContainerRouter.kt │ │ │ │ └── picker │ │ │ │ │ ├── CommunicationPicker.kt │ │ │ │ │ ├── CommunicationPickerBuilder.kt │ │ │ │ │ ├── CommunicationPickerInteractor.kt │ │ │ │ │ ├── CommunicationPickerNode.kt │ │ │ │ │ ├── CommunicationPickerView.kt │ │ │ │ │ └── mapper │ │ │ │ │ └── ViewEventToOutput.kt │ │ │ │ ├── other │ │ │ │ ├── container │ │ │ │ │ ├── OtherContainer.kt │ │ │ │ │ ├── OtherContainerBuilder.kt │ │ │ │ │ ├── OtherContainerInteractor.kt │ │ │ │ │ ├── OtherContainerNode.kt │ │ │ │ │ ├── OtherContainerView.kt │ │ │ │ │ └── routing │ │ │ │ │ │ ├── OtherContainerChildBuilders.kt │ │ │ │ │ │ └── OtherContainerRouter.kt │ │ │ │ └── picker │ │ │ │ │ ├── OtherPicker.kt │ │ │ │ │ ├── OtherPickerBuilder.kt │ │ │ │ │ ├── OtherPickerInteractor.kt │ │ │ │ │ ├── OtherPickerNode.kt │ │ │ │ │ ├── OtherPickerView.kt │ │ │ │ │ └── mapper │ │ │ │ │ └── ViewEventToOutput.kt │ │ │ │ ├── root │ │ │ │ ├── container │ │ │ │ │ ├── RootContainer.kt │ │ │ │ │ ├── RootContainerBuilder.kt │ │ │ │ │ ├── RootContainerInteractor.kt │ │ │ │ │ ├── RootContainerNode.kt │ │ │ │ │ ├── RootContainerView.kt │ │ │ │ │ ├── compose │ │ │ │ │ │ ├── Color.kt │ │ │ │ │ │ ├── Shape.kt │ │ │ │ │ │ ├── Theme.kt │ │ │ │ │ │ └── Type.kt │ │ │ │ │ └── routing │ │ │ │ │ │ ├── RootContainerChildBuilders.kt │ │ │ │ │ │ └── RootContainerRouter.kt │ │ │ │ └── picker │ │ │ │ │ ├── RootPicker.kt │ │ │ │ │ ├── RootPickerBuilder.kt │ │ │ │ │ ├── RootPickerInteractor.kt │ │ │ │ │ ├── RootPickerNode.kt │ │ │ │ │ ├── RootPickerView.kt │ │ │ │ │ └── mapper │ │ │ │ │ └── ViewEventToOutput.kt │ │ │ │ └── routing │ │ │ │ ├── routing_container │ │ │ │ ├── RoutingContainer.kt │ │ │ │ ├── RoutingContainerBuilder.kt │ │ │ │ ├── RoutingContainerInteractor.kt │ │ │ │ ├── RoutingContainerNode.kt │ │ │ │ ├── RoutingContainerView.kt │ │ │ │ └── routing │ │ │ │ │ ├── RoutingContainerChildBuilders.kt │ │ │ │ │ └── RoutingContainerRouter.kt │ │ │ │ └── routing_picker │ │ │ │ ├── RoutingPicker.kt │ │ │ │ ├── RoutingPickerBuilder.kt │ │ │ │ ├── RoutingPickerInteractor.kt │ │ │ │ ├── RoutingPickerNode.kt │ │ │ │ ├── RoutingPickerView.kt │ │ │ │ └── mapper │ │ │ │ └── ViewEventToOutput.kt │ │ │ └── res │ │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── drawable │ │ │ └── ic_launcher_background.xml │ │ │ ├── layout │ │ │ ├── activity_root.xml │ │ │ ├── rib_communication_container.xml │ │ │ └── rib_communication_picker.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── values-night │ │ │ └── themes.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ └── strings.xml │ ├── hello-world │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── detekt-baseline.xml │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── androidTest │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── helloworld │ │ │ │ └── HelloWorldTest.kt │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── helloworld │ │ │ │ ├── app │ │ │ │ └── RootActivity.kt │ │ │ │ └── hello_world │ │ │ │ ├── HelloWorld.kt │ │ │ │ ├── HelloWorldNode.kt │ │ │ │ ├── HelloWorldPresenter.kt │ │ │ │ ├── HelloWorldView.kt │ │ │ │ └── builder │ │ │ │ └── HelloWorldBuilder.kt │ │ │ └── res │ │ │ ├── layout │ │ │ ├── activity_root.xml │ │ │ └── rib_hello_world.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ └── unsplash-client │ │ ├── .gitignore │ │ ├── README.md │ │ ├── build.gradle │ │ ├── detekt-baseline.xml │ │ ├── proguard-rules.pro │ │ └── src │ │ ├── androidTest │ │ ├── java │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── example │ │ │ │ ├── FakeUserRepository.kt │ │ │ │ ├── TestImageLoader.kt │ │ │ │ ├── TestUtils.kt │ │ │ │ ├── app_bar │ │ │ │ └── AppBarTest.kt │ │ │ │ ├── element │ │ │ │ └── AppBarElement.kt │ │ │ │ └── rule │ │ │ │ └── FakeImageLoaderRule.kt │ │ └── res │ │ │ └── drawable │ │ │ └── ic_sample.png │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── example │ │ │ │ ├── RootActivity.kt │ │ │ │ ├── app_bar │ │ │ │ ├── AppBar.kt │ │ │ │ ├── AppBarBuilder.kt │ │ │ │ ├── AppBarInteractor.kt │ │ │ │ ├── AppBarNode.kt │ │ │ │ ├── AppBarView.kt │ │ │ │ └── mapper │ │ │ │ │ ├── UserToViewModel.kt │ │ │ │ │ └── ViewEventToOutput.kt │ │ │ │ ├── auth │ │ │ │ ├── AuthConfig.kt │ │ │ │ ├── AuthDataSource.kt │ │ │ │ ├── AuthState.kt │ │ │ │ ├── AuthStatePersistence.kt │ │ │ │ └── AuthStateStorage.kt │ │ │ │ ├── extensions │ │ │ │ ├── RibView.kt │ │ │ │ └── RxExt.kt │ │ │ │ ├── feed_container │ │ │ │ ├── FeedContainer.kt │ │ │ │ ├── FeedContainerBuilder.kt │ │ │ │ ├── FeedContainerInteractor.kt │ │ │ │ ├── FeedContainerNode.kt │ │ │ │ ├── FeedContainerView.kt │ │ │ │ ├── mapper │ │ │ │ │ └── FeedOutputToContainerOutput.kt │ │ │ │ └── routing │ │ │ │ │ ├── FeedContainerChildBuilders.kt │ │ │ │ │ └── FeedContainerRouter.kt │ │ │ │ ├── logged_in_container │ │ │ │ ├── LoggedInContainer.kt │ │ │ │ ├── LoggedInContainerBuilder.kt │ │ │ │ ├── LoggedInContainerInteractor.kt │ │ │ │ ├── LoggedInContainerNode.kt │ │ │ │ └── routing │ │ │ │ │ ├── LoggedInContainerChildBuilders.kt │ │ │ │ │ └── LoggedInContainerRouter.kt │ │ │ │ ├── logged_out_container │ │ │ │ ├── LoggedOutContainer.kt │ │ │ │ ├── LoggedOutContainerBuilder.kt │ │ │ │ ├── LoggedOutContainerInteractor.kt │ │ │ │ ├── LoggedOutContainerNode.kt │ │ │ │ └── routing │ │ │ │ │ ├── LoggedOutContainerChildBuilders.kt │ │ │ │ │ └── LoggedOutContainerRouter.kt │ │ │ │ ├── login │ │ │ │ ├── AuthCodeDataSource.kt │ │ │ │ ├── Login.kt │ │ │ │ ├── LoginBuilder.kt │ │ │ │ ├── LoginInteractor.kt │ │ │ │ ├── LoginNode.kt │ │ │ │ └── feature │ │ │ │ │ └── LoginFeature.kt │ │ │ │ ├── network │ │ │ │ ├── ApiFactory.kt │ │ │ │ ├── AuthInterceptor.kt │ │ │ │ ├── NetworkError.kt │ │ │ │ ├── UnauthorizedErrorInterceptor.kt │ │ │ │ ├── UnsplashApi.kt │ │ │ │ └── model │ │ │ │ │ ├── AccessToken.kt │ │ │ │ │ ├── Collection.kt │ │ │ │ │ ├── Links.kt │ │ │ │ │ ├── Photo.kt │ │ │ │ │ ├── SearchResult.kt │ │ │ │ │ ├── Urls.kt │ │ │ │ │ └── User.kt │ │ │ │ ├── photo_details │ │ │ │ ├── PhotoDetails.kt │ │ │ │ ├── PhotoDetailsBuilder.kt │ │ │ │ ├── PhotoDetailsDataSource.kt │ │ │ │ ├── PhotoDetailsInteractor.kt │ │ │ │ ├── PhotoDetailsNode.kt │ │ │ │ ├── PhotoDetailsView.kt │ │ │ │ ├── feature │ │ │ │ │ └── PhotoDetailsFeature.kt │ │ │ │ ├── mapper │ │ │ │ │ ├── NewsToOutput.kt │ │ │ │ │ ├── StateToViewModel.kt │ │ │ │ │ └── ViewEventToWish.kt │ │ │ │ └── routing │ │ │ │ │ ├── PhotoDetailsChildBuilders.kt │ │ │ │ │ └── PhotoDetailsRouter.kt │ │ │ │ ├── photo_feed │ │ │ │ ├── PhotoFeed.kt │ │ │ │ ├── PhotoFeedBuilder.kt │ │ │ │ ├── PhotoFeedDataSource.kt │ │ │ │ ├── PhotoFeedInteractor.kt │ │ │ │ ├── PhotoFeedNode.kt │ │ │ │ ├── feature │ │ │ │ │ └── PhotoFeedFeature.kt │ │ │ │ ├── mapper │ │ │ │ │ ├── StateToViewModel.kt │ │ │ │ │ ├── ViewEventToOutput.kt │ │ │ │ │ └── ViewEventToWish.kt │ │ │ │ └── view │ │ │ │ │ ├── AspectRatioDimensionsCalculator.kt │ │ │ │ │ ├── AspectRatioImageView.kt │ │ │ │ │ ├── PhotoFeedView.kt │ │ │ │ │ ├── PhotoListItem.kt │ │ │ │ │ ├── PhotoListItemViewHolder.kt │ │ │ │ │ └── PhotosAdapter.kt │ │ │ │ ├── repository │ │ │ │ └── UserRepository.kt │ │ │ │ ├── root │ │ │ │ ├── Root.kt │ │ │ │ ├── RootBuilder.kt │ │ │ │ ├── RootInteractor.kt │ │ │ │ ├── RootNode.kt │ │ │ │ └── routing │ │ │ │ │ ├── RootChildBuilders.kt │ │ │ │ │ └── RootRouter.kt │ │ │ │ └── welcome │ │ │ │ ├── Welcome.kt │ │ │ │ ├── WelcomeBuilder.kt │ │ │ │ ├── WelcomeInteractor.kt │ │ │ │ ├── WelcomeNode.kt │ │ │ │ ├── WelcomeView.kt │ │ │ │ └── mapper │ │ │ │ └── ViewEventToOutput.kt │ │ └── res │ │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── drawable │ │ │ ├── ic_launcher_background.xml │ │ │ ├── ic_like.xml │ │ │ ├── ic_like_empty.xml │ │ │ ├── ic_profile_placeholder.xml │ │ │ ├── ic_retry.xml │ │ │ └── ic_search.xml │ │ │ ├── layout │ │ │ ├── debug_switcher.xml │ │ │ ├── example_activity_root.xml │ │ │ ├── item_photo_feed_next_page_loading.xml │ │ │ ├── item_photo_feed_next_page_loading_error.xml │ │ │ ├── rib_app_bar.xml │ │ │ ├── rib_feed_container.xml │ │ │ ├── rib_login.xml │ │ │ ├── rib_photo_details.xml │ │ │ ├── rib_photo_feed.xml │ │ │ └── rib_welcome.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── values-night │ │ │ └── themes.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── themes.xml │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── badoo │ │ │ └── ribs │ │ │ └── example │ │ │ ├── ExampleUnitTest.kt │ │ │ ├── RxSchedulerExtension.kt │ │ │ ├── RxSchedulerRule.kt │ │ │ ├── auth │ │ │ └── AuthDataSourceImplTest.kt │ │ │ ├── root │ │ │ └── RootInteractorAuthStateTest.kt │ │ │ └── welcome │ │ │ └── WelcomeInteractorTest.kt │ │ └── resources │ │ └── mockito-extensions │ │ └── org.mockito.plugins.MockMaker ├── elements │ ├── android-integration │ │ ├── dialogs │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── detekt-baseline.xml │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ │ ├── androidTest │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── badoo │ │ │ │ │ └── ribs │ │ │ │ │ └── samples │ │ │ │ │ └── android │ │ │ │ │ └── dialogs │ │ │ │ │ ├── DialogsExampleTest.kt │ │ │ │ │ └── TextColorMatcher.kt │ │ │ │ └── main │ │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── badoo │ │ │ │ │ └── ribs │ │ │ │ │ └── samples │ │ │ │ │ └── android │ │ │ │ │ └── dialogs │ │ │ │ │ ├── dialogs │ │ │ │ │ ├── Dialogs.kt │ │ │ │ │ ├── LazyDialog.kt │ │ │ │ │ ├── RibDialog.kt │ │ │ │ │ ├── SimpleDialog.kt │ │ │ │ │ └── ThemedDialog.kt │ │ │ │ │ └── rib │ │ │ │ │ ├── dialogs_example │ │ │ │ │ ├── DialogsExample.kt │ │ │ │ │ ├── DialogsExampleBuilder.kt │ │ │ │ │ ├── DialogsExampleNode.kt │ │ │ │ │ ├── DialogsExamplePresenter.kt │ │ │ │ │ ├── DialogsExampleRouter.kt │ │ │ │ │ └── DialogsExampleView.kt │ │ │ │ │ └── dummy │ │ │ │ │ ├── Dummy.kt │ │ │ │ │ ├── DummyBuilder.kt │ │ │ │ │ ├── DummyNode.kt │ │ │ │ │ ├── DummyPresenter.kt │ │ │ │ │ └── DummyView.kt │ │ │ │ └── res │ │ │ │ ├── layout │ │ │ │ ├── activity_dialogs.xml │ │ │ │ ├── rib_dialogs.xml │ │ │ │ └── rib_dummy.xml │ │ │ │ └── values │ │ │ │ ├── colors.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ ├── launching-activities │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── detekt-baseline.xml │ │ │ └── src │ │ │ │ ├── androidTest │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── badoo │ │ │ │ │ └── ribs │ │ │ │ │ └── samples │ │ │ │ │ └── android │ │ │ │ │ └── launching_activities │ │ │ │ │ └── rib │ │ │ │ │ └── LaunchingActivitiesParentTest.kt │ │ │ │ └── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── badoo │ │ │ │ │ └── ribs │ │ │ │ │ └── samples │ │ │ │ │ └── android │ │ │ │ │ └── launching_activities │ │ │ │ │ ├── app │ │ │ │ │ └── OtherActivity.kt │ │ │ │ │ └── rib │ │ │ │ │ ├── child1 │ │ │ │ │ ├── LaunchingActivitiesChild1.kt │ │ │ │ │ ├── LaunchingActivitiesChild1Builder.kt │ │ │ │ │ └── LaunchingActivitiesChild1Node.kt │ │ │ │ │ ├── child2 │ │ │ │ │ ├── LaunchingActivitiesChild2.kt │ │ │ │ │ ├── LaunchingActivitiesChild2Builder.kt │ │ │ │ │ └── LaunchingActivitiesChild2Node.kt │ │ │ │ │ ├── child_common │ │ │ │ │ ├── LaunchingActivitiesChildBase.kt │ │ │ │ │ ├── LaunchingActivitiesChildInteractor.kt │ │ │ │ │ └── LaunchingActivitiesChildView.kt │ │ │ │ │ └── launching_activities_example │ │ │ │ │ ├── LaunchingActivitiesExample.kt │ │ │ │ │ ├── LaunchingActivitiesExampleBuilder.kt │ │ │ │ │ ├── LaunchingActivitiesExampleNode.kt │ │ │ │ │ ├── LaunchingActivitiesExampleView.kt │ │ │ │ │ └── routing │ │ │ │ │ ├── LaunchingActivitiesExampleChildBuilders.kt │ │ │ │ │ └── LaunchingActivitiesExampleRouter.kt │ │ │ │ └── res │ │ │ │ ├── layout │ │ │ │ ├── activity_root.xml │ │ │ │ ├── other_activity.xml │ │ │ │ ├── rib_launching_activities_child.xml │ │ │ │ └── rib_launching_activities_root.xml │ │ │ │ └── values │ │ │ │ └── strings.xml │ │ └── permissions │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── detekt-baseline.xml │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── android │ │ │ │ └── permissions │ │ │ │ └── rib │ │ │ │ ├── child1 │ │ │ │ ├── PermissionsSampleChild1.kt │ │ │ │ ├── PermissionsSampleChild1Builder.kt │ │ │ │ ├── PermissionsSampleChild1Node.kt │ │ │ │ ├── PermissionsSampleChild1Presenter.kt │ │ │ │ └── PermissionsSampleChild1View.kt │ │ │ │ ├── child2 │ │ │ │ ├── PermissionsSampleChild2.kt │ │ │ │ ├── PermissionsSampleChild2Builder.kt │ │ │ │ ├── PermissionsSampleChild2Node.kt │ │ │ │ ├── PermissionsSampleChild2Presenter.kt │ │ │ │ └── PermissionsSampleChild2ViewImpl.kt │ │ │ │ └── parent │ │ │ │ ├── PermissionsExample.kt │ │ │ │ ├── PermissionsExampleBuilder.kt │ │ │ │ ├── PermissionsExampleNode.kt │ │ │ │ ├── PermissionsExampleView.kt │ │ │ │ └── routing │ │ │ │ ├── PermissionsExampleChildBuilder.kt │ │ │ │ └── PermissionsExampleRouter.kt │ │ │ └── res │ │ │ ├── layout │ │ │ ├── rib_permissions_sample.xml │ │ │ └── rib_permissions_sample_parent.xml │ │ │ └── values │ │ │ └── strings.xml │ ├── communication │ │ ├── coordinate-multiple │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── detekt-baseline.xml │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ │ ├── androidTest │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── badoo │ │ │ │ │ └── ribs │ │ │ │ │ └── samples │ │ │ │ │ └── communication │ │ │ │ │ └── coordinate_multiple_example │ │ │ │ │ └── rib │ │ │ │ │ └── greeting_container │ │ │ │ │ └── GreetingContainerTest.kt │ │ │ │ └── main │ │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── badoo │ │ │ │ │ └── ribs │ │ │ │ │ └── samples │ │ │ │ │ └── communication │ │ │ │ │ └── coordinate_multiple_example │ │ │ │ │ └── rib │ │ │ │ │ ├── greeting │ │ │ │ │ ├── Greeting.kt │ │ │ │ │ ├── GreetingBuilder.kt │ │ │ │ │ ├── GreetingNode.kt │ │ │ │ │ ├── GreetingPresenter.kt │ │ │ │ │ └── GreetingView.kt │ │ │ │ │ ├── greeting_container │ │ │ │ │ ├── GreetingContainer.kt │ │ │ │ │ ├── GreetingContainerBuilder.kt │ │ │ │ │ ├── GreetingContainerInteractor.kt │ │ │ │ │ ├── GreetingContainerNode.kt │ │ │ │ │ ├── GreetingContainerView.kt │ │ │ │ │ └── routing │ │ │ │ │ │ ├── GreetingContainerChildBuilder.kt │ │ │ │ │ │ └── GreetingContainerRouter.kt │ │ │ │ │ └── language_selector │ │ │ │ │ ├── Language.kt │ │ │ │ │ ├── LanguageSelector.kt │ │ │ │ │ ├── LanguageSelectorBuilder.kt │ │ │ │ │ ├── LanguageSelectorNode.kt │ │ │ │ │ ├── LanguageSelectorPresenter.kt │ │ │ │ │ └── LanguageSelectorView.kt │ │ │ │ └── res │ │ │ │ ├── layout │ │ │ │ ├── activity_root.xml │ │ │ │ ├── rib_greeting.xml │ │ │ │ └── rib_language_selector.xml │ │ │ │ └── values │ │ │ │ └── strings.xml │ │ └── menu-example │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── detekt-baseline.xml │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ ├── androidTest │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── communication │ │ │ │ └── menu_example │ │ │ │ └── rib │ │ │ │ └── menu_example │ │ │ │ └── MenuExampleTest.kt │ │ │ └── main │ │ │ ├── java │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── communication │ │ │ │ └── menu_example │ │ │ │ └── rib │ │ │ │ ├── child1 │ │ │ │ ├── Child1.kt │ │ │ │ ├── Child1Builder.kt │ │ │ │ ├── Child1Node.kt │ │ │ │ └── Child1View.kt │ │ │ │ ├── child2 │ │ │ │ ├── Child2.kt │ │ │ │ ├── Child2Builder.kt │ │ │ │ ├── Child2Node.kt │ │ │ │ └── Child2View.kt │ │ │ │ ├── child3 │ │ │ │ ├── Child2View.kt │ │ │ │ ├── Child3.kt │ │ │ │ ├── Child3Builder.kt │ │ │ │ └── Child3Node.kt │ │ │ │ ├── menu │ │ │ │ ├── Menu.kt │ │ │ │ ├── MenuBuilder.kt │ │ │ │ ├── MenuNode.kt │ │ │ │ ├── MenuPresenter.kt │ │ │ │ └── MenuView.kt │ │ │ │ └── menu_example │ │ │ │ ├── MenuExample.kt │ │ │ │ ├── MenuExampleBuilder.kt │ │ │ │ ├── MenuExampleNode.kt │ │ │ │ ├── MenuExamplePresenter.kt │ │ │ │ ├── MenuExampleView.kt │ │ │ │ └── routing │ │ │ │ ├── MenuExampleChildBuilders.kt │ │ │ │ └── MenuExampleRouter.kt │ │ │ └── res │ │ │ ├── layout │ │ │ ├── activity_root.xml │ │ │ ├── rib_child1.xml │ │ │ ├── rib_child2.xml │ │ │ ├── rib_child3.xml │ │ │ ├── rib_container.xml │ │ │ └── rib_menu.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ └── strings.xml │ ├── other │ │ └── retained-instance-store │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── detekt-baseline.xml │ │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── retained_instance_store │ │ │ │ ├── rib │ │ │ │ ├── counter │ │ │ │ │ ├── Counter.kt │ │ │ │ │ ├── CounterBuilder.kt │ │ │ │ │ ├── CounterNode.kt │ │ │ │ │ ├── CounterPresenter.kt │ │ │ │ │ └── CounterView.kt │ │ │ │ └── retained_instance_example │ │ │ │ │ ├── RetainedInstanceExample.kt │ │ │ │ │ ├── RetainedInstanceExampleBuilder.kt │ │ │ │ │ ├── RetainedInstanceExampleNode.kt │ │ │ │ │ ├── RetainedInstanceExamplePresenter.kt │ │ │ │ │ ├── RetainedInstanceExampleRouter.kt │ │ │ │ │ └── RetainedInstanceExampleView.kt │ │ │ │ └── utils │ │ │ │ └── Clock.kt │ │ │ └── res │ │ │ ├── layout-land │ │ │ └── rib_retained_instance.xml │ │ │ ├── layout │ │ │ ├── activity_root.xml │ │ │ ├── rib_counter.xml │ │ │ └── rib_retained_instance.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ └── routing │ │ ├── back-stack │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── detekt-baseline.xml │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── androidTest │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── routing │ │ │ │ └── back_stack │ │ │ │ └── rib │ │ │ │ └── back_stack_example │ │ │ │ └── BackStackExampleTest.kt │ │ │ └── main │ │ │ ├── java │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── routing │ │ │ │ └── back_stack │ │ │ │ └── rib │ │ │ │ ├── back_stack_example │ │ │ │ ├── BackStackExample.kt │ │ │ │ ├── BackStackExampleBuilder.kt │ │ │ │ ├── BackStackExampleNode.kt │ │ │ │ ├── BackStackExamplePresenter.kt │ │ │ │ ├── BackStackExampleView.kt │ │ │ │ └── routing │ │ │ │ │ ├── BackStackExampleChildBuilders.kt │ │ │ │ │ └── BackStackExampleRouter.kt │ │ │ │ ├── child_a │ │ │ │ ├── ChildA.kt │ │ │ │ ├── ChildABuilder.kt │ │ │ │ ├── ChildANode.kt │ │ │ │ └── ChildAView.kt │ │ │ │ ├── child_b │ │ │ │ ├── ChildB.kt │ │ │ │ ├── ChildBBuilder.kt │ │ │ │ ├── ChildBNode.kt │ │ │ │ └── ChildBView.kt │ │ │ │ ├── child_c │ │ │ │ ├── ChildC.kt │ │ │ │ ├── ChildCBuilder.kt │ │ │ │ ├── ChildCNode.kt │ │ │ │ └── ChildCView.kt │ │ │ │ ├── child_d │ │ │ │ ├── ChildD.kt │ │ │ │ ├── ChildDBuilder.kt │ │ │ │ ├── ChildDNode.kt │ │ │ │ └── ChildDView.kt │ │ │ │ ├── child_e │ │ │ │ ├── ChildE.kt │ │ │ │ ├── ChildEBuilder.kt │ │ │ │ ├── ChildENode.kt │ │ │ │ └── ChildEView.kt │ │ │ │ └── child_f │ │ │ │ ├── ChildF.kt │ │ │ │ ├── ChildFBuilder.kt │ │ │ │ ├── ChildFNode.kt │ │ │ │ └── ChildFView.kt │ │ │ └── res │ │ │ ├── layout │ │ │ ├── activity_root.xml │ │ │ ├── rib_back_stack_example.xml │ │ │ ├── rib_child_a.xml │ │ │ ├── rib_child_b.xml │ │ │ ├── rib_child_c.xml │ │ │ ├── rib_child_d.xml │ │ │ ├── rib_child_e.xml │ │ │ └── rib_child_f.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ └── strings.xml │ │ ├── parameterised-routing │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── detekt-baseline.xml │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── androidTest │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── routing │ │ │ │ └── parameterised_routing │ │ │ │ └── rib │ │ │ │ ├── parameterised_routing_example │ │ │ │ └── ParameterisedRoutingExampleTest.kt │ │ │ │ └── profile │ │ │ │ └── ProfileTest.kt │ │ │ └── main │ │ │ ├── java │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── routing │ │ │ │ └── parameterised_routing │ │ │ │ └── rib │ │ │ │ ├── parameterised_routing_example │ │ │ │ ├── ParameterisedRoutingExample.kt │ │ │ │ ├── ParameterisedRoutingExampleBuilder.kt │ │ │ │ ├── ParameterisedRoutingExampleNode.kt │ │ │ │ ├── ParameterisedRoutingExamplePresenter.kt │ │ │ │ ├── ParameterisedRoutingExampleRouter.kt │ │ │ │ └── ParameterisedRoutingExampleView.kt │ │ │ │ └── profile │ │ │ │ ├── Profile.kt │ │ │ │ ├── ProfileBuilder.kt │ │ │ │ ├── ProfileNode.kt │ │ │ │ └── ProfileView.kt │ │ │ └── res │ │ │ ├── layout │ │ │ ├── activity_root.xml │ │ │ ├── rib_parameterised_routing_example.xml │ │ │ └── rib_profile.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ └── strings.xml │ │ ├── simple-routing-rib │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── detekt-baseline.xml │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── androidTest │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── routing │ │ │ │ └── simple_routing │ │ │ │ ├── SimpleRoutingChild1Child1Test.kt │ │ │ │ ├── SimpleRoutingChild1Child2Test.kt │ │ │ │ ├── SimpleRoutingChild1Test.kt │ │ │ │ ├── SimpleRoutingChild2Test.kt │ │ │ │ └── SimpleRoutingParentTest.kt │ │ │ └── main │ │ │ ├── java │ │ │ └── com │ │ │ │ └── badoo │ │ │ │ └── ribs │ │ │ │ └── samples │ │ │ │ └── routing │ │ │ │ └── simple_routing │ │ │ │ └── rib │ │ │ │ ├── child1 │ │ │ │ ├── Child1.kt │ │ │ │ ├── Child1Node.kt │ │ │ │ ├── Child1Presenter.kt │ │ │ │ ├── Child1View.kt │ │ │ │ ├── builder │ │ │ │ │ └── Child1Builder.kt │ │ │ │ └── routing │ │ │ │ │ ├── Child1ChildBuilders.kt │ │ │ │ │ └── Child1Router.kt │ │ │ │ ├── child1_child1 │ │ │ │ ├── Child1Child1.kt │ │ │ │ ├── Child1Child1Node.kt │ │ │ │ ├── Child1Child1View.kt │ │ │ │ └── builder │ │ │ │ │ └── Child1Child1Builder.kt │ │ │ │ ├── child1_child2 │ │ │ │ ├── Child1Child2.kt │ │ │ │ ├── Child1Child2Node.kt │ │ │ │ ├── Child1Child2View.kt │ │ │ │ └── builder │ │ │ │ │ └── Child1Child2Builder.kt │ │ │ │ ├── child2 │ │ │ │ ├── Child2.kt │ │ │ │ ├── Child2Node.kt │ │ │ │ ├── Child2Presenter.kt │ │ │ │ ├── SimpleRoutingView.kt │ │ │ │ └── builder │ │ │ │ │ └── Child2Builder.kt │ │ │ │ └── simple_routing_parent │ │ │ │ ├── SimpleRoutingParent.kt │ │ │ │ ├── SimpleRoutingParentNode.kt │ │ │ │ ├── SimpleRoutingParentView.kt │ │ │ │ ├── builder │ │ │ │ └── SimpleRoutingParentBuilder.kt │ │ │ │ └── routing │ │ │ │ ├── SimpleRoutingParentChildBuilders.kt │ │ │ │ └── SimpleRoutingParentRouter.kt │ │ │ └── res │ │ │ ├── layout │ │ │ ├── rib_simple_routing_child1.xml │ │ │ ├── rib_simple_routing_child1_child1.xml │ │ │ ├── rib_simple_routing_child1_child2.xml │ │ │ ├── rib_simple_routing_child2.xml │ │ │ └── rib_simple_routing_parent.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ └── strings.xml │ │ └── transition-animations │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── detekt-baseline.xml │ │ ├── proguard-rules.pro │ │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── badoo │ │ │ └── ribs │ │ │ └── samples │ │ │ └── routing │ │ │ └── transition_animations │ │ │ └── rib │ │ │ ├── child1 │ │ │ ├── Child1.kt │ │ │ ├── Child1Builder.kt │ │ │ ├── Child1Node.kt │ │ │ └── Child1View.kt │ │ │ ├── child2 │ │ │ ├── Child2.kt │ │ │ ├── Child2Builder.kt │ │ │ ├── Child2Node.kt │ │ │ └── Child2View.kt │ │ │ ├── child3 │ │ │ ├── Child3.kt │ │ │ ├── Child3Builder.kt │ │ │ ├── Child3Node.kt │ │ │ └── Child3View.kt │ │ │ └── transition_animations_example │ │ │ ├── TransitionAnimationsExample.kt │ │ │ ├── TransitionAnimationsExampleBuilder.kt │ │ │ ├── TransitionAnimationsExampleNode.kt │ │ │ ├── TransitionAnimationsExamplePresenter.kt │ │ │ ├── TransitionAnimationsExampleView.kt │ │ │ └── routing │ │ │ ├── TransitionAnimationsExampleChildBuilders.kt │ │ │ ├── TransitionAnimationsExampleRouter.kt │ │ │ └── TransitionAnimationsExampleTransitionHandler.kt │ │ └── res │ │ ├── drawable │ │ └── oval_bg.xml │ │ ├── layout │ │ ├── activity_root.xml │ │ ├── rib_child1.xml │ │ ├── rib_child2.xml │ │ ├── rib_child3.xml │ │ └── rib_transition_animations.xml │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── themes.xml └── resources │ ├── .gitignore │ ├── build.gradle │ ├── detekt-baseline.xml │ └── src │ └── main │ └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ └── ic_launcher_background.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ └── themes.xml ├── sandbox ├── .gitignore ├── build.gradle ├── detekt-baseline.xml ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── badoo │ │ └── ribs │ │ └── sandbox │ │ ├── app │ │ └── CompiledWorkflowTest.kt │ │ ├── matcher │ │ └── TextColorMatcher.kt │ │ └── rib │ │ ├── compose_parent │ │ └── ComposeParentTest.kt │ │ ├── dialog_example │ │ └── DialogExampleTest.kt │ │ ├── hello_world │ │ ├── HelloWorldTest.kt │ │ └── HelloWorldTestDeferred.kt │ │ ├── lorem_ipsum │ │ └── LoremIpsumTest.kt │ │ └── menu │ │ ├── MenuTest.kt │ │ ├── MenuViewTest.kt │ │ └── element │ │ ├── MenuElement.kt │ │ └── MenuItemElement.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── badoo │ │ │ └── ribs │ │ │ └── sandbox │ │ │ ├── app │ │ │ ├── AppRibCustomisations.kt │ │ │ ├── OtherActivity.kt │ │ │ └── RootActivity.kt │ │ │ ├── rib │ │ │ ├── big │ │ │ │ ├── Big.kt │ │ │ │ ├── BigBuilder.kt │ │ │ │ ├── BigInteractor.kt │ │ │ │ ├── BigNode.kt │ │ │ │ ├── BigView.kt │ │ │ │ └── routing │ │ │ │ │ ├── BigChildBuilders.kt │ │ │ │ │ └── BigRouter.kt │ │ │ ├── blocker │ │ │ │ ├── Blocker.kt │ │ │ │ ├── BlockerBuilder.kt │ │ │ │ ├── BlockerInteractor.kt │ │ │ │ ├── BlockerNode.kt │ │ │ │ ├── BlockerView.kt │ │ │ │ └── mapper │ │ │ │ │ └── ViewEventToOutput.kt │ │ │ ├── compose_leaf │ │ │ │ ├── ComposeLeaf.kt │ │ │ │ ├── ComposeLeafBuilder.kt │ │ │ │ ├── ComposeLeafInteractor.kt │ │ │ │ ├── ComposeLeafNode.kt │ │ │ │ └── ComposeLeafView.kt │ │ │ ├── compose_parent │ │ │ │ ├── ComposeParent.kt │ │ │ │ ├── ComposeParentBuilder.kt │ │ │ │ ├── ComposeParentInteractor.kt │ │ │ │ ├── ComposeParentNode.kt │ │ │ │ ├── ComposeParentView.kt │ │ │ │ └── routing │ │ │ │ │ ├── ComposeParentChildBuilders.kt │ │ │ │ │ └── ComposeParentRouter.kt │ │ │ ├── dialog_example │ │ │ │ ├── DialogExample.kt │ │ │ │ ├── DialogExampleBuilder.kt │ │ │ │ ├── DialogExampleInteractor.kt │ │ │ │ ├── DialogExampleNode.kt │ │ │ │ ├── DialogExampleView.kt │ │ │ │ ├── dialog │ │ │ │ │ ├── Dialogs.kt │ │ │ │ │ ├── LazyDialog.kt │ │ │ │ │ ├── RibDialog.kt │ │ │ │ │ ├── SimpleDialog.kt │ │ │ │ │ └── ThemedDialog.kt │ │ │ │ └── routing │ │ │ │ │ ├── DialogExampleChildBuilders.kt │ │ │ │ │ └── DialogExampleRouter.kt │ │ │ ├── foo_bar │ │ │ │ ├── FooBar.kt │ │ │ │ ├── FooBarBuilder.kt │ │ │ │ ├── FooBarInteractor.kt │ │ │ │ ├── FooBarNode.kt │ │ │ │ ├── FooBarView.kt │ │ │ │ ├── analytics │ │ │ │ │ └── FooBarAnalytics.kt │ │ │ │ ├── feature │ │ │ │ │ └── FooBarFeature.kt │ │ │ │ ├── mapper │ │ │ │ │ └── ViewEventToAnalyticsEvent.kt │ │ │ │ └── viewplugin │ │ │ │ │ └── ParentLongClickListener.kt │ │ │ ├── hello_world │ │ │ │ ├── HelloDebugView.kt │ │ │ │ ├── HelloWorld.kt │ │ │ │ ├── HelloWorldBuilder.kt │ │ │ │ ├── HelloWorldInteractor.kt │ │ │ │ ├── HelloWorldNode.kt │ │ │ │ ├── HelloWorldView.kt │ │ │ │ ├── analytics │ │ │ │ │ └── HelloWorldAnalytics.kt │ │ │ │ ├── feature │ │ │ │ │ └── HelloWorldFeature.kt │ │ │ │ ├── mapper │ │ │ │ │ ├── InputToWish.kt │ │ │ │ │ ├── NewsToOutput.kt │ │ │ │ │ └── ViewEventToAnalyticsEvent.kt │ │ │ │ └── routing │ │ │ │ │ ├── HelloWorldChildBuilders.kt │ │ │ │ │ └── HelloWorldRouter.kt │ │ │ ├── lorem_ipsum │ │ │ │ ├── LoremIpsum.kt │ │ │ │ ├── LoremIpsumBuilder.kt │ │ │ │ ├── LoremIpsumInteractor.kt │ │ │ │ ├── LoremIpsumNode.kt │ │ │ │ ├── LoremIpsumView.kt │ │ │ │ └── mapper │ │ │ │ │ └── ViewEventToOutput.kt │ │ │ ├── menu │ │ │ │ ├── Menu.kt │ │ │ │ ├── MenuBuilder.kt │ │ │ │ ├── MenuInteractor.kt │ │ │ │ ├── MenuNode.kt │ │ │ │ ├── MenuView.kt │ │ │ │ ├── feature │ │ │ │ │ └── MenuFeature.kt │ │ │ │ └── mapper │ │ │ │ │ ├── InputToState.kt │ │ │ │ │ ├── StateToViewModel.kt │ │ │ │ │ └── ViewEventToOutput.kt │ │ │ ├── portal_overlay_test │ │ │ │ ├── PortalOverlayTest.kt │ │ │ │ ├── PortalOverlayTestBuilder.kt │ │ │ │ ├── PortalOverlayTestInteractor.kt │ │ │ │ ├── PortalOverlayTestNode.kt │ │ │ │ └── PortalOverlayTestView.kt │ │ │ ├── small │ │ │ │ ├── Small.kt │ │ │ │ ├── SmallBuilder.kt │ │ │ │ ├── SmallInteractor.kt │ │ │ │ ├── SmallNode.kt │ │ │ │ ├── SmallView.kt │ │ │ │ └── routing │ │ │ │ │ ├── SmallChildBuilders.kt │ │ │ │ │ └── SmallRouter.kt │ │ │ └── switcher │ │ │ │ ├── Switcher.kt │ │ │ │ ├── SwitcherBuilder.kt │ │ │ │ ├── SwitcherDebugView.kt │ │ │ │ ├── SwitcherInteractor.kt │ │ │ │ ├── SwitcherNode.kt │ │ │ │ ├── SwitcherView.kt │ │ │ │ ├── dialog │ │ │ │ └── DialogToTestOverlay.kt │ │ │ │ └── routing │ │ │ │ ├── SwitcherChildBuilders.kt │ │ │ │ ├── SwitcherRouter.kt │ │ │ │ └── SwitcherTransitionHandler.kt │ │ │ └── util │ │ │ └── CoffeeMachine.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_other.xml │ │ ├── activity_root.xml │ │ ├── debug_helloworld.xml │ │ ├── debug_switcher.xml │ │ ├── rib_big.xml │ │ ├── rib_blocker.xml │ │ ├── rib_dialog_example.xml │ │ ├── rib_foobar.xml │ │ ├── rib_foobar_override.xml │ │ ├── rib_hello_world.xml │ │ ├── rib_hello_world_doc.xml │ │ ├── rib_lorem_ipsum.xml │ │ ├── rib_lorem_ipsum_override.xml │ │ ├── rib_menu.xml │ │ ├── rib_portal_overlay_test.xml │ │ ├── rib_small.xml │ │ └── rib_switcher.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ ├── java │ └── com │ │ └── badoo │ │ └── ribs │ │ └── sandbox │ │ └── rib │ │ ├── dialog_example │ │ └── DialogExampleRouterTest.kt │ │ ├── foo_bar │ │ └── FooBarInteractorTest.kt │ │ ├── lorem_ipsum │ │ └── LoremIpsumInteractorTest.kt │ │ ├── menu │ │ ├── MenuRibTest.kt │ │ └── feature │ │ │ └── MenuFeatureTest.kt │ │ ├── switcher │ │ ├── SwitcherInteractorTest.kt │ │ └── SwitcherRouterTest.kt │ │ ├── test │ │ └── MainScreenTest.kt │ │ └── util │ │ ├── IntentMatchers.kt │ │ ├── RxExtensions.kt │ │ ├── TestActivityStarter.kt │ │ ├── TestDefaultDependencies.kt │ │ ├── TestNode.kt │ │ ├── TestPermissionRequester.kt │ │ └── TestView.kt │ └── resources │ └── mockito-extensions │ └── org.mockito.plugins.MockMaker └── settings.gradle /documentation/barebone.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/badoo/RIBs/9ca011c5423246f2abafd88725e5b808f249288d/documentation/barebone.md -------------------------------------------------------------------------------- /documentation/experimental/jetpack-compose.md: -------------------------------------------------------------------------------- 1 | # Jetpack Compose support 2 | 3 | RIBs support Jetpack Compose! 4 | 5 | What you get: 6 | - Some new modules enabled (you can check `settings.gradle` to see which) 7 | - Compose-based implementation of `RibView`: `ComposeRibView` 8 | - Demo in `sandbox` app 9 | -------------------------------------------------------------------------------- /documentation/ourapproach.md: -------------------------------------------------------------------------------- 1 | - Our approach 2 | - Divide & conquer 3 | - Tree structure (Node, parent, child, sibling) 4 | - Complexity 5 | - DI 6 | - Testing in isolation 7 | - Reuse 8 | - Unopinionated 9 | - Plugins-based 10 | - State persistence 11 | - Transitions 12 | -------------------------------------------------------------------------------- /documentation/testing/compatibility.md: -------------------------------------------------------------------------------- 1 | # Compatibility with testing frameworks 2 | 3 | We tried to make the testing suite decoupled from any testing framework (JUnit4/JUnit5/Kotest and etc.) and want to try to keep it so. 4 | `rib-base-test-activity` the only module that has direct dependency on JUnit4 and Espresso to provide convenient rule to run tests. 5 | If you experience any incompatibility issues, feel free to create your own test helper classes based on our logic that suits your requirements. 6 | You can share your experience in the issues section or propose a pull request to improve it. 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/badoo/RIBs/9ca011c5423246f2abafd88725e5b808f249288d/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Apr 02 17:45:41 BST 2025 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /internal/junitextensions/build.gradle: -------------------------------------------------------------------------------- 1 | configureAndroidLibrary(project) 2 | 3 | apply from: rootProject.file('gradle/code-coverage.gradle') 4 | 5 | dependencies { 6 | implementation deps.test.junitApi 7 | implementation deps.android.archCoreTesting 8 | } 9 | 10 | android { 11 | namespace 'com.badoo.ribs.internal.junitextensions' 12 | 13 | packagingOptions { 14 | jniLibs { 15 | excludes += ['META-INF/LICENSE*.*'] 16 | } 17 | resources { 18 | excludes += ['META-INF/LICENSE*.*'] 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /internal/junitextensions/src/main/resources/META-INF/services/org.junit.jupiter.api.extension.Extension: -------------------------------------------------------------------------------- 1 | com.badoo.ribs.internal.junitextensions.AndroidXArchCoreExtension 2 | -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | jdk: 2 | - openjdk17 3 | install: 4 | - echo "Building artifacts" 5 | - ./gradlew clean publishToMavenLocal 6 | -------------------------------------------------------------------------------- /libraries/rib-base-test-activity/build.gradle: -------------------------------------------------------------------------------- 1 | configureAndroidLibrary(project) 2 | 3 | android { 4 | namespace 'com.badoo.ribs.test.activity' 5 | 6 | defaultConfig { 7 | versionCode 1 8 | versionName '1.0' 9 | } 10 | 11 | buildTypes { 12 | release { 13 | minifyEnabled false 14 | proguardFiles getDefaultProguardFile('proguard-android.txt') 15 | } 16 | } 17 | } 18 | 19 | dependencies { 20 | implementation deps.android.appCompat 21 | 22 | api project(':libraries:rib-base') 23 | api deps.test.junit4 24 | api deps.android.rules 25 | 26 | androidTestImplementation deps.androidTest.espresso 27 | } 28 | 29 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 30 | -------------------------------------------------------------------------------- /libraries/rib-base-test-activity/detekt-baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /libraries/rib-base-test-activity/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=RIBs (Base Test Activity) 2 | POM_ARTIFACT_ID=rib-base-test-activity 3 | POM_PACKAGING=android 4 | -------------------------------------------------------------------------------- /libraries/rib-base-test-activity/lint-baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /libraries/rib-base-test-activity/src/androidTest/java/com/badoo/ribs/test/AutoLaunchRibsRuleTest.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test 2 | 3 | import com.badoo.ribs.test.activity.R 4 | import org.junit.Rule 5 | 6 | class AutoLaunchRibsRuleTest : RibsRuleTestBase(invokeStart = false) { 7 | 8 | @get:Rule 9 | override val rule = RibsRule( 10 | theme = R.style.Theme_AppCompat_Dialog, 11 | builder = this.builder 12 | ) 13 | 14 | } 15 | -------------------------------------------------------------------------------- /libraries/rib-base-test-activity/src/androidTest/java/com/badoo/ribs/test/ManualLaunchRibsRuleTest.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test 2 | 3 | import com.badoo.ribs.test.activity.R 4 | import com.badoo.ribs.test.sample.SampleRib 5 | import org.junit.Rule 6 | 7 | class ManualLaunchRibsRuleTest : RibsRuleTestBase(invokeStart = true) { 8 | 9 | @get:Rule 10 | override val rule = RibsRule( 11 | theme = R.style.Theme_AppCompat_Dialog, 12 | ) 13 | 14 | } 15 | -------------------------------------------------------------------------------- /libraries/rib-base-test-activity/src/androidTest/java/com/badoo/ribs/test/sample/SampleBuilder.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.sample 2 | 3 | import com.badoo.ribs.builder.SimpleBuilder 4 | import com.badoo.ribs.core.modality.BuildParams 5 | 6 | class SampleBuilder : SimpleBuilder() { 7 | override fun build(buildParams: BuildParams): SampleRib = 8 | SampleNode(buildParams) 9 | } 10 | -------------------------------------------------------------------------------- /libraries/rib-base-test-activity/src/androidTest/java/com/badoo/ribs/test/sample/SampleNode.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.sample 2 | 3 | import com.badoo.ribs.core.Node 4 | import com.badoo.ribs.core.modality.BuildParams 5 | 6 | class SampleNode( 7 | buildParams: BuildParams<*> 8 | ) : Node( 9 | buildParams = buildParams, 10 | viewFactory = { SampleViewImpl(it) } 11 | ), SampleRib 12 | -------------------------------------------------------------------------------- /libraries/rib-base-test-activity/src/androidTest/java/com/badoo/ribs/test/sample/SampleRib.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.sample 2 | 3 | import com.badoo.ribs.core.Rib 4 | 5 | interface SampleRib : Rib 6 | -------------------------------------------------------------------------------- /libraries/rib-base-test-activity/src/androidTest/java/com/badoo/ribs/test/view/AutoLaunchRibsViewRuleTest.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.view 2 | 3 | import com.badoo.ribs.test.activity.R 4 | import com.badoo.ribs.test.sample.SampleViewImpl 5 | import org.junit.Rule 6 | 7 | class AutoLaunchRibsViewRuleTest : RibsViewRuleTestBase(invokeStart = false) { 8 | 9 | @get:Rule 10 | override val rule = RibsViewRule( 11 | launchActivity = true, 12 | theme = R.style.Theme_AppCompat_Dialog, 13 | viewFactory = { SampleViewImpl(it) } 14 | ) 15 | 16 | } 17 | -------------------------------------------------------------------------------- /libraries/rib-base-test-activity/src/androidTest/java/com/badoo/ribs/test/view/ManualLaunchRibsViewRuleTest.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.view 2 | 3 | import com.badoo.ribs.test.activity.R 4 | import com.badoo.ribs.test.sample.SampleViewImpl 5 | import org.junit.Rule 6 | 7 | class ManualLaunchRibsViewRuleTest : RibsViewRuleTestBase(invokeStart = true) { 8 | 9 | @get:Rule 10 | override val rule = RibsViewRule( 11 | launchActivity = false, 12 | theme = R.style.Theme_AppCompat_Dialog, 13 | viewFactory = { SampleViewImpl(it) } 14 | ) 15 | 16 | } 17 | -------------------------------------------------------------------------------- /libraries/rib-base-test-activity/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /libraries/rib-base-test-activity/src/main/java/com/badoo/ribs/compatibility.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs 2 | 3 | import com.badoo.ribs.core.Rib 4 | 5 | @Deprecated("Use new package name") 6 | typealias RibTestActivity = com.badoo.ribs.test.RibTestActivity 7 | 8 | @Deprecated("Use new package name") 9 | typealias RibsRule = com.badoo.ribs.test.RibsRule 10 | -------------------------------------------------------------------------------- /libraries/rib-base-test-activity/src/main/res/layout/rib_test.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /libraries/rib-base-test-rx3/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /libraries/rib-base-test-rx3/detekt-baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /libraries/rib-base-test-rx3/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=RIBs (Base Test Rx3 helpers) 2 | POM_ARTIFACT_ID=rib-base-test-rx3 3 | POM_PACKAGING=android 4 | -------------------------------------------------------------------------------- /libraries/rib-base-test-rx3/lint-baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /libraries/rib-base-test/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /libraries/rib-base-test/build.gradle: -------------------------------------------------------------------------------- 1 | configureAndroidLibrary(project) 2 | 3 | android { 4 | namespace 'com.badoo.ribs.test' 5 | 6 | defaultConfig { 7 | versionCode 1 8 | versionName '1.0' 9 | } 10 | 11 | buildTypes { 12 | release { 13 | minifyEnabled false 14 | proguardFiles getDefaultProguardFile('proguard-android.txt') 15 | } 16 | } 17 | } 18 | 19 | dependencies { 20 | compileOnly project(':libraries:rib-base') 21 | implementation deps.test.mockitoKotlin 22 | } 23 | 24 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 25 | -------------------------------------------------------------------------------- /libraries/rib-base-test/detekt-baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /libraries/rib-base-test/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=RIBs (Base Test) 2 | POM_ARTIFACT_ID=rib-base-test 3 | POM_PACKAGING=android 4 | -------------------------------------------------------------------------------- /libraries/rib-base-test/lint-baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /libraries/rib-base-test/src/main/java/com/badoo/ribs/test/CustomisationExt.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test 2 | 3 | import com.badoo.ribs.core.customisation.RibCustomisation 4 | import com.badoo.ribs.core.customisation.RibCustomisationDirectory 5 | import com.badoo.ribs.core.customisation.RibCustomisationDirectoryImpl 6 | import com.bumble.appyx.utils.customisations.put 7 | 8 | inline fun T.toDirectory(): RibCustomisationDirectory = 9 | RibCustomisationDirectoryImpl().also { it.put { this } } 10 | -------------------------------------------------------------------------------- /libraries/rib-base-test/src/main/java/com/badoo/ribs/test/Empty.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test 2 | 3 | import com.badoo.ribs.core.customisation.RibCustomisationDirectoryImpl 4 | import com.badoo.ribs.core.modality.BuildParams 5 | 6 | fun emptyBuildParams(): BuildParams = 7 | BuildParams( 8 | payload = null, 9 | buildContext = com.badoo.ribs.core.modality.BuildContext.root( 10 | savedInstanceState = null, 11 | customisations = RibCustomisationDirectoryImpl() 12 | ) 13 | ) 14 | -------------------------------------------------------------------------------- /libraries/rib-base-test/src/main/java/com/badoo/ribs/test/assert.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test 2 | 3 | import kotlin.reflect.KClass 4 | 5 | fun assertTrue(check: Boolean, error: () -> String) { 6 | if (!check) throw AssertionError(error()) 7 | } 8 | 9 | fun assertEquals(expected: T, actual: T, error: (() -> String)? = null) { 10 | if (actual != expected) { 11 | throw AssertionError(error?.invoke() ?: "Expected: $expected, but received $actual") 12 | } 13 | } 14 | 15 | fun assertInstanceOf(expected: KClass<*>, actual: Any?) { 16 | if (!expected.isInstance(actual)) { 17 | throw AssertionError("Expected $actual to be instance of ${expected.qualifiedName}") 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /libraries/rib-base-test/src/main/java/com/badoo/ribs/test/builder/RibBuilderStubExt.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.builder 2 | 3 | import androidx.lifecycle.Lifecycle 4 | import com.badoo.ribs.test.assertEquals 5 | 6 | fun RibBuilderStub<*, *>.assertLastNodeLifecycleState(state: Lifecycle.State) { 7 | assertEquals(state, lastNode?.lifecycle?.currentState) 8 | } 9 | 10 | fun RibBuilderStub<*, *>.assertLastNodeResumed() { 11 | assertLastNodeLifecycleState(Lifecycle.State.RESUMED) 12 | } 13 | 14 | fun RibBuilderStub<*, *>.assertLastNodeStarted() { 15 | assertLastNodeLifecycleState(Lifecycle.State.STARTED) 16 | } 17 | -------------------------------------------------------------------------------- /libraries/rib-base-test/src/main/java/com/badoo/ribs/test/node/RibNodeStub.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.node 2 | 3 | import com.badoo.ribs.core.Node 4 | import com.badoo.ribs.core.modality.BuildParams 5 | import com.badoo.ribs.core.plugin.Plugin 6 | import com.badoo.ribs.core.view.RibView 7 | import com.badoo.ribs.core.view.ViewFactory 8 | import com.badoo.ribs.test.emptyBuildParams 9 | 10 | open class RibNodeStub( 11 | buildParams: BuildParams<*> = emptyBuildParams(), 12 | plugins: List = emptyList(), 13 | viewFactory: ViewFactory? = null, 14 | ) : Node( 15 | buildParams = buildParams, 16 | viewFactory = viewFactory, 17 | plugins = plugins, 18 | ) 19 | -------------------------------------------------------------------------------- /libraries/rib-base/README.md: -------------------------------------------------------------------------------- 1 | # rib-base 2 | 3 | This module is responsible for defining base rib components. 4 | -------------------------------------------------------------------------------- /libraries/rib-base/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=RIBs (Base) 2 | POM_ARTIFACT_ID=rib-base 3 | POM_PACKAGING=android 4 | -------------------------------------------------------------------------------- /libraries/rib-base/lint-baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /libraries/rib-base/src/androidTest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /libraries/rib-base/src/androidTest/java/com/badoo/ribs/android/lifecycle/PushTwoPopOneDefaultTest.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.android.lifecycle 2 | 3 | import com.badoo.ribs.android.lifecycle.helper.ExpectedState 4 | import com.badoo.ribs.test.util.runOnMainSync 5 | 6 | class PushTwoPopOneDefaultTest : PushTwoPopOneTest() { 7 | 8 | override fun pushTwoConfigurationAndPop(setup: When, expectedState: ExpectedState) { 9 | test(setup, expectedState) { backStack, _ -> 10 | runOnMainSync { 11 | backStack.pushIt(setup.configuration1!!) 12 | backStack.pushIt(setup.configuration2!!) 13 | backStack.popBackStack() 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /libraries/rib-base/src/androidTest/java/com/badoo/ribs/android/lifecycle/helper/ExpectedState.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.android.lifecycle.helper 2 | 3 | data class ExpectedState( 4 | val permanentNode1: NodeState? = null, 5 | val permanentNode2: NodeState? = null, 6 | val node1: NodeState? = null, 7 | val node2: NodeState? = null, 8 | val node3: NodeState? = null 9 | ) 10 | -------------------------------------------------------------------------------- /libraries/rib-base/src/androidTest/java/com/badoo/ribs/android/lifecycle/transition/TransitionBaseNodeTest.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.android.lifecycle.transition 2 | 3 | import com.badoo.ribs.android.lifecycle.BaseNodesTest 4 | import com.badoo.ribs.routing.transition.handler.Slider 5 | import com.badoo.ribs.routing.transition.handler.TransitionHandler 6 | import com.badoo.ribs.test.util.ribs.root.TestRootRouter 7 | 8 | open class TransitionBaseNodeTest : BaseNodesTest() { 9 | 10 | override val transitionHandler: TransitionHandler? 11 | get() = Slider() 12 | } 13 | -------------------------------------------------------------------------------- /libraries/rib-base/src/androidTest/java/com/badoo/ribs/test/util/NoOpDialogLauncher.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.util 2 | 3 | import com.badoo.ribs.android.dialog.Dialog 4 | import com.badoo.ribs.android.dialog.DialogLauncher 5 | 6 | class NoOpDialogLauncher : DialogLauncher { 7 | 8 | override fun show(dialog: Dialog<*>, onClose: () -> Unit) { 9 | } 10 | 11 | override fun hide(dialog: Dialog<*>) { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /libraries/rib-base/src/androidTest/java/com/badoo/ribs/test/util/OtherActivity.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.util 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | 5 | class OtherActivity : AppCompatActivity() 6 | -------------------------------------------------------------------------------- /libraries/rib-base/src/androidTest/java/com/badoo/ribs/test/util/RxTestUtils.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.util 2 | 3 | import androidx.lifecycle.Lifecycle 4 | import io.reactivex.rxjava3.core.Observable 5 | import io.reactivex.rxjava3.observers.TestObserver 6 | 7 | fun Observable.subscribeOnTestObserver() = TestObserver().apply { 8 | subscribe(this) 9 | } 10 | 11 | class LifecycleObserver : TestObserver() { 12 | fun clear() { 13 | values.clear() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /libraries/rib-base/src/androidTest/java/com/badoo/ribs/test/util/TestRequestCodeClient.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.util 2 | 3 | import com.badoo.ribs.android.requestcode.RequestCodeClient 4 | 5 | class TestRequestCodeClient(override val requestCodeClientId: String = "test") : 6 | RequestCodeClient 7 | -------------------------------------------------------------------------------- /libraries/rib-base/src/androidTest/java/com/badoo/ribs/test/util/ribs/TestRibDialog.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.util.ribs 2 | 3 | import com.badoo.ribs.android.dialog.Dialog 4 | import com.badoo.ribs.android.dialog.RibFactory 5 | 6 | class TestRibDialog( 7 | ribFactory: RibFactory 8 | ) : Dialog({ 9 | ribFactory(ribFactory = ribFactory) 10 | }) 11 | -------------------------------------------------------------------------------- /libraries/rib-base/src/androidTest/java/com/badoo/ribs/test/util/ribs/child/TestChild.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.util.ribs.child 2 | 3 | import com.badoo.ribs.core.Rib 4 | 5 | interface TestChild : Rib { 6 | 7 | interface Dependency 8 | } 9 | -------------------------------------------------------------------------------- /libraries/rib-base/src/androidTest/java/com/badoo/ribs/test/util/ribs/child/TestChildInteractor.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.util.ribs.child 2 | 3 | import com.badoo.ribs.clienthelper.interactor.Interactor 4 | import com.badoo.ribs.core.modality.BuildParams 5 | 6 | class TestChildInteractor( 7 | buildParams: BuildParams<*> 8 | ) : Interactor( 9 | buildParams = buildParams 10 | ) 11 | -------------------------------------------------------------------------------- /libraries/rib-base/src/androidTest/java/com/badoo/ribs/test/util/ribs/root/TestRootView.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.test.util.ribs.root 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.ViewGroup 6 | import android.widget.FrameLayout 7 | import com.badoo.ribs.core.view.AndroidRibView 8 | import com.badoo.ribs.core.view.RibView 9 | 10 | interface TestRootView : RibView 11 | 12 | class TestRootViewImpl( 13 | context: Context, attrs: AttributeSet? = null, defStyle: Int = 0 14 | ) : AndroidRibView(), 15 | TestRootView { 16 | 17 | override val androidView: ViewGroup by lazy { 18 | FrameLayout(context, attrs, defStyle) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/android/AndroidRibViewHost.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.android 2 | 3 | import android.view.ViewGroup 4 | import com.badoo.ribs.core.view.AndroidRibView 5 | 6 | class AndroidRibViewHost( 7 | host: ViewGroup 8 | ) : AndroidRibView() { 9 | 10 | override val androidView: ViewGroup = 11 | host 12 | } 13 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/android/activitystarter/ActivityResultHandler.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.android.activitystarter 2 | 3 | import android.content.Intent 4 | 5 | interface ActivityResultHandler { 6 | 7 | fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) 8 | } 9 | 10 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/android/activitystarter/CanProvideActivityStarter.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.android.activitystarter 2 | 3 | interface CanProvideActivityStarter { 4 | val activityStarter: ActivityStarter 5 | } 6 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/android/dialog/CanProvideDialogLauncher.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.android.dialog 2 | 3 | interface CanProvideDialogLauncher { 4 | val dialogLauncher: DialogLauncher 5 | } 6 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/android/dialog/DialogLauncher.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.android.dialog 2 | 3 | interface DialogLauncher { 4 | 5 | fun show(dialog: Dialog<*>, onClose: () -> Unit) 6 | 7 | fun hide(dialog: Dialog<*>) 8 | } 9 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/android/dialog/RibFactory.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.android.dialog 2 | 3 | import com.badoo.ribs.core.Rib 4 | import com.badoo.ribs.core.modality.BuildContext 5 | 6 | typealias RibFactory = (buildContext: BuildContext) -> Rib 7 | 8 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/android/permissionrequester/CanProvidePermissionRequester.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.android.permissionrequester 2 | 3 | interface CanProvidePermissionRequester { 4 | val permissionRequester: PermissionRequester 5 | } 6 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/android/permissionrequester/PermissionRequestResultHandler.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.android.permissionrequester 2 | 3 | interface PermissionRequestResultHandler { 4 | 5 | fun onRequestPermissionsResult( 6 | requestCode: Int, 7 | permissions: Array, 8 | grantResults: IntArray 9 | ) 10 | } 11 | 12 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/android/requestcode/RequestCodeBasedEventStream.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.android.requestcode 2 | 3 | import com.badoo.ribs.android.requestcode.RequestCodeBasedEventStream.RequestCodeBasedEvent 4 | import com.badoo.ribs.minimal.reactive.Source 5 | 6 | interface RequestCodeBasedEventStream { 7 | 8 | fun events(client: RequestCodeClient): Source 9 | 10 | interface RequestCodeBasedEvent { 11 | val requestCode: Int 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/android/requestcode/RequestCodeClient.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.android.requestcode 2 | 3 | interface RequestCodeClient { 4 | 5 | val requestCodeClientId: String 6 | } 7 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/android/requestcode/RequestCodeDoesntFitInMask.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.android.requestcode 2 | 3 | class RequestCodeDoesntFitInMask(override val message: String?) : RuntimeException(message) 4 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/annotation/ExperimentalApi.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.annotation 2 | 3 | @RequiresOptIn(message = "This API is experimental. It may be changed in the future without notice.") 4 | @Retention(AnnotationRetention.BINARY) 5 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 6 | annotation class ExperimentalApi 7 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/annotation/OutdatedDocumentation.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.annotation 2 | 3 | @Retention(AnnotationRetention.SOURCE) 4 | annotation class OutdatedDocumentation 5 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/builder/SimpleBuilder.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.builder 2 | 3 | import com.badoo.ribs.core.Rib 4 | import com.badoo.ribs.core.modality.BuildContext 5 | 6 | /** 7 | * Simplified version of [Builder] that doesn't have build-time payload. 8 | */ 9 | abstract class SimpleBuilder : Builder() { 10 | 11 | fun build(buildContext: BuildContext): T = 12 | build(buildContext, null) 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/clienthelper/childaware/Callbacks.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.clienthelper.childaware 2 | 3 | import androidx.lifecycle.Lifecycle 4 | 5 | typealias ChildrenCallback = (commonLifecycle: Lifecycle, child1: T1, child2: T2) -> Unit 6 | 7 | typealias ChildCallback = (commonLifecycle: Lifecycle, child: T) -> Unit 8 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/clienthelper/childaware/LifecycleExt.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.clienthelper.childaware 2 | 3 | import androidx.lifecycle.Lifecycle 4 | 5 | internal val Lifecycle.isDestroyed 6 | get() = currentState == Lifecycle.State.DESTROYED 7 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/clienthelper/connector/Connectable.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.clienthelper.connector 2 | 3 | import com.badoo.ribs.core.plugin.NodeLifecycleAware 4 | import com.badoo.ribs.minimal.reactive.Relay 5 | 6 | interface Connectable : NodeLifecycleAware { 7 | val input: Relay 8 | val output: Relay 9 | } 10 | 11 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/core/Rib.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core 2 | 3 | import java.util.UUID 4 | 5 | /** 6 | * The conceptual main element of the system. 7 | */ 8 | interface Rib { 9 | 10 | val node: Node<*> 11 | 12 | data class Identifier( 13 | val uuid: UUID 14 | ) { 15 | 16 | companion object { 17 | internal const val KEY_UUID = "rib.uuid" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/core/customisation/MutableRibCustomisationDirectory.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.customisation 2 | 3 | import com.bumble.appyx.utils.customisations.MutableNodeCustomisationDirectory 4 | 5 | @Deprecated("Use com.bumble.appyx.utils.customisations.MutableNodeCustomisationDirectory") 6 | typealias MutableRibCustomisationDirectory = MutableNodeCustomisationDirectory 7 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/core/customisation/RibCustomisation.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.customisation 2 | 3 | import com.bumble.appyx.utils.customisations.NodeCustomisation 4 | 5 | @Deprecated("Use com.bumble.appyx.utils.customisations.NodeCustomisation") 6 | typealias RibCustomisation = NodeCustomisation 7 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/core/customisation/RibCustomisationDirectory.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.customisation 2 | 3 | import com.bumble.appyx.utils.customisations.NodeCustomisationDirectory 4 | 5 | @Deprecated("Use com.bumble.appyx.utils.customisations.NodeCustomisationDirectory") 6 | typealias RibCustomisationDirectory = NodeCustomisationDirectory 7 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/core/customisation/RibCustomisationDirectoryImpl.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.customisation 2 | 3 | import com.bumble.appyx.utils.customisations.NodeCustomisationDirectoryImpl 4 | 5 | @Deprecated("Use com.bumble.appyx.utils.customisations.NodeCustomisationDirectoryImpl") 6 | typealias RibCustomisationDirectoryImpl = NodeCustomisationDirectoryImpl 7 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/core/exception/RootNodeAttachedAsChildException.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.exception 2 | 3 | class RootNodeAttachedAsChildException(message: String) : IllegalArgumentException(message) 4 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/core/plugin/NodeAwareImpl.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.plugin 2 | 3 | import com.badoo.ribs.core.Node 4 | 5 | class NodeAwareImpl : NodeAware { 6 | override lateinit var node: Node<*> 7 | private set 8 | 9 | override fun init(node: Node<*>) { 10 | this.node = node 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/core/plugin/RibAwareImpl.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.plugin 2 | 3 | import com.badoo.ribs.core.Rib 4 | 5 | class RibAwareImpl : RibAware { 6 | override lateinit var rib: T 7 | private set 8 | 9 | override fun init(rib: T) { 10 | this.rib = rib 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/core/view/ViewFactory.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.view 2 | 3 | import androidx.lifecycle.Lifecycle 4 | 5 | fun interface ViewFactory : (ViewFactory.Context) -> View { 6 | class Context( 7 | val parent: RibView, 8 | val lifecycle: Lifecycle, 9 | ) 10 | } 11 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/core/view/ViewFactoryBuilder.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.view 2 | 3 | fun interface ViewFactoryBuilder : (Dependency) -> ViewFactory 4 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/minimal/README.md: -------------------------------------------------------------------------------- 1 | ## About this package 2 | 3 | Minimal implementations of functionality otherwise better provided by dedicated tools. 4 | 5 | Reimplemented here for the sake of making the library leaner and unassuming of additional technologies. 6 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/minimal/reactive/Cancellable.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.minimal.reactive 2 | 3 | interface Cancellable { 4 | fun cancel() 5 | 6 | companion object { 7 | fun cancellableOf(f: () -> Unit): Cancellable = 8 | object : Cancellable { 9 | override fun cancel() { 10 | f() 11 | } 12 | } 13 | } 14 | 15 | object Empty : Cancellable { 16 | override fun cancel() {} 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/minimal/reactive/CompositeCancellable.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.minimal.reactive 2 | 3 | class CompositeCancellable(vararg cancellables: Cancellable) : Cancellable { 4 | private val items = mutableListOf(*cancellables) 5 | operator fun plusAssign(item: Cancellable) { 6 | items += item 7 | } 8 | 9 | override fun cancel() { 10 | items.forEach { it.cancel() } 11 | items.clear() 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/minimal/reactive/Emitter.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.minimal.reactive 2 | 3 | interface Emitter { 4 | fun emit(value: T) 5 | } 6 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/minimal/reactive/Source.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.minimal.reactive 2 | 3 | interface Source { 4 | fun observe(callback: (T) -> Unit): Cancellable 5 | } 6 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/Routing.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing 2 | 3 | import android.os.Parcelable 4 | import kotlinx.parcelize.Parcelize 5 | import java.io.Serializable 6 | 7 | @Parcelize 8 | data class Routing( 9 | val configuration: C, 10 | val identifier: Identifier = Identifier(), // FIXME no default 11 | val meta: Parcelable = NoMeta 12 | ) : Parcelable { 13 | 14 | @Parcelize 15 | data class Identifier( 16 | val id: Serializable = 0 // FIXME no default // FIXME Parcelable 17 | ) : Parcelable 18 | } 19 | 20 | @Parcelize 21 | object NoMeta : Parcelable 22 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/activator/ChildActivator.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.activator 2 | 3 | import android.os.Parcelable 4 | import com.badoo.ribs.core.Node 5 | import com.badoo.ribs.routing.Routing 6 | 7 | interface ChildActivator { 8 | 9 | fun activate(routing: Routing, child: Node<*>) 10 | 11 | fun deactivate(routing: Routing, child: Node<*>) 12 | } 13 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/activator/DefaultChildActivator.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.activator 2 | 3 | import android.os.Parcelable 4 | import com.badoo.ribs.core.Node 5 | import com.badoo.ribs.routing.Routing 6 | 7 | class DefaultChildActivator( 8 | private val parentNode: Node<*> 9 | ) : ChildActivator { 10 | 11 | override fun activate(routing: Routing, child: Node<*>) { 12 | parentNode.attachChildView(child) 13 | } 14 | 15 | override fun deactivate(routing: Routing, child: Node<*>) { 16 | parentNode.detachChildView(child) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/history/RoutingHistory.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.history 2 | 3 | import android.os.Parcelable 4 | 5 | interface RoutingHistory : Iterable> { 6 | 7 | companion object { 8 | fun from(iterable: Iterable>): RoutingHistory = 9 | IterableHistory(iterable) 10 | } 11 | 12 | data class IterableHistory( 13 | val iterable: Iterable> 14 | ) : RoutingHistory, Iterable> by iterable 15 | } 16 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/resolution/InvokeOnCleanUp.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.resolution 2 | 3 | class InvokeOnCleanup( 4 | private val block: () -> Unit 5 | ) : Resolution { 6 | 7 | override val numberOfNodes: Int = 0 8 | 9 | override fun cleanup() { 10 | block() 11 | } 12 | 13 | companion object { 14 | fun cleanup(onLeave: () -> Unit): Resolution = 15 | InvokeOnCleanup(onLeave) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/resolution/InvokeOnExecute.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.resolution 2 | 3 | class InvokeOnExecute( 4 | private val block: () -> Unit 5 | ) : Resolution { 6 | 7 | override val numberOfNodes: Int = 0 8 | 9 | override fun execute() { 10 | block() 11 | } 12 | 13 | companion object { 14 | fun execute(onInvoke: () -> Unit): Resolution = 15 | InvokeOnExecute(onInvoke) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/resolution/RibFactory.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.resolution 2 | 3 | import com.badoo.ribs.core.Rib 4 | import com.badoo.ribs.core.modality.BuildContext 5 | 6 | typealias RibFactory = (buildContext: BuildContext) -> Rib 7 | 8 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/resolver/RoutingResolver.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.resolver 2 | 3 | import android.os.Parcelable 4 | import com.badoo.ribs.routing.Routing 5 | import com.badoo.ribs.routing.resolution.Resolution 6 | 7 | interface RoutingResolver { 8 | 9 | fun resolve(routing: Routing): Resolution 10 | } 11 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/source/backstack/Elements.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.source.backstack 2 | 3 | import com.badoo.ribs.routing.history.RoutingHistoryElement 4 | 5 | typealias Elements = List> 6 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/source/backstack/Ext.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.source.backstack 2 | 3 | import android.os.Parcelable 4 | import com.badoo.ribs.routing.Routing 5 | 6 | internal fun BackStack.State.contentIdForPosition( 7 | position: Int, 8 | content: C 9 | ): Routing.Identifier = 10 | Routing.Identifier("Back stack $id #$position = $content") 11 | 12 | @SuppressWarnings("LongParameterList") 13 | internal fun BackStack.State.overlayIdForPosition( 14 | position: Int, 15 | content: C, 16 | overlayIndex: Int, 17 | overlay: C 18 | ): Routing.Identifier = 19 | Routing.Identifier("Back stack $id overlay #$position.$overlayIndex = $content.$overlay") 20 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/state/Pool.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.state 2 | 3 | import android.os.Parcelable 4 | import com.badoo.ribs.routing.Routing 5 | 6 | internal typealias Pool = Map, RoutingContext> 7 | 8 | internal typealias MutablePool = MutableMap, RoutingContext> 9 | 10 | internal fun poolOf(): Pool = hashMapOf() 11 | 12 | internal fun mutablePoolOf(): MutablePool = hashMapOf() 13 | 14 | internal fun Pool.toMutablePool(): MutablePool = toMutableMap() 15 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/state/action/ActionExecutionParams.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.state.action 2 | 3 | import android.os.Parcelable 4 | import com.badoo.ribs.routing.Routing 5 | import com.badoo.ribs.routing.state.RoutingContext 6 | import com.badoo.ribs.routing.state.changeset.RoutingCommand 7 | 8 | internal data class ActionExecutionParams( 9 | val transactionExecutionParams: TransactionExecutionParams, 10 | val command: RoutingCommand, 11 | val routing: Routing, 12 | val addedOrRemoved: Boolean 13 | ) { 14 | val item: RoutingContext.Resolved by lazy { 15 | transactionExecutionParams.resolver.invoke(routing) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/state/action/single/ActionFactory.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.state.action.single 2 | 3 | import android.os.Parcelable 4 | import com.badoo.ribs.routing.state.action.ActionExecutionParams 5 | 6 | internal interface ActionFactory { 7 | fun create(params: ActionExecutionParams): RoutingTransitionAction 8 | } 9 | 10 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/state/action/single/ReversibleAction.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.state.action.single 2 | 3 | import android.os.Parcelable 4 | 5 | internal interface ReversibleAction : RoutingTransitionAction { 6 | fun reverse() 7 | } 8 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/state/action/single/ReversibleActionFactory.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.state.action.single 2 | 3 | import android.os.Parcelable 4 | import com.badoo.ribs.routing.state.action.ActionExecutionParams 5 | 6 | internal interface ReversibleActionFactory { 7 | fun create(params: ActionExecutionParams): ReversibleAction 8 | } 9 | 10 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/state/action/single/RoutingTransitionAction.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.state.action.single 2 | 3 | import android.os.Parcelable 4 | import com.badoo.ribs.routing.transition.TransitionElement 5 | 6 | internal interface RoutingTransitionAction { 7 | fun onBeforeTransition() 8 | fun onTransition(forceExecute: Boolean = false) 9 | fun onFinish(forceExecute: Boolean = false) 10 | val canExecute: Boolean 11 | val transitionElements: List> 12 | } 13 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/state/changeset/RoutingChangeset.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.state.changeset 2 | 3 | import android.os.Parcelable 4 | import com.badoo.ribs.routing.Routing 5 | 6 | internal typealias RoutingChangeset = List> 7 | 8 | internal fun RoutingChangeset.addedOrRemoved(routing: Routing): Boolean = 9 | any { it.routing == routing && (it is RoutingCommand.Add || it is RoutingCommand.Remove) } 10 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/state/exception/CommandExecutionException.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.state.exception 2 | 3 | class CommandExecutionException(message: String?, cause: Throwable?) : 4 | IllegalStateException(message, cause) 5 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/state/exception/KeyNotFoundInPoolException.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.state.exception 2 | 3 | import com.badoo.ribs.routing.Routing 4 | 5 | class KeyNotFoundInPoolException internal constructor( 6 | key: Routing<*>, 7 | pool: Any 8 | ) : IllegalStateException( 9 | "Key $key was not found in pool: $pool" 10 | ) 11 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/state/feature/EffectEmitter.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.state.feature 2 | 3 | internal typealias EffectEmitter = (RoutingStatePool.Effect) -> Unit 4 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/state/feature/InternalTransactionConsumer.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.state.feature 2 | 3 | internal typealias InternalTransactionConsumer = (Transaction.InternalTransaction) -> Unit 4 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/transition/TransitionDirection.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.transition 2 | 3 | enum class TransitionDirection { 4 | ENTER, EXIT 5 | } 6 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/transition/effect/Gravity.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.transition.effect 2 | 3 | enum class Gravity { 4 | LEFT, RIGHT, TOP, BOTTOM; 5 | 6 | fun reverse(): Gravity = when (this) { 7 | LEFT -> RIGHT 8 | RIGHT -> LEFT 9 | TOP -> BOTTOM 10 | BOTTOM -> TOP 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/transition/effect/helper/AnimationContainer.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.transition.effect.helper 2 | 3 | import android.view.View 4 | import android.view.ViewGroup 5 | 6 | sealed class AnimationContainer { 7 | data object RootView : AnimationContainer() 8 | data object Parent : AnimationContainer() 9 | data class FindParentById(val id: Int) : AnimationContainer() 10 | } 11 | 12 | 13 | fun View.findParentById(parentId: Int): ViewGroup? { 14 | var current: ViewGroup? = this.parent as ViewGroup? 15 | while (current != null && current.id != parentId) { 16 | current = current.parent as ViewGroup? 17 | } 18 | 19 | return current 20 | } 21 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/transition/effect/helper/EndValues.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.transition.effect.helper 2 | 3 | data class EndValues( 4 | val from: Float, 5 | val to: Float 6 | ) { 7 | val difference = to - from 8 | 9 | fun reverse() = 10 | EndValues( 11 | from = to, 12 | to = from 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/transition/effect/helper/ReverseHolder.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.transition.effect.helper 2 | 3 | class ReverseHolder(var isReversing: Boolean = false) 4 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/routing/transition/handler/Defaults.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.transition.handler 2 | 3 | import android.view.animation.AccelerateDecelerateInterpolator 4 | import android.view.animation.Interpolator 5 | 6 | internal const val defaultDuration: Long = 300 7 | 8 | internal val defaultInterpolator: Interpolator = AccelerateDecelerateInterpolator() 9 | -------------------------------------------------------------------------------- /libraries/rib-base/src/main/java/com/badoo/ribs/store/RetainedInstanceStoreExt.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.store 2 | 3 | import com.badoo.ribs.core.Rib 4 | 5 | inline fun RetainedInstanceStore.get( 6 | owner: Rib.Identifier, 7 | noinline disposer: (T) -> Unit = {}, 8 | noinline factory: () -> T 9 | ): T = 10 | get(owner, T::class, disposer, factory) 11 | -------------------------------------------------------------------------------- /libraries/rib-base/src/test/java/com/badoo/ribs/core/NodePluginNodeAwareTest.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core 2 | 3 | import com.badoo.ribs.core.plugin.NodeAware 4 | import org.junit.Test 5 | import org.junit.runner.RunWith 6 | import org.mockito.kotlin.verify 7 | import org.robolectric.RobolectricTestRunner 8 | 9 | @RunWith(RobolectricTestRunner::class) 10 | class NodePluginNodeAwareTest : NodePluginTest() { 11 | 12 | @Test 13 | fun `NodeAware plugins immediately receive init()`() { 14 | val (node, plugins) = testPlugins() 15 | 16 | plugins.forEach { 17 | verify(it).init(node) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /libraries/rib-base/src/test/java/com/badoo/ribs/core/NodePluginSystemAwareTest.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core 2 | 3 | import com.badoo.ribs.core.plugin.SystemAware 4 | import org.junit.Test 5 | import org.junit.runner.RunWith 6 | import org.mockito.kotlin.verify 7 | import org.robolectric.RobolectricTestRunner 8 | 9 | @RunWith(RobolectricTestRunner::class) 10 | class NodePluginSystemAwareTest : NodePluginTest() { 11 | 12 | @Test 13 | fun `SystemAware plugins receive onLowMemory()`() { 14 | val (node, plugins) = testPlugins() 15 | 16 | node.onLowMemory() 17 | 18 | plugins.forEach { 19 | verify(it).onLowMemory() 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /libraries/rib-base/src/test/java/com/badoo/ribs/core/helper/AnyConfiguration.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.helper 2 | 3 | import android.os.Parcelable 4 | import kotlinx.parcelize.Parcelize 5 | 6 | @Parcelize 7 | object AnyConfiguration : Parcelable { 8 | override fun toString(): String = "AnyConfiguration" 9 | } 10 | -------------------------------------------------------------------------------- /libraries/rib-base/src/test/java/com/badoo/ribs/core/helper/TestBuilder.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.helper 2 | 3 | import com.badoo.ribs.builder.SimpleBuilder 4 | import com.badoo.ribs.core.modality.BuildParams 5 | import com.badoo.ribs.core.plugin.Plugin 6 | 7 | class TestBuilder( 8 | private val plugins: List = emptyList() 9 | ) : SimpleBuilder() { 10 | 11 | override fun build(buildParams: BuildParams): TestRib = 12 | TestNode( 13 | buildParams = buildParams, 14 | plugins = plugins 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /libraries/rib-base/src/test/java/com/badoo/ribs/core/helper/TestInteractor.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.helper 2 | 3 | import androidx.lifecycle.Lifecycle 4 | import com.badoo.ribs.clienthelper.interactor.Interactor 5 | import com.badoo.ribs.core.modality.BuildParams 6 | 7 | class TestInteractor( 8 | private val onViewCreated: (view: TestView, viewLifecycle: Lifecycle) -> Unit = { _, _ -> }, 9 | buildParams: BuildParams = testBuildParams() 10 | ) : Interactor( 11 | buildParams = buildParams 12 | ) { 13 | 14 | override fun onViewCreated(view: TestView, viewLifecycle: Lifecycle) { 15 | onViewCreated.invoke(view, viewLifecycle) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /libraries/rib-base/src/test/java/com/badoo/ribs/core/helper/TestNode2.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.helper 2 | 3 | import com.badoo.ribs.core.modality.BuildParams 4 | import com.badoo.ribs.core.view.ViewFactory 5 | import org.mockito.kotlin.mock 6 | 7 | class TestNode2( 8 | buildParams: BuildParams<*> = testBuildParams(), 9 | viewFactory: ViewFactory? = mock() 10 | ) : TestNode( 11 | buildParams = buildParams, 12 | viewFactory = viewFactory 13 | ) 14 | -------------------------------------------------------------------------------- /libraries/rib-base/src/test/java/com/badoo/ribs/core/helper/TestRib.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.helper 2 | 3 | import com.badoo.ribs.core.Rib 4 | 5 | interface TestRib : Rib 6 | -------------------------------------------------------------------------------- /libraries/rib-base/src/test/java/com/badoo/ribs/core/helper/TestView.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.helper 2 | 3 | import android.view.ViewGroup 4 | import com.badoo.ribs.core.view.AndroidRibView 5 | import org.mockito.kotlin.mock 6 | 7 | class TestView : AndroidRibView() { 8 | 9 | override val androidView: ViewGroup = mock() 10 | } 11 | -------------------------------------------------------------------------------- /libraries/rib-base/src/test/java/com/badoo/ribs/core/helper/TestViewFactory.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.helper 2 | 3 | import com.badoo.ribs.core.view.ViewFactory 4 | 5 | class TestViewFactory : ViewFactory { 6 | 7 | override fun invoke(p1: ViewFactory.Context): TestView = 8 | TestView() 9 | } 10 | -------------------------------------------------------------------------------- /libraries/rib-base/src/test/java/com/badoo/ribs/core/helper/connectable/ConnectableTestRib.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.helper.connectable 2 | 3 | import com.badoo.ribs.clienthelper.connector.Connectable 4 | import com.badoo.ribs.core.helper.connectable.ConnectableTestRib.Input 5 | import com.badoo.ribs.core.helper.connectable.ConnectableTestRib.Output 6 | 7 | interface ConnectableTestRib : Connectable { 8 | 9 | sealed class Input 10 | 11 | sealed class Output { 12 | data object Output1 : Output() 13 | data object Output2 : Output() 14 | data object Output3 : Output() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /libraries/rib-base/src/test/java/com/badoo/ribs/core/lifecycle/TestLifecycle.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.lifecycle 2 | 3 | import androidx.lifecycle.Lifecycle 4 | import androidx.lifecycle.LifecycleOwner 5 | import androidx.lifecycle.LifecycleRegistry 6 | 7 | class TestLifecycle() : LifecycleOwner { 8 | private val registry = LifecycleRegistry(this) 9 | 10 | constructor(state: Lifecycle.State) : this() { 11 | this.state = state 12 | } 13 | 14 | var state: Lifecycle.State 15 | get() = registry.currentState 16 | set(value) { 17 | registry.currentState = value 18 | } 19 | 20 | override val lifecycle: Lifecycle 21 | get() = registry 22 | 23 | } 24 | -------------------------------------------------------------------------------- /libraries/rib-base/src/test/java/com/badoo/ribs/routing/state/DifferTest.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.routing.state 2 | 3 | import org.junit.Test 4 | 5 | 6 | class DifferTest { 7 | 8 | @Test 9 | fun `TODO`() { 10 | // TODO write unit tests for RoutingHistoryDiffer. 11 | // For now, integration test done in BackStackDiffingIntegrationTest are enough to call it safe 12 | // TODO tests for non-back stack based, generic routing sources 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /libraries/rib-base/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker: -------------------------------------------------------------------------------- 1 | mock-maker-inline 2 | -------------------------------------------------------------------------------- /libraries/rib-compose/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /libraries/rib-compose/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/badoo/RIBs/9ca011c5423246f2abafd88725e5b808f249288d/libraries/rib-compose/consumer-rules.pro -------------------------------------------------------------------------------- /libraries/rib-compose/detekt-baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /libraries/rib-compose/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=RIBs (Compose) 2 | POM_ARTIFACT_ID=rib-compose 3 | POM_PACKAGING=android 4 | -------------------------------------------------------------------------------- /libraries/rib-compose/src/main/java/com/badoo/ribs/compose/ComposeView.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.compose 2 | 3 | import androidx.compose.runtime.Composable 4 | 5 | typealias ComposeView = @Composable () -> Unit 6 | -------------------------------------------------------------------------------- /libraries/rib-debug-utils/build.gradle: -------------------------------------------------------------------------------- 1 | configureAndroidLibrary(project) 2 | 3 | android { 4 | namespace 'com.badoo.ribs.debugutils' 5 | } 6 | 7 | dependencies { 8 | api project(":libraries:rib-base") 9 | } 10 | 11 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 12 | -------------------------------------------------------------------------------- /libraries/rib-debug-utils/detekt-baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /libraries/rib-debug-utils/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=RIBs (Debug Utils) 2 | POM_ARTIFACT_ID=rib-debug-utils 3 | POM_PACKAGING=android 4 | -------------------------------------------------------------------------------- /libraries/rib-debug-utils/src/main/java/com/badoo/ribs/core/plugin/utils/debug/DebugControls.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.plugin.utils.debug 2 | 3 | import android.view.View 4 | import android.view.ViewGroup 5 | import com.badoo.ribs.core.Rib 6 | 7 | abstract class DebugControls( 8 | override val label: String, 9 | viewFactory: ((ViewGroup) -> View) 10 | ) : AbstractDebugControls( 11 | viewFactory = viewFactory 12 | ) 13 | -------------------------------------------------------------------------------- /libraries/rib-debug-utils/src/main/java/com/badoo/ribs/core/plugin/utils/debug/GrowthDirection.kt: -------------------------------------------------------------------------------- 1 | package com.badoo.ribs.core.plugin.utils.debug 2 | 3 | enum class GrowthDirection { 4 | TOP, BOTTOM 5 | } 6 | -------------------------------------------------------------------------------- /libraries/rib-debug-utils/src/main/res/layout/debug_root.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 |