Skip to content

Commit

Permalink
Update README to split the code snippet into components and provide a…
Browse files Browse the repository at this point in the history
… short description for each
  • Loading branch information
horatiu-udrea committed Jan 9, 2025
1 parent 613e57c commit 6c4b00f
Showing 1 changed file with 24 additions and 3 deletions.
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,24 @@ dependencies {
```

### Android Example
Find full implementation in [android-demo sources](android-demo/src/main/java/com/example/android_demo) and tests for the components in [android-demo tests](android-demo/src/test/java/com/example/android_demo).
Full implementation is in [android-demo sources](android-demo/src/main/java/com/example/android_demo) and tests for the components are in [android-demo tests](android-demo/src/test/java/com/example/android_demo).

A template for Android Studio can be found [here](.idea/fileTemplates/MVI%20ViewModel.kt).
You can also find a template for Android Studio [here](.idea/fileTemplates/MVI%20ViewModel.kt).

Here is a description of the main components. They can either be in one single file or split into multiple files in the same package, for readability.
#### The component aliases
These exist to keep everything easy to read. They also help with navigating easily among components.

```kotlin
// Use "Go to definition" to easily navigate sections
typealias S = ProductsState
typealias I = ProductsIntent
typealias D = ProductsDependencies
```
#### The viewmodel itself
The viewmodel itself doesn't define any logic, just the initial state. It has callbacks that can be used for debugging or observability.

```kotlin
class ProductsViewModel(dependencies: D) : MVIViewModel<S, I, D>(initialState = ProductsState(), dependencies) {

// Put a breakpoint on the line with "Unit" and observe all received intents
Expand Down Expand Up @@ -81,15 +89,25 @@ class ProductsViewModel(dependencies: D) : MVIViewModel<S, I, D>(initialState =
super.onException(intent, exception, sendIntent)
}
}
```
#### The state
The state is a simple data class, preferably immutable.

```kotlin
data class ProductsState(
val products: List<Product> = emptyList(),
val productsLoading: Boolean = false,
val purchaseError: Boolean = false
)

data class Product(val id: Int, val name: String, val price: Double)
```
#### The intents
Here are the intent definitions as immutable data objects and data classes. They also contain the logic to handle the intent.
The `state` object is used to change the state or schedule other intents, while `Run`,
`RunIfNotRunning`, `RunAfterCurrent`, `CancelCurrentThenRun` and `CancelIntent` are used to control the scheduling of intent handlers.

```kotlin
sealed interface ProductsIntent : IntentHandler<S, I, D> {
data object RefreshProducts : I, RunIfNotRunning<S, I, D>({ state ->
// Change the state and provide a description
Expand Down Expand Up @@ -132,7 +150,10 @@ sealed interface ProductsIntent : IntentHandler<S, I, D> {
state.change { it.copy(purchaseError = false) }
})
}

```
#### The dependencies
The dependencies are grouped in a separate class and can be injected as normal.
```kotlin
// Group all dependencies here. This can be injected using your favorite DI tool.
class ProductsDependencies(
val getProductsUseCase: suspend () -> List<Product>,
Expand Down

0 comments on commit 6c4b00f

Please sign in to comment.