forked from agzam/vyatsu-schedule
fix(teacher): register migration, containment period queries, concurrency guards
- Register AppDatabase.MIGRATION_3_4 so v3 databases upgrade without data loss - Query teacher schedule periods by containment (weekStart<=x AND weekEnd>=x) instead of exact weekStart, matching 2-week catalog windows - Clip buildTeacherSchedule days to the requested week range - Add weeksFor() to enumerate weeks of a catalog window for the UI selector - Serialize syncPeriod body with a Mutex to protect the unique index - Rethrow CancellationException before generic catch; version loadRevision checks so stale observers/loads are cancelled - Sync job tracking in PickerViewModel; keep loading true while empty - Drop dead selectTeacher helper
This commit is contained in:
@@ -13,6 +13,7 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import java.time.DayOfWeek
|
||||
import java.time.temporal.TemporalAdjusters
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
@@ -45,6 +46,7 @@ class PickerViewModel(
|
||||
val uiState: StateFlow<PickerUiState> = _uiState.asStateFlow()
|
||||
|
||||
private var teachersJob: kotlinx.coroutines.Job? = null
|
||||
private var syncJob: kotlinx.coroutines.Job? = null
|
||||
|
||||
init {
|
||||
groupsLoad()
|
||||
@@ -139,11 +141,20 @@ class PickerViewModel(
|
||||
|
||||
_uiState.value = _uiState.value.copy(syncProgress = null, teachersLoading = true)
|
||||
|
||||
viewModelScope.launch {
|
||||
runCatching {
|
||||
syncJob?.cancel()
|
||||
syncJob = viewModelScope.launch {
|
||||
try {
|
||||
teacherScheduleRepository.syncPeriod(today).collect { progress ->
|
||||
_uiState.value = _uiState.value.copy(syncProgress = progress)
|
||||
}
|
||||
} catch (e: CancellationException) {
|
||||
throw e
|
||||
} catch (e: Throwable) {
|
||||
_uiState.value = _uiState.value.copy(
|
||||
error = e.message ?: "Не удалось загрузить расписание преподавателей"
|
||||
)
|
||||
} finally {
|
||||
_uiState.value = _uiState.value.copy(teachersLoading = false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,10 +162,11 @@ class PickerViewModel(
|
||||
teachersJob = viewModelScope.launch {
|
||||
teacherScheduleRepository.observeTeachers(period).collect { teachers ->
|
||||
val query = _uiState.value.teacherQuery
|
||||
val isLoading = _uiState.value.teachersLoading
|
||||
_uiState.value = _uiState.value.copy(
|
||||
teachersLoading = false,
|
||||
teachers = teachers,
|
||||
filteredTeachers = filterTeachers(teachers, query),
|
||||
teachersLoading = isLoading && teachers.isEmpty(),
|
||||
error = null
|
||||
)
|
||||
}
|
||||
@@ -178,11 +190,4 @@ class PickerViewModel(
|
||||
fun retryTeachers() {
|
||||
syncAndObserveTeachers()
|
||||
}
|
||||
|
||||
fun selectTeacher(teacher: Teacher) {
|
||||
viewModelScope.launch {
|
||||
preferencesRepository.clearSelectedGroup()
|
||||
preferencesRepository.setSelectedTeacherId(teacher.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user