Skip to content

Commit

Permalink
Rename FragmentStoreBuilder to FeaturesBuilder. (#381)
Browse files Browse the repository at this point in the history
* Rename FragmentStoreBuilder to FeaturesBuilder.

* Construct ActivityStore directly.
  • Loading branch information
Laimiux authored Sep 4, 2024
1 parent d60112a commit fc65f7f
Show file tree
Hide file tree
Showing 22 changed files with 100 additions and 130 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
- Enable fine-grained control of dispatching via `Plugin.defaultDispatcher`, `RuntimeConfig.defaultDispatcher`, `Transition.ExecutionType` and `Effect.Type`.
- Remove `RxStream` type alias.
- Replace `implementation` function with a value
- Removed `FlowFactory` and `Flow`
- **Breaking**: Removed `FlowFactory` and `Flow`
- **Breaking**: Replace `FragmentStoreBuilder` with `FeaturesBuilder`

## [0.7.1] - June 28, 2022
- **Breaking**: Rename `FragmentBindingBuilder` to `FragmentStoreBuilder`
Expand Down
20 changes: 12 additions & 8 deletions docs/Formula-Android.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,11 @@ class MyApp : Application() {

FormulaAndroid.init(this) {
activity(MyActivity::class) {
store(MyActivityComponent(this)) {
bind(CounterFeatureFactory())
}
ActivityStore(
fragmentStore = FragmentFlowStore.init(MyActivityComponent(this)) {
bind(CounterFeatureFactory())
}
)
}
}
}
Expand Down Expand Up @@ -357,9 +359,11 @@ Now that we have our dependencies configured, let's bind the flow factory to our
val appComponent = AppComponent()
FormulaAndroid.init(this) {
activity(MyActivity::class) {
store(appComponent) {
bind(AuthFlowFactory())
}
ActivityStore(
fragmentStore = FragmentFlowStore.init(appComponent) {
bind(AuthFlowFactory())
}
)
}
}
```
Expand Down Expand Up @@ -393,7 +397,7 @@ class MyApp : Application() {
FormulaAndroid.init(this) {
activity<MyActivity> {

store(
ActivityStore(
streams = {
// You can subscribe to your RxJava streams here.
val timerState = Observable
Expand Down Expand Up @@ -453,7 +457,7 @@ FormulaAndroid.init(this) {
// This component will survive configuration changes.
val activityComponent = appComponent.createMyActivityComponent()

store(
ActivityStore(
configureActivity = {
// in this callback `this` is the instance of MyActivity
// so we can use it to inject dependencies
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class MyApp : Application() {

FormulaAndroid.init(this) {
activity<MyActivity> {
store(
ActivityStore(
streams = {
val formula = CounterFormula()
update(formula.toObservable(), MyActivity::render)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import com.instacart.formula.android.ActivityStore
import com.instacart.formula.android.FormulaAppCompatActivity
import org.junit.Before
import org.junit.Rule
Expand All @@ -25,7 +26,7 @@ class ActivityLifecycleEventTest {
FormulaAndroid.init(app) {
activity<TestActivity> {
events = mutableListOf()
store(
ActivityStore(
streams = {
activityLifecycleState().subscribe {
events.add(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import com.instacart.formula.android.ActivityStore
import com.instacart.formula.android.FormulaAppCompatActivity
import com.jakewharton.rxrelay3.PublishRelay
import org.junit.Before
Expand Down Expand Up @@ -35,7 +36,7 @@ class ActivityUpdateTest {
initFormula = { app ->
FormulaAndroid.init(app) {
activity<TestActivity> {
store(
ActivityStore(
streams = {
update(updateRelay, TestActivity::applyUpdate)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import com.instacart.formula.android.ActivityStore
import com.instacart.formula.android.FormulaAppCompatActivity
import io.reactivex.rxjava3.core.Observable
import org.junit.Before
Expand Down Expand Up @@ -38,7 +39,7 @@ class ActivityUpdateTimingTest {
initFormula = { app ->
FormulaAndroid.init(app) {
activity<TestActivity> {
store(
ActivityStore(
streams = {
update(updateRelay, TestActivity::applyUpdate)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import com.instacart.formula.android.ActivityStore
import com.instacart.formula.android.Feature
import com.instacart.formula.android.FeatureFactory
import com.instacart.formula.android.FragmentFlowStore
import com.instacart.formula.android.ViewFactory
import com.instacart.formula.android.events.ActivityResult
import com.instacart.formula.test.TestFragmentActivity
Expand All @@ -25,11 +27,11 @@ class FragmentAndroidEventTest {
initFormula = { app ->
FormulaAndroid.init(app) {
activity<TestFragmentActivity> {
store(
ActivityStore(
configureActivity = {
initialContract = TestLifecycleKey()
it.initialContract = TestLifecycleKey()
},
contracts = {
fragmentStore = FragmentFlowStore.init {
val featureFactory = object : FeatureFactory<Unit, TestLifecycleKey> {
override fun initialize(dependencies: Unit, key: TestLifecycleKey): Feature {
return Feature(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import com.instacart.formula.android.ActivityStore
import com.instacart.formula.android.FragmentFlowState
import com.instacart.formula.android.FragmentKey
import com.instacart.formula.android.BackCallback
import com.instacart.formula.android.FragmentFlowStore
import com.instacart.formula.test.TestKey
import com.instacart.formula.test.TestKeyWithId
import com.instacart.formula.test.TestFragmentActivity
Expand Down Expand Up @@ -39,17 +41,17 @@ class FragmentFlowRenderViewTest {
initFormula = { app ->
FormulaAndroid.init(app) {
activity<TestFragmentActivity> {
store(
configureActivity = {
initialContract = TestKey()
onPreCreated(this)
ActivityStore(
configureActivity = { activity ->
activity.initialContract = TestKey()
onPreCreated(activity)
},
onRenderFragmentState = { a, state ->
lastState = state

updateThreads.add(Thread.currentThread())
},
contracts = {
fragmentStore = FragmentFlowStore.init {
bind(TestFeatureFactory<TestKey> { stateChanges(it) })
bind(TestFeatureFactory<TestKeyWithId> { stateChanges(it) })
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import com.instacart.formula.android.ActivityStore
import com.instacart.formula.android.FormulaFragment
import com.instacart.formula.android.ActivityStoreContext
import com.instacart.formula.android.FeatureFactory
import com.instacart.formula.android.FragmentFlowStore
import com.instacart.formula.android.FragmentKey
import com.instacart.formula.test.TestKey
import com.instacart.formula.test.TestKeyWithId
Expand All @@ -32,11 +34,11 @@ class FragmentLifecycleStateTest {
started = mutableListOf()
resumed = mutableListOf()

store(
ActivityStore(
configureActivity = {
initialContract = TestKey()
it.initialContract = TestKey()
},
contracts = {
fragmentStore = FragmentFlowStore.init {
bind(featureFactory<TestKey>(this@activity))
bind(featureFactory<TestKeyWithId>(this@activity))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import android.os.Bundle
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import com.instacart.formula.android.ActivityStore
import com.instacart.formula.android.Feature
import com.instacart.formula.android.FeatureFactory
import com.instacart.formula.android.FragmentFlowStore
import com.instacart.formula.android.ViewFactory
import com.instacart.formula.test.TestFragmentActivity
import com.instacart.formula.test.TestFragmentLifecycleCallback
Expand All @@ -30,13 +32,13 @@ class FragmentLifecycleTest {
@get:Rule val formulaRule = TestFormulaRule(initFormula = { app ->
FormulaAndroid.init(app) {
activity<TestFragmentActivity> {
store(
configureActivity = {
ActivityStore(
configureActivity = { activity ->
lifecycleCallback = TestFragmentLifecycleCallback()
contract = TestLifecycleKey()
initialContract = contract
activity.initialContract = contract
},
contracts = {
fragmentStore = FragmentFlowStore.init {
val featureFactory = object : FeatureFactory<Unit, TestLifecycleKey> {
override fun initialize(dependencies: Unit, key: TestLifecycleKey): Feature {
return Feature(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import io.reactivex.rxjava3.disposables.Disposable
* navigation destination [com.instacart.formula.fragment.FragmentKey] to its state
* management stream.
*
* @param contracts Fragment state management defined for this [Activity].
* @param fragmentStore Fragment state management defined for this [Activity].
* @param streams This provides ability to configure arbitrary RxJava streams that survive
* configuration changes. Check [com.instacart.formula.android.StreamConfigurator] for utility methods.
* @param configureActivity This is invoked as part of [com.instacart.formula.FormulaAndroid.onPreCreate]. You can
Expand All @@ -18,7 +18,7 @@ import io.reactivex.rxjava3.disposables.Disposable
* @param onFragmentLifecycleEvent This is callback for when a fragment is added or removed.
*/
class ActivityStore<Activity : FragmentActivity>(
val contracts: FragmentFlowStore,
val fragmentStore: FragmentFlowStore = FragmentFlowStore.EMPTY,
val streams: (StreamConfigurator<Activity>.() -> Disposable)? = null,
val configureActivity: ((Activity) -> Unit)? = null,
val onRenderFragmentState: ((Activity, FragmentFlowState) -> Unit)? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ package com.instacart.formula.android
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Lifecycle
import com.instacart.formula.android.events.ActivityResult
import com.instacart.formula.android.events.FragmentLifecycleEvent
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.Disposable

/**
* This class provides context within which you can create [ActivityStore]. It provides
Expand Down Expand Up @@ -69,68 +67,4 @@ abstract class ActivityStoreContext<out Activity : FragmentActivity> {
* it will do nothing.
*/
abstract fun send(effect: Activity.() -> Unit)

/**
* Creates an [ActivityStore].
*
* @param configureActivity This is called when activity is created before view inflation. You can use this to
* configure / inject the activity.
* @param onRenderFragmentState This is called after [FragmentFlowState] is applied to UI.
* @param onFragmentLifecycleEvent This is called after each [FragmentLifecycleEvent].
* @param streams This provides ability to configure arbitrary RxJava streams that survive
* configuration changes. Check [StreamConfigurator] for utility methods.
* @param contracts [FragmentFlowStore] used to provide state management for individual screens.
*/
fun <ActivityT : FragmentActivity> store(
configureActivity: (ActivityT.() -> Unit)? = null,
onRenderFragmentState: ((ActivityT, FragmentFlowState) -> Unit)? = null,
onFragmentLifecycleEvent: ((FragmentLifecycleEvent) -> Unit)? = null,
streams: (StreamConfigurator<ActivityT>.() -> Disposable)? = null,
contracts: FragmentFlowStore
): ActivityStore<ActivityT> {
return ActivityStore(
contracts = contracts,
configureActivity = configureActivity,
onFragmentLifecycleEvent = onFragmentLifecycleEvent,
onRenderFragmentState = onRenderFragmentState,
streams = streams
)
}

/**
* Creates an [ActivityStore].
*
* @param configureActivity This is called when activity is created before view inflation. You can use this to
* configure / inject the activity.
* @param onRenderFragmentState This is called after [FragmentFlowState] is applied to UI.
* @param onFragmentLifecycleEvent This is called after each [FragmentLifecycleEvent].
* @param streams This provides ability to configure arbitrary RxJava streams that survive
* configuration changes. Check [StreamConfigurator] for utility methods.
* @param contracts Builder method that configures [FragmentFlowStore] used to provide state management for individual screens.
*/
inline fun <ActivityT : FragmentActivity> store(
noinline configureActivity: (ActivityT.() -> Unit)? = null,
noinline onRenderFragmentState: ((ActivityT, FragmentFlowState) -> Unit)? = null,
noinline onFragmentLifecycleEvent: ((FragmentLifecycleEvent) -> Unit)? = null,
noinline streams: (StreamConfigurator<ActivityT>.() -> Disposable)? = null,
crossinline contracts: FragmentStoreBuilder<Unit>.() -> Unit = {}
): ActivityStore<ActivityT> {
return store(
configureActivity = configureActivity,
onRenderFragmentState = onRenderFragmentState,
onFragmentLifecycleEvent = onFragmentLifecycleEvent,
streams = streams,
contracts = contracts(Unit, contracts)
)
}

/**
* Convenience method to to create a [FragmentFlowStore] with a [Component] instance.
*/
inline fun <Component> contracts(
rootComponent: Component,
crossinline contracts: FragmentStoreBuilder<Component>.() -> Unit
): FragmentFlowStore {
return FragmentFlowStore.init(rootComponent, contracts)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import io.reactivex.rxjava3.core.Observable
* and the [stateObservable] observable.
*
* To define a feature, we need to create a [FeatureFactory] for a specific [FragmentKey] type
* and [bind][FragmentStoreBuilder.bind] it to the [FragmentFlowStore].
* and [bind][FeaturesBuilder.bind] it to the [FragmentFlowStore].
*
* Take a look at [FeatureFactory] for more information.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ package com.instacart.formula.android
* }
* ```
*
* Once we define a [FeatureFactory], we need to [bind][FragmentStoreBuilder.bind] it to a
* Once we define a [FeatureFactory], we need to [bind][FeaturesBuilder.bind] it to a
* [FragmentFlowStore]. The fragment flow store will call [initialize] the first time
* [FormulaFragment] with a new [Key] is attached. It will subscribe to the state management
* and persist it across configuration changes.
Expand Down
Loading

0 comments on commit fc65f7f

Please sign in to comment.