From 63c3058f5b0e580211f63fb3ab744961fd2fe973 Mon Sep 17 00:00:00 2001 From: aayush262 Date: Fri, 5 Apr 2024 13:20:24 +0530 Subject: [PATCH] feat: voiceActor's characters info --- .../connections/anilist/AnilistQueries.kt | 45 ++++++++++ .../connections/anilist/api/Character.kt | 2 +- .../main/java/ani/dantotsu/media/Author.kt | 11 +-- .../java/ani/dantotsu/media/AuthorActivity.kt | 82 +++++++++++-------- .../java/ani/dantotsu/media/AuthorAdapter.kt | 5 +- .../dantotsu/media/CharacterDetailsAdapter.kt | 6 +- .../dantotsu/media/OtherDetailsViewModel.kt | 7 +- .../res/layout/item_character_details.xml | 4 +- 8 files changed, 117 insertions(+), 45 deletions(-) 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 928ea4b3..fa4a3090 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt @@ -1387,7 +1387,52 @@ Page(page:$page,perPage:50) { author.yearMedia = yearMedia return author } + suspend fun getVoiceActorsDetails(author: Author): Author { + fun query(page: Int = 0) = """ { + Staff(id:${author.id}) { + id + characters(page: $page,sort:FAVOURITES_DESC) { + pageInfo{ + hasNextPage + } + nodes{ + id + name { + first + middle + last + full + native + userPreferred + } + image { + large + medium + } + + } + } + } +}""".replace("\n", " ").replace(""" """, "") + var hasNextPage = true + var page = 0 + val characters = arrayListOf() + while (hasNextPage) { + page++ + hasNextPage = executeQuery( + query(page), + force = true + )?.data?.author?.characters?.let { + it.nodes?.forEach { i -> + characters.add(Character(i.id, i.name?.userPreferred, i.image?.large, i.image?.medium, "", false)) + } + it.pageInfo?.hasNextPage == true + } ?: false + } + author.character = characters + return author + } suspend fun toggleFollow(id: Int): Query.ToggleFollow? { return executeQuery( """mutation{ToggleFollow(userId:$id){id, isFollowing, isFollower}}""" diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/api/Character.kt b/app/src/main/java/ani/dantotsu/connections/anilist/api/Character.kt index 6f6a7db8..ec5a9ef4 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/api/Character.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/api/Character.kt @@ -55,7 +55,7 @@ data class CharacterConnection( @SerialName("nodes") var nodes: List?, // The pagination information - // @SerialName("pageInfo") var pageInfo: PageInfo?, + @SerialName("pageInfo") var pageInfo: PageInfo?, ) : java.io.Serializable @Serializable diff --git a/app/src/main/java/ani/dantotsu/media/Author.kt b/app/src/main/java/ani/dantotsu/media/Author.kt index 9ab3c169..803ef989 100644 --- a/app/src/main/java/ani/dantotsu/media/Author.kt +++ b/app/src/main/java/ani/dantotsu/media/Author.kt @@ -3,9 +3,10 @@ package ani.dantotsu.media import java.io.Serializable data class Author( - val id: Int, - val name: String?, - val image: String?, - val role: String?, - var yearMedia: MutableMap>? = null + var id: Int, + var name: String?, + var image: String?, + var role: String?, + var yearMedia: MutableMap>? = null, + var character: ArrayList? = null ) : Serializable diff --git a/app/src/main/java/ani/dantotsu/media/AuthorActivity.kt b/app/src/main/java/ani/dantotsu/media/AuthorActivity.kt index 22bc54f1..6c5ee146 100644 --- a/app/src/main/java/ani/dantotsu/media/AuthorActivity.kt +++ b/app/src/main/java/ani/dantotsu/media/AuthorActivity.kt @@ -32,7 +32,7 @@ class AuthorActivity : AppCompatActivity() { private val model: OtherDetailsViewModel by viewModels() private var author: Author? = null private var loaded = false - + private var isVoiceArtist: Boolean = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -55,43 +55,59 @@ class AuthorActivity : AppCompatActivity() { binding.studioClose.setOnClickListener { onBackPressedDispatcher.onBackPressed() } + isVoiceArtist = intent.getBooleanExtra("isVoiceArtist", false) + if (isVoiceArtist) { + model.getVoiceActor().observe(this) { + if (it != null) { + author = it + loaded = true + binding.studioProgressBar.visibility = View.GONE + binding.studioRecycler.visibility = View.VISIBLE + binding.studioRecycler.adapter = CharacterAdapter(author!!.character ?: arrayListOf()) + binding.studioRecycler.layoutManager = GridLayoutManager( + this, + (screenWidth / 120f).toInt() + ) + } + } + }else{ + model.getAuthor().observe(this) { + if (it != null) { + author = it + loaded = true + binding.studioProgressBar.visibility = View.GONE + binding.studioRecycler.visibility = View.VISIBLE - model.getAuthor().observe(this) { - if (it != null) { - author = it - loaded = true - binding.studioProgressBar.visibility = View.GONE - binding.studioRecycler.visibility = View.VISIBLE + val titlePosition = arrayListOf() + val concatAdapter = ConcatAdapter() + val map = author!!.yearMedia ?: return@observe + val keys = map.keys.toTypedArray() + var pos = 0 - val titlePosition = arrayListOf() - val concatAdapter = ConcatAdapter() - val map = author!!.yearMedia ?: return@observe - val keys = map.keys.toTypedArray() - var pos = 0 - - val gridSize = (screenWidth / 124f).toInt() - val gridLayoutManager = GridLayoutManager(this, gridSize) - gridLayoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { - override fun getSpanSize(position: Int): Int { - return when (position in titlePosition) { - true -> gridSize - else -> 1 + val gridSize = (screenWidth / 124f).toInt() + val gridLayoutManager = GridLayoutManager(this, gridSize) + gridLayoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { + override fun getSpanSize(position: Int): Int { + return when (position in titlePosition) { + true -> gridSize + else -> 1 + } } } - } - for (i in keys.indices) { - val medias = map[keys[i]]!! - val empty = if (medias.size >= 4) medias.size % 4 else 4 - medias.size - titlePosition.add(pos) - pos += (empty + medias.size + 1) + for (i in keys.indices) { + val medias = map[keys[i]]!! + val empty = if (medias.size >= 4) medias.size % 4 else 4 - medias.size + titlePosition.add(pos) + pos += (empty + medias.size + 1) - concatAdapter.addAdapter(TitleAdapter("${keys[i]} (${medias.size})")) - concatAdapter.addAdapter(MediaAdaptor(0, medias, this, true)) - concatAdapter.addAdapter(EmptyAdapter(empty)) - } + concatAdapter.addAdapter(TitleAdapter("${keys[i]} (${medias.size})")) + concatAdapter.addAdapter(MediaAdaptor(0, medias, this, true)) + concatAdapter.addAdapter(EmptyAdapter(empty)) + } - binding.studioRecycler.adapter = concatAdapter - binding.studioRecycler.layoutManager = gridLayoutManager + binding.studioRecycler.adapter = concatAdapter + binding.studioRecycler.layoutManager = gridLayoutManager + } } } val live = Refresh.activity.getOrPut(this.hashCode()) { MutableLiveData(true) } @@ -99,7 +115,7 @@ class AuthorActivity : AppCompatActivity() { if (it) { scope.launch { if (author != null) - withContext(Dispatchers.IO) { model.loadAuthor(author!!) } + withContext(Dispatchers.IO) { if (isVoiceArtist) model.loadVoiceActor(author!!) else model.loadAuthor(author!!)} live.postValue(false) } } diff --git a/app/src/main/java/ani/dantotsu/media/AuthorAdapter.kt b/app/src/main/java/ani/dantotsu/media/AuthorAdapter.kt index 56086b20..c7ac9645 100644 --- a/app/src/main/java/ani/dantotsu/media/AuthorAdapter.kt +++ b/app/src/main/java/ani/dantotsu/media/AuthorAdapter.kt @@ -15,7 +15,8 @@ import ani.dantotsu.setAnimation import java.io.Serializable class AuthorAdapter( - private val authorList: ArrayList + private val authorList: ArrayList, + private val isVA: Boolean = false, ) : RecyclerView.Adapter() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AuthorViewHolder { val binding = @@ -43,7 +44,7 @@ class AuthorAdapter( Intent( itemView.context, AuthorActivity::class.java - ).putExtra("author", author as Serializable), + ).putExtra("author", author as Serializable).putExtra("isVoiceArtist", isVA), ActivityOptionsCompat.makeSceneTransitionAnimation( itemView.context as Activity, Pair.create( diff --git a/app/src/main/java/ani/dantotsu/media/CharacterDetailsAdapter.kt b/app/src/main/java/ani/dantotsu/media/CharacterDetailsAdapter.kt index 5cf6899c..d3d5d811 100644 --- a/app/src/main/java/ani/dantotsu/media/CharacterDetailsAdapter.kt +++ b/app/src/main/java/ani/dantotsu/media/CharacterDetailsAdapter.kt @@ -2,6 +2,7 @@ package ani.dantotsu.media import android.app.Activity import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -37,10 +38,13 @@ class CharacterDetailsAdapter(private val character: Character, private val acti val markWon = Markwon.builder(activity).usePlugin(SoftBreakAddsNewLinePlugin.create()) .usePlugin(SpoilerPlugin()).build() markWon.setMarkdown(binding.characterDesc, desc.replace("~!", "||").replace("!~", "||")) - binding.voiceActorRecycler.adapter = AuthorAdapter(character.voiceActor ?: arrayListOf()) + binding.voiceActorRecycler.adapter = AuthorAdapter(character.voiceActor ?: arrayListOf(), true) binding.voiceActorRecycler.layoutManager = LinearLayoutManager( activity, LinearLayoutManager.HORIZONTAL, false ) + if (binding.voiceActorRecycler.adapter!!.itemCount == 0) { + binding.voiceActorContainer.visibility = View.GONE + } } override fun getItemCount(): Int = 1 diff --git a/app/src/main/java/ani/dantotsu/media/OtherDetailsViewModel.kt b/app/src/main/java/ani/dantotsu/media/OtherDetailsViewModel.kt index 0be0fc22..394ddf0a 100644 --- a/app/src/main/java/ani/dantotsu/media/OtherDetailsViewModel.kt +++ b/app/src/main/java/ani/dantotsu/media/OtherDetailsViewModel.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import ani.dantotsu.connections.anilist.Anilist +import org.checkerframework.checker.units.qual.A import java.text.DateFormat import java.util.Date @@ -25,7 +26,11 @@ class OtherDetailsViewModel : ViewModel() { suspend fun loadAuthor(m: Author) { if (author.value == null) author.postValue(Anilist.query.getAuthorDetails(m)) } - + private val voiceActor: MutableLiveData = MutableLiveData(null) + fun getVoiceActor(): LiveData = voiceActor + suspend fun loadVoiceActor(m: Author) { + if (voiceActor.value == null) voiceActor.postValue(Anilist.query.getVoiceActorsDetails(m)) + } private val calendar: MutableLiveData>> = MutableLiveData(null) fun getCalendar(): LiveData>> = calendar suspend fun loadCalendar() { diff --git a/app/src/main/res/layout/item_character_details.xml b/app/src/main/res/layout/item_character_details.xml index 509ca427..cb5141f0 100644 --- a/app/src/main/res/layout/item_character_details.xml +++ b/app/src/main/res/layout/item_character_details.xml @@ -55,6 +55,8 @@ tools:layoutManager="androidx.recyclerview.widget.GridLayoutManager" tools:listitem="@layout/item_media_compact" tools:orientation="horizontal" /> + + - - \ No newline at end of file