made inf scrolling better + fixed search bug

This commit is contained in:
LagradOst 2022-07-30 17:30:23 +02:00
parent 625ff8c910
commit d3b3091fe0
10 changed files with 179 additions and 47 deletions

View file

@ -3,7 +3,6 @@ package com.lagradost.cloudstream3.animeproviders
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.getQualityFromName import com.lagradost.cloudstream3.utils.getQualityFromName
import java.net.URLDecoder import java.net.URLDecoder
@ -75,7 +74,6 @@ class AniflixProvider : MainAPI() {
val token = getToken() val token = getToken()
val url = "$mainUrl/_next/data/$token/search.json?keyword=$query" val url = "$mainUrl/_next/data/$token/search.json?keyword=$query"
val response = app.get(url) val response = app.get(url)
println("resp: $url ===> ${response.text}")
val searchResponse = val searchResponse =
response.parsedSafe<Search>() response.parsedSafe<Search>()
?: throw ErrorLoadingException("No Media") ?: throw ErrorLoadingException("No Media")

View file

@ -24,6 +24,7 @@ class HomeChildItemAdapter(
) : ) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() { RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var isHorizontal: Boolean = false var isHorizontal: Boolean = false
var hasNext : Boolean = false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layout = overrideLayout val layout = overrideLayout

View file

@ -22,6 +22,7 @@ import androidx.fragment.app.activityViewModels
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearSnapHelper import androidx.recyclerview.widget.LinearSnapHelper
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
@ -46,6 +47,8 @@ import com.lagradost.cloudstream3.ui.search.SearchHelper.handleSearchClickCallba
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult
import com.lagradost.cloudstream3.utils.AppUtils.setMaxViewPoolSize
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import com.lagradost.cloudstream3.utils.DataStore.getKey import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.setKey import com.lagradost.cloudstream3.utils.DataStore.setKey
import com.lagradost.cloudstream3.utils.DataStoreHelper import com.lagradost.cloudstream3.utils.DataStoreHelper
@ -119,11 +122,27 @@ class HomeFragment : Fragment() {
val errorProfilePic = errorProfilePics.random() val errorProfilePic = errorProfilePics.random()
fun Activity.loadHomepageList(item: HomePageList, deleteCallback: (() -> Unit)? = null) { fun Activity.loadHomepageList(
item: HomePageList,
deleteCallback: (() -> Unit)? = null,
) {
loadHomepageList(
expand = HomeViewModel.ExpandableHomepageList(item, 1, false),
deleteCallback = deleteCallback,
expandCallback = null
)
}
fun Activity.loadHomepageList(
expand: HomeViewModel.ExpandableHomepageList,
deleteCallback: (() -> Unit)? = null,
expandCallback: (suspend (String) -> HomeViewModel.ExpandableHomepageList?)? = null
) {
val context = this val context = this
val bottomSheetDialogBuilder = BottomSheetDialog(context) val bottomSheetDialogBuilder = BottomSheetDialog(context)
bottomSheetDialogBuilder.setContentView(R.layout.home_episodes_expanded) bottomSheetDialogBuilder.setContentView(R.layout.home_episodes_expanded)
val title = bottomSheetDialogBuilder.findViewById<TextView>(R.id.home_expanded_text)!! val title = bottomSheetDialogBuilder.findViewById<TextView>(R.id.home_expanded_text)!!
val item = expand.list
title.text = item.name title.text = item.name
val recycle = val recycle =
bottomSheetDialogBuilder.findViewById<AutofitRecyclerView>(R.id.home_expanded_recycler)!! bottomSheetDialogBuilder.findViewById<AutofitRecyclerView>(R.id.home_expanded_recycler)!!
@ -176,8 +195,36 @@ class HomeFragment : Fragment() {
if (callback.action == SEARCH_ACTION_LOAD || callback.action == SEARCH_ACTION_PLAY_FILE) { if (callback.action == SEARCH_ACTION_LOAD || callback.action == SEARCH_ACTION_PLAY_FILE) {
bottomSheetDialogBuilder.dismissSafe(this) bottomSheetDialogBuilder.dismissSafe(this)
} }
}.apply {
hasNext = expand.hasNext
} }
recycle.addOnScrollListener(object : RecyclerView.OnScrollListener() {
var expandCount = 0
val name = expand.list.name
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
val adapter = recyclerView.adapter
if (adapter !is SearchAdapter) return
val count = adapter.itemCount
val currentHasNext = adapter.hasNext
if (!recyclerView.canScrollVertically(1) && currentHasNext && expandCount != count) {
expandCount = count
ioSafe {
expandCallback?.invoke(name)?.let { newExpand ->
(recyclerView.adapter as? SearchAdapter?)?.apply {
hasNext = newExpand.hasNext
updateList(newExpand.list.list)
}
}
}
}
}
})
val spanListener = { span: Int -> val spanListener = { span: Int ->
recycle.spanCount = span recycle.spanCount = span
//(recycle.adapter as SearchAdapter).notifyDataSetChanged() //(recycle.adapter as SearchAdapter).notifyDataSetChanged()
@ -537,7 +584,10 @@ class HomeFragment : Fragment() {
listHomepageItems.clear() listHomepageItems.clear()
// println("ITEMCOUNT: ${d.values.size} ${home_master_recycler?.adapter?.itemCount}") // println("ITEMCOUNT: ${d.values.size} ${home_master_recycler?.adapter?.itemCount}")
(home_master_recycler?.adapter as? ParentItemAdapter?)?.updateList(d.values.toMutableList()) (home_master_recycler?.adapter as? ParentItemAdapter?)?.updateList(
d.values.toMutableList(),
home_master_recycler
)
home_loading?.isVisible = false home_loading?.isVisible = false
home_loading_error?.isVisible = false home_loading_error?.isVisible = false
@ -843,15 +893,18 @@ class HomeFragment : Fragment() {
ParentItemAdapter(mutableListOf(), { callback -> ParentItemAdapter(mutableListOf(), { callback ->
homeHandleSearch(callback) homeHandleSearch(callback)
}, { item -> }, { item ->
activity?.loadHomepageList(item) activity?.loadHomepageList(item, expandCallback = {
homeViewModel.expandAndReturn(it)
})
}, { name -> }, { name ->
homeViewModel.expand(name) homeViewModel.expand(name)
}) })
home_master_recycler?.setMaxViewPoolSize(0, Int.MAX_VALUE)
home_master_recycler.layoutManager = object : LinearLayoutManager(context) { home_master_recycler.layoutManager = object : LinearLayoutManager(context) {
override fun supportsPredictiveItemAnimations(): Boolean { override fun supportsPredictiveItemAnimations(): Boolean {
return false return false
} }
}; // GridLayoutManager(context, 1).also { it.supportsPredictiveItemAnimations() } } // GridLayoutManager(context, 1).also { it.supportsPredictiveItemAnimations() }
if (context?.isTvSettings() == false) { if (context?.isTvSettings() == false) {
LinearSnapHelper().attachToRecyclerView(home_main_poster_recyclerview) // snap LinearSnapHelper().attachToRecyclerView(home_main_poster_recyclerview) // snap

View file

@ -6,10 +6,12 @@ import android.view.ViewGroup
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListUpdateCallback
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.HomePageList import com.lagradost.cloudstream3.HomePageList
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.ui.search.SearchClickCallback import com.lagradost.cloudstream3.ui.search.SearchClickCallback
import com.lagradost.cloudstream3.ui.search.SearchFragment.Companion.filterSearchResponse
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
import kotlinx.android.synthetic.main.homepage_parent.view.* import kotlinx.android.synthetic.main.homepage_parent.view.*
@ -17,11 +19,12 @@ import kotlinx.android.synthetic.main.homepage_parent.view.*
class ParentItemAdapter( class ParentItemAdapter(
private var items: MutableList<HomeViewModel.ExpandableHomepageList>, private var items: MutableList<HomeViewModel.ExpandableHomepageList>,
private val clickCallback: (SearchClickCallback) -> Unit, private val clickCallback: (SearchClickCallback) -> Unit,
private val moreInfoClickCallback: (HomePageList) -> Unit, private val moreInfoClickCallback: (HomeViewModel.ExpandableHomepageList) -> Unit,
private val expandCallback: ((String) -> Unit)? = null, private val expandCallback: ((String) -> Unit)? = null,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, i: Int): ParentViewHolder { override fun onCreateViewHolder(parent: ViewGroup, i: Int): ParentViewHolder {
//println("onCreateViewHolder $i")
val layout = val layout =
if (parent.context.isTvSettings()) R.layout.homepage_parent_tv else R.layout.homepage_parent if (parent.context.isTvSettings()) R.layout.homepage_parent_tv else R.layout.homepage_parent
return ParentViewHolder( return ParentViewHolder(
@ -33,6 +36,8 @@ class ParentItemAdapter(
} }
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
//println("onBindViewHolder $position")
when (holder) { when (holder) {
is ParentViewHolder -> { is ParentViewHolder -> {
holder.bind(items[position]) holder.bind(items[position])
@ -55,14 +60,25 @@ class ParentItemAdapter(
} }
@JvmName("updateListExpandableHomepageList") @JvmName("updateListExpandableHomepageList")
fun updateList(newList: MutableList<HomeViewModel.ExpandableHomepageList>) { fun updateList(
newList: MutableList<HomeViewModel.ExpandableHomepageList>,
recyclerView: RecyclerView? = null
) {
// this
// 1. prevents deep copy that makes this.items == newList
// 2. filters out undesirable results
// 3. moves empty results to the bottom (sortedBy is a stable sort)
val new =
newList.map { it.copy(list = it.list.copy(list = it.list.list.filterSearchResponse())) }
.sortedBy { it.list.list.isEmpty() }
val diffResult = DiffUtil.calculateDiff( val diffResult = DiffUtil.calculateDiff(
SearchDiffCallback(items, newList) SearchDiffCallback(items, new)
) )
items.clear() items.clear()
items.addAll(newList.map { it.copy(list = it.list.copy()) }) // I have to do this otherwise it is a "copy" and dispatchUpdatesTo wont work items.addAll(new)
/*val mAdapter = this val mAdapter = this
diffResult.dispatchUpdatesTo(object : ListUpdateCallback { diffResult.dispatchUpdatesTo(object : ListUpdateCallback {
override fun onInserted(position: Int, count: Int) { override fun onInserted(position: Int, count: Int) {
mAdapter.notifyItemRangeInserted(position, count) mAdapter.notifyItemRangeInserted(position, count)
@ -77,18 +93,44 @@ class ParentItemAdapter(
} }
override fun onChanged(position: Int, count: Int, payload: Any?) { override fun onChanged(position: Int, count: Int, payload: Any?) {
mAdapter.notifyItemRangeChanged(position, count, payload) // I know kinda messy, what this does is using the update or bind instead of onCreateViewHolder -> bind
} recyclerView?.apply {
})*/ // this loops every viewHolder in the recycle view and checks the position to see if it is within the update range
val missingUpdates = (position until (position + count)).toMutableSet()
for (i in 0 until mAdapter.itemCount) {
val viewHolder = getChildViewHolder(getChildAt(i))
val absolutePosition = viewHolder.absoluteAdapterPosition
if (absolutePosition >= position && absolutePosition < position + count) {
val expand = items.getOrNull(absolutePosition) ?: continue
if (viewHolder is ParentViewHolder) {
missingUpdates -= absolutePosition
if (viewHolder.title.text == expand.list.name) {
viewHolder.update(expand)
} else {
viewHolder.bind(expand)
}
}
}
}
diffResult.dispatchUpdatesTo(this) // just in case some item did not get updated
for (i in missingUpdates) {
mAdapter.notifyItemChanged(i, payload)
}
} ?: run { // in case we don't have a nice
mAdapter.notifyItemRangeChanged(position, count, payload)
}
}
})
//diffResult.dispatchUpdatesTo(this)
} }
class ParentViewHolder class ParentViewHolder
constructor( constructor(
itemView: View, itemView: View,
private val clickCallback: (SearchClickCallback) -> Unit, private val clickCallback: (SearchClickCallback) -> Unit,
private val moreInfoClickCallback: (HomePageList) -> Unit, private val moreInfoClickCallback: (HomeViewModel.ExpandableHomepageList) -> Unit,
private val expandCallback: ((String) -> Unit)? = null, private val expandCallback: ((String) -> Unit)? = null,
) : ) :
RecyclerView.ViewHolder(itemView) { RecyclerView.ViewHolder(itemView) {
@ -96,6 +138,23 @@ class ParentItemAdapter(
val recyclerView: RecyclerView = itemView.home_child_recyclerview val recyclerView: RecyclerView = itemView.home_child_recyclerview
private val moreInfo: FrameLayout? = itemView.home_child_more_info private val moreInfo: FrameLayout? = itemView.home_child_more_info
fun update(expand: HomeViewModel.ExpandableHomepageList) {
val info = expand.list
(recyclerView.adapter as? HomeChildItemAdapter?)?.apply {
updateList(info.list.toMutableList())
hasNext = expand.hasNext
} ?: run {
recyclerView.adapter = HomeChildItemAdapter(
info.list.toMutableList(),
clickCallback = clickCallback,
nextFocusUp = recyclerView.nextFocusUpId,
nextFocusDown = recyclerView.nextFocusDownId,
).apply {
isHorizontal = info.isHorizontalImages
}
}
}
fun bind(expand: HomeViewModel.ExpandableHomepageList) { fun bind(expand: HomeViewModel.ExpandableHomepageList) {
val info = expand.list val info = expand.list
recyclerView.adapter = HomeChildItemAdapter( recyclerView.adapter = HomeChildItemAdapter(
@ -105,6 +164,7 @@ class ParentItemAdapter(
nextFocusDown = recyclerView.nextFocusDownId, nextFocusDown = recyclerView.nextFocusDownId,
).apply { ).apply {
isHorizontal = info.isHorizontalImages isHorizontal = info.isHorizontalImages
hasNext = expand.hasNext
} }
title.text = info.name title.text = info.name
@ -116,8 +176,12 @@ class ParentItemAdapter(
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState) super.onScrollStateChanged(recyclerView, newState)
val count = recyclerView.adapter?.itemCount ?: return val adapter = recyclerView.adapter
if (!recyclerView.canScrollHorizontally(1) && expand.hasNext && expandCount != count) { if (adapter !is HomeChildItemAdapter) return
val count = adapter.itemCount
val hasNext = adapter.hasNext
if (!recyclerView.canScrollHorizontally(1) && hasNext && expandCount != count) {
expandCount = count expandCount = count
expandCallback?.invoke(name) expandCallback?.invoke(name)
} }
@ -127,7 +191,7 @@ class ParentItemAdapter(
//(recyclerView.adapter as HomeChildItemAdapter).notifyDataSetChanged() //(recyclerView.adapter as HomeChildItemAdapter).notifyDataSetChanged()
moreInfo?.setOnClickListener { moreInfo?.setOnClickListener {
moreInfoClickCallback.invoke(info) moreInfoClickCallback.invoke(expand)
} }
} }
} }

View file

@ -158,9 +158,8 @@ class HomeViewModel : ViewModel() {
val lock: MutableSet<String> = mutableSetOf() val lock: MutableSet<String> = mutableSetOf()
// this is soo over engineered, but idk how I can make it clean without making the main api harder to use :pensive: suspend fun expandAndReturn(name: String) : ExpandableHomepageList? {
fun expand(name: String) = viewModelScope.launch { if (lock.contains(name)) return null
if (lock.contains(name)) return@launch
lock += name lock += name
repo?.apply { repo?.apply {
@ -183,11 +182,8 @@ class HomeViewModel : ViewModel() {
"Expanded contained an item that was previously already in the list\n${list.name} = ${this.list.list}\n${newList.name} = ${newList.list}" "Expanded contained an item that was previously already in the list\n${list.name} = ${this.list.list}\n${newList.name} = ${newList.list}"
} }
val before = list.list.size
this.list.list += newList.list this.list.list += newList.list
this.list.list.distinctBy { it.url } // just to be sure we are not adding the same shit for some reason this.list.list.distinctBy { it.url } // just to be sure we are not adding the same shit for some reason
expandable[key] = this
val after = list.list.size
} ?: debugWarning { } ?: debugWarning {
"Expanded an item not in main load named $key, current list is ${expandable.keys}" "Expanded an item not in main load named $key, current list is ${expandable.keys}"
} }
@ -201,6 +197,13 @@ class HomeViewModel : ViewModel() {
} }
lock -= name lock -= name
return expandable[name]
}
// this is soo over engineered, but idk how I can make it clean without making the main api harder to use :pensive:
fun expand(name: String) = viewModelScope.launch {
expandAndReturn(name)
} }
private fun load(api: MainAPI?) = viewModelScope.launch { private fun load(api: MainAPI?) = viewModelScope.launch {

View file

@ -27,7 +27,6 @@ import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.loadHomepageLis
import com.lagradost.cloudstream3.ui.home.ParentItemAdapter import com.lagradost.cloudstream3.ui.home.ParentItemAdapter
import com.lagradost.cloudstream3.ui.search.SearchAdapter import com.lagradost.cloudstream3.ui.search.SearchAdapter
import com.lagradost.cloudstream3.ui.search.SearchClickCallback import com.lagradost.cloudstream3.ui.search.SearchClickCallback
import com.lagradost.cloudstream3.ui.search.SearchFragment.Companion.filterSearchResponse
import com.lagradost.cloudstream3.ui.search.SearchHelper import com.lagradost.cloudstream3.ui.search.SearchHelper
import com.lagradost.cloudstream3.ui.search.SearchViewModel import com.lagradost.cloudstream3.ui.search.SearchViewModel
import com.lagradost.cloudstream3.utils.UIHelper import com.lagradost.cloudstream3.utils.UIHelper
@ -173,7 +172,7 @@ class QuickSearchFragment : Fragment() {
updateList(list.map { ongoing -> updateList(list.map { ongoing ->
val ongoingList = HomePageList( val ongoingList = HomePageList(
ongoing.apiName, ongoing.apiName,
if (ongoing.data is Resource.Success) ongoing.data.value.filterSearchResponse() else ArrayList() if (ongoing.data is Resource.Success) ongoing.data.value else ArrayList()
) )
ongoingList ongoingList
}) })

View file

@ -27,6 +27,7 @@ class SearchAdapter(
private val resView: AutofitRecyclerView, private val resView: AutofitRecyclerView,
private val clickCallback: (SearchClickCallback) -> Unit, private val clickCallback: (SearchClickCallback) -> Unit,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var hasNext : Boolean = false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layout = if(parent.context.IsBottomLayout()) R.layout.search_result_grid_expanded else R.layout.search_result_grid val layout = if(parent.context.IsBottomLayout()) R.layout.search_result_grid_expanded else R.layout.search_result_grid

View file

@ -426,7 +426,7 @@ class SearchFragment : Fragment() {
val newItems = list.map { ongoing -> val newItems = list.map { ongoing ->
val ongoingList = HomePageList( val ongoingList = HomePageList(
ongoing.apiName, ongoing.apiName,
if (ongoing.data is Resource.Success) ongoing.data.value.filterSearchResponse() else ArrayList() if (ongoing.data is Resource.Success) ongoing.data.value else ArrayList()
) )
ongoingList ongoingList
} }

View file

@ -43,6 +43,7 @@ class SearchViewModel : ViewModel() {
_currentSearch.postValue(emptyList()) _currentSearch.postValue(emptyList())
} }
private var currentSearchIndex = 0
private var onGoingSearch: Job? = null private var onGoingSearch: Job? = null
fun searchAndCancel( fun searchAndCancel(
query: String, query: String,
@ -50,6 +51,7 @@ class SearchViewModel : ViewModel() {
ignoreSettings: Boolean = false, ignoreSettings: Boolean = false,
isQuickSearch: Boolean = false, isQuickSearch: Boolean = false,
) { ) {
currentSearchIndex++
onGoingSearch?.cancel() onGoingSearch?.cancel()
onGoingSearch = search(query, providersActive, ignoreSettings, isQuickSearch) onGoingSearch = search(query, providersActive, ignoreSettings, isQuickSearch)
} }
@ -70,6 +72,7 @@ class SearchViewModel : ViewModel() {
isQuickSearch: Boolean = false, isQuickSearch: Boolean = false,
) = ) =
viewModelScope.launch { viewModelScope.launch {
val currentIndex = currentSearchIndex
if (query.length <= 1) { if (query.length <= 1) {
clearSearch() clearSearch()
return@launch return@launch
@ -91,40 +94,44 @@ class SearchViewModel : ViewModel() {
_searchResponse.postValue(Resource.Loading()) _searchResponse.postValue(Resource.Loading())
val currentList = ArrayList<OnGoingSearch>()
_currentSearch.postValue(ArrayList()) _currentSearch.postValue(ArrayList())
withContext(Dispatchers.IO) { // This interrupts UI otherwise withContext(Dispatchers.IO) { // This interrupts UI otherwise
val currentList = ArrayList<OnGoingSearch>()
repos.filter { a -> repos.filter { a ->
(ignoreSettings || (providersActive.isEmpty() || providersActive.contains(a.name))) && (!isQuickSearch || a.hasQuickSearch) (ignoreSettings || (providersActive.isEmpty() || providersActive.contains(a.name))) && (!isQuickSearch || a.hasQuickSearch)
}.apmap { a -> // Parallel }.apmap { a -> // Parallel
val search = if (isQuickSearch) a.quickSearch(query) else a.search(query) val search = if (isQuickSearch) a.quickSearch(query) else a.search(query)
if(currentSearchIndex != currentIndex) return@apmap
currentList.add(OnGoingSearch(a.name, search)) currentList.add(OnGoingSearch(a.name, search))
_currentSearch.postValue(currentList) _currentSearch.postValue(currentList)
} }
}
_currentSearch.postValue(currentList)
val list = ArrayList<SearchResponse>() if(currentSearchIndex != currentIndex) return@withContext // this should prevent rewrite of existing data bug
val nestedList =
currentList.map { it.data }
.filterIsInstance<Resource.Success<List<SearchResponse>>>().map { it.value }
// I do it this way to move the relevant search results to the top _currentSearch.postValue(currentList)
var index = 0 val list = ArrayList<SearchResponse>()
while (true) { val nestedList =
var added = 0 currentList.map { it.data }
for (sublist in nestedList) { .filterIsInstance<Resource.Success<List<SearchResponse>>>().map { it.value }
if (sublist.size > index) {
list.add(sublist[index]) // I do it this way to move the relevant search results to the top
added++ var index = 0
while (true) {
var added = 0
for (sublist in nestedList) {
if (sublist.size > index) {
list.add(sublist[index])
added++
}
} }
if (added == 0) break
index++
} }
if (added == 0) break
index++
}
_searchResponse.postValue(Resource.Success(list)) _searchResponse.postValue(Resource.Success(list))
}
} }
} }

View file

@ -26,6 +26,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
import androidx.core.text.toSpanned import androidx.core.text.toSpanned
import androidx.recyclerview.widget.RecyclerView
import androidx.tvprovider.media.tv.PreviewChannelHelper import androidx.tvprovider.media.tv.PreviewChannelHelper
import androidx.tvprovider.media.tv.TvContractCompat import androidx.tvprovider.media.tv.TvContractCompat
import androidx.tvprovider.media.tv.WatchNextProgram import androidx.tvprovider.media.tv.WatchNextProgram
@ -52,6 +53,11 @@ import java.net.URL
import java.net.URLDecoder import java.net.URLDecoder
object AppUtils { object AppUtils {
fun RecyclerView.setMaxViewPoolSize(maxViewTypeId: Int, maxPoolSize: Int) {
for (i in 0..maxViewTypeId)
recycledViewPool.setMaxRecycledViews(i, maxPoolSize)
}
//fun Context.deleteFavorite(data: SearchResponse) { //fun Context.deleteFavorite(data: SearchResponse) {
// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return // if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
// normalSafeApiCall { // normalSafeApiCall {