Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename FragmentStoreBuilder to FeaturesBuilder. #381

Merged
merged 2 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we consider a rename from FragmentFlowStore to maybe just FragmentStore as well? When I see Flow, I always just think Coroutine Flow so it can be a little jarring to realize that its not that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, will do in a follow up.

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
Loading