Skip to content

Commit 98b25b6

Browse files
Add cancellable app data loading job
1 parent 989a37c commit 98b25b6

File tree

1 file changed

+71
-65
lines changed

1 file changed

+71
-65
lines changed

app/src/main/kotlin/com/d4rk/cleaner/app/apps/manager/ui/AppManagerViewModel.kt

Lines changed: 71 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import android.content.BroadcastReceiver
55
import android.content.Context
66
import android.content.Intent
77
import android.content.IntentFilter
8+
import androidx.lifecycle.viewModelScope
89
import com.d4rk.android.libs.apptoolkit.core.di.DispatcherProvider
910
import com.d4rk.android.libs.apptoolkit.core.domain.model.network.DataState
1011
import com.d4rk.android.libs.apptoolkit.core.domain.model.ui.UiSnackbar
@@ -28,10 +29,12 @@ import com.d4rk.cleaner.app.apps.manager.domain.usecases.ShareApkUseCase
2829
import com.d4rk.cleaner.app.apps.manager.domain.usecases.ShareAppUseCase
2930
import com.d4rk.cleaner.app.apps.manager.domain.usecases.UninstallAppUseCase
3031
import com.d4rk.cleaner.core.utils.helpers.CleaningEventBus
32+
import kotlinx.coroutines.Job
3133
import kotlinx.coroutines.flow.MutableStateFlow
3234
import kotlinx.coroutines.flow.asStateFlow
3335
import kotlinx.coroutines.flow.collectLatest
3436
import kotlinx.coroutines.flow.flowOn
37+
import kotlinx.coroutines.flow.launchIn
3538
import kotlinx.coroutines.flow.onEach
3639
import kotlinx.coroutines.flow.update
3740
import 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

Comments
 (0)