feat: voiceActor's characters info

This commit is contained in:
aayush262 2024-04-05 13:20:24 +05:30
parent dec4996760
commit 63c3058f5b
8 changed files with 117 additions and 45 deletions

View file

@ -1387,7 +1387,52 @@ Page(page:$page,perPage:50) {
author.yearMedia = yearMedia author.yearMedia = yearMedia
return author 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<Character>()
while (hasNextPage) {
page++
hasNextPage = executeQuery<Query.Author>(
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? { suspend fun toggleFollow(id: Int): Query.ToggleFollow? {
return executeQuery<Query.ToggleFollow>( return executeQuery<Query.ToggleFollow>(
"""mutation{ToggleFollow(userId:$id){id, isFollowing, isFollower}}""" """mutation{ToggleFollow(userId:$id){id, isFollowing, isFollower}}"""

View file

@ -55,7 +55,7 @@ data class CharacterConnection(
@SerialName("nodes") var nodes: List<Character>?, @SerialName("nodes") var nodes: List<Character>?,
// The pagination information // The pagination information
// @SerialName("pageInfo") var pageInfo: PageInfo?, @SerialName("pageInfo") var pageInfo: PageInfo?,
) : java.io.Serializable ) : java.io.Serializable
@Serializable @Serializable

View file

@ -3,9 +3,10 @@ package ani.dantotsu.media
import java.io.Serializable import java.io.Serializable
data class Author( data class Author(
val id: Int, var id: Int,
val name: String?, var name: String?,
val image: String?, var image: String?,
val role: String?, var role: String?,
var yearMedia: MutableMap<String, ArrayList<Media>>? = null var yearMedia: MutableMap<String, ArrayList<Media>>? = null,
var character: ArrayList<Character>? = null
) : Serializable ) : Serializable

View file

@ -32,7 +32,7 @@ class AuthorActivity : AppCompatActivity() {
private val model: OtherDetailsViewModel by viewModels() private val model: OtherDetailsViewModel by viewModels()
private var author: Author? = null private var author: Author? = null
private var loaded = false private var loaded = false
private var isVoiceArtist: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -55,43 +55,59 @@ class AuthorActivity : AppCompatActivity() {
binding.studioClose.setOnClickListener { binding.studioClose.setOnClickListener {
onBackPressedDispatcher.onBackPressed() 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) { val titlePosition = arrayListOf<Int>()
if (it != null) { val concatAdapter = ConcatAdapter()
author = it val map = author!!.yearMedia ?: return@observe
loaded = true val keys = map.keys.toTypedArray()
binding.studioProgressBar.visibility = View.GONE var pos = 0
binding.studioRecycler.visibility = View.VISIBLE
val titlePosition = arrayListOf<Int>() val gridSize = (screenWidth / 124f).toInt()
val concatAdapter = ConcatAdapter() val gridLayoutManager = GridLayoutManager(this, gridSize)
val map = author!!.yearMedia ?: return@observe gridLayoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
val keys = map.keys.toTypedArray() override fun getSpanSize(position: Int): Int {
var pos = 0 return when (position in titlePosition) {
true -> gridSize
val gridSize = (screenWidth / 124f).toInt() else -> 1
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) {
for (i in keys.indices) { val medias = map[keys[i]]!!
val medias = map[keys[i]]!! val empty = if (medias.size >= 4) medias.size % 4 else 4 - medias.size
val empty = if (medias.size >= 4) medias.size % 4 else 4 - medias.size titlePosition.add(pos)
titlePosition.add(pos) pos += (empty + medias.size + 1)
pos += (empty + medias.size + 1)
concatAdapter.addAdapter(TitleAdapter("${keys[i]} (${medias.size})")) concatAdapter.addAdapter(TitleAdapter("${keys[i]} (${medias.size})"))
concatAdapter.addAdapter(MediaAdaptor(0, medias, this, true)) concatAdapter.addAdapter(MediaAdaptor(0, medias, this, true))
concatAdapter.addAdapter(EmptyAdapter(empty)) concatAdapter.addAdapter(EmptyAdapter(empty))
} }
binding.studioRecycler.adapter = concatAdapter binding.studioRecycler.adapter = concatAdapter
binding.studioRecycler.layoutManager = gridLayoutManager binding.studioRecycler.layoutManager = gridLayoutManager
}
} }
} }
val live = Refresh.activity.getOrPut(this.hashCode()) { MutableLiveData(true) } val live = Refresh.activity.getOrPut(this.hashCode()) { MutableLiveData(true) }
@ -99,7 +115,7 @@ class AuthorActivity : AppCompatActivity() {
if (it) { if (it) {
scope.launch { scope.launch {
if (author != null) if (author != null)
withContext(Dispatchers.IO) { model.loadAuthor(author!!) } withContext(Dispatchers.IO) { if (isVoiceArtist) model.loadVoiceActor(author!!) else model.loadAuthor(author!!)}
live.postValue(false) live.postValue(false)
} }
} }

View file

@ -15,7 +15,8 @@ import ani.dantotsu.setAnimation
import java.io.Serializable import java.io.Serializable
class AuthorAdapter( class AuthorAdapter(
private val authorList: ArrayList<Author> private val authorList: ArrayList<Author>,
private val isVA: Boolean = false,
) : RecyclerView.Adapter<AuthorAdapter.AuthorViewHolder>() { ) : RecyclerView.Adapter<AuthorAdapter.AuthorViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AuthorViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AuthorViewHolder {
val binding = val binding =
@ -43,7 +44,7 @@ class AuthorAdapter(
Intent( Intent(
itemView.context, itemView.context,
AuthorActivity::class.java AuthorActivity::class.java
).putExtra("author", author as Serializable), ).putExtra("author", author as Serializable).putExtra("isVoiceArtist", isVA),
ActivityOptionsCompat.makeSceneTransitionAnimation( ActivityOptionsCompat.makeSceneTransitionAnimation(
itemView.context as Activity, itemView.context as Activity,
Pair.create( Pair.create(

View file

@ -2,6 +2,7 @@ package ani.dantotsu.media
import android.app.Activity import android.app.Activity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView 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()) val markWon = Markwon.builder(activity).usePlugin(SoftBreakAddsNewLinePlugin.create())
.usePlugin(SpoilerPlugin()).build() .usePlugin(SpoilerPlugin()).build()
markWon.setMarkdown(binding.characterDesc, desc.replace("~!", "||").replace("!~", "||")) 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( binding.voiceActorRecycler.layoutManager = LinearLayoutManager(
activity, LinearLayoutManager.HORIZONTAL, false activity, LinearLayoutManager.HORIZONTAL, false
) )
if (binding.voiceActorRecycler.adapter!!.itemCount == 0) {
binding.voiceActorContainer.visibility = View.GONE
}
} }
override fun getItemCount(): Int = 1 override fun getItemCount(): Int = 1

View file

@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import ani.dantotsu.connections.anilist.Anilist import ani.dantotsu.connections.anilist.Anilist
import org.checkerframework.checker.units.qual.A
import java.text.DateFormat import java.text.DateFormat
import java.util.Date import java.util.Date
@ -25,7 +26,11 @@ class OtherDetailsViewModel : ViewModel() {
suspend fun loadAuthor(m: Author) { suspend fun loadAuthor(m: Author) {
if (author.value == null) author.postValue(Anilist.query.getAuthorDetails(m)) if (author.value == null) author.postValue(Anilist.query.getAuthorDetails(m))
} }
private val voiceActor: MutableLiveData<Author> = MutableLiveData(null)
fun getVoiceActor(): LiveData<Author> = voiceActor
suspend fun loadVoiceActor(m: Author) {
if (voiceActor.value == null) voiceActor.postValue(Anilist.query.getVoiceActorsDetails(m))
}
private val calendar: MutableLiveData<Map<String, MutableList<Media>>> = MutableLiveData(null) private val calendar: MutableLiveData<Map<String, MutableList<Media>>> = MutableLiveData(null)
fun getCalendar(): LiveData<Map<String, MutableList<Media>>> = calendar fun getCalendar(): LiveData<Map<String, MutableList<Media>>> = calendar
suspend fun loadCalendar() { suspend fun loadCalendar() {

View file

@ -55,6 +55,8 @@
tools:layoutManager="androidx.recyclerview.widget.GridLayoutManager" tools:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
tools:listitem="@layout/item_media_compact" tools:listitem="@layout/item_media_compact"
tools:orientation="horizontal" /> tools:orientation="horizontal" />
</LinearLayout>
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -65,6 +67,4 @@
android:padding="8dp" android:padding="8dp"
android:text="@string/roles" android:text="@string/roles"
android:textSize="18sp" /> android:textSize="18sp" />
</LinearLayout>
</LinearLayout> </LinearLayout>