crunchyroll support #49
@ -368,4 +368,21 @@ object Crunchyroll {
|
|||||||
return objects(objects)
|
return objects(objects)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
suspend fun upNextAccount(n: Int = 20): ContinueWatchingList {
|
||||||
|
val watchlistEndpoint = "/content/v1/$accountID/up_next_account"
|
||||||
|
val parameters = listOf("locale" to locale, "n" to n)
|
||||||
|
|
||||||
|
val resultUpNextAccount = request(watchlistEndpoint, parameters)
|
||||||
|
val list: ContinueWatchingList = resultUpNextAccount.component1()?.obj()?.let {
|
||||||
|
json.decodeFromString(it.toString())
|
||||||
|
} ?: NoneContinueWatchingList
|
||||||
|
|
||||||
|
// val objects = list.items.map{ it.panel.episodeMetadata.seriesId }
|
||||||
|
// return objects(objects)
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,15 +17,19 @@ enum class SortBy(val str: String) {
|
|||||||
/**
|
/**
|
||||||
* search, browse, watchlist data types (all collections)
|
* search, browse, watchlist data types (all collections)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// TODO make generic
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Collection(
|
data class Collection(
|
||||||
@SerialName("total") val total: Int,
|
@SerialName("total") val total: Int,
|
||||||
@SerialName("items") val items: List<Item>
|
@SerialName("items") val items: List<Item>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO don't use aliases
|
||||||
typealias SearchCollection = Collection
|
typealias SearchCollection = Collection
|
||||||
typealias BrowseResult = Collection
|
typealias BrowseResult = Collection
|
||||||
typealias Watchlist = Collection
|
typealias Watchlist = Collection
|
||||||
|
typealias UpNextAccount = Collection
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class SearchResult(
|
data class SearchResult(
|
||||||
@ -44,9 +48,10 @@ data class ContinueWatchingItem(
|
|||||||
@SerialName("panel") val panel: EpisodePanel,
|
@SerialName("panel") val panel: EpisodePanel,
|
||||||
@SerialName("new") val new: Boolean,
|
@SerialName("new") val new: Boolean,
|
||||||
@SerialName("new_content") val newContent: Boolean,
|
@SerialName("new_content") val newContent: Boolean,
|
||||||
@SerialName("is_favorite") val isFavorite: Boolean,
|
// not present in up_next_account's continue_watching_item
|
||||||
@SerialName("never_watched") val neverWatched: Boolean,
|
// @SerialName("is_favorite") val isFavorite: Boolean,
|
||||||
@SerialName("completion_status") val completionStatus: Boolean,
|
// @SerialName("never_watched") val neverWatched: Boolean,
|
||||||
|
// @SerialName("completion_status") val completionStatus: Boolean,
|
||||||
@SerialName("playhead") val playhead: Int,
|
@SerialName("playhead") val playhead: Int,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,12 +15,13 @@ import org.mosad.teapod.util.ItemMedia
|
|||||||
import org.mosad.teapod.util.adapter.MediaItemAdapter
|
import org.mosad.teapod.util.adapter.MediaItemAdapter
|
||||||
import org.mosad.teapod.util.decoration.MediaItemDecoration
|
import org.mosad.teapod.util.decoration.MediaItemDecoration
|
||||||
import org.mosad.teapod.util.showFragment
|
import org.mosad.teapod.util.showFragment
|
||||||
|
import org.mosad.teapod.util.toItemMediaList
|
||||||
|
|
||||||
class HomeFragment : Fragment() {
|
class HomeFragment : Fragment() {
|
||||||
|
|
||||||
private lateinit var binding: FragmentHomeBinding
|
private lateinit var binding: FragmentHomeBinding
|
||||||
|
private lateinit var adapterUpNext: MediaItemAdapter
|
||||||
private lateinit var adapterWatchlist: MediaItemAdapter
|
private lateinit var adapterWatchlist: MediaItemAdapter
|
||||||
private lateinit var adapterNewEpisodes: MediaItemAdapter
|
|
||||||
private lateinit var adapterNewTitles: MediaItemAdapter
|
private lateinit var adapterNewTitles: MediaItemAdapter
|
||||||
private lateinit var adapterTopTen: MediaItemAdapter
|
private lateinit var adapterTopTen: MediaItemAdapter
|
||||||
|
|
||||||
@ -71,17 +72,21 @@ class HomeFragment : Fragment() {
|
|||||||
|
|
||||||
val asyncJobList = arrayListOf<Job>()
|
val asyncJobList = arrayListOf<Job>()
|
||||||
|
|
||||||
|
// continue watching
|
||||||
|
val upNextJob = lifecycleScope.launch {
|
||||||
|
// TODO create EpisodeItemAdapter, which will start the playback of the selected episode immediately
|
||||||
|
adapterUpNext = MediaItemAdapter(Crunchyroll.upNextAccount().toItemMediaList())
|
||||||
|
binding.recyclerNewEpisodes.adapter = adapterUpNext
|
||||||
|
}
|
||||||
|
asyncJobList.add(upNextJob)
|
||||||
|
|
||||||
// watchlist
|
// watchlist
|
||||||
val watchlistJob = lifecycleScope.launch {
|
val watchlistJob = lifecycleScope.launch {
|
||||||
adapterWatchlist = MediaItemAdapter(mapMyListToItemMedia())
|
adapterWatchlist = MediaItemAdapter(Crunchyroll.watchlist(50).toItemMediaList())
|
||||||
binding.recyclerWatchlist.adapter = adapterWatchlist
|
binding.recyclerWatchlist.adapter = adapterWatchlist
|
||||||
}
|
}
|
||||||
asyncJobList.add(watchlistJob)
|
asyncJobList.add(watchlistJob)
|
||||||
|
|
||||||
// new episodes TODO replace with continue watching
|
|
||||||
// adapterNewEpisodes = MediaItemAdapter(AoDParser.newEpisodesList)
|
|
||||||
// binding.recyclerNewEpisodes.adapter = adapterNewEpisodes
|
|
||||||
|
|
||||||
// new titles TODO
|
// new titles TODO
|
||||||
// adapterNewTitles = MediaItemAdapter(AoDParser.newTitlesList)
|
// adapterNewTitles = MediaItemAdapter(AoDParser.newTitlesList)
|
||||||
// binding.recyclerNewTitles.adapter = adapterNewTitles
|
// binding.recyclerNewTitles.adapter = adapterNewTitles
|
||||||
@ -122,18 +127,14 @@ class HomeFragment : Fragment() {
|
|||||||
activity?.showFragment(MediaFragment(""))
|
activity?.showFragment(MediaFragment(""))
|
||||||
}
|
}
|
||||||
|
|
||||||
adapterWatchlist.onItemClick = { id, _ ->
|
adapterUpNext.onItemClick = { id, _ ->
|
||||||
activity?.showFragment(MediaFragment("")) //(mediaId))
|
activity?.showFragment(MediaFragment(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
adapterWatchlist.onItemClick = { id, _ ->
|
||||||
|
activity?.showFragment(MediaFragment(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
// adapterNewEpisodes.onItemClick = { id, _ ->
|
|
||||||
// activity?.showFragment(MediaFragment("")) //(mediaId))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// adapterNewSimulcasts.onItemClick = { id, _ ->
|
|
||||||
// activity?.showFragment(MediaFragment("")) //(mediaId))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// adapterNewTitles.onItemClick = { id, _ ->
|
// adapterNewTitles.onItemClick = { id, _ ->
|
||||||
// activity?.showFragment(MediaFragment("")) //(mediaId))
|
// activity?.showFragment(MediaFragment("")) //(mediaId))
|
||||||
// }
|
// }
|
||||||
@ -143,10 +144,4 @@ class HomeFragment : Fragment() {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun mapMyListToItemMedia(): List<ItemMedia> {
|
|
||||||
return Crunchyroll.watchlist(50).items.map {
|
|
||||||
ItemMedia(it.id, it.title, it.images.poster_wide[0][0].source)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,8 @@
|
|||||||
package org.mosad.teapod.util
|
package org.mosad.teapod.util
|
||||||
|
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import org.mosad.teapod.parser.crunchyroll.Collection
|
||||||
|
import org.mosad.teapod.parser.crunchyroll.ContinueWatchingList
|
||||||
|
|
||||||
fun TextView.setDrawableTop(drawable: Int) {
|
fun TextView.setDrawableTop(drawable: Int) {
|
||||||
this.setCompoundDrawablesWithIntrinsicBounds(0, drawable, 0, 0)
|
this.setCompoundDrawablesWithIntrinsicBounds(0, drawable, 0, 0)
|
||||||
@ -9,3 +11,18 @@ fun TextView.setDrawableTop(drawable: Int) {
|
|||||||
fun <T> concatenate(vararg lists: List<T>): List<T> {
|
fun <T> concatenate(vararg lists: List<T>): List<T> {
|
||||||
return listOf(*lists).flatten()
|
return listOf(*lists).flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO move to correct location
|
||||||
|
fun Collection.toItemMediaList(): List<ItemMedia> {
|
||||||
|
return this.items.map {
|
||||||
|
ItemMedia(it.id, it.title, it.images.poster_wide[0][0].source)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ContinueWatchingList.toItemMediaList(): List<ItemMedia> {
|
||||||
|
return this.items.map {
|
||||||
|
// TODO add season and episode to title
|
||||||
|
ItemMedia(it.panel.episodeMetadata.seriesId, it.panel.title, it.panel.images.thumbnail[0][0].source)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -107,6 +107,34 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linear_up_next"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingBottom="7dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_new_episodes"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingTop="15dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
android:paddingBottom="5dp"
|
||||||
|
android:text="@string/up_next"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_new_episodes"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
tools:listitem="@layout/item_media" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/linear_watchlist"
|
android:id="@+id/linear_watchlist"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -135,34 +163,6 @@
|
|||||||
tools:listitem="@layout/item_media" />
|
tools:listitem="@layout/item_media" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/linear_new_episodes"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingBottom="7dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/text_new_episodes"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingStart="10dp"
|
|
||||||
android:paddingTop="15dp"
|
|
||||||
android:paddingEnd="5dp"
|
|
||||||
android:paddingBottom="5dp"
|
|
||||||
android:text="@string/new_episodes"
|
|
||||||
android:textSize="16sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/recycler_new_episodes"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
|
||||||
tools:listitem="@layout/item_media" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/linear_new_titles"
|
android:id="@+id/linear_new_titles"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -111,6 +111,7 @@
|
|||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:layout_marginEnd="7dp"
|
android:layout_marginEnd="7dp"
|
||||||
android:text="@string/text_title_ex"
|
android:text="@string/text_title_ex"
|
||||||
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@ -128,7 +129,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="12dp"
|
||||||
android:layout_marginTop="7dp"
|
android:layout_marginTop="5dp"
|
||||||
android:layout_marginEnd="12dp"
|
android:layout_marginEnd="12dp"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
@ -136,15 +137,19 @@
|
|||||||
android:id="@+id/linear_my_list_action"
|
android:id="@+id/linear_my_list_action"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:foreground="?android:selectableItemBackground"
|
||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/image_my_list_action"
|
android:id="@+id/image_my_list_action"
|
||||||
android:layout_width="36dp"
|
android:layout_width="48dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="48dp"
|
||||||
android:contentDescription="@string/my_list"
|
android:contentDescription="@string/my_list"
|
||||||
android:padding="5dp"
|
android:paddingStart="11dp"
|
||||||
|
android:paddingTop="11dp"
|
||||||
|
android:paddingEnd="11dp"
|
||||||
|
android:paddingBottom="7dp"
|
||||||
android:src="@drawable/ic_baseline_add_24"
|
android:src="@drawable/ic_baseline_add_24"
|
||||||
app:tint="?buttonBackground" />
|
app:tint="?buttonBackground" />
|
||||||
|
|
||||||
@ -164,7 +169,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="7dp"
|
android:layout_marginStart="7dp"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="7dp"
|
||||||
android:layout_marginEnd="7dp"
|
android:layout_marginEnd="7dp"
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
app:tabGravity="start"
|
app:tabGravity="start"
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
<!-- home fragment -->
|
<!-- home fragment -->
|
||||||
<string name="highlight_media">Highlight</string>
|
<string name="highlight_media">Highlight</string>
|
||||||
|
<string name="up_next">Weiterschauen</string>
|
||||||
<string name="my_list">Meine Liste</string>
|
<string name="my_list">Meine Liste</string>
|
||||||
<string name="new_episodes">Neue Episoden</string>
|
<string name="new_episodes">Neue Episoden</string>
|
||||||
<string name="new_simulcasts">Neue Simulcasts</string>
|
<string name="new_simulcasts">Neue Simulcasts</string>
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
<!-- home fragment -->
|
<!-- home fragment -->
|
||||||
<string name="highlight_media">Highlight</string>
|
<string name="highlight_media">Highlight</string>
|
||||||
|
<string name="up_next">Up next</string>
|
||||||
<string name="my_list">My list</string>
|
<string name="my_list">My list</string>
|
||||||
<string name="new_episodes">New episodes</string>
|
<string name="new_episodes">New episodes</string>
|
||||||
<string name="new_simulcasts">New simulcasts</string>
|
<string name="new_simulcasts">New simulcasts</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user