From 9c0861a8e4d3b469795c952d6097b2223892add1 Mon Sep 17 00:00:00 2001 From: rebelonion <87634197+rebelonion@users.noreply.github.com> Date: Sun, 17 Mar 2024 01:39:21 -0500 Subject: [PATCH] feat: character fav --- app/src/main/java/ani/dantotsu/Functions.kt | 1 - .../connections/anilist/AnilistQueries.kt | 5 +++-- .../dantotsu/connections/anilist/api/Data.kt | 4 +++- .../main/java/ani/dantotsu/media/Character.kt | 2 +- .../dantotsu/media/CharacterDetailsActivity.kt | 18 ++++++++++++++++++ .../ani/dantotsu/profile/ProfileFragment.kt | 2 +- 6 files changed, 26 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/ani/dantotsu/Functions.kt b/app/src/main/java/ani/dantotsu/Functions.kt index 65858cb5..0c1c0664 100644 --- a/app/src/main/java/ani/dantotsu/Functions.kt +++ b/app/src/main/java/ani/dantotsu/Functions.kt @@ -1182,7 +1182,6 @@ fun buildMarkwon(activity: Context, userInputContent: Boolean = true, fragment: if (resource is GifDrawable) { resource.start() } - Logger.log("Image loaded successfully: $model") return false } diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt index 16f9f51a..68f18f39 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt @@ -70,7 +70,7 @@ class AnilistQueries { media.cameFromContinue = false val query = - """{Media(id:${media.id}){id mediaListEntry{id status score(format:POINT_100) progress private notes repeat customLists updatedAt startedAt{year month day}completedAt{year month day}}isFavourite siteUrl idMal nextAiringEpisode{episode airingAt}source countryOfOrigin format duration season seasonYear startDate{year month day}endDate{year month day}genres studios(isMain:true){nodes{id name siteUrl}}description trailer { site id } synonyms tags { name rank isMediaSpoiler } characters(sort:[ROLE,FAVOURITES_DESC],perPage:25,page:1){edges{role node{id image{medium}name{userPreferred}}}}relations{edges{relationType(version:2)node{id idMal mediaListEntry{progress private score(format:POINT_100) status} episodes chapters nextAiringEpisode{episode} popularity meanScore isAdult isFavourite format title{english romaji userPreferred}type status(version:2)bannerImage coverImage{large}}}}staffPreview: staff(perPage: 8, sort: [RELEVANCE, ID]) {edges{role node{id image{large,medium} name{userPreferred}}}}recommendations(sort:RATING_DESC){nodes{mediaRecommendation{id idMal mediaListEntry{progress private score(format:POINT_100) status} episodes chapters nextAiringEpisode{episode}meanScore isAdult isFavourite format title{english romaji userPreferred}type status(version:2)bannerImage coverImage{large}}}}externalLinks{url site}}}""" + """{Media(id:${media.id}){id mediaListEntry{id status score(format:POINT_100)progress private notes repeat customLists updatedAt startedAt{year month day}completedAt{year month day}}isFavourite siteUrl idMal nextAiringEpisode{episode airingAt}source countryOfOrigin format duration season seasonYear startDate{year month day}endDate{year month day}genres studios(isMain:true){nodes{id name siteUrl}}description trailer{site id}synonyms tags{name rank isMediaSpoiler}characters(sort:[ROLE,FAVOURITES_DESC],perPage:25,page:1){edges{role node{id image{medium}name{userPreferred}isFavourite}}}relations{edges{relationType(version:2)node{id idMal mediaListEntry{progress private score(format:POINT_100)status}episodes chapters nextAiringEpisode{episode}popularity meanScore isAdult isFavourite format title{english romaji userPreferred}type status(version:2)bannerImage coverImage{large}}}}staffPreview:staff(perPage:8,sort:[RELEVANCE,ID]){edges{role node{id image{large medium}name{userPreferred}}}}recommendations(sort:RATING_DESC){nodes{mediaRecommendation{id idMal mediaListEntry{progress private score(format:POINT_100)status}episodes chapters nextAiringEpisode{episode}meanScore isAdult isFavourite format title{english romaji userPreferred}type status(version:2)bannerImage coverImage{large}}}}externalLinks{url site}}}""" runBlocking { val anilist = async { var response = executeQuery(query, force = true, show = true) @@ -127,6 +127,7 @@ class AnilistQueries { name = i.node?.name?.userPreferred, image = i.node?.image?.medium, banner = media.banner ?: media.cover, + isFav = i.node?.isFavourite ?: false, role = when (i.role.toString()) { "MAIN" -> currContext()?.getString(R.string.main_role) ?: "MAIN" @@ -1339,7 +1340,7 @@ Page(page:$page,perPage:50) { suspend fun getUserProfile(id: Int): Query.UserProfileResponse? { return executeQuery( - """{followerPage:Page{followers(userId:$id){id}pageInfo{total}}followingPage:Page{following(userId:$id){id}pageInfo{total}}user:User(id:$id){id,name,about(asHtml:true)avatar{medium,large},bannerImage,isFollowing,isFollower,isBlocked,favourites{anime{nodes{id,coverImage{extraLarge,large,medium,color}}}manga{nodes{id,coverImage{extraLarge,large,medium,color}}}characters{nodes{id,name{first,middle,last,full,native,alternative,userPreferred},image{large,medium}}}staff{nodes{id,name{first,middle,last,full,native,alternative,userPreferred},image{large,medium}}}studios{nodes{id,name}}}statistics{anime{count,meanScore,standardDeviation,minutesWatched,episodesWatched,chaptersRead,volumesRead}manga{count,meanScore,standardDeviation,minutesWatched,episodesWatched,chaptersRead,volumesRead}}siteUrl}}""", + """{followerPage:Page{followers(userId:$id){id}pageInfo{total}}followingPage:Page{following(userId:$id){id}pageInfo{total}}user:User(id:$id){id name about(asHtml:true)avatar{medium large}bannerImage isFollowing isFollower isBlocked favourites{anime{nodes{id coverImage{extraLarge large medium color}}}manga{nodes{id coverImage{extraLarge large medium color}}}characters{nodes{id name{first middle last full native alternative userPreferred}image{large medium}isFavourite}}staff{nodes{id name{first middle last full native alternative userPreferred}image{large medium}isFavourite}}studios{nodes{id name isFavourite}}}statistics{anime{count meanScore standardDeviation minutesWatched episodesWatched chaptersRead volumesRead}manga{count meanScore standardDeviation minutesWatched episodesWatched chaptersRead volumesRead}}siteUrl}}""", force = true ) } diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/api/Data.kt b/app/src/main/java/ani/dantotsu/connections/anilist/api/Data.kt index f7cc0be2..58445406 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/api/Data.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/api/Data.kt @@ -343,7 +343,9 @@ class Query { @SerialName("name") val name: CharacterName, @SerialName("image") - val image: CharacterImage + val image: CharacterImage, + @SerialName("isFavourite") + val isFavourite: Boolean ): java.io.Serializable @Serializable diff --git a/app/src/main/java/ani/dantotsu/media/Character.kt b/app/src/main/java/ani/dantotsu/media/Character.kt index 1c23ff50..e774ed30 100644 --- a/app/src/main/java/ani/dantotsu/media/Character.kt +++ b/app/src/main/java/ani/dantotsu/media/Character.kt @@ -9,7 +9,7 @@ data class Character( val image: String?, val banner: String?, val role: String, - + var isFav: Boolean, var description: String? = null, var age: String? = null, var gender: String? = null, diff --git a/app/src/main/java/ani/dantotsu/media/CharacterDetailsActivity.kt b/app/src/main/java/ani/dantotsu/media/CharacterDetailsActivity.kt index 3081f796..3a5f9180 100644 --- a/app/src/main/java/ani/dantotsu/media/CharacterDetailsActivity.kt +++ b/app/src/main/java/ani/dantotsu/media/CharacterDetailsActivity.kt @@ -16,6 +16,8 @@ import androidx.recyclerview.widget.ConcatAdapter import androidx.recyclerview.widget.GridLayoutManager import ani.dantotsu.R import ani.dantotsu.Refresh +import ani.dantotsu.connections.anilist.Anilist +import ani.dantotsu.connections.anilist.AnilistMutations import ani.dantotsu.databinding.ActivityCharacterBinding import ani.dantotsu.initActivity import ani.dantotsu.loadImage @@ -26,6 +28,7 @@ import ani.dantotsu.others.getSerialized import ani.dantotsu.px import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefName +import ani.dantotsu.snackString import ani.dantotsu.statusBarHeight import ani.dantotsu.themes.ThemeManager import com.google.android.material.appbar.AppBarLayout @@ -88,6 +91,21 @@ class CharacterDetailsActivity : AppCompatActivity(), AppBarLayout.OnOffsetChang openLinkInBrowser(link) true } + binding.characterFav.setImageResource( + if (character.isFav) R.drawable.ic_round_favorite_24 else R.drawable.ic_round_favorite_border_24 + ) + binding.characterFav.setOnClickListener { + lifecycleScope.launch { + if (Anilist.mutation.toggleFav(AnilistMutations.FavType.CHARACTER, character.id)) { + character.isFav = !character.isFav + binding.characterFav.setImageResource( + if (character.isFav) R.drawable.ic_round_favorite_24 else R.drawable.ic_round_favorite_border_24 + ) + } else { + snackString("Failed to toggle favorite") + } + } + } model.getCharacter().observe(this) { if (it != null && !loaded) { character = it diff --git a/app/src/main/java/ani/dantotsu/profile/ProfileFragment.kt b/app/src/main/java/ani/dantotsu/profile/ProfileFragment.kt index 103e93a0..c968b04d 100644 --- a/app/src/main/java/ani/dantotsu/profile/ProfileFragment.kt +++ b/app/src/main/java/ani/dantotsu/profile/ProfileFragment.kt @@ -121,7 +121,7 @@ class ProfileFragment : Fragment() { ) user.favourites?.characters?.nodes?.forEach { i -> - favCharacter.add(Character(i.id, i.name.full, i.image.large, i.image.large, "")) + favCharacter.add(Character(i.id, i.name.full, i.image.large, i.image.large, "", true)) } user.favourites?.staff?.nodes?.forEach { i ->