Skip to content

Commit

Permalink
feat: migrate to Room-RxJava3 and dump RxBridge
Browse files Browse the repository at this point in the history
  • Loading branch information
RivuChk committed Nov 19, 2020
1 parent 1700fe6 commit 0de2a42
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 129 deletions.
7 changes: 3 additions & 4 deletions README.md
Expand Up @@ -12,11 +12,10 @@ The goal of this project is to have a demo application using popular MVI Arch pa
- Lottie for Splash Animation
- Dagger HILT for DI (Migrated from Koin in this commit: [21a9db64bee1359bd57cf99ba757467da63f10b2](https://github.com/RivuChk/Jetpack-Compose-MVI-Demo/commit/21a9db64bee1359bd57cf99ba757467da63f10b2))
- RxJava 3 for Streams
- Room for DB (With RxJava 2)
- RxBridge, to convert Rx2 Streams (from Room) to Rx3
- Room for DB (With RxJava 3)
- Mockito for mocking
- LiveData for emiting states from ViewModel
- `LazyColumnItems` from Compose for showing List
- LiveData for emitting states from ViewModel
- `LazyColumnFor` from Compose for showing List
- *Glide* for image loading with Composable `Image`
- Composable `ConstraintLayout`
- Composable `TopAppBar`
Expand Down
8 changes: 3 additions & 5 deletions app/build.gradle
Expand Up @@ -103,7 +103,7 @@ dependencies {

implementation "androidx.compose.runtime:runtime:$compose_version"
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
implementation "androidx.compose.runtime:runtime-rxjava2:$compose_version"
implementation "androidx.compose.runtime:runtime-rxjava3:$compose_version"
implementation "androidx.compose.compiler:compiler:$compose_version"
implementation "androidx.compose.foundation:foundation:$compose_version"
implementation "androidx.compose.ui:ui:$compose_version"
Expand Down Expand Up @@ -161,12 +161,10 @@ dependencies {
androidTestImplementation("androidx.ui:ui-test:$compose_version")

//Room DB
def room_version = "2.3.0-alpha01"
def room_version = "2.3.0-alpha03"

implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
implementation "androidx.room:room-rxjava2:$room_version"
implementation "androidx.room:room-rxjava3:$room_version"
kapt "androidx.room:room-compiler:$room_version"
//RxJava3 Bridge Required as Room doesn't support RxJava3 yet
implementation "com.github.akarnokd:rxjava3-bridge:3.0.0"
}
@@ -1,6 +1,6 @@
package dev.rivu.mvijetpackcomposedemo.moviesearch.data

import androidx.room.EmptyResultSetException
import androidx.room.rxjava3.EmptyResultSetException
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.model.Movie
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.model.MovieDetail
import io.reactivex.rxjava3.core.Completable
Expand Down
@@ -1,149 +1,138 @@
package dev.rivu.mvijetpackcomposedemo.moviesearch.data.local

import androidx.room.EmptyResultSetException
import androidx.room.rxjava3.EmptyResultSetException
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.MovieDataStore
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.local.database.MovieDao
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.local.database.MovieEnitity
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.model.Movie
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.model.MovieDetail
import hu.akarnokd.rxjava3.bridge.RxJavaBridge
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Single

class LocalMovieDataStore(private val movieDao: MovieDao) : MovieDataStore {

override fun getMoviesStream(searchQuery: String): Flowable<List<Movie>> {
return RxJavaBridge.toV3Flowable(
movieDao.getMoviesStream(searchQuery)
.map { list ->
list.map {
Movie(
imdbID = it.imdbID,
poster = it.poster,
title = it.title,
type = it.type,
year = it.year
)
}
return movieDao.getMoviesStream(searchQuery)
.map { list ->
list.map {
Movie(
imdbID = it.imdbID,
poster = it.poster,
title = it.title,
type = it.type,
year = it.year
)
}
)
}
}

override fun getMovies(searchQuery: String): Single<List<Movie>> {
return RxJavaBridge.toV3Single(
movieDao.getMovies(searchQuery)
.map { list ->
list.map {
Movie(
imdbID = it.imdbID,
poster = it.poster,
title = it.title,
type = it.type,
year = it.year
)
}
}
)
}

override fun addMovies(movieList: List<Movie>): Completable {
return return RxJavaBridge.toV3Completable(
movieDao.addMovies(
movieList.map {
MovieEnitity(
return movieDao.getMovies(searchQuery)
.map { list ->
list.map {
Movie(
imdbID = it.imdbID,
poster = it.poster,
title = it.title,
type = it.type,
year = it.year
)
}
)
)
}
}

override fun getMovieDetail(imdbId: String): Single<MovieDetail> {
return RxJavaBridge.toV3Single(
movieDao.getMovie(imdbId)
.map {
if (it.detail == null) {
throw EmptyResultSetException("detail not present for this movie")
} else {
MovieDetail(
imdbID = it.imdbID,
poster = it.poster,
title = it.title,
type = it.type,
year = it.year,

response = it.detail.response,
actors = it.detail.actors,
awards = it.detail.awards,
boxOffice = it.detail.boxOffice,
country = it.detail.country,
dVD = it.detail.dVD,
director = it.detail.director,
genre = it.detail.genre,
imdbRating = it.detail.imdbRating,
imdbVotes = it.detail.imdbVotes,
language = it.detail.language,
metascore = it.detail.metascore,
plot = it.detail.plot,
production = it.detail.production,
rated = it.detail.rated,
ratings = it.detail.ratings.map {
MovieDetail.Rating(
source = it.source,
value = it.value
)
},
released = it.detail.released,
runtime = it.detail.runtime,
website = it.detail.website,
writer = it.detail.writer
)
}
}
override fun addMovies(movieList: List<Movie>): Completable {
return movieDao.addMovies(
movieList.map {
MovieEnitity(
imdbID = it.imdbID,
poster = it.poster,
title = it.title,
type = it.type,
year = it.year
)
}
)
}

override fun addMovieDetail(movie: MovieDetail): Completable {
return RxJavaBridge.toV3Completable(
movieDao.updateMovieInDB(
MovieEnitity(
imdbID = movie.imdbID,
poster = movie.poster,
title = movie.title,
type = movie.type,
year = movie.year,
detail = MovieEnitity.Detail(
response = movie.response,
actors = movie.actors,
awards = movie.awards,
boxOffice = movie.boxOffice,
country = movie.country,
dVD = movie.dVD,
director = movie.director,
genre = movie.genre,
imdbRating = movie.imdbRating,
imdbVotes = movie.imdbVotes,
language = movie.language,
metascore = movie.metascore,
plot = movie.plot,
production = movie.production,
rated = movie.rated,
ratings = movie.ratings.map {
MovieEnitity.Detail.Rating(
override fun getMovieDetail(imdbId: String): Single<MovieDetail> {
return movieDao.getMovie(imdbId)
.map {
if (it.detail == null) {
throw EmptyResultSetException("detail not present for this movie")
} else {
MovieDetail(
imdbID = it.imdbID,
poster = it.poster,
title = it.title,
type = it.type,
year = it.year,

response = it.detail.response,
actors = it.detail.actors,
awards = it.detail.awards,
boxOffice = it.detail.boxOffice,
country = it.detail.country,
dVD = it.detail.dVD,
director = it.detail.director,
genre = it.detail.genre,
imdbRating = it.detail.imdbRating,
imdbVotes = it.detail.imdbVotes,
language = it.detail.language,
metascore = it.detail.metascore,
plot = it.detail.plot,
production = it.detail.production,
rated = it.detail.rated,
ratings = it.detail.ratings.map {
MovieDetail.Rating(
source = it.source,
value = it.value
)
},
released = movie.released,
runtime = movie.runtime,
website = movie.website,
writer = movie.writer
released = it.detail.released,
runtime = it.detail.runtime,
website = it.detail.website,
writer = it.detail.writer
)
}
}
}

override fun addMovieDetail(movie: MovieDetail): Completable {
return movieDao.updateMovieInDB(
MovieEnitity(
imdbID = movie.imdbID,
poster = movie.poster,
title = movie.title,
type = movie.type,
year = movie.year,
detail = MovieEnitity.Detail(
response = movie.response,
actors = movie.actors,
awards = movie.awards,
boxOffice = movie.boxOffice,
country = movie.country,
dVD = movie.dVD,
director = movie.director,
genre = movie.genre,
imdbRating = movie.imdbRating,
imdbVotes = movie.imdbVotes,
language = movie.language,
metascore = movie.metascore,
plot = movie.plot,
production = movie.production,
rated = movie.rated,
ratings = movie.ratings.map {
MovieEnitity.Detail.Rating(
source = it.source,
value = it.value
)
},
released = movie.released,
runtime = movie.runtime,
website = movie.website,
writer = movie.writer
)
)
)
Expand Down
@@ -1,9 +1,9 @@
package dev.rivu.mvijetpackcomposedemo.moviesearch.data.local.database

import androidx.room.*
import io.reactivex.Completable
import io.reactivex.Flowable
import io.reactivex.Single
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Single

@Dao
interface MovieDao {
Expand Down
@@ -1,4 +1,4 @@
import androidx.room.EmptyResultSetException
import androidx.room.rxjava3.EmptyResultSetException
import com.nhaarman.mockitokotlin2.*
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.MovieDataStore
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.MovieRepository
Expand Down
@@ -1,4 +1,4 @@
import androidx.room.EmptyResultSetException
import androidx.room.rxjava3.EmptyResultSetException
import com.nhaarman.mockitokotlin2.atLeastOnce
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
Expand All @@ -12,9 +12,9 @@ import dev.rivu.mvijetpackcomposedemo.moviesearch.data.local.database.MovieDao
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.local.database.MovieEnitity
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.model.Movie
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.model.MovieDetail
import io.reactivex.Completable
import io.reactivex.Flowable
import io.reactivex.Single
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Single
import org.mockito.ArgumentMatchers.anyList
import org.mockito.ArgumentMatchers.anyString
import org.spekframework.spek2.Spek
Expand Down

0 comments on commit 0de2a42

Please sign in to comment.