封装BaseViewModel

This commit is contained in:
Hsy
2025-10-15 15:03:16 +08:00
parent 6e8529caad
commit 05ff710872
24 changed files with 727 additions and 333 deletions

View File

@@ -1,7 +1,7 @@
package com.taskttl.data.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.taskttl.core.viewmodel.BaseViewModel
import com.taskttl.data.local.model.Category
import com.taskttl.data.local.model.CategoryType
import com.taskttl.data.local.model.Countdown
@@ -10,12 +10,6 @@ import com.taskttl.data.repository.CountdownRepository
import com.taskttl.data.state.CountdownEffect
import com.taskttl.data.state.CountdownIntent
import com.taskttl.data.state.CountdownState
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.getString
import taskttl.composeapp.generated.resources.Res
@@ -37,20 +31,15 @@ import taskttl.composeapp.generated.resources.countdown_update_success
*/
class CountdownViewModel(
private val countdownRepository: CountdownRepository,
private val categoryRepository: CategoryRepository
) : ViewModel() {
private val categoryRepository: CategoryRepository,
) : BaseViewModel<CountdownState, CountdownIntent, CountdownEffect>(CountdownState()) {
private val _state = MutableStateFlow(CountdownState())
val state: StateFlow<CountdownState> = _state.asStateFlow()
private val _effects = MutableSharedFlow<CountdownEffect>()
val effects: SharedFlow<CountdownEffect> = _effects.asSharedFlow()
init {
handleIntent(CountdownIntent.LoadCountdowns)
processIntent(CountdownIntent.LoadCountdowns)
}
fun handleIntent(intent: CountdownIntent) {
public override fun handleIntent(intent: CountdownIntent) {
when (intent) {
is CountdownIntent.LoadCountdowns -> loadCountdowns()
is CountdownIntent.GetCountdownById -> getCountdownById(intent.countdownId)
@@ -64,29 +53,27 @@ class CountdownViewModel(
private fun loadCountdowns() {
viewModelScope.launch {
_state.value = _state.value.copy(isLoading = true, error = null)
updateState { copy(isLoading = true) }
try {
launch {
categoryRepository.getCategoriesByType(CategoryType.COUNTDOWN)
.collect { categories ->
_state.value = _state.value.copy(categories = categories)
}
.collect { categories -> updateState { copy(categories = categories) } }
}
launch {
countdownRepository.getAllCountdowns().collect { countdowns ->
_state.value = _state.value.copy(
countdowns = countdowns,
filteredCountdowns = filterCountdowns(countdowns),
isLoading = false
)
updateState {
copy(
countdowns = countdowns,
filteredCountdowns = filterCountdowns(countdowns)
)
}
}
}
} catch (e: Exception) {
_state.value =
_state.value.copy(
isLoading = false,
error = e.message ?: getString(Res.string.countdown_load_failed)
)
val errStr = getString(Res.string.countdown_load_failed)
updateState { copy(isLoading = false, error = e.message ?: errStr) }
} finally {
updateState { copy(isLoading = false) }
}
}
}
@@ -96,11 +83,10 @@ class CountdownViewModel(
viewModelScope.launch {
try {
val countdown = countdownRepository.getCountdownById(countdownId)
_state.value = _state.value.copy(editingCountdown = countdown)
updateState { copy(editingCountdown = countdown) }
} catch (e: Exception) {
_state.value = _state.value.copy(
error = e.message ?: getString(Res.string.countdown_query_failed)
)
val errStr = getString(Res.string.countdown_query_failed)
updateState { copy(isLoading = false, error = e.message ?: errStr) }
}
}
}
@@ -109,12 +95,11 @@ class CountdownViewModel(
viewModelScope.launch {
try {
countdownRepository.insertCountdown(countdown)
_effects.emit(CountdownEffect.ShowMessage(getString(Res.string.countdown_add_success)))
_effects.emit(CountdownEffect.NavigateBack)
sendEvent(CountdownEffect.ShowMessage(getString(Res.string.countdown_add_success)))
sendEvent(CountdownEffect.NavigateBack)
} catch (e: Exception) {
_state.value = _state.value.copy(
error = e.message ?: getString(Res.string.countdown_add_failed)
)
val errStr = getString(Res.string.countdown_add_failed)
updateState { copy(isLoading = false, error = e.message ?: errStr) }
}
}
}
@@ -123,11 +108,11 @@ class CountdownViewModel(
viewModelScope.launch {
try {
countdownRepository.updateCountdown(countdown)
_effects.emit(CountdownEffect.ShowMessage(getString(Res.string.countdown_update_success)))
sendEvent(CountdownEffect.ShowMessage(getString(Res.string.countdown_update_success)))
sendEvent(CountdownEffect.NavigateBack)
} catch (e: Exception) {
_state.value = _state.value.copy(
error = e.message ?: getString(Res.string.countdown_update_failed)
)
val errStr = getString(Res.string.countdown_update_failed)
updateState { copy(isLoading = false, error = e.message ?: errStr) }
}
}
}
@@ -136,26 +121,29 @@ class CountdownViewModel(
viewModelScope.launch {
try {
countdownRepository.deleteCountdown(countdownId)
_effects.emit(CountdownEffect.ShowMessage(getString(Res.string.countdown_delete_success)))
sendEvent(CountdownEffect.ShowMessage(getString(Res.string.countdown_delete_success)))
} catch (e: Exception) {
_state.value = _state.value.copy(error = e.message ?: getString(Res.string.countdown_delete_failed))
val errStr = getString(Res.string.countdown_delete_failed)
updateState { copy(isLoading = false, error = e.message ?: errStr) }
}
}
}
private fun filterByCategory(category: Category?) {
_state.value = _state.value.copy(
selectedCategory = category,
filteredCountdowns = filterCountdowns(_state.value.countdowns)
)
updateState {
copy(
selectedCategory = category,
filteredCountdowns = filterCountdowns(state.value.countdowns)
)
}
}
private fun clearError() {
_state.value = _state.value.copy(error = null)
updateState { copy(error = null) }
}
private fun filterCountdowns(countdowns: List<Countdown>): List<Countdown> {
val currentState = _state.value
val currentState = state.value
return countdowns.filter { countdown ->
currentState.selectedCategory?.let { countdown.category == it } ?: true
}