Skip to content

Commit

Permalink
Mark NavigationFlow.update as public again, and add a documentation c…
Browse files Browse the repository at this point in the history
…omment explaining what it should be used for.
  • Loading branch information
isaac-udy committed May 21, 2024
1 parent ef1ac84 commit 0223b49
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 2.4.2
* Added `update` to the public API for `NavigationFlow`, as this is required for some use cases where the flow needs to be updated after changes in external state which may affect the logic of the flow. This function was previously named `next`, and removed from the public API in 2.4.0.

## 2.4.1
* Added `EnroBackConfiguration`, which can be set when creating a `NavigationController`. This controls how Enro handles back presses.
* EnroBackConfiguration.Default will use the behavior that has been standard in Enro until this point
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,49 @@ public class NavigationFlow<T> internal constructor(
}
}

internal fun update() {
/**
* This method is used to cause the flow to re-evaluate it's current state. This happens once automatically when the flow
* is created, and then once every time a step returns a result, or a step is edited using [FlowStepActions]. However, you
* may want to call this method yourself if there is external state that may have changed that would affect the flow.
*
* An example of where this is useful is if you wanted to call a suspending function, and then update external state
* based on the result of the suspending function before resuming the flow. An example of how this would work:
* ```
* class ExampleViewModel(
* savedStateHandle: SavedStateHandle,
* ) : ViewModel() {
* private var suspendingFunctionInvoked = false
*
* private val resultFlow by registerForFlowResult(
* savedStateHandle = savedStateHandle,
* flow = {
* // ...
* if (!suspendingFunctionInvoked) {
* performSuspendingAction()
* escape()
* }
* // ...
* },
* onCompleted = { /*...*/ }
* )
*
* private fun performSuspendingAction() {
* viewModelScope.launch {
* delay(1000)
* suspendingFunctionInvoked = true
* resultFlow.update()
* }
* }
* }
* ```
*
* In the example above, when the if statement is reached, and "suspendingFunctionInvoked" is not true, the flow will call
* "performSuspendingAction" and then immediately call "escape". The call to "escape" will cause the flow to stop evaluating
* which steps should occur. The call to [update] inside "performSuspendingAction" will cause the flow to re-evaluate
* the state, and continue the flow from where it left off. Because "suspendingFunctionInvoked" will have been set to true,
* the flow won't execute that if statement, and will instead continue on to whatever logic is next.
*/
public fun update() {
val flowScope = NavigationFlowScope(this, resultManager, reference)
runCatching { return@update onCompleted(flowScope.flow()) }
.recover {
Expand Down Expand Up @@ -127,6 +169,15 @@ public class NavigationFlow<T> internal constructor(
}
}

/**
* This method creates a NavigationFlow in the scope of a ViewModel. There can only be one NavigationFlow created within each
* NavigationDestination. The [flow] lambda will be invoked multiple times over the lifecycle of the NavigationFlow, and should
* generally not cause external side effects. The [onCompleted] lambda will be invoked when the flow completes and returns a
* result.
*
* [NavigationFlow.update] is triggered automatically as part of this function, you do not need to manually call update to
* begin the flow.
*/
public fun <T> ViewModel.registerForFlowResult(
savedStateHandle: SavedStateHandle,
flow: NavigationFlowScope.() -> T,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class FlowStepActions<T: NavigationKey.WithResult<*>>(
}

/**
* Triggers editing of the step in the NavigationFlow. This clears the result, and immediately triggers an update on
* Triggers editing of the step in the NavigationFlow. This clears the result, and immediately triggers an [update] on
* the flow.
*
* If you want to cause multiple steps to be cleared before editing, you should call [clearResult] on each step before
Expand Down

0 comments on commit 0223b49

Please sign in to comment.