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

163 lines
6.6 KiB
Kotlin
Raw Normal View History

2025-10-08 18:08:15 +08:00
package com.taskttl.data.viewmodel
import androidx.lifecycle.viewModelScope
2025-10-15 15:03:16 +08:00
import com.taskttl.core.viewmodel.BaseViewModel
2025-10-08 18:08:15 +08:00
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.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,
2025-10-15 15:03:16 +08:00
private val categoryRepository: CategoryRepository,
) : BaseViewModel<CountdownState, CountdownIntent, CountdownEffect>(CountdownState()) {
2025-10-08 18:08:15 +08:00
init {
2025-10-15 15:03:16 +08:00
processIntent(CountdownIntent.LoadCountdowns)
2025-10-08 18:08:15 +08:00
}
2025-10-15 15:03:16 +08:00
public override fun handleIntent(intent: CountdownIntent) {
2025-10-08 18:08:15 +08:00
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 {
2025-10-15 15:03:16 +08:00
updateState { copy(isLoading = true) }
2025-10-08 18:08:15 +08:00
try {
launch {
categoryRepository.getCategoriesByType(CategoryType.COUNTDOWN)
2025-10-15 15:03:16 +08:00
.collect { categories -> updateState { copy(categories = categories) } }
2025-10-08 18:08:15 +08:00
}
launch {
countdownRepository.getAllCountdowns().collect { countdowns ->
2025-10-15 15:03:16 +08:00
updateState {
copy(
countdowns = countdowns,
filteredCountdowns = filterCountdowns(countdowns)
)
}
2025-10-08 18:08:15 +08:00
}
}
} catch (e: Exception) {
2025-10-15 15:03:16 +08:00
val errStr = getString(Res.string.countdown_load_failed)
updateState { copy(isLoading = false, error = e.message ?: errStr) }
} finally {
updateState { copy(isLoading = false) }
2025-10-08 18:08:15 +08:00
}
}
}
private fun getCountdownById(countdownId: String) {
viewModelScope.launch {
try {
val countdown = countdownRepository.getCountdownById(countdownId)
2025-10-15 15:03:16 +08:00
updateState { copy(editingCountdown = countdown) }
2025-10-08 18:08:15 +08:00
} catch (e: Exception) {
2025-10-15 15:03:16 +08:00
val errStr = getString(Res.string.countdown_query_failed)
updateState { copy(isLoading = false, error = e.message ?: errStr) }
2025-10-08 18:08:15 +08:00
}
}
}
private fun addCountdown(countdown: Countdown) {
viewModelScope.launch {
try {
2025-10-16 21:45:02 +08:00
if (state.value.isProcessing) return@launch
updateState { copy(isLoading = false, isProcessing = true) }
2025-10-08 18:08:15 +08:00
countdownRepository.insertCountdown(countdown)
2025-10-15 15:03:16 +08:00
sendEvent(CountdownEffect.ShowMessage(getString(Res.string.countdown_add_success)))
sendEvent(CountdownEffect.NavigateBack)
2025-10-08 18:08:15 +08:00
} catch (e: Exception) {
2025-10-15 15:03:16 +08:00
val errStr = getString(Res.string.countdown_add_failed)
2025-10-16 21:45:02 +08:00
updateState { copy(error = e.message ?: errStr) }
} finally {
updateState { copy(isLoading = false, isProcessing = false) }
2025-10-08 18:08:15 +08:00
}
}
}
private fun updateCountdown(countdown: Countdown) {
viewModelScope.launch {
try {
2025-10-16 21:45:02 +08:00
if (state.value.isProcessing) return@launch
updateState { copy(isLoading = false, isProcessing = true) }
2025-10-08 18:08:15 +08:00
countdownRepository.updateCountdown(countdown)
2025-10-15 15:03:16 +08:00
sendEvent(CountdownEffect.ShowMessage(getString(Res.string.countdown_update_success)))
sendEvent(CountdownEffect.NavigateBack)
2025-10-08 18:08:15 +08:00
} catch (e: Exception) {
2025-10-15 15:03:16 +08:00
val errStr = getString(Res.string.countdown_update_failed)
2025-10-16 21:45:02 +08:00
updateState { copy(error = e.message ?: errStr) }
} finally {
updateState { copy(isLoading = false, isProcessing = false) }
2025-10-08 18:08:15 +08:00
}
}
}
private fun deleteCountdown(countdownId: String) {
viewModelScope.launch {
try {
2025-10-16 21:45:02 +08:00
if (state.value.isProcessing) return@launch
updateState { copy(isLoading = false, isProcessing = true) }
2025-10-08 18:08:15 +08:00
countdownRepository.deleteCountdown(countdownId)
2025-10-15 15:03:16 +08:00
sendEvent(CountdownEffect.ShowMessage(getString(Res.string.countdown_delete_success)))
2025-10-08 18:08:15 +08:00
} catch (e: Exception) {
2025-10-15 15:03:16 +08:00
val errStr = getString(Res.string.countdown_delete_failed)
2025-10-16 21:45:02 +08:00
updateState { copy(error = e.message ?: errStr) }
} finally {
updateState { copy(isLoading = false, isProcessing = false) }
2025-10-08 18:08:15 +08:00
}
}
}
private fun filterByCategory(category: Category?) {
2025-10-15 15:03:16 +08:00
updateState {
copy(
selectedCategory = category,
filteredCountdowns = filterCountdowns(state.value.countdowns)
)
}
2025-10-08 18:08:15 +08:00
}
private fun clearError() {
2025-10-15 15:03:16 +08:00
updateState { copy(error = null) }
2025-10-08 18:08:15 +08:00
}
private fun filterCountdowns(countdowns: List<Countdown>): List<Countdown> {
2025-10-15 15:03:16 +08:00
val currentState = state.value
2025-10-08 18:08:15 +08:00
return countdowns.filter { countdown ->
currentState.selectedCategory?.let { countdown.category == it } ?: true
}
}
}