Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ open class HomeChildItemAdapter(
position,
holder.itemView,
nextFocusUp,
nextFocusDown
nextFocusDown,
isHorizontal = isHorizontal
)

holder.itemView.tag = position
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.lagradost.cloudstream3.APIHolder
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
import com.lagradost.cloudstream3.CommonActivity.activity
import com.lagradost.cloudstream3.HomePageList
Expand Down Expand Up @@ -146,10 +147,13 @@ class QuickSearchFragment : BaseFragment<QuickSearchBinding>(

val firstProvider = providers?.firstOrNull()
if (isSingleProvider && firstProvider != null) {
val isHorizontal = APIHolder.isApiHorizontal(firstProvider)
binding.quickSearchAutofitResults.apply {
spanCount = context.getSpanCount(isHorizontal)
setRecycledViewPool(SearchAdapter.sharedPool)
adapter = SearchAdapter(
this,
isHorizontal = isHorizontal,
) { callback ->
SearchHelper.handleSearchClickCallback(callback)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import com.lagradost.cloudstream3.ui.result.ResultFragment.updateUIEvent
import com.lagradost.cloudstream3.ui.search.SearchAdapter
import com.lagradost.cloudstream3.ui.search.SearchHelper
import com.lagradost.cloudstream3.ui.setRecycledViewPool
import com.lagradost.cloudstream3.utils.UIHelper.getSpanCount
import com.lagradost.cloudstream3.ui.settings.SettingsGeneral.Companion.pickDownloadPath
import com.lagradost.cloudstream3.ui.settings.utils.getChooseFolderLauncher
import com.lagradost.cloudstream3.utils.AppContextUtils.getNameFull
Expand Down Expand Up @@ -1450,12 +1451,25 @@ open class ResultFragmentPhone : BaseFragment<FragmentResultSwipeBinding>(
private fun setRecommendations(rec: List<SearchResponse>?, validApiName: String?) {
val isInvalid = rec.isNullOrEmpty()
val matchAgainst = validApiName ?: rec?.firstOrNull()?.apiName
val isHorizontal = viewModel.isRecommendationsHorizontal(rec)

recommendationBinding?.apply {
root.isGone = isInvalid
resultRecommendationsList.spanCount = root.context.getSpanCount(isHorizontal)
val currentAdapter = resultRecommendationsList.adapter as? SearchAdapter
val adapter = if (currentAdapter != null) {
currentAdapter.apply { this.isHorizontal = isHorizontal }
} else {
SearchAdapter(
resultRecommendationsList,
isHorizontal = isHorizontal,
) { callback ->
SearchHelper.handleSearchClickCallback(callback)
}.also { resultRecommendationsList.adapter = it }
}
root.post {
rec?.let { list ->
(resultRecommendationsList.adapter as? SearchAdapter)?.submitList(list.filter { it.apiName == matchAgainst })
adapter.submitList(list.filter { it.apiName == matchAgainst })
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,26 @@ class ResultFragmentTv : BaseFragment<FragmentResultTvBinding>(
private fun setRecommendations(rec: List<SearchResponse>?, validApiName: String?) {
currentRecommendations = rec ?: emptyList()
val isInvalid = rec.isNullOrEmpty()
val matchAgainst = validApiName ?: rec?.firstOrNull()?.apiName
val isHorizontal = viewModel.isRecommendationsHorizontal(rec)
binding?.apply {
resultRecommendationsList.isGone = isInvalid
resultRecommendationsHolder.isGone = isInvalid
val matchAgainst = validApiName ?: rec?.firstOrNull()?.apiName
(resultRecommendationsList.adapter as? SearchAdapter)?.submitList(rec?.filter { it.apiName == matchAgainst }
resultRecommendationsList.spanCount = if (isHorizontal) 4 else 8
val currentAdapter = resultRecommendationsList.adapter as? SearchAdapter
val adapter = if (currentAdapter != null) {
currentAdapter.apply { this.isHorizontal = isHorizontal }
} else {
SearchAdapter(
resultRecommendationsList,
isHorizontal = isHorizontal,
) { callback ->
if (callback.action == SEARCH_ACTION_FOCUSED) {
toggleEpisodes(false)
} else SearchHelper.handleSearchClickCallback(callback)
}.also { resultRecommendationsList.adapter = it }
}
adapter.submitList(rec?.filter { it.apiName == matchAgainst }
?: emptyList())

rec?.map { it.apiName }?.distinct()?.let { apiNames ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.SeasonData
import com.lagradost.cloudstream3.ShowStatus
import com.lagradost.cloudstream3.SimklSyncServices
import com.lagradost.cloudstream3.isHorizontalCard
import com.lagradost.cloudstream3.SubtitleFile
import com.lagradost.cloudstream3.TorrentLoadResponse
import com.lagradost.cloudstream3.TrackerType
Expand Down Expand Up @@ -193,6 +194,7 @@ data class ResultData(
val nextAiringDate: UiText?,
val nextAiringEpisode: UiText?,
val plotHeaderText: UiText,
val isHorizontalRecommendations: Boolean = false,
val posterHeaders: Map<String, String>? = null,
)

Expand Down Expand Up @@ -305,6 +307,7 @@ fun LoadResponse.toResultData(repo: APIRepository): ResultData {
backgroundPosterUrl = backgroundPosterUrl,
logoUrl = logoUrl,
title = name,
isHorizontalRecommendations = this.isHorizontalRecommendations || APIHolder.getApiFromNameNull(this.apiName)?.hasHorizontalRecommendations == true || APIHolder.isApiHorizontal(this.apiName) || type == TvType.Live,
typeText = txt(
when (type) {
TvType.TvSeries -> R.string.tv_series_singular
Expand Down Expand Up @@ -492,6 +495,12 @@ class ResultViewModel2 : ViewModel() {
MutableLiveData(null)
val page: LiveData<Resource<ResultData>?> = _page

/** Whether the currently loaded content's recommendations should render as horizontal cards. */
fun isRecommendationsHorizontal(rec: List<SearchResponse>?): Boolean {
return (page.value as? Resource.Success)?.value?.isHorizontalRecommendations == true ||
rec?.any { it.isHorizontalCard() } == true
}

private val _episodes: MutableLiveData<Resource<List<ResultEpisode>>?> =
MutableLiveData(Resource.Loading())
val episodes: LiveData<Resource<List<ResultEpisode>>?> = _episodes
Expand Down Expand Up @@ -2559,6 +2568,7 @@ class ResultViewModel2 : ViewModel() {
override var duration: Int? = null,
override var trailers: MutableList<TrailerData> = mutableListOf(),
override var recommendations: List<SearchResponse>? = null,
override var isHorizontalRecommendations: Boolean = false,
override var actors: List<ActorData>? = null,
override var comingSoon: Boolean = false,
override var syncData: MutableMap<String, String> = mutableMapOf(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package com.lagradost.cloudstream3.ui.search
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.isHorizontalCard
import com.lagradost.cloudstream3.databinding.SearchResultGridBinding
import com.lagradost.cloudstream3.databinding.SearchResultGridExpandedBinding
import com.lagradost.cloudstream3.ui.AutofitRecyclerView
Expand Down Expand Up @@ -32,7 +32,7 @@ class SearchClickCallback(

class SearchAdapter(
private val resView: AutofitRecyclerView,
private val isHorizontal:Boolean = false,
var isHorizontal: Boolean = false,
private val clickCallback: (SearchClickCallback) -> Unit,
) : NoStateAdapter<SearchResponse>(diffCallback = BaseDiffCallback(itemSame = { a, b ->
if (a.id != null || b.id != null) {
Expand All @@ -48,10 +48,6 @@ class SearchAdapter(

var hasNext: Boolean = false

private val coverRatio = if(isHorizontal) 1.8 else 0.68

private val coverHeight: Int get() = (resView.itemWidth / coverRatio).roundToInt()

override fun onCreateContent(parent: ViewGroup): ViewHolderState<Any> {
val inflater = LayoutInflater.from(parent.context)

Expand Down Expand Up @@ -79,21 +75,23 @@ class SearchAdapter(
}

override fun onBindContent(holder: ViewHolderState<Any>, item: SearchResponse, position: Int) {
val imageView = when (val binding = holder.view) {
is SearchResultGridExpandedBinding -> binding.imageView
is SearchResultGridBinding -> binding.imageView
val isCardHorizontal = item.isHorizontalCard(isHorizontal)

val currentRatio = if (isCardHorizontal) 1.8 else 0.68
val currentCoverHeight = (resView.itemWidth / currentRatio).roundToInt()

val backgroundCard = when (val binding = holder.view) {
is SearchResultGridExpandedBinding -> binding.backgroundCard
is SearchResultGridBinding -> binding.backgroundCard
else -> null
}

if (imageView != null) {
val params = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
coverHeight
)
if (imageView.layoutParams.width != params.width || imageView.layoutParams.height != params.height) {
imageView.layoutParams = params
backgroundCard?.let {
val cardParams = it.layoutParams
if (cardParams.height != currentCoverHeight) {
cardParams.height = currentCoverHeight
it.layoutParams = cardParams
}
}
SearchResultBuilder.bind(clickCallback, item, position, holder.view.root)
SearchResultBuilder.bind(clickCallback, item, position, holder.view.root, isHorizontal = isCardHorizontal)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import androidx.core.view.doOnLayout
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton
import com.lagradost.cloudstream3.APIHolder
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
import com.lagradost.cloudstream3.AllLanguagesName
import com.lagradost.cloudstream3.AnimeSearchResponse
Expand All @@ -40,6 +41,7 @@ import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.isHorizontalCard
import com.lagradost.cloudstream3.databinding.FragmentSearchBinding
import com.lagradost.cloudstream3.databinding.HomeSelectMainpageBinding
import com.lagradost.cloudstream3.mvvm.Resource
Expand All @@ -48,6 +50,7 @@ import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.ui.APIRepository
import com.lagradost.cloudstream3.ui.BaseAdapter
import com.lagradost.cloudstream3.ui.BaseFragment
import com.lagradost.cloudstream3.ui.home.HomeChildItemAdapter
import com.lagradost.cloudstream3.ui.home.HomeFragment
import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.bindChips
import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.currentSpan
Expand Down Expand Up @@ -234,6 +237,7 @@ class SearchFragment : BaseFragment<FragmentSearchBinding>(
binding: FragmentSearchBinding,
savedInstanceState: Bundle?
) {
context?.let { HomeChildItemAdapter.updatePosterSize(it) }
reloadRepos()
binding.apply {
val adapter =
Expand Down Expand Up @@ -469,9 +473,12 @@ class SearchFragment : BaseFragment<FragmentSearchBinding>(
it.value.let { data ->
val list = data.list
if (list.isNotEmpty()) {
(binding.searchAutofitResults.adapter as? SearchAdapter)?.submitList(
list
)
val isHorizontal = list.any { it.isHorizontalCard() }
binding.searchAutofitResults.spanCount = view?.context?.getSpanCount(isHorizontal) ?: currentSpan
(binding.searchAutofitResults.adapter as? SearchAdapter)?.apply {
this.isHorizontal = isHorizontal
submitList(list)
}
}
}
searchExitIcon?.alpha = 1f
Expand Down Expand Up @@ -512,7 +519,8 @@ class SearchFragment : BaseFragment<FragmentSearchBinding>(

val homePageList = HomePageList(
providerName,
dataListFiltered
dataListFiltered,
isHorizontalImages = false
)

HomeViewModel.ExpandableHomepageList(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.lagradost.cloudstream3.LiveSearchResponse
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.SearchQuality
import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.isHorizontalCard
import com.lagradost.cloudstream3.isMovieType
import com.lagradost.cloudstream3.syncproviders.SyncAPI
import com.lagradost.cloudstream3.ui.settings.Globals.TV
Expand Down Expand Up @@ -50,6 +51,7 @@ object SearchResultBuilder {
itemView: View,
nextFocusUp: Int? = null,
nextFocusDown: Int? = null,
isHorizontal: Boolean = false,
colorCallback: ((Palette) -> Unit)? = null
) {
val cardView: ImageView = itemView.findViewById(R.id.imageView)
Expand Down Expand Up @@ -132,8 +134,9 @@ object SearchResultBuilder {
cardText?.text = card.name
cardText?.isVisible = showTitle
cardView.isVisible = true
if (!card.posterUrl.isNullOrEmpty()) {
cardView.loadImage(card.posterUrl, card.posterHeaders) {
val poster = if (card.isHorizontalCard(isHorizontal)) card.backgroundPosterUrl ?: card.posterUrl else card.posterUrl
if (!poster.isNullOrEmpty()) {
cardView.loadImage(poster, card.posterHeaders) {
error { getImageFromDrawable(itemView.context, R.drawable.default_cover) }
}
} else cardView.loadImage(R.drawable.default_cover)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ class SyncSearchViewModel {
override var quality: SearchQuality? = null,
override var posterHeaders: Map<String, String>? = null,
override var score: Score? = null,
override var backgroundPosterUrl: String? = null,
) : SearchResponse
}
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ object DataStoreHelper {
@Transient override var score: Score? = null,
@Transient open val tags: List<String>? = null,
) : SearchResponse {
@Transient override var backgroundPosterUrl: String? = null
@JsonProperty("rating", access = JsonProperty.Access.WRITE_ONLY)
@SerialName("rating")
@Deprecated(
Expand Down Expand Up @@ -506,6 +507,7 @@ object DataStoreHelper {
@JsonProperty("quality") @SerialName("quality") override var quality: SearchQuality? = null,
@JsonProperty("posterHeaders") @SerialName("posterHeaders") override var posterHeaders: Map<String, String>? = null,
@JsonProperty("score") @SerialName("score") override var score: Score? = null,
@JsonProperty("backgroundPosterUrl") @SerialName("backgroundPosterUrl") override var backgroundPosterUrl: String? = null,
) : SearchResponse

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ object UIHelper {

fun Context.getSpanCount(isHorizontal:Boolean=false): Int {
// val compactView = false
val spanCountLandscape = if (isHorizontal) 3 else 6
val spanCountLandscape = if (isHorizontal) 5 else 6
val spanCountPortrait = if (isHorizontal) 2 else 3
val orientation = resources.configuration.orientation

Expand Down
Loading