@@ -5,6 +5,7 @@ import android.content.BroadcastReceiver
55import android.content.Context
66import android.content.Intent
77import android.content.IntentFilter
8+ import androidx.lifecycle.viewModelScope
89import com.d4rk.android.libs.apptoolkit.core.di.DispatcherProvider
910import com.d4rk.android.libs.apptoolkit.core.domain.model.network.DataState
1011import com.d4rk.android.libs.apptoolkit.core.domain.model.ui.UiSnackbar
@@ -28,10 +29,12 @@ import com.d4rk.cleaner.app.apps.manager.domain.usecases.ShareApkUseCase
2829import com.d4rk.cleaner.app.apps.manager.domain.usecases.ShareAppUseCase
2930import com.d4rk.cleaner.app.apps.manager.domain.usecases.UninstallAppUseCase
3031import com.d4rk.cleaner.core.utils.helpers.CleaningEventBus
32+ import kotlinx.coroutines.Job
3133import kotlinx.coroutines.flow.MutableStateFlow
3234import kotlinx.coroutines.flow.asStateFlow
3335import kotlinx.coroutines.flow.collectLatest
3436import kotlinx.coroutines.flow.flowOn
37+ import kotlinx.coroutines.flow.launchIn
3538import kotlinx.coroutines.flow.onEach
3639import kotlinx.coroutines.flow.update
3740import kotlinx.coroutines.launch
@@ -61,6 +64,7 @@ class AppManagerViewModel(
6164
6265 private var pendingUninstallPackage: String? = null
6366 private var pendingInstallPackage: String? = null
67+ private var loadJob: Job ? = null
6468
6569 fun onSearchQueryChange (query : String ) {
6670 _searchQuery .value = query
@@ -150,90 +154,92 @@ class AppManagerViewModel(
150154 }
151155
152156 private fun loadAppData () {
153- launch {
154- val installedAppsFlow =
155- getInstalledAppsUseCase().flowOn(dispatchers.default).onEach { result ->
156- _uiState .update { currentState ->
157- when (result) {
158- is DataState . Loading -> currentState.copy(
159- data = currentState.data? .copy(
160- userAppsLoading = true ,
161- systemAppsLoading = true
162- )
157+ loadJob?.cancel()
158+
159+ val installedAppsFlow =
160+ getInstalledAppsUseCase().flowOn(dispatchers.default).onEach { result ->
161+ _uiState .update { currentState ->
162+ when (result) {
163+ is DataState . Loading -> currentState.copy(
164+ data = currentState.data?.copy(
165+ userAppsLoading = true ,
166+ systemAppsLoading = true
163167 )
164-
165- is DataState .Success -> {
166- val pm = applicationContext.packageManager
167- val comparator = compareBy< android.content.pm.ApplicationInfo > (
168- { runCatching { pm.getApplicationLabel(it).toString() }
169- .getOrNull()
170- ?.lowercase(Locale .getDefault())
171- ? : it.packageName.lowercase(Locale .getDefault()) },
172- { it.packageName.lowercase(Locale .getDefault()) }
173- )
174- currentState.copy(
175- data = currentState.data?.copy(
176- installedApps = result.data.sortedWith(comparator),
177- userAppsLoading = false ,
178- systemAppsLoading = false
179- )
180- )
181- }
182-
183- is DataState .Error -> currentState.copy(
168+ ),
169+
170+ is DataState .Success -> {
171+ val pm = applicationContext.packageManager
172+ val comparator = compareBy< android.content.pm.ApplicationInfo > (
173+ { runCatching { pm.getApplicationLabel(it).toString() }
174+ .getOrNull()
175+ ?.lowercase(Locale .getDefault())
176+ ? : it.packageName.lowercase(Locale .getDefault()) },
177+ { it.packageName.lowercase(Locale .getDefault()) }
178+ )
179+ currentState.copy(
184180 data = currentState.data?.copy(
181+ installedApps = result.data.sortedWith(comparator),
185182 userAppsLoading = false ,
186183 systemAppsLoading = false
187184 )
188185 )
189- }
186+ },
187+
188+ is DataState .Error -> currentState.copy(
189+ data = currentState.data?.copy(
190+ userAppsLoading = false ,
191+ systemAppsLoading = false
192+ )
193+ )
190194 }
191195 }
196+ }
192197
193- val apkFilesFlow =
194- getApkFilesFromStorageUseCase().flowOn(dispatchers.default).onEach { result ->
195- _uiState .update { currentState ->
196- when (result) {
197- is DataState .Loading -> currentState.copy(
198- data = currentState.data?.copy(
199- apkFilesLoading = true
200- )
198+ val apkFilesFlow =
199+ getApkFilesFromStorageUseCase().flowOn(dispatchers.default).onEach { result ->
200+ _uiState .update { currentState ->
201+ when (result) {
202+ is DataState .Loading -> currentState.copy(
203+ data = currentState.data?.copy(
204+ apkFilesLoading = true
201205 )
202-
203- is DataState . Success -> currentState.copy(
204- data = currentState.data? .copy(
205- apkFiles = result .data.sortedBy {
206- it.path.substringAfterLast( ' / ' ).lowercase()
207- },
208- apkFilesLoading = false ))
209-
210- is DataState . Error -> currentState.copy(
211- data = currentState.data? .copy(
212- apkFilesLoading = false
213- )
206+ ),
207+
208+ is DataState . Success -> currentState.copy(
209+ data = currentState .data?.copy(
210+ apkFiles = result.data.sortedBy {
211+ it.path.substringAfterLast( ' / ' ).lowercase()
212+ },
213+ apkFilesLoading = false )),
214+
215+ is DataState . Error -> currentState.copy(
216+ data = currentState.data?.copy(
217+ apkFilesLoading = false
214218 )
215- }
219+ )
216220 }
217221 }
222+ }
218223
219- val usageStatsFlow =
220- getAppsLastUsedUseCase().flowOn(dispatchers.default).onEach { result ->
221- _uiState .update { currentState ->
222- when (result) {
223- is DataState .Success -> currentState.copy(
224- data = currentState.data?.copy(
225- appUsageStats = result.data
226- )
224+ val usageStatsFlow =
225+ getAppsLastUsedUseCase().flowOn(dispatchers.default).onEach { result ->
226+ _uiState .update { currentState ->
227+ when (result) {
228+ is DataState .Success -> currentState.copy(
229+ data = currentState.data?.copy(
230+ appUsageStats = result.data
227231 )
232+ ),
228233
229- else -> currentState
230- }
234+ else -> currentState
231235 }
232236 }
237+ }
233238
234- launch(dispatchers.io) { installedAppsFlow.collectLatest {} }
235- launch(dispatchers.io) { apkFilesFlow.collectLatest {} }
236- launch(dispatchers.io) { usageStatsFlow.collectLatest {} }
239+ loadJob = viewModelScope.launch(dispatchers.io) {
240+ installedAppsFlow.launchIn(this )
241+ apkFilesFlow.launchIn(this )
242+ usageStatsFlow.launchIn(this )
237243 }
238244 }
239245
0 commit comments