-
Notifications
You must be signed in to change notification settings - Fork 14
ViewModel Scope #35
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
ViewModel Scope #35
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,11 +4,11 @@ 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 | ||
import javax.inject.Inject | ||
import kotlinx.coroutines.launch | ||
|
||
class LoginViewModel @Inject constructor( | ||
private val loginUseCase: LoginUseCase, | ||
|
@@ -28,19 +28,13 @@ class LoginViewModel @Inject constructor( | |
} | ||
|
||
fun onLoginClick() { | ||
uiScope.launch { | ||
val username = username.value ?: return@launch | ||
val password = password.value ?: return@launch | ||
|
||
_loginInProgress.value = true | ||
|
||
val loginResult = onBackgroundThread { | ||
loginUseCase.run(LoginUseCase.Params(username, password)) | ||
} | ||
|
||
loginResult.either(::handleFailure, ::navigateHome) | ||
_loginInProgress.value = true | ||
|
||
val username = username.value ?: return | ||
val password = password.value ?: return | ||
Comment on lines
+31
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. line 31 should be below line 33 & 34 since one of them could return from the function and _loginInProgress.value would hang with true |
||
loginUseCase.invoke(viewModelScope, LoginUseCase.Params(username, password)) { | ||
_loginInProgress.value = false | ||
it.either(::handleFailure, ::navigateHome) | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -18,7 +19,6 @@ import com.adesso.movee.uimodel.MovieUiModel | |
import com.adesso.movee.uimodel.ShowHeaderUiModel | ||
import com.adesso.movee.uimodel.ShowUiModel | ||
import javax.inject.Inject | ||
import kotlinx.coroutines.launch | ||
|
||
class MovieViewModel @Inject constructor( | ||
private val fetchPopularMoviesUseCase: FetchPopularMoviesUseCase, | ||
|
@@ -49,12 +49,8 @@ class MovieViewModel @Inject constructor( | |
} | ||
|
||
private fun fetchNowPlayingMovies() { | ||
bgScope.launch { | ||
val nowPlayingMoviesResult = fetchNowPlayingMoviesUseCase.run(UseCase.None) | ||
|
||
onUIThread { | ||
nowPlayingMoviesResult.either(::handleFailure, ::postNowPlayingMovieList) | ||
} | ||
fetchNowPlayingMoviesUseCase.invoke(viewModelScope, UseCase.None) { | ||
it.either(::handleFailure, ::postNowPlayingMovieList) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. postNowPlayingMovieList() uses LiveData's setValue() function which must be called from main thread. Either we need to use postValue(), or switch context when calling postNowPlayingMovieList() |
||
} | ||
} | ||
|
||
|
@@ -63,12 +59,8 @@ class MovieViewModel @Inject constructor( | |
} | ||
|
||
private fun fetchPopularMovies() { | ||
bgScope.launch { | ||
val popularMoviesResult = fetchPopularMoviesUseCase.run(UseCase.None) | ||
|
||
onUIThread { | ||
popularMoviesResult.either(::handleFailure, ::postPopularMovieList) | ||
} | ||
fetchPopularMoviesUseCase.invoke(viewModelScope, UseCase.None) { | ||
it.either(::handleFailure, ::postPopularMovieList) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. postPopularMovieList() uses LiveData's setValue() function which must be called from main thread. Either we need to use postValue(), or switch context when calling postPopularMovieList() |
||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,13 +3,13 @@ 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 | ||
import com.adesso.movee.uimodel.MovieCreditUiModel | ||
import com.adesso.movee.uimodel.MovieDetailUiModel | ||
import javax.inject.Inject | ||
import kotlinx.coroutines.launch | ||
|
||
class MovieDetailViewModel @Inject constructor( | ||
private val fetchMovieDetailUseCase: FetchMovieDetailUseCase, | ||
|
@@ -24,13 +24,8 @@ class MovieDetailViewModel @Inject constructor( | |
|
||
fun fetchMovieDetails(id: Long) { | ||
if (_movieDetails.value == null) { | ||
bgScope.launch { | ||
val movieDetailResult = | ||
fetchMovieDetailUseCase.run(FetchMovieDetailUseCase.Params(id)) | ||
|
||
onUIThread { | ||
movieDetailResult.either(::handleFailure, ::postMovieDetail) | ||
} | ||
fetchMovieDetailUseCase.invoke(viewModelScope, FetchMovieDetailUseCase.Params(id)) { | ||
it.either(::handleFailure, ::postMovieDetail) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. postMovieDetail() uses LiveData's setValue() function which must be called from main thread. Either we need to use postValue(), or switch context when calling postMovieDetail() |
||
} | ||
} | ||
} | ||
|
@@ -41,13 +36,8 @@ class MovieDetailViewModel @Inject constructor( | |
|
||
fun fetchMovieCredits(id: Long) { | ||
if (_movieCredits.value == null) { | ||
bgScope.launch { | ||
val movieCreditsResult = | ||
fetchMovieCreditsUseCase.run(FetchMovieCreditsUseCase.Params(id)) | ||
|
||
onUIThread { | ||
movieCreditsResult.either(::handleFailure, ::postMovieCredits) | ||
} | ||
fetchMovieCreditsUseCase.invoke(viewModelScope, FetchMovieCreditsUseCase.Params(id)) { | ||
it.either(::handleFailure, ::postMovieCredits) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. postMovieCredits() uses LiveData's setValue() function which must be called from main thread. Either we need to use postValue(), or switch context when calling postMovieCredits() |
||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -11,7 +12,6 @@ import com.adesso.movee.internal.util.AppBarStateChangeListener.State.EXPANDED | |
import com.adesso.movee.internal.util.AppBarStateChangeListener.State.IDLE | ||
import com.adesso.movee.uimodel.PersonDetailUiModel | ||
import javax.inject.Inject | ||
import kotlinx.coroutines.launch | ||
|
||
class PersonDetailViewModel @Inject constructor( | ||
private val fetchPersonDetailsUseCase: FetchPersonDetailsUseCase, | ||
|
@@ -25,13 +25,11 @@ class PersonDetailViewModel @Inject constructor( | |
|
||
fun fetchPersonDetails(personId: Long) { | ||
if (_personDetails.value == null) { | ||
bgScope.launch { | ||
val personDetailResult = | ||
fetchPersonDetailsUseCase.run(FetchPersonDetailsUseCase.Params(personId)) | ||
|
||
onUIThread { | ||
personDetailResult.either(::handleFailure, ::postPersonDetails) | ||
} | ||
fetchPersonDetailsUseCase.invoke( | ||
viewModelScope, | ||
FetchPersonDetailsUseCase.Params(personId) | ||
) { | ||
it.either(::handleFailure, ::postPersonDetails) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. postPersonDetails() uses LiveData's setValue() function which must be called from main thread. Either we need to use postValue(), or switch context when calling postPersonDetails() |
||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,14 +4,14 @@ 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 | ||
import com.adesso.movee.internal.util.UseCase | ||
import com.adesso.movee.uimodel.LoginState | ||
import com.adesso.movee.uimodel.UserDetailUiModel | ||
import javax.inject.Inject | ||
import kotlinx.coroutines.launch | ||
|
||
class ProfileViewModel @Inject constructor( | ||
private val fetchUserDetailsUseCase: FetchUserDetailsUseCase, | ||
|
@@ -32,12 +32,8 @@ class ProfileViewModel @Inject constructor( | |
} | ||
|
||
private fun getLoginState() { | ||
bgScope.launch { | ||
val loginStateResult = getLoginStateUseCase.run(UseCase.None) | ||
|
||
onUIThread { | ||
loginStateResult.either(::handleFailure, ::handleLoginStateSuccess) | ||
} | ||
getLoginStateUseCase.invoke(viewModelScope, UseCase.None) { | ||
it.either(::handleFailure, ::handleLoginStateSuccess) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. handleLoginStateSuccess() calls postLoginState() inside. postLoginState() uses LiveData's setValue() function which must be called from main thread. Either we need to use postValue(), or switch context when calling postLoginState(). Also, handleLoginStateSuccess() calls updateUserDetails() which is a network operation and switches context with Dispatchers.IO. Using postValue() at postLoginState() would better suit here. |
||
} | ||
} | ||
|
||
|
@@ -58,12 +54,8 @@ class ProfileViewModel @Inject constructor( | |
} | ||
|
||
private fun fetchUserDetails() { | ||
bgScope.launch { | ||
val userDetailsResult = fetchUserDetailsUseCase.run(UseCase.None) | ||
|
||
onUIThread { | ||
userDetailsResult.either(::handleFailure, ::postUserDetails) | ||
} | ||
fetchUserDetailsUseCase.invoke(viewModelScope, UseCase.None) { | ||
it.either(::handleFailure, ::postUserDetails) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. postUserDetails() uses LiveData's setValue() function which must be called from main thread. Either we need to use postValue(), or switch context when calling postUserDetails() |
||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -13,7 +14,6 @@ import com.adesso.movee.uimodel.TvShowMultiSearchUiModel | |
import javax.inject.Inject | ||
import kotlinx.coroutines.CancellationException | ||
import kotlinx.coroutines.Job | ||
import kotlinx.coroutines.launch | ||
|
||
class SearchViewModel @Inject constructor( | ||
private val multiSearchUseCase: MultiSearchUseCase, | ||
|
@@ -31,11 +31,12 @@ class SearchViewModel @Inject constructor( | |
val query = text?.trim() ?: return | ||
if (query.length > MIN_SEARCHABLE_LENGTH) { | ||
multiSearchJob?.cancel() | ||
multiSearchJob = bgScope.launch { | ||
val searchResult = multiSearchUseCase.run(MultiSearchUseCase.Params(query)) | ||
onUIThread { | ||
searchResult.either(::handleSearchFailure, ::postMultiSearchResult) | ||
} | ||
|
||
multiSearchUseCase.invoke( | ||
viewModelScope, | ||
MultiSearchUseCase.Params(query) | ||
) { | ||
it.either(::handleSearchFailure, ::postMultiSearchResult) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. postMultiSearchResult() uses LiveData's setValue() functions which must be called from main thread. Either we need to use postValue() on both LiveDatas we wan't their values to change, or switch context when calling postMultiSearchResult() |
||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -17,7 +18,6 @@ import com.adesso.movee.uimodel.ShowHeaderUiModel | |
import com.adesso.movee.uimodel.ShowUiModel | ||
import com.adesso.movee.uimodel.TvShowUiModel | ||
import javax.inject.Inject | ||
import kotlinx.coroutines.launch | ||
|
||
class TvShowViewModel @Inject constructor( | ||
private val fetchTopRatedTvShowsUseCase: FetchTopRatedTvShowsUseCase, | ||
|
@@ -48,12 +48,8 @@ class TvShowViewModel @Inject constructor( | |
} | ||
|
||
private fun fetchTopRatedTvShows() { | ||
bgScope.launch { | ||
val topRatedTvShowsResult = fetchTopRatedTvShowsUseCase.run(UseCase.None) | ||
|
||
onUIThread { | ||
topRatedTvShowsResult.either(::handleFailure, ::postTopRatedTvShows) | ||
} | ||
fetchTopRatedTvShowsUseCase.invoke(viewModelScope, UseCase.None) { | ||
it.either(::handleFailure, ::postTopRatedTvShows) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. postTopRatedTvShows() uses LiveData's setValue() function which must be called from main thread. Either we need to use postValue(), or switch context when calling postTopRatedTvShows() |
||
} | ||
} | ||
|
||
|
@@ -62,12 +58,8 @@ class TvShowViewModel @Inject constructor( | |
} | ||
|
||
private fun fetchNowPlayingTvShows() { | ||
bgScope.launch { | ||
val nowPlayingTvShowsResult = fetchNowPlayingTvShowsUseCase.run(UseCase.None) | ||
|
||
onUIThread { | ||
nowPlayingTvShowsResult.either(::handleFailure, ::postNowPlayingTvShows) | ||
} | ||
fetchNowPlayingTvShowsUseCase.invoke(viewModelScope, UseCase.None) { | ||
it.either(::handleFailure, ::postNowPlayingTvShows) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. postNowPlayingTvShows() uses LiveData's setValue() function which must be called from main thread. Either we need to use postValue(), or switch context when calling postNowPlayingTvShows() |
||
} | ||
} | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to use async{} here? Wouldn't
suffice?