feat: more options in anime and manga side

This commit is contained in:
aayush262 2024-03-30 02:39:47 +05:30
parent 7951c2cf37
commit 2dc3035a7c
18 changed files with 657 additions and 53 deletions

View file

@ -1022,7 +1022,49 @@ query (${"$"}page: Int = 1, ${"$"}id: Int, ${"$"}type: MediaType, ${"$"}isAdult:
}
return null
}
private fun trendingMovie(): String{
return """Page(page:1,perPage:50){pageInfo{hasNextPage total}media(sort:POPULARITY_DESC, type: ANIME, format: MOVIE, onList:${PrefManager.getVal<Boolean>(PrefName.IncludeAnimeList)}){id idMal status chapters episodes nextAiringEpisode{episode}isAdult type meanScore isFavourite format bannerImage countryOfOrigin coverImage{large}title{english romaji userPreferred}mediaListEntry{progress private score(format:POINT_100)status}}}"""
}
private fun topRatedAnime(): String{
return """Page(page:1,perPage:50){pageInfo{hasNextPage total}media(sort: SCORE_DESC, type: ANIME,onList:${PrefManager.getVal<Boolean>(PrefName.IncludeAnimeList)}){id idMal status chapters episodes nextAiringEpisode{episode}isAdult type meanScore isFavourite format bannerImage countryOfOrigin coverImage{large}title{english romaji userPreferred}mediaListEntry{progress private score(format:POINT_100)status}}}"""
}
private fun mostFavAnime(): String{
return """Page(page:1,perPage:50){pageInfo{hasNextPage total}media(sort:FAVOURITES_DESC,type: ANIME,onList:${PrefManager.getVal<Boolean>(PrefName.IncludeAnimeList)}){id idMal status chapters episodes nextAiringEpisode{episode}isAdult type meanScore isFavourite format bannerImage countryOfOrigin coverImage{large}title{english romaji userPreferred}mediaListEntry{progress private score(format:POINT_100)status}}}"""
}
suspend fun loadAnimeList(): Query.AnimeList?{
return executeQuery<Query.AnimeList>(
"""{
trendingMovie:${trendingMovie()}
topRated:${topRatedAnime()}
mostFav:${mostFavAnime()}
}""".trimIndent(), force = true
)
}
private fun trendingManga(): String{
return """Page(page:1,perPage:50){pageInfo{hasNextPage total}media(sort:POPULARITY_DESC, type: MANGA, onList:${PrefManager.getVal<Boolean>(PrefName.IncludeMangaList)}){id idMal status chapters episodes nextAiringEpisode{episode}isAdult type meanScore isFavourite format bannerImage countryOfOrigin coverImage{large}title{english romaji userPreferred}mediaListEntry{progress private score(format:POINT_100)status}}}"""
}
private fun trendingManhwa(): String{
return """Page(page:1,perPage:50){pageInfo{hasNextPage total}media(sort:POPULARITY_DESC, type: MANGA, countryOfOrigin:KR onList:${PrefManager.getVal<Boolean>(PrefName.IncludeMangaList)}){id idMal status chapters episodes nextAiringEpisode{episode}isAdult type meanScore isFavourite format bannerImage countryOfOrigin coverImage{large}title{english romaji userPreferred}mediaListEntry{progress private score(format:POINT_100)status}}}"""
}
private fun topRatedManga(): String{
return """Page(page:1,perPage:50){pageInfo{hasNextPage total}media(sort: SCORE_DESC, type: MANGA,onList:${PrefManager.getVal<Boolean>(PrefName.IncludeMangaList)}){id idMal status chapters episodes nextAiringEpisode{episode}isAdult type meanScore isFavourite format bannerImage countryOfOrigin coverImage{large}title{english romaji userPreferred}mediaListEntry{progress private score(format:POINT_100)status}}}"""
}
private fun mostFavManga(): String{
return """Page(page:1,perPage:50){pageInfo{hasNextPage total}media(sort:FAVOURITES_DESC,type: MANGA,onList:${PrefManager.getVal<Boolean>(PrefName.IncludeMangaList)}){id idMal status chapters episodes nextAiringEpisode{episode}isAdult type meanScore isFavourite format bannerImage countryOfOrigin coverImage{large}title{english romaji userPreferred}mediaListEntry{progress private score(format:POINT_100)status}}}"""
}
suspend fun loadMangaList(): Query.MangaList?{
return executeQuery<Query.MangaList>(
"""{
trendingManga:${trendingManga()}
trendingManhwa:${trendingManhwa()}
topRated:${topRatedManga()}
mostFav:${mostFavManga()}
}""".trimIndent(), force = true
)
}
suspend fun recentlyUpdated(
smaller: Boolean = true,
greater: Long = 0,

View file

@ -156,6 +156,7 @@ class AnilistAnimeViewModel : ViewModel() {
suspend fun loadUpdated() = updated.postValue(Anilist.query.recentlyUpdated())
private val animePopular = MutableLiveData<SearchResults?>(null)
fun getPopular(): LiveData<SearchResults?> = animePopular
suspend fun loadPopular(
type: String,
@ -192,6 +193,30 @@ class AnilistAnimeViewModel : ViewModel() {
)
var loaded: Boolean = false
private val popularMovies: MutableLiveData<MutableList<Media>> =
MutableLiveData<MutableList<Media>>(null)
fun getMovies(): LiveData<MutableList<Media>> = popularMovies
private val topRated: MutableLiveData<MutableList<Media>> =
MutableLiveData<MutableList<Media>>(null)
fun getTopRated(): LiveData<MutableList<Media>> = topRated
private val mostFav: MutableLiveData<MutableList<Media>> =
MutableLiveData<MutableList<Media>>(null)
fun getMostFav(): LiveData<MutableList<Media>> = mostFav
suspend fun loadAll() {
val response = Anilist.query.loadAnimeList()
val trendingMovie = response?.data?.trendingMovie?.media?.map { Media(it) }?.toMutableList()
popularMovies.postValue(trendingMovie ?: arrayListOf())
val topRatedList = response?.data?.topRated?.media?.map { Media(it) }?.toMutableList()
topRated.postValue(topRatedList ?: arrayListOf())
val mostFavList = response?.data?.mostFav?.media?.map { Media(it) }?.toMutableList()
mostFav.postValue(mostFavList ?: arrayListOf())
}
}
class AnilistMangaViewModel : ViewModel() {
@ -268,6 +293,37 @@ class AnilistMangaViewModel : ViewModel() {
)
var loaded: Boolean = false
private val popularManga: MutableLiveData<MutableList<Media>> =
MutableLiveData<MutableList<Media>>(null)
fun getPopularManga(): LiveData<MutableList<Media>> = popularManga
private val popularManhwa: MutableLiveData<MutableList<Media>> =
MutableLiveData<MutableList<Media>>(null)
fun getPopularManhwa(): LiveData<MutableList<Media>> = popularManhwa
private val topRated: MutableLiveData<MutableList<Media>> =
MutableLiveData<MutableList<Media>>(null)
fun getTopRated(): LiveData<MutableList<Media>> = topRated
private val mostFav: MutableLiveData<MutableList<Media>> =
MutableLiveData<MutableList<Media>>(null)
fun getMostFav(): LiveData<MutableList<Media>> = mostFav
suspend fun loadAll() {
val response = Anilist.query.loadMangaList()
val trendingManga = response?.data?.trendingManga?.media?.map { Media(it) }?.toMutableList()
popularManga.postValue(trendingManga ?: arrayListOf())
val trendingManhwa = response?.data?.trendingManhwa?.media?.map { Media(it) }?.toMutableList()
popularManhwa.postValue(trendingManhwa ?: arrayListOf())
val topRatedList = response?.data?.topRated?.media?.map { Media(it) }?.toMutableList()
topRated.postValue(topRatedList ?: arrayListOf())
val mostFavList = response?.data?.mostFav?.media?.map { Media(it) }?.toMutableList()
mostFav.postValue(mostFavList ?: arrayListOf())
}
}
class AnilistSearch : ViewModel() {

View file

@ -152,7 +152,31 @@ class Query {
@SerialName("mangaMediaList") val mangaMediaList: ani.dantotsu.connections.anilist.api.MediaListCollection?
)
}
@Serializable
data class AnimeList(
@SerialName("data")
val data: Data?
) {
@Serializable
data class Data(
@SerialName("trendingMovie") val trendingMovie: ani.dantotsu.connections.anilist.api.Page?,
@SerialName("topRated") val topRated: ani.dantotsu.connections.anilist.api.Page?,
@SerialName("mostFav") val mostFav: ani.dantotsu.connections.anilist.api.Page?,
)
}
@Serializable
data class MangaList(
@SerialName("data")
val data: Data?
) {
@Serializable
data class Data(
@SerialName("trendingManga") val trendingManga: ani.dantotsu.connections.anilist.api.Page?,
@SerialName("trendingManhwa") val trendingManhwa: ani.dantotsu.connections.anilist.api.Page?,
@SerialName("topRated") val topRated: ani.dantotsu.connections.anilist.api.Page?,
@SerialName("mostFav") val mostFav: ani.dantotsu.connections.anilist.api.Page?,
)
}
@Serializable
data class ToggleFollow(
@SerialName("data")

View file

@ -207,6 +207,21 @@ class AnimeFragment : Fragment() {
animePageAdapter.updateRecent(MediaAdaptor(0, it, requireActivity()))
}
}
model.getMovies().observe(viewLifecycleOwner) {
if (it != null) {
animePageAdapter.updateMovies(MediaAdaptor(0, it, requireActivity()))
}
}
model.getTopRated().observe(viewLifecycleOwner) {
if (it != null) {
animePageAdapter.updateTopRated(MediaAdaptor(0, it, requireActivity()))
}
}
model.getMostFav().observe(viewLifecycleOwner) {
if (it != null) {
animePageAdapter.updateMostFav(MediaAdaptor(0, it, requireActivity()))
}
}
if (animePageAdapter.trendingViewPager != null) {
animePageAdapter.updateHeight()
model.getTrending().observe(viewLifecycleOwner) {
@ -264,6 +279,7 @@ class AnimeFragment : Fragment() {
model.loaded = true
model.loadTrending(1)
model.loadUpdated()
model.loadAll()
model.loadPopular(
"ANIME", sort = Anilist.sortBy[1], onList = PrefManager.getVal(
PrefName.PopularAnimeList

View file

@ -212,7 +212,55 @@ class AnimePageAdapter : RecyclerView.Adapter<AnimePageAdapter.AnimePageViewHold
binding.animePopular.visibility = View.VISIBLE
binding.animePopular.startAnimation(setSlideUp())
}
fun updateMovies(adaptor: MediaAdaptor) {
binding.animeMoviesProgressBar.visibility = View.GONE
binding.animeMoviesRecyclerView.adapter = adaptor
binding.animeMoviesRecyclerView.layoutManager =
LinearLayoutManager(
binding.animeMoviesRecyclerView.context,
LinearLayoutManager.HORIZONTAL,
false
)
binding.animeMoviesRecyclerView.visibility = View.VISIBLE
binding.animeMovies.visibility = View.VISIBLE
binding.animeMovies.startAnimation(setSlideUp())
binding.animeMoviesRecyclerView.layoutAnimation =
LayoutAnimationController(setSlideIn(), 0.25f)
}
fun updateTopRated(adaptor: MediaAdaptor) {
binding.animeTopRatedProgressBar.visibility = View.GONE
binding.animeTopRatedRecyclerView.adapter = adaptor
binding.animeTopRatedRecyclerView.layoutManager =
LinearLayoutManager(
binding.animeTopRatedRecyclerView.context,
LinearLayoutManager.HORIZONTAL,
false
)
binding.animeTopRatedRecyclerView.visibility = View.VISIBLE
binding.animeTopRated.visibility = View.VISIBLE
binding.animeTopRated.startAnimation(setSlideUp())
binding.animeTopRatedRecyclerView.layoutAnimation =
LayoutAnimationController(setSlideIn(), 0.25f)
}
fun updateMostFav(adaptor: MediaAdaptor) {
binding.animeMostFavProgressBar.visibility = View.GONE
binding.animeMostFavRecyclerView.adapter = adaptor
binding.animeMostFavRecyclerView.layoutManager =
LinearLayoutManager(
binding.animeMostFavRecyclerView.context,
LinearLayoutManager.HORIZONTAL,
false
)
binding.animeMostFavRecyclerView.visibility = View.VISIBLE
binding.animeMostFav.visibility = View.VISIBLE
binding.animeMostFav.startAnimation(setSlideUp())
binding.animeMostFavRecyclerView.layoutAnimation =
LayoutAnimationController(setSlideIn(), 0.25f)
}
fun updateAvatar() {
if (Anilist.avatar != null && ready.value == true) {
trendingBinding.userAvatar.loadImage(Anilist.avatar)

View file

@ -165,6 +165,26 @@ class MangaFragment : Fragment() {
mangaPageAdapter.updateNovel(MediaAdaptor(0, it, requireActivity()))
}
}
model.getPopularManga().observe(viewLifecycleOwner) {
if (it != null) {
mangaPageAdapter.updateTrendingManga(MediaAdaptor(0, it, requireActivity()))
}
}
model.getPopularManhwa().observe(viewLifecycleOwner) {
if (it != null) {
mangaPageAdapter.updateTrendingManhwa(MediaAdaptor(0, it, requireActivity()))
}
}
model.getTopRated().observe(viewLifecycleOwner) {
if (it != null) {
mangaPageAdapter.updateTopRated(MediaAdaptor(0, it, requireActivity()))
}
}
model.getMostFav().observe(viewLifecycleOwner) {
if (it != null) {
mangaPageAdapter.updateMostFav(MediaAdaptor(0, it, requireActivity()))
}
}
if (mangaPageAdapter.trendingViewPager != null) {
mangaPageAdapter.updateHeight()
model.getTrending().observe(viewLifecycleOwner) {
@ -238,6 +258,7 @@ class MangaFragment : Fragment() {
model.loaded = true
model.loadTrending()
model.loadTrendingNovel()
model.loadAll()
model.loadPopular(
"MANGA", sort = Anilist.sortBy[1], onList = PrefManager.getVal(
PrefName.PopularMangaList

View file

@ -180,6 +180,70 @@ class MangaPageAdapter : RecyclerView.Adapter<MangaPageAdapter.MangaPageViewHold
LayoutAnimationController(setSlideIn(), 0.25f)
}
fun updateTrendingManga(adaptor: MediaAdaptor) {
binding.mangaTrendingMangaProgressBar.visibility = View.GONE
binding.mangaTrendingMangaRecyclerView.adapter = adaptor
binding.mangaTrendingMangaRecyclerView.layoutManager =
LinearLayoutManager(
binding.mangaTrendingMangaRecyclerView.context,
LinearLayoutManager.HORIZONTAL,
false
)
binding.mangaTrendingMangaRecyclerView.visibility = View.VISIBLE
binding.mangaTrendingManga.visibility = View.VISIBLE
binding.mangaTrendingManga.startAnimation(setSlideUp())
binding.mangaTrendingMangaRecyclerView.layoutAnimation =
LayoutAnimationController(setSlideIn(), 0.25f)
}
fun updateTrendingManhwa(adaptor: MediaAdaptor) {
binding.mangaTrendingManhwaProgressBar.visibility = View.GONE
binding.mangaTrendingManhwaRecyclerView.adapter = adaptor
binding.mangaTrendingManhwaRecyclerView.layoutManager =
LinearLayoutManager(
binding.mangaNovelRecyclerView.context,
LinearLayoutManager.HORIZONTAL,
false
)
binding.mangaTrendingManhwaRecyclerView.visibility = View.VISIBLE
binding.mangaTrendingManhwa.visibility = View.VISIBLE
binding.mangaTrendingManhwa.startAnimation(setSlideUp())
binding.mangaTrendingManhwaRecyclerView.layoutAnimation =
LayoutAnimationController(setSlideIn(), 0.25f)
}
fun updateTopRated(adaptor: MediaAdaptor) {
binding.mangaTopRatedProgressBar.visibility = View.GONE
binding.mangaTopRatedRecyclerView.adapter = adaptor
binding.mangaTopRatedRecyclerView.layoutManager =
LinearLayoutManager(
binding.mangaTopRatedRecyclerView.context,
LinearLayoutManager.HORIZONTAL,
false
)
binding.mangaTopRatedRecyclerView.visibility = View.VISIBLE
binding.mangaTopRated.visibility = View.VISIBLE
binding.mangaTopRated.startAnimation(setSlideUp())
binding.mangaTopRatedRecyclerView.layoutAnimation =
LayoutAnimationController(setSlideIn(), 0.25f)
}
fun updateMostFav(adaptor: MediaAdaptor) {
binding.mangaMostFavProgressBar.visibility = View.GONE
binding.mangaMostFavRecyclerView.adapter = adaptor
binding.mangaMostFavRecyclerView.layoutManager =
LinearLayoutManager(
binding.mangaMostFavRecyclerView.context,
LinearLayoutManager.HORIZONTAL,
false
)
binding.mangaMostFavRecyclerView.visibility = View.VISIBLE
binding.mangaMostFav.visibility = View.VISIBLE
binding.mangaMostFav.startAnimation(setSlideUp())
binding.mangaMostFavRecyclerView.layoutAnimation =
LayoutAnimationController(setSlideIn(), 0.25f)
}
fun updateNovel(adaptor: MediaAdaptor) {
binding.mangaNovelProgressBar.visibility = View.GONE
binding.mangaNovelRecyclerView.adapter = adaptor
@ -195,8 +259,6 @@ class MangaPageAdapter : RecyclerView.Adapter<MangaPageAdapter.MangaPageViewHold
binding.mangaNovel.startAnimation(setSlideUp())
binding.mangaNovelRecyclerView.layoutAnimation =
LayoutAnimationController(setSlideIn(), 0.25f)
binding.mangaPopular.visibility = View.VISIBLE
binding.mangaPopular.startAnimation(setSlideUp())
}
fun updateAvatar() {

View file

@ -52,7 +52,7 @@ class AnimeWatchAdapter(
private val fragment: AnimeWatchFragment,
private val watchSources: WatchSources
) : RecyclerView.Adapter<AnimeWatchAdapter.ViewHolder>() {
private var autoSelect = true
var subscribe: MediaDetailsActivity.PopImageButton? = null
private var _binding: ItemAnimeWatchBinding? = null
@ -437,7 +437,8 @@ class AnimeWatchAdapter(
val sourceFound = media.anime.episodes!!.isNotEmpty()
binding.animeSourceNotFound.isGone = sourceFound
binding.faqbutton.isGone = sourceFound
if (!sourceFound && PrefManager.getVal(PrefName.SearchSources)) {
if (!sourceFound && PrefManager.getVal(PrefName.SearchSources) && autoSelect) {
if (binding.animeSource.adapter.count > media.selected!!.sourceIndex + 1) {
val nextIndex = media.selected!!.sourceIndex + 1
binding.animeSource.setText(binding.animeSource.adapter
@ -453,6 +454,7 @@ class AnimeWatchAdapter(
fragment.loadEpisodes(nextIndex, false)
}
}
binding.animeSource.setOnClickListener { autoSelect = false }
} else {
binding.animeSourceContinue.visibility = View.GONE
binding.animeSourceNotFound.visibility = View.GONE

View file

@ -55,12 +55,12 @@ class FeedFragment : Fragment() {
if (userId == -1) userId = null
global = arguments?.getBoolean("global", false) ?: false
val navBar = if (userId != null)
(activity as ProfileActivity).navBar
else
(activity as FeedActivity).navBar
val navBar = if (userId != null) {
(activity as ProfileActivity).navBar
}else{
(activity as FeedActivity).navBar
}
binding.listRecyclerView.setBaseline(navBar)
binding.listRecyclerView.adapter = adapter
binding.listRecyclerView.layoutManager =
LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
@ -72,10 +72,11 @@ class FeedFragment : Fragment() {
super.onResume()
if (this::binding.isInitialized) {
binding.root.requestLayout()
val navBar = if (userId != null)
val navBar = if (userId != null) {
(activity as ProfileActivity).navBar
else
}else{
(activity as FeedActivity).navBar
}
binding.listRecyclerView.setBaseline(navBar)
if (!loadedFirstTime) {
activity.lifecycleScope.launch(Dispatchers.IO) {

View file

@ -454,7 +454,10 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
settingsShowYt.setOnCheckedChangeListener { _, isChecked ->
PrefManager.setVal(PrefName.ShowYtButton, isChecked)
}
settingsIncludeAnimeList.isChecked = PrefManager.getVal(PrefName.IncludeAnimeList)
settingsIncludeAnimeList.setOnCheckedChangeListener { _, isChecked ->
PrefManager.setVal(PrefName.IncludeAnimeList, isChecked)
}
var previousEp: View = when (PrefManager.getVal<Int>(PrefName.AnimeDefaultView)) {
0 -> settingsEpList
1 -> settingsEpGrid
@ -541,6 +544,11 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
settingsChpCompact.setOnClickListener {
uiChp(1, it)
}
settingsIncludeMangaList.isChecked = PrefManager.getVal(PrefName.IncludeMangaList)
settingsIncludeMangaList.setOnCheckedChangeListener { _, isChecked ->
PrefManager.setVal(PrefName.IncludeMangaList, isChecked)
}
}
bindingExtensions = ActivitySettingsExtensionsBinding.bind(binding.root).apply {

View file

@ -77,6 +77,8 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
MangaListSortOrder(Pref(Location.UI, String::class, "score")),
CommentSortOrder(Pref(Location.UI, String::class, "newest")),
FollowerLayout(Pref(Location.UI, Int::class, 0)),
IncludeAnimeList(Pref(Location.UI, Boolean::class, true)),
IncludeMangaList(Pref(Location.UI, Boolean::class, true)),
//Player
DefaultSpeed(Pref(Location.Player, Int::class, 5)),

View file

@ -140,13 +140,13 @@ class ProfileStatsWidget : AppWidgetProvider() {
)
)
setTextColor(R.id.userLabel, titleTextColor)
setTextColor(R.id.topLeftItem, statsTextColor)
setTextColor(R.id.topLeftItem, titleTextColor)
setTextColor(R.id.topLeftLabel, statsTextColor)
setTextColor(R.id.topRightItem, statsTextColor)
setTextColor(R.id.topRightItem, titleTextColor)
setTextColor(R.id.topRightLabel, statsTextColor)
setTextColor(R.id.bottomLeftItem, statsTextColor)
setTextColor(R.id.bottomLeftItem, titleTextColor)
setTextColor(R.id.bottomLeftLabel, statsTextColor)
setTextColor(R.id.bottomRightItem, statsTextColor)
setTextColor(R.id.bottomRightItem, titleTextColor)
setTextColor(R.id.bottomRightLabel, statsTextColor)
setImageViewBitmap(