Skip to content

Commit

Permalink
Encapsulate usage of CoroutineDispatcher in ViewModel
Browse files Browse the repository at this point in the history
  • Loading branch information
Faltenreich committed Dec 17, 2023
1 parent 1855d1d commit d8e6aa0
Show file tree
Hide file tree
Showing 11 changed files with 18 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@ import com.faltenreich.diaguard.dashboard.usecase.GetLatestBloodSugarUseCase
import com.faltenreich.diaguard.dashboard.usecase.GetTodayUseCase
import com.faltenreich.diaguard.shared.architecture.ViewModel
import com.faltenreich.diaguard.shared.di.inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flowOn

class DashboardViewModel(
dispatcher: CoroutineDispatcher = inject(),
getLatestBloodSugar: GetLatestBloodSugarUseCase = inject(),
getToday: GetTodayUseCase = inject(),
getAverage: GetAverageUseCase = inject(),
Expand All @@ -22,7 +19,7 @@ class DashboardViewModel(
getToday(),
getAverage(),
DashboardViewState::Revisit,
).flowOn(dispatcher)
)

override fun onIntent(intent: Unit) = Unit
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@ import com.faltenreich.diaguard.shared.architecture.FormViewModel
import com.faltenreich.diaguard.shared.datetime.DateTimeFactory
import com.faltenreich.diaguard.shared.datetime.DateTimeFormatter
import com.faltenreich.diaguard.shared.datetime.DateUnit
import com.faltenreich.diaguard.shared.di.inject
import com.faltenreich.diaguard.shared.localization.Localization
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class ExportFormViewModel(
dispatcher: CoroutineDispatcher = inject(),
getMeasurementProperties: GetMeasurementPropertiesUseCase,
private val export: ExportUseCase,
dateTimeFactory: DateTimeFactory,
Expand Down Expand Up @@ -54,7 +51,7 @@ class ExportFormViewModel(
var properties by mutableStateOf(emptyList<ExportFormMeasurementProperty>())

init {
scope.launch(dispatcher) {
scope.launch {
getMeasurementProperties().collect { properties ->
val exportProperties = properties.map { property ->
ExportFormMeasurementProperty(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@ import com.faltenreich.diaguard.shared.architecture.ViewModel
import com.faltenreich.diaguard.shared.architecture.combine
import com.faltenreich.diaguard.shared.datetime.DateTimeConstants
import com.faltenreich.diaguard.shared.di.inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch

class MeasurementPropertyFormViewModel(
property: MeasurementProperty,
dispatcher: CoroutineDispatcher = inject(),
getMeasurementTypesUseCase: GetMeasurementTypesUseCase = inject(),
countMeasurementValuesOfProperty: CountMeasurementValuesOfPropertyUseCase = inject(),
updateMeasurementProperty: UpdateMeasurementPropertyUseCase = inject(),
Expand All @@ -39,15 +36,15 @@ class MeasurementPropertyFormViewModel(
getMeasurementTypesUseCase(property),
countMeasurementValuesOfProperty(property),
MeasurementPropertyFormViewState::Loaded,
).flowOn(dispatcher)
)

init {
// FIXME: Setting both at the same time cancels the first collector
scope.launch(dispatcher) {
scope.launch {
name.debounce(DateTimeConstants.INPUT_DEBOUNCE)
.collectLatest { name -> updateMeasurementProperty(property.copy(name = name)) }
}
scope.launch(dispatcher) {
scope.launch {
icon.debounce(DateTimeConstants.INPUT_DEBOUNCE)
.collectLatest { icon -> updateMeasurementProperty(property.copy(icon = icon)) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@ import com.faltenreich.diaguard.measurement.property.MeasurementProperty
import com.faltenreich.diaguard.measurement.property.form.UpdateMeasurementPropertyUseCase
import com.faltenreich.diaguard.shared.architecture.ViewModel
import com.faltenreich.diaguard.shared.di.inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flowOn

class MeasurementPropertyListViewModel(
dispatcher: CoroutineDispatcher = inject(),
getMeasurementProperties: GetMeasurementPropertiesUseCase = inject(),
private val updateMeasurementProperty: UpdateMeasurementPropertyUseCase = inject(),
private val createMeasurementProperty: CreateMeasurementPropertyUseCase = inject(),
Expand All @@ -22,7 +19,7 @@ class MeasurementPropertyListViewModel(
showFormDialog,
getMeasurementProperties(),
MeasurementPropertyListViewState::Loaded,
).flowOn(dispatcher)
)

private val properties: List<MeasurementProperty>?
get() = (stateInScope.value as? MeasurementPropertyListViewState.Loaded)?.listItems
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@ import com.faltenreich.diaguard.measurement.type.MeasurementType
import com.faltenreich.diaguard.shared.architecture.ViewModel
import com.faltenreich.diaguard.shared.datetime.DateTimeConstants
import com.faltenreich.diaguard.shared.di.inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch

class MeasurementTypeFormViewModel(
measurementTypeId: Long,
dispatcher: CoroutineDispatcher = inject(),
getMeasurementTypeUseCase: GetMeasurementTypeUseCase = inject(),
countMeasurementValuesOfType: CountMeasurementValuesOfTypeUseCase = inject(),
private val updateMeasurementType: UpdateMeasurementTypeUseCase = inject(),
Expand All @@ -43,24 +40,24 @@ class MeasurementTypeFormViewModel(
measurementCount = measurementCount,
)
}
}.flowOn(dispatcher)
}

init {
scope.launch(dispatcher) {
scope.launch {
type.filterNotNull().distinctUntilChangedBy(MeasurementType::id).collectLatest { type ->
typeName.value = type.name
unitName.value = type.selectedUnit.name
}
}
// FIXME: Setting other flow at the same time cancels the first collector
scope.launch(dispatcher) {
scope.launch {
typeName.debounce(DateTimeConstants.INPUT_DEBOUNCE).collectLatest { name ->
val type = (stateInScope.value as? MeasurementTypeFormViewState.Loaded)?.type
checkNotNull(type)
updateMeasurementType(type.copy(name = name))
}
}
scope.launch(dispatcher) {
scope.launch {
unitName.debounce(DateTimeConstants.INPUT_DEBOUNCE).collectLatest { name ->
val type = (stateInScope.value as? MeasurementTypeFormViewState.Loaded)?.type
checkNotNull(type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@ import com.faltenreich.diaguard.measurement.type.MeasurementType
import com.faltenreich.diaguard.measurement.type.form.UpdateMeasurementTypeUseCase
import com.faltenreich.diaguard.shared.architecture.ViewModel
import com.faltenreich.diaguard.shared.di.inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.launch

class MeasurementTypeListViewModel(
private val dispatcher: CoroutineDispatcher = inject(),
private val updateMeasurementType: UpdateMeasurementTypeUseCase = inject(),
) : ViewModel<Unit, MeasurementTypeListIntent>() {

Expand All @@ -27,21 +24,21 @@ class MeasurementTypeListViewModel(
private fun decrementSortIndex(
type: MeasurementType,
inTypes: List<MeasurementType>,
) = scope.launch(dispatcher) {
) {
swapSortIndexes(first = type, second = inTypes.last { it.sortIndex < type.sortIndex })
}

private fun incrementSortIndex(
type: MeasurementType,
inTypes: List<MeasurementType>,
) = scope.launch(dispatcher) {
) {
swapSortIndexes(first = type, second = inTypes.first { it.sortIndex > type.sortIndex })
}

private fun swapSortIndexes(
first: MeasurementType,
second: MeasurementType,
) = scope.launch(dispatcher) {
) {
updateMeasurementType(first.copy(sortIndex = second.sortIndex))
updateMeasurementType(second.copy(sortIndex = first.sortIndex))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@ import com.faltenreich.diaguard.preference.store.screen.GetStartScreenUseCase
import com.faltenreich.diaguard.preference.store.screen.StartScreen
import com.faltenreich.diaguard.shared.architecture.ViewModel
import com.faltenreich.diaguard.shared.di.inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map

class NavigationViewModel(
dispatcher: CoroutineDispatcher = inject(),
getStartScreen: GetStartScreenUseCase = inject(),
) : ViewModel<NavigationViewState, Unit>() {

Expand All @@ -24,7 +21,7 @@ class NavigationViewModel(
StartScreen.LOG -> LogScreen()
},
)
}.flowOn(dispatcher)
}

override fun onIntent(intent: Unit) = Unit
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@ package com.faltenreich.diaguard.onboarding
import com.faltenreich.diaguard.backup.ImportUseCase
import com.faltenreich.diaguard.shared.architecture.ViewModel
import com.faltenreich.diaguard.shared.di.inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map

class OnboardingViewModel(
dispatcher: CoroutineDispatcher = inject(),
hasData: HasDataUseCase = inject(),
private val import: ImportUseCase = inject(),
) : ViewModel<OnboardingViewState, OnboardingIntent>() {
Expand All @@ -18,7 +15,7 @@ class OnboardingViewModel(
true -> OnboardingViewState.SubsequentStart
false -> OnboardingViewState.FirstStart
}
}.flowOn(dispatcher)
}

override fun onIntent(intent: OnboardingIntent) {
when (intent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,16 @@ package com.faltenreich.diaguard.preference.list
import com.faltenreich.diaguard.preference.list.item.PreferenceListItem
import com.faltenreich.diaguard.shared.architecture.ViewModel
import com.faltenreich.diaguard.shared.di.inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map

class PreferenceListViewModel(
preferences: List<PreferenceListItem>?,
getDefaultPreferences: GetDefaultPreferencesUseCase = inject(),
dispatcher: CoroutineDispatcher = inject(),
) : ViewModel<PreferenceListViewState, Unit>() {

override val state = (preferences?.let(::flowOf) ?: getDefaultPreferences())
.map(PreferenceListViewState::Loaded)
.flowOn(dispatcher)

override fun onIntent(intent: Unit) = Unit
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch

Expand All @@ -23,7 +24,7 @@ abstract class ViewModel<State, Intent>(
abstract val state: Flow<State>

val stateInScope: StateFlow<State?> by lazy {
state.stateIn(
state.flowOn(dispatcher).stateIn(
scope = scope,
started = SharingStarted.Lazily,
initialValue = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,15 @@ import com.faltenreich.diaguard.shared.datetime.Date
import com.faltenreich.diaguard.shared.datetime.DateTimeFactory
import com.faltenreich.diaguard.shared.datetime.DateUnit
import com.faltenreich.diaguard.shared.di.inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map

class TimelineViewModel(
date: Date?,
dispatcher: CoroutineDispatcher = inject(),
dateTimeFactory: DateTimeFactory = inject(),
entryRepository: EntryRepository = inject(),
measurementPropertyRepository: MeasurementPropertyRepository = inject(),
Expand Down Expand Up @@ -55,7 +52,7 @@ class TimelineViewModel(
valuesForList,
propertiesForList,
::TimelineViewState,
).flowOn(dispatcher)
)

override fun onIntent(intent: TimelineIntent) {
when (intent) {
Expand Down

0 comments on commit d8e6aa0

Please sign in to comment.