11package org.openedx.downloads.presentation.download
22
3- import androidx.compose.material.icons.Icons
4- import androidx.compose.material.icons.automirrored.outlined.InsertDriveFile
53import androidx.fragment.app.FragmentManager
64import androidx.lifecycle.viewModelScope
75import kotlinx.coroutines.Dispatchers
@@ -138,7 +136,13 @@ class DownloadsViewModel(
138136 val computedState = if (blockStates.isEmpty()) {
139137 DownloadedState .NOT_DOWNLOADED
140138 } else {
141- determineCourseState(blockStates)
139+ val downloadedSize = _uiState .value.downloadModels
140+ .filter { it.courseId == courseId }
141+ .sumOf { it.size }
142+ val courseSize = _uiState .value.downloadCoursePreviews
143+ .find { it.id == courseId }?.totalSize ? : 0
144+ val isSizeMatch: Boolean = downloadedSize.toDouble() / courseSize >= 0.95
145+ determineCourseState(blockStates, isSizeMatch)
142146 }
143147 if (currentCourseState == DownloadedState .LOADING_COURSE_STRUCTURE &&
144148 computedState == DownloadedState .NOT_DOWNLOADED
@@ -156,9 +160,12 @@ class DownloadsViewModel(
156160 }
157161 }
158162
159- private fun determineCourseState (blockStates : List <DownloadedState >): DownloadedState {
163+ private fun determineCourseState (
164+ blockStates : List <DownloadedState >,
165+ isSizeMatch : Boolean
166+ ): DownloadedState {
160167 return when {
161- blockStates.all { it == DownloadedState .DOWNLOADED } -> DownloadedState .DOWNLOADED
168+ blockStates.all { it == DownloadedState .DOWNLOADED } && isSizeMatch -> DownloadedState .DOWNLOADED
162169 blockStates.all { it == DownloadedState .WAITING } -> DownloadedState .WAITING
163170 blockStates.any { it == DownloadedState .DOWNLOADING } -> DownloadedState .DOWNLOADING
164171 else -> DownloadedState .NOT_DOWNLOADED
@@ -169,7 +176,9 @@ class DownloadsViewModel(
169176 viewModelScope.launch(Dispatchers .IO ) {
170177 updateLoadingState(isLoading = ! refresh, isRefreshing = refresh)
171178 interactor.getDownloadCoursesPreview(refresh)
172- .onCompletion { resetLoadingState() }
179+ .onCompletion {
180+ resetLoadingState()
181+ }
173182 .catch { e ->
174183 emitErrorMessage(e)
175184 }
@@ -183,7 +192,11 @@ class DownloadsViewModel(
183192 .forEach { addDownloadableChildrenForSequentialBlock(it) }
184193 initDownloadModelsStatus()
185194 _uiState .update { state ->
186- state.copy(downloadCoursePreviews = downloadCoursePreviews)
195+ state.copy(
196+ downloadCoursePreviews = downloadCoursePreviews,
197+ isLoading = false ,
198+ isRefreshing = false
199+ )
187200 }
188201 }
189202 }
@@ -195,12 +208,6 @@ class DownloadsViewModel(
195208 }
196209 }
197210
198- private fun resetLoadingState () {
199- _uiState .update { state ->
200- state.copy(isLoading = false , isRefreshing = false )
201- }
202- }
203-
204211 private suspend fun emitErrorMessage (e : Throwable ) {
205212 val text = if (e.isInternetError()) {
206213 R .string.core_error_no_connection
@@ -213,7 +220,6 @@ class DownloadsViewModel(
213220 }
214221
215222 fun refreshData () {
216- _uiState .update { it.copy(isRefreshing = true ) }
217223 fetchDownloads(refresh = true )
218224 }
219225
@@ -258,7 +264,6 @@ class DownloadsViewModel(
258264 val downloadDialogItem = DownloadDialogItem (
259265 title = title,
260266 size = totalSize,
261- icon = Icons .AutoMirrored .Outlined .InsertDriveFile
262267 )
263268 downloadDialogManager.showRemoveDownloadModelPopup(
264269 downloadDialogItem = downloadDialogItem,
@@ -343,6 +348,12 @@ class DownloadsViewModel(
343348 )
344349 }
345350
351+ private fun resetLoadingState () {
352+ _uiState .update { state ->
353+ state.copy(isLoading = false , isRefreshing = false )
354+ }
355+ }
356+
346357 private fun updateCourseState (courseId : String , state : DownloadedState ) {
347358 _uiState .update { currentState ->
348359 currentState.copy(
0 commit comments