Skip to content

Commit

Permalink
Added Anime Calendar, Fixes #339
Browse files Browse the repository at this point in the history
  • Loading branch information
brahmkshatriya committed Oct 21, 2022
1 parent 7847029 commit 1384c45
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 38 deletions.
3 changes: 3 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
<activity
android:name=".media.StudioActivity"
android:exported="true" />
<activity
android:name=".media.CalendarActivity"
android:exported="true" />
<activity
android:name=".user.ListActivity"
android:exported="true" />
Expand Down
10 changes: 4 additions & 6 deletions app/src/main/java/ani/saikou/AnimePageAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import ani.saikou.anilist.Anilist
import ani.saikou.databinding.ItemAnimePageBinding
import ani.saikou.media.CalendarActivity
import ani.saikou.media.MediaAdaptor
import ani.saikou.media.SearchActivity
import ani.saikou.settings.SettingsDialogFragment
Expand Down Expand Up @@ -75,7 +76,7 @@ class AnimePageAdapter : RecyclerView.Adapter<AnimePageAdapter.AnimePageViewHold
}

binding.animeGenreImage.loadImage("https://s4.anilist.co/file/anilistcdn/media/anime/banner/16498-8jpFCOcDmneX.jpg")
binding.animeTopScoreImage.loadImage("https://s4.anilist.co/file/anilistcdn/media/anime/banner/125367-hGPJLSNfprO3.jpg")
binding.animeCalendarImage.loadImage("https://s4.anilist.co/file/anilistcdn/media/anime/banner/125367-hGPJLSNfprO3.jpg")

binding.animeGenre.setOnClickListener {
ContextCompat.startActivity(
Expand All @@ -84,13 +85,10 @@ class AnimePageAdapter : RecyclerView.Adapter<AnimePageAdapter.AnimePageViewHold
null
)
}
binding.animeTopScore.setOnClickListener {
binding.animeCalendar.setOnClickListener {
ContextCompat.startActivity(
it.context,
Intent(it.context, SearchActivity::class.java)
.putExtra("type", "ANIME")
.putExtra("sortBy", "Score")
.putExtra("search", true),
Intent(it.context, CalendarActivity::class.java),
null
)
}
Expand Down
57 changes: 41 additions & 16 deletions app/src/main/java/ani/saikou/anilist/AnilistQueries.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ani.saikou.anilist
import android.app.Activity
import ani.saikou.*
import ani.saikou.anilist.api.FuzzyDate
import ani.saikou.anilist.api.Page
import ani.saikou.anilist.api.Query
import ani.saikou.anilist.api.User
import ani.saikou.media.Character
Expand Down Expand Up @@ -691,11 +692,11 @@ query (${"$"}page: Int = 1, ${"$"}id: Int, ${"$"}type: MediaType, ${"$"}isAdult:

suspend fun recentlyUpdated(
smaller: Boolean = true,
page: Int = 1,
greater: Long = 0,
lesser: Long = System.currentTimeMillis() / 1000 - 10000
): MutableList<Media>? {
val query = """{
suspend fun execute(page:Int = 1):Page?{
val query = """{
Page(page:$page,perPage:50) {
pageInfo {
hasNextPage
Expand All @@ -706,6 +707,8 @@ Page(page:$page,perPage:50) {
airingAt_lesser: $lesser
sort:TIME_DESC
) {
episode
airingAt
media {
id
idMal
Expand Down Expand Up @@ -735,21 +738,43 @@ Page(page:$page,perPage:50) {
}
}
}""".replace("\n", " ").replace(""" """, "")
val response = executeQuery<Query.Page>(query, force = true)?.data?.page?.airingSchedules ?: return null

val idArr = mutableListOf<Int>()
val listOnly = loadData("recently_list_only") ?: false
return response.mapNotNull { i ->
i.media?.let {
if (!smaller) Media(it)
else if (!idArr.contains(it.id))
if (!listOnly && (it.countryOfOrigin == "JP" && (if (!Anilist.adult) it.isAdult == false else true)) || (listOnly && it.mediaListEntry != null)) {
idArr.add(it.id)
Media(it)
} else null
else null
return executeQuery<Query.Page>(query, force = true)?.data?.page
}
if(smaller) {
val response = execute()?.airingSchedules ?: return null
val idArr = mutableListOf<Int>()
val listOnly = loadData("recently_list_only") ?: false
return response.mapNotNull { i ->
i.media?.let {
if (!idArr.contains(it.id))
if (!listOnly && (it.countryOfOrigin == "JP" && (if (!Anilist.adult) it.isAdult == false else true)) || (listOnly && it.mediaListEntry != null)) {
idArr.add(it.id)
Media(it)
} else null
else null
}
}.toMutableList()
}else{
var i = 1
val list = mutableListOf<Media>()
var res : Page? = null
suspend fun next(){
res = execute(i)
list.addAll(res?.airingSchedules?.mapNotNull { j ->
j.media?.let {
if (it.countryOfOrigin == "JP" && (if (!Anilist.adult) it.isAdult == false else true)) {
Media(it).apply { relation = "${j.episode},${j.airingAt}" }
} else null
}
}?: listOf())
}
next()
while (res?.pageInfo?.hasNextPage == true){
next()
i++
}
}.toMutableList()
return list
}
}

suspend fun getCharacterDetails(character: Character): Character {
Expand Down
105 changes: 105 additions & 0 deletions app/src/main/java/ani/saikou/media/CalendarActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package ani.saikou.media

import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.GridLayoutManager
import ani.saikou.*
import ani.saikou.databinding.ActivityStudioBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class CalendarActivity : AppCompatActivity() {
private lateinit var binding: ActivityStudioBinding
private val scope = lifecycleScope
private val model: OtherDetailsViewModel by viewModels()
private var loaded = false

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityStudioBinding.inflate(layoutInflater)
setContentView(binding.root)

initActivity(this)
this.window.statusBarColor = ContextCompat.getColor(this, R.color.nav_bg)

val screenWidth = resources.displayMetrics.run { widthPixels / density }

binding.root.updateLayoutParams<ViewGroup.MarginLayoutParams> { topMargin += statusBarHeight }
binding.studioRecycler.updatePadding(bottom = 64f.px + navBarHeight)
binding.studioTitle.isSelected = true
binding.studioTitle.setText(R.string.release_calender)

binding.studioClose.setOnClickListener {
onBackPressed()
}

model.getCalendar().observe(this) {
if (it != null) {
loaded = true
binding.studioProgressBar.visibility = View.GONE
binding.studioRecycler.visibility = View.VISIBLE

val titlePosition = arrayListOf<Int>()
val concatAdapter = ConcatAdapter()
val map = it
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
}
}
}
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))
}

binding.studioRecycler.adapter = concatAdapter
binding.studioRecycler.layoutManager = gridLayoutManager
}
}
val live = Refresh.activity.getOrPut(this.hashCode()) { MutableLiveData(true) }
live.observe(this) {
if (it) {
scope.launch {
withContext(Dispatchers.IO) { model.loadCalendar() }
live.postValue(false)
}
}
}
}

override fun onDestroy() {
if (Refresh.activity.containsKey(this.hashCode())) {
Refresh.activity.remove(this.hashCode())
}
super.onDestroy()
}

override fun onResume() {
binding.studioProgressBar.visibility = if (!loaded) View.VISIBLE else View.GONE
super.onResume()
}
}
24 changes: 24 additions & 0 deletions app/src/main/java/ani/saikou/media/OtherDetailsViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import ani.saikou.anilist.Anilist
import java.text.DateFormat
import java.util.*

class OtherDetailsViewModel : ViewModel() {
private val character: MutableLiveData<Character> = MutableLiveData(null)
Expand All @@ -17,4 +19,26 @@ class OtherDetailsViewModel : ViewModel() {
suspend fun loadStudio(m: Studio) {
if (studio.value == null) studio.postValue(Anilist.query.getStudioDetails(m))
}

private val calendar: MutableLiveData<Map<String,MutableList<Media>>> = MutableLiveData(null)
fun getCalendar(): LiveData<Map<String,MutableList<Media>>> = calendar
suspend fun loadCalendar() {
val curr = System.currentTimeMillis()/1000
val res = Anilist.query.recentlyUpdated(false,curr-86400,curr+(86400*6))
val df = DateFormat.getDateInstance(DateFormat.FULL)
val map = mutableMapOf<String,MutableList<Media>>()
val idMap = mutableMapOf<String,MutableList<Int>>()
res?.forEach {
val v = it.relation?.split(",")?.map { i-> i.toLong() }!!
val dateInfo = df.format(Date(v[1]*1000))
val list = map.getOrPut(dateInfo) { mutableListOf() }
val idList = idMap.getOrPut(dateInfo) { mutableListOf() }
it.relation = "Episode ${v[0]}"
if(!idList.contains(it.id)) {
idList.add(it.id)
list.add(it)
}
}
calendar.postValue(map)
}
}
2 changes: 0 additions & 2 deletions app/src/main/res/layout/activity_studio.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"


android:layout_width="match_parent"
android:layout_height="match_parent">

Expand Down
27 changes: 13 additions & 14 deletions app/src/main/res/layout/item_anime_page.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,12 @@
</FrameLayout>

<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingStart="32dp"
android:paddingEnd="32dp"
android:clipToPadding="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
android:scrollbarSize="0dp">

<LinearLayout
android:id="@+id/animeSeasonsCont"
Expand Down Expand Up @@ -145,7 +146,7 @@
app:cardCornerRadius="16dp"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/animeTopScore"
app:layout_constraintEnd_toStartOf="@+id/animeCalendar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_max="256dp">
Expand Down Expand Up @@ -189,7 +190,7 @@
</com.google.android.material.card.MaterialCardView>

<com.google.android.material.card.MaterialCardView
android:id="@+id/animeTopScore"
android:id="@+id/animeCalendar"
android:layout_width="match_parent"
android:layout_height="72dp"
android:layout_margin="8dp"
Expand All @@ -203,7 +204,7 @@
app:layout_constraintWidth_max="256dp">

<ImageView
android:id="@+id/animeTopScoreImage"
android:id="@+id/animeCalendarImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
Expand All @@ -227,7 +228,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fontFamily="@font/poppins_bold"
android:text="@string/top_score"
android:text="@string/release_calender"
android:textAllCaps="true"
android:textColor="@color/bg_white"
android:textSize="16sp" />
Expand Down Expand Up @@ -258,8 +259,7 @@
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="250dp"
tools:visibility="gone">
android:minHeight="250dp">

<ProgressBar
android:id="@+id/animeUpdatedProgressBar"
Expand Down Expand Up @@ -290,9 +290,8 @@
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:visibility="invisible"
tools:visibility="visible"
android:orientation="horizontal">
android:orientation="horizontal"
android:visibility="invisible">

<TextView
android:layout_width="0dp"
Expand All @@ -307,8 +306,8 @@
android:id="@+id/animeIncludeList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/include_media_in_list"
android:checked="true"/>
android:checked="true"
android:text="@string/include_media_in_list" />


</LinearLayout>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -308,5 +308,6 @@
<string name="next_season">Next Season</string>
<string name="previous_season">Previous Season</string>
<string name="include_media_in_list">Include List</string>
<string name="release_calender">Calender</string>

</resources>

0 comments on commit 1384c45

Please sign in to comment.