From c5cc3456df82b680e09956146742bb87b30e454d Mon Sep 17 00:00:00 2001 From: shalenMathew Date: Mon, 3 Jun 2024 23:16:07 +0530 Subject: [PATCH] fav feature implemented --- .../movieflix/core/adapters/FavAdapters.kt | 69 ++++++++++++++ .../movieflix/core/di/DatabaseModule.kt | 12 ++- .../example/movieflix/core/utils/Constants.kt | 1 + .../example/movieflix/core/utils/ViewUtils.kt | 9 +- .../movieflix/data/local/LocalDataSource.kt | 13 +++ .../example/movieflix/data/local/MovieDao.kt | 11 +++ .../movieflix/data/local/MovieDatabase.kt | 3 +- .../data/local/entity/FavouritesEntity.kt | 12 +++ .../data/repository/FavMovieRepositoryImpl.kt | 20 ++++ .../domain/repository/FavMovieRepository.kt | 12 +++ .../movieflix/domain/usecases/FavMovie.kt | 23 +++++ .../details/MovieDetailsFragment.kt | 45 +++++++++ .../presentation/favorites/FavFragment.kt | 77 +++++++++++++++ .../presentation/home/HomeFragment.kt | 4 + .../viewmodels/FavMovieViewModel.kt | 37 ++++++++ .../watchlist/WatchListFragment.kt | 1 + app/src/main/res/drawable/fav_red.png | Bin 0 -> 10569 bytes app/src/main/res/layout/fragment_fav.xml | 88 ++++++++++++++++++ .../res/layout/fragment_movie_details.xml | 4 +- .../main/res/layout/fragment_watch_list.xml | 2 +- app/src/main/res/navigation/navigation.xml | 12 +++ 21 files changed, 449 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/com/example/movieflix/core/adapters/FavAdapters.kt create mode 100644 app/src/main/java/com/example/movieflix/data/local/entity/FavouritesEntity.kt create mode 100644 app/src/main/java/com/example/movieflix/data/repository/FavMovieRepositoryImpl.kt create mode 100644 app/src/main/java/com/example/movieflix/domain/repository/FavMovieRepository.kt create mode 100644 app/src/main/java/com/example/movieflix/domain/usecases/FavMovie.kt create mode 100644 app/src/main/java/com/example/movieflix/presentation/favorites/FavFragment.kt create mode 100644 app/src/main/java/com/example/movieflix/presentation/viewmodels/FavMovieViewModel.kt create mode 100644 app/src/main/res/drawable/fav_red.png create mode 100644 app/src/main/res/layout/fragment_fav.xml diff --git a/app/src/main/java/com/example/movieflix/core/adapters/FavAdapters.kt b/app/src/main/java/com/example/movieflix/core/adapters/FavAdapters.kt new file mode 100644 index 0000000..dfc1bc9 --- /dev/null +++ b/app/src/main/java/com/example/movieflix/core/adapters/FavAdapters.kt @@ -0,0 +1,69 @@ +package com.example.movieflix.core.adapters + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.example.movieflix.R +import com.example.movieflix.core.utils.Constants +import com.example.movieflix.core.utils.isNetworkAvailable +import com.example.movieflix.core.utils.loadImage +import com.example.movieflix.data.local.entity.FavouritesEntity +import com.example.movieflix.data.local.entity.WatchListEntity +import com.example.movieflix.databinding.ItemListBinding +import com.example.movieflix.domain.model.MovieResult + +class FavAdapters(private var onPosterClick: ((movieResult: MovieResult) -> Unit)): + ListAdapter(DiffUtilCallback()) { + inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) { + var binding: ItemListBinding + init { + binding = ItemListBinding.bind(itemView) + } + fun bind(favouritesEntity: FavouritesEntity)=binding.apply{ + + val item = favouritesEntity.movieResult + itemListPoster.loadImage(Constants.TMDB_POSTER_IMAGE_BASE_URL_W342.plus(item.posterPath)) + itemListRatingTxt.text = String.format("%.1f", item.voteAverage) + + root.setOnClickListener(){ + if (isNetworkAvailable(root.context)){ + onPosterClick(item) + }else{ + Toast.makeText(root.context, "Internet req", Toast.LENGTH_SHORT).show() + } + } + } + } + + + class DiffUtilCallback : DiffUtil.ItemCallback() { + override fun areItemsTheSame( + oldItem: FavouritesEntity, + newItem: FavouritesEntity + ): Boolean { + return oldItem == newItem + } + + override fun areContentsTheSame( + oldItem: FavouritesEntity, + newItem: FavouritesEntity + ): Boolean { + return oldItem == newItem + } + + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.item_list,parent,false) + return ViewHolder(view) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.bind(getItem(position)) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/movieflix/core/di/DatabaseModule.kt b/app/src/main/java/com/example/movieflix/core/di/DatabaseModule.kt index 6677df8..222a87c 100644 --- a/app/src/main/java/com/example/movieflix/core/di/DatabaseModule.kt +++ b/app/src/main/java/com/example/movieflix/core/di/DatabaseModule.kt @@ -5,13 +5,16 @@ import android.content.Context import androidx.room.Room import com.example.movieflix.core.utils.Constants import com.example.movieflix.core.utils.GsonParser +import com.example.movieflix.core.utils.MIGRATION_2_3 import com.example.movieflix.data.local.LocalDataSource import com.example.movieflix.data.local.MovieDao import com.example.movieflix.data.local.MovieDataTypeConverter import com.example.movieflix.data.local.MovieDatabase import com.example.movieflix.data.remote.RemoteDataSource +import com.example.movieflix.data.repository.FavMovieRepositoryImpl import com.example.movieflix.data.repository.MovieInfoRepositoryImpl import com.example.movieflix.data.repository.WatchListRepositoryImpl +import com.example.movieflix.domain.repository.FavMovieRepository import com.example.movieflix.domain.repository.MovieInfoRepository import com.example.movieflix.domain.repository.WatchListRepository import com.google.gson.Gson @@ -30,7 +33,8 @@ object DatabaseModule { @Singleton fun providesMovieDataBase(@ApplicationContext context: Context): MovieDatabase { return Room.databaseBuilder(context,MovieDatabase::class.java,Constants.DATABASE_NAME) - .fallbackToDestructiveMigration() +// .fallbackToDestructiveMigration() + .addMigrations(MIGRATION_2_3) .addTypeConverter(MovieDataTypeConverter(GsonParser(Gson()))) .build() } @@ -57,4 +61,10 @@ object DatabaseModule { return WatchListRepositoryImpl(localDataSource) } + @Provides + @Singleton + fun getFavMovie(localDataSource: LocalDataSource):FavMovieRepository{ + return FavMovieRepositoryImpl(localDataSource) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/example/movieflix/core/utils/Constants.kt b/app/src/main/java/com/example/movieflix/core/utils/Constants.kt index 8abefa9..4b8ab19 100644 --- a/app/src/main/java/com/example/movieflix/core/utils/Constants.kt +++ b/app/src/main/java/com/example/movieflix/core/utils/Constants.kt @@ -29,5 +29,6 @@ object Constants { const val DATABASE_NAME = "movie_data_database" const val TABLE_NAME = "movie_data_table" const val WATCHLIST_TABLE_NAME = "watch_list_news_table" + const val FAVOURITES_TABLE_NAME="favorites_table" } \ No newline at end of file diff --git a/app/src/main/java/com/example/movieflix/core/utils/ViewUtils.kt b/app/src/main/java/com/example/movieflix/core/utils/ViewUtils.kt index c99ba81..0a0fbde 100644 --- a/app/src/main/java/com/example/movieflix/core/utils/ViewUtils.kt +++ b/app/src/main/java/com/example/movieflix/core/utils/ViewUtils.kt @@ -5,8 +5,9 @@ import android.content.Intent import android.net.ConnectivityManager import android.provider.Settings import android.view.View -import android.widget.TextView import android.widget.Toast +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase import com.example.movieflix.domain.model.Genre import java.text.SimpleDateFormat import java.util.Date @@ -114,4 +115,10 @@ fun shareMovie(context:Context,title:String,trailer:String){ fun getRandomChar():String{ val alphabet = ('a'..'z') return alphabet.random().toString() +} + + val MIGRATION_2_3 = object : Migration(2, 3) { + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL("CREATE TABLE IF NOT EXISTS `${Constants.FAVOURITES_TABLE_NAME}` (`id` INTEGER NOT NULL, `movieResult` TEXT NOT NULL, PRIMARY KEY(`id`))") + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/movieflix/data/local/LocalDataSource.kt b/app/src/main/java/com/example/movieflix/data/local/LocalDataSource.kt index 658ee40..6047f86 100644 --- a/app/src/main/java/com/example/movieflix/data/local/LocalDataSource.kt +++ b/app/src/main/java/com/example/movieflix/data/local/LocalDataSource.kt @@ -1,6 +1,7 @@ package com.example.movieflix.data.local import androidx.lifecycle.LiveData +import com.example.movieflix.data.local.entity.FavouritesEntity import com.example.movieflix.data.local.entity.HomeFeedEntity import com.example.movieflix.data.local.entity.WatchListEntity import com.example.movieflix.domain.model.MovieResult @@ -29,4 +30,16 @@ suspend fun insertHomeFeedData(homeFeedEntity: HomeFeedEntity){ return movieDao.getAllWatchListData() } + suspend fun insertFavMovie(favouritesEntity: FavouritesEntity){ + movieDao.insertFavMovie(favouritesEntity) + } + + suspend fun deleteFavMovie(favouritesEntity: FavouritesEntity){ + movieDao.deleteFavMovie(favouritesEntity) + } + + fun getAllFavMovie():LiveData>{ + return movieDao.getAllFavMovies() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/example/movieflix/data/local/MovieDao.kt b/app/src/main/java/com/example/movieflix/data/local/MovieDao.kt index 8539b7e..93b3f1f 100644 --- a/app/src/main/java/com/example/movieflix/data/local/MovieDao.kt +++ b/app/src/main/java/com/example/movieflix/data/local/MovieDao.kt @@ -6,6 +6,7 @@ import androidx.room.Delete import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query +import com.example.movieflix.data.local.entity.FavouritesEntity import com.example.movieflix.data.local.entity.HomeFeedEntity import com.example.movieflix.data.local.entity.WatchListEntity import com.example.movieflix.domain.model.MovieResult @@ -25,4 +26,14 @@ interface MovieDao { @Query(" SELECT * FROM watch_list_news_table ORDER BY id DESC ") fun getAllWatchListData():LiveData> + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertFavMovie(favouritesEntity: FavouritesEntity) + + @Delete + suspend fun deleteFavMovie(favouritesEntity: FavouritesEntity) + + @Query( " SELECT * FROM favorites_table ORDER BY id DESC ") + fun getAllFavMovies():LiveData> + + } \ No newline at end of file diff --git a/app/src/main/java/com/example/movieflix/data/local/MovieDatabase.kt b/app/src/main/java/com/example/movieflix/data/local/MovieDatabase.kt index b4a6537..b23a58d 100644 --- a/app/src/main/java/com/example/movieflix/data/local/MovieDatabase.kt +++ b/app/src/main/java/com/example/movieflix/data/local/MovieDatabase.kt @@ -3,10 +3,11 @@ package com.example.movieflix.data.local import androidx.room.Database import androidx.room.RoomDatabase import androidx.room.TypeConverters +import com.example.movieflix.data.local.entity.FavouritesEntity import com.example.movieflix.data.local.entity.HomeFeedEntity import com.example.movieflix.data.local.entity.WatchListEntity -@Database(entities = [HomeFeedEntity::class,WatchListEntity::class], version = 2) +@Database(entities = [HomeFeedEntity::class,WatchListEntity::class,FavouritesEntity::class], version = 3) @TypeConverters(MovieDataTypeConverter::class) abstract class MovieDatabase:RoomDatabase(){ abstract val dao:MovieDao diff --git a/app/src/main/java/com/example/movieflix/data/local/entity/FavouritesEntity.kt b/app/src/main/java/com/example/movieflix/data/local/entity/FavouritesEntity.kt new file mode 100644 index 0000000..adbcb0d --- /dev/null +++ b/app/src/main/java/com/example/movieflix/data/local/entity/FavouritesEntity.kt @@ -0,0 +1,12 @@ +package com.example.movieflix.data.local.entity + +import androidx.room.Entity +import androidx.room.PrimaryKey +import com.example.movieflix.core.utils.Constants +import com.example.movieflix.domain.model.MovieResult + +@Entity(Constants.FAVOURITES_TABLE_NAME) +data class FavouritesEntity( + @PrimaryKey val id:Int, + val movieResult: MovieResult +) \ No newline at end of file diff --git a/app/src/main/java/com/example/movieflix/data/repository/FavMovieRepositoryImpl.kt b/app/src/main/java/com/example/movieflix/data/repository/FavMovieRepositoryImpl.kt new file mode 100644 index 0000000..ae1d741 --- /dev/null +++ b/app/src/main/java/com/example/movieflix/data/repository/FavMovieRepositoryImpl.kt @@ -0,0 +1,20 @@ +package com.example.movieflix.data.repository + +import androidx.lifecycle.LiveData +import com.example.movieflix.data.local.LocalDataSource +import com.example.movieflix.data.local.entity.FavouritesEntity +import com.example.movieflix.domain.repository.FavMovieRepository + +class FavMovieRepositoryImpl(private val localDataSource: LocalDataSource):FavMovieRepository { + override suspend fun insertFavMovie(favouritesEntity: FavouritesEntity) { + localDataSource.insertFavMovie(favouritesEntity) + } + + override suspend fun deleteFavMovie(favouritesEntity: FavouritesEntity) { + localDataSource.deleteFavMovie(favouritesEntity) + } + + override fun getAllFavMovie(): LiveData> { + return localDataSource.getAllFavMovie() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/movieflix/domain/repository/FavMovieRepository.kt b/app/src/main/java/com/example/movieflix/domain/repository/FavMovieRepository.kt new file mode 100644 index 0000000..6db2b67 --- /dev/null +++ b/app/src/main/java/com/example/movieflix/domain/repository/FavMovieRepository.kt @@ -0,0 +1,12 @@ +package com.example.movieflix.domain.repository + +import androidx.lifecycle.LiveData +import com.example.movieflix.data.local.entity.FavouritesEntity + +interface FavMovieRepository { + suspend fun insertFavMovie(favouritesEntity: FavouritesEntity) + + suspend fun deleteFavMovie(favouritesEntity: FavouritesEntity) + + fun getAllFavMovie(): LiveData> +} \ No newline at end of file diff --git a/app/src/main/java/com/example/movieflix/domain/usecases/FavMovie.kt b/app/src/main/java/com/example/movieflix/domain/usecases/FavMovie.kt new file mode 100644 index 0000000..53fd067 --- /dev/null +++ b/app/src/main/java/com/example/movieflix/domain/usecases/FavMovie.kt @@ -0,0 +1,23 @@ +package com.example.movieflix.domain.usecases + +import androidx.lifecycle.LiveData +import com.example.movieflix.data.local.entity.FavouritesEntity +import com.example.movieflix.domain.repository.FavMovieRepository +import com.example.movieflix.domain.repository.WatchListRepository +import javax.inject.Inject + +class FavMovie @Inject constructor(private val favMovieRepository: FavMovieRepository) { + + suspend fun insertFavMovie(favouritesEntity: FavouritesEntity){ + favMovieRepository.insertFavMovie(favouritesEntity) + } + + suspend fun deleteFavMovie(favouritesEntity: FavouritesEntity){ + favMovieRepository.deleteFavMovie(favouritesEntity) + } + + fun getAllFavMovie(): LiveData>{ + return favMovieRepository.getAllFavMovie() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/movieflix/presentation/details/MovieDetailsFragment.kt b/app/src/main/java/com/example/movieflix/presentation/details/MovieDetailsFragment.kt index 8875450..7b8ca5e 100644 --- a/app/src/main/java/com/example/movieflix/presentation/details/MovieDetailsFragment.kt +++ b/app/src/main/java/com/example/movieflix/presentation/details/MovieDetailsFragment.kt @@ -28,6 +28,7 @@ import com.example.movieflix.core.utils.showToast import com.example.movieflix.databinding.FragmentMovieDetailsBinding import com.example.movieflix.domain.model.MovieResult import com.example.movieflix.domain.model.MovieVideoResult +import com.example.movieflix.presentation.viewmodels.FavMovieViewModel import com.example.movieflix.presentation.viewmodels.HomeInfoViewModel import com.example.movieflix.presentation.viewmodels.WatchListViewModel import com.google.android.material.bottomsheet.BottomSheetDialogFragment @@ -54,8 +55,11 @@ class MovieDetailsFragment : BottomSheetDialogFragment(){ CustomTabsIntent.Builder().setShowTitle(true).build() } private val watchListViewModel:WatchListViewModel by viewModels() + private val favMovieViewModel: FavMovieViewModel by viewModels() private var isInWatchList:Boolean = false + private var isFav:Boolean=false + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { setStyle(STYLE_NO_FRAME, R.style.SheetDialog) @@ -101,6 +105,24 @@ class MovieDetailsFragment : BottomSheetDialogFragment(){ isInWatchList=!isInWatchList } + fragmentMovieDetailsFavBtn.setOnClickListener(){ + + if (!isFav){ + favMovieViewModel.insertFavMovieData(movieResult) + favIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(),R.drawable.fav_red)) + showToast(requireContext(),"Movie added to Favourites") + }else{ + + favMovieViewModel.deleteWatchListData(movieResult) + favIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(),R.drawable.fav_outline)) + showToast(requireContext(),"Movie removed from Favourites") + } + + isFav=!isFav + + } + + fragmentMovieDetailsShareBtn.setOnClickListener(){ shareMovie(requireContext(),movieResult.title.toString(),youtubeUrl) } @@ -201,6 +223,22 @@ class MovieDetailsFragment : BottomSheetDialogFragment(){ } } + + favMovieViewModel.getAllMovieData().observe(viewLifecycleOwner){ + + if(it.isNotEmpty()){ + var isFav:Boolean + for (res in it){ + isFav = (res.id==mediaId) + + if(isFav){ + changeFavIcon() + break + } + } + } + + } } private fun changeAddToWatchListIcon() { @@ -210,6 +248,13 @@ class MovieDetailsFragment : BottomSheetDialogFragment(){ } } + private fun changeFavIcon(){ + binding.apply { + isFav=true + favIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(),R.drawable.fav)) + } + } + private fun initializePlayer(key: String?) { binding.posterImage.gone() binding.ytIcon.gone() diff --git a/app/src/main/java/com/example/movieflix/presentation/favorites/FavFragment.kt b/app/src/main/java/com/example/movieflix/presentation/favorites/FavFragment.kt new file mode 100644 index 0000000..e5890dd --- /dev/null +++ b/app/src/main/java/com/example/movieflix/presentation/favorites/FavFragment.kt @@ -0,0 +1,77 @@ +package com.example.movieflix.presentation.favorites + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.navigation.fragment.findNavController +import com.example.movieflix.R +import com.example.movieflix.core.adapters.FavAdapters +import com.example.movieflix.core.adapters.WatchListAdapter +import com.example.movieflix.core.utils.Constants +import com.example.movieflix.core.utils.gone +import com.example.movieflix.core.utils.visible +import com.example.movieflix.databinding.FragmentFavBinding +import com.example.movieflix.databinding.FragmentWatchListBinding +import com.example.movieflix.presentation.viewmodels.FavMovieViewModel +import com.example.movieflix.presentation.viewmodels.WatchListViewModel +import com.google.gson.Gson +import dagger.hilt.android.AndroidEntryPoint + + +@AndroidEntryPoint +class FavFragment : Fragment() { + private val favMovieViewModel:FavMovieViewModel by viewModels() + + private var _binding: FragmentFavBinding? = null + private val binding get() = _binding!! + private lateinit var adapter: FavAdapters + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + // Inflate the layout for this fragment + _binding = DataBindingUtil.inflate(inflater,R.layout.fragment_fav,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + inIt() + observer() + } + + + private fun inIt() { + favMovieViewModel.getAllMovieData() + adapter=FavAdapters (onPosterClick = { + val bundle = Bundle() + bundle.putString(Constants.MEDIA_SEND_REQUEST_KEY, Gson().toJson(it)) + findNavController().navigate(R.id.action_favFragment_to_movieDetailsFragment,bundle) + }) + + binding.fragmentFavRv.adapter=adapter + } + + private fun observer() { + favMovieViewModel.getAllMovieData().observe(viewLifecycleOwner){ + + if (it.isNotEmpty()){ + adapter.submitList(it) + binding.fragmentFavNoMovie.gone() + }else{ + binding.fragmentFavRv.gone() + binding.fragmentFavNoMovie.visible() + } + } + } + override fun onDestroy() { + super.onDestroy() + _binding=null + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/movieflix/presentation/home/HomeFragment.kt b/app/src/main/java/com/example/movieflix/presentation/home/HomeFragment.kt index 0acb30a..75084ea 100644 --- a/app/src/main/java/com/example/movieflix/presentation/home/HomeFragment.kt +++ b/app/src/main/java/com/example/movieflix/presentation/home/HomeFragment.kt @@ -74,6 +74,10 @@ binding.apply { findNavController().navigate(R.id.action_homeFragment_to_watchListFragment) } + fragmentHomeFavorite.setOnClickListener(){ + findNavController().navigate(R.id.action_homeFragment_to_favFragment) + } + fragmentHomeWatchNowBtn.setOnClickListener(){ val layoutManger=binding.fragmentHomeBannerImgRv.layoutManager as LinearLayoutManager val firstVisibleItem = layoutManger.findFirstVisibleItemPosition() diff --git a/app/src/main/java/com/example/movieflix/presentation/viewmodels/FavMovieViewModel.kt b/app/src/main/java/com/example/movieflix/presentation/viewmodels/FavMovieViewModel.kt new file mode 100644 index 0000000..985da53 --- /dev/null +++ b/app/src/main/java/com/example/movieflix/presentation/viewmodels/FavMovieViewModel.kt @@ -0,0 +1,37 @@ +package com.example.movieflix.presentation.viewmodels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.example.movieflix.data.local.entity.FavouritesEntity +import com.example.movieflix.data.local.entity.WatchListEntity +import com.example.movieflix.domain.model.MovieResult +import com.example.movieflix.domain.usecases.FavMovie +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import javax.inject.Inject + + +@HiltViewModel +class FavMovieViewModel @Inject constructor(private val favMovie: FavMovie):ViewModel() { + + fun insertFavMovieData(movieResult: MovieResult){ + val favMovieEntity = FavouritesEntity(movieResult.id!!,movieResult) + viewModelScope.launch { + favMovie.insertFavMovie(favMovieEntity) + } + } + + fun getAllMovieData(): LiveData> { + return favMovie.getAllFavMovie() + } + + fun deleteWatchListData(movieResult: MovieResult){ + val favMovieEntity = FavouritesEntity(movieResult.id!!,movieResult) + viewModelScope.launch { + favMovie.deleteFavMovie(favMovieEntity) + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/movieflix/presentation/watchlist/WatchListFragment.kt b/app/src/main/java/com/example/movieflix/presentation/watchlist/WatchListFragment.kt index d7e246a..28e0f1c 100644 --- a/app/src/main/java/com/example/movieflix/presentation/watchlist/WatchListFragment.kt +++ b/app/src/main/java/com/example/movieflix/presentation/watchlist/WatchListFragment.kt @@ -14,6 +14,7 @@ import com.example.movieflix.core.utils.Constants import com.example.movieflix.core.utils.gone import com.example.movieflix.core.utils.visible import com.example.movieflix.databinding.FragmentWatchListBinding +import com.example.movieflix.presentation.viewmodels.FavMovieViewModel import com.example.movieflix.presentation.viewmodels.WatchListViewModel import com.google.gson.Gson import dagger.hilt.android.AndroidEntryPoint diff --git a/app/src/main/res/drawable/fav_red.png b/app/src/main/res/drawable/fav_red.png new file mode 100644 index 0000000000000000000000000000000000000000..230824e455d44a7c530762699003d5a5e42e0f21 GIT binary patch literal 10569 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 T7zDod2r;(pu&vtack2HEq4%S` literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/fragment_fav.xml b/app/src/main/res/layout/fragment_fav.xml new file mode 100644 index 0000000..787cc3b --- /dev/null +++ b/app/src/main/res/layout/fragment_fav.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_movie_details.xml b/app/src/main/res/layout/fragment_movie_details.xml index 69bce18..1ffa678 100644 --- a/app/src/main/res/layout/fragment_movie_details.xml +++ b/app/src/main/res/layout/fragment_movie_details.xml @@ -253,7 +253,7 @@ diff --git a/app/src/main/res/layout/fragment_watch_list.xml b/app/src/main/res/layout/fragment_watch_list.xml index aa5d0ea..9cfde7b 100644 --- a/app/src/main/res/layout/fragment_watch_list.xml +++ b/app/src/main/res/layout/fragment_watch_list.xml @@ -62,7 +62,7 @@ android:paddingBottom="@dimen/_18sdp" android:text="Watch-List" android:textColor="@color/white" - android:textSize="@dimen/_15ssp" /> + android:textSize="@dimen/_20ssp" /> + + + + \ No newline at end of file