From c3bf08899a5fe915ebca3c4233f4f75ca7208019 Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Sat, 20 Dec 2025 14:51:09 +0530 Subject: [PATCH 01/13] Improving Extractors and also Improved getQualityFromName() --- .../cloudstream3/extractors/BuzzServer.kt | 45 +++++++++++++++++++ .../cloudstream3/extractors/Krakenfiles.kt | 29 ++++++++---- .../cloudstream3/utils/ExtractorApi.kt | 29 ++++++++---- 3 files changed, 86 insertions(+), 17 deletions(-) create mode 100644 library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt new file mode 100644 index 00000000000..880d6329a97 --- /dev/null +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt @@ -0,0 +1,45 @@ +package com.lagradost.cloudstream3.extractors + +import com.lagradost.api.Log +import com.lagradost.cloudstream3.SubtitleFile +import com.lagradost.cloudstream3.app +import com.lagradost.cloudstream3.utils.ExtractorApi +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.getQualityFromName +import com.lagradost.cloudstream3.utils.newExtractorLink + +class BuzzServer : ExtractorApi() { + override val name = "BuzzServer" + override val mainUrl = "https://buzzheavier.com" + override val requiresReferer = true + + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + try { + val qualityText = app.get(url).documentLarge.selectFirst("div.max-w-2xl > span")?.text() + val quality = getQualityFromName(qualityText) + val response = app.get("$url/download", referer = url, allowRedirects = false) + val redirectUrl = response.headers["hx-redirect"] ?: "" + + if (redirectUrl.isNotEmpty()) { + callback.invoke( + newExtractorLink( + "BuzzServer", + "BuzzServer", + redirectUrl, + ) { + this.quality = quality + } + ) + } else { + Log.w("BuzzServer", "No redirect URL found in headers.") + } + } catch (e: Exception) { + Log.e("BuzzServer", "Exception occurred: ${e.message}") + } + } +} \ No newline at end of file diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Krakenfiles.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Krakenfiles.kt index b605a39c6b4..ea59825f91f 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Krakenfiles.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Krakenfiles.kt @@ -5,6 +5,7 @@ import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities +import com.lagradost.cloudstream3.utils.getQualityFromName import com.lagradost.cloudstream3.utils.httpsify import com.lagradost.cloudstream3.utils.newExtractorLink @@ -19,18 +20,28 @@ open class Krakenfiles : ExtractorApi() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ) { - val id = Regex("/(?:view|embed-video)/([\\da-zA-Z]+)").find(url)?.groupValues?.get(1) + val id = Regex("/(?:view|embed-video)/([\\da-zA-Z]+)") + .find(url) + ?.groupValues + ?.get(1) + ?: return + val doc = app.get("$mainUrl/embed-video/$id").document - val link = doc.selectFirst("source")?.attr("src") + val title = doc.select("span.coin-name").text() + val link = doc.selectFirst("source")?.attr("src") ?: return + val quality = getQualityFromName(title) + - callback.invoke( + callback( newExtractorLink( - this.name, - this.name, - httpsify(link ?: return), - ) + name, + name, + httpsify(link) + ) { + this.quality = quality + } ) - } -} \ No newline at end of file +} + diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt index 641c913195e..f3ddb6694b1 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -18,6 +18,7 @@ import com.lagradost.cloudstream3.extractors.BigwarpArt import com.lagradost.cloudstream3.extractors.BigwarpIO import com.lagradost.cloudstream3.extractors.Blogger import com.lagradost.cloudstream3.extractors.BullStream +import com.lagradost.cloudstream3.extractors.BuzzServer import com.lagradost.cloudstream3.extractors.ByseSX import com.lagradost.cloudstream3.extractors.Bysezejataos import com.lagradost.cloudstream3.extractors.ByteShare @@ -791,15 +792,26 @@ enum class Qualities(var value: Int, val defaultPriority: Int) { } } +private val QUALITY_REGEX_MAP = listOf( + Regex("""\b(4k|2160p?|2160)\b""", RegexOption.IGNORE_CASE) to Qualities.P2160.value, + Regex("""\b1440p?|1440\b""", RegexOption.IGNORE_CASE) to Qualities.P1440.value, + Regex("""\b1080p?|1080\b""", RegexOption.IGNORE_CASE) to Qualities.P1080.value, + Regex("""\b720p?|720\b""", RegexOption.IGNORE_CASE) to Qualities.P720.value, + Regex("""\b480p?|480\b""", RegexOption.IGNORE_CASE) to Qualities.P480.value +) +private var lastResolvedQuality: Int = Qualities.Unknown.value + fun getQualityFromName(qualityName: String?): Int { - if (qualityName == null) - return Qualities.Unknown.value - - val match = qualityName.lowercase().replace("p", "").trim() - return when (match) { - "4k" -> Qualities.P2160 - else -> null - }?.value ?: match.toIntOrNull() ?: Qualities.Unknown.value + if (qualityName.isNullOrBlank()) + return lastResolvedQuality + + for ((regex, quality) in QUALITY_REGEX_MAP) { + if (regex.containsMatchIn(qualityName)) { + lastResolvedQuality = maxOf(lastResolvedQuality, quality) + return lastResolvedQuality + } + } + return lastResolvedQuality } private val packedRegex = Regex("""eval\(function\(p,a,c,k,e,.*\)\)""") @@ -1077,6 +1089,7 @@ val extractorApis: MutableList = arrayListOf( Fembed9hd(), StreamM4u(), Krakenfiles(), + BuzzServer(), Gofile(), Vicloud(), Uservideo(), From ff1c195e32bd7ee310c8ba5ccda95bf669dcd0dd Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Sat, 20 Dec 2025 14:55:21 +0530 Subject: [PATCH 02/13] Improving Extractors and also Improved getQualityFromName() --- .../kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt index 880d6329a97..9e0eb7f6098 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt @@ -1,6 +1,7 @@ package com.lagradost.cloudstream3.extractors import com.lagradost.api.Log +import com.lagradost.cloudstream3.Prerelease import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.ExtractorApi @@ -8,6 +9,7 @@ import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.getQualityFromName import com.lagradost.cloudstream3.utils.newExtractorLink +@Prerelease class BuzzServer : ExtractorApi() { override val name = "BuzzServer" override val mainUrl = "https://buzzheavier.com" From 0bbdba17449741a0725635d18632216150a7c3d6 Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Fri, 2 Jan 2026 15:36:52 +0530 Subject: [PATCH 03/13] Smart Branding Logo on Background Poster --- .../ui/result/ResultFragmentPhone.kt | 11 +++++++++++ .../cloudstream3/ui/result/ResultFragmentTv.kt | 11 +++++++++++ .../cloudstream3/ui/result/ResultViewModel2.kt | 4 ++++ app/src/main/res/layout/fragment_result.xml | 10 ++++++++++ app/src/main/res/layout/fragment_result_tv.xml | 16 ++++++++++++++-- .../kotlin/com/lagradost/cloudstream3/MainAPI.kt | 6 ++++++ 6 files changed, 56 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt index 3bac24dd74e..a5f5b4288e7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt @@ -800,6 +800,17 @@ open class ResultFragmentPhone : FullScreenPlayer() { } } + if (!d.logourl.isNullOrBlank()) { + backgroundPosterWatermarkBadge.isVisible = true + resultTitle.isVisible = false + + backgroundPosterWatermarkBadge.loadImage(d.logourl) + } else { + // No logo URL → show title + backgroundPosterWatermarkBadge.isVisible = false + resultTitle.isVisible = true + } + var isExpanded = false resultDescription.apply { setTextHtml(d.plotText) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt index af2fe254dd0..150162b7bbe 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt @@ -909,6 +909,17 @@ class ResultFragmentTv : BaseFragment( backgroundPoster.loadImage(d.posterBackgroundImage) { error { getImageFromDrawable(context ?: return@error null, error) } } + + if (!d.logourl.isNullOrBlank()) { + backgroundPosterWatermarkBadgeHolder.isVisible = true + resultTitle.isVisible = false + + backgroundPosterWatermarkBadgeHolder.loadImage(d.logourl) + } else { + // No logo URL → show title + backgroundPosterWatermarkBadgeHolder.isVisible = false + resultTitle.isVisible = true + } comingSoon = d.comingSoon resultTvComingSoon.isVisible = d.comingSoon diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt index 27ae0eacc24..aa81003981d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt @@ -120,6 +120,7 @@ data class ResultData( val posterImage: String?, val posterBackgroundImage: String?, + val logourl: String?, val plotText: UiText, val apiName: UiText, val ratingText: UiText?, @@ -245,6 +246,7 @@ fun LoadResponse.toResultData(repo: APIRepository): ResultData { plot!! ), backgroundPosterUrl = backgroundPosterUrl, + logourl = logourl, title = name, typeText = txt( when (type) { @@ -1895,6 +1897,7 @@ class ResultViewModel2 : ViewModel() { // set posters, might fuck up due to headers idk posterUrl = posterUrl ?: res?.image backgroundPosterUrl = backgroundPosterUrl ?: res?.cover + logourl = logourl }, { if (meta == null) return@runAllAsync @@ -2695,6 +2698,7 @@ class ResultViewModel2 : ViewModel() { override var syncData: MutableMap = mutableMapOf(), override var posterHeaders: Map? = null, override var backgroundPosterUrl: String? = null, + override var logourl: String? = null, override var contentRating: String? = null, override var uniqueUrl: String = url, val id: Int?, diff --git a/app/src/main/res/layout/fragment_result.xml b/app/src/main/res/layout/fragment_result.xml index e025e72bd27..2a44c327f63 100644 --- a/app/src/main/res/layout/fragment_result.xml +++ b/app/src/main/res/layout/fragment_result.xml @@ -293,6 +293,16 @@ android:layout_height="match_parent" android:scaleType="centerCrop" /> + + + + + + var posterHeaders: Map? var backgroundPosterUrl: String? + var logourl: String? var contentRating: String? var uniqueUrl: String @@ -2217,6 +2218,7 @@ constructor( override var syncData: MutableMap = mutableMapOf(), override var posterHeaders: Map? = null, override var backgroundPosterUrl: String? = null, + override var logourl: String? = null, override var contentRating: String? = null, override var uniqueUrl: String = url ) : LoadResponse @@ -2277,6 +2279,7 @@ constructor( override var nextAiring: NextAiring? = null, override var seasonNames: List? = null, override var backgroundPosterUrl: String? = null, + override var logourl: String? = null, override var contentRating: String? = null, override var uniqueUrl: String = url ) : LoadResponse, EpisodeResponse { @@ -2362,6 +2365,7 @@ constructor( override var syncData: MutableMap = mutableMapOf(), override var posterHeaders: Map? = null, override var backgroundPosterUrl: String? = null, + override var logourl: String? = null, override var contentRating: String? = null, override var uniqueUrl: String = url ) : LoadResponse @@ -2410,6 +2414,7 @@ constructor( override var syncData: MutableMap = mutableMapOf(), override var posterHeaders: Map? = null, override var backgroundPosterUrl: String? = null, + override var logourl: String? = null, override var contentRating: String? = null, override var uniqueUrl: String = url ) : LoadResponse @@ -2589,6 +2594,7 @@ constructor( override var nextAiring: NextAiring? = null, override var seasonNames: List? = null, override var backgroundPosterUrl: String? = null, + override var logourl: String? = null, override var contentRating: String? = null, override var uniqueUrl: String = url ) : LoadResponse, EpisodeResponse { From 8970a9866dacc553a41d306ffe2a357671011210 Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Fri, 2 Jan 2026 15:46:24 +0530 Subject: [PATCH 04/13] Smart Branding Logo on Background Poster --- app/src/main/res/layout/fragment_result.xml | 2 +- app/src/main/res/layout/fragment_result_tv.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/fragment_result.xml b/app/src/main/res/layout/fragment_result.xml index 2a44c327f63..f3607fcc413 100644 --- a/app/src/main/res/layout/fragment_result.xml +++ b/app/src/main/res/layout/fragment_result.xml @@ -298,7 +298,7 @@ android:layout_width="wrap_content" android:layout_height="56dp" android:layout_gravity="bottom|start" - android:layout_marginStart="5dp" + android:layout_marginStart="18dp" android:layout_marginBottom="10dp" android:adjustViewBounds="true" android:scaleType="fitCenter" /> diff --git a/app/src/main/res/layout/fragment_result_tv.xml b/app/src/main/res/layout/fragment_result_tv.xml index 92dbc46ef4e..961ce152196 100644 --- a/app/src/main/res/layout/fragment_result_tv.xml +++ b/app/src/main/res/layout/fragment_result_tv.xml @@ -42,7 +42,7 @@ https://developer.android.com/design/ui/tv/samples/jet-fit android:layout_width="wrap_content" android:layout_height="56dp" android:layout_gravity="bottom|start" - android:layout_marginStart="12dp" + android:layout_marginStart="18dp" android:layout_marginBottom="45dp" android:adjustViewBounds="true" android:scaleType="fitCenter" /> From 2c1117c2905d4c21108d4efd332c792a09c6e348 Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Fri, 2 Jan 2026 16:00:50 +0530 Subject: [PATCH 05/13] Minor Fix --- app/src/main/res/layout/fragment_result.xml | 7 ++++--- app/src/main/res/layout/fragment_result_tv.xml | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/layout/fragment_result.xml b/app/src/main/res/layout/fragment_result.xml index f3607fcc413..7de3648d586 100644 --- a/app/src/main/res/layout/fragment_result.xml +++ b/app/src/main/res/layout/fragment_result.xml @@ -295,13 +295,14 @@ + android:scaleType="fitStart" + android:foregroundGravity="bottom|left" /> + android:scaleType="fitStart" /> Date: Fri, 2 Jan 2026 16:14:24 +0530 Subject: [PATCH 06/13] Minor Fix --- app/src/main/res/layout/fragment_result.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/layout/fragment_result.xml b/app/src/main/res/layout/fragment_result.xml index 7de3648d586..8943889cb7c 100644 --- a/app/src/main/res/layout/fragment_result.xml +++ b/app/src/main/res/layout/fragment_result.xml @@ -293,6 +293,12 @@ android:layout_height="match_parent" android:scaleType="centerCrop" /> + + - - From 0d5670d76e6da11b3957f2eee03a7790ac187bcb Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Fri, 2 Jan 2026 17:01:31 +0530 Subject: [PATCH 07/13] Minor Fix Show Title if Trailer Loads --- .../com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt index a5f5b4288e7..3452549dee7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt @@ -161,6 +161,7 @@ open class ResultFragmentPhone : FullScreenPlayer() { } private fun loadTrailer(index: Int? = null) { + val isSuccess = currentTrailers.getOrNull(index ?: currentTrailerIndex)?.let { (extractedTrailerLink,_) -> context?.let { ctx -> @@ -189,6 +190,7 @@ open class ResultFragmentPhone : FullScreenPlayer() { // result_trailer_loading?.isVisible = isSuccess val turnVis = !isSuccess && !isFullScreenPlayer resultBinding?.apply { + resultTitle.isVisible = isSuccess resultSmallscreenHolder.isVisible = turnVis resultPosterBackgroundHolder.apply { val fadeIn: Animation = AlphaAnimation(alpha, if (turnVis) 1.0f else 0.0f).apply { From b98a199e7f0a47608972ca899886d527f414c881 Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Sat, 3 Jan 2026 21:02:21 +0530 Subject: [PATCH 08/13] Fixes and Changes --- .../ui/result/ResultFragmentPhone.kt | 23 +++++++++-- .../ui/result/ResultFragmentTv.kt | 38 ++++++++++++++----- .../ui/result/ResultViewModel2.kt | 8 ++-- app/src/main/res/layout/fragment_result.xml | 13 ++++--- .../main/res/layout/fragment_result_tv.xml | 11 +++--- .../com/lagradost/cloudstream3/MainAPI.kt | 12 +++--- 6 files changed, 73 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt index 3452549dee7..9b1ffecdf96 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt @@ -86,6 +86,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.populateChips import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes import com.lagradost.cloudstream3.utils.UIHelper.setListViewHeightBasedOnItems import com.lagradost.cloudstream3.utils.UIHelper.setNavigationBarColorCompat +import com.lagradost.cloudstream3.utils.UiImage import com.lagradost.cloudstream3.utils.VideoDownloadHelper import com.lagradost.cloudstream3.utils.getImageFromDrawable import com.lagradost.cloudstream3.utils.setText @@ -802,17 +803,33 @@ open class ResultFragmentPhone : FullScreenPlayer() { } } - if (!d.logourl.isNullOrBlank()) { + if (!d.logoUrl.isNullOrBlank()) { + backgroundPosterWatermarkBadge.isVisible = true resultTitle.isVisible = false - backgroundPosterWatermarkBadge.loadImage(d.logourl) + backgroundPosterWatermarkBadge.loadImage( + imageData = UiImage.Image(d.logoUrl), + builder = { + listener( + onSuccess = { _, _ -> + backgroundPosterWatermarkBadge.isVisible = true + resultTitle.isVisible = false + }, + onError = { _, _ -> + backgroundPosterWatermarkBadge.isVisible = false + resultTitle.isVisible = true + } + ) + } + ) + } else { - // No logo URL → show title backgroundPosterWatermarkBadge.isVisible = false resultTitle.isVisible = true } + var isExpanded = false resultDescription.apply { setTextHtml(d.plotText) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt index 150162b7bbe..d1d725406d3 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt @@ -60,12 +60,14 @@ import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard import com.lagradost.cloudstream3.utils.UIHelper.navigate import com.lagradost.cloudstream3.utils.UIHelper.populateChips import com.lagradost.cloudstream3.utils.UIHelper.setNavigationBarColorCompat +import com.lagradost.cloudstream3.utils.UiImage import com.lagradost.cloudstream3.utils.getImageFromDrawable import com.lagradost.cloudstream3.utils.setText import com.lagradost.cloudstream3.utils.setTextHtml +import com.lagradost.cloudstream3.utils.txt class ResultFragmentTv : BaseFragment( - BaseFragment.BindingCreator.Inflate(FragmentResultTvBinding::inflate) + BindingCreator.Inflate(FragmentResultTvBinding::inflate) ) { private lateinit var viewModel: ResultViewModel2 @@ -160,7 +162,7 @@ class ResultFragmentTv : BaseFragment( // very dirty selection resultRecommendationsFilterSelection.isVisible = apiNames.size > 1 resultRecommendationsFilterSelection.update(apiNames.map { - com.lagradost.cloudstream3.utils.txt( + txt( it ) to it }) @@ -605,10 +607,10 @@ class ResultFragmentTv : BaseFragment( } else R.string.favorite_removed val name = (viewModel.page.value as? Resource.Success)?.value?.title - ?: com.lagradost.cloudstream3.utils.txt(R.string.no_data) + ?: txt(R.string.no_data) .asStringNull(context) ?: "" CommonActivity.showToast( - com.lagradost.cloudstream3.utils.txt( + txt( message, name ), Toast.LENGTH_SHORT @@ -646,10 +648,10 @@ class ResultFragmentTv : BaseFragment( } else R.string.subscription_deleted val name = (viewModel.page.value as? Resource.Success)?.value?.title - ?: com.lagradost.cloudstream3.utils.txt(R.string.no_data) + ?: txt(R.string.no_data) .asStringNull(context) ?: "" CommonActivity.showToast( - com.lagradost.cloudstream3.utils.txt( + txt( message, name ), Toast.LENGTH_SHORT @@ -910,16 +912,34 @@ class ResultFragmentTv : BaseFragment( error { getImageFromDrawable(context ?: return@error null, error) } } - if (!d.logourl.isNullOrBlank()) { + if (!d.logoUrl.isNullOrBlank()) { + backgroundPosterWatermarkBadgeHolder.isVisible = true resultTitle.isVisible = false - backgroundPosterWatermarkBadgeHolder.loadImage(d.logourl) + backgroundPosterWatermarkBadgeHolder.loadImage( + imageData = UiImage.Image(d.logoUrl), + builder = { + listener( + onSuccess = { _, _ -> + backgroundPosterWatermarkBadgeHolder.isVisible = true + resultTitle.isVisible = false + }, + onError = { _, _ -> + backgroundPosterWatermarkBadgeHolder.isVisible = false + resultTitle.isVisible = true + } + ) + } + ) + } else { - // No logo URL → show title backgroundPosterWatermarkBadgeHolder.isVisible = false resultTitle.isVisible = true } + + + comingSoon = d.comingSoon resultTvComingSoon.isVisible = d.comingSoon diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt index aa81003981d..d0d9b8c9333 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt @@ -120,7 +120,7 @@ data class ResultData( val posterImage: String?, val posterBackgroundImage: String?, - val logourl: String?, + val logoUrl: String?, val plotText: UiText, val apiName: UiText, val ratingText: UiText?, @@ -246,7 +246,7 @@ fun LoadResponse.toResultData(repo: APIRepository): ResultData { plot!! ), backgroundPosterUrl = backgroundPosterUrl, - logourl = logourl, + logoUrl = logoUrl, title = name, typeText = txt( when (type) { @@ -1897,7 +1897,7 @@ class ResultViewModel2 : ViewModel() { // set posters, might fuck up due to headers idk posterUrl = posterUrl ?: res?.image backgroundPosterUrl = backgroundPosterUrl ?: res?.cover - logourl = logourl + logoUrl = logoUrl }, { if (meta == null) return@runAllAsync @@ -2698,7 +2698,7 @@ class ResultViewModel2 : ViewModel() { override var syncData: MutableMap = mutableMapOf(), override var posterHeaders: Map? = null, override var backgroundPosterUrl: String? = null, - override var logourl: String? = null, + override var logoUrl: String? = null, override var contentRating: String? = null, override var uniqueUrl: String = url, val id: Int?, diff --git a/app/src/main/res/layout/fragment_result.xml b/app/src/main/res/layout/fragment_result.xml index 8943889cb7c..9eeec61d574 100644 --- a/app/src/main/res/layout/fragment_result.xml +++ b/app/src/main/res/layout/fragment_result.xml @@ -301,14 +301,17 @@ + android:contentDescription="@null" /> + diff --git a/app/src/main/res/layout/fragment_result_tv.xml b/app/src/main/res/layout/fragment_result_tv.xml index 366c79c94d2..5675070455e 100644 --- a/app/src/main/res/layout/fragment_result_tv.xml +++ b/app/src/main/res/layout/fragment_result_tv.xml @@ -39,13 +39,14 @@ https://developer.android.com/design/ui/tv/samples/jet-fit + android:scaleType="fitStart" + android:contentDescription="@null" /> var posterHeaders: Map? var backgroundPosterUrl: String? - var logourl: String? + var logoUrl: String? var contentRating: String? var uniqueUrl: String @@ -2218,7 +2218,7 @@ constructor( override var syncData: MutableMap = mutableMapOf(), override var posterHeaders: Map? = null, override var backgroundPosterUrl: String? = null, - override var logourl: String? = null, + override var logoUrl: String? = null, override var contentRating: String? = null, override var uniqueUrl: String = url ) : LoadResponse @@ -2279,7 +2279,7 @@ constructor( override var nextAiring: NextAiring? = null, override var seasonNames: List? = null, override var backgroundPosterUrl: String? = null, - override var logourl: String? = null, + override var logoUrl: String? = null, override var contentRating: String? = null, override var uniqueUrl: String = url ) : LoadResponse, EpisodeResponse { @@ -2365,7 +2365,7 @@ constructor( override var syncData: MutableMap = mutableMapOf(), override var posterHeaders: Map? = null, override var backgroundPosterUrl: String? = null, - override var logourl: String? = null, + override var logoUrl: String? = null, override var contentRating: String? = null, override var uniqueUrl: String = url ) : LoadResponse @@ -2414,7 +2414,7 @@ constructor( override var syncData: MutableMap = mutableMapOf(), override var posterHeaders: Map? = null, override var backgroundPosterUrl: String? = null, - override var logourl: String? = null, + override var logoUrl: String? = null, override var contentRating: String? = null, override var uniqueUrl: String = url ) : LoadResponse @@ -2594,7 +2594,7 @@ constructor( override var nextAiring: NextAiring? = null, override var seasonNames: List? = null, override var backgroundPosterUrl: String? = null, - override var logourl: String? = null, + override var logoUrl: String? = null, override var contentRating: String? = null, override var uniqueUrl: String = url ) : LoadResponse, EpisodeResponse { From 26dd6dbc5c18119c501b93919874affaee8142ce Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Mon, 5 Jan 2026 18:02:45 +0530 Subject: [PATCH 09/13] Fixes --- .../ui/result/ResultFragmentPhone.kt | 3 +-- .../ui/result/ResultFragmentTv.kt | 2 +- app/src/main/res/layout/fragment_result.xml | 5 +++-- .../main/res/layout/fragment_result_tv.xml | 21 +++++++++++-------- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt index 9b1ffecdf96..fc0a3bffa3d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt @@ -804,12 +804,11 @@ open class ResultFragmentPhone : FullScreenPlayer() { } if (!d.logoUrl.isNullOrBlank()) { - backgroundPosterWatermarkBadge.isVisible = true resultTitle.isVisible = false backgroundPosterWatermarkBadge.loadImage( - imageData = UiImage.Image(d.logoUrl), + imageData = UiImage.Image(d.logoUrl,headers = d.posterHeaders), builder = { listener( onSuccess = { _, _ -> diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt index d1d725406d3..cd0622d4d41 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt @@ -918,7 +918,7 @@ class ResultFragmentTv : BaseFragment( resultTitle.isVisible = false backgroundPosterWatermarkBadgeHolder.loadImage( - imageData = UiImage.Image(d.logoUrl), + imageData = UiImage.Image(d.logoUrl,headers = d.posterHeaders), builder = { listener( onSuccess = { _, _ -> diff --git a/app/src/main/res/layout/fragment_result.xml b/app/src/main/res/layout/fragment_result.xml index 9eeec61d574..c6de5954279 100644 --- a/app/src/main/res/layout/fragment_result.xml +++ b/app/src/main/res/layout/fragment_result.xml @@ -302,10 +302,11 @@ + + - Date: Tue, 6 Jan 2026 10:50:36 +0530 Subject: [PATCH 10/13] Adding Logo to show on Homepage as well --- .../ui/home/HomeParentItemAdapterPreview.kt | 35 +++++++++++++++++++ .../cloudstream3/ui/home/HomeScrollAdapter.kt | 21 +++++++++++ .../main/res/layout/fragment_home_head_tv.xml | 9 +++++ app/src/main/res/layout/home_scroll_view.xml | 9 +++++ 4 files changed, 74 insertions(+) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapterPreview.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapterPreview.kt index e6b82e47382..091baec043b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapterPreview.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapterPreview.kt @@ -58,6 +58,7 @@ import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showOptionSelectSt import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbarMargin import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbarView import com.lagradost.cloudstream3.utils.UIHelper.populateChips +import com.lagradost.cloudstream3.utils.UiImage class HomeParentItemAdapterPreview( val fragment: LifecycleOwner, @@ -350,6 +351,40 @@ class HomeParentItemAdapterPreview( R.style.ChipFilledSemiTransparent ) + + val logoUrl = item.logoUrl?.takeIf { it.isNotBlank() } + + homeBackgroundPosterWatermarkBadgeHolder.visibility = View.VISIBLE + homeBackgroundPosterWatermarkBadgeHolder.alpha = 0f + homePreviewText.isVisible = false + + if (logoUrl != null) { + homeBackgroundPosterWatermarkBadgeHolder.loadImage( + imageData = UiImage.Image( + logoUrl, + headers = item.posterHeaders + ), + builder = { + listener( + onSuccess = { _, _ -> + // logo loaded → show logo only + homeBackgroundPosterWatermarkBadgeHolder.alpha = 1f + homePreviewText.isVisible = false + }, + onError = { _, _ -> + // logo failed → show title + homeBackgroundPosterWatermarkBadgeHolder.alpha = 0f + homePreviewText.isVisible = true + } + ) + } + ) + } else { + // no logo at all → show title immediately + homeBackgroundPosterWatermarkBadgeHolder.alpha = 0f + homePreviewText.isVisible = true + } + homePreviewTags.isGone = item.tags.isNullOrEmpty() diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeScrollAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeScrollAdapter.kt index 9bec473b58b..c18593be3cb 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeScrollAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeScrollAdapter.kt @@ -4,6 +4,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.view.isGone +import androidx.core.view.isVisible import com.lagradost.cloudstream3.LoadResponse import com.lagradost.cloudstream3.databinding.HomeScrollViewBinding import com.lagradost.cloudstream3.databinding.HomeScrollViewTvBinding @@ -15,6 +16,7 @@ import com.lagradost.cloudstream3.ui.settings.Globals.TV import com.lagradost.cloudstream3.ui.settings.Globals.isLandscape import com.lagradost.cloudstream3.ui.settings.Globals.isLayout import com.lagradost.cloudstream3.utils.ImageLoader.loadImage +import com.lagradost.cloudstream3.utils.UiImage class HomeScrollAdapter( val callback: ((View, Int, LoadResponse) -> Unit) @@ -66,6 +68,25 @@ class HomeScrollAdapter( maxLines = 2 } binding.homeScrollPreviewTitle.text = item.name + val logoUrl = item.logoUrl?.takeIf { it.isNotBlank() } + if (logoUrl != null) { + binding.homePreviewLogo.loadImage( + imageData = UiImage.Image(logoUrl), + builder = { + listener( + onSuccess = { _, _ -> + // logo really loaded + binding.homeScrollPreviewTitle.isVisible = false + }, + onError = { _, _ -> + // logo failed → show title + binding.homeScrollPreviewTitle.isVisible = true + } + ) + } + ) + } + } is HomeScrollViewTvBinding -> { diff --git a/app/src/main/res/layout/fragment_home_head_tv.xml b/app/src/main/res/layout/fragment_home_head_tv.xml index 11a8b815ffb..7c0da5795d5 100644 --- a/app/src/main/res/layout/fragment_home_head_tv.xml +++ b/app/src/main/res/layout/fragment_home_head_tv.xml @@ -67,6 +67,15 @@ android:orientation="vertical" android:padding="10dp"> + + + + Date: Tue, 6 Jan 2026 11:01:09 +0530 Subject: [PATCH 11/13] Fixes --- .../com/lagradost/cloudstream3/ui/home/HomeScrollAdapter.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeScrollAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeScrollAdapter.kt index c18593be3cb..1ff226fb35c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeScrollAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeScrollAdapter.kt @@ -71,15 +71,17 @@ class HomeScrollAdapter( val logoUrl = item.logoUrl?.takeIf { it.isNotBlank() } if (logoUrl != null) { binding.homePreviewLogo.loadImage( - imageData = UiImage.Image(logoUrl), + imageData = UiImage.Image(logoUrl,item.posterHeaders), builder = { listener( onSuccess = { _, _ -> // logo really loaded + binding.homePreviewLogo.isVisible = true binding.homeScrollPreviewTitle.isVisible = false }, onError = { _, _ -> // logo failed → show title + binding.homePreviewLogo.isVisible = false binding.homeScrollPreviewTitle.isVisible = true } ) From e41f02a49923cacefe5e8c9964f9d2b015805d16 Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Tue, 6 Jan 2026 12:36:38 +0530 Subject: [PATCH 12/13] Minor Improvement Fix --- .../ui/home/HomeParentItemAdapterPreview.kt | 10 ++++++---- .../cloudstream3/ui/home/HomeScrollAdapter.kt | 4 ++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapterPreview.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapterPreview.kt index 091baec043b..9060ae288d9 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapterPreview.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapterPreview.kt @@ -354,7 +354,7 @@ class HomeParentItemAdapterPreview( val logoUrl = item.logoUrl?.takeIf { it.isNotBlank() } - homeBackgroundPosterWatermarkBadgeHolder.visibility = View.VISIBLE + homeBackgroundPosterWatermarkBadgeHolder.isVisible = false homeBackgroundPosterWatermarkBadgeHolder.alpha = 0f homePreviewText.isVisible = false @@ -368,23 +368,25 @@ class HomeParentItemAdapterPreview( listener( onSuccess = { _, _ -> // logo loaded → show logo only + homeBackgroundPosterWatermarkBadgeHolder.isVisible = true homeBackgroundPosterWatermarkBadgeHolder.alpha = 1f homePreviewText.isVisible = false }, onError = { _, _ -> // logo failed → show title - homeBackgroundPosterWatermarkBadgeHolder.alpha = 0f + homeBackgroundPosterWatermarkBadgeHolder.isVisible = false homePreviewText.isVisible = true } ) } ) } else { - // no logo at all → show title immediately - homeBackgroundPosterWatermarkBadgeHolder.alpha = 0f + // no logo → show title immediately + homeBackgroundPosterWatermarkBadgeHolder.isVisible = false homePreviewText.isVisible = true } + homePreviewTags.isGone = item.tags.isNullOrEmpty() diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeScrollAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeScrollAdapter.kt index 1ff226fb35c..9687cc29b8d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeScrollAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeScrollAdapter.kt @@ -68,6 +68,10 @@ class HomeScrollAdapter( maxLines = 2 } binding.homeScrollPreviewTitle.text = item.name + + binding.homePreviewLogo.isVisible = false + binding.homeScrollPreviewTitle.isVisible = false + val logoUrl = item.logoUrl?.takeIf { it.isNotBlank() } if (logoUrl != null) { binding.homePreviewLogo.loadImage( From 15d05fef4bb631f4701043edf1774fc20568206b Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Tue, 6 Jan 2026 19:18:05 +0530 Subject: [PATCH 13/13] Minor Improvement Fix --- app/src/main/res/layout/fragment_result_tv.xml | 4 ++-- .../commonMain/kotlin/com/lagradost/cloudstream3/MainAPI.kt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/fragment_result_tv.xml b/app/src/main/res/layout/fragment_result_tv.xml index ff7c2c92d65..3dff8f0d535 100644 --- a/app/src/main/res/layout/fragment_result_tv.xml +++ b/app/src/main/res/layout/fragment_result_tv.xml @@ -61,8 +61,8 @@ https://developer.android.com/design/ui/tv/samples/jet-fit