fix: loading instead error screen

This commit is contained in:
2026-09-11 00:18:23 +03:00
parent 99e05e8232
commit 65bb6cc7db
4 changed files with 43 additions and 28 deletions
+1 -1
View File
@@ -23,7 +23,6 @@ fun AppRoot() {
val container = app.container val container = app.container
val scheduleViewModel: ScheduleViewModel = viewModel(factory = scheduleFactory(container)) val scheduleViewModel: ScheduleViewModel = viewModel(factory = scheduleFactory(container))
val groupPickerViewModel: GroupPickerViewModel = viewModel(factory = groupPickerFactory(container))
val updateViewModel: UpdateViewModel = viewModel(factory = updateFactory(container)) val updateViewModel: UpdateViewModel = viewModel(factory = updateFactory(container))
val state by scheduleViewModel.uiState.collectAsState() val state by scheduleViewModel.uiState.collectAsState()
@@ -53,6 +52,7 @@ fun AppRoot() {
} }
if (state.noGroup) { if (state.noGroup) {
val groupPickerViewModel: GroupPickerViewModel = viewModel(factory = groupPickerFactory(container))
GroupPickerScreen( GroupPickerScreen(
viewModel = groupPickerViewModel, viewModel = groupPickerViewModel,
onGroupPicked = { group -> scheduleViewModel.selectGroup(group.id) } onGroupPicked = { group -> scheduleViewModel.selectGroup(group.id) }
@@ -42,7 +42,6 @@ object GroupsParser {
return tables.flatMap { table -> return tables.flatMap { table ->
table.select("> tbody > tr, > tr").flatMap { row -> table.select("> tbody > tr, > tr").flatMap { row ->
Log.v("ROW", row.html());
val faculty = shortname(row.selectFirst("div.fak_name")?.text().orEmpty()) // val faculty = shortname(row.selectFirst("div.fak_name")?.text().orEmpty()) //
row.select("div.grpPeriod").map { grp -> row.select("div.grpPeriod").map { grp ->
@@ -18,6 +18,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.only import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBars import androidx.compose.foundation.layout.statusBars
import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
@@ -75,6 +76,12 @@ fun ScheduleScreen(viewModel: ScheduleViewModel, onSwitchGroup: () -> Unit) {
TopAppBar( TopAppBar(
title = { Text(state.groupName ?: "Расписание", style = MaterialTheme.typography.titleMedium) }, title = { Text(state.groupName ?: "Расписание", style = MaterialTheme.typography.titleMedium) },
actions = { actions = {
if (state.isLoading && state.schedule != null) {
CircularProgressIndicator(
modifier = Modifier.size(24.dp),
strokeWidth = 2.dp
)
}
TextButton(onClick = { onSwitchGroup() }) { TextButton(onClick = { onSwitchGroup() }) {
Text("Сменить группу") Text("Сменить группу")
} }
@@ -86,16 +93,7 @@ fun ScheduleScreen(viewModel: ScheduleViewModel, onSwitchGroup: () -> Unit) {
) )
Column(Modifier.fillMaxSize().padding(horizontal = 0.dp, vertical = 0.dp)) { Column(Modifier.fillMaxSize().padding(horizontal = 0.dp, vertical = 0.dp)) {
when { when {
state.isSyncing && state.schedule == null -> { state.schedule == null && state.loadError -> {
Row(
Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
CircularProgressIndicator()
}
}
state.schedule == null -> {
Column( Column(
Modifier.fillMaxWidth(), Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
@@ -110,6 +108,15 @@ fun ScheduleScreen(viewModel: ScheduleViewModel, onSwitchGroup: () -> Unit) {
} }
} }
state.schedule == null -> {
Row(
Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
CircularProgressIndicator()
}
}
else -> { else -> {
val schedule = state.schedule!! val schedule = state.schedule!!
val weekDays = state.weekStart val weekDays = state.weekStart
@@ -37,6 +37,7 @@ class ScheduleViewModel(
fun selectGroup(groupId: String) { fun selectGroup(groupId: String) {
currentGroupId = groupId currentGroupId = groupId
_uiState.value = _uiState.value.copy(noGroup = false, isLoading = true, loadError = false)
viewModelScope.launch { viewModelScope.launch {
preferencesRepository.setSelectedGroup(groupId) preferencesRepository.setSelectedGroup(groupId)
val groupName = groupRepository.getGroups().firstOrNull { it.id == groupId }?.name val groupName = groupRepository.getGroups().firstOrNull { it.id == groupId }?.name
@@ -61,7 +62,7 @@ class ScheduleViewModel(
} }
launch { launch {
syncIfMissingToday(groupId) syncIfMissing(groupId)
} }
} }
} }
@@ -96,7 +97,9 @@ class ScheduleViewModel(
schedule = schedule, schedule = schedule,
weekStart = weekStart, weekStart = weekStart,
dayDate = dayDate, dayDate = dayDate,
todayDate = todayDate todayDate = todayDate,
isLoading = false,
loadError = false
) )
} }
@@ -128,30 +131,36 @@ class ScheduleViewModel(
} }
} }
private suspend fun syncIfMissingToday(groupId: String) { private suspend fun syncIfMissing(groupId: String) {
val schedule = scheduleRepository.getSchedule(groupId) if (scheduleRepository.getSchedule(groupId) != null) {
val today = ScheduleDates.moscowToday() _uiState.value = _uiState.value.copy(isLoading = false)
val hasTodayPeriod = schedule?.periodOf(today) != null return
if (hasTodayPeriod) return }
_uiState.value = _uiState.value.copy(isSyncing = true) loadSchedule(groupId)
scheduleRepository.sync(groupId) }
_uiState.value = _uiState.value.copy(isSyncing = false)
private suspend fun loadSchedule(groupId: String) {
_uiState.value = _uiState.value.copy(isLoading = true, loadError = false)
val schedule = scheduleRepository.sync(groupId)
_uiState.value = if (schedule != null) {
_uiState.value.copy(isLoading = false, loadError = false)
} else {
_uiState.value.copy(isLoading = false, loadError = true)
}
} }
fun switchGroup() { fun switchGroup() {
viewModelScope.launch { viewModelScope.launch {
currentGroupId = null currentGroupId = null
preferencesRepository.clearSelectedGroup() preferencesRepository.clearSelectedGroup()
_uiState.value = _uiState.value.copy(noGroup = true) _uiState.value = _uiState.value.copy(noGroup = true, isLoading = false, loadError = false)
} }
} }
fun refresh() { fun refresh() {
val groupId = currentGroupId ?: return val groupId = currentGroupId ?: return
viewModelScope.launch { viewModelScope.launch {
_uiState.value = _uiState.value.copy(isRefreshing = true) loadSchedule(groupId)
scheduleRepository.sync(groupId)
_uiState.value = _uiState.value.copy(isRefreshing = false)
} }
} }
@@ -175,8 +184,8 @@ class ScheduleViewModel(
data class ScheduleUiState( data class ScheduleUiState(
val noGroup: Boolean = false, val noGroup: Boolean = false,
val isRefreshing: Boolean = false, val isLoading: Boolean = false,
val isSyncing: Boolean = false, val loadError: Boolean = false,
val schedule: Schedule? = null, val schedule: Schedule? = null,
val groupName: String? = null, val groupName: String? = null,
val weekStart: LocalDate? = null, val weekStart: LocalDate? = null,