From f09a43cfaad02aa5bbfb8e0f859a5e821b098833 Mon Sep 17 00:00:00 2001 From: GeorgCantor Date: Thu, 17 Sep 2020 20:36:44 +0300 Subject: [PATCH 1/7] Added inserting movies to favorites --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 10 ++--- .../topcorn/data/local/AppDatabase.kt | 2 +- .../topcorn/data/local/FavoriteMovie.kt | 34 ++++++++++++++++ .../topcorn/data/local/daos/MoviesDao.kt | 11 +++++ .../data/repositories/movies/MoviesRepo.kt | 11 +++++ .../di/modules/ActivitiesBuilderModule.kt | 4 ++ .../topcorn/di/modules/ViewModelModule.kt | 6 +++ .../activities/favorites/FavoritesActivity.kt | 30 ++++++++++++++ .../favorites/FavoritesViewModel.kt | 22 ++++++++++ .../ui/activities/feed/FeedActivity.kt | 12 +++--- .../ui/activities/movie/MovieViewModel.kt | 27 ++++++++++++- .../topcorn/ui/adapters/FavoritesAdapter.kt | 38 ++++++++++++++++++ .../main/res/layout/activity_favorites.xml | 21 ++++++++++ app/src/main/res/layout/activity_movie.xml | 13 ++++++ app/src/main/res/layout/item_favorite.xml | 40 +++++++++++++++++++ build.gradle | 2 +- 17 files changed, 269 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/com/theapache64/topcorn/data/local/FavoriteMovie.kt create mode 100644 app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt create mode 100644 app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesViewModel.kt create mode 100644 app/src/main/java/com/theapache64/topcorn/ui/adapters/FavoritesAdapter.kt create mode 100644 app/src/main/res/layout/activity_favorites.xml create mode 100644 app/src/main/res/layout/item_favorite.xml diff --git a/app/build.gradle b/app/build.gradle index 3207070..d13da5f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -99,6 +99,7 @@ dependencies { // Moshi implementation 'com.squareup.moshi:moshi:1.9.2' + implementation 'com.github.bumptech.glide:glide:4.11.0' // MaterialColors implementation 'com.theah64.materialcolors:materialcolors:1.0.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cdc23fb..7acded4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,7 +16,7 @@ android:usesCleartextTraffic="true" tools:ignore="GoogleAppIndexingWarning" tools:targetApi="m"> - + - - - + - - + android:theme="@style/AppTheme.NoActionBar" /> diff --git a/app/src/main/java/com/theapache64/topcorn/data/local/AppDatabase.kt b/app/src/main/java/com/theapache64/topcorn/data/local/AppDatabase.kt index 171a2e3..d513eb8 100644 --- a/app/src/main/java/com/theapache64/topcorn/data/local/AppDatabase.kt +++ b/app/src/main/java/com/theapache64/topcorn/data/local/AppDatabase.kt @@ -6,7 +6,7 @@ import androidx.room.TypeConverters import com.theapache64.topcorn.data.local.daos.MoviesDao import com.theapache64.topcorn.data.remote.Movie -@Database(entities = [Movie::class], version = 1) +@Database(entities = [Movie::class, FavoriteMovie::class], version = 1) @TypeConverters(Converters::class) abstract class AppDatabase : RoomDatabase() { abstract fun movieDao(): MoviesDao diff --git a/app/src/main/java/com/theapache64/topcorn/data/local/FavoriteMovie.kt b/app/src/main/java/com/theapache64/topcorn/data/local/FavoriteMovie.kt new file mode 100644 index 0000000..bd07bd5 --- /dev/null +++ b/app/src/main/java/com/theapache64/topcorn/data/local/FavoriteMovie.kt @@ -0,0 +1,34 @@ +package com.theapache64.topcorn.data.local + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import com.squareup.moshi.Json + +@Entity(tableName = "favorites") +data class FavoriteMovie( + @Json(name = "actors") + val actors: List?, + @Json(name = "desc") + val desc: String?, + @Json(name = "directors") + val directors: List?, + @Json(name = "genre") + val genre: List?, + @Json(name = "image_url") + val imageUrl: String?, + @Json(name = "thumb_url") + val thumbUrl: String?, + @Json(name = "imdb_url") + val imdbUrl: String?, + @Json(name = "name") + val name: String?, + @Json(name = "rating") + val rating: Float?, + @Json(name = "year") + val year: Int? +) { + @PrimaryKey(autoGenerate = true) + @ColumnInfo(name = "id") + var id: Long = 0 +} \ No newline at end of file diff --git a/app/src/main/java/com/theapache64/topcorn/data/local/daos/MoviesDao.kt b/app/src/main/java/com/theapache64/topcorn/data/local/daos/MoviesDao.kt index 988b7cc..323a2c7 100644 --- a/app/src/main/java/com/theapache64/topcorn/data/local/daos/MoviesDao.kt +++ b/app/src/main/java/com/theapache64/topcorn/data/local/daos/MoviesDao.kt @@ -2,7 +2,9 @@ package com.theapache64.topcorn.data.local.daos import androidx.room.Dao import androidx.room.Insert +import androidx.room.OnConflictStrategy import androidx.room.Query +import com.theapache64.topcorn.data.local.FavoriteMovie import com.theapache64.topcorn.data.remote.Movie import kotlinx.coroutines.flow.Flow @@ -16,4 +18,13 @@ interface MoviesDao { @Insert fun addAll(data: List) + + @Query("SELECT * FROM favorites") + suspend fun getAllFavoriteMovies(): List + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insert(favoriteMovie: FavoriteMovie) + + @Query("DELETE FROM favorites WHERE id = :id") + fun deleteById(id: Long) } diff --git a/app/src/main/java/com/theapache64/topcorn/data/repositories/movies/MoviesRepo.kt b/app/src/main/java/com/theapache64/topcorn/data/repositories/movies/MoviesRepo.kt index 5d3a198..f0ed794 100644 --- a/app/src/main/java/com/theapache64/topcorn/data/repositories/movies/MoviesRepo.kt +++ b/app/src/main/java/com/theapache64/topcorn/data/repositories/movies/MoviesRepo.kt @@ -2,6 +2,7 @@ package com.theapache64.topcorn.data.repositories.movies import android.content.SharedPreferences import androidx.core.content.edit +import com.theapache64.topcorn.data.local.FavoriteMovie import com.theapache64.topcorn.data.local.daos.MoviesDao import com.theapache64.topcorn.data.remote.ApiInterface import com.theapache64.topcorn.data.remote.Movie @@ -10,6 +11,8 @@ import com.theapache64.topcorn.utils.test.OpenForTesting import com.theapache64.twinkill.network.utils.Resource import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.async +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOn import javax.inject.Inject @@ -61,6 +64,14 @@ class MoviesRepo @Inject constructor( }.asFlow().flowOn(Dispatchers.IO) } + suspend fun getAllFavoriteMovies() = moviesDao.getAllFavoriteMovies() + + suspend fun insertToFavoritesAsync(favoriteMovie: FavoriteMovie) = coroutineScope { + async { + moviesDao.insert(favoriteMovie) + } + } + @ExperimentalTime private fun isExpired(lastSynced: Long): Boolean { val currentTime = System.currentTimeMillis() diff --git a/app/src/main/java/com/theapache64/topcorn/di/modules/ActivitiesBuilderModule.kt b/app/src/main/java/com/theapache64/topcorn/di/modules/ActivitiesBuilderModule.kt index 214d074..a3c4f67 100644 --- a/app/src/main/java/com/theapache64/topcorn/di/modules/ActivitiesBuilderModule.kt +++ b/app/src/main/java/com/theapache64/topcorn/di/modules/ActivitiesBuilderModule.kt @@ -1,6 +1,7 @@ package com.theapache64.topcorn.di.modules +import com.theapache64.topcorn.ui.activities.favorites.FavoritesActivity import com.theapache64.topcorn.ui.activities.feed.FeedActivity import com.theapache64.topcorn.ui.activities.movie.MovieActivity import com.theapache64.topcorn.ui.activities.splash.SplashActivity @@ -22,4 +23,7 @@ abstract class ActivitiesBuilderModule { @ContributesAndroidInjector abstract fun getMovieActivity(): MovieActivity + @ContributesAndroidInjector + abstract fun getFavoritesActivity(): FavoritesActivity + } \ No newline at end of file diff --git a/app/src/main/java/com/theapache64/topcorn/di/modules/ViewModelModule.kt b/app/src/main/java/com/theapache64/topcorn/di/modules/ViewModelModule.kt index 56d42dc..9e2160b 100644 --- a/app/src/main/java/com/theapache64/topcorn/di/modules/ViewModelModule.kt +++ b/app/src/main/java/com/theapache64/topcorn/di/modules/ViewModelModule.kt @@ -1,6 +1,7 @@ package com.theapache64.topcorn.di.modules import androidx.lifecycle.ViewModel +import com.theapache64.topcorn.ui.activities.favorites.FavoritesViewModel import com.theapache64.topcorn.ui.activities.feed.FeedViewModel import com.theapache64.topcorn.ui.activities.movie.MovieViewModel import com.theapache64.topcorn.ui.activities.splash.SplashViewModel @@ -33,4 +34,9 @@ abstract class ViewModelModule { @ViewModelKey(MovieViewModel::class) abstract fun bindMovieViewModel(viewModel: MovieViewModel): ViewModel + @Binds + @IntoMap + @ViewModelKey(FavoritesViewModel::class) + abstract fun bindFavoritesViewModel(viewModel: FavoritesViewModel): ViewModel + } \ No newline at end of file diff --git a/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt b/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt new file mode 100644 index 0000000..3dc0487 --- /dev/null +++ b/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt @@ -0,0 +1,30 @@ +package com.theapache64.topcorn.ui.activities.favorites + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProvider +import com.theapache64.topcorn.R +import com.theapache64.topcorn.ui.adapters.FavoritesAdapter +import dagger.android.AndroidInjection +import kotlinx.android.synthetic.main.activity_favorites.* +import javax.inject.Inject + +class FavoritesActivity : AppCompatActivity() { + + @Inject + lateinit var factory: ViewModelProvider.Factory + private lateinit var viewModel: FavoritesViewModel + + override fun onCreate(savedInstanceState: Bundle?) { + AndroidInjection.inject(this) + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_favorites) + + viewModel = ViewModelProvider(this, factory).get(FavoritesViewModel::class.java) + + viewModel.favoritesMovies.observe(this, Observer { + favorites_recycler.adapter = FavoritesAdapter(it) + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesViewModel.kt b/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesViewModel.kt new file mode 100644 index 0000000..903268b --- /dev/null +++ b/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesViewModel.kt @@ -0,0 +1,22 @@ +package com.theapache64.topcorn.ui.activities.favorites + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.theapache64.topcorn.data.local.FavoriteMovie +import com.theapache64.topcorn.data.repositories.movies.MoviesRepo +import kotlinx.coroutines.launch +import javax.inject.Inject + +class FavoritesViewModel @Inject constructor( + private val moviesRepo: MoviesRepo +) : ViewModel() { + + val favoritesMovies = MutableLiveData>() + + init { + viewModelScope.launch { + favoritesMovies.postValue(moviesRepo.getAllFavoriteMovies()) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/theapache64/topcorn/ui/activities/feed/FeedActivity.kt b/app/src/main/java/com/theapache64/topcorn/ui/activities/feed/FeedActivity.kt index c4e3203..1258e37 100644 --- a/app/src/main/java/com/theapache64/topcorn/ui/activities/feed/FeedActivity.kt +++ b/app/src/main/java/com/theapache64/topcorn/ui/activities/feed/FeedActivity.kt @@ -15,6 +15,7 @@ import androidx.recyclerview.widget.RecyclerView import com.theapache64.topcorn.R import com.theapache64.topcorn.data.remote.Movie import com.theapache64.topcorn.databinding.ActivityFeedBinding +import com.theapache64.topcorn.ui.activities.favorites.FavoritesActivity import com.theapache64.topcorn.ui.activities.movie.MovieActivity import com.theapache64.topcorn.ui.adapters.FeedAdapter import com.theapache64.twinkill.logger.info @@ -96,11 +97,12 @@ class FeedActivity : BaseAppCompatActivity() { // Watching for github home viewModel.openGithub.observe(this, Observer { - val intent = Intent( - Intent.ACTION_VIEW, - Uri.parse(GITHUB_URL) - ) - startActivity(intent) + startActivity(Intent(this, FavoritesActivity::class.java)) +// val intent = Intent( +// Intent.ACTION_VIEW, +// Uri.parse(GITHUB_URL) +// ) +// startActivity(intent) }) // Watching for toast diff --git a/app/src/main/java/com/theapache64/topcorn/ui/activities/movie/MovieViewModel.kt b/app/src/main/java/com/theapache64/topcorn/ui/activities/movie/MovieViewModel.kt index 2dd3ee6..9024dee 100644 --- a/app/src/main/java/com/theapache64/topcorn/ui/activities/movie/MovieViewModel.kt +++ b/app/src/main/java/com/theapache64/topcorn/ui/activities/movie/MovieViewModel.kt @@ -1,11 +1,17 @@ package com.theapache64.topcorn.ui.activities.movie import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.theapache64.topcorn.data.local.FavoriteMovie import com.theapache64.topcorn.data.remote.Movie +import com.theapache64.topcorn.data.repositories.movies.MoviesRepo import com.theapache64.twinkill.utils.livedata.SingleLiveEvent +import kotlinx.coroutines.launch import javax.inject.Inject -class MovieViewModel @Inject constructor() : ViewModel() { +class MovieViewModel @Inject constructor( + private val moviesRepo: MoviesRepo +) : ViewModel() { fun init(movie: Movie) { this.movie = movie @@ -19,6 +25,25 @@ class MovieViewModel @Inject constructor() : ViewModel() { closeActivity.value = true } + fun onFavoriteButtonClicked() { + viewModelScope.launch { + moviesRepo.insertToFavoritesAsync( + FavoriteMovie( + movie?.actors, + movie?.desc, + movie?.directors, + movie?.genre, + movie?.imageUrl, + movie?.thumbUrl, + movie?.imdbUrl, + movie?.name, + movie?.rating, + movie?.year + ) + ) + } + } + fun onGoToImdbClicked() { openImdb.value = true } diff --git a/app/src/main/java/com/theapache64/topcorn/ui/adapters/FavoritesAdapter.kt b/app/src/main/java/com/theapache64/topcorn/ui/adapters/FavoritesAdapter.kt new file mode 100644 index 0000000..1795a72 --- /dev/null +++ b/app/src/main/java/com/theapache64/topcorn/ui/adapters/FavoritesAdapter.kt @@ -0,0 +1,38 @@ +package com.theapache64.topcorn.ui.adapters + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.theapache64.topcorn.R +import com.theapache64.topcorn.data.local.FavoriteMovie +import kotlinx.android.synthetic.main.item_favorite.view.* + +class FavoritesAdapter(private val favorites: List) : + RecyclerView.Adapter() { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = FavoritesViewHolder( + LayoutInflater.from(parent.context).inflate(R.layout.item_favorite, parent, false) + ) + + override fun onBindViewHolder(holder: FavoritesViewHolder, position: Int) { + val favorite = favorites[position] + with(holder) { + title.text = favorite.name + + Glide.with(itemView) + .load(favorite.imageUrl) + .into(poster) + } + } + + override fun getItemCount() = favorites.size + + class FavoritesViewHolder(view: View) : RecyclerView.ViewHolder(view) { + val title: TextView = view.tv_title + val poster: ImageView = view.iv_poster + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_favorites.xml b/app/src/main/res/layout/activity_favorites.xml new file mode 100644 index 0000000..b575ebe --- /dev/null +++ b/app/src/main/res/layout/activity_favorites.xml @@ -0,0 +1,21 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_movie.xml b/app/src/main/res/layout/activity_movie.xml index fbf3dfd..84914df 100644 --- a/app/src/main/res/layout/activity_movie.xml +++ b/app/src/main/res/layout/activity_movie.xml @@ -33,6 +33,19 @@ app:layout_constraintTop_toTopOf="parent" tools:ignore="ContentDescription" /> + + + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index b1e5652..b419e66 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.0.0-beta05' + classpath 'com.android.tools.build:gradle:4.0.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module app.build.gradle files From 436658088cd3cb5ececab13fff2593b6d2609c60 Mon Sep 17 00:00:00 2001 From: GeorgCantor Date: Thu, 17 Sep 2020 21:45:18 +0300 Subject: [PATCH 2/7] Added removing from favorites --- .../topcorn/data/local/daos/MoviesDao.kt | 4 +- .../data/repositories/movies/MoviesRepo.kt | 6 +++ .../ui/activities/feed/FeedActivity.kt | 8 +--- .../ui/activities/feed/FeedViewModel.kt | 4 +- .../ui/activities/movie/MovieActivity.kt | 5 +++ .../ui/activities/movie/MovieViewModel.kt | 41 ++++++++++++------- app/src/main/res/drawable/ic_star_24.xml | 10 +++++ .../main/res/drawable/ic_star_border_24.xml | 10 +++++ app/src/main/res/layout/activity_movie.xml | 2 +- 9 files changed, 64 insertions(+), 26 deletions(-) create mode 100644 app/src/main/res/drawable/ic_star_24.xml create mode 100644 app/src/main/res/drawable/ic_star_border_24.xml diff --git a/app/src/main/java/com/theapache64/topcorn/data/local/daos/MoviesDao.kt b/app/src/main/java/com/theapache64/topcorn/data/local/daos/MoviesDao.kt index 323a2c7..f4db97b 100644 --- a/app/src/main/java/com/theapache64/topcorn/data/local/daos/MoviesDao.kt +++ b/app/src/main/java/com/theapache64/topcorn/data/local/daos/MoviesDao.kt @@ -25,6 +25,6 @@ interface MoviesDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insert(favoriteMovie: FavoriteMovie) - @Query("DELETE FROM favorites WHERE id = :id") - fun deleteById(id: Long) + @Query("DELETE FROM favorites WHERE imageUrl = :url") + suspend fun deleteByUrl(url: String) } diff --git a/app/src/main/java/com/theapache64/topcorn/data/repositories/movies/MoviesRepo.kt b/app/src/main/java/com/theapache64/topcorn/data/repositories/movies/MoviesRepo.kt index f0ed794..716465e 100644 --- a/app/src/main/java/com/theapache64/topcorn/data/repositories/movies/MoviesRepo.kt +++ b/app/src/main/java/com/theapache64/topcorn/data/repositories/movies/MoviesRepo.kt @@ -72,6 +72,12 @@ class MoviesRepo @Inject constructor( } } + suspend fun deleteByUrlAsync(url: String) = coroutineScope { + async { + moviesDao.deleteByUrl(url) + } + } + @ExperimentalTime private fun isExpired(lastSynced: Long): Boolean { val currentTime = System.currentTimeMillis() diff --git a/app/src/main/java/com/theapache64/topcorn/ui/activities/feed/FeedActivity.kt b/app/src/main/java/com/theapache64/topcorn/ui/activities/feed/FeedActivity.kt index 1258e37..31ee2bb 100644 --- a/app/src/main/java/com/theapache64/topcorn/ui/activities/feed/FeedActivity.kt +++ b/app/src/main/java/com/theapache64/topcorn/ui/activities/feed/FeedActivity.kt @@ -95,14 +95,8 @@ class FeedActivity : BaseAppCompatActivity() { AppCompatDelegate.setDefaultNightMode(darkModeFlag) }) - // Watching for github home - viewModel.openGithub.observe(this, Observer { + viewModel.openFavorites.observe(this, Observer { startActivity(Intent(this, FavoritesActivity::class.java)) -// val intent = Intent( -// Intent.ACTION_VIEW, -// Uri.parse(GITHUB_URL) -// ) -// startActivity(intent) }) // Watching for toast diff --git a/app/src/main/java/com/theapache64/topcorn/ui/activities/feed/FeedViewModel.kt b/app/src/main/java/com/theapache64/topcorn/ui/activities/feed/FeedViewModel.kt index 88e52e8..0591099 100644 --- a/app/src/main/java/com/theapache64/topcorn/ui/activities/feed/FeedViewModel.kt +++ b/app/src/main/java/com/theapache64/topcorn/ui/activities/feed/FeedViewModel.kt @@ -69,7 +69,7 @@ class FeedViewModel @Inject constructor( private val _toast = MutableLiveData() val toast: LiveData = _toast - val openGithub = SingleLiveEvent() + val openFavorites = SingleLiveEvent() private val sortedOrder = MutableLiveData() @@ -115,7 +115,7 @@ class FeedViewModel @Inject constructor( } fun onHeartClicked() { - openGithub.value = true + openFavorites.value = true } /* diff --git a/app/src/main/java/com/theapache64/topcorn/ui/activities/movie/MovieActivity.kt b/app/src/main/java/com/theapache64/topcorn/ui/activities/movie/MovieActivity.kt index 391efd0..51e82f8 100644 --- a/app/src/main/java/com/theapache64/topcorn/ui/activities/movie/MovieActivity.kt +++ b/app/src/main/java/com/theapache64/topcorn/ui/activities/movie/MovieActivity.kt @@ -12,6 +12,7 @@ import com.theapache64.topcorn.databinding.ActivityMovieBinding import com.theapache64.twinkill.ui.activities.base.BaseAppCompatActivity import com.theapache64.twinkill.utils.extensions.bindContentView import dagger.android.AndroidInjection +import kotlinx.android.synthetic.main.activity_movie.* import javax.inject.Inject class MovieActivity : BaseAppCompatActivity() { @@ -44,6 +45,10 @@ class MovieActivity : BaseAppCompatActivity() { val movie = intent.getSerializableExtra(KEY_MOVIE) as Movie viewModel.init(movie) + viewModel.isFavorite.observe(this, Observer { + ib_favorite_toggle.setImageResource(if (it) R.drawable.ic_star_24 else R.drawable.ic_star_border_24) + }) + viewModel.closeActivity.observe(this, Observer { finish() }) diff --git a/app/src/main/java/com/theapache64/topcorn/ui/activities/movie/MovieViewModel.kt b/app/src/main/java/com/theapache64/topcorn/ui/activities/movie/MovieViewModel.kt index 9024dee..3bb6747 100644 --- a/app/src/main/java/com/theapache64/topcorn/ui/activities/movie/MovieViewModel.kt +++ b/app/src/main/java/com/theapache64/topcorn/ui/activities/movie/MovieViewModel.kt @@ -1,5 +1,6 @@ package com.theapache64.topcorn.ui.activities.movie +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.theapache64.topcorn.data.local.FavoriteMovie @@ -13,8 +14,14 @@ class MovieViewModel @Inject constructor( private val moviesRepo: MoviesRepo ) : ViewModel() { + val isFavorite = MutableLiveData() + fun init(movie: Movie) { this.movie = movie + viewModelScope.launch { + val favorites = moviesRepo.getAllFavoriteMovies() + isFavorite.postValue(favorites.any { it.imageUrl == movie.imageUrl }) + } } val openImdb = SingleLiveEvent() @@ -27,21 +34,27 @@ class MovieViewModel @Inject constructor( fun onFavoriteButtonClicked() { viewModelScope.launch { - moviesRepo.insertToFavoritesAsync( - FavoriteMovie( - movie?.actors, - movie?.desc, - movie?.directors, - movie?.genre, - movie?.imageUrl, - movie?.thumbUrl, - movie?.imdbUrl, - movie?.name, - movie?.rating, - movie?.year - ) - ) + when (isFavorite.value) { + false -> { + moviesRepo.insertToFavoritesAsync( + FavoriteMovie( + movie?.actors, + movie?.desc, + movie?.directors, + movie?.genre, + movie?.imageUrl, + movie?.thumbUrl, + movie?.imdbUrl, + movie?.name, + movie?.rating, + movie?.year + ) + ) + } + true -> moviesRepo.deleteByUrlAsync(movie?.imageUrl ?: "") + } } + isFavorite.value = isFavorite.value != true } fun onGoToImdbClicked() { diff --git a/app/src/main/res/drawable/ic_star_24.xml b/app/src/main/res/drawable/ic_star_24.xml new file mode 100644 index 0000000..6335165 --- /dev/null +++ b/app/src/main/res/drawable/ic_star_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_star_border_24.xml b/app/src/main/res/drawable/ic_star_border_24.xml new file mode 100644 index 0000000..a1c9b57 --- /dev/null +++ b/app/src/main/res/drawable/ic_star_border_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_movie.xml b/app/src/main/res/layout/activity_movie.xml index 84914df..b4d4d7a 100644 --- a/app/src/main/res/layout/activity_movie.xml +++ b/app/src/main/res/layout/activity_movie.xml @@ -40,7 +40,7 @@ android:background="?android:attr/selectableItemBackground" android:onClick="@{()->viewModel.onFavoriteButtonClicked()}" android:padding="18dp" - android:src="@drawable/ic_heart" + android:src="@drawable/ic_star_border_24" android:tint="@color/toolbarIconColor" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" From 7343be7f16d52a7c49cf98fd308ab1dbb755ad78 Mon Sep 17 00:00:00 2001 From: GeorgCantor Date: Thu, 17 Sep 2020 22:03:29 +0300 Subject: [PATCH 3/7] Added opening MovieActivity from FavoritesActivity --- .../activities/favorites/FavoritesActivity.kt | 10 +++++++- .../favorites/FavoritesViewModel.kt | 2 +- .../topcorn/ui/adapters/FavoritesAdapter.kt | 24 +++++++++++++++++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt b/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt index 3dc0487..ec37d3f 100644 --- a/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt +++ b/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt @@ -5,6 +5,7 @@ import android.os.Bundle import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import com.theapache64.topcorn.R +import com.theapache64.topcorn.ui.activities.movie.MovieActivity import com.theapache64.topcorn.ui.adapters.FavoritesAdapter import dagger.android.AndroidInjection import kotlinx.android.synthetic.main.activity_favorites.* @@ -24,7 +25,14 @@ class FavoritesActivity : AppCompatActivity() { viewModel = ViewModelProvider(this, factory).get(FavoritesViewModel::class.java) viewModel.favoritesMovies.observe(this, Observer { - favorites_recycler.adapter = FavoritesAdapter(it) + favorites_recycler.adapter = FavoritesAdapter(it) { movie -> + startActivity(MovieActivity.getStartIntent(this, movie)) + } }) } + + override fun onResume() { + super.onResume() + viewModel.getFavorites() + } } \ No newline at end of file diff --git a/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesViewModel.kt b/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesViewModel.kt index 903268b..ca07b75 100644 --- a/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesViewModel.kt +++ b/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesViewModel.kt @@ -14,7 +14,7 @@ class FavoritesViewModel @Inject constructor( val favoritesMovies = MutableLiveData>() - init { + fun getFavorites() { viewModelScope.launch { favoritesMovies.postValue(moviesRepo.getAllFavoriteMovies()) } diff --git a/app/src/main/java/com/theapache64/topcorn/ui/adapters/FavoritesAdapter.kt b/app/src/main/java/com/theapache64/topcorn/ui/adapters/FavoritesAdapter.kt index 1795a72..8d857c5 100644 --- a/app/src/main/java/com/theapache64/topcorn/ui/adapters/FavoritesAdapter.kt +++ b/app/src/main/java/com/theapache64/topcorn/ui/adapters/FavoritesAdapter.kt @@ -9,10 +9,13 @@ import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.theapache64.topcorn.R import com.theapache64.topcorn.data.local.FavoriteMovie +import com.theapache64.topcorn.data.remote.Movie import kotlinx.android.synthetic.main.item_favorite.view.* -class FavoritesAdapter(private val favorites: List) : - RecyclerView.Adapter() { +class FavoritesAdapter( + private val favorites: List, + private val clickListener: (Movie) -> Unit +) : RecyclerView.Adapter() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = FavoritesViewHolder( LayoutInflater.from(parent.context).inflate(R.layout.item_favorite, parent, false) @@ -26,6 +29,23 @@ class FavoritesAdapter(private val favorites: List) : Glide.with(itemView) .load(favorite.imageUrl) .into(poster) + + itemView.setOnClickListener { + clickListener( + Movie( + favorite.actors ?: emptyList(), + favorite.desc ?: "", + favorite.directors ?: emptyList(), + favorite.genre ?: emptyList(), + favorite.imageUrl ?: "", + favorite.thumbUrl ?: "", + favorite.imdbUrl ?: "", + favorite.name ?: "", + favorite.rating ?: 0F, + favorite.year ?: 0 + ) + ) + } } } From b3705da01d00fc14e594335ae48e8c795b708f64 Mon Sep 17 00:00:00 2001 From: GeorgCantor Date: Thu, 17 Sep 2020 22:21:51 +0300 Subject: [PATCH 4/7] Added empty list hint --- .../activities/favorites/FavoritesActivity.kt | 17 +++++++++++++++++ .../activities/favorites/FavoritesViewModel.kt | 5 ++++- app/src/main/res/layout/activity_favorites.xml | 13 +++++++++++++ app/src/main/res/values/strings.xml | 3 +-- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt b/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt index ec37d3f..35bd724 100644 --- a/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt +++ b/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt @@ -2,6 +2,9 @@ package com.theapache64.topcorn.ui.activities.favorites import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.view.MenuItem +import android.view.View.GONE +import android.view.View.VISIBLE import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import com.theapache64.topcorn.R @@ -22,6 +25,11 @@ class FavoritesActivity : AppCompatActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.activity_favorites) + supportActionBar?.apply { + setDisplayHomeAsUpEnabled(true) + setDisplayShowHomeEnabled(true) + } + viewModel = ViewModelProvider(this, factory).get(FavoritesViewModel::class.java) viewModel.favoritesMovies.observe(this, Observer { @@ -29,10 +37,19 @@ class FavoritesActivity : AppCompatActivity() { startActivity(MovieActivity.getStartIntent(this, movie)) } }) + + viewModel.isListEmpty.observe(this, Observer { empty -> + empty_text.visibility = if (empty) VISIBLE else GONE + }) } override fun onResume() { super.onResume() viewModel.getFavorites() } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == android.R.id.home) onBackPressed() + return super.onOptionsItemSelected(item) + } } \ No newline at end of file diff --git a/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesViewModel.kt b/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesViewModel.kt index ca07b75..a54a9db 100644 --- a/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesViewModel.kt +++ b/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesViewModel.kt @@ -13,10 +13,13 @@ class FavoritesViewModel @Inject constructor( ) : ViewModel() { val favoritesMovies = MutableLiveData>() + val isListEmpty = MutableLiveData() fun getFavorites() { viewModelScope.launch { - favoritesMovies.postValue(moviesRepo.getAllFavoriteMovies()) + val favorites = moviesRepo.getAllFavoriteMovies() + favoritesMovies.postValue(favorites) + isListEmpty.value = favorites.isNullOrEmpty() } } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_favorites.xml b/app/src/main/res/layout/activity_favorites.xml index b575ebe..ac5e2b9 100644 --- a/app/src/main/res/layout/activity_favorites.xml +++ b/app/src/main/res/layout/activity_favorites.xml @@ -18,4 +18,17 @@ app:spanCount="3" tools:listitem="@layout/item_movie" /> + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a2231c5..e6fdebe 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,6 +8,5 @@ OPEN IMDB Sorted by year Sorted by rating - - + Favorite list is empty From 55c6d051e1b7731fc5f14786b063677fca377388 Mon Sep 17 00:00:00 2001 From: GeorgCantor Date: Fri, 18 Sep 2020 12:47:03 +0300 Subject: [PATCH 5/7] removed feed_onHeartClicked_goToGitHub test --- .../ui/activities/feed/FeedActivityTest.kt | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/app/src/test/java/com/theapache64/topcorn/ui/activities/feed/FeedActivityTest.kt b/app/src/test/java/com/theapache64/topcorn/ui/activities/feed/FeedActivityTest.kt index 7f2505a..b8599ec 100644 --- a/app/src/test/java/com/theapache64/topcorn/ui/activities/feed/FeedActivityTest.kt +++ b/app/src/test/java/com/theapache64/topcorn/ui/activities/feed/FeedActivityTest.kt @@ -1,21 +1,12 @@ package com.theapache64.topcorn.ui.activities.feed -import android.app.Activity -import android.app.Instrumentation import android.content.Context -import android.content.Intent import androidx.recyclerview.widget.RecyclerView import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ApplicationProvider.getApplicationContext import androidx.test.espresso.Espresso.onView import androidx.test.espresso.ViewAssertion -import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.assertion.ViewAssertions.matches -import androidx.test.espresso.intent.Intents -import androidx.test.espresso.intent.Intents.intended -import androidx.test.espresso.intent.Intents.intending -import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction -import androidx.test.espresso.intent.matcher.IntentMatchers.hasData import androidx.test.espresso.matcher.ViewMatchers.* import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry @@ -36,7 +27,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runBlockingTest -import org.hamcrest.CoreMatchers.allOf import org.junit.After import org.junit.Assert.assertEquals import org.junit.Before @@ -113,20 +103,6 @@ class FeedActivityTest { ac.close() } - @Test - fun feed_onHeartClicked_goToGitHub() = runBlockingTest { - Intents.init() - val intentResult = Instrumentation.ActivityResult(Activity.RESULT_OK, Intent()) - val sendingIntent = allOf( - hasAction(Intent.ACTION_VIEW), - hasData(FeedActivity.GITHUB_URL) - ) - intending(sendingIntent).respondWith(intentResult) - onView(withId(R.id.ib_heart)).check(matches(isDisplayed())).perform(click()) - intended(sendingIntent) - Intents.release() - } - @Test fun feed_load_click() { From 0f8a3bd3fcd281782f11203de5eedd3b71cbc121 Mon Sep 17 00:00:00 2001 From: GeorgCantor Date: Fri, 18 Sep 2020 12:56:15 +0300 Subject: [PATCH 6/7] Added title to FavoritesActivity --- .../topcorn/ui/activities/favorites/FavoritesActivity.kt | 1 + app/src/main/res/values/strings.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt b/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt index 35bd724..1879af2 100644 --- a/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt +++ b/app/src/main/java/com/theapache64/topcorn/ui/activities/favorites/FavoritesActivity.kt @@ -28,6 +28,7 @@ class FavoritesActivity : AppCompatActivity() { supportActionBar?.apply { setDisplayHomeAsUpEnabled(true) setDisplayShowHomeEnabled(true) + setTitle(R.string.favorites) } viewModel = ViewModelProvider(this, factory).get(FavoritesViewModel::class.java) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e6fdebe..8eb1b9c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,5 +8,6 @@ OPEN IMDB Sorted by year Sorted by rating + Favorites Favorite list is empty From c038f55038288fba37a6266781fd174ad9723dbb Mon Sep 17 00:00:00 2001 From: GeorgCantor Date: Fri, 18 Sep 2020 13:05:50 +0300 Subject: [PATCH 7/7] fixed item_favorite width --- app/src/main/res/layout/activity_favorites.xml | 17 +++++------------ app/src/main/res/layout/item_favorite.xml | 4 ++-- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/app/src/main/res/layout/activity_favorites.xml b/app/src/main/res/layout/activity_favorites.xml index ac5e2b9..5631659 100644 --- a/app/src/main/res/layout/activity_favorites.xml +++ b/app/src/main/res/layout/activity_favorites.xml @@ -1,5 +1,5 @@ - @@ -22,13 +18,10 @@ android:id="@+id/empty_text" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_gravity="center" android:text="@string/list_is_empty" android:textColor="@color/primaryTextColor" android:textSize="18sp" - android:visibility="gone" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + android:visibility="gone" /> - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/item_favorite.xml b/app/src/main/res/layout/item_favorite.xml index bdbb6ed..04c5340 100644 --- a/app/src/main/res/layout/item_favorite.xml +++ b/app/src/main/res/layout/item_favorite.xml @@ -3,13 +3,13 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/cl_movie" - android:layout_width="120dp" + android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp">