Skip to content
Draft
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 @@ -4,6 +4,7 @@ import com.lagradost.cloudstream3.APIHolder.unixTime
import com.lagradost.cloudstream3.APIHolder.unixTimeMS
import com.lagradost.cloudstream3.DubStatus
import com.lagradost.cloudstream3.ErrorLoadingException
import com.lagradost.cloudstream3.Genres
import com.lagradost.cloudstream3.HomePageResponse
import com.lagradost.cloudstream3.LoadResponse
import com.lagradost.cloudstream3.MainAPI
Expand Down Expand Up @@ -142,6 +143,14 @@ class APIRepository(val api: MainAPI) {
}
}

suspend fun discover(types: List<TvType?>, genres: List<Genres?>): Resource<List<SearchResponse>> {
return safeApiCall {
withTimeout(getTimeout(api.searchTimeoutMs)) {
api.discover(types, genres) ?: throw ErrorLoadingException()
}
}
}

suspend fun waitForHomeDelay() {
val delta = api.sequentialMainPageScrollDelay + api.lastHomepageRequest - unixTimeMS
if (delta < 0) return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ class HomeViewModel : ViewModel() {
}
}


fun loadStoredData(preferredWatchStatus: Set<WatchType>?) = viewModelScope.launchSafe {
val watchStatusIds = withContext(Dispatchers.IO) {
getAllWatchStateIds()?.map { id ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,23 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.removeKeys
import com.lagradost.cloudstream3.AllLanguagesName
import com.lagradost.cloudstream3.AnimeSearchResponse
import com.lagradost.cloudstream3.CommonActivity.showToast
import com.lagradost.cloudstream3.ErrorLoadingException
import com.lagradost.cloudstream3.HomePageList
import com.lagradost.cloudstream3.MainAPI
import com.lagradost.cloudstream3.MainActivity
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.actions.VideoClickActionHolder
import com.lagradost.cloudstream3.databinding.FragmentSearchBinding
import com.lagradost.cloudstream3.databinding.HomeSelectMainpageBinding
import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.mvvm.safeApiCall
import com.lagradost.cloudstream3.ui.APIRepository
import com.lagradost.cloudstream3.ui.APIRepository.Companion.getTimeout
import com.lagradost.cloudstream3.ui.BaseAdapter
import com.lagradost.cloudstream3.ui.home.HomeFragment
import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.bindChips
Expand All @@ -70,11 +74,14 @@ import com.lagradost.cloudstream3.utils.AppContextUtils.setDefaultFocus
import com.lagradost.cloudstream3.utils.Coroutines.main
import com.lagradost.cloudstream3.utils.DataStoreHelper
import com.lagradost.cloudstream3.utils.DataStoreHelper.currentAccount
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showMultiDialog
import com.lagradost.cloudstream3.utils.SubtitleHelper
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.utils.UIHelper.getSpanCount
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
import kotlinx.coroutines.withTimeout
import java.util.Locale
import java.util.concurrent.locks.ReentrantLock

Expand Down Expand Up @@ -273,6 +280,30 @@ class SearchFragment : Fragment() {
}
}

binding?.searchGenreFilter?.setOnClickListener {
val name = DataStoreHelper.currentHomePage
val provider = getApiFromNameNull(name)
val availableGenres = provider?.supportedGenres
val prefNames = availableGenres?.map {
it.name
} ?: return@setOnClickListener
activity?.showMultiDialog(
prefNames,
listOf(),
"Genres",
{},
{ enabledIndices ->
val listOfSelectedGenres = if (enabledIndices.isEmpty()) {
availableGenres
} else {
availableGenres.filterIndexed { index, _ -> index in enabledIndices }
}
searchViewModel.discoverAndCancel(provider.supportedTypes.toList(), listOfSelectedGenres.toList(), provider)
}
)
}


val searchExitIcon =
binding?.mainSearch?.findViewById<ImageView>(androidx.appcompat.R.id.search_close_btn)
// val searchMagIcon =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.lagradost.cloudstream3.APIHolder.apis
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.getKeys
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.Genres
import com.lagradost.cloudstream3.MainAPI
import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.amap
import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.launchSafe
Expand Down Expand Up @@ -63,6 +67,15 @@ class SearchViewModel : ViewModel() {
onGoingSearch = search(query, providersActive, ignoreSettings, isQuickSearch)
}

fun discoverAndCancel(
types: List<TvType?>,
genres: List<Genres?>,
provider: MainAPI,
) {
onGoingSearch?.cancel()
onGoingSearch = discover(types, genres, provider)
}

fun updateHistory() = viewModelScope.launch {
ioSafe {
val items = getKeys("$currentAccount/$SEARCH_HISTORY_KEY")?.mapNotNull {
Expand All @@ -72,6 +85,8 @@ class SearchViewModel : ViewModel() {
}
}



private fun search(
query: String,
providersActive: Set<String>,
Expand Down Expand Up @@ -141,4 +156,49 @@ class SearchViewModel : ViewModel() {
_searchResponse.postValue(Resource.Success(list))
}
}


private fun discover(
types: List<TvType?>,
genres: List<Genres?>,
provider: MainAPI,
) =
viewModelScope.launchSafe {

_searchResponse.postValue(Resource.Loading())
val currentIndex = currentSearchIndex

_currentSearch.postValue(ArrayList())

withContext(Dispatchers.IO) { // This interrupts UI otherwise
val currentList = ArrayList<OnGoingSearch>()
val a = APIRepository(provider)
val discover = a?.discover(types, genres) ?: return@withContext

currentList.add(OnGoingSearch(provider.name, discover))
if (currentSearchIndex != currentIndex) return@withContext // this should prevent rewrite of existing data bug TODO useless ??

_currentSearch.postValue(currentList)
val list = ArrayList<SearchResponse>()
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 TODO remove ??
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))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.preference.PreferenceManager
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.actions.VideoClickActionHolder
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.ui.home.HomeViewModel
import com.lagradost.cloudstream3.ui.settings.Globals.EMULATOR
import com.lagradost.cloudstream3.ui.settings.Globals.PHONE
import com.lagradost.cloudstream3.ui.settings.Globals.TV
Expand Down Expand Up @@ -176,6 +177,7 @@ class SettingsPlayer : PreferenceFragmentCompat() {
}

getPref(R.string.player_default_key)?.setOnPreferenceClickListener {
//val api = HomeViewModel
val players = VideoClickActionHolder.getPlayers(activity)
val prefNames = buildList {
add(getString(R.string.player_settings_play_in_app))
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/res/layout/fragment_search.xml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@
<include
android:id="@+id/tvtypes_chips_scroll"
layout="@layout/tvtypes_chips_scroll" />
<com.google.android.material.button.MaterialButton
android:id="@+id/search_genre_filter"
style="@style/SelectableButton"
android:layout_width="match_parent"
android:layout_gravity="center"
android:text="Genres"
app:icon="@drawable/ic_baseline_keyboard_arrow_down_24" />

</LinearLayout>


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ abstract class MainAPI {

open val hasMainPage = false
open val hasQuickSearch = false
open val hasDiscover = false

/**
* The timeout on the `loadLinks` functions in milliseconds,
Expand Down Expand Up @@ -545,6 +546,12 @@ abstract class MainAPI {
TvType.OVA,
)

open val supportedGenres = setOf(
Genres.Action,
Genres.Horror,
Genres.Romance
)

open val vpnStatus = VPNStatus.None
open val providerType = ProviderType.DirectProvider

Expand All @@ -564,6 +571,10 @@ abstract class MainAPI {
throw NotImplementedError()
}

open suspend fun discover(types: List<TvType?>, genres: List<Genres?>): List<SearchResponse>? {
throw NotImplementedError()
}

// @WorkerThread
open suspend fun quickSearch(query: String): List<SearchResponse>? {
throw NotImplementedError()
Expand Down Expand Up @@ -969,6 +980,14 @@ class Score private constructor(
}
}

@Suppress("UNUSED_PARAMETER")
enum class Genres(value: Int?) {
Action(1),
Romance(2),
Horror(3)
}


@Suppress("UNUSED_PARAMETER")
enum class TvType(value: Int?) {
Movie(1),
Expand Down