diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index c5c31c60..9b145064 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -111,6 +111,12 @@ object APIHolder { } var apis: List = arrayListOf() + private var apiMap: Map? = null + + private fun initMap() { + if (apiMap == null) + apiMap = apis.mapIndexed { index, api -> api.name to index }.toMap() + } fun getApiFromName(apiName: String?): MainAPI { return getApiFromNameNull(apiName) ?: apis[defProvider] @@ -118,11 +124,9 @@ object APIHolder { fun getApiFromNameNull(apiName: String?): MainAPI? { if (apiName == null) return null - for (api in allProviders) { - if (apiName == api.name) - return api - } - return null + initMap() + + return apiMap?.get(apiName)?.let { apis.getOrNull(it) } } fun getApiFromUrlNull(url: String?): MainAPI? { @@ -622,10 +626,65 @@ interface SearchResponse { val apiName: String var type: TvType? var posterUrl: String? + var posterHeaders: Map? var id: Int? var quality: SearchQuality? } +fun MainAPI.newMovieSearchResponse( + name: String, + url: String, + type: TvType = TvType.Movie, + fix: Boolean = true, + initializer: MovieSearchResponse.() -> Unit = { }, +): MovieSearchResponse { + val builder = MovieSearchResponse(name, if (fix) fixUrl(url) else url, this.name, type) + builder.initializer() + + return builder +} + +fun MainAPI.newTvSeriesSearchResponse( + name: String, + url: String, + type: TvType = TvType.TvSeries, + fix: Boolean = true, + initializer: TvSeriesSearchResponse.() -> Unit = { }, +): TvSeriesSearchResponse { + val builder = TvSeriesSearchResponse(name, if (fix) fixUrl(url) else url, this.name, type) + builder.initializer() + + return builder +} + + +fun MainAPI.newAnimeSearchResponse( + name: String, + url: String, + type: TvType = TvType.Anime, + fix: Boolean = true, + initializer: AnimeSearchResponse.() -> Unit = { }, +): AnimeSearchResponse { + val builder = AnimeSearchResponse(name, if (fix) fixUrl(url) else url, this.name, type) + builder.initializer() + + return builder +} + +fun SearchResponse.addQuality(quality: String) { + this.quality = getQualityFromString(quality) +} + +fun SearchResponse.addPoster(url: String?, headers: Map? = null) { + this.posterUrl = url + this.posterHeaders = headers +} + +fun LoadResponse.addPoster(url: String?, headers: Map? = null) { + this.posterUrl = url + this.posterHeaders = headers +} + enum class ActorRole { Main, Supporting, @@ -648,19 +707,62 @@ data class AnimeSearchResponse( override val name: String, override val url: String, override val apiName: String, - override var type: TvType?, + override var type: TvType? = null, - override var posterUrl: String?, - val year: Int? = null, - val dubStatus: EnumSet? = null, + override var posterUrl: String? = null, + var year: Int? = null, + var dubStatus: EnumSet? = null, + + var otherName: String? = null, + var episodes: MutableMap = mutableMapOf(), - val otherName: String? = null, - val dubEpisodes: Int? = null, - val subEpisodes: Int? = null, override var id: Int? = null, override var quality: SearchQuality? = null, + override var posterHeaders: Map? = null, ) : SearchResponse +fun AnimeSearchResponse.addDubStatus(status: DubStatus, episodes: Int? = null) { + this.dubStatus = dubStatus?.also { it.add(status) } ?: EnumSet.of(status) + if (this.type?.isMovieType() != true) + if (episodes != null && episodes > 0) + this.episodes[status] = episodes +} + +fun AnimeSearchResponse.addDubStatus(isDub: Boolean, episodes: Int? = null) { + addDubStatus(if (isDub) DubStatus.Dubbed else DubStatus.Subbed, episodes) +} + +fun AnimeSearchResponse.addDub(episodes: Int?) { + if(episodes == null || episodes <= 0) return + addDubStatus(DubStatus.Dubbed, episodes) +} + +fun AnimeSearchResponse.addSub(episodes: Int?) { + if(episodes == null || episodes <= 0) return + addDubStatus(DubStatus.Subbed, episodes) +} + +fun AnimeSearchResponse.addDubStatus( + dubExist: Boolean, + subExist: Boolean, + dubEpisodes: Int? = null, + subEpisodes: Int? = null +) { + if (dubExist) + addDubStatus(DubStatus.Dubbed, dubEpisodes) + + if (subExist) + addDubStatus(DubStatus.Subbed, subEpisodes) +} + +fun AnimeSearchResponse.addDubStatus(status: String, episodes: Int? = null) { + if (status.contains("(dub)", ignoreCase = true)) { + addDubStatus(DubStatus.Dubbed) + } else if (status.contains("(sub)", ignoreCase = true)) { + addDubStatus(DubStatus.Subbed) + } +} + data class TorrentSearchResponse( override val name: String, override val url: String, @@ -670,31 +772,34 @@ data class TorrentSearchResponse( override var posterUrl: String?, override var id: Int? = null, override var quality: SearchQuality? = null, + override var posterHeaders: Map? = null, ) : SearchResponse data class MovieSearchResponse( override val name: String, override val url: String, override val apiName: String, - override var type: TvType?, + override var type: TvType? = null, - override var posterUrl: String?, + override var posterUrl: String? = null, val year: Int? = null, override var id: Int? = null, override var quality: SearchQuality? = null, + override var posterHeaders: Map? = null, ) : SearchResponse data class TvSeriesSearchResponse( override val name: String, override val url: String, override val apiName: String, - override var type: TvType?, + override var type: TvType? = null, - override var posterUrl: String?, - val year: Int?, - val episodes: Int?, + override var posterUrl: String? = null, + val year: Int? = null, + val episodes: Int? = null, override var id: Int? = null, override var quality: SearchQuality? = null, + override var posterHeaders: Map? = null, ) : SearchResponse interface LoadResponse { @@ -713,6 +818,7 @@ interface LoadResponse { var actors: List? var comingSoon: Boolean var syncData: MutableMap + var posterHeaders: Map? companion object { private val malIdPrefix = malApi.idPrefix @@ -844,6 +950,7 @@ data class TorrentLoadResponse( override var actors: List? = null, override var comingSoon: Boolean = false, override var syncData: MutableMap = mutableMapOf(), + override var posterHeaders: Map? = null, ) : LoadResponse data class AnimeLoadResponse( @@ -871,6 +978,7 @@ data class AnimeLoadResponse( override var actors: List? = null, override var comingSoon: Boolean = false, override var syncData: MutableMap = mutableMapOf(), + override var posterHeaders: Map? = null, ) : LoadResponse fun AnimeLoadResponse.addEpisodes(status: DubStatus, episodes: List?) { @@ -882,7 +990,7 @@ fun MainAPI.newAnimeLoadResponse( name: String, url: String, type: TvType, - comingSoonIfNone: Boolean, + comingSoonIfNone: Boolean = true, initializer: AnimeLoadResponse.() -> Unit = { }, ): AnimeLoadResponse { val builder = AnimeLoadResponse(name = name, url = url, apiName = this.name, type = type) @@ -898,15 +1006,6 @@ fun MainAPI.newAnimeLoadResponse( 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( override var name: String, override var url: String, @@ -926,6 +1025,7 @@ data class MovieLoadResponse( override var actors: List? = null, override var comingSoon: Boolean = false, override var syncData: MutableMap = mutableMapOf(), + override var posterHeaders: Map? = null, ) : LoadResponse fun MainAPI.newMovieLoadResponse( @@ -1046,6 +1146,7 @@ data class TvSeriesLoadResponse( override var actors: List? = null, override var comingSoon: Boolean = false, override var syncData: MutableMap = mutableMapOf(), + override var posterHeaders: Map? = null, ) : LoadResponse fun MainAPI.newTvSeriesLoadResponse( diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AllAnimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AllAnimeProvider.kt index 1c322927..7f74cc37 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AllAnimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AllAnimeProvider.kt @@ -14,7 +14,6 @@ import org.mozilla.javascript.Context import org.mozilla.javascript.Scriptable import java.net.URI import java.net.URLDecoder -import java.util.* class AllAnimeProvider : MainAPI() { @@ -88,49 +87,48 @@ class AllAnimeProvider : MainAPI() { @JsonProperty("data") val data: Data ) - data class RandomMain ( - @JsonProperty("data" ) var data : DataRan? = DataRan() + data class RandomMain( + @JsonProperty("data") var data: DataRan? = DataRan() ) - data class DataRan ( - @JsonProperty("queryRandomRecommendation" ) var queryRandomRecommendation : ArrayList = arrayListOf() + data class DataRan( + @JsonProperty("queryRandomRecommendation") var queryRandomRecommendation: ArrayList = arrayListOf() ) - data class QueryRandomRecommendation ( - @JsonProperty("_id" ) val Id : String? = null, - @JsonProperty("name" ) val name : String? = null, - @JsonProperty("englishName" ) val englishName : String? = null, - @JsonProperty("nativeName" ) val nativeName : String? = null, - @JsonProperty("thumbnail" ) val thumbnail : String? = null, - @JsonProperty("airedStart" ) val airedStart : String? = null, - @JsonProperty("availableChapters" ) val availableChapters : String? = null, - @JsonProperty("availableEpisodes" ) val availableEpisodes : String? = null, - @JsonProperty("__typename" ) val _typename : String? = null + data class QueryRandomRecommendation( + @JsonProperty("_id") val Id: String? = null, + @JsonProperty("name") val name: String? = null, + @JsonProperty("englishName") val englishName: String? = null, + @JsonProperty("nativeName") val nativeName: String? = null, + @JsonProperty("thumbnail") val thumbnail: String? = null, + @JsonProperty("airedStart") val airedStart: String? = null, + @JsonProperty("availableChapters") val availableChapters: String? = null, + @JsonProperty("availableEpisodes") val availableEpisodes: String? = null, + @JsonProperty("__typename") val _typename: String? = null ) override suspend fun getMainPage(): HomePageResponse { val items = ArrayList() val urls = listOf( - Pair("Top Anime", - "$mainUrl/graphql?variables=%7B%22search%22%3A%7B%22allowAdult%22%3Afalse%2C%22sortBy%22%3A%22Top%22%7D%2C%22limit%22%3A26%2C%22page%22%3A1%2C%22translationType%22%3A%22sub%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%229343797cc3d9e3f444e2d3b7db9a84d759b816a4d84512ea72d079f85bb96e98%22%7D%7D"), - Pair("Animes", - "$mainUrl/graphql?variables=%7B%22search%22%3A%7B%22allowAdult%22%3Afalse%7D%2C%22limit%22%3A26%2C%22page%22%3A1%2C%22translationType%22%3A%22sub%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%229343797cc3d9e3f444e2d3b7db9a84d759b816a4d84512ea72d079f85bb96e98%22%7D%7D"), + Pair( + "Top Anime", + "$mainUrl/graphql?variables=%7B%22search%22%3A%7B%22allowAdult%22%3Afalse%2C%22sortBy%22%3A%22Top%22%7D%2C%22limit%22%3A26%2C%22page%22%3A1%2C%22translationType%22%3A%22sub%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%229343797cc3d9e3f444e2d3b7db9a84d759b816a4d84512ea72d079f85bb96e98%22%7D%7D" + ), + Pair( + "Animes", + "$mainUrl/graphql?variables=%7B%22search%22%3A%7B%22allowAdult%22%3Afalse%7D%2C%22limit%22%3A26%2C%22page%22%3A1%2C%22translationType%22%3A%22sub%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%229343797cc3d9e3f444e2d3b7db9a84d759b816a4d84512ea72d079f85bb96e98%22%7D%7D" + ), ) - val random = "$mainUrl/graphql?variables=%7B%22format%22%3A%22anime%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%2221ac672633498a3698e8f6a93ce6c2b3722b29a216dcca93363bf012c360cd54%22%7D%7D" + val random = + "$mainUrl/graphql?variables=%7B%22format%22%3A%22anime%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%2221ac672633498a3698e8f6a93ce6c2b3722b29a216dcca93363bf012c360cd54%22%7D%7D" val ranlink = app.get(random).text val jsonran = parseJson(ranlink) val ranhome = jsonran.data?.queryRandomRecommendation?.map { - AnimeSearchResponse( - it.name!!, - "$mainUrl/anime/${it.Id}", - this.name, - TvType.Anime, - it.thumbnail, - null, - EnumSet.of(DubStatus.Subbed, DubStatus.Dubbed), - it.nativeName, - ) + newAnimeSearchResponse(it.name!!,"$mainUrl/anime/${it.Id}", fix = false) { + this.posterUrl = it.thumbnail + this.otherName = it.nativeName + } } items.add(HomePageList("Random", ranhome!!)) @@ -144,18 +142,14 @@ class AllAnimeProvider : MainAPI() { !(it.availableEpisodes?.raw == 0 && it.availableEpisodes.sub == 0 && it.availableEpisodes.dub == 0) } results.map { - home.add(AnimeSearchResponse( - it.name, - "$mainUrl/anime/${it.Id}", - this.name, - TvType.Anime, - it.thumbnail, - it.airedStart?.year, - EnumSet.of(DubStatus.Subbed, DubStatus.Dubbed), - it.englishName, - it.availableEpisodes?.dub, - it.availableEpisodes?.sub - )) + home.add( + newAnimeSearchResponse(it.name, "$mainUrl/anime/${it.Id}", fix = false) { + this.posterUrl = it.thumbnail + this.year = it.airedStart?.year + this.otherName = it.englishName + addDub(it.availableEpisodes?.dub) + addSub(it.availableEpisodes?.sub) + }) } items.add(HomePageList(HomeName, home)) } @@ -180,18 +174,13 @@ class AllAnimeProvider : MainAPI() { } return results.map { - AnimeSearchResponse( - it.name, - "$mainUrl/anime/${it.Id}", - this.name, - TvType.Anime, - it.thumbnail, - it.airedStart?.year, - EnumSet.of(DubStatus.Subbed, DubStatus.Dubbed), - it.englishName, - it.availableEpisodes?.dub, - it.availableEpisodes?.sub - ) + newAnimeSearchResponse(it.name, "$mainUrl/anime/${it.Id}", fix = false) { + this.posterUrl = it.thumbnail + this.year = it.airedStart?.year + this.otherName = it.englishName + addDub(it.availableEpisodes?.dub) + addSub(it.availableEpisodes?.sub) + } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt index ec35c8e2..4dd0e752 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt @@ -12,7 +12,6 @@ import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.JsUnpacker import com.lagradost.cloudstream3.utils.getQualityFromName import org.jsoup.Jsoup -import java.util.* import kotlin.math.pow class AnimePaheProvider : MainAPI() { @@ -84,19 +83,14 @@ class AnimePaheProvider : MainAPI() { try { val response = app.get(i.first).text val episodes = mapper.readValue(response).data.map { - - AnimeSearchResponse( + newAnimeSearchResponse( it.animeTitle, "https://pahe.win/a/${it.animeId}?slug=${it.animeTitle}", - this.name, - TvType.Anime, - it.snapshot, - null, - EnumSet.of(DubStatus.Subbed), - null, - null, - it.episode - ) + fix = false + ) { + this.posterUrl = it.snapshot + addDubStatus(DubStatus.Subbed, it.episode) + } } items.add(HomePageList(i.second, episodes)) @@ -151,18 +145,14 @@ class AnimePaheProvider : MainAPI() { val data = req.let { mapper.readValue(it) } return data.data.map { - AnimeSearchResponse( + newAnimeSearchResponse( it.title, "https://pahe.win/a/${it.id}?slug=${it.title}", - this.name, - TvType.Anime, - it.poster, - it.year, - EnumSet.of(DubStatus.Subbed), - null, - null, - it.episodes - ) + fix = false + ) { + this.posterUrl = it.poster + addDubStatus(DubStatus.Subbed, it.episodes) + } } } @@ -189,7 +179,6 @@ class AnimePaheProvider : MainAPI() { @JsonProperty("data") val data: List ) - private suspend fun generateListOfEpisodes(link: String): ArrayList { try { val attrs = link.split('/') diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeWorldProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeWorldProvider.kt index 8df4b1f0..3456c0fb 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeWorldProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeWorldProvider.kt @@ -9,7 +9,6 @@ import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities import org.json.JSONObject import org.jsoup.nodes.Element -import java.util.* class AnimeWorldProvider : MainAPI() { override var mainUrl = "https://www.animeworld.tv" @@ -31,6 +30,7 @@ class AnimeWorldProvider : MainAPI() { else -> TvType.Anime } } + fun getStatus(t: String?): ShowStatus? { return when (t?.lowercase()) { "finito" -> ShowStatus.Completed @@ -54,25 +54,20 @@ class AnimeWorldProvider : MainAPI() { val statusElement = this.select("div.status") // .first() val dub = statusElement.select(".dub").isNotEmpty() - val dubStatus = if (dub) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(DubStatus.Subbed) - val episode = statusElement.select(".ep").text().split(' ').last().toIntOrNull() + + val episode = if (showEpisode) statusElement.select(".ep").text().split(' ').last() + .toIntOrNull() else null val type = when { statusElement.select(".movie").isNotEmpty() -> TvType.AnimeMovie statusElement.select(".ova").isNotEmpty() -> TvType.OVA else -> TvType.Anime } - return AnimeSearchResponse( - title, - url, - name, - type, - poster, - dubStatus = dubStatus, - otherName = if (otherTitle != title) otherTitle else null, - dubEpisodes = if (showEpisode && type != TvType.AnimeMovie && dub) episode else null, - subEpisodes = if (showEpisode && type != TvType.AnimeMovie && !dub) episode else null - ) + return newAnimeSearchResponse(title, url, type) { + addDubStatus(dub, episode) + this.otherName = otherTitle + this.posterUrl = poster + } } override suspend fun getMainPage(): HomePageResponse { @@ -113,14 +108,17 @@ class AnimeWorldProvider : MainAPI() { arr[0].split(' ')[0].toIntOrNull() else arr[1].split(' ')[0].toIntOrNull()?.let { - arr[0].removeSuffix("h").toIntOrNull()?.times(60)!!.plus(it) } + arr[0].removeSuffix("h").toIntOrNull()?.times(60)!!.plus(it) + } } + val document = app.get(url).document val widget = document.select("div.widget.info") val title = widget.select(".info .title").text().removeSuffix(" (ITA)") val otherTitle = widget.select(".info .title").attr("data-jtitle").removeSuffix(" (ITA)") - val description = widget.select(".desc .long").first()?.text() ?: widget.select(".desc").text() + val description = + widget.select(".desc .long").first()?.text() ?: widget.select(".desc").text() val poster = document.select(".thumb img").attr("src") val type: TvType = getType(widget.select("dd").first()?.text()) diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt index 233ab127..e197d79f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt @@ -2,8 +2,9 @@ package com.lagradost.cloudstream3.animeproviders import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.parseJson +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor import java.util.* class AnimeflvnetProvider:MainAPI() { @@ -13,6 +14,11 @@ class AnimeflvnetProvider:MainAPI() { else if (t.contains("Película")) TvType.AnimeMovie else TvType.Anime } + fun getDubStatus(title: String): DubStatus { + return if (title.contains("Latino") || title.contains("Castellano")) + DubStatus.Dubbed + else DubStatus.Subbed + } } override var mainUrl = "https://www3.animeflv.net" override var name = "Animeflv.net" @@ -43,19 +49,10 @@ class AnimeflvnetProvider:MainAPI() { val url = it.selectFirst("a").attr("href").replace(epRegex,"") .replace("ver/","anime/") val epNum = it.selectFirst("span.Capi").text().replace("Episodio ","").toIntOrNull() - AnimeSearchResponse( - title, - fixUrl(url), - this.name, - TvType.Anime, - fixUrl(poster), - null, - if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of( - DubStatus.Dubbed - ) else EnumSet.of(DubStatus.Subbed), - subEpisodes = epNum, - dubEpisodes = epNum, - ) + newAnimeSearchResponse(title, url) { + this.posterUrl = fixUrl(poster) + addDubStatus(getDubStatus(title), epNum) + } }) ) for ((url, name) in urls) { @@ -64,15 +61,10 @@ class AnimeflvnetProvider:MainAPI() { val home = doc.select("ul.ListAnimes li article").map { val title = it.selectFirst("h3.Title").text() val poster = it.selectFirst("figure img").attr("src") - AnimeSearchResponse( - title, - fixUrl(it.selectFirst("a").attr("href")), - this.name, - TvType.Anime, - fixUrl(poster), - null, - if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(DubStatus.Subbed), - ) + newAnimeSearchResponse(title, fixUrl(it.selectFirst("a").attr("href"))) { + this.posterUrl = fixUrl(poster) + addDubStatus(MonoschinosProvider.getDubStatus(title)) + } } items.add(HomePageList(name, home)) diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt index ea50567b..230809f8 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt @@ -201,20 +201,10 @@ class GogoanimeProvider : MainAPI() { items.add(HomePageList(i.second, (parseRegex.findAll(html.text).map { val (link, epNum, title, poster) = it.destructured val isSub = listOf(1, 3).contains(i.first.toInt()) - AnimeSearchResponse( - title, - link, - this.name, - TvType.Anime, - poster, - null, - if (isSub) EnumSet.of(DubStatus.Subbed) else EnumSet.of( - DubStatus.Dubbed - ), - null, - if (!isSub) epNum.toIntOrNull() else null, - if (isSub) epNum.toIntOrNull() else null, - ) + newAnimeSearchResponse(title, link) { + this.posterUrl = poster + addDubStatus(!isSub, epNum.toIntOrNull()) + } }).toList())) } catch (e: Exception) { e.printStackTrace() diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt index 0e248ea2..4823e682 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt @@ -14,6 +14,12 @@ class MonoschinosProvider : MainAPI() { else if (t.contains("Pelicula")) TvType.AnimeMovie else TvType.Anime } + + fun getDubStatus(title: String): DubStatus { + return if (title.contains("Latino") || title.contains("Castellano")) + DubStatus.Dubbed + else DubStatus.Subbed + } } override var mainUrl = "https://monoschinos2.com" @@ -50,19 +56,10 @@ class MonoschinosProvider : MainAPI() { val url = it.selectFirst("a").attr("href").replace("ver/", "anime/") .replace(epRegex, "sub-espanol") val epNum = it.selectFirst(".positioning h5").text().toIntOrNull() - AnimeSearchResponse( - title, - url, - this.name, - TvType.Anime, - poster, - null, - if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of( - DubStatus.Dubbed - ) else EnumSet.of(DubStatus.Subbed), - subEpisodes = epNum, - dubEpisodes = epNum, - ) + newAnimeSearchResponse(title, url) { + this.posterUrl = fixUrl(poster) + addDubStatus(getDubStatus(title), epNum) + } }) ) @@ -71,17 +68,10 @@ class MonoschinosProvider : MainAPI() { val home = app.get(i.first, timeout = 120).document.select(".col-6").map { val title = it.selectFirst(".seristitles").text() val poster = it.selectFirst("img.animemainimg").attr("src") - AnimeSearchResponse( - title, - fixUrl(it.selectFirst("a").attr("href")), - this.name, - TvType.Anime, - fixUrl(poster), - null, - if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of( - DubStatus.Dubbed - ) else EnumSet.of(DubStatus.Subbed), - ) + newAnimeSearchResponse(title, fixUrl(it.selectFirst("a").attr("href"))) { + this.posterUrl = fixUrl(poster) + addDubStatus(getDubStatus(title)) + } } items.add(HomePageList(i.second, home)) diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NineAnimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NineAnimeProvider.kt index fd687b51..0a5367be 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NineAnimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NineAnimeProvider.kt @@ -17,12 +17,25 @@ class NineAnimeProvider : MainAPI() { override val hasDownloadSupport = true override val supportedTypes = setOf(TvType.Anime) + companion object { + fun getDubStatus(title: String): DubStatus { + return if (title.contains("(dub)", ignoreCase = true)) { + DubStatus.Dubbed + } else { + DubStatus.Subbed + } + } + } + override suspend fun getMainPage(): HomePageResponse { val items = listOf( Pair("$mainUrl/ajax/home/widget?name=trending", "Trending"), Pair("$mainUrl/ajax/home/widget?name=updated_all", "All"), Pair("$mainUrl/ajax/home/widget?name=updated_sub&page=1", "Recently Updated (SUB)"), - Pair("$mainUrl/ajax/home/widget?name=updated_dub&page=1", "Recently Updated (DUB)"), + Pair( + "$mainUrl/ajax/home/widget?name=updated_dub&page=1", + "Recently Updated (DUB)(DUB)" + ), Pair( "$mainUrl/ajax/home/widget?name=updated_chinese&page=1", "Recently Updated (Chinese)" @@ -37,17 +50,11 @@ class NineAnimeProvider : MainAPI() { val title = it.selectFirst("a.name").text() val link = it.selectFirst("a").attr("href") val poster = it.selectFirst("a.poster img").attr("src") - AnimeSearchResponse( - title, - link, - this.name, - TvType.Anime, - poster, - null, - if (title.contains("(DUB)") || title.contains("(Dub)")) EnumSet.of( - DubStatus.Dubbed - ) else EnumSet.of(DubStatus.Subbed), - ) + + newAnimeSearchResponse(title, link) { + this.posterUrl = poster + addDubStatus(getDubStatus(title)) + } } HomePageList(name, home) @@ -206,24 +213,18 @@ class NineAnimeProvider : MainAPI() { Episode(link, name) } ?: return null - val recommendations = - doc.select("div.container aside.main section div.body ul.anime-list li")?.mapNotNull { element -> - val recTitle = element.select("a.name").text() ?: return@mapNotNull null - val image = element.select("a.poster img")?.attr("src") - val recUrl = fixUrl(element.select("a").attr("href")) - AnimeSearchResponse( - recTitle, - fixUrl(recUrl), - this.name, - TvType.Anime, - image, - dubStatus = - if (recTitle.contains("(DUB)") || recTitle.contains("(Dub)")) EnumSet.of( - DubStatus.Dubbed - ) else EnumSet.of(DubStatus.Subbed), - ) - } + doc.select("div.container aside.main section div.body ul.anime-list li") + ?.mapNotNull { element -> + val recTitle = element.select("a.name")?.text() ?: return@mapNotNull null + val image = element.select("a.poster img")?.attr("src") + val recUrl = fixUrl(element.select("a").attr("href")) + newAnimeSearchResponse(recTitle, recUrl) { + this.posterUrl = image + addDubStatus(getDubStatus(recTitle)) + } + } + val infodoc = doc.selectFirst("div.info .meta .col1").text() val tvType = if (infodoc.contains("Movie")) TvType.AnimeMovie else TvType.Anime val status = @@ -231,13 +232,14 @@ class NineAnimeProvider : MainAPI() { else if (infodoc.contains("Airing")) ShowStatus.Ongoing else null val tags = doc.select("div.info .meta .col1 div:contains(Genre) a").map { it.text() } + return newAnimeLoadResponse(title, url, tvType) { - posterUrl = poster - addEpisodes(DubStatus.Subbed, episodes) - plot = description + this.posterUrl = poster + this.plot = description this.recommendations = recommendations - showStatus = status + this.showStatus = status this.tags = tags + addEpisodes(DubStatus.Subbed, episodes) } } @@ -260,7 +262,8 @@ class NineAnimeProvider : MainAPI() { callback: (ExtractorLink) -> Unit ): Boolean { val document = app.get(data).document - val animeid = document.selectFirst("div.player-wrapper.watchpage").attr("data-id") ?: return false + val animeid = + document.selectFirst("div.player-wrapper.watchpage").attr("data-id") ?: return false val animeidencoded = encode(getVrf(animeid) ?: return false) Jsoup.parse( @@ -287,7 +290,7 @@ class NineAnimeProvider : MainAPI() { parseJson(epserver) } else null)?.url?.let { it1 -> getLink(it1.replace("=", "")) } ?.replace("/embed/", "/e/") - } catch (e : Exception) { + } catch (e: Exception) { logError(e) null } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt index 51428cea..de947e19 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt @@ -17,7 +17,6 @@ import okhttp3.Interceptor import org.jsoup.Jsoup import org.jsoup.nodes.Element import java.net.URI -import java.util.* private const val OPTIONS = "OPTIONS" @@ -52,30 +51,31 @@ class ZoroProvider : MainAPI() { } } + val epRegex = Regex("Ep (\\d+)/") private fun Element.toSearchResult(): SearchResponse? { val href = fixUrl(this.select("a").attr("href")) val title = this.select("h3.film-name").text() - /*val episodes = this.select("div.fd-infor > span.fdi-item")?.get(1)?.text()?.let { eps -> + val dubSub = this.select(".film-poster > .tick.ltr").text() + //val episodes = this.selectFirst(".film-poster > .tick-eps")?.text()?.toIntOrNull() + + val dubExist = dubSub.contains("dub", ignoreCase = true) + val subExist = dubSub.contains("sub", ignoreCase = true) + val episodes = this.selectFirst(".film-poster > .tick.rtl > .tick-eps")?.text()?.let { eps -> + //println("REGEX:::: $eps") // current episode / max episode - val epRegex = Regex("Ep (\\d+)/")//Regex("Ep (\\d+)/(\\d+)") + //Regex("Ep (\\d+)/(\\d+)") epRegex.find(eps)?.groupValues?.get(1)?.toIntOrNull() - }*/ + } if (href.contains("/news/") || title.trim().equals("News", ignoreCase = true)) return null val posterUrl = fixUrl(this.select("img").attr("data-src")) val type = getType(this.select("div.fd-infor > span.fdi-item").text()) - return AnimeSearchResponse( - title, - href, - this@ZoroProvider.name, - type, - posterUrl, - null, - null, - ) + return newAnimeSearchResponse(title, href, type) { + this.posterUrl = posterUrl + addDubStatus(dubExist, subExist, episodes, episodes) + } } - override suspend fun getMainPage(): HomePageResponse { val html = app.get("$mainUrl/home").text val document = Jsoup.parse(html) @@ -152,30 +152,14 @@ class ZoroProvider : MainAPI() { val dubExist = dubsub?.contains("DUB") ?: false val subExist = dubsub?.contains("SUB") ?: false || dubsub?.contains("RAW") ?: false - val set = if (dubExist && subExist) { - EnumSet.of(DubStatus.Dubbed, DubStatus.Subbed) - } else if (dubExist) { - EnumSet.of(DubStatus.Dubbed) - } else { - EnumSet.of(DubStatus.Subbed) - } - val tvType = getType(it.selectFirst(".film-detail > .fd-infor > .fdi-item")?.text().toString()) val href = fixUrl(it.selectFirst(".film-name a").attr("href")) - AnimeSearchResponse( - title, - href, - name, - tvType, - poster, - null, - set, - null, - if (dubExist) episodes else null, - if (subExist) episodes else null, - ) + newAnimeSearchResponse(title, href, tvType) { + this.posterUrl = poster + addDubStatus(dubExist, subExist, episodes, episodes) + } } } @@ -187,8 +171,8 @@ class ZoroProvider : MainAPI() { } data class ZoroSyncData( - @JsonProperty("mal_id") val malId : String?, - @JsonProperty("anilist_id") val aniListId : String?, + @JsonProperty("mal_id") val malId: String?, + @JsonProperty("anilist_id") val aniListId: String?, ) override suspend fun load(url: String): LoadResponse { diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt index 3c113a10..03c39617 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt @@ -14,6 +14,11 @@ class DoramasYTProvider : MainAPI() { else if (t.contains("Pelicula")) TvType.Movie else TvType.TvSeries } + fun getDubStatus(title: String): DubStatus { + return if (title.contains("Latino") || title.contains("Castellano")) + DubStatus.Dubbed + else DubStatus.Subbed + } } override var mainUrl = "https://doramasyt.com" @@ -53,39 +58,22 @@ class DoramasYTProvider : MainAPI() { val url = it.selectFirst("a").attr("href").replace("ver/", "dorama/") .replace(epRegex, "sub-espanol") val epNum = it.selectFirst("h3").text().toIntOrNull() - AnimeSearchResponse( - title, - url, - this.name, - TvType.Anime, - poster, - null, - if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of( - DubStatus.Dubbed - ) else EnumSet.of(DubStatus.Subbed), - subEpisodes = epNum, - dubEpisodes = epNum, - ) + newAnimeSearchResponse(title,url) { + this.posterUrl = fixUrl(poster) + addDubStatus(getDubStatus(title), epNum) + } }) ) for (i in urls) { try { - val home = app.get(i.first, timeout = 120).document.select(".col-6").map { val title = it.selectFirst(".animedtls p").text() val poster = it.selectFirst(".anithumb img").attr("src") - AnimeSearchResponse( - title, - it.selectFirst("a").attr("href"), - this.name, - TvType.Anime, - poster, - null, - if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of( - DubStatus.Dubbed - ) else EnumSet.of(DubStatus.Subbed), - ) + newAnimeSearchResponse(title, fixUrl(it.selectFirst("a").attr("href"))) { + this.posterUrl = fixUrl(poster) + addDubStatus(getDubStatus(title)) + } } items.add(HomePageList(i.second, home)) diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt index c9dd894a..4715e54f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt @@ -85,7 +85,7 @@ open class VidstreamProviderTemplate : MainAPI() { val description = soup.selectFirst(".post-entry")?.text()?.trim() var poster: String? = null - var year : Int? = null + var year: Int? = null val episodes = soup.select(".listing.items.lists > .video-block").withIndex().map { (_, li) -> @@ -105,7 +105,7 @@ open class VidstreamProviderTemplate : MainAPI() { val epNum = Regex("""Episode (\d+)""").find(epTitle)?.destructured?.component1() ?.toIntOrNull() - if(year == null) { + if (year == null) { year = epDate?.split("-")?.get(0)?.toIntOrNull() } newEpisode(li.selectFirst("a").attr("href")) { @@ -173,25 +173,13 @@ open class VidstreamProviderTemplate : MainAPI() { val isSeries = (name.contains("Season") || name.contains("Episode")) if (isSeries) { - TvSeriesSearchResponse( - name, - link, - this.name, - TvType.TvSeries, - image, - null, - null, - ) + newTvSeriesSearchResponse(name, link) { + posterUrl = image + } } else { - MovieSearchResponse( - name, - link, - this.name, - TvType.Movie, - image, - null, - null, - ) + newMovieSearchResponse(name, link) { + posterUrl = image + } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt index c97c384b..c88a7471 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt @@ -770,7 +770,7 @@ class HomeFragment : Fragment() { home_main_text?.text = random.name + if (random is AnimeSearchResponse && !random.dubStatus.isNullOrEmpty()) { - random.dubStatus.joinToString( + random.dubStatus?.joinToString( prefix = " • ", separator = " | " ) { it.name } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt index 0762cabb..b4e9c6b8 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt @@ -710,7 +710,8 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio CastButtonFactory.setUpMediaRouteButton(act, media_route_button) val castContext = CastContext.getSharedInstance(act.applicationContext) - media_route_button?.isGone = castContext.castState == CastState.NO_DEVICES_AVAILABLE + media_route_button?.isGone = + castContext.castState == CastState.NO_DEVICES_AVAILABLE castContext.addCastStateListener { state -> media_route_button?.isGone = state == CastState.NO_DEVICES_AVAILABLE @@ -1299,7 +1300,6 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio } observe(syncModel.syncIds) { - println("VALUES::: $it") syncdata = it } @@ -1657,8 +1657,8 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio val posterImageLink = d.posterUrl if (!posterImageLink.isNullOrEmpty()) { - result_poster?.setImage(posterImageLink) - result_poster_blur?.setImageBlur(posterImageLink, 10, 3) + result_poster?.setImage(posterImageLink, d.posterHeaders) + result_poster_blur?.setImageBlur(posterImageLink, 10, 3, d.posterHeaders) //Full screen view of Poster image if (context?.isTrueTvSettings() == false) // Poster not clickable on tv result_poster_holder?.setOnClickListener { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt index 289c2904..e2d3891f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt @@ -52,7 +52,8 @@ class SearchFragment : Fragment() { fun List.filterSearchResponse(): List { return this.filter { response -> if (response is AnimeSearchResponse) { - (response.dubStatus.isNullOrEmpty()) || (response.dubStatus.any { + val status = response.dubStatus + (status.isNullOrEmpty()) || (status.any { APIRepository.dubStatusActive.contains(it) }) } else { @@ -225,11 +226,13 @@ class SearchFragment : Fragment() { } }.sortedBy { it.name.lowercase() } - val names = currentValidApis.map { if(isMultiLang) "${ - SubtitleHelper.getFlagFromIso( - it.lang - )?.plus(" ") ?: "" - }${it.name}" else it.name } + val names = currentValidApis.map { + if (isMultiLang) "${ + SubtitleHelper.getFlagFromIso( + it.lang + )?.plus(" ") ?: "" + }${it.name}" else it.name + } for ((index, api) in currentValidApis.map { it.name }.withIndex()) { listView?.setItemChecked(index, currentSelectedApis.contains(api)) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchResultBuilder.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchResultBuilder.kt index 3546ba8c..3d2f4c59 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchResultBuilder.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchResultBuilder.kt @@ -47,7 +47,7 @@ object SearchResultBuilder { textIsDub?.isVisible = false textIsSub?.isVisible = false - when(card.quality) { + when (card.quality) { SearchQuality.BlueRay -> R.string.quality_blueray SearchQuality.Cam -> R.string.quality_cam SearchQuality.CamRip -> R.string.quality_cam_rip @@ -75,7 +75,7 @@ object SearchResultBuilder { cardText?.text = card.name cardView.isVisible = true - if (!cardView.setImage(card.posterUrl)) { + if (!cardView.setImage(card.posterUrl, card.posterHeaders)) { cardView.setImageResource(R.drawable.default_cover) } @@ -182,20 +182,24 @@ object SearchResultBuilder { } } is AnimeSearchResponse -> { - if (card.dubStatus != null && card.dubStatus.size > 0) { - if (card.dubStatus.contains(DubStatus.Dubbed)) { + val dubStatus = card.dubStatus + if (!dubStatus.isNullOrEmpty()) { + if (dubStatus.contains(DubStatus.Dubbed)) { textIsDub?.visibility = View.VISIBLE } - if (card.dubStatus.contains(DubStatus.Subbed)) { + if (dubStatus.contains(DubStatus.Subbed)) { textIsSub?.visibility = View.VISIBLE } } + val dubEpisodes = card.episodes[DubStatus.Dubbed] + val subEpisodes = card.episodes[DubStatus.Subbed] + textIsDub?.apply { val dubText = context.getString(R.string.app_dubbed_text) - text = if (card.dubEpisodes != null && card.dubEpisodes > 0) { + text = if (dubEpisodes != null && dubEpisodes > 0) { context.getString(R.string.app_dub_sub_episode_text_format) - .format(dubText, card.dubEpisodes) + .format(dubText, dubEpisodes) } else { dubText } @@ -203,9 +207,9 @@ object SearchResultBuilder { textIsSub?.apply { val subText = context.getString(R.string.app_subbed_text) - text = if (card.subEpisodes != null && card.subEpisodes > 0) { + text = if (subEpisodes != null && subEpisodes > 0) { context.getString(R.string.app_dub_sub_episode_text_format) - .format(subText, card.subEpisodes) + .format(subText, subEpisodes) } else { subText } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SyncSearchViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SyncSearchViewModel.kt index d1adca73..9c517d4a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SyncSearchViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SyncSearchViewModel.kt @@ -16,7 +16,8 @@ class SyncSearchViewModel { override var type: TvType?, override var posterUrl: String?, override var id: Int?, - override var quality: SearchQuality? = null + override var quality: SearchQuality? = null, + override var posterHeaders: Map? = null, ) : SearchResponse private fun SyncAPI.SyncSearchResult.toSearchResponse(): SyncSearchResultSearchResponse { diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt index de948d67..2fd0aa17 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt @@ -43,7 +43,8 @@ object DataStoreHelper { @JsonProperty("type") override var type: TvType? = null, @JsonProperty("posterUrl") override var posterUrl: String?, @JsonProperty("year") val year: Int?, - @JsonProperty("quality") override var quality: SearchQuality? = null + @JsonProperty("quality") override var quality: SearchQuality? = null, + @JsonProperty("posterHeaders") override var posterHeaders: Map? = null, ) : SearchResponse data class ResumeWatchingResult( @@ -60,7 +61,8 @@ object DataStoreHelper { @JsonProperty("episode") val episode: Int?, @JsonProperty("season") val season: Int?, @JsonProperty("isFromDownload") val isFromDownload: Boolean, - @JsonProperty("quality") override var quality: SearchQuality? = null + @JsonProperty("quality") override var quality: SearchQuality? = null, + @JsonProperty("posterHeaders") override var posterHeaders: Map? = null, ) : SearchResponse var currentAccount: String = "0" //TODO ACCOUNT IMPLEMENTATION diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt index 3d0d0550..c7969d5e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt @@ -148,11 +148,11 @@ object UIHelper { return color } - fun ImageView?.setImage(url: String?): Boolean { + fun ImageView?.setImage(url: String?, headers: Map? = null): Boolean { if (this == null || url.isNullOrBlank()) return false return try { GlideApp.with(this.context) - .load(GlideUrl(url)).transition( + .load(GlideUrl(url) { headers ?: emptyMap() }).transition( DrawableTransitionOptions.withCrossFade() ) .into(this) @@ -163,11 +163,17 @@ object UIHelper { } } - fun ImageView?.setImageBlur(url: String?, radius: Int, sample: Int = 3) { + fun ImageView?.setImageBlur( + url: String?, + radius: Int, + sample: Int = 3, + headers: Map? = null + ) { if (this == null || url.isNullOrBlank()) return try { GlideApp.with(this.context) - .load(GlideUrl(url)).apply(bitmapTransform(BlurTransformation(radius, sample))) + .load(GlideUrl(url) { headers ?: emptyMap() }) + .apply(bitmapTransform(BlurTransformation(radius, sample))) .transition( DrawableTransitionOptions.withCrossFade() ) diff --git a/app/src/main/res/layout/home_result_big_grid.xml b/app/src/main/res/layout/home_result_big_grid.xml index 710257c0..65998375 100644 --- a/app/src/main/res/layout/home_result_big_grid.xml +++ b/app/src/main/res/layout/home_result_big_grid.xml @@ -24,6 +24,11 @@ android:layout_height="match_parent" android:foreground="?android:attr/selectableItemBackgroundBorderless" android:contentDescription="@string/search_poster_img_des" /> +