Skip to content

Commit

Permalink
feat: more thumbnails, descriptions (thanks to @yupcm)
Browse files Browse the repository at this point in the history
  • Loading branch information
aayush2622 committed May 29, 2024
1 parent 11655bd commit 8822ef6
Show file tree
Hide file tree
Showing 25 changed files with 279 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ class AnilistMutations {
return errors?.toString()
?: (currContext()?.getString(ani.dantotsu.R.string.success) ?: "Success")
}
suspend fun postMessage(userId: Int, text: String, edit: Int? = null,isPrivate: Boolean = false): String {
val encodedText = text.stringSanitizer()
val query = "mutation{SaveMessageActivity(${if (edit != null) "id:$edit," else ""} recipientId:$userId,message:$encodedText,private:$isPrivate){id}}"
val result = executeQuery<JsonObject>(query)
val errors = result?.get("errors")
return errors?.toString()
?: (currContext()?.getString(ani.dantotsu.R.string.success) ?: "Success")
}
suspend fun postReply(activityId: Int, text: String, edit: Int? = null ): String {
val encodedText = text.stringSanitizer()
val query = "mutation{SaveActivityReply(${if (edit != null) "id:$edit," else ""} activityId:$activityId,text:$encodedText){id}}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ani.dantotsu.checkGenreTime
import ani.dantotsu.checkId
import ani.dantotsu.connections.anilist.Anilist.authorRoles
import ani.dantotsu.connections.anilist.Anilist.executeQuery
import ani.dantotsu.connections.anilist.api.Activity
import ani.dantotsu.connections.anilist.api.FeedResponse
import ani.dantotsu.connections.anilist.api.FuzzyDate
import ani.dantotsu.connections.anilist.api.NotificationResponse
Expand Down Expand Up @@ -453,13 +454,24 @@ class AnilistQueries {
)
if (user.id == Anilist.userid) {
anilistActivities.add(0, userToAdd)

} else {
list.add(userToAdd)
}
}
}


if (anilistActivities.isEmpty() && Anilist.token != null){
anilistActivities.add(0,
User(
Anilist.userid!!,
Anilist.username!!,
Anilist.avatar,
Anilist.bg,
activity = listOf()
)
)
}
list.addAll(0, anilistActivities)
return list.toCollection(ArrayList())
} else return null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class StatusActivity : AppCompatActivity(), StoriesCallback {

override fun onStoriesStart() {
position -= 1
if (position >= 0) {
if (position >= 0 && activity[position].activity.isNotEmpty()) {
val key = "activities"
val watchedActivity = PrefManager.getCustomVal<Set<Int>>(key, setOf())
val startFrom = findFirstNonMatch(watchedActivity, activity[position].activity )
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/ani/dantotsu/home/status/Stories.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.Context
import android.content.Intent
import android.content.res.ColorStateList
import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
Expand All @@ -15,6 +16,7 @@ import androidx.core.app.ActivityOptionsCompat
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.core.view.isVisible
import androidx.core.widget.NestedScrollView
import androidx.fragment.app.FragmentActivity
import ani.dantotsu.R
import ani.dantotsu.blurImage
Expand Down
29 changes: 22 additions & 7 deletions app/src/main/java/ani/dantotsu/home/status/UserStatusAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import ani.dantotsu.profile.ProfileActivity
import ani.dantotsu.profile.User
import ani.dantotsu.setAnimation
import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.snackString
import ani.dantotsu.util.MarkdownCreatorActivity

class UserStatusAdapter(private val user: ArrayList<User>) :
RecyclerView.Adapter<UserStatusAdapter.UsersViewHolder>() {
Expand All @@ -23,6 +25,10 @@ class UserStatusAdapter(private val user: ArrayList<User>) :
RecyclerView.ViewHolder(binding.root) {
init {
itemView.setOnClickListener {
if (user[bindingAdapterPosition].activity.isEmpty()) {
snackString("No activity")
return@setOnClickListener
}
StatusActivity.user = user
ContextCompat.startActivity(
itemView.context,
Expand All @@ -34,14 +40,23 @@ class UserStatusAdapter(private val user: ArrayList<User>) :
)
}
itemView.setOnLongClickListener {
ContextCompat.startActivity(
itemView.context,
Intent(
if (user[bindingAdapterPosition].id == Anilist.userid) {
ContextCompat.startActivity(
itemView.context,
ProfileActivity::class.java
).putExtra("userId", user[bindingAdapterPosition].id),
null
)
Intent(itemView.context, MarkdownCreatorActivity::class.java)
.putExtra("type", "activity"),
null
)
}else{
ContextCompat.startActivity(
itemView.context,
Intent(
itemView.context,
ProfileActivity::class.java
).putExtra("userId", user[bindingAdapterPosition].id),
null
)
}
true
}
}
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/ani/dantotsu/media/CharacterAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.core.content.ContextCompat
import androidx.core.util.Pair
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.RecyclerView
import ani.dantotsu.copyToClipboard
import ani.dantotsu.databinding.ItemCharacterBinding
import ani.dantotsu.loadImage
import ani.dantotsu.setAnimation
Expand All @@ -32,6 +33,9 @@ class CharacterAdapter(
binding.itemCompactRelation.text = whitespace
binding.itemCompactImage.loadImage(character.image)
binding.itemCompactTitle.text = character.name
binding.root.setOnClickListener {
copyToClipboard(character.name ?: "")
}
}

override fun getItemCount(): Int = characterList.size
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/ani/dantotsu/media/MediaDetailsViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import ani.dantotsu.media.anime.Episode
import ani.dantotsu.media.anime.SelectorDialogFragment
import ani.dantotsu.media.manga.MangaChapter
import ani.dantotsu.others.AniSkip
import ani.dantotsu.others.Anify
import ani.dantotsu.others.Jikan
import ani.dantotsu.others.Kitsu
import ani.dantotsu.parsers.AnimeSources
Expand Down Expand Up @@ -99,6 +100,15 @@ class MediaDetailsViewModel : ViewModel() {
if (kitsuEpisodes.value == null) kitsuEpisodes.postValue(Kitsu.getKitsuEpisodesDetails(s))
}
}
private val anifyEpisodes: MutableLiveData<Map<String, Episode>> =
MutableLiveData<Map<String, Episode>>(null)

fun getAnifyEpisodes(): LiveData<Map<String, Episode>> = anifyEpisodes
suspend fun loadAnifyEpisodes(s: Int) {
tryWithSuspend {
if (anifyEpisodes.value == null) anifyEpisodes.postValue(Anify.fetchAndParseMetadata(s))
}
}

private val fillerEpisodes: MutableLiveData<Map<String, Episode>> =
MutableLiveData<Map<String, Episode>>(null)
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/ani/dantotsu/media/anime/Anime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ data class Anime(
var slug: String? = null,
var kitsuEpisodes: Map<String, Episode>? = null,
var fillerEpisodes: Map<String, Episode>? = null,
var anifyEpisodes: Map<String, Episode>? = null,
) : Serializable
41 changes: 23 additions & 18 deletions app/src/main/java/ani/dantotsu/media/anime/AnimeWatchFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import ani.dantotsu.media.MediaType
import ani.dantotsu.navBarHeight
import ani.dantotsu.notifications.subscription.SubscriptionHelper
import ani.dantotsu.notifications.subscription.SubscriptionHelper.Companion.saveSubscription
import ani.dantotsu.others.Anify
import ani.dantotsu.others.LanguageMapper
import ani.dantotsu.parsers.AnimeParser
import ani.dantotsu.parsers.AnimeSources
Expand Down Expand Up @@ -214,8 +215,9 @@ class AnimeWatchFragment : Fragment() {
media.selected!!.sourceIndex = model.watchSources!!.list.lastIndex
} else {
awaitAll(
async { model.loadKitsuEpisodes(media) },
async { model.loadFillerEpisodes(media) }
//async { model.loadKitsuEpisodes(media) }, if someday anify dies
//async { model.loadFillerEpisodes(media) },
async { model.loadAnifyEpisodes(media.id)}
)
}
model.loadEpisodes(media, media.selected!!.sourceIndex)
Expand All @@ -231,19 +233,6 @@ class AnimeWatchFragment : Fragment() {
val episodes = loadedEpisodes[media.selected!!.sourceIndex]
if (episodes != null) {
episodes.forEach { (i, episode) ->
fun getThumbnail(episodes: List<MediaStreamingEpisode>): List<Pair<String, FileUrl?>> {
return episodes.mapNotNull { episode ->
val regex = Regex("""Episode\s*(\d+)\s*-\s*(.*)""")
val number = episode.title?.let {
val matchResult = regex.matchEntire(it)
matchResult?.destructured?.component1()
}
number?.let { number to FileUrl[episode.thumbnail] }
}
}

val getThumbnail = getThumbnail(media.streamingEpisodes ?: emptyList())

if (media.anime?.fillerEpisodes != null) {
if (media.anime!!.fillerEpisodes!!.containsKey(i)) {
episode.title =
Expand All @@ -258,11 +247,23 @@ class AnimeWatchFragment : Fragment() {
episode.title = if (MediaNameAdapter.removeEpisodeNumberCompletely(
episode.title ?: ""
).isBlank()
) media.anime!!.kitsuEpisodes!![i]?.title
)
media.anime!!.kitsuEpisodes!![i]?.title
?: episode.title else episode.title
?: media.anime!!.kitsuEpisodes!![i]?.title ?: episode.title
episode.thumb = getThumbnail.find { it.first == i }?.second
?: media.anime!!.kitsuEpisodes!![i]?.thumb ?: episode.thumb
episode.thumb = media.anime!!.kitsuEpisodes!![i]?.thumb ?: episode.thumb
}
}
if (media.anime?.anifyEpisodes != null) {
if (media.anime!!.anifyEpisodes!!.containsKey(i)) {
episode.desc = media.anime!!.anifyEpisodes!![i]?.desc ?: episode.desc
episode.title = if (MediaNameAdapter.removeEpisodeNumberCompletely(
episode.title ?: ""
).isBlank()
) media.anime!!.anifyEpisodes!![i]?.title ?: episode.title else episode.title
?: media.anime!!.anifyEpisodes!![i]?.title ?: episode.title
episode.thumb = media.anime!!.anifyEpisodes!![i]?.thumb ?: episode.thumb

}
}
}
Expand Down Expand Up @@ -309,6 +310,10 @@ class AnimeWatchFragment : Fragment() {
if (i != null)
media.anime?.fillerEpisodes = i
}
model.getAnifyEpisodes().observe(viewLifecycleOwner) { i ->
if (i != null)
media.anime?.anifyEpisodes = i
}
}

fun onSourceChange(i: Int): AnimeParser {
Expand Down
46 changes: 46 additions & 0 deletions app/src/main/java/ani/dantotsu/others/Anify.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package ani.dantotsu.others

import ani.dantotsu.FileUrl
import ani.dantotsu.Mapper
import ani.dantotsu.client
import ani.dantotsu.media.anime.Episode
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.decodeFromJsonElement

object Anify {
suspend fun fetchAndParseMetadata(id :Int): Map<String, Episode>? {
val response = client.get("https://api.anify.tv/content-metadata/$id")
.parsed<JsonArray>().map {
Mapper.json.decodeFromJsonElement<ContentMetadata>(it)
}
return response.first().data.associate {
it.number.toString() to Episode(
number = it.number.toString(),
title = it.title,
desc = it.description,
thumb = FileUrl[it.img],
filler = it.isFiller,
)
}
}
@Serializable
data class ContentMetadata(
@SerialName("providerId") val providerId: String,
@SerialName("data") val data: List<ProviderData>
)

@Serializable
data class ProviderData(
@SerialName("id") val id: String,
@SerialName("description") val description: String,
@SerialName("hasDub") val hasDub: Boolean,
@SerialName("img") val img: String,
@SerialName("isFiller") val isFiller: Boolean,
@SerialName("number") val number: Int,
@SerialName("title") val title: String,
@SerialName("updatedAt") val updatedAt: Long,
@SerialName("rating") val rating: Double? = null
)
}
9 changes: 0 additions & 9 deletions app/src/main/java/ani/dantotsu/profile/ProfileActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,6 @@ class ProfileActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedListene
true
}

R.id.action_create_new_activity -> {
ContextCompat.startActivity(
context,
Intent(context, MarkdownCreatorActivity::class.java)
.putExtra("type", "activity"),
null
)
true
}

else -> false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.navBarHeight
import ani.dantotsu.profile.ProfileActivity
import ani.dantotsu.setBaseline
import ani.dantotsu.util.MarkdownCreatorActivity
import com.xwray.groupie.GroupieAdapter
import eu.kanade.tachiyomi.util.system.getSerializableCompat
import kotlinx.coroutines.launch
Expand All @@ -46,14 +47,35 @@ class ActivityFragment : Fragment() {
type = arguments?.getSerializableCompat<ActivityType>("type") as ActivityType
userId = arguments?.getInt("userId")
activityId = arguments?.getInt("activityId")
binding.titleBar.visibility = if (type == ActivityType.OTHER_USER) View.VISIBLE else View.GONE
binding.titleText.text = if (userId == Anilist.userid) getString(R.string.create_new_activity) else getString(R.string.write_a_message)
binding.titleImage.setOnClickListener {
if(userId == Anilist.userid) {
ContextCompat.startActivity(
requireContext(),
Intent(context, MarkdownCreatorActivity::class.java)
.putExtra("type", "activity"),
null
)
} else{
ContextCompat.startActivity(
requireContext(),
Intent(context, MarkdownCreatorActivity::class.java)
.putExtra("type", "message")
.putExtra("userId", userId),

null
)
}
}
binding.listRecyclerView.adapter = adapter
binding.listRecyclerView.layoutManager = LinearLayoutManager(context)
binding.listProgressBar.isVisible = true

binding.feedRefresh.updateLayoutParams<ViewGroup.MarginLayoutParams> {
bottomMargin = navBarHeight
}
binding.emptyTextView.text = getString(R.string.no_notifications)
binding.emptyTextView.text = getString(R.string.no_activities)
lifecycleScope.launch {
getList()
if (adapter.itemCount == 0) {
Expand Down Expand Up @@ -87,8 +109,8 @@ class ActivityFragment : Fragment() {

private suspend fun getList() {
val list = when (type) {
ActivityType.GLOBAL -> getActivities(true)
ActivityType.USER -> getActivities()
ActivityType.GLOBAL -> getActivities(global = true)
ActivityType.USER -> getActivities(filter = true)
ActivityType.OTHER_USER -> getActivities(userId = userId)
ActivityType.ONE -> getActivities(activityId = activityId)
}
Expand All @@ -99,12 +121,13 @@ class ActivityFragment : Fragment() {
global: Boolean = false,
userId: Int? = null,
activityId: Int? = null,
filter:Boolean = false
): List<Activity> {
val res = Anilist.query.getFeed(userId, global, page, activityId)?.data?.page?.activities
page += 1
return res
?.filter { if (Anilist.adult) true else it.media?.isAdult != true }
?.filterNot { it.recipient?.id != null && it.recipient.id != Anilist.userid }
?.filterNot { it.recipient?.id != null && it.recipient.id != Anilist.userid && filter }
?: emptyList()
}

Expand Down
Loading

0 comments on commit 8822ef6

Please sign in to comment.