feat: socials in media

This commit is contained in:
aayush262 2024-04-07 00:51:50 +05:30
parent abe3f883ae
commit e49f0dbf32
9 changed files with 119 additions and 16 deletions

View file

@ -20,6 +20,7 @@ import ani.dantotsu.media.Character
import ani.dantotsu.media.Media import ani.dantotsu.media.Media
import ani.dantotsu.media.Studio import ani.dantotsu.media.Studio
import ani.dantotsu.others.MalScraper import ani.dantotsu.others.MalScraper
import ani.dantotsu.profile.User
import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.snackString import ani.dantotsu.snackString
@ -72,14 +73,14 @@ class AnilistQueries {
media.cameFromContinue = false media.cameFromContinue = false
val query = val query =
"""{Media(id:${media.id}){id favourites popularity 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 voiceActors { id name { first middle last full native userPreferred } image { large medium } languageV2 } 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}}}""" """{Media(id:${media.id}){id favourites popularity 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 voiceActors { id name { first middle last full native userPreferred } image { large medium } languageV2 } 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}}Page(page:1){pageInfo{total perPage currentPage lastPage hasNextPage}mediaList(isFollowing:true,sort:[STARTED_ON],mediaId:${media.id}){id status score progress progressVolumes user{id name avatar{large medium}}}}}"""
runBlocking { runBlocking {
val anilist = async { val anilist = async {
var response = executeQuery<Query.Media>(query, force = true, show = true) var response = executeQuery<Query.Media>(query, force = true, show = true)
if (response != null) { if (response != null) {
fun parse() { fun parse() {
val fetchedMedia = response?.data?.media ?: return val fetchedMedia = response?.data?.media ?: return
val user = response?.data?.page
media.source = fetchedMedia.source?.toString() media.source = fetchedMedia.source?.toString()
media.countryOfOrigin = fetchedMedia.countryOfOrigin media.countryOfOrigin = fetchedMedia.countryOfOrigin
media.format = fetchedMedia.format?.toString() media.format = fetchedMedia.format?.toString()
@ -144,7 +145,7 @@ class AnilistQueries {
Author( Author(
id = it.id, id = it.id,
name = it.name?.userPreferred, name = it.name?.userPreferred,
image = it.image?.medium, image = it.image?.large,
role = it.languageV2 role = it.languageV2
) )
} as ArrayList<Author> } as ArrayList<Author>
@ -161,7 +162,7 @@ class AnilistQueries {
Author( Author(
id = id, id = id,
name = i.node?.name?.userPreferred, name = i.node?.name?.userPreferred,
image = i.node?.image?.medium, image = i.node?.image?.large,
role = when (i.role.toString()) { role = when (i.role.toString()) {
"MAIN" -> currContext()?.getString(R.string.main_role) "MAIN" -> currContext()?.getString(R.string.main_role)
?: "MAIN" ?: "MAIN"
@ -208,7 +209,21 @@ class AnilistQueries {
} }
} }
} }
if (user?.mediaList?.isNotEmpty() == true) {
media.users = user.mediaList?.mapNotNull {
it.user?.let { user ->
if (user.id != Anilist.userid) {
User(
user.id,
user.name ?: "Unknown",
user.avatar?.large,
"",
it.status?.toString(),
)
} else null
}
}?.toCollection(arrayListOf()) ?: arrayListOf()
}
if (fetchedMedia.mediaListEntry != null) { if (fetchedMedia.mediaListEntry != null) {
fetchedMedia.mediaListEntry?.apply { fetchedMedia.mediaListEntry?.apply {
media.userProgress = progress media.userProgress = progress

View file

@ -24,7 +24,9 @@ class Query {
@Serializable @Serializable
data class Data( data class Data(
@SerialName("Media") @SerialName("Media")
val media: ani.dantotsu.connections.anilist.api.Media? val media: ani.dantotsu.connections.anilist.api.Media?,
@SerialName("Page")
val page: ani.dantotsu.connections.anilist.api.Page?
) )
} }

View file

@ -7,6 +7,7 @@ import ani.dantotsu.connections.anilist.api.MediaList
import ani.dantotsu.connections.anilist.api.MediaType import ani.dantotsu.connections.anilist.api.MediaType
import ani.dantotsu.media.anime.Anime import ani.dantotsu.media.anime.Anime
import ani.dantotsu.media.manga.Manga import ani.dantotsu.media.manga.Manga
import ani.dantotsu.profile.User
import java.io.Serializable import java.io.Serializable
import ani.dantotsu.connections.anilist.api.Media as ApiMedia import ani.dantotsu.connections.anilist.api.Media as ApiMedia
@ -66,7 +67,7 @@ data class Media(
var sequel: Media? = null, var sequel: Media? = null,
var relations: ArrayList<Media>? = null, var relations: ArrayList<Media>? = null,
var recommendations: ArrayList<Media>? = null, var recommendations: ArrayList<Media>? = null,
var users: ArrayList<User>? = null,
var vrvId: String? = null, var vrvId: String? = null,
var crunchySlug: String? = null, var crunchySlug: String? = null,

View file

@ -570,6 +570,23 @@ class MediaInfoFragment : Fragment() {
parent.addView(root) parent.addView(root)
} }
} }
if(!media.users.isNullOrEmpty() && !offline){
ItemTitleRecyclerBinding.inflate(
LayoutInflater.from(context),
parent,
false
).apply {
itemTitle.setText(R.string.social)
itemRecycler.adapter =
MediaSocialAdapter(media.users!!)
itemRecycler.layoutManager = LinearLayoutManager(
requireContext(),
LinearLayoutManager.HORIZONTAL,
false
)
parent.addView(root)
}
}
} }
} }

View file

@ -0,0 +1,49 @@
package ani.dantotsu.media
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import ani.dantotsu.databinding.ItemFollowerGridBinding
import ani.dantotsu.loadImage
import ani.dantotsu.profile.ProfileActivity
import ani.dantotsu.profile.User
import ani.dantotsu.setAnimation
class MediaSocialAdapter(private val user: ArrayList<User>) :
RecyclerView.Adapter<MediaSocialAdapter.DeveloperViewHolder>() {
inner class DeveloperViewHolder(val binding: ItemFollowerGridBinding) :
RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DeveloperViewHolder {
return DeveloperViewHolder(
ItemFollowerGridBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
override fun onBindViewHolder(holder: DeveloperViewHolder, position: Int) {
val b = holder.binding
setAnimation(b.root.context, b.root)
val user = user[position]
b.profileUserName.text = user.name
b.profileUserAvatar.loadImage(user.pfp)
b.profileInfo.text = user.info
b.profileInfo.visibility = View.VISIBLE
b.profileUserAvatar.setOnClickListener {
val intent = Intent(b.root.context, ProfileActivity::class.java)
intent.putExtra("userId", user.id)
ContextCompat.startActivity(b.root.context, intent, null)
}
}
override fun getItemCount(): Int = user.size
}

View file

@ -5,4 +5,5 @@ data class User(
val name: String, val name: String,
val pfp: String?, val pfp: String?,
val banner: String?, val banner: String?,
val info: String? = null,
) )

View file

@ -4,8 +4,9 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="8dp" android:orientation="vertical"
android:orientation="vertical"> android:padding="8dp">
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/profileUserAvatarContainer" android:id="@+id/profileUserAvatarContainer"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -13,12 +14,13 @@
android:layout_gravity="center" android:layout_gravity="center"
android:backgroundTint="@color/bg_white" android:backgroundTint="@color/bg_white"
app:cardCornerRadius="124dp"> app:cardCornerRadius="124dp">
<ImageView <ImageView
android:id="@+id/profileUserAvatar" android:id="@+id/profileUserAvatar"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="100dp" android:layout_height="100dp"
tools:tint="@color/transparent" tools:ignore="ContentDescription,ImageContrastCheck"
tools:ignore="ContentDescription,ImageContrastCheck" /> tools:tint="@color/transparent" />
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
<TextView <TextView
@ -26,11 +28,25 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical" android:layout_gravity="center_horizontal|center_vertical"
android:ellipsize="end"
android:fontFamily="@font/poppins_semi_bold" android:fontFamily="@font/poppins_semi_bold"
android:text="@string/username" android:text="@string/username"
android:textColor="?attr/colorOnBackground" android:textColor="?attr/colorOnBackground"
android:textSize="12sp" android:textSize="12sp"
android:ellipsize="end"
android:textStyle="bold" /> android:textStyle="bold" />
<TextView
android:id="@+id/profileInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:ellipsize="end"
android:fontFamily="@font/poppins_semi_bold"
android:singleLine="true"
android:text="@string/video_info_info"
android:textSize="12sp"
android:alpha="0.58"
android:gravity="center"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout> </LinearLayout>

View file

@ -888,4 +888,6 @@ Non quae tempore quo provident laudantium qui illo dolor vel quia dolor et exerc
<string name="voice_actors">Voice Actors</string> <string name="voice_actors">Voice Actors</string>
<string name="download_permission_required">Permission is required to download</string> <string name="download_permission_required">Permission is required to download</string>
<string name="media">Media</string> <string name="media">Media</string>
<string name="users">Users</string>
<string name="social">Social</string>
</resources> </resources>