Skip to content

Instantly share code, notes, and snippets.

@tuannha95
Created October 28, 2020 07:42
Show Gist options
  • Save tuannha95/76df199323e441923a5b14deb0b86bcb to your computer and use it in GitHub Desktop.
Save tuannha95/76df199323e441923a5b14deb0b86bcb to your computer and use it in GitHub Desktop.
package com.gunaya.demo.demomeow.presentation.base
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.gunaya.demo.demomeow.utils.EventWrapper
import com.gunaya.demo.demomeow.utils.SingleLiveEvent
import com.gunaya.demo.demomeow.utils.UseCaseResult
import kotlinx.coroutines.*
import kotlin.coroutines.CoroutineContext
// To avoid writing the same extensions multiple times, we'll make an abstract class for ViewModels
abstract class BaseViewModel : ViewModel(), CoroutineScope {
// Coroutine's background job
private val job = Job()
// Define default thread for Coroutine as Main and add job
override val coroutineContext: CoroutineContext = job + Dispatchers.Main
val loading = MutableLiveData<EventWrapper<Boolean>>()
val error = SingleLiveEvent<String>()
val isLoading = MutableLiveData<Boolean>().apply { value = false }
private val isShowLoading = MutableLiveData<Boolean>().apply {
value = false
}
val isShowDialogLoading = MediatorLiveData<Boolean>().apply {
value = false
addSource(isLoading) {
value = it && isShowLoading.value == true
}
addSource(isShowLoading) {
value = isLoading.value == true && it
}
}
open suspend fun onError(throwable: Throwable) {
withContext(Dispatchers.Main) {
hideLoading()
}
}
open fun showError(e: Throwable) {
error.value = e.message
}
fun showLoading() {
isLoading.value = true
}
fun hideLoading() {
isLoading.value = false
}
fun showDialogLoading(isShow: Boolean) {
showLoading()
isShowLoading.value = isShow
}
fun hideDialogLoading(isShow: Boolean) {
hideLoading()
isShowLoading.value = isShow
}
fun handleError(result: UseCaseResult.DataError<*>) {
error.value = result.data?.error?.errorDescription
error.value = null
}
suspend inline fun <reified T : Any> callAPI(
noinline result: suspend () -> UseCaseResult<T>,
isShowDialogLoading: Boolean = true,
crossinline handleSuccess: (T) -> Unit = {}
): T? {
return coroutineScope {
var data: T? = null
try {
showDialogLoading(isShowDialogLoading)
when (val response = result.invoke()) {
is UseCaseResult.Success<*> -> {
data = response.data as T
handleSuccess(data)
}
is UseCaseResult.DataError<*> -> {
handleError(response)
data = null
}
}
hideDialogLoading(isShowDialogLoading)
} catch (e: Exception) {
e.printStackTrace()
onError(e)
}
data
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment