Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replacing CoroutineScopes with viewModelScope #58

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 8 additions & 21 deletions app/src/main/kotlin/com/adesso/movee/base/BaseAndroidViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.annotation.StringRes
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import androidx.navigation.NavDirections
import com.adesso.movee.R
import com.adesso.movee.internal.popup.PopUpType
Expand All @@ -15,11 +16,8 @@ import com.adesso.movee.internal.util.Event
import com.adesso.movee.internal.util.Failure
import com.adesso.movee.navigation.NavigationCommand
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.withContext

@Suppress("ConvertSecondaryConstructorToPrimary")
@SuppressLint("StaticFieldLeak")
abstract class BaseAndroidViewModel(application: Application) : AndroidViewModel(application) {

Expand All @@ -32,37 +30,37 @@ abstract class BaseAndroidViewModel(application: Application) : AndroidViewModel
private val _navigation = MutableLiveData<Event<NavigationCommand>>()
val navigation: LiveData<Event<NavigationCommand>> = _navigation

private val viewModelJob = SupervisorJob()

protected val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
protected val bgScope = CoroutineScope(Dispatchers.Default + viewModelJob)

protected open fun handleFailure(failure: Failure) {
val (title, message) = when (failure) {
is Failure.NoConnectivityError -> Pair(
"",
getString(R.string.common_error_network_connection)
)

is Failure.UnknownHostError -> Pair("", getString(R.string.common_error_unknown_host))
is Failure.ServerError -> Pair("", failure.message)
is Failure.JsonError, is Failure.EmptyResponse -> Pair(
"",
getString(R.string.common_error_invalid_response)
)

is Failure.FormValidationError -> Pair(
getString(R.string.common_title_popup_form_validation),
failure.message
?: getString(R.string.common_error_invalid_form)
)

is Failure.IoError -> Pair("", getString(R.string.common_error_can_not_save_data))
is Failure.UnknownError -> Pair(
"",
failure.exception.localizedMessage ?: getString(R.string.common_error_unknown)
)

is Failure.HttpError -> Pair(
"",
getString(R.string.common_error_http, failure.code.toString())
)

is Failure.TimeOutError -> Pair("", getString(R.string.common_error_timeout))
else -> Pair("", failure.message ?: failure.toString())
}
Expand Down Expand Up @@ -100,14 +98,8 @@ abstract class BaseAndroidViewModel(application: Application) : AndroidViewModel
_navigation.value = Event(NavigationCommand.Back)
}

protected suspend fun onUIThread(block: suspend CoroutineScope.() -> Unit) {
withContext(uiScope.coroutineContext) {
block.invoke(this)
}
}

protected suspend fun <T> onBackgroundThread(block: suspend CoroutineScope.() -> T): T {
return withContext(bgScope.coroutineContext) {
protected suspend fun <T> runOnViewModelScope(block: suspend CoroutineScope.() -> T): T {
return withContext(viewModelScope.coroutineContext) {
block.invoke(this)
}
}
Expand All @@ -119,9 +111,4 @@ abstract class BaseAndroidViewModel(application: Application) : AndroidViewModel
protected fun getString(@StringRes resId: Int, vararg formatArgs: Any): String {
return getApplication<Application>().getString(resId, formatArgs)
}

override fun onCleared() {
super.onCleared()
viewModelJob.cancel()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Application
import android.net.Uri
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.adesso.movee.base.BaseAndroidViewModel
import com.adesso.movee.domain.LoginUseCase
import com.adesso.movee.internal.util.Event
Expand All @@ -30,13 +31,13 @@ class LoginViewModel @Inject constructor(
}

fun onLoginClick() {
uiScope.launch {
viewModelScope.launch {
val username = username.value ?: return@launch
val password = password.value ?: return@launch

_loginInProgress.value = true

val loginResult = onBackgroundThread {
val loginResult = runOnViewModelScope {
Mrtckr008 marked this conversation as resolved.
Show resolved Hide resolved
loginUseCase.run(LoginUseCase.Params(username, password))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Application
import androidx.annotation.StringRes
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.adesso.movee.R
import com.adesso.movee.base.BaseAndroidViewModel
import com.adesso.movee.domain.FetchNowPlayingMoviesUseCase
Expand Down Expand Up @@ -51,10 +52,10 @@ class MovieViewModel @Inject constructor(
}

private fun fetchNowPlayingMovies() {
bgScope.launch {
viewModelScope.launch {
val nowPlayingMoviesResult = fetchNowPlayingMoviesUseCase.run(UseCase.None)

onUIThread {
runOnViewModelScope {
nowPlayingMoviesResult
.onSuccess(::postNowPlayingMovieList)
.onFailure(::handleFailure)
Expand All @@ -67,10 +68,10 @@ class MovieViewModel @Inject constructor(
}

private fun fetchPopularMovies() {
bgScope.launch {
viewModelScope.launch {
val popularMoviesResult = fetchPopularMoviesUseCase.run(UseCase.None)

onUIThread {
runOnViewModelScope {
popularMoviesResult
.onSuccess(::postPopularMovieList)
.onFailure(::handleFailure)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.adesso.movee.scene.moviedetail
import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.adesso.movee.base.BaseAndroidViewModel
import com.adesso.movee.domain.FetchMovieCreditsUseCase
import com.adesso.movee.domain.FetchMovieDetailUseCase
Expand All @@ -27,11 +28,11 @@ class MovieDetailViewModel @Inject constructor(

fun fetchMovieDetails(id: Long) {
if (_movieDetails.value == null) {
bgScope.launch {
viewModelScope.launch {
val movieDetailResult =
fetchMovieDetailUseCase.run(FetchMovieDetailUseCase.Params(id))

onUIThread {
runOnViewModelScope {
movieDetailResult
.onSuccess(::postMovieDetail)
.onFailure(::handleFailure)
Expand All @@ -46,11 +47,11 @@ class MovieDetailViewModel @Inject constructor(

fun fetchMovieCredits(id: Long) {
if (_movieCredits.value == null) {
bgScope.launch {
viewModelScope.launch {
val movieCreditsResult =
fetchMovieCreditsUseCase.run(FetchMovieCreditsUseCase.Params(id))

onUIThread {
runOnViewModelScope {
movieCreditsResult
.onSuccess(::postMovieCredits)
.onFailure(::handleFailure)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.adesso.movee.scene.persondetail
import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.adesso.movee.base.BaseAndroidViewModel
import com.adesso.movee.domain.FetchPersonDetailsUseCase
import com.adesso.movee.internal.util.AppBarStateChangeListener
Expand All @@ -27,11 +28,11 @@ class PersonDetailViewModel @Inject constructor(

fun fetchPersonDetails(personId: Long) {
if (_personDetails.value == null) {
bgScope.launch {
viewModelScope.launch {
val personDetailResult =
fetchPersonDetailsUseCase.run(FetchPersonDetailsUseCase.Params(personId))

onUIThread {
runOnViewModelScope {
personDetailResult
.onSuccess(::postPersonDetails)
.onFailure(::handleFailure)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.viewModelScope
import com.adesso.movee.base.BaseAndroidViewModel
import com.adesso.movee.domain.FetchUserDetailsUseCase
import com.adesso.movee.domain.GetLoginStateUseCase
Expand Down Expand Up @@ -34,10 +35,10 @@ class ProfileViewModel @Inject constructor(
}

private fun getLoginState() {
bgScope.launch {
viewModelScope.launch {
val loginStateResult = getLoginStateUseCase.run(UseCase.None)

onUIThread {
runOnViewModelScope {
loginStateResult
.onSuccess(::handleLoginStateSuccess)
.onFailure(::handleFailure)
Expand All @@ -62,10 +63,10 @@ class ProfileViewModel @Inject constructor(
}

private fun fetchUserDetails() {
bgScope.launch {
viewModelScope.launch {
val userDetailsResult = fetchUserDetailsUseCase.run(UseCase.None)

onUIThread {
runOnViewModelScope {
userDetailsResult
.onSuccess(::postUserDetails)
.onFailure(::handleFailure)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.adesso.movee.scene.search
import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.adesso.movee.base.BaseAndroidViewModel
import com.adesso.movee.domain.MultiSearchUseCase
import com.adesso.movee.internal.util.Failure
Expand Down Expand Up @@ -33,9 +34,9 @@ class SearchViewModel @Inject constructor(
val query = text?.trim() ?: return
if (query.length > MIN_SEARCHABLE_LENGTH) {
multiSearchJob?.cancel()
multiSearchJob = bgScope.launch {
multiSearchJob = viewModelScope.launch {
val searchResult = multiSearchUseCase.run(MultiSearchUseCase.Params(query))
onUIThread {
runOnViewModelScope {
searchResult
.onSuccess(::postMultiSearchResult)
.onFailure(::handleFailure)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.adesso.movee.scene.tvshow
import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.adesso.movee.R
import com.adesso.movee.base.BaseAndroidViewModel
import com.adesso.movee.domain.FetchNowPlayingTvShowsUseCase
Expand Down Expand Up @@ -50,10 +51,10 @@ class TvShowViewModel @Inject constructor(
}

private fun fetchTopRatedTvShows() {
bgScope.launch {
viewModelScope.launch {
val topRatedTvShowsResult = fetchTopRatedTvShowsUseCase.run(UseCase.None)

onUIThread {
runOnViewModelScope {
topRatedTvShowsResult
.onSuccess(::postTopRatedTvShows)
.onFailure(::handleFailure)
Expand All @@ -66,10 +67,10 @@ class TvShowViewModel @Inject constructor(
}

private fun fetchNowPlayingTvShows() {
bgScope.launch {
viewModelScope.launch {
val nowPlayingTvShowsResult = fetchNowPlayingTvShowsUseCase.run(UseCase.None)

onUIThread {
runOnViewModelScope {
nowPlayingTvShowsResult
.onSuccess(::postNowPlayingTvShows)
.onFailure(::handleFailure)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.viewModelScope
import com.adesso.movee.base.BaseAndroidViewModel
import com.adesso.movee.domain.FetchTvShowCreditsUseCase
import com.adesso.movee.domain.FetchTvShowDetailUseCase
Expand Down Expand Up @@ -31,11 +32,11 @@ class TvShowDetailViewModel @Inject constructor(

fun fetchTvShowDetail(id: Long) {
if (_tvShowDetails.value == null) {
bgScope.launch {
viewModelScope.launch {
val tvShowDetailResult =
fetchTvShowDetailUseCase.run(FetchTvShowDetailUseCase.Params(id))

onUIThread {
runOnViewModelScope {
tvShowDetailResult
.onSuccess(::postTvShowDetail)
.onFailure(::handleFailure)
Expand All @@ -50,11 +51,11 @@ class TvShowDetailViewModel @Inject constructor(

fun fetchTvShowCredits(id: Long) {
if (_tvShowCredits.value == null) {
bgScope.launch {
viewModelScope.launch {
val tvShowCreditResult =
fetchTvShowCreditsUseCase.run(FetchTvShowCreditsUseCase.Params(id))

onUIThread {
runOnViewModelScope {
tvShowCreditResult
.onSuccess(::postTvShowCredits)
.onFailure(::handleFailure)
Expand Down