From ade36a3208ab5af65949297d75b3e5756ae6eb7c Mon Sep 17 00:00:00 2001 From: pauliancu97 Date: Sat, 9 Oct 2021 13:30:45 +0300 Subject: [PATCH 1/2] updated kotlin version, made AnimeDao methods be suspended functions --- build.gradle | 2 +- data/build.gradle | 2 ++ .../java/divyansh/tech/animeclassroom/database/AnimeDao.kt | 6 +++--- domain/build.gradle | 3 +++ 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 7d6b510..ecde831 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext { gradle_version="4.1.2" - kotlin_version="1.4.31" + kotlin_version="1.5.31" core_ktx="1.3.2" appcompat="1.2.0" material="1.3.0" diff --git a/data/build.gradle b/data/build.gradle index bfac8d2..ed11f18 100644 --- a/data/build.gradle +++ b/data/build.gradle @@ -70,4 +70,6 @@ dependencies { implementation "androidx.room:room-runtime:$room_version" kapt "androidx.room:room-compiler:$room_version" + annotationProcessor "androidx.room:room-compiler:$room_version" + implementation "androidx.room:room-ktx:$room_version" } \ No newline at end of file diff --git a/data/src/main/java/divyansh/tech/animeclassroom/database/AnimeDao.kt b/data/src/main/java/divyansh/tech/animeclassroom/database/AnimeDao.kt index 3bca95d..99818d8 100644 --- a/data/src/main/java/divyansh/tech/animeclassroom/database/AnimeDao.kt +++ b/data/src/main/java/divyansh/tech/animeclassroom/database/AnimeDao.kt @@ -10,11 +10,11 @@ import divyansh.tech.animeclassroom.models.home.OfflineAnimeModel @Dao interface AnimeDao { @Query("SELECT * FROM animes") - fun getAllAnimes(): List + suspend fun getAllAnimes(): List @Insert - fun insertAnime(anime: OfflineAnimeModel) + suspend fun insertAnime(anime: OfflineAnimeModel) @Delete - fun deleteAnime(anime: OfflineAnimeModel) + suspend fun deleteAnime(anime: OfflineAnimeModel) } \ No newline at end of file diff --git a/domain/build.gradle b/domain/build.gradle index f2ad020..249e93d 100644 --- a/domain/build.gradle +++ b/domain/build.gradle @@ -58,4 +58,7 @@ dependencies { implementation "androidx.room:room-runtime:$room_version" kapt "androidx.room:room-compiler:$room_version" + annotationProcessor "androidx.room:room-compiler:$room_version" + implementation "androidx.room:room-ktx:$room_version" + } \ No newline at end of file From e4011a22126fec961e4cc7682157170c447356dc Mon Sep 17 00:00:00 2001 From: pauliancu97 Date: Sat, 9 Oct 2021 20:52:59 +0300 Subject: [PATCH 2/2] fully implemented the favorites anime page --- .../favorites/FavoritesFragment.kt | 2 +- .../screens/animes/FavoriteAnimeCallbacks.kt | 19 +++++ .../screens/animes/FavoriteAnimeFragment.kt | 78 +++++++++++++++++++ .../screens/animes/FavoriteAnimeViewModel.kt | 34 ++++++++ .../epoxy/EpoxyFavoriteAnimeController.kt | 22 ++++++ .../animes/epoxy/EpoxyFavoriteAnimeModels.kt | 25 ++++++ .../favorites/utils/ViewPagerAdapter.kt | 10 +-- .../res/layout/fragment_favorite_anime.xml | 32 ++++++++ .../layout/recycler_item_favorite_anime.xml | 55 +++++++++++++ .../main/res/navigation/home_navigation.xml | 6 +- app/src/main/res/values/strings.xml | 2 +- .../favorites/FavoriteAnimeLocalRepo.kt | 3 +- 12 files changed, 278 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/FavoriteAnimeCallbacks.kt create mode 100644 app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/FavoriteAnimeFragment.kt create mode 100644 app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/FavoriteAnimeViewModel.kt create mode 100644 app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/epoxy/EpoxyFavoriteAnimeController.kt create mode 100644 app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/epoxy/EpoxyFavoriteAnimeModels.kt create mode 100644 app/src/main/res/layout/fragment_favorite_anime.xml create mode 100644 app/src/main/res/layout/recycler_item_favorite_anime.xml diff --git a/app/src/main/java/divyansh/tech/animeclassroom/favorites/FavoritesFragment.kt b/app/src/main/java/divyansh/tech/animeclassroom/favorites/FavoritesFragment.kt index cd03fdf..50a6fec 100644 --- a/app/src/main/java/divyansh/tech/animeclassroom/favorites/FavoritesFragment.kt +++ b/app/src/main/java/divyansh/tech/animeclassroom/favorites/FavoritesFragment.kt @@ -62,7 +62,7 @@ class FavoritesFragment: Fragment() { if (mediator != null) mediator!!.detach() pagerAdapter.removeAllFragments() - pagerAdapter.addFragments(tabNames) + pagerAdapter.addFragments() binding.viewPager2.offscreenPageLimit = pagerAdapter.itemCount val tabs = mutableListOf().apply { diff --git a/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/FavoriteAnimeCallbacks.kt b/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/FavoriteAnimeCallbacks.kt new file mode 100644 index 0000000..6c2b0a2 --- /dev/null +++ b/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/FavoriteAnimeCallbacks.kt @@ -0,0 +1,19 @@ +package divyansh.tech.animeclassroom.favorites.screens.animes + +import divyansh.tech.animeclassroom.common.AnimeClickCallback +import divyansh.tech.animeclassroom.common.CommonViewModel +import divyansh.tech.animeclassroom.favorites.FavoritesFragmentDirections + +class FavoriteAnimeCallbacks(private val viewModel: CommonViewModel) : AnimeClickCallback { + override fun onAnimeClicked(animeUrl: String) { + viewModel.changeNavigation( + FavoritesFragmentDirections.actionFavoritesFragmentToAnimeDetailFragment( + animeUrl = animeUrl + ) + ) + } + + override fun onEpisodeClicked(episodeUrl: String) {} + + override fun onGenreClicked(genreUrl: String) {} +} \ No newline at end of file diff --git a/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/FavoriteAnimeFragment.kt b/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/FavoriteAnimeFragment.kt new file mode 100644 index 0000000..9e192c8 --- /dev/null +++ b/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/FavoriteAnimeFragment.kt @@ -0,0 +1,78 @@ +package divyansh.tech.animeclassroom.favorites.screens.animes + +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.navigation.fragment.findNavController +import androidx.recyclerview.widget.GridLayoutManager +import dagger.hilt.android.AndroidEntryPoint +import divyansh.tech.animeclassroom.EventObserver +import divyansh.tech.animeclassroom.ResultWrapper +import divyansh.tech.animeclassroom.databinding.FragmentFavoriteAnimeBinding +import divyansh.tech.animeclassroom.favorites.screens.animes.epoxy.EpoxyFavoriteAnimeController + +@AndroidEntryPoint +class FavoriteAnimeFragment : Fragment() { + + companion object { + fun getInstance() = FavoriteAnimeFragment() + } + + private lateinit var _favoriteAnimeFragmentBinding: FragmentFavoriteAnimeBinding + private val binding: FragmentFavoriteAnimeBinding + get() = _favoriteAnimeFragmentBinding + + private val viewModel by viewModels() + + private val favoriteAnimeController: EpoxyFavoriteAnimeController by lazy { + EpoxyFavoriteAnimeController(FavoriteAnimeCallbacks(viewModel)) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _favoriteAnimeFragmentBinding = FragmentFavoriteAnimeBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupRecyclerView() + setupObservers() + } + + private fun setupObservers() { + viewModel.favoriteAnimeListState.observe(viewLifecycleOwner) { result -> + when (result) { + is ResultWrapper.Success -> { + result.data?.let { + binding.noAnimeText.visibility = if (it.isEmpty()) View.VISIBLE else View.GONE + favoriteAnimeController.setData(it) + } + } + is ResultWrapper.Error -> Log.i("FAVORITES", result.message.toString()) + is ResultWrapper.Loading -> {} + } + + } + viewModel.navigation.observe( + viewLifecycleOwner, + EventObserver { + findNavController().navigate(it) + } + ) + } + + private fun setupRecyclerView() { + with(binding.favoriteAnimeList) { + layoutManager = GridLayoutManager(requireContext(), 3) + adapter = favoriteAnimeController.adapter + } + } +} \ No newline at end of file diff --git a/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/FavoriteAnimeViewModel.kt b/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/FavoriteAnimeViewModel.kt new file mode 100644 index 0000000..c257c79 --- /dev/null +++ b/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/FavoriteAnimeViewModel.kt @@ -0,0 +1,34 @@ +package divyansh.tech.animeclassroom.favorites.screens.animes + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.viewModelScope +import dagger.hilt.android.lifecycle.HiltViewModel +import divyansh.tech.animeclassroom.ResultWrapper +import divyansh.tech.animeclassroom.common.CommonViewModel +import divyansh.tech.animeclassroom.di.DispatcherModule +import divyansh.tech.animeclassroom.favorites.FavoriteAnimeLocalRepo +import divyansh.tech.animeclassroom.models.home.OfflineAnimeModel +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class FavoriteAnimeViewModel @Inject constructor( + favoriteAnimeLocalRepo: FavoriteAnimeLocalRepo, + @DispatcherModule.IODispatcher coroutineDispatcher: CoroutineDispatcher +): CommonViewModel() { + + private val _favoriteAnimeListState: MutableLiveData>> = + MutableLiveData() + val favoriteAnimeListState: LiveData>> = _favoriteAnimeListState + + init { + viewModelScope.launch(coroutineDispatcher) { + _favoriteAnimeListState.postValue(ResultWrapper.Loading()) + _favoriteAnimeListState.postValue( + ResultWrapper.Success(favoriteAnimeLocalRepo.getAllAnime()) + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/epoxy/EpoxyFavoriteAnimeController.kt b/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/epoxy/EpoxyFavoriteAnimeController.kt new file mode 100644 index 0000000..d7b7d92 --- /dev/null +++ b/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/epoxy/EpoxyFavoriteAnimeController.kt @@ -0,0 +1,22 @@ +package divyansh.tech.animeclassroom.favorites.screens.animes.epoxy + +import com.airbnb.epoxy.TypedEpoxyController +import divyansh.tech.animeclassroom.common.AnimeClickCallback +import divyansh.tech.animeclassroom.models.home.OfflineAnimeModel + +class EpoxyFavoriteAnimeController( + private val animeClickCallback: AnimeClickCallback +) : TypedEpoxyController>() { + + override fun buildModels(data: List?) { + data?.let { offlineAnimeModels -> + offlineAnimeModels.forEach { + epoxyFavoriteAnime { + id(it.animeUrl) + anime(it) + animeCallback(animeClickCallback) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/epoxy/EpoxyFavoriteAnimeModels.kt b/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/epoxy/EpoxyFavoriteAnimeModels.kt new file mode 100644 index 0000000..7c6ee0e --- /dev/null +++ b/app/src/main/java/divyansh/tech/animeclassroom/favorites/screens/animes/epoxy/EpoxyFavoriteAnimeModels.kt @@ -0,0 +1,25 @@ +package divyansh.tech.animeclassroom.favorites.screens.animes.epoxy + +import androidx.databinding.ViewDataBinding +import com.airbnb.epoxy.DataBindingEpoxyModel +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import divyansh.tech.animeclassroom.BR +import divyansh.tech.animeclassroom.R +import divyansh.tech.animeclassroom.common.AnimeClickCallback +import divyansh.tech.animeclassroom.models.home.OfflineAnimeModel + +@EpoxyModelClass(layout = R.layout.recycler_item_favorite_anime) +abstract class EpoxyFavoriteAnimeModel : DataBindingEpoxyModel() { + + @EpoxyAttribute + lateinit var anime: OfflineAnimeModel + + @EpoxyAttribute + lateinit var animeCallback: AnimeClickCallback + + override fun setDataBindingVariables(binding: ViewDataBinding) { + binding.setVariable(BR.anime, anime) + binding.setVariable(BR.animeCallback, animeCallback) + } +} \ No newline at end of file diff --git a/app/src/main/java/divyansh/tech/animeclassroom/favorites/utils/ViewPagerAdapter.kt b/app/src/main/java/divyansh/tech/animeclassroom/favorites/utils/ViewPagerAdapter.kt index 84bdaa3..51c9219 100644 --- a/app/src/main/java/divyansh/tech/animeclassroom/favorites/utils/ViewPagerAdapter.kt +++ b/app/src/main/java/divyansh/tech/animeclassroom/favorites/utils/ViewPagerAdapter.kt @@ -5,6 +5,7 @@ import androidx.fragment.app.FragmentManager import androidx.lifecycle.Lifecycle import androidx.viewpager2.adapter.FragmentStateAdapter import divyansh.tech.animeclassroom.favorites.screens.DynamicTabFragment +import divyansh.tech.animeclassroom.favorites.screens.animes.FavoriteAnimeFragment class ViewPagerAdapter(private val list: MutableList = mutableListOf(), @@ -22,13 +23,10 @@ class ViewPagerAdapter(private val list: MutableList = mutableListOf() return list[position] } - fun addFragments(ls:List){ + fun addFragments(){ pageIds.clear() - ls.forEach { - category -> - list.add(DynamicTabFragment.getInstance(category)) - } - + list.add(FavoriteAnimeFragment.getInstance()) + list.add(DynamicTabFragment.getInstance("Mangas")) pageIds.addAll(list.map { it.hashCode().toLong() }) notifyDataSetChanged() } diff --git a/app/src/main/res/layout/fragment_favorite_anime.xml b/app/src/main/res/layout/fragment_favorite_anime.xml new file mode 100644 index 0000000..03c2980 --- /dev/null +++ b/app/src/main/res/layout/fragment_favorite_anime.xml @@ -0,0 +1,32 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/recycler_item_favorite_anime.xml b/app/src/main/res/layout/recycler_item_favorite_anime.xml new file mode 100644 index 0000000..f3c69f8 --- /dev/null +++ b/app/src/main/res/layout/recycler_item_favorite_anime.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/home_navigation.xml b/app/src/main/res/navigation/home_navigation.xml index ce759a7..851fd26 100644 --- a/app/src/main/res/navigation/home_navigation.xml +++ b/app/src/main/res/navigation/home_navigation.xml @@ -60,7 +60,11 @@ + android:label="FavoritesFragment" > + + Night Mode System - + Empty Favorite Animes List \ No newline at end of file diff --git a/domain/src/main/java/divyansh/tech/animeclassroom/favorites/FavoriteAnimeLocalRepo.kt b/domain/src/main/java/divyansh/tech/animeclassroom/favorites/FavoriteAnimeLocalRepo.kt index 62f8978..ff09cc0 100644 --- a/domain/src/main/java/divyansh/tech/animeclassroom/favorites/FavoriteAnimeLocalRepo.kt +++ b/domain/src/main/java/divyansh/tech/animeclassroom/favorites/FavoriteAnimeLocalRepo.kt @@ -20,8 +20,9 @@ class FavoriteAnimeLocalRepo @Inject constructor( dao.insertAnime(model) } - suspend fun getAllAnime() { + suspend fun getAllAnime(): List { val list = dao.getAllAnimes() Log.i("ROOM REPO -> ", list.toString()) + return list } } \ No newline at end of file