From c818a35577852427f578f65c5ee25c8699112a9d Mon Sep 17 00:00:00 2001 From: Rajan Maurya Date: Wed, 25 Feb 2026 09:49:29 +0530 Subject: [PATCH] feat(ui): add launchIO helper to BaseViewModel for background operations Add a launchIO helper function to BaseViewModel that launches coroutines on Dispatchers.Default. This prevents UI freezing when performing network or database operations by ensuring they run on background threads. Uses Dispatchers.Default instead of Dispatchers.IO for multiplatform compatibility (IO is not available on JS/WasmJS targets). Usage: - Replace `viewModelScope.launch { }` with `launchIO { }` for I/O operations - StateFlow updates remain thread-safe - Progress indicators animate smoothly during API calls Co-Authored-By: Claude Opus 4.5 --- .../template/core/base/ui/BaseViewModel.kt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/core-base/ui/src/commonMain/kotlin/template/core/base/ui/BaseViewModel.kt b/core-base/ui/src/commonMain/kotlin/template/core/base/ui/BaseViewModel.kt index 2b4b8550..c40b0be5 100644 --- a/core-base/ui/src/commonMain/kotlin/template/core/base/ui/BaseViewModel.kt +++ b/core-base/ui/src/commonMain/kotlin/template/core/base/ui/BaseViewModel.kt @@ -11,6 +11,9 @@ package template.core.base.ui import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.SendChannel import kotlinx.coroutines.flow.Flow @@ -97,4 +100,18 @@ abstract class BaseViewModel( protected fun sendEvent(event: E) { viewModelScope.launch { eventChannel.send(event) } } + + /** + * Launches a coroutine on [Dispatchers.Default] for network or database operations. + * Use this instead of `viewModelScope.launch` for any I/O-bound work to avoid + * blocking the main thread and causing UI freezes. + * + * Note: Uses Default dispatcher for multiplatform compatibility (IO is not available on JS). + * + * @param block The suspending block to execute on the background dispatcher. + * @return The [Job] representing the coroutine. + */ + protected fun launchIO(block: suspend CoroutineScope.() -> Unit): Job { + return viewModelScope.launch(Dispatchers.Default, block = block) + } }