Files
TaskTTL/composeApp/src/commonMain/kotlin/com/taskttl/data/viewmodel/CountdownViewModel.kt

163 lines
6.3 KiB
Kotlin
Raw Normal View History

2025-10-08 18:08:15 +08:00
package com.taskttl.data.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.taskttl.data.local.model.Category
import com.taskttl.data.local.model.CategoryType
import com.taskttl.data.local.model.Countdown
import com.taskttl.data.repository.CategoryRepository
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
2025-10-12 22:08:39 +08:00
import org.jetbrains.compose.resources.getString
import taskttl.composeapp.generated.resources.Res
import taskttl.composeapp.generated.resources.countdown_add_failed
import taskttl.composeapp.generated.resources.countdown_add_success
import taskttl.composeapp.generated.resources.countdown_delete_failed
import taskttl.composeapp.generated.resources.countdown_delete_success
import taskttl.composeapp.generated.resources.countdown_load_failed
import taskttl.composeapp.generated.resources.countdown_query_failed
import taskttl.composeapp.generated.resources.countdown_update_failed
import taskttl.composeapp.generated.resources.countdown_update_success
2025-10-08 18:08:15 +08:00
/**
* 倒计时视图模型
* @author admin
* @date 2025/10/04
* @constructor 创建[CountdownViewModel]
* @param [countdownRepository] 倒计时存储库
*/
class CountdownViewModel(
private val countdownRepository: CountdownRepository,
private val categoryRepository: CategoryRepository
) : ViewModel() {
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)
}
fun handleIntent(intent: CountdownIntent) {
when (intent) {
is CountdownIntent.LoadCountdowns -> loadCountdowns()
is CountdownIntent.GetCountdownById -> getCountdownById(intent.countdownId)
is CountdownIntent.AddCountdown -> addCountdown(intent.countdown)
is CountdownIntent.UpdateCountdown -> updateCountdown(intent.countdown)
is CountdownIntent.DeleteCountdown -> deleteCountdown(intent.countdownId)
is CountdownIntent.FilterByCategory -> filterByCategory(intent.category)
is CountdownIntent.ClearError -> clearError()
}
}
private fun loadCountdowns() {
viewModelScope.launch {
_state.value = _state.value.copy(isLoading = true, error = null)
try {
launch {
categoryRepository.getCategoriesByType(CategoryType.COUNTDOWN)
.collect { categories ->
_state.value = _state.value.copy(categories = categories)
}
}
launch {
countdownRepository.getAllCountdowns().collect { countdowns ->
_state.value = _state.value.copy(
countdowns = countdowns,
filteredCountdowns = filterCountdowns(countdowns),
isLoading = false
)
}
}
} catch (e: Exception) {
_state.value =
2025-10-12 22:08:39 +08:00
_state.value.copy(
isLoading = false,
error = e.message ?: getString(Res.string.countdown_load_failed)
)
2025-10-08 18:08:15 +08:00
}
}
}
private fun getCountdownById(countdownId: String) {
viewModelScope.launch {
try {
val countdown = countdownRepository.getCountdownById(countdownId)
_state.value = _state.value.copy(editingCountdown = countdown)
} catch (e: Exception) {
2025-10-12 22:08:39 +08:00
_state.value = _state.value.copy(
error = e.message ?: getString(Res.string.countdown_query_failed)
)
2025-10-08 18:08:15 +08:00
}
}
}
private fun addCountdown(countdown: Countdown) {
viewModelScope.launch {
try {
countdownRepository.insertCountdown(countdown)
2025-10-12 22:08:39 +08:00
_effects.emit(CountdownEffect.ShowMessage(getString(Res.string.countdown_add_success)))
2025-10-08 18:08:15 +08:00
_effects.emit(CountdownEffect.NavigateBack)
} catch (e: Exception) {
2025-10-12 22:08:39 +08:00
_state.value = _state.value.copy(
error = e.message ?: getString(Res.string.countdown_add_failed)
)
2025-10-08 18:08:15 +08:00
}
}
}
private fun updateCountdown(countdown: Countdown) {
viewModelScope.launch {
try {
countdownRepository.updateCountdown(countdown)
2025-10-12 22:08:39 +08:00
_effects.emit(CountdownEffect.ShowMessage(getString(Res.string.countdown_update_success)))
2025-10-08 18:08:15 +08:00
} catch (e: Exception) {
2025-10-12 22:08:39 +08:00
_state.value = _state.value.copy(
error = e.message ?: getString(Res.string.countdown_update_failed)
)
2025-10-08 18:08:15 +08:00
}
}
}
private fun deleteCountdown(countdownId: String) {
viewModelScope.launch {
try {
countdownRepository.deleteCountdown(countdownId)
2025-10-12 22:08:39 +08:00
_effects.emit(CountdownEffect.ShowMessage(getString(Res.string.countdown_delete_success)))
2025-10-08 18:08:15 +08:00
} catch (e: Exception) {
2025-10-12 22:08:39 +08:00
_state.value = _state.value.copy(error = e.message ?: getString(Res.string.countdown_delete_failed))
2025-10-08 18:08:15 +08:00
}
}
}
private fun filterByCategory(category: Category?) {
_state.value = _state.value.copy(
selectedCategory = category,
filteredCountdowns = filterCountdowns(_state.value.countdowns)
)
}
private fun clearError() {
_state.value = _state.value.copy(error = null)
}
private fun filterCountdowns(countdowns: List<Countdown>): List<Countdown> {
val currentState = _state.value
return countdowns.filter { countdown ->
currentState.selectedCategory?.let { countdown.category == it } ?: true
}
}
}