Skip to content

Commit

Permalink
Favourite button function added
Browse files Browse the repository at this point in the history
  • Loading branch information
ShashankSinha98 committed Apr 4, 2022
1 parent ec67f27 commit 0f10bd9
Show file tree
Hide file tree
Showing 21 changed files with 491 additions and 40 deletions.
1 change: 1 addition & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.shashank.moviedb.data;

public interface ResourceCallback {
void onResponse(Resource resource);
public interface ResourceCallback<T> {
void onResponse(Resource<T> resource);
}
24 changes: 16 additions & 8 deletions app/src/main/java/com/shashank/moviedb/data/local/MovieDao.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
package com.shashank.moviedb.data.local;

import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;

import com.shashank.moviedb.data.local.entity.FavouriteMovieIdsEntity;
import com.shashank.moviedb.model.MovieResult;
import com.shashank.moviedb.model.NowPlayingMovieIdsEntity;
import com.shashank.moviedb.model.TrendingMovieIdsEntity;
import com.shashank.moviedb.data.local.entity.NowPlayingMovieIdsEntity;
import com.shashank.moviedb.data.local.entity.TrendingMovieIdsEntity;

import java.util.List;

import io.reactivex.Completable;
import io.reactivex.Flowable;
import io.reactivex.Single;

// Using RxJava with Room DB
// @link: https://medium.com/androiddevelopers/room-rxjava-acb0cd4f3757
Expand All @@ -31,9 +30,6 @@ public interface MovieDao {
void insertNowPlayingMovieIds(NowPlayingMovieIdsEntity... trendingMovieIds);


@Query("SELECT * FROM movies")
Flowable<List<MovieResult>> getMovieResults();

@Query("SELECT * FROM trending_movie_ids")
Flowable<List<TrendingMovieIdsEntity>> getTrendingMovieIds();

Expand All @@ -43,4 +39,16 @@ public interface MovieDao {
@Query("SELECT * FROM movies WHERE id IN (:movieIds)")
Flowable<List<MovieResult>> getMovieResultsForMovieIds(List<Long> movieIds);

@Query("SELECT COUNT(*) FROM favourite_movie_ids WHERE movie_id=:movieId")
Flowable<Integer> getFavouriteCountForMovieId(Long movieId);

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertFavouriteMovieId(FavouriteMovieIdsEntity favouriteMovieIdsEntity);

@Delete
void deleteFavouriteMovieId(FavouriteMovieIdsEntity favouriteMovieIdsEntity);

@Query("SELECT * FROM favourite_movie_ids")
Flowable<List<FavouriteMovieIdsEntity>> getFavouriteMovieIdsEntities();

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

import androidx.room.Database;
import androidx.room.RoomDatabase;

import com.shashank.moviedb.data.local.entity.FavouriteMovieIdsEntity;
import com.shashank.moviedb.model.MovieResult;
import com.shashank.moviedb.model.NowPlayingMovieIdsEntity;
import com.shashank.moviedb.model.TrendingMovieIdsEntity;
import com.shashank.moviedb.data.local.entity.NowPlayingMovieIdsEntity;
import com.shashank.moviedb.data.local.entity.TrendingMovieIdsEntity;

@Database(entities = {
MovieResult.class,
TrendingMovieIdsEntity.class,
NowPlayingMovieIdsEntity.class
NowPlayingMovieIdsEntity.class,
FavouriteMovieIdsEntity.class
}, version = 1, exportSchema = false)
public abstract class MovieDatabase extends RoomDatabase {
public abstract MovieDao getMovieDao();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.shashank.moviedb.data.local.entity;

import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;

@Entity(tableName = "favourite_movie_ids")
public class FavouriteMovieIdsEntity {

@PrimaryKey(autoGenerate = false)
@ColumnInfo(name = "movie_id")
private Long movieId;

public FavouriteMovieIdsEntity(Long movieId) {
this.movieId = movieId;
}

public Long getMovieId() {
return movieId;
}

public void setMovieId(Long movieId) {
this.movieId = movieId;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.shashank.moviedb.model;
package com.shashank.moviedb.data.local.entity;

import androidx.room.ColumnInfo;
import androidx.room.Entity;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.shashank.moviedb.model;
package com.shashank.moviedb.data.local.entity;

import androidx.room.ColumnInfo;
import androidx.room.Entity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,14 @@ public interface MovieRepository {
void fetchTrendingMovies(ResourceCallback resourceCallback);

void fetchMovieDetail(Long movieId, ResourceCallback resourceCallback);

void isFavourite(long movieId, ResourceCallback<Boolean> resourceCallback);

void addFavourite(long movieId, ResourceCallback<Boolean> resourceCallback);

void removeFavourite(long movieId, ResourceCallback<Boolean> resourceCallback);

void getFavouriteMovieIds(ResourceCallback<List<Long>> resourceCallback);

void checkMovieDataInDatabaseForIds(List<Long> movieIds, ResourceCallback<List<MovieResult>> resourceCallback);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
import com.shashank.moviedb.data.ResourceCallback;
import com.shashank.moviedb.data.Resource;
import com.shashank.moviedb.data.local.MovieDao;
import com.shashank.moviedb.data.local.entity.FavouriteMovieIdsEntity;
import com.shashank.moviedb.model.MovieDetail;
import com.shashank.moviedb.model.MovieResponse;
import com.shashank.moviedb.model.MovieResult;
import com.shashank.moviedb.model.NowPlayingMovieIdsEntity;
import com.shashank.moviedb.model.TrendingMovieIdsEntity;
import com.shashank.moviedb.data.local.entity.NowPlayingMovieIdsEntity;
import com.shashank.moviedb.data.local.entity.TrendingMovieIdsEntity;
import com.shashank.moviedb.util.Constants.QueryParams;

import java.util.ArrayList;
Expand Down Expand Up @@ -158,6 +159,116 @@ public void onComplete() {
});
}

@Override
public void isFavourite(long movieId, ResourceCallback<Boolean> resourceCallback) {
resourceCallback.onResponse(Resource.loading("Querying favourite status for movieId: "+movieId));

movieDao.getFavouriteCountForMovieId(movieId)
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer count) throws Exception {
resourceCallback.onResponse(Resource.success((count>0)));
}
});
}


@Override
public void addFavourite(long movieId, ResourceCallback<Boolean> resourceCallback) {
resourceCallback.onResponse(Resource.loading("Adding Movie to Favourite, movieId: "+movieId));

Completable.fromAction(new Action() {
@Override
public void run() throws Exception {
movieDao.insertFavouriteMovieId(new FavouriteMovieIdsEntity(movieId));
}
}).subscribeOn(Schedulers.io())
.subscribe(new CompletableObserver() {
@Override
public void onSubscribe(@NonNull Disposable d) {

}

@Override
public void onComplete() {
resourceCallback.onResponse(Resource.success(true));
}

@Override
public void onError(@NonNull Throwable e) {
resourceCallback.onResponse(Resource.error("Error adding movieId: "+movieId+" to favourite", null));
}
});

}

@Override
public void removeFavourite(long movieId, ResourceCallback<Boolean> resourceCallback) {
resourceCallback.onResponse(Resource.loading("Removing Movie from Favourite, movieId: "+movieId));

Completable.fromAction(new Action() {
@Override
public void run() throws Exception {
movieDao.deleteFavouriteMovieId(new FavouriteMovieIdsEntity(movieId));
}
}).subscribeOn(Schedulers.io())
.subscribe(new CompletableObserver() {
@Override
public void onSubscribe(@NonNull Disposable d) {

}

@Override
public void onComplete() {
resourceCallback.onResponse(Resource.success(false));
}

@Override
public void onError(@NonNull Throwable e) {
resourceCallback.onResponse(Resource.error("Error removing movieId: "+movieId+" from favourite", null));
}
});

}

@Override
public void getFavouriteMovieIds(ResourceCallback<List<Long>> resourceCallback) {
resourceCallback.onResponse(Resource.loading("Querying Favourite movie ids from db"));

movieDao.getFavouriteMovieIdsEntities()
.subscribeOn(Schedulers.computation())
.subscribe(new Consumer<List<FavouriteMovieIdsEntity>>() {
@Override
public void accept(List<FavouriteMovieIdsEntity> favouriteMovieIdsEntities) throws Exception {
if(favouriteMovieIdsEntities==null || favouriteMovieIdsEntities.isEmpty()) {
resourceCallback.onResponse(Resource.error("Error/Empty favourite query response", null));;
} else {
List<Long> favouriteIds = new ArrayList<>();
for(FavouriteMovieIdsEntity favouriteMovieIdsEntity: favouriteMovieIdsEntities) {
favouriteIds.add(favouriteMovieIdsEntity.getMovieId());
}
resourceCallback.onResponse(Resource.success(favouriteIds));
}
}
});
}

@Override
public void checkMovieDataInDatabaseForIds(List<Long> movieIds, ResourceCallback<List<MovieResult>> callback) {
// Fetch movies data from DB
movieDao.getMovieResultsForMovieIds(movieIds).subscribeOn(Schedulers.io())
.subscribe(new Consumer<List<MovieResult>>() {
@Override
public void accept(List<MovieResult> movieResults) throws Exception {
Log.d(TAG, "xlr8: processMovieResponse : accept: movieResults: "+movieResults);
if(movieResults==null || movieResults.size()==0)
callback.onResponse(Resource.error("Error Fetching Data from DB / DB is Empty", null));
else callback.onResponse(Resource.success(movieResults));
}
});
}


/********************************************** PRIVATE HELPER FUNCTIONS *****************************************************************************/

Expand Down Expand Up @@ -241,7 +352,7 @@ public void accept(List<TrendingMovieIdsEntity> trendingMovieIdsEntities) throws
}

// Step 2.2- fetch movie of these ids only
checkMovieDataInDatabaseForIds(callback, trendingMovieIds);
checkMovieDataInDatabaseForIds(trendingMovieIds, callback);
} else {
callback.onResponse(Resource.error("Error/Empty response while querying DB", null));
}
Expand All @@ -262,7 +373,7 @@ public void accept(List<NowPlayingMovieIdsEntity> nowPlayingMovieIdsEntities) th
}

// Step 2.2- fetch movie of these ids only
checkMovieDataInDatabaseForIds(callback, nowPlayingMovieIds);
checkMovieDataInDatabaseForIds(nowPlayingMovieIds, callback);
} else {
callback.onResponse(Resource.error("Error/Empty response while querying DB", null));
}
Expand All @@ -272,17 +383,4 @@ public void accept(List<NowPlayingMovieIdsEntity> nowPlayingMovieIdsEntities) th

}

private void checkMovieDataInDatabaseForIds(ResourceCallback callback, List<Long> movieIds) {
// Fetch movies data from DB
movieDao.getMovieResultsForMovieIds(movieIds).subscribeOn(Schedulers.io())
.subscribe(new Consumer<List<MovieResult>>() {
@Override
public void accept(List<MovieResult> movieResults) throws Exception {
Log.d(TAG, "xlr8: processMovieResponse : accept: movieResults: "+movieResults);
if(movieResults==null || movieResults.size()==0)
callback.onResponse(Resource.error("Error Fetching Data from DB / DB is Empty", null));
else callback.onResponse(Resource.success(movieResults));
}
});
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.shashank.moviedb.di.trending;

import com.shashank.moviedb.ui.detail.DetailFragment;
import com.shashank.moviedb.ui.favourites.FavouriteFragment;
import com.shashank.moviedb.ui.nowplaying.NowPlayingFragment;
import com.shashank.moviedb.ui.trending.TrendingFragment;

Expand All @@ -18,4 +19,7 @@ public abstract class HomeFragmentBuildersModule {

@ContributesAndroidInjector
abstract DetailFragment contributeDetailFragment();

@ContributesAndroidInjector
abstract FavouriteFragment contributeFavouriteFragment();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import com.shashank.moviedb.di.ViewModelKey;
import com.shashank.moviedb.ui.detail.DetailViewModel;
import com.shashank.moviedb.ui.favourites.FavouriteViewModel;
import com.shashank.moviedb.ui.nowplaying.NowPlayingViewModel;
import com.shashank.moviedb.ui.trending.TrendingViewModel;

Expand All @@ -29,4 +30,9 @@ public abstract class HomeViewModelModule {
@IntoMap
@ViewModelKey(DetailViewModel.class)
abstract ViewModel bindDetailViewModel(DetailViewModel detailViewModel);

@Binds
@IntoMap
@ViewModelKey(FavouriteViewModel.class)
abstract ViewModel bindFavouriteViewModel(FavouriteViewModel favouriteViewModel);
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public void onDestinationChanged(@NonNull NavController controller, @NonNull Nav
switch (destination.getId()) {
case R.id.nav_trending:
case R.id.nav_now_playing:
case R.id.nav_favourite:
toolbar.setVisibility(View.VISIBLE);
toolbarTextView.setText(destination.getLabel());
break;
Expand Down
Loading

0 comments on commit 0f10bd9

Please sign in to comment.