@@ -23,14 +23,19 @@ class ScheduleViewModel(
2323 private val _uiState = MutableLiveData <ScheduleUiState >()
2424 val uiState: LiveData <ScheduleUiState > = _uiState
2525
26+ private var isLoading = false
27+ private var dateRange: ClosedRange <LocalDate >? = null
28+
2629 fun fetchScheduleData (forceRefresh : Boolean ) {
30+ if (isLoading) return
31+ isLoading = true
32+
2733 viewModelScope.launch {
2834 try {
29- val startDate = LocalDate .now().minusDays(7 )
30- val endDate = LocalDate .now().plusDays(7 )
35+ val startDate = dateRange?.start ? : LocalDate .now().minusDays(7 )
36+ val endDate = dateRange?.endInclusive ? : LocalDate .now().plusDays(7 )
3137
32- val cachedSchedule =
33- scheduleRepository.getCachedScheduleForRange(startDate, endDate)
38+ val cachedSchedule = scheduleRepository.getCachedScheduleForRange(startDate, endDate)
3439
3540 if (cachedSchedule.isNotEmpty() && ! forceRefresh) {
3641
@@ -48,10 +53,100 @@ class ScheduleViewModel(
4853 val remoteSchedule = scheduleRepository.getScheduleForRange(startDate, endDate)
4954 _uiState .postValue(ScheduleUiState .Success (remoteSchedule, false ))
5055 }
56+ dateRange = startDate.. endDate
57+ } catch (e: Exception ) {
58+ val errorMessage = " Failed to update schedule: ${e.message} "
59+ _uiState .postValue(ScheduleUiState .Error (errorMessage))
60+ e.printStackTrace()
61+ } finally {
62+ isLoading = false
63+ }
64+ }
65+ }
66+
67+ fun fetchPreviousDays () {
68+ if (isLoading) return
69+ isLoading = true
70+
71+ viewModelScope.launch {
72+ val currentSchedule = (_uiState .value as ? ScheduleUiState .Success )?.schedule ? : emptyList()
73+ try {
74+ val currentStartDate = dateRange?.start ? : LocalDate .now()
75+ val newStartDate = currentStartDate.minusDays(7 )
76+ val newEndDate = currentStartDate.minusDays(1 )
77+
78+ val cachedSchedule = scheduleRepository.getCachedScheduleForRange(newStartDate, newEndDate)
79+ val remoteSchedule = if (cachedSchedule.isNotEmpty()) {
80+ val totalDays = Duration .between(newStartDate.atStartOfDay(), newEndDate.atStartOfDay()).toDays() + 1
81+
82+ if (cachedSchedule.size < totalDays) {
83+ _uiState .postValue(ScheduleUiState .Loading )
84+ scheduleRepository.getScheduleForRange(newStartDate, newEndDate)
85+ } else {
86+ cachedSchedule
87+ }
88+ } else {
89+ _uiState .value = ScheduleUiState .Loading
90+ scheduleRepository.getScheduleForRange(newStartDate, newEndDate)
91+ }
92+
93+ val updatedSchedule = (remoteSchedule + currentSchedule).distinctBy { it.date }.sortedBy { it.date }
94+ _uiState .postValue(ScheduleUiState .Success (updatedSchedule, false ))
95+ dateRange = newStartDate.. (dateRange?.endInclusive ? : LocalDate .now())
96+ } catch (e: Exception ) {
97+ val errorMessage = " Failed to update schedule: ${e.message} "
98+ _uiState .postValue(ScheduleUiState .Error (errorMessage))
99+ _uiState .postValue(ScheduleUiState .Success (currentSchedule, false ))
100+ e.printStackTrace()
101+ } finally {
102+ isLoading = false
103+ }
104+ }
105+ }
106+
107+ fun fetchNextDays () {
108+ if (isLoading) return
109+ isLoading = true
110+
111+ viewModelScope.launch {
112+ val currentSchedule =
113+ (_uiState .value as ? ScheduleUiState .Success )?.schedule ? : emptyList()
114+ try {
115+
116+ val currentEndDate = dateRange?.endInclusive ? : LocalDate .now()
117+ val newStartDate = currentEndDate.plusDays(1 )
118+ val newEndDate = currentEndDate.plusDays(7 )
119+
120+ val cachedSchedule =
121+ scheduleRepository.getCachedScheduleForRange(newStartDate, newEndDate)
122+ val remoteSchedule = if (cachedSchedule.isNotEmpty()) {
123+ val totalDays =
124+ Duration .between(newStartDate.atStartOfDay(), newEndDate.atStartOfDay())
125+ .toDays() + 1
126+
127+ if (cachedSchedule.size < totalDays) {
128+ _uiState .postValue(ScheduleUiState .Loading )
129+ scheduleRepository.getScheduleForRange(newStartDate, newEndDate)
130+ } else {
131+ cachedSchedule
132+ }
133+ } else {
134+ _uiState .value = ScheduleUiState .Loading
135+ scheduleRepository.getScheduleForRange(newStartDate, newEndDate)
136+ }
137+
138+ val updatedSchedule =
139+ (currentSchedule + remoteSchedule).distinctBy { it.date }.sortedBy { it.date }
140+ _uiState .postValue(ScheduleUiState .Success (updatedSchedule, false ))
141+
142+ dateRange = (dateRange?.start ? : LocalDate .now()).. newEndDate
51143 } catch (e: Exception ) {
52144 val errorMessage = " Failed to update schedule: ${e.message} "
53145 _uiState .postValue(ScheduleUiState .Error (errorMessage))
146+ _uiState .postValue(ScheduleUiState .Success (currentSchedule, false ))
54147 e.printStackTrace()
148+ } finally {
149+ isLoading = false
55150 }
56151 }
57152 }
0 commit comments