This commit is contained in:
LagradOst 2021-06-26 21:32:50 +02:00
parent f0df8ec391
commit 41d81a0c40
7 changed files with 134 additions and 40 deletions

View file

@ -193,7 +193,14 @@ fun LoadResponse?.isAnimeBased(): Boolean {
return (this.type == TvType.Anime || this.type == TvType.ONA) // && (this is AnimeLoadResponse) return (this.type == TvType.Anime || this.type == TvType.ONA) // && (this is AnimeLoadResponse)
} }
data class AnimeEpisode(val url: String, val name: String? = null) data class AnimeEpisode(
val url: String,
val name: String? = null,
val posterUrl: String? = null,
val date: String? = null,
val rating: Int? = null,
val descript: String? = null,
)
data class AnimeLoadResponse( data class AnimeLoadResponse(
val engName: String?, val engName: String?,

View file

@ -1,5 +1,6 @@
package com.lagradost.cloudstream3.ui.result package com.lagradost.cloudstream3.ui.result
import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -7,12 +8,19 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import androidx.annotation.LayoutRes
import androidx.core.widget.ContentLoadingProgressBar
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl
import com.google.android.gms.cast.framework.CastContext import com.google.android.gms.cast.framework.CastContext
import com.google.android.gms.cast.framework.CastState import com.google.android.gms.cast.framework.CastState
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.UIHelper.isCastApiAvailable import com.lagradost.cloudstream3.UIHelper.isCastApiAvailable
import kotlinx.android.synthetic.main.result_episode.view.* import kotlinx.android.synthetic.main.result_episode.view.*
import kotlinx.android.synthetic.main.result_episode.view.episode_holder
import kotlinx.android.synthetic.main.result_episode.view.episode_text
import kotlinx.android.synthetic.main.result_episode_large.view.*
const val ACTION_PLAY_EPISODE_IN_PLAYER = 1 const val ACTION_PLAY_EPISODE_IN_PLAYER = 1
const val ACTION_RELOAD_EPISODE = 4 const val ACTION_RELOAD_EPISODE = 4
@ -27,10 +35,21 @@ class EpisodeAdapter(
private val clickCallback: (EpisodeClickEvent) -> Unit, private val clickCallback: (EpisodeClickEvent) -> Unit,
) : ) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() { RecyclerView.Adapter<RecyclerView.ViewHolder>() {
@LayoutRes
private var layout: Int = 0
fun updateLayout() {
layout = if (cardList.filter { it.poster != null }.size >= cardList.size / 2)
R.layout.result_episode_large
else R.layout.result_episode
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
/*val layout = if (cardList.filter { it.poster != null }.size >= cardList.size / 2)
R.layout.result_episode_large
else R.layout.result_episode*/
return CardViewHolder( return CardViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.result_episode, parent, false), LayoutInflater.from(parent.context).inflate(layout, parent, false),
activity, activity,
resView, resView,
clickCallback clickCallback
@ -56,13 +75,19 @@ class EpisodeAdapter(
resView: RecyclerView, resView: RecyclerView,
private val clickCallback: (EpisodeClickEvent) -> Unit, private val clickCallback: (EpisodeClickEvent) -> Unit,
) : RecyclerView.ViewHolder(itemView) { ) : RecyclerView.ViewHolder(itemView) {
private val episodeViewPrecentage: View = itemView.episode_view_procentage private val episodeViewPrecentage: View? = itemView.episode_view_procentage
private val episodeViewPercentageOff: View = itemView.episode_view_procentage_off private val episodeViewPercentageOff: View? = itemView.episode_view_procentage_off
private val episodeText: TextView = itemView.episode_text private val episodeText: TextView = itemView.episode_text
val episodeExtra: ImageView = itemView.episode_extra private val episodeRating: TextView? = itemView.episode_rating
private val episodePlay: ImageView = itemView.episode_play private val episodeDescript: TextView? = itemView.episode_descript
private val episodeProgress: ContentLoadingProgressBar? = itemView.episode_progress
private val episodePoster: ImageView? = itemView.episode_poster
// val episodeExtra: ImageView = itemView.episode_extra
// private val episodePlay: ImageView = itemView.episode_play
private val episodeHolder = itemView.episode_holder private val episodeHolder = itemView.episode_holder
@SuppressLint("SetTextI18n")
fun bind(card: ResultEpisode) { fun bind(card: ResultEpisode) {
episodeText.text = card.name ?: "Episode ${card.episode}" episodeText.text = card.name ?: "Episode ${card.episode}"
@ -76,8 +101,41 @@ class EpisodeAdapter(
} }
val watchProgress = card.getWatchProgress() val watchProgress = card.getWatchProgress()
if (episodeViewPrecentage != null && episodeViewPercentageOff != null) {
setWidth(episodeViewPrecentage, watchProgress) setWidth(episodeViewPrecentage, watchProgress)
setWidth(episodeViewPercentageOff, 1 - watchProgress) setWidth(episodeViewPercentageOff, 1 - watchProgress)
}
episodeProgress?.progress = (watchProgress * 50).toInt()
episodeProgress?.visibility = if (watchProgress > 0.0f) View.VISIBLE else View.GONE
if (card.poster != null) {
episodePoster?.visibility = View.VISIBLE
if (episodePoster != null) {
val glideUrl =
GlideUrl(card.poster)
activity.let {
Glide.with(it)
.load(glideUrl)
.into(episodePoster)
}
}
} else {
episodePoster?.visibility = View.GONE
}
if (card.rating != null) {
episodeRating?.text = "%.1f".format(card.rating.toFloat() / 10f).replace(",", ".")
} else {
episodeRating?.text = ""
}
if (card.descript != null) {
episodeDescript?.visibility = View.VISIBLE
episodeDescript?.text = card.descript
} else {
episodeDescript?.visibility = View.GONE
}
episodeHolder.setOnClickListener { episodeHolder.setOnClickListener {
if (activity.isCastApiAvailable()) { if (activity.isCastApiAvailable()) {

View file

@ -64,6 +64,8 @@ data class ResultEpisode(
val index: Int, val index: Int,
val position: Long, // time in MS val position: Long, // time in MS
val duration: Long, // duration in MS val duration: Long, // duration in MS
val rating: Int?,
val descript: String?,
) )
fun ResultEpisode.getRealPosition(): Long { fun ResultEpisode.getRealPosition(): Long {
@ -91,9 +93,12 @@ fun Context.buildResultEpisode(
apiName: String, apiName: String,
id: Int, id: Int,
index: Int, index: Int,
rating: Int?,
descript: String?,
): ResultEpisode { ): ResultEpisode {
val posDur = getViewPos(id) val posDur = getViewPos(id)
return ResultEpisode(name, return ResultEpisode(
name,
poster, poster,
episode, episode,
season, season,
@ -102,7 +107,10 @@ fun Context.buildResultEpisode(
id, id,
index, index,
posDur?.position ?: 0, posDur?.position ?: 0,
posDur?.duration ?: 0) posDur?.duration ?: 0,
rating,
descript,
)
} }
fun ResultEpisode.getWatchProgress(): Float { fun ResultEpisode.getWatchProgress(): Float {
@ -355,6 +363,7 @@ class ResultFragment : Fragment() {
result_episodes_text.text = "${episodes.size} Episode${if (episodes.size == 1) "" else "s"}" result_episodes_text.text = "${episodes.size} Episode${if (episodes.size == 1) "" else "s"}"
currentEpisodes = episodes currentEpisodes = episodes
(result_episodes.adapter as EpisodeAdapter).cardList = episodes (result_episodes.adapter as EpisodeAdapter).cardList = episodes
(result_episodes.adapter as EpisodeAdapter).updateLayout()
(result_episodes.adapter as EpisodeAdapter).notifyDataSetChanged() (result_episodes.adapter as EpisodeAdapter).notifyDataSetChanged()
} }
@ -400,7 +409,7 @@ class ResultFragment : Fragment() {
if (d.year != null) metadataInfoArray.add(Pair("Year", d.year.toString())) if (d.year != null) metadataInfoArray.add(Pair("Year", d.year.toString()))
val rating = d.rating val rating = d.rating
if (rating != null) metadataInfoArray.add(Pair("Rating", if (rating != null) metadataInfoArray.add(Pair("Rating",
"%.2f/10.0".format(rating.toFloat() / 10f).replace(",", "."))) "%.1f/10.0".format(rating.toFloat() / 10f).replace(",", ".")))
val duration = d.duration val duration = d.duration
if (duration != null) metadataInfoArray.add(Pair("Duration", duration)) if (duration != null) metadataInfoArray.add(Pair("Duration", duration))

View file

@ -87,13 +87,15 @@ class ResultViewModel : ViewModel() {
for ((index, i) in dataList.withIndex()) { for ((index, i) in dataList.withIndex()) {
episodes.add(context.buildResultEpisode( episodes.add(context.buildResultEpisode(
i.name, i.name,
null, i.posterUrl,
index + 1, //TODO MAKE ABLE TO NOT HAVE SOME EPISODE index + 1, //TODO MAKE ABLE TO NOT HAVE SOME EPISODE
null, // TODO FIX SEASON null, // TODO FIX SEASON
i.url, i.url,
apiName, apiName,
(mainId + index + 1), (mainId + index + 1),
index, index,
i.rating,
i.descript,
)) ))
} }
_episodes.postValue(episodes) _episodes.postValue(episodes)
@ -106,13 +108,15 @@ class ResultViewModel : ViewModel() {
episodes.add(context.buildResultEpisode( episodes.add(context.buildResultEpisode(
(i.name (i.name
?: (if (i.season != null && i.episode != null) "S${i.season}:E${i.episode}" else null)), // TODO ADD NAMES ?: (if (i.season != null && i.episode != null) "S${i.season}:E${i.episode}" else null)), // TODO ADD NAMES
null, i.posterUrl,
i.episode ?: (index + 1), i.episode ?: (index + 1),
i.season, i.season,
i.data, i.data,
apiName, apiName,
(mainId + index + 1).hashCode(), (mainId + index + 1).hashCode(),
index, index,
i.rating,
i.descript
)) ))
} }
_episodes.postValue(episodes) _episodes.postValue(episodes)
@ -126,6 +130,8 @@ class ResultViewModel : ViewModel() {
d.apiName, d.apiName,
(mainId + 1), (mainId + 1),
0, 0,
null,
null,
))) )))
} }
} }

View file

@ -17,7 +17,9 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
> >
<FrameLayout android:layout_gravity="center_vertical" android:layout_width="match_parent" <FrameLayout
android:layout_gravity="center_vertical"
android:layout_width="match_parent"
android:layout_marginEnd="30dp" android:layout_marginEnd="30dp"
android:layout_height="30dp"> android:layout_height="30dp">
<androidx.appcompat.widget.SearchView <androidx.appcompat.widget.SearchView

View file

@ -6,7 +6,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
app:cardCornerRadius="@dimen/roundedImageRadius" app:cardCornerRadius="@dimen/roundedImageRadius"
app:cardBackgroundColor="?attr/itemBackground" app:cardBackgroundColor="@color/itemBackground"
android:id="@+id/episode_holder" android:id="@+id/episode_holder"
android:foreground="?android:attr/selectableItemBackgroundBorderless" android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:layout_marginBottom="5dp" android:layout_marginBottom="5dp"
@ -16,9 +16,12 @@
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<LinearLayout android:layout_width="match_parent" android:orientation="horizontal" <LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<FrameLayout <androidx.cardview.widget.CardView
app:cardCornerRadius="@dimen/roundedImageRadius"
android:layout_width="126dp" android:layout_width="126dp"
android:layout_height="72dp" android:layout_height="72dp"
> >
@ -30,7 +33,8 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:contentDescription="@string/episode_poster"> android:contentDescription="@string/episode_poster">
</ImageView> </ImageView>
<ImageView tools:src="@drawable/play_button" <ImageView
android:src="@drawable/play_button"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
@ -44,26 +48,34 @@
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:layout_height="5dp"> android:layout_height="5dp">
</androidx.core.widget.ContentLoadingProgressBar> </androidx.core.widget.ContentLoadingProgressBar>
</FrameLayout> </androidx.cardview.widget.CardView>
<LinearLayout android:layout_marginStart="10dp" android:orientation="vertical" <LinearLayout
android:layout_gravity="center" android:layout_width="match_parent" android:layout_marginStart="15dp"
android:orientation="vertical"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/episode_text"
tools:text="1. Jobless"
android:textColor="@color/textColor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<TextView android:id="@+id/episode_text" tools:text="1. Jobless" android:textColor="?attr/textColor"
android:layout_width="wrap_content" android:layout_height="wrap_content">
</TextView> </TextView>
<TextView android:id="@+id/episode_rating" <TextView
android:id="@+id/episode_rating"
tools:text="8.8" tools:text="8.8"
android:textColor="?attr/grayTextColor" android:textColor="@color/grayTextColor"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
</TextView> </TextView>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<TextView <TextView
android:paddingTop="2.5dp" android:paddingTop="10dp"
android:paddingBottom="10dp"
android:id="@+id/episode_descript" android:id="@+id/episode_descript"
android:textColor="?attr/grayTextColor" android:textColor="@color/grayTextColor"
tools:text="Jon and Daenerys arrive in Winterfell and are met with skepticism. Sam learns about the fate of his family. Cersei gives Euron the reward he aims for. Theon follows his heart. " tools:text="Jon and Daenerys arrive in Winterfell and are met with skepticism. Sam learns about the fate of his family. Cersei gives Euron the reward he aims for. Theon follows his heart. "
android:layout_width="match_parent" android:layout_height="wrap_content"> android:layout_width="match_parent" android:layout_height="wrap_content">
</TextView> </TextView>

View file

@ -12,7 +12,7 @@
<color name="darkBackground">#2B2C30</color> <!--0f0f10 0E0E10 303135 2B2C30--> <color name="darkBackground">#2B2C30</color> <!--0f0f10 0E0E10 303135 2B2C30-->
<color name="bitDarkerGrayBackground">#1C1C20</color> <!--191a1f 19181E 202125 1C1C20--> <color name="bitDarkerGrayBackground">#1C1C20</color> <!--191a1f 19181E 202125 1C1C20-->
<color name="grayBackground">#1C1C20</color> <!--141419 202125--> <color name="grayBackground">#1C1C20</color> <!--141419 202125-->
<color name="itemBackground">#17171B</color> <!--1B1B20--> <color name="itemBackground">#17171B</color> <!-- 17171B 1B1B20-->
<color name="textColor">#e9eaee</color> <!--FFF--> <color name="textColor">#e9eaee</color> <!--FFF-->
<color name="grayTextColor">#9ba0a4</color> <!-- 5e5f62--> <color name="grayTextColor">#9ba0a4</color> <!-- 5e5f62-->