Designed by Stefanus Ayudha
Communication should be done in single channel, that just make sense.
Every UI state should be manifested in the model. For example: selected, active, inactive, etc.
graph LR
A[Cars] --> B[CarDisplay] --> C{{Presentation}}
graph LR
A[List of Cars] --> B[[Automated State: List of Car Display]]
C[Selected Card ID] --> B
B --> D{{Presentation}}
@JvmInline
value class CarID(val value: String)
@JvmInline
value class CarName(val value: String)
data class Car(
val id: CarID,
val name: CarName,
)
data class CarDisplay(
val car: Car,
val selected: Boolean = false,
)
sealed interface MViewModelIntent
object Idle : MViewModelIntent
data class SelectCar(
val carID: CarID
): MViewModelIntent
data class UpdateCarList(
val pld: GetCarsPLD
): MViewModelIntent
class MViewModel(
val repo: CarRepo
) : ViewModel() {
val intent by register<MViewModelIntent>(Idle)
/** provide data of cars **/
val carsProvider: Provider<GetCarsPLD, List<Car>> by lazy {
val provider by provider(operator = repository::getCars)
/** automate the provider on receive message **/
provider.automate {
collect(intent.data) { i ->
if (i is UpdateCarList) {
update(intent.pld)
}
}
}
}
/** selected car, in case user select a car from the list**/
val selectedCarID: Flow<Option<CarID>> by lazy {
MutableState(None)
.automate {
collect(intent.data) { i ->
if (i is SelectCar) {
emit(Some(i.carID))
}
}
}
}
/** # Model Hold The UI State
* Car display list is a list of CarDisplay not Car.
* The purpose of CarDisplay object is to make it capable to hold the UI state with it, such selected, maybe enable and disable as well.
* **/
val carsDisplay: Flow<List<CarsDisplay>> =
/** automation state **/
combine(
sampleProvider.success,
selectedCarID,
) { carProviderSuccess, selectedCarID ->
carProviderSuccess
.fold {
ifEmpty = { listOf()}
ifSome = { it }
}
/** manage selected car **/
.map {
CarDisplay(
car = it,
selected = it.id == selectedCarID
)
}
}.flowOn(Dispatchers.IO)
}
Now you can observe the car list display and just render it. No Side effect, Less code Diversity.