From 2839d59a283380f5f2697d96da7845e611ea582a Mon Sep 17 00:00:00 2001 From: LagradOst Date: Thu, 12 Aug 2021 02:04:58 +0200 Subject: [PATCH] 1.2.2 --- app/build.gradle | 4 +- .../com/lagradost/cloudstream3/AllProvider.kt | 87 ------------------ .../com/lagradost/cloudstream3/MainAPI.kt | 2 - .../cloudstream3/ui/APIRepository.kt | 5 ++ .../cloudstream3/ui/home/HomeFragment.kt | 89 ++++++++++--------- .../cloudstream3/ui/search/SearchFragment.kt | 59 +++++++++--- .../cloudstream3/ui/search/SearchViewModel.kt | 66 ++++++++++---- app/src/main/res/drawable/search_icon.xml | 4 +- app/src/main/res/layout/fragment_search.xml | 10 ++- app/src/main/res/values/colors.xml | 4 +- app/src/main/res/xml/settings.xml | 13 +++ 11 files changed, 174 insertions(+), 169 deletions(-) delete mode 100644 app/src/main/java/com/lagradost/cloudstream3/AllProvider.kt diff --git a/app/build.gradle b/app/build.gradle index 6e15de92..cf761fd4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,8 @@ android { applicationId "com.lagradost.cloudstream3" minSdkVersion 21 targetSdkVersion 30 - versionCode 12 - versionName "1.2.1" + versionCode 13 + versionName "1.2.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/com/lagradost/cloudstream3/AllProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/AllProvider.kt deleted file mode 100644 index 69904319..00000000 --- a/app/src/main/java/com/lagradost/cloudstream3/AllProvider.kt +++ /dev/null @@ -1,87 +0,0 @@ -package com.lagradost.cloudstream3 - -import com.lagradost.cloudstream3.APIHolder.apis -import com.lagradost.cloudstream3.mvvm.normalSafeApiCall -import com.lagradost.cloudstream3.mvvm.safeApiCall - -class AllProvider : MainAPI() { - override val name: String - get() = "All Sources" - - var providersActive = HashSet() - - override fun quickSearch(query: String): ArrayList? { - val list = apis.filter { a -> - a.name != this.name && (providersActive.size == 0 || providersActive.contains(a.name)) - }.filter { a -> a.hasQuickSearch }.pmap { a -> - normalSafeApiCall { - a.quickSearch(query) - } - } - - var maxCount = 0 - var providerCount = 0 - for (res in list) { - if (res != null) { - if (res.size > maxCount) { - maxCount = res.size - } - providerCount++ - } - } - - println("PROV: " + providerCount + "|" + maxCount) - if (providerCount == 0) return null - if (maxCount == 0) return ArrayList() - - val result = ArrayList() - for (i in 0..maxCount) { - for (res in list) { - if (res != null) { - if (i < res.size) { - result.add(res[i]) - } - } - } - } - - return result - } - - override fun search(query: String): ArrayList? { - val list = apis.filter { a -> - a.name != this.name && (providersActive.size == 0 || providersActive.contains(a.name)) - }.pmap { a -> - normalSafeApiCall { - a.search(query) - } - } - - var maxCount = 0 - var providerCount = 0 - for (res in list) { - if (res != null) { - if (res.size > maxCount) { - maxCount = res.size - } - providerCount++ - } - } - - if (providerCount == 0) return null - if (maxCount == 0) return ArrayList() - - val result = ArrayList() - for (i in 0..maxCount) { - for (res in list) { - if (res != null) { - if (i < res.size) { - result.add(res[i]) - } - } - } - } - - return result - } -} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index caade0c5..e384fa9d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -25,8 +25,6 @@ object APIHolder { val unixTime: Long get() = System.currentTimeMillis() / 1000L - val allApi = AllProvider() - private const val defProvider = 0 val apis = arrayListOf( diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/APIRepository.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/APIRepository.kt index 533262df..27edc0fc 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/APIRepository.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/APIRepository.kt @@ -7,8 +7,13 @@ import com.lagradost.cloudstream3.mvvm.safeApiCall import com.lagradost.cloudstream3.utils.ExtractorLink class APIRepository(val api: MainAPI) { + companion object { + var providersActive = HashSet() + } + val name: String get() = api.name val mainUrl: String get() = api.mainUrl + val hasQuickSearch: Boolean get() = api.hasQuickSearch suspend fun load(url: String): Resource { return safeApiCall { 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 2670aa51..5f5e8b05 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 @@ -1,6 +1,8 @@ package com.lagradost.cloudstream3.ui.home import android.annotation.SuppressLint +import android.app.Activity +import android.content.Context import android.content.Intent import android.content.res.Configuration import android.net.Uri @@ -45,6 +47,50 @@ import kotlinx.android.synthetic.main.fragment_home.* const val HOME_BOOKMARK_VALUE = "home_bookmarked_last" class HomeFragment : Fragment() { + companion object { + val configEvent = Event() + var currentSpan = 1 + + fun Activity.loadHomepageList(item: HomePageList) { + val context = this + val bottomSheetDialogBuilder = BottomSheetDialog(context) + bottomSheetDialogBuilder.setContentView(R.layout.home_episodes_expanded) + val title = bottomSheetDialogBuilder.findViewById(R.id.home_expanded_text)!! + title.text = item.name + val recycle = bottomSheetDialogBuilder.findViewById(R.id.home_expanded_recycler)!! + val titleHolder = bottomSheetDialogBuilder.findViewById(R.id.home_expanded_drag_down)!! + + titleHolder.setOnClickListener { + bottomSheetDialogBuilder.dismiss() + } + + // Span settings + recycle.spanCount = currentSpan + + recycle.adapter = SearchAdapter(item.list, recycle) { callback -> + handleSearchClickCallback(this, callback) + if (callback.action == SEARCH_ACTION_LOAD) { + bottomSheetDialogBuilder.dismiss() + } + } + + val spanListener = { span: Int -> + recycle.spanCount = span + (recycle.adapter as SearchAdapter).notifyDataSetChanged() + } + + configEvent += spanListener + + bottomSheetDialogBuilder.setOnDismissListener { + configEvent -= spanListener + } + + (recycle.adapter as SearchAdapter).notifyDataSetChanged() + + bottomSheetDialogBuilder.show() + } + } + private lateinit var homeViewModel: HomeViewModel override fun onCreateView( @@ -58,8 +104,6 @@ class HomeFragment : Fragment() { return inflater.inflate(R.layout.fragment_home, container, false) } - private val configEvent = Event() - private var currentSpan = 1 private var currentHomePage: HomePageResponse? = null var currentMainIndex = 0 var currentMainList: ArrayList = ArrayList() @@ -254,48 +298,11 @@ class HomeFragment : Fragment() { } } - fun loadHomepageList(item: HomePageList) { - val bottomSheetDialogBuilder = BottomSheetDialog(view.context) - bottomSheetDialogBuilder.setContentView(R.layout.home_episodes_expanded) - val title = bottomSheetDialogBuilder.findViewById(R.id.home_expanded_text)!! - title.text = item.name - val recycle = bottomSheetDialogBuilder.findViewById(R.id.home_expanded_recycler)!! - val titleHolder = bottomSheetDialogBuilder.findViewById(R.id.home_expanded_drag_down)!! - - titleHolder.setOnClickListener { - bottomSheetDialogBuilder.dismiss() - } - - // Span settings - recycle.spanCount = currentSpan - - recycle.adapter = SearchAdapter(item.list, recycle) { callback -> - handleSearchClickCallback(activity, callback) - if (callback.action == SEARCH_ACTION_LOAD) { - bottomSheetDialogBuilder.dismiss() - } - } - - val spanListener = { span: Int -> - recycle.spanCount = span - (recycle.adapter as SearchAdapter).notifyDataSetChanged() - } - - configEvent += spanListener - - bottomSheetDialogBuilder.setOnDismissListener { - configEvent -= spanListener - } - - (recycle.adapter as SearchAdapter).notifyDataSetChanged() - - bottomSheetDialogBuilder.show() - } val adapter: RecyclerView.Adapter = ParentItemAdapter(listOf(), { callback -> handleSearchClickCallback(activity, callback) }, { item -> - loadHomepageList(item) + activity?.loadHomepageList(item) }) observe(homeViewModel.availableWatchStatusTypes) { availableWatchStatusTypes -> @@ -319,7 +326,7 @@ class HomeFragment : Fragment() { home_bookmarked_child_recyclerview?.adapter?.notifyDataSetChanged() home_bookmarked_child_more_info.setOnClickListener { - loadHomepageList( + activity?.loadHomepageList( HomePageList( home_bookmarked_parent_item_title?.text?.toString() ?: getString(R.string.error_bookmarks_text), bookmarks 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 8eb9a02b..0ede9a1c 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 @@ -14,16 +14,20 @@ import androidx.appcompat.widget.SearchView import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import androidx.preference.PreferenceManager +import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.lagradost.cloudstream3.APIHolder.allApi import com.lagradost.cloudstream3.APIHolder.apis import com.lagradost.cloudstream3.APIHolder.getApiSettings +import com.lagradost.cloudstream3.HomePageList import com.lagradost.cloudstream3.R -import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar -import com.lagradost.cloudstream3.utils.UIHelper.getGridIsCompact import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.mvvm.observe -import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment +import com.lagradost.cloudstream3.ui.APIRepository.Companion.providersActive +import com.lagradost.cloudstream3.ui.home.HomeFragment +import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.loadHomepageList +import com.lagradost.cloudstream3.ui.home.ParentItemAdapter +import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar +import com.lagradost.cloudstream3.utils.UIHelper.getGridIsCompact import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard import kotlinx.android.synthetic.main.fragment_search.* @@ -49,11 +53,14 @@ class SearchFragment : Fragment() { val spanCountPortrait = if (compactView) 1 else 3 val orientation = resources.configuration.orientation - if (orientation == Configuration.ORIENTATION_LANDSCAPE) { - cardSpace.spanCount = spanCountLandscape + val currentSpan = if (orientation == Configuration.ORIENTATION_LANDSCAPE) { + spanCountLandscape } else { - cardSpace.spanCount = spanCountPortrait + spanCountPortrait } + cardSpace.spanCount = currentSpan + HomeFragment.currentSpan = currentSpan + HomeFragment.configEvent.invoke(currentSpan) } override fun onConfigurationChanged(newConfig: Configuration) { @@ -113,7 +120,7 @@ class SearchFragment : Fragment() { apiNames.filter { a -> apiNamesSettingLocal.contains(a) }.toSet() ) edit.apply() - allApi.providersActive = apiNamesSettingLocal + providersActive = apiNamesSettingLocal } } builder.setTitle("Search Providers") @@ -138,9 +145,11 @@ class SearchFragment : Fragment() { when (it) { is Resource.Success -> { it.value.let { data -> - if (data != null) { - (cardSpace?.adapter as SearchAdapter?)?.cardList = data.filterNotNull() - cardSpace?.adapter?.notifyDataSetChanged() + if (data.isNotEmpty()) { + (cardSpace?.adapter as SearchAdapter?)?.apply { + cardList = data.toList() + notifyDataSetChanged() + } } } searchExitIcon.alpha = 1f @@ -157,8 +166,18 @@ class SearchFragment : Fragment() { } } } + + observe(searchViewModel.currentSearch) { list -> + (search_master_recycler?.adapter as ParentItemAdapter?)?.apply { + items = list.map { + HomePageList(it.apiName, if (it.data is Resource.Success) it.data.value else ArrayList()) + } + notifyDataSetChanged() + } + } + activity?.let { - allApi.providersActive = it.getApiSettings() + providersActive = it.getApiSettings() } main_search.setOnQueryTextFocusChangeListener { searchView, b -> @@ -173,6 +192,22 @@ class SearchFragment : Fragment() { } } main_search.onActionViewExpanded() + + val masterAdapter: RecyclerView.Adapter = ParentItemAdapter(listOf(), { callback -> + SearchHelper.handleSearchClickCallback(activity, callback) + }, { item -> + activity?.loadHomepageList(item) + }) + + search_master_recycler.adapter = masterAdapter + search_master_recycler.layoutManager = GridLayoutManager(context, 1) + + val settingsManager = PreferenceManager.getDefaultSharedPreferences(context) + val isAdvancedSearch = settingsManager.getBoolean("advanced_search", true) + + search_master_recycler.visibility = if(isAdvancedSearch) View.VISIBLE else View.GONE + cardSpace.visibility = if(!isAdvancedSearch) View.VISIBLE else View.GONE + // SubtitlesFragment.push(activity) //searchViewModel.search("iron man") //(activity as AppCompatActivity).loadResult("https://shiro.is/overlord-dubbed", "overlord-dubbed", "Shiro") diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchViewModel.kt index c007621b..ecce9e3f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchViewModel.kt @@ -4,18 +4,27 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.lagradost.cloudstream3.APIHolder.allApi +import com.lagradost.cloudstream3.APIHolder.apis import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.mvvm.Resource -import com.lagradost.cloudstream3.mvvm.safeApiCall import com.lagradost.cloudstream3.ui.APIRepository +import com.lagradost.cloudstream3.ui.APIRepository.Companion.providersActive import kotlinx.coroutines.launch +data class OnGoingSearch( + val apiName: String, + val data: Resource> +) + class SearchViewModel : ViewModel() { private val _searchResponse: MutableLiveData>> = MutableLiveData() val searchResponse: LiveData>> get() = _searchResponse + + private val _currentSearch: MutableLiveData> = MutableLiveData() + val currentSearch: LiveData> get() = _currentSearch + var searchCounter = 0 - private val repo = APIRepository(allApi) + private val repos = apis.map { APIRepository(it) } private fun clearSearch() { _searchResponse.postValue(Resource.Success(ArrayList())) @@ -23,29 +32,50 @@ class SearchViewModel : ViewModel() { fun search(query: String) = viewModelScope.launch { searchCounter++ - if(query.length <= 1) { + if (query.length <= 1) { clearSearch() return@launch } val localSearchCounter = searchCounter _searchResponse.postValue(Resource.Loading()) - val data = repo.search(query) - if(localSearchCounter != searchCounter) return@launch - _searchResponse.postValue(data) + val currentList = ArrayList() + + _currentSearch.postValue(ArrayList()) + + repos.filter { a -> + (providersActive.size == 0 || providersActive.contains(a.name)) + }.map { a -> + currentList.add(OnGoingSearch(a.name, a.search(query))) + if (localSearchCounter == searchCounter) { + _currentSearch.postValue(currentList) + } + } + _currentSearch.postValue(currentList) + + if (localSearchCounter != searchCounter) return@launch + + val list = ArrayList() + val nestedList = currentList.map { it.data }.filterIsInstance>>().map { it.value } + + // I do it this way to move the relevant search results to the top + 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++ + } + + _searchResponse.postValue(Resource.Success(list)) } fun quickSearch(query: String) = viewModelScope.launch { - searchCounter++ - if(query.length <= 1) { - clearSearch() - return@launch - } - val localSearchCounter = searchCounter - _searchResponse.postValue(Resource.Loading()) - val data = repo.quickSearch(query) - - if(localSearchCounter != searchCounter) return@launch - _searchResponse.postValue(data) + return@launch } } \ No newline at end of file diff --git a/app/src/main/res/drawable/search_icon.xml b/app/src/main/res/drawable/search_icon.xml index 870d0db6..18e5e6f8 100644 --- a/app/src/main/res/drawable/search_icon.xml +++ b/app/src/main/res/drawable/search_icon.xml @@ -1,8 +1,8 @@ - - + /> + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 83f617ff..66e4fb7b 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -23,9 +23,9 @@ #FFF #3d50fa - #4D3B65F5 + #803B65F5 #F54A3B - #4DF53B66 + #80F53B66 #F54A3B #4DF54A3B diff --git a/app/src/main/res/xml/settings.xml b/app/src/main/res/xml/settings.xml index 58d49656..d4273244 100644 --- a/app/src/main/res/xml/settings.xml +++ b/app/src/main/res/xml/settings.xml @@ -58,6 +58,19 @@ /> + + +