fixed #832 and fixed #835

This commit is contained in:
LagradOst 2022-03-21 00:59:17 +01:00
parent c2ba8dc7e4
commit 2870ad435f
9 changed files with 444 additions and 394 deletions

View file

@ -101,7 +101,7 @@ object APIHolder {
) )
} }
var apis : List<MainAPI> = arrayListOf() var apis: List<MainAPI> = arrayListOf()
fun getApiFromName(apiName: String?): MainAPI { fun getApiFromName(apiName: String?): MainAPI {
return getApiFromNameNull(apiName) ?: apis[defProvider] return getApiFromNameNull(apiName) ?: apis[defProvider]
@ -148,7 +148,7 @@ object APIHolder {
val domain = encodeToString( val domain = encodeToString(
(uri.scheme + "://" + uri.host + ":443").encodeToByteArray(), (uri.scheme + "://" + uri.host + ":443").encodeToByteArray(),
0 0
).replace("\n", "").replace("=",".") ).replace("\n", "").replace("=", ".")
val vToken = val vToken =
app.get( app.get(
@ -281,7 +281,8 @@ object APIHolder {
3 = restricted, must donate 30 benenes to use 3 = restricted, must donate 30 benenes to use
*/ */
const val PROVIDER_STATUS_KEY = "PROVIDER_STATUS_KEY" const val PROVIDER_STATUS_KEY = "PROVIDER_STATUS_KEY"
const val PROVIDER_STATUS_URL = "https://raw.githubusercontent.com/LagradOst/CloudStream-3/master/providers.json" const val PROVIDER_STATUS_URL =
"https://raw.githubusercontent.com/LagradOst/CloudStream-3/master/providers.json"
const val PROVIDER_STATUS_BETA_ONLY = 3 const val PROVIDER_STATUS_BETA_ONLY = 3
const val PROVIDER_STATUS_SLOW = 2 const val PROVIDER_STATUS_SLOW = 2
const val PROVIDER_STATUS_OK = 1 const val PROVIDER_STATUS_OK = 1
@ -296,10 +297,10 @@ data class ProvidersInfoJson(
/**Every provider will **not** have try catch built in, so handle exceptions when calling these functions*/ /**Every provider will **not** have try catch built in, so handle exceptions when calling these functions*/
abstract class MainAPI { abstract class MainAPI {
companion object { companion object {
var overrideData : HashMap<String, ProvidersInfoJson>? = null var overrideData: HashMap<String, ProvidersInfoJson>? = null
} }
public fun overrideWithNewData(data : ProvidersInfoJson) { public fun overrideWithNewData(data: ProvidersInfoJson) {
this.name = data.name this.name = data.name
this.mainUrl = data.url this.mainUrl = data.url
} }
@ -540,13 +541,28 @@ class HomePageList(
var list: List<SearchResponse> var list: List<SearchResponse>
) )
enum class SearchQuality {
//https://en.wikipedia.org/wiki/Pirated_movie_release_types
Cam,
CamRip,
HdCam,
Telesync, // TS
WorkPrint,
Telecine, // TC
HQ,
HD,
BlueRay,
DVD,
}
interface SearchResponse { interface SearchResponse {
val name: String val name: String
val url: String val url: String
val apiName: String val apiName: String
val type: TvType? var type: TvType?
val posterUrl: String? var posterUrl: String?
val id: Int? var id: Int?
var quality : SearchQuality?
} }
enum class ActorRole { enum class ActorRole {
@ -571,49 +587,53 @@ data class AnimeSearchResponse(
override val name: String, override val name: String,
override val url: String, override val url: String,
override val apiName: String, override val apiName: String,
override val type: TvType, override var type: TvType?,
override val posterUrl: String?, override var posterUrl: String?,
val year: Int? = null, val year: Int? = null,
val dubStatus: EnumSet<DubStatus>? = null, val dubStatus: EnumSet<DubStatus>? = null,
val otherName: String? = null, val otherName: String? = null,
val dubEpisodes: Int? = null, val dubEpisodes: Int? = null,
val subEpisodes: Int? = null, val subEpisodes: Int? = null,
override val id: Int? = null, override var id: Int? = null,
override var quality: SearchQuality? = null,
) : SearchResponse ) : SearchResponse
data class TorrentSearchResponse( data class TorrentSearchResponse(
override val name: String, override val name: String,
override val url: String, override val url: String,
override val apiName: String, override val apiName: String,
override val type: TvType, override var type: TvType?,
override val posterUrl: String?, override var posterUrl: String?,
override val id: Int? = null, override var id: Int? = null,
override var quality: SearchQuality? = null,
) : SearchResponse ) : SearchResponse
data class MovieSearchResponse( data class MovieSearchResponse(
override val name: String, override val name: String,
override val url: String, override val url: String,
override val apiName: String, override val apiName: String,
override val type: TvType, override var type: TvType?,
override val posterUrl: String?, override var posterUrl: String?,
val year: Int? = null, val year: Int? = null,
override val id: Int? = null, override var id: Int? = null,
override var quality: SearchQuality? = null,
) : SearchResponse ) : SearchResponse
data class TvSeriesSearchResponse( data class TvSeriesSearchResponse(
override val name: String, override val name: String,
override val url: String, override val url: String,
override val apiName: String, override val apiName: String,
override val type: TvType, override var type: TvType?,
override val posterUrl: String?, override var posterUrl: String?,
val year: Int?, val year: Int?,
val episodes: Int?, val episodes: Int?,
override val id: Int? = null, override var id: Int? = null,
override var quality: SearchQuality? = null,
) : SearchResponse ) : SearchResponse
interface LoadResponse { interface LoadResponse {
@ -630,6 +650,7 @@ interface LoadResponse {
val trailerUrl: String? val trailerUrl: String?
var recommendations: List<SearchResponse>? var recommendations: List<SearchResponse>?
var actors: List<ActorData>? var actors: List<ActorData>?
var comingSoon: Boolean
companion object { companion object {
@JvmName("addActorNames") @JvmName("addActorNames")
@ -715,6 +736,7 @@ data class TorrentLoadResponse(
override var trailerUrl: String? = null, override var trailerUrl: String? = null,
override var recommendations: List<SearchResponse>? = null, override var recommendations: List<SearchResponse>? = null,
override var actors: List<ActorData>? = null, override var actors: List<ActorData>? = null,
override var comingSoon: Boolean = false,
) : LoadResponse ) : LoadResponse
data class AnimeLoadResponse( data class AnimeLoadResponse(
@ -742,6 +764,7 @@ data class AnimeLoadResponse(
override var trailerUrl: String? = null, override var trailerUrl: String? = null,
override var recommendations: List<SearchResponse>? = null, override var recommendations: List<SearchResponse>? = null,
override var actors: List<ActorData>? = null, override var actors: List<ActorData>? = null,
override var comingSoon: Boolean = false,
) : LoadResponse ) : LoadResponse
fun AnimeLoadResponse.addEpisodes(status: DubStatus, episodes: List<AnimeEpisode>?) { fun AnimeLoadResponse.addEpisodes(status: DubStatus, episodes: List<AnimeEpisode>?) {
@ -753,13 +776,31 @@ fun MainAPI.newAnimeLoadResponse(
name: String, name: String,
url: String, url: String,
type: TvType, type: TvType,
initializer: AnimeLoadResponse.() -> Unit = { } comingSoonIfNone : Boolean,
initializer: AnimeLoadResponse.() -> Unit = { },
): AnimeLoadResponse { ): AnimeLoadResponse {
val builder = AnimeLoadResponse(name = name, url = url, apiName = this.name, type = type) val builder = AnimeLoadResponse(name = name, url = url, apiName = this.name, type = type)
builder.initializer() builder.initializer()
if(comingSoonIfNone) {
builder.comingSoon = true
for (key in builder.episodes.keys)
if(!builder.episodes[key].isNullOrEmpty()) {
builder.comingSoon = false
break
}
}
return builder return builder
} }
fun MainAPI.newAnimeLoadResponse(
name: String,
url: String,
type: TvType,
initializer: AnimeLoadResponse.() -> Unit = { },
): AnimeLoadResponse {
return newAnimeLoadResponse(name, url, type, true, initializer)
}
data class MovieLoadResponse( data class MovieLoadResponse(
override var name: String, override var name: String,
override var url: String, override var url: String,
@ -778,6 +819,7 @@ data class MovieLoadResponse(
override var trailerUrl: String? = null, override var trailerUrl: String? = null,
override var recommendations: List<SearchResponse>? = null, override var recommendations: List<SearchResponse>? = null,
override var actors: List<ActorData>? = null, override var actors: List<ActorData>? = null,
override var comingSoon: Boolean = false,
) : LoadResponse ) : LoadResponse
fun MainAPI.newMovieLoadResponse( fun MainAPI.newMovieLoadResponse(
@ -792,7 +834,8 @@ fun MainAPI.newMovieLoadResponse(
url = url, url = url,
apiName = this.name, apiName = this.name,
type = type, type = type,
dataUrl = dataUrl dataUrl = dataUrl,
comingSoon = dataUrl.isBlank()
) )
builder.initializer() builder.initializer()
return builder return builder
@ -828,6 +871,7 @@ data class TvSeriesLoadResponse(
override var trailerUrl: String? = null, override var trailerUrl: String? = null,
override var recommendations: List<SearchResponse>? = null, override var recommendations: List<SearchResponse>? = null,
override var actors: List<ActorData>? = null, override var actors: List<ActorData>? = null,
override var comingSoon: Boolean = false,
) : LoadResponse ) : LoadResponse
fun MainAPI.newTvSeriesLoadResponse( fun MainAPI.newTvSeriesLoadResponse(
@ -842,7 +886,8 @@ fun MainAPI.newTvSeriesLoadResponse(
url = url, url = url,
apiName = this.name, apiName = this.name,
type = type, type = type,
episodes = episodes episodes = episodes,
comingSoon = episodes.isEmpty(),
) )
builder.initializer() builder.initializer()
return builder return builder

View file

@ -157,7 +157,7 @@ open class SflixProvider() : MainAPI() {
val dataId = details.attr("data-id") val dataId = details.attr("data-id")
val id = if (dataId.isNullOrEmpty()) val id = if (dataId.isNullOrEmpty())
idRegex.find(url)?.groupValues?.get(1) idRegex.find(url)?.groupValues?.get(1)
?: throw RuntimeException("Unable to get id from '$url'") ?: throw ErrorLoadingException("Unable to get id from '$url'")
else dataId else dataId
val recommendations = val recommendations =
@ -199,6 +199,8 @@ open class SflixProvider() : MainAPI() {
} }
} }
val comingSoon = sourceIds.isEmpty()
return newMovieLoadResponse(title, url, TvType.Movie, sourceIds.toJson()) { return newMovieLoadResponse(title, url, TvType.Movie, sourceIds.toJson()) {
this.year = year this.year = year
this.posterUrl = posterUrl this.posterUrl = posterUrl
@ -207,6 +209,7 @@ open class SflixProvider() : MainAPI() {
addActors(cast) addActors(cast)
this.tags = tags this.tags = tags
this.recommendations = recommendations this.recommendations = recommendations
this.comingSoon = comingSoon
} }
} else { } else {
val seasonsDocument = app.get("$mainUrl/ajax/v2/tv/seasons/$id").document val seasonsDocument = app.get("$mainUrl/ajax/v2/tv/seasons/$id").document
@ -252,6 +255,7 @@ open class SflixProvider() : MainAPI() {
) )
} }
} }
return newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes) { return newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes) {
this.posterUrl = posterUrl this.posterUrl = posterUrl
this.year = year this.year = year

View file

@ -1375,12 +1375,13 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
val sourceDialog = sourceBuilder.create() val sourceDialog = sourceBuilder.create()
sourceDialog.show() sourceDialog.show()
sourceDialog.findViewById<ImageView?>(R.id.imgPoster)?.apply { sourceDialog.findViewById<ImageView?>(R.id.imgPoster)
setImageBitmap(bitmap) ?.apply {
setOnClickListener { setImageBitmap(bitmap)
sourceDialog.dismissSafe() setOnClickListener {
sourceDialog.dismissSafe()
}
} }
}
} }
} catch (e: Exception) { } catch (e: Exception) {
logError(e) logError(e)
@ -1423,6 +1424,11 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
//result_tag_holder?.visibility = GONE //result_tag_holder?.visibility = GONE
// result_status.visibility = GONE // result_status.visibility = GONE
d.comingSoon.let { soon ->
result_coming_soon?.isVisible = soon
result_data_holder?.isGone = soon
}
val tags = d.tags val tags = d.tags
if (tags.isNullOrEmpty()) { if (tags.isNullOrEmpty()) {
//result_tag_holder?.visibility = GONE //result_tag_holder?.visibility = GONE

View file

@ -150,7 +150,7 @@ object SearchResultBuilder {
playImg?.visibility = View.VISIBLE playImg?.visibility = View.VISIBLE
if (!card.type.isMovieType()) { if (card.type?.isMovieType() == false) {
cardText?.text = cardText?.text =
cardText?.context?.getNameFull(card.name, card.episode, card.season) cardText?.context?.getNameFull(card.name, card.episode, card.season)
} }

View file

@ -4,11 +4,8 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.APIHolder.apis import com.lagradost.cloudstream3.APIHolder.apis
import com.lagradost.cloudstream3.ErrorLoadingException
import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.apmap
import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.safeApiCall import com.lagradost.cloudstream3.mvvm.safeApiCall
import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.SyncApis import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.SyncApis
@ -54,9 +51,10 @@ class SearchViewModel : ViewModel() {
override val name: String, override val name: String,
override val url: String, override val url: String,
override val apiName: String, override val apiName: String,
override val type: TvType?, override var type: TvType?,
override val posterUrl: String?, override var posterUrl: String?,
override val id: Int?, override var id: Int?,
override var quality: SearchQuality? = null
) : SearchResponse ) : SearchResponse
private fun SyncAPI.SyncSearchResult.toSearchResponse(): SyncSearchResultSearchResponse { private fun SyncAPI.SyncSearchResult.toSearchResponse(): SyncSearchResultSearchResponse {

View file

@ -63,7 +63,7 @@ object AppUtils {
context: Context, context: Context,
card: DataStoreHelper.ResumeWatchingResult card: DataStoreHelper.ResumeWatchingResult
): WatchNextProgram { ): WatchNextProgram {
val isSeries = !card.type.isMovieType() val isSeries = card.type?.isMovieType() == false
val title = if (isSeries) { val title = if (isSeries) {
context.getNameFull(card.name, card.episode, card.season) context.getNameFull(card.name, card.episode, card.season)
} else { } else {

View file

@ -6,6 +6,7 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.getKeys
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.DubStatus import com.lagradost.cloudstream3.DubStatus
import com.lagradost.cloudstream3.SearchQuality
import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.TvType import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.ui.WatchType import com.lagradost.cloudstream3.ui.WatchType
@ -33,31 +34,33 @@ object DataStoreHelper {
} }
data class BookmarkedData( data class BookmarkedData(
@JsonProperty("id") override val id: Int?, @JsonProperty("id") override var id: Int?,
@JsonProperty("bookmarkedTime") val bookmarkedTime: Long, @JsonProperty("bookmarkedTime") val bookmarkedTime: Long,
@JsonProperty("latestUpdatedTime") val latestUpdatedTime: Long, @JsonProperty("latestUpdatedTime") val latestUpdatedTime: Long,
@JsonProperty("name") override val name: String, @JsonProperty("name") override val name: String,
@JsonProperty("url") override val url: String, @JsonProperty("url") override val url: String,
@JsonProperty("apiName") override val apiName: String, @JsonProperty("apiName") override val apiName: String,
@JsonProperty("type") override val type: TvType, @JsonProperty("type") override var type: TvType? = null,
@JsonProperty("posterUrl") override val posterUrl: String?, @JsonProperty("posterUrl") override var posterUrl: String?,
@JsonProperty("year") val year: Int?, @JsonProperty("year") val year: Int?,
@JsonProperty("quality") override var quality: SearchQuality? = null
) : SearchResponse ) : SearchResponse
data class ResumeWatchingResult( data class ResumeWatchingResult(
@JsonProperty("name") override val name: String, @JsonProperty("name") override val name: String,
@JsonProperty("url") override val url: String, @JsonProperty("url") override val url: String,
@JsonProperty("apiName") override val apiName: String, @JsonProperty("apiName") override val apiName: String,
@JsonProperty("type") override val type: TvType, @JsonProperty("type") override var type: TvType? = null,
@JsonProperty("posterUrl") override val posterUrl: String?, @JsonProperty("posterUrl") override var posterUrl: String?,
@JsonProperty("watchPos") val watchPos: PosDur?, @JsonProperty("watchPos") val watchPos: PosDur?,
@JsonProperty("id") override val id: Int?, @JsonProperty("id") override var id: Int?,
@JsonProperty("parentId") val parentId: Int?, @JsonProperty("parentId") val parentId: Int?,
@JsonProperty("episode") val episode: Int?, @JsonProperty("episode") val episode: Int?,
@JsonProperty("season") val season: Int?, @JsonProperty("season") val season: Int?,
@JsonProperty("isFromDownload") val isFromDownload: Boolean, @JsonProperty("isFromDownload") val isFromDownload: Boolean,
@JsonProperty("quality") override var quality: SearchQuality? = null
) : SearchResponse ) : SearchResponse
var currentAccount: String = "0" //TODO ACCOUNT IMPLEMENTATION var currentAccount: String = "0" //TODO ACCOUNT IMPLEMENTATION

View file

@ -459,67 +459,64 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<com.google.android.material.button.MaterialButton <TextView
android:paddingTop="50dp"
android:visibility="gone" android:visibility="gone"
android:text="@string/add_sync" android:textColor="?attr/textColor"
android:id="@+id/result_coming_soon"
android:textSize="20sp"
android:gravity="center"
android:textStyle="bold"
android:layout_gravity="center"
android:text="@string/coming_soon"
android:layout_width="match_parent" android:layout_width="match_parent"
app:icon="@drawable/ic_baseline_add_24" android:layout_height="wrap_content" />
android:id="@+id/result_add_sync"
android:layout_gravity="center_vertical"
android:layout_marginStart="0dp"
android:layout_marginBottom="10dp"
style="@style/WhiteButton" />
<LinearLayout <LinearLayout
tools:visibility="visible"
android:layout_marginTop="5dp"
android:orientation="vertical" android:orientation="vertical"
android:id="@+id/result_movie_parent" android:id="@+id/result_data_holder"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:layout_marginBottom="10dp" android:visibility="gone"
android:nextFocusUp="@id/result_bookmark_button" android:text="@string/add_sync"
android:nextFocusDown="@id/result_download_movie" android:layout_width="match_parent"
app:icon="@drawable/ic_baseline_add_24"
android:id="@+id/result_add_sync"
android:id="@+id/result_play_movie"
style="@style/WhiteButton"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:visibility="visible"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:text="@string/play_movie_button"
app:icon="@drawable/ic_baseline_play_arrow_24"
android:layout_width="match_parent" />
<!--<com.google.android.material.button.MaterialButton
android:nextFocusUp="@id/result_play_movie"
android:nextFocusDown="@id/result_season_button"
android:layout_marginBottom="10dp"
android:id="@+id/result_download_movie"
style="@style/BlackButton"
android:layout_marginStart="0dp" android:layout_marginStart="0dp"
android:layout_marginEnd="0dp" android:layout_marginBottom="10dp"
android:visibility="visible" style="@style/WhiteButton" />
android:layout_gravity="center_vertical"
tools:text="Downloading"
tools:icon="@drawable/netflix_download"
android:clickable="true" <LinearLayout
android:focusable="true" tools:visibility="visible"
android:layout_width="match_parent" />--> android:layout_marginTop="5dp"
android:orientation="vertical"
<FrameLayout android:id="@+id/result_movie_parent"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:layout_marginBottom="10dp"
android:nextFocusUp="@id/result_bookmark_button"
android:nextFocusDown="@id/result_download_movie"
android:id="@+id/result_play_movie"
style="@style/WhiteButton"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:visibility="visible"
android:layout_gravity="center_vertical"
android:text="@string/play_movie_button"
app:icon="@drawable/ic_baseline_play_arrow_24"
android:layout_width="match_parent" />
<!--<com.google.android.material.button.MaterialButton
android:nextFocusUp="@id/result_play_movie" android:nextFocusUp="@id/result_play_movie"
android:nextFocusDown="@id/result_season_button" android:nextFocusDown="@id/result_season_button"
android:layout_marginBottom="10dp"
android:id="@+id/result_download_movie" android:id="@+id/result_download_movie"
style="@style/BlackButton" style="@style/BlackButton"
@ -527,339 +524,324 @@
android:layout_marginEnd="0dp" android:layout_marginEnd="0dp"
android:visibility="visible" android:visibility="visible"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
tools:text="Downloading"
tools:icon="@drawable/netflix_download"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:layout_width="match_parent" /> android:layout_width="match_parent" />-->
<LinearLayout <FrameLayout
android:gravity="center"
android:orientation="horizontal"
android:layout_gravity="center"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<androidx.core.widget.ContentLoadingProgressBar <com.google.android.material.button.MaterialButton
android:id="@+id/result_movie_progress_downloaded" android:nextFocusUp="@id/result_play_movie"
android:layout_width="25dp" android:nextFocusDown="@id/result_season_button"
android:layout_height="25dp"
android:indeterminate="false"
android:progressDrawable="@drawable/circular_progress_bar_filled"
android:background="@drawable/circle_shape"
style="?android:attr/progressBarStyleHorizontal"
android:max="100"
android:layout_margin="5dp"
android:paddingEnd="5dp"
android:paddingStart="5dp"
android:layout_gravity="end|center_vertical"
android:progress="30"
android:visibility="visible" />
<ImageView android:id="@+id/result_download_movie"
android:id="@+id/result_movie_download_icon" style="@style/BlackButton"
app:tint="?attr/white" android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:visibility="visible" android:visibility="visible"
android:layout_height="wrap_content" android:layout_gravity="center_vertical"
android:clickable="true"
android:focusable="true"
android:layout_width="match_parent" />
<LinearLayout
android:gravity="center"
android:orientation="horizontal"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_width="30dp" android:layout_width="match_parent"
android:background="?selectableItemBackgroundBorderless" android:layout_height="wrap_content">
android:src="@drawable/ic_baseline_play_arrow_24"
android:contentDescription="@string/download" />
<TextView <androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/result_movie_download_text" android:id="@+id/result_movie_progress_downloaded"
android:letterSpacing="0.09" android:layout_width="25dp"
android:textColor="?attr/textColor" android:layout_height="25dp"
android:textSize="15sp" android:indeterminate="false"
android:textStyle="bold" android:progressDrawable="@drawable/circular_progress_bar_filled"
android:gravity="center" android:background="@drawable/circle_shape"
android:textAllCaps="false" style="?android:attr/progressBarStyleHorizontal"
tools:text="Downloading" android:max="100"
android:layout_width="wrap_content" android:layout_margin="5dp"
android:layout_height="match_parent" /> android:paddingEnd="5dp"
android:paddingStart="5dp"
android:layout_gravity="end|center_vertical"
android:progress="30"
android:visibility="visible" />
<TextView <ImageView
android:visibility="gone" android:id="@+id/result_movie_download_icon"
android:id="@+id/result_movie_download_text_precentage" app:tint="?attr/white"
android:letterSpacing="0.09" android:visibility="visible"
android:paddingStart="5dp" android:layout_height="wrap_content"
android:paddingEnd="5dp" android:layout_gravity="center"
android:textColor="?attr/textColor" android:layout_width="30dp"
android:textSize="15sp" android:background="?selectableItemBackgroundBorderless"
android:textStyle="bold" android:src="@drawable/ic_baseline_play_arrow_24"
android:gravity="center" android:contentDescription="@string/download" />
android:textAllCaps="false"
tools:text="68%" <TextView
android:layout_width="wrap_content" android:id="@+id/result_movie_download_text"
android:layout_height="match_parent" /> android:letterSpacing="0.09"
</LinearLayout> android:textColor="?attr/textColor"
</FrameLayout> android:textSize="15sp"
android:textStyle="bold"
android:gravity="center"
android:textAllCaps="false"
tools:text="Downloading"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<TextView
android:visibility="gone"
android:id="@+id/result_movie_download_text_precentage"
android:letterSpacing="0.09"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:textColor="?attr/textColor"
android:textSize="15sp"
android:textStyle="bold"
android:gravity="center"
android:textAllCaps="false"
tools:text="68%"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
</FrameLayout>
<!--<androidx.core.widget.ContentLoadingProgressBar <!--<androidx.core.widget.ContentLoadingProgressBar
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="20dp" android:layout_height="20dp"
tools:progress="50" tools:progress="50"
android:id="@+id/result_movie_progress_downloaded" android:id="@+id/result_movie_progress_downloaded"
android:indeterminate="false" android:indeterminate="false"
style="?android:attr/progressBarStyleHorizontal" style="?android:attr/progressBarStyleHorizontal"
android:progressBackgroundTint="?attr/colorPrimary" android:progressBackgroundTint="?attr/colorPrimary"
android:max="100" android:max="100"
android:layout_gravity="end|center_vertical" android:layout_gravity="end|center_vertical"
android:progress="0" android:progress="0"
android:visibility="gone"
tools:visibility="visible" />
-->
<!-- <TextView
android:id="@+id/result_movie_text_progress"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
tools:text="128MB / 237MB"
android:textColor="?attr/grayTextColor"
android:layout_width="wrap_content"
android:layout_height="match_parent" />-->
</LinearLayout>
<LinearLayout
android:visibility="gone"
tools:visibility="visible"
android:layout_marginTop="5dp"
android:orientation="vertical"
android:id="@+id/result_series_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton
android:layout_marginBottom="10dp"
android:nextFocusUp="@id/result_bookmark_button"
android:nextFocusDown="@id/result_download_movie"
android:id="@+id/result_resume_series_button"
style="@style/WhiteButton"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:visibility="visible"
tools:visibility="visible"
android:layout_gravity="center_vertical"
android:text="@string/resume"
app:icon="@drawable/ic_baseline_play_arrow_24"
android:layout_width="match_parent" />
<com.google.android.material.button.MaterialButton
android:layout_marginBottom="10dp"
android:nextFocusUp="@id/result_bookmark_button"
android:nextFocusDown="@id/result_download_movie"
android:id="@+id/result_next_series_button"
style="@style/WhiteButton"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:visibility="gone"
android:layout_gravity="center_vertical"
android:text="@string/next_episode"
app:icon="@drawable/cast_ic_mini_controller_skip_next"
android:layout_width="match_parent" />
<TextView
android:textColor="?attr/textColor"
android:id="@+id/result_resume_series_title"
android:textStyle="bold"
android:textSize="17sp"
tools:text="S1E1 Episode 1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
tools:visibility="visible"
android:visibility="gone"
android:paddingTop="10dp"
android:id="@+id/result_resume_progress_holder"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.core.widget.ContentLoadingProgressBar
android:layout_height="20dp"
tools:progress="50"
android:id="@+id/result_resume_series_progress"
android:indeterminate="false"
style="?android:attr/progressBarStyleHorizontal"
android:progressBackgroundTint="?attr/colorPrimary"
android:max="100"
android:layout_gravity="end|center_vertical"
android:progress="0"
android:layout_width="match_parent"
android:layout_weight="1"
android:visibility="visible"
tools:visibility="visible" />
<TextView
android:id="@+id/result_resume_series_progress_text"
android:layout_gravity="center"
android:paddingStart="10dp"
android:gravity="center"
tools:text="69m\nremaining"
android:layout_weight="0"
android:textColor="?attr/grayTextColor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="RtlSymmetry" />
</LinearLayout>
<!--<TextView
android:visibility="gone"
android:drawableLeft="@drawable/ic_baseline_play_arrow_24"
android:gravity="center_vertical"
android:textSize="20sp"
android:textColor="?attr/textColor"
android:text="More like this"
android:layout_width="wrap_content" android:layout_height="60dp">
</TextView>
<com.google.android.material.tabs.TabLayout
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabTextColor="?attr/textColor"
android:foreground="@color/transparent"
android:backgroundTint="@color/transparent"
app:tabIndicatorGravity="top"
android:textAllCaps="false"
app:tabIconTint="?attr/textColor"
app:tabIndicatorColor="?attr/textColor"
android:id="@+id/result_tabs"
app:tabGravity="start">
<com.google.android.material.tabs.TabItem
android:text="Episodes"
android:icon="@null"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</com.google.android.material.tabs.TabItem>
<com.google.android.material.tabs.TabItem
android:text="Sync"
android:icon="@null"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</com.google.android.material.tabs.TabItem>
</com.google.android.material.tabs.TabLayout>-->
<LinearLayout
android:id="@+id/result_episodes_tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_marginBottom="10dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton
tools:visibility="visible"
tools:text="Season 1"
android:nextFocusUp="@id/result_descript"
android:nextFocusRight="@id/result_episode_select"
android:nextFocusLeft="@id/result_episode_select"
android:nextFocusDown="@id/result_episodes"
android:id="@+id/result_season_button"
android:visibility="gone" android:visibility="gone"
android:layout_gravity="center_vertical" tools:visibility="visible" />
android:layout_marginStart="0dp" -->
style="@style/MultiSelectButton" /> <!-- <TextView
android:id="@+id/result_movie_text_progress"
<com.google.android.material.button.MaterialButton android:layout_gravity="center_vertical"
tools:visibility="visible" android:gravity="center_vertical"
tools:text="50-100" tools:text="128MB / 237MB"
android:textColor="?attr/grayTextColor"
android:nextFocusUp="@id/result_descript" android:layout_width="wrap_content"
android:nextFocusRight="@id/result_season_button" android:layout_height="match_parent" />-->
android:nextFocusLeft="@id/result_season_button"
android:nextFocusDown="@id/result_episodes"
android:id="@+id/result_episode_select"
android:visibility="gone"
android:layout_gravity="center_vertical"
android:layout_marginStart="0dp"
style="@style/MultiSelectButton" />
<com.google.android.material.button.MaterialButton
tools:visibility="visible"
tools:text="Dubbed"
android:nextFocusUp="@id/result_descript"
android:nextFocusRight="@id/result_season_button"
android:nextFocusLeft="@id/result_season_button"
android:nextFocusDown="@id/result_episodes"
android:id="@+id/result_dub_select"
android:visibility="gone"
android:layout_gravity="center_vertical"
android:layout_marginStart="0dp"
style="@style/MultiSelectButton" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/result_episodes_text"
tools:text="8 Episodes"
android:textSize="17sp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:layout_gravity="center_vertical"
android:textStyle="normal"
android:textColor="?attr/textColor" />
</LinearLayout> </LinearLayout>
<com.facebook.shimmer.ShimmerFrameLayout <LinearLayout
android:visibility="gone"
tools:visibility="visible" tools:visibility="visible"
app:shimmer_base_alpha="0.2" android:layout_marginTop="5dp"
app:shimmer_highlight_alpha="0.3" android:orientation="vertical"
app:shimmer_duration="@integer/loading_time" android:id="@+id/result_series_parent"
app:shimmer_auto_start="true"
android:id="@+id/result_episode_loading"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content">
android:layout_gravity="center"
android:layout_marginTop="15dp" <com.google.android.material.button.MaterialButton
android:layout_marginBottom="10dp"
android:nextFocusUp="@id/result_bookmark_button"
android:nextFocusDown="@id/result_download_movie"
android:id="@+id/result_resume_series_button"
style="@style/WhiteButton"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:visibility="visible"
tools:visibility="visible"
android:layout_gravity="center_vertical"
android:text="@string/resume"
app:icon="@drawable/ic_baseline_play_arrow_24"
android:layout_width="match_parent" />
<com.google.android.material.button.MaterialButton
android:layout_marginBottom="10dp"
android:nextFocusUp="@id/result_bookmark_button"
android:nextFocusDown="@id/result_download_movie"
android:id="@+id/result_next_series_button"
style="@style/WhiteButton"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:visibility="gone"
android:layout_gravity="center_vertical"
android:text="@string/next_episode"
app:icon="@drawable/cast_ic_mini_controller_skip_next"
android:layout_width="match_parent" />
<TextView
android:textColor="?attr/textColor"
android:id="@+id/result_resume_series_title"
android:textStyle="bold"
android:textSize="17sp"
tools:text="S1E1 Episode 1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
tools:visibility="visible"
android:visibility="gone"
android:paddingTop="10dp"
android:id="@+id/result_resume_progress_holder"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.core.widget.ContentLoadingProgressBar
android:layout_height="20dp"
tools:progress="50"
android:id="@+id/result_resume_series_progress"
android:indeterminate="false"
style="?android:attr/progressBarStyleHorizontal"
android:progressBackgroundTint="?attr/colorPrimary"
android:max="100"
android:layout_gravity="end|center_vertical"
android:progress="0"
android:layout_width="match_parent"
android:layout_weight="1"
android:visibility="visible"
tools:visibility="visible" />
<TextView
android:id="@+id/result_resume_series_progress_text"
android:layout_gravity="center"
android:paddingStart="10dp"
android:gravity="center"
tools:text="69m\nremaining"
android:layout_weight="0"
android:textColor="?attr/grayTextColor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="RtlSymmetry" />
</LinearLayout>
<LinearLayout
android:id="@+id/result_episodes_tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout <LinearLayout
android:orientation="vertical" android:layout_marginBottom="10dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<include layout="@layout/loading_episode" /> <com.google.android.material.button.MaterialButton
tools:visibility="visible"
tools:text="Season 1"
android:nextFocusUp="@id/result_descript"
android:nextFocusRight="@id/result_episode_select"
android:nextFocusLeft="@id/result_episode_select"
android:nextFocusDown="@id/result_episodes"
<include layout="@layout/loading_episode" /> android:id="@+id/result_season_button"
android:visibility="gone"
android:layout_gravity="center_vertical"
android:layout_marginStart="0dp"
style="@style/MultiSelectButton" />
<include layout="@layout/loading_episode" /> <com.google.android.material.button.MaterialButton
tools:visibility="visible"
tools:text="50-100"
<include layout="@layout/loading_episode" /> android:nextFocusUp="@id/result_descript"
android:nextFocusRight="@id/result_season_button"
android:nextFocusLeft="@id/result_season_button"
android:nextFocusDown="@id/result_episodes"
android:id="@+id/result_episode_select"
android:visibility="gone"
android:layout_gravity="center_vertical"
android:layout_marginStart="0dp"
style="@style/MultiSelectButton" />
<com.google.android.material.button.MaterialButton
tools:visibility="visible"
tools:text="Dubbed"
android:nextFocusUp="@id/result_descript"
android:nextFocusRight="@id/result_season_button"
android:nextFocusLeft="@id/result_season_button"
android:nextFocusDown="@id/result_episodes"
android:id="@+id/result_dub_select"
android:visibility="gone"
android:layout_gravity="center_vertical"
android:layout_marginStart="0dp"
style="@style/MultiSelectButton" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/result_episodes_text"
tools:text="8 Episodes"
android:textSize="17sp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:layout_gravity="center_vertical"
android:textStyle="normal"
android:textColor="?attr/textColor" />
</LinearLayout> </LinearLayout>
</com.facebook.shimmer.ShimmerFrameLayout>
<!--<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/result_episode_loading"
style="@style/Widget.AppCompat.ProgressBar" <com.facebook.shimmer.ShimmerFrameLayout
android:layout_gravity="center" tools:visibility="visible"
android:layout_width="50dp" app:shimmer_base_alpha="0.2"
android:layout_height="50dp" />--> app:shimmer_highlight_alpha="0.3"
app:shimmer_duration="@integer/loading_time"
app:shimmer_auto_start="true"
android:id="@+id/result_episode_loading"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginTop="15dp"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView <LinearLayout
android:descendantFocusability="afterDescendants" android:orientation="vertical"
android:id="@+id/result_episodes" android:layout_width="match_parent"
android:clipToPadding="false" android:layout_height="wrap_content">
android:layout_marginTop="0dp"
android:paddingBottom="100dp" <include layout="@layout/loading_episode" />
tools:listitem="@layout/result_episode"
android:layout_width="match_parent" <include layout="@layout/loading_episode" />
android:layout_height="wrap_content" />
<include layout="@layout/loading_episode" />
<include layout="@layout/loading_episode" />
</LinearLayout>
</com.facebook.shimmer.ShimmerFrameLayout>
<!--<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/result_episode_loading"
style="@style/Widget.AppCompat.ProgressBar"
android:layout_gravity="center"
android:layout_width="50dp"
android:layout_height="50dp" />-->
<androidx.recyclerview.widget.RecyclerView
android:descendantFocusability="afterDescendants"
android:id="@+id/result_episodes"
android:clipToPadding="false"
android:layout_marginTop="0dp"
android:paddingBottom="100dp"
tools:listitem="@layout/result_episode"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>

View file

@ -429,5 +429,17 @@
<string name="actor_background">Background</string> <string name="actor_background">Background</string>
<string name="home_source">Source</string> <string name="home_source">Source</string>
<string name="coming_soon">Coming soon…</string>
<string name="quality_cam">Cam</string>
<string name="quality_cam_rip">Cam</string>
<string name="quality_cam_hd">Cam</string>
<string name="quality_hq">HQ</string>
<string name="quality_hd">HD</string>
<string name="quality_ts">TS</string>
<string name="quality_tc">TC</string>
<string name="quality_blueray">BlueRay</string>
<string name="quality_workprint">WP</string>
<string name="quality_dvd">DVD</string>
<string name="poster_image">Poster Image</string> <string name="poster_image">Poster Image</string>
</resources> </resources>