163 lines
6.6 KiB
Kotlin
163 lines
6.6 KiB
Kotlin
package com.taskttl.data.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
|
|
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
|
|
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
|
|
|
|
/**
|
|
* 倒计时视图模型
|
|
* @author admin
|
|
* @date 2025/10/04
|
|
* @constructor 创建[CountdownViewModel]
|
|
* @param [countdownRepository] 倒计时存储库
|
|
*/
|
|
class CountdownViewModel(
|
|
private val countdownRepository: CountdownRepository,
|
|
private val categoryRepository: CategoryRepository,
|
|
) : BaseViewModel<CountdownState, CountdownIntent, CountdownEffect>(CountdownState()) {
|
|
|
|
|
|
init {
|
|
processIntent(CountdownIntent.LoadCountdowns)
|
|
}
|
|
|
|
public override 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 {
|
|
updateState { copy(isLoading = true) }
|
|
try {
|
|
launch {
|
|
categoryRepository.getCategoriesByType(CategoryType.COUNTDOWN)
|
|
.collect { categories -> updateState { copy(categories = categories) } }
|
|
}
|
|
launch {
|
|
countdownRepository.getAllCountdowns().collect { countdowns ->
|
|
updateState {
|
|
copy(
|
|
countdowns = countdowns,
|
|
filteredCountdowns = filterCountdowns(countdowns)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
} catch (e: Exception) {
|
|
val errStr = getString(Res.string.countdown_load_failed)
|
|
updateState { copy(isLoading = false, error = e.message ?: errStr) }
|
|
} finally {
|
|
updateState { copy(isLoading = false) }
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private fun getCountdownById(countdownId: String) {
|
|
viewModelScope.launch {
|
|
try {
|
|
val countdown = countdownRepository.getCountdownById(countdownId)
|
|
updateState { copy(editingCountdown = countdown) }
|
|
} catch (e: Exception) {
|
|
val errStr = getString(Res.string.countdown_query_failed)
|
|
updateState { copy(isLoading = false, error = e.message ?: errStr) }
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun addCountdown(countdown: Countdown) {
|
|
viewModelScope.launch {
|
|
try {
|
|
if (state.value.isProcessing) return@launch
|
|
updateState { copy(isLoading = false, isProcessing = true) }
|
|
countdownRepository.insertCountdown(countdown)
|
|
sendEvent(CountdownEffect.ShowMessage(getString(Res.string.countdown_add_success)))
|
|
sendEvent(CountdownEffect.NavigateBack)
|
|
} catch (e: Exception) {
|
|
val errStr = getString(Res.string.countdown_add_failed)
|
|
updateState { copy(error = e.message ?: errStr) }
|
|
} finally {
|
|
updateState { copy(isLoading = false, isProcessing = false) }
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun updateCountdown(countdown: Countdown) {
|
|
viewModelScope.launch {
|
|
try {
|
|
if (state.value.isProcessing) return@launch
|
|
updateState { copy(isLoading = false, isProcessing = true) }
|
|
countdownRepository.updateCountdown(countdown)
|
|
sendEvent(CountdownEffect.ShowMessage(getString(Res.string.countdown_update_success)))
|
|
sendEvent(CountdownEffect.NavigateBack)
|
|
} catch (e: Exception) {
|
|
val errStr = getString(Res.string.countdown_update_failed)
|
|
updateState { copy(error = e.message ?: errStr) }
|
|
} finally {
|
|
updateState { copy(isLoading = false, isProcessing = false) }
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun deleteCountdown(countdownId: String) {
|
|
viewModelScope.launch {
|
|
try {
|
|
if (state.value.isProcessing) return@launch
|
|
updateState { copy(isLoading = false, isProcessing = true) }
|
|
countdownRepository.deleteCountdown(countdownId)
|
|
sendEvent(CountdownEffect.ShowMessage(getString(Res.string.countdown_delete_success)))
|
|
} catch (e: Exception) {
|
|
val errStr = getString(Res.string.countdown_delete_failed)
|
|
updateState { copy(error = e.message ?: errStr) }
|
|
} finally {
|
|
updateState { copy(isLoading = false, isProcessing = false) }
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun filterByCategory(category: Category?) {
|
|
updateState {
|
|
copy(
|
|
selectedCategory = category,
|
|
filteredCountdowns = filterCountdowns(state.value.countdowns)
|
|
)
|
|
}
|
|
}
|
|
|
|
private fun clearError() {
|
|
updateState { 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
|
|
}
|
|
}
|
|
} |