diff --git a/app/src/main/java/dev/achmad/ledgerr/ui/screens/category/CategoryScreenModel.kt b/app/src/main/java/dev/achmad/ledgerr/ui/screens/category/CategoryScreenModel.kt index 500ccbe..a9c4498 100644 --- a/app/src/main/java/dev/achmad/ledgerr/ui/screens/category/CategoryScreenModel.kt +++ b/app/src/main/java/dev/achmad/ledgerr/ui/screens/category/CategoryScreenModel.kt @@ -7,10 +7,13 @@ import dev.achmad.ledgerr.domain.category.interactor.DeleteCategory import dev.achmad.ledgerr.domain.category.interactor.GetCategories import dev.achmad.ledgerr.domain.category.interactor.UpsertCategory import dev.achmad.ledgerr.domain.category.model.Category +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext class CategoryScreenModel( private val getCategories: GetCategories = inject(), @@ -19,6 +22,7 @@ class CategoryScreenModel( ) : ScreenModel { val categories: StateFlow> = getCategories.subscribeAll() + .flowOn(Dispatchers.IO) .stateIn( scope = screenModelScope, started = SharingStarted.Eagerly, @@ -27,13 +31,17 @@ class CategoryScreenModel( fun upsert(category: Category) { screenModelScope.launch { - upsertCategory.await(category) + withContext(Dispatchers.IO) { + upsertCategory.await(category) + } } } fun delete(id: Long) { screenModelScope.launch { - runCatching { deleteCategory.await(id) } + withContext(Dispatchers.IO) { + runCatching { deleteCategory.await(id) } + } } } } diff --git a/app/src/main/java/dev/achmad/ledgerr/ui/screens/import_bank_statement/ImportBankStatementScreenModel.kt b/app/src/main/java/dev/achmad/ledgerr/ui/screens/import_bank_statement/ImportBankStatementScreenModel.kt index 510cd22..dd6dbd1 100644 --- a/app/src/main/java/dev/achmad/ledgerr/ui/screens/import_bank_statement/ImportBankStatementScreenModel.kt +++ b/app/src/main/java/dev/achmad/ledgerr/ui/screens/import_bank_statement/ImportBankStatementScreenModel.kt @@ -11,6 +11,7 @@ import dev.achmad.ledgerr.domain.category.interactor.GetCategories import dev.achmad.ledgerr.domain.category.model.Category import dev.achmad.ledgerr.domain.expense.interactor.InsertExpenses import dev.achmad.ledgerr.domain.expense.model.Expense +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow @@ -18,9 +19,11 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext sealed interface ImportState { data class BankPicker(val importers: List) : ImportState @@ -44,6 +47,7 @@ class ImportBankStatementScreenModel( val snackbar: SharedFlow = _snackbar.asSharedFlow() val categories: StateFlow> = getCategories.subscribeAll() + .flowOn(Dispatchers.IO) .stateIn( scope = screenModelScope, started = SharingStarted.Eagerly, @@ -55,7 +59,9 @@ class ImportBankStatementScreenModel( fun processPdf(uri: Uri, importer: BankStatementImporter) { screenModelScope.launch { _state.value = ImportState.Processing(importer.bankName) - val result = importer.await(uri) + val result = withContext(Dispatchers.IO) { + importer.await(uri) + } result .onSuccess { rows -> if (rows.isEmpty()) { @@ -105,23 +111,25 @@ class ImportBankStatementScreenModel( fun confirm(navigator: Navigator) { screenModelScope.launch { val confirmation = _state.value as? ImportState.Confirmation ?: return@launch - if (defaultCategoryId == 0L) { - defaultCategoryId = getCategories.awaitDefault().id - } val selected = confirmation.rows.filter { it.isSelected } if (selected.isEmpty()) { _snackbar.tryEmit("No items selected") return@launch } - val expenses = selected.map { pending -> - Expense( - amount = pending.amount, - categoryId = pending.suggestedCategoryId ?: defaultCategoryId, - date = pending.date, - note = pending.description, - ) + withContext(Dispatchers.IO) { + if (defaultCategoryId == 0L) { + defaultCategoryId = getCategories.awaitDefault().id + } + val expenses = selected.map { pending -> + Expense( + amount = pending.amount, + categoryId = pending.suggestedCategoryId ?: defaultCategoryId, + date = pending.date, + note = pending.description, + ) + } + insertExpenses.awaitAll(expenses) } - insertExpenses.awaitAll(expenses) navigator.pop() } } diff --git a/app/src/main/java/dev/achmad/ledgerr/ui/screens/settings/SettingsScreenModel.kt b/app/src/main/java/dev/achmad/ledgerr/ui/screens/settings/SettingsScreenModel.kt index 22827d6..1bba75f 100644 --- a/app/src/main/java/dev/achmad/ledgerr/ui/screens/settings/SettingsScreenModel.kt +++ b/app/src/main/java/dev/achmad/ledgerr/ui/screens/settings/SettingsScreenModel.kt @@ -8,7 +8,9 @@ import dev.achmad.ledgerr.domain.category.interactor.SeedDefaultCategories import dev.achmad.ledgerr.domain.data.interactor.ClearAllData import dev.achmad.ledgerr.domain.expense.model.DateRange import dev.achmad.ledgerr.domain.export.interactor.ExportExpensesToCsv +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext class SettingsScreenModel( private val exportExpensesToCsv: ExportExpensesToCsv = inject(), @@ -18,15 +20,20 @@ class SettingsScreenModel( fun exportToCsv(range: DateRange, uri: Uri, onResult: (Result) -> Unit) { screenModelScope.launch { - onResult(exportExpensesToCsv.await(range, uri)) + val result = withContext(Dispatchers.IO) { + exportExpensesToCsv.await(range, uri) + } + onResult(result) } } fun clearData(onResult: (Result) -> Unit) { screenModelScope.launch { - val result = runCatching { - clearAllData.await() - seedDefaultCategories.await() + val result = withContext(Dispatchers.IO) { + runCatching { + clearAllData.await() + seedDefaultCategories.await() + } } onResult(result) }