phone UI changes + cache

This commit is contained in:
reduplicated 2022-10-28 03:51:27 +02:00
parent ecd363992c
commit 997420a942
16 changed files with 905 additions and 1105 deletions

View file

@ -26,6 +26,8 @@ class APIRepository(val api: MainAPI) {
fun isInvalidData(data: String): Boolean { fun isInvalidData(data: String): Boolean {
return data.isEmpty() || data == "[]" || data == "about:blank" return data.isEmpty() || data == "[]" || data == "about:blank"
} }
private val cacheHash: HashMap<Pair<String,String>, LoadResponse> = hashMapOf()
} }
val hasMainPage = api.hasMainPage val hasMainPage = api.hasMainPage
@ -39,7 +41,13 @@ class APIRepository(val api: MainAPI) {
suspend fun load(url: String): Resource<LoadResponse> { suspend fun load(url: String): Resource<LoadResponse> {
return safeApiCall { return safeApiCall {
if (isInvalidData(url)) throw ErrorLoadingException() if (isInvalidData(url)) throw ErrorLoadingException()
api.load(api.fixUrl(url)) ?: throw ErrorLoadingException() val fixedUrl = api.fixUrl(url)
val key = Pair(api.name,url)
cacheHash[key] ?: api.load(fixedUrl)?.also {
// we cache 20 responses because ppl often go back to the same shit + 20 because I dont want to cause too much memory leak
if (cacheHash.size > 20) cacheHash.remove(cacheHash.keys.random())
cacheHash[key] = it
} ?: throw ErrorLoadingException()
} }
} }
@ -75,7 +83,12 @@ class APIRepository(val api: MainAPI) {
api.lastHomepageRequest = unixTimeMS api.lastHomepageRequest = unixTimeMS
nameIndex?.let { api.mainPage.getOrNull(it) }?.let { data -> nameIndex?.let { api.mainPage.getOrNull(it) }?.let { data ->
listOf(api.getMainPage(page, MainPageRequest(data.name, data.data, data.horizontalImages))) listOf(
api.getMainPage(
page,
MainPageRequest(data.name, data.data, data.horizontalImages)
)
)
} ?: run { } ?: run {
if (api.sequentialMainPage) { if (api.sequentialMainPage) {
var first = true var first = true

View file

@ -5,13 +5,12 @@ import androidx.annotation.StringRes
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
enum class WatchType(val internalId: Int, @StringRes val stringRes: Int, @DrawableRes val iconRes: Int) { enum class WatchType(val internalId: Int, @StringRes val stringRes: Int, @DrawableRes val iconRes: Int) {
// FIX ICONS WATCHING(0, R.string.type_watching, R.drawable.ic_baseline_bookmark_24),
WATCHING(0, R.string.type_watching, R.drawable.ic_baseline_remove_red_eye_24), COMPLETED(1, R.string.type_completed, R.drawable.ic_baseline_bookmark_24),
COMPLETED(1, R.string.type_completed, R.drawable.ic_baseline_check_24), ONHOLD(2, R.string.type_on_hold, R.drawable.ic_baseline_bookmark_24),
ONHOLD(2, R.string.type_on_hold, R.drawable.ic_baseline_pause_24), DROPPED(3, R.string.type_dropped, R.drawable.ic_baseline_bookmark_24),
DROPPED(3, R.string.type_dropped, R.drawable.ic_baseline_close_24), PLANTOWATCH(4, R.string.type_plan_to_watch, R.drawable.ic_baseline_bookmark_24),
PLANTOWATCH(4, R.string.type_plan_to_watch, R.drawable.ic_baseline_close_24), NONE(5, R.string.type_none, R.drawable.ic_baseline_add_24);
NONE(5, R.string.type_none, R.drawable.ic_baseline_remove_red_eye_24);
companion object { companion object {
fun fromInternalId(id: Int?) = values().find { value -> value.internalId == id } ?: NONE fun fromInternalId(id: Int?) = values().find { value -> value.internalId == id } ?: NONE

View file

@ -14,6 +14,8 @@ import android.view.ViewGroup
import android.widget.* import android.widget.*
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.getDrawable
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.widget.NestedScrollView import androidx.core.widget.NestedScrollView
@ -26,11 +28,14 @@ import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
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.google.android.material.chip.Chip
import com.google.android.material.chip.ChipGroup
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.APIHolder.apis import com.lagradost.cloudstream3.APIHolder.apis
import com.lagradost.cloudstream3.APIHolder.filterProviderByPreferredMedia import com.lagradost.cloudstream3.APIHolder.filterProviderByPreferredMedia
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings
import com.lagradost.cloudstream3.APIHolder.getId
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent
import com.lagradost.cloudstream3.MainActivity.Companion.mainPluginsLoadedEvent import com.lagradost.cloudstream3.MainActivity.Companion.mainPluginsLoadedEvent
@ -43,6 +48,7 @@ import com.lagradost.cloudstream3.ui.APIRepository.Companion.randomApi
import com.lagradost.cloudstream3.ui.AutofitRecyclerView import com.lagradost.cloudstream3.ui.AutofitRecyclerView
import com.lagradost.cloudstream3.ui.WatchType import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment
import com.lagradost.cloudstream3.ui.result.ResultViewModel2.Companion.updateWatchStatus
import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST
import com.lagradost.cloudstream3.ui.result.setLinearListLayout import com.lagradost.cloudstream3.ui.result.setLinearListLayout
import com.lagradost.cloudstream3.ui.search.* import com.lagradost.cloudstream3.ui.search.*
@ -50,6 +56,7 @@ 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.isRecyclerScrollable import com.lagradost.cloudstream3.utils.AppUtils.isRecyclerScrollable
import com.lagradost.cloudstream3.utils.AppUtils.loadResult
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.AppUtils.setMaxViewPoolSize
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
@ -61,11 +68,11 @@ import com.lagradost.cloudstream3.utils.DataStoreHelper.deleteAllResumeStateIds
import com.lagradost.cloudstream3.utils.DataStoreHelper.removeLastWatched import com.lagradost.cloudstream3.utils.DataStoreHelper.removeLastWatched
import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultWatchState import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultWatchState
import com.lagradost.cloudstream3.utils.Event import com.lagradost.cloudstream3.utils.Event
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showOptionSelectStringRes import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showOptionSelectStringRes
import com.lagradost.cloudstream3.utils.SubtitleHelper.getFlagFromIso import com.lagradost.cloudstream3.utils.SubtitleHelper.getFlagFromIso
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbarView
import com.lagradost.cloudstream3.utils.UIHelper.getSpanCount import com.lagradost.cloudstream3.utils.UIHelper.getSpanCount
import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes
import com.lagradost.cloudstream3.utils.UIHelper.setImage import com.lagradost.cloudstream3.utils.UIHelper.setImage
@ -82,14 +89,12 @@ import kotlinx.android.synthetic.main.fragment_home.home_loading
import kotlinx.android.synthetic.main.fragment_home.home_loading_error import kotlinx.android.synthetic.main.fragment_home.home_loading_error
import kotlinx.android.synthetic.main.fragment_home.home_loading_shimmer import kotlinx.android.synthetic.main.fragment_home.home_loading_shimmer
import kotlinx.android.synthetic.main.fragment_home.home_loading_statusbar import kotlinx.android.synthetic.main.fragment_home.home_loading_statusbar
import kotlinx.android.synthetic.main.fragment_home.home_main_poster_recyclerview
import kotlinx.android.synthetic.main.fragment_home.home_master_recycler import kotlinx.android.synthetic.main.fragment_home.home_master_recycler
import kotlinx.android.synthetic.main.fragment_home.home_plan_to_watch_btt import kotlinx.android.synthetic.main.fragment_home.home_plan_to_watch_btt
import kotlinx.android.synthetic.main.fragment_home.home_provider_meta_info import kotlinx.android.synthetic.main.fragment_home.home_provider_meta_info
import kotlinx.android.synthetic.main.fragment_home.home_provider_name import kotlinx.android.synthetic.main.fragment_home.home_provider_name
import kotlinx.android.synthetic.main.fragment_home.home_reload_connection_open_in_browser import kotlinx.android.synthetic.main.fragment_home.home_reload_connection_open_in_browser
import kotlinx.android.synthetic.main.fragment_home.home_reload_connectionerror import kotlinx.android.synthetic.main.fragment_home.home_reload_connectionerror
import kotlinx.android.synthetic.main.fragment_home.home_statusbar
import kotlinx.android.synthetic.main.fragment_home.home_type_completed_btt import kotlinx.android.synthetic.main.fragment_home.home_type_completed_btt
import kotlinx.android.synthetic.main.fragment_home.home_type_dropped_btt import kotlinx.android.synthetic.main.fragment_home.home_type_dropped_btt
import kotlinx.android.synthetic.main.fragment_home.home_type_on_hold_btt import kotlinx.android.synthetic.main.fragment_home.home_type_on_hold_btt
@ -100,6 +105,8 @@ import kotlinx.android.synthetic.main.fragment_home.home_watch_parent_item_title
import kotlinx.android.synthetic.main.fragment_home.result_error_text import kotlinx.android.synthetic.main.fragment_home.result_error_text
import kotlinx.android.synthetic.main.fragment_home_tv.* import kotlinx.android.synthetic.main.fragment_home_tv.*
import kotlinx.android.synthetic.main.home_episodes_expanded.* import kotlinx.android.synthetic.main.home_episodes_expanded.*
import kotlinx.android.synthetic.main.tvtypes_chips.*
import kotlinx.android.synthetic.main.tvtypes_chips.view.*
import java.util.* import java.util.*
const val HOME_BOOKMARK_VALUE_LIST = "home_bookmarked_last_list" const val HOME_BOOKMARK_VALUE_LIST = "home_bookmarked_last_list"
@ -247,16 +254,16 @@ class HomeFragment : Fragment() {
} }
fun getPairList( fun getPairList(
anime: MaterialButton?, anime: Chip?,
cartoons: MaterialButton?, cartoons: Chip?,
tvs: MaterialButton?, tvs: Chip?,
docs: MaterialButton?, docs: Chip?,
movies: MaterialButton?, movies: Chip?,
asian: MaterialButton?, asian: Chip?,
livestream: MaterialButton?, livestream: Chip?,
nsfw: MaterialButton?, nsfw: Chip?,
others: MaterialButton?, others: Chip?,
): List<Pair<MaterialButton?, List<TvType>>> { ): List<Pair<Chip?, List<TvType>>> {
// This list should be same order as home screen to aid navigation // This list should be same order as home screen to aid navigation
return listOf( return listOf(
Pair(movies, listOf(TvType.Movie, TvType.Torrent)), Pair(movies, listOf(TvType.Movie, TvType.Torrent)),
@ -271,6 +278,59 @@ class HomeFragment : Fragment() {
) )
} }
private fun getPairList(header: ChipGroup) = getPairList(
header.home_select_anime,
header.home_select_cartoons,
header.home_select_tv_series,
header.home_select_documentaries,
header.home_select_movies,
header.home_select_asian,
header.home_select_livestreams,
header.home_select_nsfw,
header.home_select_others
)
fun validateChips(header: ChipGroup?, validTypes: List<TvType>) {
if (header == null) return
val pairList = getPairList(header)
for ((button, types) in pairList) {
val isValid = validTypes.any { types.contains(it) }
button?.isVisible = isValid
}
}
fun updateChips(header: ChipGroup?, selectedTypes: List<TvType>) {
if (header == null) return
val pairList = getPairList(header)
for ((button, types) in pairList) {
button?.isChecked =
button?.isVisible == true && selectedTypes.any { types.contains(it) }
}
}
fun bindChips(
header: ChipGroup?,
selectedTypes: List<TvType>,
validTypes: List<TvType>,
callback: (List<TvType>) -> Unit
) {
if (header == null) return
val pairList = getPairList(header)
for ((button, types) in pairList) {
val isValid = validTypes.any { types.contains(it) }
button?.isVisible = isValid
button?.isChecked = isValid && selectedTypes.any { types.contains(it) }
button?.setOnCheckedChangeListener { _, _ ->
val list = ArrayList<TvType>()
for ((sbutton, vvalidTypes) in pairList) {
if (sbutton?.isChecked == true)
list.addAll(vvalidTypes)
}
callback(list)
}
}
}
fun Context.selectHomepage(selectedApiName: String?, callback: (String) -> Unit) { fun Context.selectHomepage(selectedApiName: String?, callback: (String) -> Unit) {
val validAPIs = filterProviderByPreferredMedia().toMutableList() val validAPIs = filterProviderByPreferredMedia().toMutableList()
@ -296,21 +356,9 @@ class HomeFragment : Fragment() {
?.toMutableList() ?.toMutableList()
?: mutableListOf(TvType.Movie, TvType.TvSeries) ?: mutableListOf(TvType.Movie, TvType.TvSeries)
val anime = dialog.findViewById<MaterialButton>(R.id.home_select_anime)
val cartoons = dialog.findViewById<MaterialButton>(R.id.home_select_cartoons)
val tvs = dialog.findViewById<MaterialButton>(R.id.home_select_tv_series)
val docs = dialog.findViewById<MaterialButton>(R.id.home_select_documentaries)
val movies = dialog.findViewById<MaterialButton>(R.id.home_select_movies)
val asian = dialog.findViewById<MaterialButton>(R.id.home_select_asian)
val livestream = dialog.findViewById<MaterialButton>(R.id.home_select_livestreams)
val nsfw = dialog.findViewById<MaterialButton>(R.id.home_select_nsfw)
val others = dialog.findViewById<MaterialButton>(R.id.home_select_others)
val cancelBtt = dialog.findViewById<MaterialButton>(R.id.cancel_btt) val cancelBtt = dialog.findViewById<MaterialButton>(R.id.cancel_btt)
val applyBtt = dialog.findViewById<MaterialButton>(R.id.apply_btt) val applyBtt = dialog.findViewById<MaterialButton>(R.id.apply_btt)
val pairList =
getPairList(anime, cartoons, tvs, docs, movies, asian, livestream, nsfw, others)
cancelBtt?.setOnClickListener { cancelBtt?.setOnClickListener {
dialog.dismissSafe() dialog.dismissSafe()
} }
@ -355,52 +403,14 @@ class HomeFragment : Fragment() {
arrayAdapter.notifyDataSetChanged() arrayAdapter.notifyDataSetChanged()
} }
/** bindChips(
* Since fire tv is fucked we need to manually define the focus layout. dialog.home_select_group,
* Since visible buttons are only known in runtime this is required. preSelectedTypes,
**/ validAPIs.flatMap { it.supportedTypes }.distinct()
var lastButton: MaterialButton? = null ) { list ->
preSelectedTypes.clear()
for ((button, validTypes) in pairList) { preSelectedTypes.addAll(list)
val isValid = updateList()
validAPIs.any { api -> validTypes.any { api.supportedTypes.contains(it) } }
button?.isVisible = isValid
if (isValid) {
// Set focus navigation
button?.let { currentButton ->
lastButton?.nextFocusRightId = currentButton.id
lastButton?.id?.let { currentButton.nextFocusLeftId = it }
lastButton = currentButton
}
fun buttonContains(): Boolean {
return preSelectedTypes.any { validTypes.contains(it) }
}
button?.isSelected = buttonContains()
button?.setOnClickListener {
preSelectedTypes.clear()
preSelectedTypes.addAll(validTypes)
for ((otherButton, _) in pairList) {
otherButton?.isSelected = false
}
button.isSelected = true
updateList()
}
button?.setOnLongClickListener {
if (!buttonContains()) {
button.isSelected = true
preSelectedTypes.addAll(validTypes)
} else {
button.isSelected = false
preSelectedTypes.removeAll(validTypes)
}
updateList()
return@setOnLongClickListener true
}
}
} }
updateList() updateList()
} }
@ -422,7 +432,6 @@ class HomeFragment : Fragment() {
} }
private fun toggleMainVisibility(visible: Boolean) { private fun toggleMainVisibility(visible: Boolean) {
home_main_holder?.isVisible = visible
home_main_poster_recyclerview?.isVisible = visible home_main_poster_recyclerview?.isVisible = visible
} }
@ -531,6 +540,51 @@ class HomeFragment : Fragment() {
home_random?.visibility = View.GONE home_random?.visibility = View.GONE
} }
observe(homeViewModel.preview) { preview ->
when (preview) {
is Resource.Success -> {
home_preview?.isVisible = true
preview.value.apply {
home_preview_tags?.text = tags?.joinToString("") ?: ""
home_preview_tags?.isGone = tags.isNullOrEmpty()
home_preview_image?.setImage(posterUrl, posterHeaders)
home_preview_title?.text = name
home_preview_play?.setOnClickListener {
activity?.loadResult(url, apiName, START_ACTION_RESUME_LATEST)
//activity.loadSearchResult(url, START_ACTION_RESUME_LATEST)
}
home_preview_info?.setOnClickListener {
activity?.loadResult(url, apiName)
//activity.loadSearchResult(random)
}
// very ugly code, but I dont care
val watchType = DataStoreHelper.getResultWatchState(preview.value.getId())
home_preview_bookmark?.setText(watchType.stringRes)
home_preview_bookmark?.setCompoundDrawablesWithIntrinsicBounds(null,getDrawable(home_preview_bookmark.context, watchType.iconRes),null,null)
home_preview_bookmark?.setOnClickListener { fab ->
activity?.showBottomDialog(
WatchType.values().map { fab.context.getString(it.stringRes) }
.toList(),
DataStoreHelper.getResultWatchState(preview.value.getId()).ordinal,
fab.context.getString(R.string.action_add_to_bookmarks),
showApply = false,
{}) {
val newValue = WatchType.values()[it]
home_preview_bookmark?.setCompoundDrawablesWithIntrinsicBounds(null,getDrawable(home_preview_bookmark.context, newValue.iconRes),null,null)
home_preview_bookmark?.setText(newValue.stringRes)
updateWatchStatus(preview.value, newValue)
reloadStored()
}
}
}
}
else -> {
home_preview?.isVisible = false
}
}
}
observe(homeViewModel.apiName) { apiName -> observe(homeViewModel.apiName) { apiName ->
currentApiName = apiName currentApiName = apiName
// setKey(USER_SELECTED_HOMEPAGE_API, apiName) // setKey(USER_SELECTED_HOMEPAGE_API, apiName)
@ -563,17 +617,17 @@ class HomeFragment : Fragment() {
HomeChildItemAdapter( HomeChildItemAdapter(
mutableListOf(), mutableListOf(),
R.layout.home_result_big_grid, R.layout.home_result_big_grid,
nextFocusUp = home_main_poster_recyclerview.nextFocusUpId, nextFocusUp = home_main_poster_recyclerview?.nextFocusUpId,
nextFocusDown = home_main_poster_recyclerview.nextFocusDownId nextFocusDown = home_main_poster_recyclerview?.nextFocusDownId
) { callback -> ) { callback ->
homeHandleSearch(callback) homeHandleSearch(callback)
} }
home_main_poster_recyclerview.setLinearListLayout() home_main_poster_recyclerview?.setLinearListLayout()
observe(homeViewModel.randomItems) { items -> observe(homeViewModel.randomItems) { items ->
if (items.isNullOrEmpty()) { if (items.isNullOrEmpty()) {
toggleMainVisibility(false) toggleMainVisibility(false)
} else { } else {
val tempAdapter = home_main_poster_recyclerview.adapter as HomeChildItemAdapter? val tempAdapter = home_main_poster_recyclerview?.adapter as? HomeChildItemAdapter?
// no need to reload if it has the same data // no need to reload if it has the same data
if (tempAdapter != null && tempAdapter.cardList == items) { if (tempAdapter != null && tempAdapter.cardList == items) {
toggleMainVisibility(true) toggleMainVisibility(true)
@ -938,7 +992,7 @@ class HomeFragment : Fragment() {
} }
} }
context?.fixPaddingStatusbarView(home_statusbar) //context?.fixPaddingStatusbarView(home_statusbar)
context?.fixPaddingStatusbar(home_loading_statusbar) context?.fixPaddingStatusbar(home_loading_statusbar)
home_master_recycler.adapter = home_master_recycler.adapter =
@ -959,33 +1013,6 @@ class HomeFragment : Fragment() {
} }
} // GridLayoutManager(context, 1).also { it.supportsPredictiveItemAnimations() } } // GridLayoutManager(context, 1).also { it.supportsPredictiveItemAnimations() }
if (!isTvSettings()) {
LinearSnapHelper().attachToRecyclerView(home_main_poster_recyclerview) // snap
val centerLayoutManager =
CenterZoomLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
centerLayoutManager.setOnSizeListener { index ->
(home_main_poster_recyclerview?.adapter as HomeChildItemAdapter?)?.cardList?.get(
index
)?.let { random ->
home_main_play?.setOnClickListener {
activity.loadSearchResult(random, START_ACTION_RESUME_LATEST)
}
home_main_info?.setOnClickListener {
activity.loadSearchResult(random)
}
home_main_text?.text =
random.name + if (random is AnimeSearchResponse && !random.dubStatus.isNullOrEmpty()) {
random.dubStatus?.joinToString(
prefix = "",
separator = " | "
) { it.name }
} else ""
}
}
home_main_poster_recyclerview?.layoutManager = centerLayoutManager // scale
}
reloadStored() reloadStored()
loadHomePage() loadHomePage()

View file

@ -13,6 +13,7 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.context
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.HomePageList import com.lagradost.cloudstream3.HomePageList
import com.lagradost.cloudstream3.LoadResponse
import com.lagradost.cloudstream3.MainAPI import com.lagradost.cloudstream3.MainAPI
import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.mvvm.* import com.lagradost.cloudstream3.mvvm.*
@ -32,7 +33,6 @@ import com.lagradost.cloudstream3.utils.USER_SELECTED_HOMEPAGE_API
import com.lagradost.cloudstream3.utils.VideoDownloadHelper import com.lagradost.cloudstream3.utils.VideoDownloadHelper
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.util.* import java.util.*
import kotlin.collections.set import kotlin.collections.set
@ -58,7 +58,9 @@ class HomeViewModel : ViewModel() {
val bookmarks: LiveData<Pair<Boolean, List<SearchResponse>>> = _bookmarks val bookmarks: LiveData<Pair<Boolean, List<SearchResponse>>> = _bookmarks
private val _resumeWatching = MutableLiveData<List<SearchResponse>>() private val _resumeWatching = MutableLiveData<List<SearchResponse>>()
private val _preview = MutableLiveData<Resource<LoadResponse>>()
val resumeWatching: LiveData<List<SearchResponse>> = _resumeWatching val resumeWatching: LiveData<List<SearchResponse>> = _resumeWatching
val preview: LiveData<Resource<LoadResponse>> = _preview
fun loadResumeWatching() = viewModelScope.launchSafe { fun loadResumeWatching() = viewModelScope.launchSafe {
val resumeWatching = withContext(Dispatchers.IO) { val resumeWatching = withContext(Dispatchers.IO) {
@ -207,6 +209,7 @@ class HomeViewModel : ViewModel() {
expandAndReturn(name) expandAndReturn(name)
} }
private fun load(api: MainAPI?) = viewModelScope.launchSafe { private fun load(api: MainAPI?) = viewModelScope.launchSafe {
repo = if (api != null) { repo = if (api != null) {
APIRepository(api) APIRepository(api)
@ -219,6 +222,7 @@ class HomeViewModel : ViewModel() {
if (repo?.hasMainPage == true) { if (repo?.hasMainPage == true) {
_page.postValue(Resource.Loading()) _page.postValue(Resource.Loading())
_preview.postValue(Resource.Loading())
when (val data = repo?.getMainPage(1, null)) { when (val data = repo?.getMainPage(1, null)) {
is Resource.Success -> { is Resource.Success -> {
@ -232,8 +236,38 @@ class HomeViewModel : ViewModel() {
ExpandableHomepageList(filteredList, 1, home.hasNext) ExpandableHomepageList(filteredList, 1, home.hasNext)
} }
} }
_page.postValue(Resource.Success(expandable))
val items = data.value.mapNotNull { it?.items }.flatten() val items = data.value.mapNotNull { it?.items }.flatten()
items.randomOrNull()?.list?.randomOrNull()?.url?.let { url ->
// backup request in case first fails
var first = repo?.load(url)
if(first == null ||first is Resource.Failure) {
first = repo?.load(items.random().list.random().url)
}
first?.let {
_preview.postValue(it)
} ?: run {
_preview.postValue(
Resource.Failure(
false,
null,
null,
"No repo found, this should never happen"
)
)
}
} ?: run {
_preview.postValue(
Resource.Failure(
false,
null,
null,
"No homepage items"
)
)
}
_page.postValue(Resource.Success(expandable))
//val home = data.value //val home = data.value
if (items.isNotEmpty()) { if (items.isNotEmpty()) {
@ -263,6 +297,7 @@ class HomeViewModel : ViewModel() {
} }
} else { } else {
_page.postValue(Resource.Success(emptyMap())) _page.postValue(Resource.Success(emptyMap()))
_preview.postValue(Resource.Failure(false, null, null, "No homepage"))
} }
} }

View file

@ -412,6 +412,29 @@ class ResultViewModel2 : ViewModel() {
return this?.firstOrNull { it.season == season } return this?.firstOrNull { it.season == season }
} }
fun updateWatchStatus(currentResponse : LoadResponse, status: WatchType) {
val currentId = currentResponse.getId()
val resultPage = currentResponse
DataStoreHelper.setResultWatchState(currentId, status.internalId)
val current = DataStoreHelper.getBookmarkedData(currentId)
val currentTime = System.currentTimeMillis()
DataStoreHelper.setBookmarkedData(
currentId,
DataStoreHelper.BookmarkedData(
currentId,
current?.bookmarkedTime ?: currentTime,
currentTime,
resultPage.name,
resultPage.url,
resultPage.apiName,
resultPage.type,
resultPage.posterUrl,
resultPage.year
)
)
}
private fun filterName(name: String?): String? { private fun filterName(name: String?): String? {
if (name == null) return null if (name == null) return null
Regex("[eE]pisode [0-9]*(.*)").find(name)?.groupValues?.get(1)?.let { Regex("[eE]pisode [0-9]*(.*)").find(name)?.groupValues?.get(1)?.let {
@ -764,28 +787,10 @@ class ResultViewModel2 : ViewModel() {
private val _selectPopup: MutableLiveData<Some<SelectPopup>> = MutableLiveData(Some.None) private val _selectPopup: MutableLiveData<Some<SelectPopup>> = MutableLiveData(Some.None)
val selectPopup: LiveData<Some<SelectPopup>> get() = _selectPopup val selectPopup: LiveData<Some<SelectPopup>> get() = _selectPopup
fun updateWatchStatus(status: WatchType) {
val currentId = currentId ?: return
val resultPage = currentResponse ?: return
_watchStatus.postValue(status)
DataStoreHelper.setResultWatchState(currentId, status.internalId) fun updateWatchStatus(status: WatchType) {
val current = DataStoreHelper.getBookmarkedData(currentId) updateWatchStatus(currentResponse ?: return,status)
val currentTime = System.currentTimeMillis() _watchStatus.postValue(status)
DataStoreHelper.setBookmarkedData(
currentId,
DataStoreHelper.BookmarkedData(
currentId,
current?.bookmarkedTime ?: currentTime,
currentTime,
resultPage.name,
resultPage.url,
resultPage.apiName,
resultPage.type,
resultPage.posterUrl,
resultPage.year
)
)
} }
private fun startChromecast( private fun startChromecast(

View file

@ -26,15 +26,19 @@ import com.lagradost.cloudstream3.APIHolder.filterSearchResultByFilmQuality
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings
import com.lagradost.cloudstream3.APIHolder.getApiSettings import com.lagradost.cloudstream3.APIHolder.getApiSettings
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent
import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.mvvm.observe import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.ui.APIRepository import com.lagradost.cloudstream3.ui.APIRepository
import com.lagradost.cloudstream3.ui.home.HomeFragment 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 import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.currentSpan
import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.loadHomepageList import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.loadHomepageList
import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.updateChips
import com.lagradost.cloudstream3.ui.home.ParentItemAdapter import com.lagradost.cloudstream3.ui.home.ParentItemAdapter
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
import com.lagradost.cloudstream3.utils.Coroutines.main import com.lagradost.cloudstream3.utils.Coroutines.main
@ -46,6 +50,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.utils.UIHelper.getSpanCount import com.lagradost.cloudstream3.utils.UIHelper.getSpanCount
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
import kotlinx.android.synthetic.main.fragment_search.* import kotlinx.android.synthetic.main.fragment_search.*
import kotlinx.android.synthetic.main.tvtypes_chips.*
import java.util.concurrent.locks.ReentrantLock import java.util.concurrent.locks.ReentrantLock
const val SEARCH_PREF_TAGS = "search_pref_tags" const val SEARCH_PREF_TAGS = "search_pref_tags"
@ -130,65 +135,26 @@ class SearchFragment : Fragment() {
// Null if defined as a variable // Null if defined as a variable
// This needs to be run after view created // This needs to be run after view created
private fun getPairList(): List<Pair<MaterialButton?, List<TvType>>> {
return HomeFragment.getPairList(
search_select_anime,
search_select_cartoons,
search_select_tv_series,
search_select_documentaries,
search_select_movies,
search_select_asian,
search_select_livestreams,
search_select_nsfw,
search_select_others
)
}
private fun reloadRepos(success: Boolean = false) = main { private fun reloadRepos(success: Boolean = false) = main {
val pairList = getPairList()
searchViewModel.reloadRepos() searchViewModel.reloadRepos()
context?.filterProviderByPreferredMedia()?.let { validAPIs -> context?.filterProviderByPreferredMedia()?.let { validAPIs ->
for ((button, validTypes) in pairList) { bindChips(
val isValid = home_select_group,
validAPIs.any { api -> validTypes.any { api.supportedTypes.contains(it) } } selectedSearchTypes,
button?.isVisible = isValid validAPIs.flatMap { api -> api.supportedTypes }.distinct()
if (isValid) { ) { list ->
fun buttonContains(): Boolean { if (selectedSearchTypes.toSet() != list.toSet()) {
return selectedSearchTypes.any { validTypes.contains(it) } setKey(SEARCH_PREF_TAGS, selectedSearchTypes)
} selectedSearchTypes.clear()
selectedSearchTypes.addAll(list)
button?.isSelected = buttonContains() search(main_search?.query?.toString())
button?.setOnClickListener {
val last = selectedSearchTypes.toSet()
selectedSearchTypes.clear()
selectedSearchTypes.addAll(validTypes)
for ((otherButton, _) in pairList) {
otherButton?.isSelected = false
}
it?.context?.setKey(SEARCH_PREF_TAGS, selectedSearchTypes)
it?.isSelected = true
if (last != selectedSearchTypes.toSet()) // if you click the same button again the it does nothing
search(main_search?.query?.toString())
}
button?.setOnLongClickListener {
if (!buttonContains()) {
it?.isSelected = true
selectedSearchTypes.addAll(validTypes)
} else {
it?.isSelected = false
selectedSearchTypes.removeAll(validTypes)
}
it?.context?.setKey(SEARCH_PREF_TAGS, selectedSearchTypes)
search(main_search?.query?.toString())
return@setOnLongClickListener true
}
} }
} }
} }
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@ -239,31 +205,67 @@ class SearchFragment : Fragment() {
builder.let { dialog -> builder.let { dialog ->
val isMultiLang = ctx.getApiProviderLangSettings().size > 1 val isMultiLang = ctx.getApiProviderLangSettings().size > 1
val anime = dialog.findViewById<MaterialButton>(R.id.home_select_anime)
val cartoons = dialog.findViewById<MaterialButton>(R.id.home_select_cartoons)
val tvs = dialog.findViewById<MaterialButton>(R.id.home_select_tv_series)
val docs = dialog.findViewById<MaterialButton>(R.id.home_select_documentaries)
val movies = dialog.findViewById<MaterialButton>(R.id.home_select_movies)
val asian = dialog.findViewById<MaterialButton>(R.id.home_select_asian)
val livestream =
dialog.findViewById<MaterialButton>(R.id.home_select_livestreams)
val nsfw = dialog.findViewById<MaterialButton>(R.id.home_select_nsfw)
val other = dialog.findViewById<MaterialButton>(R.id.home_select_others)
val cancelBtt = dialog.findViewById<MaterialButton>(R.id.cancel_btt) val cancelBtt = dialog.findViewById<MaterialButton>(R.id.cancel_btt)
val applyBtt = dialog.findViewById<MaterialButton>(R.id.apply_btt) val applyBtt = dialog.findViewById<MaterialButton>(R.id.apply_btt)
val pairList = val listView = dialog.findViewById<ListView>(R.id.listview1)
HomeFragment.getPairList( val arrayAdapter = ArrayAdapter<String>(ctx, R.layout.sort_bottom_single_choice)
anime, listView?.adapter = arrayAdapter
cartoons, listView?.choiceMode = AbsListView.CHOICE_MODE_MULTIPLE
tvs,
docs, listView?.setOnItemClickListener { _, _, i, _ ->
movies, if (currentValidApis.isNotEmpty()) {
asian, val api = currentValidApis[i].name
livestream, if (currentSelectedApis.contains(api)) {
nsfw, listView.setItemChecked(i, false)
other currentSelectedApis -= api
) } else {
listView.setItemChecked(i, true)
currentSelectedApis += api
}
}
}
fun updateList(types: List<TvType>) {
setKey(SEARCH_PREF_TAGS, types.map {it.name})
arrayAdapter.clear()
currentValidApis = validAPIs.filter { api ->
api.supportedTypes.any {
types.contains(it)
}
}.sortedBy { it.name.lowercase() }
val names = currentValidApis.map {
if (isMultiLang) "${
SubtitleHelper.getFlagFromIso(
it.lang
)?.plus(" ") ?: ""
}${it.name}" else it.name
}
for ((index, api) in currentValidApis.map { it.name }.withIndex()) {
listView?.setItemChecked(index, currentSelectedApis.contains(api))
}
//arrayAdapter.notifyDataSetChanged()
arrayAdapter.addAll(names)
arrayAdapter.notifyDataSetChanged()
}
val selectedSearchTypes = getKey<List<String>>(SEARCH_PREF_TAGS)
?.mapNotNull { listName ->
TvType.values().firstOrNull { it.name == listName }
}
?.toMutableList()
?: mutableListOf(TvType.Movie, TvType.TvSeries)
bindChips(
dialog.home_select_group,
selectedSearchTypes,
TvType.values().toList()
) { list ->
updateList(list)
}
cancelBtt?.setOnClickListener { cancelBtt?.setOnClickListener {
dialog.dismissSafe() dialog.dismissSafe()
@ -284,90 +286,7 @@ class SearchFragment : Fragment() {
context?.setKey(SEARCH_PREF_PROVIDERS, currentSelectedApis.toList()) context?.setKey(SEARCH_PREF_PROVIDERS, currentSelectedApis.toList())
selectedApis = currentSelectedApis selectedApis = currentSelectedApis
} }
updateList(selectedSearchTypes.toList())
val selectedSearchTypes = context?.getKey<List<String>>(SEARCH_PREF_TAGS)
?.mapNotNull { listName ->
TvType.values().firstOrNull { it.name == listName }
}
?.toMutableList()
?: mutableListOf(TvType.Movie, TvType.TvSeries)
val listView = dialog.findViewById<ListView>(R.id.listview1)
val arrayAdapter = ArrayAdapter<String>(ctx, R.layout.sort_bottom_single_choice)
listView?.adapter = arrayAdapter
listView?.choiceMode = AbsListView.CHOICE_MODE_MULTIPLE
listView?.setOnItemClickListener { _, _, i, _ ->
if (currentValidApis.isNotEmpty()) {
val api = currentValidApis[i].name
if (currentSelectedApis.contains(api)) {
listView.setItemChecked(i, false)
currentSelectedApis -= api
} else {
listView.setItemChecked(i, true)
currentSelectedApis += api
}
}
}
fun updateList() {
arrayAdapter.clear()
currentValidApis = validAPIs.filter { api ->
api.supportedTypes.any {
selectedSearchTypes.contains(it)
}
}.sortedBy { it.name.lowercase() }
val names = currentValidApis.map {
if (isMultiLang) "${
SubtitleHelper.getFlagFromIso(
it.lang
)?.plus(" ") ?: ""
}${it.name}" else it.name
}
for ((index, api) in currentValidApis.map { it.name }.withIndex()) {
listView?.setItemChecked(index, currentSelectedApis.contains(api))
}
//arrayAdapter.notifyDataSetChanged()
arrayAdapter.addAll(names)
arrayAdapter.notifyDataSetChanged()
}
for ((button, validTypes) in pairList) {
val isValid =
validAPIs.any { api -> validTypes.any { api.supportedTypes.contains(it) } }
button?.isVisible = isValid
if (isValid) {
fun buttonContains(): Boolean {
return selectedSearchTypes.any { validTypes.contains(it) }
}
button?.isSelected = buttonContains()
button?.setOnClickListener {
selectedSearchTypes.clear()
selectedSearchTypes.addAll(validTypes)
for ((otherButton, _) in pairList) {
otherButton?.isSelected = false
}
button.isSelected = true
updateList()
}
button?.setOnLongClickListener {
if (!buttonContains()) {
button.isSelected = true
selectedSearchTypes.addAll(validTypes)
} else {
button.isSelected = false
selectedSearchTypes.removeAll(validTypes)
}
updateList()
return@setOnLongClickListener true
}
}
}
updateList()
} }
} }
} }
@ -380,14 +299,6 @@ class SearchFragment : Fragment() {
?.toMutableList() ?.toMutableList()
?: mutableListOf(TvType.Movie, TvType.TvSeries) ?: mutableListOf(TvType.Movie, TvType.TvSeries)
val pairList = getPairList()
fun updateSelectedList(list: MutableList<TvType>) {
selectedSearchTypes = list
for ((button, validTypes) in pairList) {
button?.isSelected = selectedSearchTypes.any { validTypes.contains(it) }
}
}
if (isTrueTvSettings()) { if (isTrueTvSettings()) {
search_filter.isFocusable = true search_filter.isFocusable = true
search_filter.isFocusableInTouchMode = true search_filter.isFocusableInTouchMode = true
@ -500,7 +411,7 @@ class SearchFragment : Fragment() {
SEARCH_HISTORY_OPEN -> { SEARCH_HISTORY_OPEN -> {
searchViewModel.clearSearch() searchViewModel.clearSearch()
if (searchItem.type.isNotEmpty()) if (searchItem.type.isNotEmpty())
updateSelectedList(searchItem.type.toMutableList()) updateChips(home_select_group, searchItem.type.toMutableList())
main_search?.setQuery(searchItem.searchText, true) main_search?.setQuery(searchItem.searchText, true)
} }
SEARCH_HISTORY_REMOVE -> { SEARCH_HISTORY_REMOVE -> {

View file

@ -9,8 +9,9 @@ import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.mvvm.observe import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.getPairList import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.bindChips
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
import com.lagradost.cloudstream3.ui.settings.appLanguages import com.lagradost.cloudstream3.ui.settings.appLanguages
@ -18,6 +19,8 @@ import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showMultiDialog
import com.lagradost.cloudstream3.utils.SubtitleHelper import com.lagradost.cloudstream3.utils.SubtitleHelper
import com.lagradost.cloudstream3.utils.UIHelper.toPx import com.lagradost.cloudstream3.utils.UIHelper.toPx
import kotlinx.android.synthetic.main.fragment_plugins.* import kotlinx.android.synthetic.main.fragment_plugins.*
import kotlinx.android.synthetic.main.tvtypes_chips.*
import kotlinx.android.synthetic.main.tvtypes_chips_scroll.*
const val PLUGINS_BUNDLE_NAME = "name" const val PLUGINS_BUNDLE_NAME = "name"
const val PLUGINS_BUNDLE_URL = "url" const val PLUGINS_BUNDLE_URL = "url"
@ -145,56 +148,10 @@ class PluginsFragment : Fragment() {
pluginViewModel.updatePluginList(context, url) pluginViewModel.updatePluginList(context, url)
tv_types_scroll_view?.isVisible = true tv_types_scroll_view?.isVisible = true
// 💀💀💀💀💀💀💀 Recyclerview when bindChips(home_select_group, emptyList(), TvType.values().toList()) { list ->
val pairList = getPairList( pluginViewModel.tvTypes.clear()
home_select_anime, pluginViewModel.tvTypes.addAll(list.map { it.name })
home_select_cartoons, pluginViewModel.updateFilteredPlugins()
home_select_tv_series,
home_select_documentaries,
home_select_movies,
home_select_asian,
home_select_livestreams,
home_select_nsfw,
home_select_others
)
// val supportedTypes: Array<String> =
// pluginViewModel.filteredPlugins.value!!.second.flatMap { it -> it.plugin.second.tvTypes ?: listOf("Other") }.distinct().toTypedArray()
// Copy pasted code
for ((button, validTypes) in pairList) {
val validTypesMapped = validTypes.map { it.name }
val isValid = true
//validTypes.any { it -> supportedTypes.contains(it.name) }
button?.isVisible = isValid
if (isValid) {
fun buttonContains(): Boolean {
return pluginViewModel.tvTypes.any { validTypesMapped.contains(it) }
}
button?.isSelected = buttonContains()
button?.setOnClickListener {
pluginViewModel.tvTypes.clear()
pluginViewModel.tvTypes.addAll(validTypesMapped)
for ((otherButton, _) in pairList) {
otherButton?.isSelected = false
}
button.isSelected = true
pluginViewModel.updateFilteredPlugins()
}
button?.setOnLongClickListener {
if (!buttonContains()) {
button.isSelected = true
pluginViewModel.tvTypes.addAll(validTypesMapped)
} else {
button.isSelected = false
pluginViewModel.tvTypes.removeAll(validTypesMapped)
}
pluginViewModel.updateFilteredPlugins()
return@setOnLongClickListener true
}
}
} }
} }
} }

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorPrimary" android:state_checked="true"/>
<item android:color="?attr/primaryGrayBackground" android:state_checked="false"/>
</selector>

View file

@ -1,79 +1,83 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/homeRoot" android:id="@+id/homeRoot"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|keyboard|navigation" android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|keyboard|navigation"
android:paddingTop="0dp"> android:paddingTop="0dp">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_height="match_parent" android:layout_width="match_parent"
android:layout_width="match_parent"> android:layout_height="match_parent">
<com.google.android.material.navigationrail.NavigationRailView <com.google.android.material.navigationrail.NavigationRailView
android:layout_width="62dp" android:id="@+id/nav_rail_view"
android:layout_height="match_parent" android:layout_width="62dp"
android:id="@+id/nav_rail_view" android:layout_height="match_parent"
android:background="?attr/primaryGrayBackground" android:background="?attr/primaryGrayBackground"
app:itemTextColor="@color/item_select_color" app:itemIconTint="@color/item_select_color"
app:itemIconTint="@color/item_select_color" app:itemTextColor="@color/item_select_color"
app:menuGravity="center" app:labelVisibilityMode="unlabeled"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent"
app:labelVisibilityMode="unlabeled" app:menu="@menu/bottom_nav_menu"
app:menu="@menu/bottom_nav_menu"> app:menuGravity="center">
</com.google.android.material.navigationrail.NavigationRailView> </com.google.android.material.navigationrail.NavigationRailView>
<!-- android:layout_height="65dp"
app:labelVisibilityMode="unlabeled"
-->
<com.google.android.material.bottomnavigation.BottomNavigationView <com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view" android:id="@+id/nav_view"
android:layout_width="0dp" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_width="0dp"
android:background="?attr/primaryGrayBackground" app:labelVisibilityMode="labeled"
android:background="?attr/primaryGrayBackground"
app:labelVisibilityMode="labeled" app:itemIconTint="@color/item_select_color"
app:itemTextColor="@color/item_select_color" app:itemTextColor="@color/item_select_color"
app:itemIconTint="@color/item_select_color"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:menu="@menu/bottom_nav_menu" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" /> app:menu="@menu/bottom_nav_menu" />
<androidx.fragment.app.FragmentContainerView <androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment" android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment" android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
app:defaultNavHost="true" app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation" app:layout_constraintBottom_toTopOf="@+id/cast_mini_controller_holder"
app:layout_constraintStart_toEndOf="@+id/nav_rail_view" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/cast_mini_controller_holder" app:layout_constraintStart_toEndOf="@+id/nav_rail_view"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent" /> app:navGraph="@navigation/mobile_navigation" />
<LinearLayout <LinearLayout
tools:layout_height="100dp" android:id="@+id/cast_mini_controller_holder"
android:layout_width="0dp" android:layout_width="0dp"
app:layout_constraintStart_toEndOf="@+id/nav_rail_view" android:layout_height="wrap_content"
android:layout_height="wrap_content" app:layout_constraintBottom_toTopOf="@+id/nav_view"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/nav_view" app:layout_constraintStart_toEndOf="@+id/nav_rail_view"
android:id="@+id/cast_mini_controller_holder"> tools:layout_height="100dp">
<!--com.google.android.gms.cast.framework.media.widget.MiniControllerFragment--> <!--com.google.android.gms.cast.framework.media.widget.MiniControllerFragment-->
<fragment <fragment
app:customCastBackgroundColor="?attr/primaryGrayBackground" android:id="@+id/cast_mini_controller"
app:castControlButtons="@array/cast_mini_controller_control_buttons" class="com.lagradost.cloudstream3.ui.MyMiniControllerFragment"
android:id="@+id/cast_mini_controller" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:visibility="gone"
android:visibility="gone"
class="com.lagradost.cloudstream3.ui.MyMiniControllerFragment" app:castControlButtons="@array/cast_mini_controller_control_buttons"
tools:ignore="FragmentTagUsage" /> app:customCastBackgroundColor="?attr/primaryGrayBackground"
tools:ignore="FragmentTagUsage" />
</LinearLayout> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout> </FrameLayout>

View file

@ -1,87 +1,87 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:id="@+id/home_root"
android:layout_height="match_parent" android:layout_width="match_parent"
android:id="@+id/home_root" android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment"> tools:context=".ui.home.HomeFragment">
<FrameLayout <FrameLayout
android:visibility="gone" android:id="@+id/home_loading"
tools:visibility="gone" android:layout_width="match_parent"
android:id="@+id/home_loading" android:layout_height="match_parent"
android:layout_width="match_parent" android:visibility="gone"
android:layout_height="match_parent"> tools:visibility="gone">
<ProgressBar <ProgressBar
android:layout_gravity="center" android:layout_width="50dp"
android:visibility="gone" android:layout_height="50dp"
tools:visibility="gone" android:layout_gravity="center"
android:layout_width="50dp" android:visibility="gone"
android:layout_height="50dp" /> tools:visibility="gone" />
<com.facebook.shimmer.ShimmerFrameLayout <com.facebook.shimmer.ShimmerFrameLayout
android:id="@+id/home_loading_shimmer" android:id="@+id/home_loading_shimmer"
app:shimmer_base_alpha="0.2" android:layout_width="match_parent"
app:shimmer_highlight_alpha="0.3" android:layout_height="match_parent"
app:shimmer_duration="@integer/loading_time" android:layout_gravity="center"
app:shimmer_auto_start="true" android:layout_marginTop="15dp"
android:paddingTop="40dp" android:orientation="vertical"
android:layout_width="match_parent" android:paddingTop="40dp"
android:layout_height="match_parent" app:shimmer_auto_start="true"
android:layout_gravity="center" app:shimmer_base_alpha="0.2"
android:layout_marginTop="15dp" app:shimmer_duration="@integer/loading_time"
android:orientation="vertical"> app:shimmer_highlight_alpha="0.3">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<FrameLayout <FrameLayout
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content"> android:orientation="horizontal">
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_margin="@dimen/loading_margin" android:layout_width="125dp"
android:layout_gravity="center" android:layout_height="200dp"
app:cardCornerRadius="@dimen/loading_radius" android:layout_gravity="center"
android:background="@color/grayShimmer" android:layout_margin="@dimen/loading_margin"
android:translationX="-164dp" android:background="@color/grayShimmer"
android:layout_width="125dp" android:translationX="-164dp"
android:layout_height="200dp" /> app:cardCornerRadius="@dimen/loading_radius" />
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_margin="@dimen/loading_margin" android:layout_width="148dp"
android:layout_gravity="center" android:layout_height="234dp"
app:cardCornerRadius="@dimen/loading_radius" android:layout_gravity="center"
android:background="@color/grayShimmer" android:layout_margin="@dimen/loading_margin"
android:layout_width="148dp" android:background="@color/grayShimmer"
android:layout_height="234dp" /> app:cardCornerRadius="@dimen/loading_radius" />
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_margin="@dimen/loading_margin" android:layout_width="125dp"
android:layout_gravity="center" android:layout_height="200dp"
app:cardCornerRadius="@dimen/loading_radius" android:layout_gravity="center"
android:background="@color/grayShimmer" android:layout_margin="@dimen/loading_margin"
android:translationX="164dp" android:background="@color/grayShimmer"
android:layout_width="125dp" android:translationX="164dp"
android:layout_height="200dp" /> app:cardCornerRadius="@dimen/loading_radius" />
</FrameLayout> </FrameLayout>
<include layout="@layout/loading_line_short_center" /> <include layout="@layout/loading_line_short_center" />
<LinearLayout <LinearLayout
android:orientation="vertical" android:layout_width="match_parent"
android:layout_marginTop="@dimen/result_padding" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/result_padding" android:layout_marginStart="@dimen/result_padding"
android:layout_marginEnd="@dimen/result_padding" android:layout_marginTop="@dimen/result_padding"
android:layout_width="match_parent" android:layout_marginEnd="@dimen/result_padding"
android:layout_height="wrap_content"> android:orientation="vertical">
<include layout="@layout/loading_list" /> <include layout="@layout/loading_list" />
@ -93,168 +93,170 @@
</com.facebook.shimmer.ShimmerFrameLayout> </com.facebook.shimmer.ShimmerFrameLayout>
<FrameLayout <FrameLayout
android:id="@+id/home_loading_statusbar" android:id="@+id/home_loading_statusbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="70dp"> android:layout_height="70dp">
<ImageView <ImageView
android:id="@+id/home_change_api_loading" android:id="@+id/home_change_api_loading"
android:layout_margin="10dp" android:layout_width="30dp"
android:layout_gravity="center_vertical|end" android:layout_height="30dp"
android:background="?android:attr/selectableItemBackgroundBorderless" android:layout_gravity="center_vertical|end"
android:src="@drawable/ic_baseline_keyboard_arrow_down_24" android:layout_margin="10dp"
android:layout_width="30dp" android:background="?android:attr/selectableItemBackgroundBorderless"
android:layout_height="30dp" android:contentDescription="@string/home_change_provider_img_des"
android:contentDescription="@string/home_change_provider_img_des" /> android:src="@drawable/ic_baseline_keyboard_arrow_down_24" />
</FrameLayout> </FrameLayout>
</FrameLayout> </FrameLayout>
<LinearLayout <LinearLayout
android:visibility="gone" android:id="@+id/home_loading_error"
tools:visibility="gone" android:layout_width="match_parent"
android:id="@+id/home_loading_error" android:layout_height="wrap_content"
android:orientation="vertical" android:layout_gravity="center"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="gone">
<com.google.android.material.button.MaterialButton
android:id="@+id/home_reload_connectionerror"
style="@style/WhiteButton"
android:layout_width="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_width="match_parent" android:layout_margin="5dp"
android:layout_height="wrap_content"> android:minWidth="200dp"
android:text="@string/reload_error"
app:icon="@drawable/ic_baseline_autorenew_24" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:layout_gravity="center" android:id="@+id/home_reload_connection_open_in_browser"
style="@style/WhiteButton" style="@style/BlackButton"
android:layout_margin="5dp" android:layout_width="wrap_content"
app:icon="@drawable/ic_baseline_autorenew_24" android:layout_gravity="center"
android:text="@string/reload_error" android:layout_margin="5dp"
android:id="@+id/home_reload_connectionerror" android:minWidth="200dp"
android:layout_width="wrap_content" android:text="@string/result_open_in_browser"
android:minWidth="200dp" /> app:icon="@drawable/ic_baseline_public_24" />
<com.google.android.material.button.MaterialButton
android:layout_gravity="center"
style="@style/BlackButton"
android:layout_margin="5dp"
app:icon="@drawable/ic_baseline_public_24"
android:text="@string/result_open_in_browser"
android:id="@+id/home_reload_connection_open_in_browser"
android:layout_width="wrap_content"
android:minWidth="200dp" />
<TextView <TextView
android:layout_margin="5dp" android:id="@+id/result_error_text"
android:gravity="center" android:layout_width="match_parent"
android:layout_gravity="center" android:layout_height="wrap_content"
android:id="@+id/result_error_text" android:layout_gravity="center"
android:textColor="?attr/textColor" android:layout_margin="5dp"
android:layout_width="match_parent" android:gravity="center"
android:layout_height="wrap_content" /> android:textColor="?attr/textColor" />
</LinearLayout> </LinearLayout>
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView
android:background="?attr/primaryBlackBackground" android:id="@+id/home_loaded"
tools:visibility="visible" android:layout_width="match_parent"
android:visibility="gone" android:layout_height="match_parent"
android:id="@+id/home_loaded" android:background="?attr/primaryBlackBackground"
android:layout_width="match_parent" android:visibility="gone"
android:layout_height="match_parent"> tools:visibility="visible">
<LinearLayout <LinearLayout
android:orientation="vertical" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="match_parent"
android:layout_height="match_parent"> android:orientation="vertical">
<View <View
android:background="?attr/primaryGrayBackground" android:id="@+id/home_statusbar"
android:id="@+id/home_statusbar" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="match_parent" /> android:background="?attr/primaryGrayBackground" />
<FrameLayout <FrameLayout
android:id="@+id/home_settings_bar" android:id="@+id/home_settings_bar"
android:background="?attr/primaryGrayBackground"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="70dp"> android:layout_height="70dp"
android:background="?attr/primaryGrayBackground"
android:visibility="gone">
<LinearLayout <LinearLayout
android:paddingTop="10dp" android:layout_width="match_parent"
android:paddingBottom="10dp" android:layout_height="match_parent"
android:paddingStart="10dp" android:orientation="horizontal"
android:paddingEnd="10dp" android:paddingStart="10dp"
android:orientation="horizontal" android:paddingTop="10dp"
android:layout_width="match_parent" android:paddingEnd="10dp"
android:layout_height="match_parent"> android:paddingBottom="10dp">
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/home_profile_picture_holder" android:id="@+id/home_profile_picture_holder"
android:layout_marginEnd="10dp" android:layout_width="40dp"
app:cardCornerRadius="100dp" android:layout_height="40dp"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_width="40dp" android:layout_marginEnd="10dp"
android:layout_height="40dp"> app:cardCornerRadius="100dp">
<ImageView <ImageView
android:scaleType="centerCrop" android:id="@+id/home_profile_picture"
android:id="@+id/home_profile_picture" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="match_parent"
android:layout_height="match_parent" android:scaleType="centerCrop"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
<FrameLayout <FrameLayout
android:layout_gravity="center_vertical" android:layout_width="match_parent"
android:visibility="visible" android:layout_height="40dp"
android:background="@drawable/search_background" android:layout_gravity="center_vertical"
android:layout_width="match_parent" android:background="@drawable/search_background"
android:layout_height="40dp"> android:visibility="visible">
<androidx.appcompat.widget.SearchView <androidx.appcompat.widget.SearchView
android:id="@+id/home_search" android:id="@+id/home_search2"
app:queryBackground="@color/transparent" android:layout_width="match_parent"
app:searchIcon="@drawable/search_icon" android:layout_height="match_parent"
android:paddingStart="-10dp" android:layout_gravity="center_vertical"
android:iconifiedByDefault="false" android:iconifiedByDefault="false"
app:queryHint="@string/search_hint" android:paddingStart="-10dp"
android:layout_width="match_parent" app:iconifiedByDefault="false"
android:layout_height="match_parent" app:queryBackground="@color/transparent"
android:layout_gravity="center_vertical" app:queryHint="@string/search_hint"
app:iconifiedByDefault="false" app:searchIcon="@drawable/search_icon"
tools:ignore="RtlSymmetry" /> tools:ignore="RtlSymmetry" />
</FrameLayout> </FrameLayout>
<LinearLayout <LinearLayout
android:visibility="gone" android:layout_width="match_parent"
android:gravity="center" android:layout_height="match_parent"
android:orientation="vertical" android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
<TextView
android:id="@+id/home_provider_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_vertical"
android:textColor="?attr/textColor"
android:textSize="20sp"
tools:text="Hello World" />
<TextView <TextView
android:gravity="center_vertical" android:id="@+id/home_provider_meta_info"
android:layout_gravity="center" android:layout_width="match_parent"
android:id="@+id/home_provider_name" android:layout_height="wrap_content"
android:textColor="?attr/textColor" android:layout_gravity="center"
android:textSize="20sp" android:gravity="center_vertical"
tools:text="Hello World" android:textColor="?attr/grayTextColor"
android:layout_width="match_parent" android:textSize="14sp"
tools:text="Hello World" />
android:layout_height="wrap_content" />
<TextView
android:gravity="center_vertical"
android:layout_gravity="center"
android:id="@+id/home_provider_meta_info"
android:textColor="?attr/grayTextColor"
android:textSize="14sp"
tools:text="Hello World"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
@ -278,273 +280,309 @@
</ImageView>--> </ImageView>-->
</FrameLayout> </FrameLayout>
<LinearLayout <FrameLayout
android:layout_marginTop="10dp" tools:visibility="visible"
android:id="@+id/home_main_holder" android:visibility="gone"
android:orientation="vertical" android:id="@+id/home_preview"
android:layout_width="match_parent"
android:layout_height="500dp">
<ImageView
android:alpha="0.8"
android:id="@+id/home_preview_image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="match_parent"
android:scaleType="centerCrop"
tools:src="@drawable/example_poster" />
<androidx.recyclerview.widget.RecyclerView <View
android:descendantFocusability="afterDescendants" android:id="@+id/title_shadow"
android:nextFocusUp="@id/home_change_api"
android:nextFocusDown="@id/home_main_info"
android:clipToPadding="false"
android:paddingStart="148dp"
android:paddingEnd="148dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:id="@+id/home_main_poster_recyclerview"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:listitem="@layout/home_result_grid" />
<!--<ImageView
android:foreground="@drawable/outline_drawable"
android:id="@+id/home_main_poster"
tools:src="@drawable/example_poster"
android:layout_gravity="center"
android:scaleType="centerCrop"
android:layout_width="150dp"
android:layout_height="212dp"
android:contentDescription="@string/home_main_poster_img_des">
</ImageView>-->
<TextView
android:id="@+id/home_main_text"
android:layout_gravity="center"
android:gravity="center"
tools:text="Perfect Run"
android:textStyle="bold"
android:layout_margin="5dp"
android:textSize="15sp"
android:textColor="?attr/textColor"
android:layout_width="match_parent"
android:maxLines="2"
android:ellipsize="end"
android:layout_height="40sp" />
<LinearLayout
android:visibility="visible"
android:padding="5dp"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton
android:nextFocusLeft="@id/nav_rail_view"
android:nextFocusUp="@id/home_main_poster_recyclerview"
android:nextFocusRight="@id/home_main_info"
android:nextFocusDown="@id/home_watch_child_more_info"
style="@style/WhiteButton"
android:visibility="visible"
android:layout_gravity="center"
android:id="@+id/home_main_play"
android:text="@string/home_play"
app:icon="@drawable/ic_baseline_play_arrow_24"
android:minWidth="120dp"
android:layout_width="wrap_content" />
<com.google.android.material.button.MaterialButton
android:nextFocusLeft="@id/home_main_play"
android:nextFocusUp="@id/home_main_poster_recyclerview"
android:nextFocusRight="@id/home_change_api"
android:nextFocusDown="@id/home_watch_child_more_info"
style="@style/BlackButton"
android:visibility="visible"
android:layout_gravity="center"
android:text="@string/home_info"
app:icon="@drawable/ic_outline_info_24"
android:id="@+id/home_main_info"
android:clickable="true"
android:focusable="true"
android:minWidth="120dp"
android:layout_width="wrap_content" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/home_watch_holder"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="300dp"
android:layout_gravity="bottom"
android:background="@drawable/background_shadow" />
<FrameLayout <FrameLayout
android:nextFocusLeft="@id/nav_rail_view"
android:nextFocusUp="@id/home_main_info"
android:nextFocusDown="@id/home_watch_child_recyclerview"
android:foreground="?android:attr/selectableItemBackgroundBorderless" android:layout_width="match_parent"
android:id="@+id/home_watch_child_more_info" android:layout_height="80dp"
android:padding="12dp" android:layout_gravity="top"
android:visibility="gone">
<androidx.appcompat.widget.SearchView
android:id="@+id/home_search"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:iconifiedByDefault="false"
android:paddingStart="-10dp"
app:iconifiedByDefault="false"
app:queryBackground="@color/transparent"
app:queryHint="@string/search_hint"
app:searchIcon="@drawable/search_icon"
tools:ignore="RtlSymmetry" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="vertical">
<TextView
android:textStyle="bold"
android:paddingBottom="10dp"
android:id="@+id/home_preview_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/white"
android:textSize="17sp"
tools:text="The Perfect Run" />
<!--<TextView
android:paddingStart="30dp"
android:paddingEnd="30dp"
android:id="@+id/home_season_tags"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="5 seasons 50 episodes" />-->
<TextView
android:paddingStart="30dp"
android:paddingEnd="30dp"
android:id="@+id/home_preview_tags"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="Hello • World • Tags" />
<LinearLayout
android:padding="20dp"
android:gravity="center"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/home_preview_bookmark"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:layout_gravity="center"
android:gravity="center"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:text="@string/none"
android:textColor="@color/white"
app:drawableTopCompat="@drawable/ic_baseline_add_24"
app:tint="@color/white" />
<com.google.android.material.button.MaterialButton
android:layout_gravity="center"
style="@style/WhiteButton"
android:id="@+id/home_preview_play"
android:layout_width="wrap_content"
android:text="@string/home_play"
app:icon="@drawable/ic_baseline_play_arrow_24" />
<TextView
android:background="?android:attr/selectableItemBackgroundBorderless"
android:id="@+id/home_preview_info"
android:gravity="center"
android:layout_gravity="center"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:text="@string/home_info"
android:textColor="@color/white"
app:drawableTopCompat="@drawable/ic_outline_info_24"
app:tint="@color/white" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
<LinearLayout
android:id="@+id/home_watch_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<FrameLayout
android:id="@+id/home_watch_child_more_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:nextFocusLeft="@id/nav_rail_view"
android:nextFocusDown="@id/home_watch_child_recyclerview"
android:padding="12dp">
<TextView <TextView
android:layout_gravity="center_vertical" android:id="@+id/home_watch_parent_item_title"
android:id="@+id/home_watch_parent_item_title" style="@style/WatchHeaderText"
style="@style/WatchHeaderText" android:layout_gravity="center_vertical"
android:text="@string/continue_watching" /> android:text="@string/continue_watching" />
<ImageView <ImageView
app:tint="?attr/textColor" android:layout_width="30dp"
android:layout_marginEnd="5dp" android:layout_height="match_parent"
android:layout_gravity="end|center_vertical" android:layout_gravity="end|center_vertical"
android:src="@drawable/ic_baseline_arrow_forward_24" android:layout_marginEnd="5dp"
android:layout_width="30dp" android:contentDescription="@string/home_more_info"
android:layout_height="match_parent" android:src="@drawable/ic_baseline_arrow_forward_24"
android:contentDescription="@string/home_more_info" /> app:tint="?attr/textColor" />
</FrameLayout> </FrameLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:paddingHorizontal="5dp" android:id="@+id/home_watch_child_recyclerview"
android:clipToPadding="false" android:layout_width="wrap_content"
android:descendantFocusability="afterDescendants" android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" android:clipToPadding="false"
android:id="@+id/home_watch_child_recyclerview" android:descendantFocusability="afterDescendants"
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="wrap_content" android:paddingHorizontal="5dp"
android:layout_height="wrap_content" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/home_result_grid" /> tools:listitem="@layout/home_result_grid" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/home_bookmarked_holder" android:id="@+id/home_bookmarked_holder"
android:orientation="vertical" android:layout_width="match_parent"
android:visibility="gone" android:layout_height="wrap_content"
tools:visibility="visible" android:orientation="vertical"
android:layout_width="match_parent" android:visibility="gone"
android:layout_height="wrap_content"> tools:visibility="visible">
<FrameLayout <FrameLayout
android:nextFocusLeft="@id/nav_rail_view" android:id="@+id/home_bookmarked_child_more_info"
android:nextFocusUp="@id/home_watch_child_recyclerview" android:layout_width="match_parent"
android:nextFocusForward="@id/home_bookmarked_child_recyclerview" android:layout_height="wrap_content"
android:foreground="?android:attr/selectableItemBackgroundBorderless" android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:id="@+id/home_bookmarked_child_more_info" android:nextFocusLeft="@id/nav_rail_view"
android:paddingTop="5dp" android:nextFocusUp="@id/home_watch_child_recyclerview"
android:paddingBottom="5dp" android:nextFocusForward="@id/home_bookmarked_child_recyclerview"
android:paddingStart="12dp" android:paddingStart="12dp"
android:paddingEnd="12dp" android:paddingTop="5dp"
android:layout_width="match_parent" android:paddingEnd="12dp"
android:layout_height="wrap_content"> android:paddingBottom="5dp">
<HorizontalScrollView <HorizontalScrollView
android:fadingEdge="horizontal" android:layout_width="wrap_content"
android:requiresFadingEdge="horizontal" android:layout_height="wrap_content"
android:layout_marginEnd="50dp" android:layout_marginEnd="50dp"
android:layout_width="wrap_content" android:fadingEdge="horizontal"
android:layout_height="wrap_content"> android:requiresFadingEdge="horizontal">
<LinearLayout <LinearLayout
android:orientation="horizontal" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content"> android:orientation="horizontal">
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:nextFocusLeft="@id/nav_rail_view" android:id="@+id/home_type_watching_btt"
android:nextFocusRight="@id/home_plan_to_watch_btt" style="@style/RoundedSelectableButton"
android:id="@+id/home_type_watching_btt" android:nextFocusLeft="@id/nav_rail_view"
android:text="@string/type_watching" android:nextFocusRight="@id/home_plan_to_watch_btt"
style="@style/RoundedSelectableButton" /> android:text="@string/type_watching" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:nextFocusLeft="@id/home_type_watching_btt" android:id="@+id/home_plan_to_watch_btt"
android:nextFocusRight="@id/home_type_on_hold_btt" style="@style/RoundedSelectableButton"
android:id="@+id/home_plan_to_watch_btt" android:nextFocusLeft="@id/home_type_watching_btt"
android:text="@string/type_plan_to_watch" android:nextFocusRight="@id/home_type_on_hold_btt"
style="@style/RoundedSelectableButton" /> android:text="@string/type_plan_to_watch" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:nextFocusLeft="@id/home_plan_to_watch_btt" android:id="@+id/home_type_on_hold_btt"
android:nextFocusRight="@id/home_type_dropped_btt" style="@style/RoundedSelectableButton"
android:id="@+id/home_type_on_hold_btt" android:nextFocusLeft="@id/home_plan_to_watch_btt"
android:text="@string/type_on_hold" android:nextFocusRight="@id/home_type_dropped_btt"
style="@style/RoundedSelectableButton" /> android:text="@string/type_on_hold" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:nextFocusLeft="@id/home_type_on_hold_btt" android:id="@+id/home_type_dropped_btt"
android:nextFocusRight="@id/home_type_completed_btt" style="@style/RoundedSelectableButton"
android:id="@+id/home_type_dropped_btt" android:nextFocusLeft="@id/home_type_on_hold_btt"
android:text="@string/type_dropped" android:nextFocusRight="@id/home_type_completed_btt"
style="@style/RoundedSelectableButton" /> android:text="@string/type_dropped" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:nextFocusLeft="@id/home_type_dropped_btt" android:id="@+id/home_type_completed_btt"
android:id="@+id/home_type_completed_btt" style="@style/RoundedSelectableButton"
android:text="@string/type_completed" android:nextFocusLeft="@id/home_type_dropped_btt"
style="@style/RoundedSelectableButton" /> android:text="@string/type_completed" />
</LinearLayout> </LinearLayout>
</HorizontalScrollView> </HorizontalScrollView>
<ImageView <ImageView
app:tint="?attr/textColor" android:layout_width="30dp"
android:layout_marginEnd="5dp" android:layout_height="match_parent"
android:layout_gravity="end|center_vertical" android:layout_gravity="end|center_vertical"
android:src="@drawable/ic_baseline_arrow_forward_24" android:layout_marginEnd="5dp"
android:layout_width="30dp" android:contentDescription="@string/home_more_info"
android:layout_height="match_parent" android:src="@drawable/ic_baseline_arrow_forward_24"
android:contentDescription="@string/home_more_info" /> app:tint="?attr/textColor" />
</FrameLayout> </FrameLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:paddingHorizontal="5dp" android:id="@+id/home_bookmarked_child_recyclerview"
android:clipToPadding="false" android:layout_width="wrap_content"
android:descendantFocusability="afterDescendants" android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" android:clipToPadding="false"
android:id="@+id/home_bookmarked_child_recyclerview" android:descendantFocusability="afterDescendants"
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="wrap_content" android:paddingHorizontal="5dp"
android:layout_height="wrap_content" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/home_result_grid" /> tools:listitem="@layout/home_result_grid" />
</LinearLayout> </LinearLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:nextFocusLeft="@id/nav_rail_view" android:id="@+id/home_master_recycler"
android:descendantFocusability="afterDescendants" android:layout_width="match_parent"
android:id="@+id/home_master_recycler" android:layout_height="match_parent"
android:layout_width="match_parent" android:descendantFocusability="afterDescendants"
android:layout_height="match_parent" android:nextFocusLeft="@id/nav_rail_view"
tools:listitem="@layout/homepage_parent" /> tools:listitem="@layout/homepage_parent" />
</LinearLayout> </LinearLayout>
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:visibility="gone" android:id="@+id/home_api_fab"
tools:visibility="visible" style="@style/ExtendedFloatingActionButton"
android:text="@string/home_source" android:text="@string/home_source"
android:id="@+id/home_api_fab" android:textColor="?attr/textColor"
app:icon="@drawable/ic_baseline_filter_list_24" android:visibility="gone"
style="@style/ExtendedFloatingActionButton" app:icon="@drawable/ic_baseline_filter_list_24"
android:textColor="?attr/textColor" tools:ignore="ContentDescription"
tools:ignore="ContentDescription" /> tools:visibility="visible" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:visibility="gone" android:id="@+id/home_random"
tools:visibility="visible" style="@style/ExtendedFloatingActionButton"
android:text="@string/home_random" android:layout_gravity="bottom|start"
android:id="@+id/home_random" android:text="@string/home_random"
android:layout_gravity="bottom|start" android:textColor="?attr/textColor"
app:icon="@drawable/ic_baseline_play_arrow_24" android:visibility="gone"
style="@style/ExtendedFloatingActionButton" app:icon="@drawable/ic_baseline_play_arrow_24"
android:textColor="?attr/textColor" tools:ignore="ContentDescription"
tools:ignore="ContentDescription" /> tools:visibility="visible" />
</FrameLayout> </FrameLayout>

View file

@ -25,108 +25,7 @@
app:titleTextColor="?attr/textColor" app:titleTextColor="?attr/textColor"
tools:title="Overlord" /> tools:title="Overlord" />
<HorizontalScrollView <include layout="@layout/tvtypes_chips_scroll" />
android:id="@+id/tv_types_scroll_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/primaryGrayBackground"
android:clipToPadding="true"
android:fadingEdge="horizontal"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:requiresFadingEdge="horizontal"
app:layout_scrollFlags="scroll|enterAlways">
<!-- Man what the fuck we need a recyclerview -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- android:minWidth="0dp"
app:iconTint="?attr/textColor"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
app:iconGravity="textStart"
app:iconPadding="0dp"
android:layout_height="35dp"-->
<!-- <com.google.android.material.button.MaterialButton
android:nextFocusRight="@id/home_select_tv_series"
app:icon="@drawable/ic_baseline_close_24"
android:id="@+id/home_select_none"
style="@style/RoundedSelectableButtonIcon"/>-->
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_movies"
style="@style/RoundedSelectableButton"
android:nextFocusRight="@id/home_select_tv_series"
android:text="@string/movies" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_tv_series"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_movies"
android:nextFocusRight="@id/home_select_anime"
android:text="@string/tv_series" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_anime"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_tv_series"
android:nextFocusRight="@id/home_select_asian"
android:text="@string/anime" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_asian"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_anime"
android:nextFocusRight="@id/home_select_cartoons"
android:text="@string/asian_drama" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_cartoons"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_asian"
android:nextFocusRight="@id/home_select_documentaries"
android:text="@string/cartoons" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_documentaries"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_cartoons"
android:nextFocusRight="@id/home_select_livestreams"
android:text="@string/documentaries" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_livestreams"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_documentaries"
android:nextFocusRight="@id/home_select_nsfw"
android:text="@string/livestreams" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_nsfw"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_livestreams"
android:nextFocusRight="@id/home_select_nsfw"
android:text="@string/nsfw" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_others"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_nsfw"
android:text="@string/others" />
</LinearLayout>
</HorizontalScrollView>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView

View file

@ -82,86 +82,7 @@
app:tint="?attr/textColor" /> app:tint="?attr/textColor" />
</FrameLayout> </FrameLayout>
<HorizontalScrollView <include layout="@layout/tvtypes_chips_scroll" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fadingEdge="horizontal"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:requiresFadingEdge="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="@+id/search_select_movies"
style="@style/RoundedSelectableButton"
android:nextFocusRight="@id/search_select_tv_series"
android:text="@string/movies" />
<com.google.android.material.button.MaterialButton
android:id="@+id/search_select_tv_series"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/search_select_movies"
android:nextFocusRight="@id/search_select_anime"
android:text="@string/tv_series" />
<com.google.android.material.button.MaterialButton
android:id="@+id/search_select_anime"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/search_select_tv_series"
android:nextFocusRight="@id/search_select_asian"
android:text="@string/anime" />
<com.google.android.material.button.MaterialButton
android:id="@+id/search_select_asian"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/search_select_anime"
android:nextFocusRight="@id/search_select_cartoons"
android:text="@string/asian_drama" />
<com.google.android.material.button.MaterialButton
android:id="@+id/search_select_cartoons"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/search_select_asian"
android:nextFocusRight="@id/search_select_documentaries"
android:text="@string/cartoons" />
<com.google.android.material.button.MaterialButton
android:id="@+id/search_select_documentaries"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/search_select_cartoons"
android:nextFocusRight="@id/search_select_livestreams"
android:text="@string/documentaries" />
<com.google.android.material.button.MaterialButton
android:id="@+id/search_select_livestreams"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/search_select_documentaries"
android:nextFocusRight="@id/search_select_nsfw"
android:text="@string/livestreams" />
<com.google.android.material.button.MaterialButton
android:id="@+id/search_select_nsfw"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/search_select_livestreams"
android:nextFocusRight="@id/search_select_others"
android:text="@string/nsfw" />
<com.google.android.material.button.MaterialButton
android:id="@+id/search_select_others"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/search_select_nsfw"
android:text="@string/others" />
</LinearLayout>
</HorizontalScrollView>
<com.lagradost.cloudstream3.ui.AutofitRecyclerView <com.lagradost.cloudstream3.ui.AutofitRecyclerView

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -10,143 +10,47 @@
android:id="@+id/listview1" android:id="@+id/listview1"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:nestedScrollingEnabled="true"
android:layout_rowWeight="1" android:layout_rowWeight="1"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:layout_marginBottom="60dp" android:layout_marginBottom="60dp"
android:clipToPadding="false" android:clipToPadding="false"
android:minHeight="0dp" android:minHeight="0dp"
android:nestedScrollingEnabled="true"
android:nextFocusLeft="@id/apply_btt" android:nextFocusLeft="@id/apply_btt"
android:nextFocusRight="@id/cancel_btt" android:nextFocusRight="@id/cancel_btt"
android:requiresFadingEdge="vertical" android:requiresFadingEdge="vertical"
tools:listitem="@layout/sort_bottom_single_choice" /> tools:listitem="@layout/sort_bottom_single_choice" />
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="-60dp"
android:clipToPadding="true"
android:fadingEdge="horizontal"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:requiresFadingEdge="horizontal">
<!-- Man what the fuck we need a recyclerview -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- android:minWidth="0dp"
app:iconTint="?attr/textColor"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
app:iconGravity="textStart"
app:iconPadding="0dp"
android:layout_height="35dp"-->
<!-- <com.google.android.material.button.MaterialButton
android:nextFocusRight="@id/home_select_tv_series"
app:icon="@drawable/ic_baseline_close_24"
android:id="@+id/home_select_none"
style="@style/RoundedSelectableButtonIcon"/>-->
<!--
If you reorder this fix getPairList() too!
That shit is responsible for focus selection
-->
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_movies"
style="@style/RoundedSelectableButton"
android:nextFocusRight="@id/home_select_tv_series"
android:text="@string/movies" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_tv_series"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_movies"
android:nextFocusRight="@id/home_select_anime"
android:text="@string/tv_series" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_anime"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_tv_series"
android:nextFocusRight="@id/home_select_asian"
android:text="@string/anime" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_asian"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_anime"
android:nextFocusRight="@id/home_select_cartoons"
android:text="@string/asian_drama" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_cartoons"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_asian"
android:nextFocusRight="@id/home_select_documentaries"
android:text="@string/cartoons" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_documentaries"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_cartoons"
android:nextFocusRight="@id/home_select_livestreams"
android:text="@string/documentaries" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_livestreams"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_documentaries"
android:nextFocusRight="@id/home_select_nsfw"
android:text="@string/livestreams" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_nsfw"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_livestreams"
android:nextFocusRight="@id/home_select_others"
android:text="@string/nsfw" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_select_others"
style="@style/RoundedSelectableButton"
android:nextFocusLeft="@id/home_select_nsfw"
android:text="@string/others" />
</LinearLayout>
</HorizontalScrollView>
<LinearLayout <LinearLayout
android:id="@+id/apply_btt_holder" android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:gravity="bottom|end" android:layout_width="match_parent"
android:orientation="horizontal" android:layout_height="60dp">
android:visibility="gone"> <include layout="@layout/tvtypes_chips_scroll" />
<LinearLayout
android:id="@+id/apply_btt_holder"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="-60dp"
android:layout_gravity="bottom"
android:gravity="bottom|end"
android:orientation="horizontal"
android:visibility="gone">
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/apply_btt" android:id="@+id/apply_btt"
style="@style/WhiteButton" style="@style/WhiteButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_gravity="center_vertical|end" android:layout_gravity="center_vertical|end"
android:text="@string/sort_apply" /> android:text="@string/sort_apply" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/cancel_btt" android:id="@+id/cancel_btt"
style="@style/BlackButton" style="@style/BlackButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_gravity="center_vertical|end" android:layout_gravity="center_vertical|end"
android:text="@string/sort_cancel" /> android:text="@string/sort_cancel" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout>
</FrameLayout>

View file

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.chip.ChipGroup android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:id="@+id/home_select_group"
app:singleSelection="false"
xmlns:android="http://schemas.android.com/apk/res/android">
<com.google.android.material.chip.Chip
android:id="@+id/home_select_movies"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/movies" />
<com.google.android.material.chip.Chip
android:id="@+id/home_select_tv_series"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tv_series" />
<com.google.android.material.chip.Chip
android:id="@+id/home_select_anime"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/anime" />
<com.google.android.material.chip.Chip
android:id="@+id/home_select_asian"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/asian_drama" />
<com.google.android.material.chip.Chip
android:id="@+id/home_select_cartoons"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cartoons" />
<com.google.android.material.chip.Chip
android:id="@+id/home_select_documentaries"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/documentaries" />
<com.google.android.material.chip.Chip
android:id="@+id/home_select_livestreams"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/livestreams" />
<com.google.android.material.chip.Chip
android:id="@+id/home_select_nsfw"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/nsfw" />
<com.google.android.material.chip.Chip
android:id="@+id/home_select_others"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/others" />
</com.google.android.material.chip.ChipGroup>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView android:id="@+id/tv_types_scroll_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fadingEdge="horizontal"
android:requiresFadingEdge="horizontal"
xmlns:android="http://schemas.android.com/apk/res/android">
<include layout="@layout/tvtypes_chips" />
</HorizontalScrollView>

View file

@ -75,6 +75,10 @@
<item name="primaryGrayBackground">@color/amoledModeLight</item> <item name="primaryGrayBackground">@color/amoledModeLight</item>
</style> </style>
<style name="ChipFilled" parent="@style/Widget.Material3.Chip.Filter">
<item name="chipBackgroundColor">@color/chip_color</item>
</style>
<style name="AmoledMode"> <style name="AmoledMode">
<item name="primaryGrayBackground">@color/black</item> <item name="primaryGrayBackground">@color/black</item>
<item name="primaryBlackBackground">@color/black</item> <item name="primaryBlackBackground">@color/black</item>