tv UI change + homepage optimization

This commit is contained in:
LagradOst 2022-12-28 12:51:55 +01:00
parent 4f4061961a
commit 2a32f62fe3
31 changed files with 2012 additions and 1362 deletions

View File

@ -138,7 +138,7 @@ class ExampleInstrumentedTest {
}
break
}
if(!validResults) {
if (!validResults) {
System.err.println("Api ${api.name} did not load on any")
}
@ -183,7 +183,9 @@ class ExampleInstrumentedTest {
getAllProviders().amap { api ->
if (api.hasMainPage) {
try {
val homepage = api.getMainPage()
val f = api.mainPage.first()
val homepage =
api.getMainPage(1, MainPageRequest(f.name, f.data, f.horizontalImages))
when {
homepage == null -> {
System.err.println("Homepage provider ${api.name} did not correctly load homepage!")
@ -192,7 +194,7 @@ class ExampleInstrumentedTest {
System.err.println("Homepage provider ${api.name} does not contain any items!")
}
homepage.items.any { it.list.isEmpty() } -> {
System.err.println ("Homepage provider ${api.name} does not have any items on result!")
System.err.println("Homepage provider ${api.name} does not have any items on result!")
}
}
} catch (e: Exception) {
@ -231,7 +233,7 @@ class ExampleInstrumentedTest {
invalidProvider.add(Pair(api, e))
}
}
if(invalidProvider.isEmpty()) {
if (invalidProvider.isEmpty()) {
println("No Invalid providers! :D")
} else {
println("Invalid providers are: ")

View File

@ -0,0 +1,11 @@
package com.lagradost.cloudstream3
import android.view.LayoutInflater
import androidx.annotation.LayoutRes
import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.ui.HeaderViewDecoration
fun setHeaderDecoration(view: RecyclerView, @LayoutRes headerViewRes: Int) {
val headerView = LayoutInflater.from(view.context).inflate(headerViewRes, null)
view.addItemDecoration(HeaderViewDecoration(headerView))
}

View File

@ -10,12 +10,18 @@ import android.view.KeyEvent
import android.view.Menu
import android.view.MenuItem
import android.view.WindowManager
import android.widget.FrameLayout
import android.widget.LinearLayout
import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.IdRes
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import androidx.core.view.marginRight
import androidx.core.view.setMargins
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentContainerView
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hierarchy
@ -66,6 +72,7 @@ import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings
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.updateTv
import com.lagradost.cloudstream3.ui.settings.SettingsGeneral
import com.lagradost.cloudstream3.ui.setup.HAS_DONE_SETUP_KEY
import com.lagradost.cloudstream3.ui.setup.SetupFragmentExtensions
@ -89,6 +96,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.getResourceColor
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
import com.lagradost.cloudstream3.utils.UIHelper.navigate
import com.lagradost.cloudstream3.utils.UIHelper.requestRW
import com.lagradost.cloudstream3.utils.UIHelper.toPx
import com.lagradost.cloudstream3.utils.USER_PROVIDER_API
import com.lagradost.cloudstream3.utils.USER_SELECTED_HOMEPAGE_API
import com.lagradost.nicehttp.Requests
@ -379,6 +387,27 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
R.id.navigation_settings_plugins,
).contains(destination.id)
val dontPush = listOf(
R.id.navigation_home,
R.id.navigation_search,
R.id.navigation_results_phone,
R.id.navigation_results_tv,
R.id.navigation_player,
).contains(destination.id)
nav_host_fragment?.apply {
val params = layoutParams as ConstraintLayout.LayoutParams
params.setMargins(
if (!dontPush && isTvSettings()) resources.getDimensionPixelSize(R.dimen.navbar_width) else 0,
params.topMargin,
params.rightMargin,
params.bottomMargin
)
layoutParams = params
}
val landscape = when (resources.configuration.orientation) {
Configuration.ORIENTATION_LANDSCAPE -> {
true
@ -619,7 +648,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
}
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
updateTv()
if (isTvSettings()) {
setContentView(R.layout.activity_main_tv)
} else {
@ -743,7 +772,12 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
nav_view?.setupWithNavController(navController)
val nav_rail = findViewById<NavigationRailView?>(R.id.nav_rail_view)
nav_rail?.setupWithNavController(navController)
if (isTvSettings()) {
nav_rail?.background?.alpha = 200
} else {
nav_rail?.background?.alpha = 255
}
nav_rail?.setOnItemSelectedListener { item ->
onNavDestinationSelected(
item,

View File

@ -0,0 +1,42 @@
package com.lagradost.cloudstream3.ui
import android.graphics.Canvas
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.RecyclerView
class HeaderViewDecoration(private val customView: View) : RecyclerView.ItemDecoration() {
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDraw(c, parent, state)
customView.layout(parent.left, 0, parent.right, customView.measuredHeight)
for (i in 0 until parent.childCount) {
val view = parent.getChildAt(i)
if (parent.getChildAdapterPosition(view) == 0) {
c.save()
val height = customView.measuredHeight
val top = view.top - height
c.translate(0f, top.toFloat())
customView.draw(c)
c.restore()
break
}
}
}
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
if (parent.getChildAdapterPosition(view) == 0) {
customView.measure(
View.MeasureSpec.makeMeasureSpec(parent.measuredWidth, View.MeasureSpec.AT_MOST),
View.MeasureSpec.makeMeasureSpec(parent.measuredHeight, View.MeasureSpec.AT_MOST)
)
outRect.set(0, customView.measuredHeight, 0, 0)
} else {
outRect.setEmpty()
}
}
}

View File

@ -31,6 +31,7 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton
import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipDrawable
import com.google.android.material.chip.ChipGroup
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.APIHolder.apis
@ -84,31 +85,21 @@ import com.lagradost.cloudstream3.utils.UIHelper.setImage
import com.lagradost.cloudstream3.utils.UIHelper.setImageBlur
import com.lagradost.cloudstream3.utils.USER_SELECTED_HOMEPAGE_API
import com.lagradost.cloudstream3.widget.CenterZoomLayoutManager
import kotlinx.android.synthetic.main.activity_main_tv.*
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.android.synthetic.main.fragment_home.home_api_fab
import kotlinx.android.synthetic.main.fragment_home.home_bookmarked_child_recyclerview
import kotlinx.android.synthetic.main.fragment_home.home_bookmarked_holder
import kotlinx.android.synthetic.main.fragment_home.home_change_api_loading
import kotlinx.android.synthetic.main.fragment_home.home_loaded
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_shimmer
import kotlinx.android.synthetic.main.fragment_home.home_loading_statusbar
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_provider_meta_info
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_connectionerror
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_on_hold_btt
import kotlinx.android.synthetic.main.fragment_home.home_type_watching_btt
import kotlinx.android.synthetic.main.fragment_home.home_watch_child_recyclerview
import kotlinx.android.synthetic.main.fragment_home.home_watch_holder
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_head_tv.*
import kotlinx.android.synthetic.main.fragment_home_tv.*
import kotlinx.android.synthetic.main.fragment_result.*
import kotlinx.android.synthetic.main.fragment_search.*
import kotlinx.android.synthetic.main.home_episodes_expanded.*
import kotlinx.android.synthetic.main.tvtypes_chips.*
@ -440,10 +431,6 @@ class HomeFragment : Fragment() {
return inflater.inflate(layout, container, false)
}
private fun toggleMainVisibility(visible: Boolean) {
home_main_poster_recyclerview?.isVisible = visible
}
@SuppressLint("NotifyDataSetChanged") // we need to notify to change poster
private fun fixGrid() {
activity?.getSpanCount()?.let {
@ -467,7 +454,7 @@ class HomeFragment : Fragment() {
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
(home_preview_viewpager?.adapter as? HomeScrollAdapter)?.notifyDataSetChanged()
//(home_preview_viewpager?.adapter as? HomeScrollAdapter)?.notifyDataSetChanged()
fixGrid()
}
@ -517,8 +504,9 @@ class HomeFragment : Fragment() {
}*/
private fun focusCallback(card: SearchResponse) {
home_focus_text?.text = card.name
home_blur_poster?.setImageBlur(card.posterUrl, 50)
// home_focus_text?.text = card.name
// home_blur_poster?.setImageBlur(card.posterUrl, 50, headers = card.posterHeaders)
// home_bg_poster?.setImage(card.posterUrl,headers =card.posterHeaders)
}
private fun homeHandleSearch(callback: SearchClickCallback) {
@ -537,8 +525,8 @@ class HomeFragment : Fragment() {
super.onViewCreated(view, savedInstanceState)
fixGrid()
home_change_api?.setOnClickListener(apiChangeClickListener)
home_change_api_loading?.setOnClickListener(apiChangeClickListener)
home_preview_change_api?.setOnClickListener(apiChangeClickListener)
home_api_fab?.setOnClickListener(apiChangeClickListener)
home_random?.setOnClickListener {
if (listHomepageItems.isNotEmpty()) {
@ -557,208 +545,135 @@ class HomeFragment : Fragment() {
observe(homeViewModel.preview) { preview ->
// Always reset the padding, otherwise the will move lower and lower
// home_fix_padding?.setPadding(0, 0, 0, 0)
home_fix_padding?.let { v ->
val params = v.layoutParams
params.height = 0
v.layoutParams = params
}
//home_fix_padding?.let { v ->
// val params = v.layoutParams
// params.height = 0
// v.layoutParams = params
//}
when (preview) {
is Resource.Success -> {
home_preview?.isVisible = true
(home_preview_viewpager?.adapter as? HomeScrollAdapter)?.apply {
if (!setItems(preview.value.second, preview.value.first)) {
home_preview_viewpager?.setCurrentItem(0, false)
}
// home_preview_viewpager?.setCurrentItem(1000, false)
}
(home_master_recycler?.adapter as? HomeParentItemAdapterPreview?)?.setPreviewData(
preview
)
//.also {
//home_preview_viewpager?.adapter =
//}
}
else -> {
(home_preview_viewpager?.adapter as? HomeScrollAdapter)?.setItems(
listOf(),
false
)
home_preview?.isVisible = false
context?.fixPaddingStatusbarView(home_fix_padding)
}
}
//when (preview) {
// is Resource.Success -> {
// home_preview?.isVisible = true
// (home_preview_viewpager?.adapter as? HomeScrollAdapter)?.apply {
// if (!setItems(preview.value.second, preview.value.first)) {
// home_preview_viewpager?.setCurrentItem(0, false)
// }
// // home_preview_viewpager?.setCurrentItem(1000, false)
// }
//
// //.also {
// //home_preview_viewpager?.adapter =
// //}
// }
// else -> {
// (home_preview_viewpager?.adapter as? HomeScrollAdapter)?.setItems(
// listOf(),
// false
// )
// home_preview?.isVisible = false
// context?.fixPaddingStatusbarView(home_fix_padding)
// }
//}
}
val searchText =
home_search?.findViewById<SearchView.SearchAutoComplete>(androidx.appcompat.R.id.search_src_text)
searchText?.context?.getResourceColor(R.attr.white)?.let { color ->
searchText.setTextColor(color)
searchText.setHintTextColor(color)
}
home_preview_viewpager?.apply {
setPageTransformer(HomeScrollTransformer())
val callback: OnPageChangeCallback = object : OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
// home_search?.isIconified = true
//home_search?.isVisible = true
//home_search?.clearFocus()
(home_preview_viewpager?.adapter as? HomeScrollAdapter)?.apply {
if (position >= itemCount - 1 && hasMoreItems) {
hasMoreItems = false // dont make two requests
homeViewModel.loadMoreHomeScrollResponses()
}
getItem(position)
?.apply {
home_preview_title_holder?.let { parent ->
TransitionManager.beginDelayedTransition(parent, ChangeBounds())
}
// 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(this.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(this.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(this, newValue)
reloadStored()
}
}
}
}
}
}
registerOnPageChangeCallback(callback)
adapter = HomeScrollAdapter()
}
//val searchText =
// home_search?.findViewById<SearchView.SearchAutoComplete>(androidx.appcompat.R.id.search_src_text)
//searchText?.context?.getResourceColor(R.attr.white)?.let { color ->
// searchText.setTextColor(color)
// searchText.setHintTextColor(color)
//}
observe(homeViewModel.apiName) { apiName ->
currentApiName = apiName
// setKey(USER_SELECTED_HOMEPAGE_API, apiName)
home_api_fab?.text = apiName
home_provider_name?.text = apiName
try {
home_search?.queryHint = getString(R.string.search_hint_site).format(apiName)
} catch (e: Exception) {
logError(e)
}
home_provider_meta_info?.isVisible = false
//home_provider_name?.text = apiName
// try {
// home_search?.queryHint = getString(R.string.search_hint_site).format(apiName)
// } catch (e: Exception) {
// logError(e)
// }
//home_provider_meta_info?.isVisible = false
getApiFromNameNull(apiName)?.let { currentApi ->
val typeChoices = listOf(
Pair(R.string.movies, listOf(TvType.Movie)),
Pair(R.string.tv_series, listOf(TvType.TvSeries)),
Pair(R.string.documentaries, listOf(TvType.Documentary)),
Pair(R.string.cartoons, listOf(TvType.Cartoon)),
Pair(R.string.anime, listOf(TvType.Anime, TvType.OVA, TvType.AnimeMovie)),
Pair(R.string.torrent, listOf(TvType.Torrent)),
Pair(R.string.asian_drama, listOf(TvType.AsianDrama)),
).filter { item -> currentApi.supportedTypes.any { type -> item.second.contains(type) } }
home_provider_meta_info?.text =
typeChoices.joinToString(separator = ", ") { getString(it.first) }
home_provider_meta_info?.isVisible = true
}
//getApiFromNameNull(apiName)?.let { currentApi ->
// val typeChoices = listOf(
// Pair(R.string.movies, listOf(TvType.Movie)),
// Pair(R.string.tv_series, listOf(TvType.TvSeries)),
// Pair(R.string.documentaries, listOf(TvType.Documentary)),
// Pair(R.string.cartoons, listOf(TvType.Cartoon)),
// Pair(R.string.anime, listOf(TvType.Anime, TvType.OVA, TvType.AnimeMovie)),
// Pair(R.string.torrent, listOf(TvType.Torrent)),
// Pair(R.string.asian_drama, listOf(TvType.AsianDrama)),
// ).filter { item -> currentApi.supportedTypes.any { type -> item.second.contains(type) } }
// home_provider_meta_info?.text =
// typeChoices.joinToString(separator = ", ") { getString(it.first) }
// home_provider_meta_info?.isVisible = true
//}
}
home_main_poster_recyclerview?.adapter =
HomeChildItemAdapter(
mutableListOf(),
R.layout.home_result_big_grid,
nextFocusUp = home_main_poster_recyclerview?.nextFocusUpId,
nextFocusDown = home_main_poster_recyclerview?.nextFocusDownId
) { callback ->
homeHandleSearch(callback)
}
home_main_poster_recyclerview?.setLinearListLayout()
observe(homeViewModel.randomItems) { items ->
if (items.isNullOrEmpty()) {
toggleMainVisibility(false)
} else {
val tempAdapter = home_main_poster_recyclerview?.adapter as? HomeChildItemAdapter?
// no need to reload if it has the same data
if (tempAdapter != null && tempAdapter.cardList == items) {
toggleMainVisibility(true)
return@observe
}
//home_main_poster_recyclerview?.adapter =
// HomeChildItemAdapter(
// mutableListOf(),
// R.layout.home_result_big_grid,
// nextFocusUp = home_main_poster_recyclerview?.nextFocusUpId,
// nextFocusDown = home_main_poster_recyclerview?.nextFocusDownId
// ) { callback ->
// homeHandleSearch(callback)
// }
//home_main_poster_recyclerview?.setLinearListLayout()
//observe(homeViewModel.randomItems) { items ->
// if (items.isNullOrEmpty()) {
// toggleMainVisibility(false)
// } else {
// val tempAdapter = home_main_poster_recyclerview?.adapter as? HomeChildItemAdapter?
// // no need to reload if it has the same data
// if (tempAdapter != null && tempAdapter.cardList == items) {
// toggleMainVisibility(true)
// return@observe
// }
//
// val randomSize = items.size
// tempAdapter?.updateList(items)
// if (!isTvSettings()) {
// home_main_poster_recyclerview?.post {
// (home_main_poster_recyclerview?.layoutManager as CenterZoomLayoutManager?)?.let { manager ->
// manager.updateSize(forceUpdate = true)
// if (randomSize > 2) {
// manager.scrollToPosition(randomSize / 2)
// manager.snap { dx ->
// home_main_poster_recyclerview?.post {
// // this is the best I can do, fuck android for not including instant scroll
// home_main_poster_recyclerview?.smoothScrollBy(dx, 0)
// }
// }
// }
// }
// }
// } else {
// items.firstOrNull()?.let {
// focusCallback(it)
// }
// }
// toggleMainVisibility(true)
// }
//}
val randomSize = items.size
tempAdapter?.updateList(items)
if (!isTvSettings()) {
home_main_poster_recyclerview?.post {
(home_main_poster_recyclerview?.layoutManager as CenterZoomLayoutManager?)?.let { manager ->
manager.updateSize(forceUpdate = true)
if (randomSize > 2) {
manager.scrollToPosition(randomSize / 2)
manager.snap { dx ->
home_main_poster_recyclerview?.post {
// this is the best I can do, fuck android for not including instant scroll
home_main_poster_recyclerview?.smoothScrollBy(dx, 0)
}
}
}
}
}
} else {
items.firstOrNull()?.let {
focusCallback(it)
}
}
toggleMainVisibility(true)
}
}
home_search?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
QuickSearchFragment.pushSearch(activity, query, currentApiName?.let { arrayOf(it) })
return true
}
override fun onQueryTextChange(newText: String): Boolean {
//searchViewModel.quickSearch(newText)
return true
}
})
//home_search?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
// override fun onQueryTextSubmit(query: String): Boolean {
// QuickSearchFragment.pushSearch(activity, query, currentApiName?.let { arrayOf(it) })
//
// return true
// }
//
// override fun onQueryTextChange(newText: String): Boolean {
// //searchViewModel.quickSearch(newText)
// return true
// }
//})
observe(homeViewModel.page) { data ->
when (data) {
@ -769,7 +684,6 @@ class HomeFragment : Fragment() {
val mutableListOfResponse = mutableListOf<SearchResponse>()
listHomepageItems.clear()
// println("ITEMCOUNT: ${d.values.size} ${home_master_recycler?.adapter?.itemCount}")
(home_master_recycler?.adapter as? ParentItemAdapter?)?.updateList(
d.values.toMutableList(),
home_master_recycler
@ -777,7 +691,7 @@ class HomeFragment : Fragment() {
home_loading?.isVisible = false
home_loading_error?.isVisible = false
home_loaded?.isVisible = true
//home_loaded?.isVisible = true
if (toggleRandomButton) {
//Flatten list
d.values.forEach { dlist ->
@ -817,80 +731,29 @@ class HomeFragment : Fragment() {
home_loading?.isVisible = false
home_loading_error?.isVisible = true
home_loaded?.isVisible = false
//home_loaded?.isVisible = false
}
is Resource.Loading -> {
(home_master_recycler?.adapter as? ParentItemAdapter?)?.updateList(listOf())
home_loading_shimmer?.startShimmer()
home_loading?.isVisible = true
home_loading_error?.isVisible = false
home_loaded?.isVisible = false
//home_loaded?.isVisible = false
}
}
}
val toggleList = listOf(
Pair(home_type_watching_btt, WatchType.WATCHING),
Pair(home_type_completed_btt, WatchType.COMPLETED),
Pair(home_type_dropped_btt, WatchType.DROPPED),
Pair(home_type_on_hold_btt, WatchType.ONHOLD),
Pair(home_plan_to_watch_btt, WatchType.PLANTOWATCH),
)
val currentSet = getKey<IntArray>(HOME_BOOKMARK_VALUE_LIST)
?.map { WatchType.fromInternalId(it) }?.toSet() ?: emptySet()
for ((chip, watch) in toggleList) {
chip.isChecked = currentSet.contains(watch)
chip?.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
homeViewModel.loadStoredData(
setOf(watch)
// If we filter all buttons then two can be checked at the same time
// Revert this if you want to go back to multi selection
// toggleList.filter { it.first?.isChecked == true }.map { it.second }.toSet()
)
}
// Else if all are unchecked -> Do not load data
else if (toggleList.all { it.first?.isChecked != true }) {
homeViewModel.loadStoredData(emptySet())
}
}
/*chip?.setOnClickListener {
homeViewModel.loadStoredData(EnumSet.of(watch))
}
chip?.setOnLongClickListener { itemView ->
val list = EnumSet.noneOf(WatchType::class.java)
itemView.context.getKey<IntArray>(HOME_BOOKMARK_VALUE_LIST)
?.map { WatchType.fromInternalId(it) }?.let {
list.addAll(it)
}
if (list.contains(watch)) {
list.remove(watch)
} else {
list.add(watch)
}
homeViewModel.loadStoredData(list)
return@setOnLongClickListener true
}*/
}
observe(homeViewModel.availableWatchStatusTypes) { availableWatchStatusTypes ->
context?.setKey(
HOME_BOOKMARK_VALUE_LIST,
availableWatchStatusTypes.first.map { it.internalId }.toIntArray()
)
(home_master_recycler?.adapter as? HomeParentItemAdapterPreview?)?.setAvailableWatchStatusTypes(
availableWatchStatusTypes
)
for (item in toggleList) {
val watch = item.second
item.first?.apply {
isVisible = availableWatchStatusTypes.second.contains(watch)
isSelected = availableWatchStatusTypes.first.contains(watch)
}
}
/*home_bookmark_select?.setOnClickListener {
it.popupMenuNoIcons(availableWatchStatusTypes.second.map { type ->
@ -905,32 +768,40 @@ class HomeFragment : Fragment() {
home_bookmarked_parent_item_title?.text = getString(availableWatchStatusTypes.first.stringRes)*/
}
observe(homeViewModel.bookmarks) { (isVis, bookmarks) ->
home_bookmarked_holder.isVisible = isVis
(home_bookmarked_child_recyclerview?.adapter as? HomeChildItemAdapter?)?.updateList(
bookmarks
//TODO REMAKE
observe(homeViewModel.bookmarks) { data ->
(home_master_recycler?.adapter as? HomeParentItemAdapterPreview?)?.setBookmarkData(
data
)
home_bookmarked_child_more_info?.setOnClickListener {
activity?.loadHomepageList(
HomePageList(
getString(R.string.error_bookmarks_text), //home_bookmarked_parent_item_title?.text?.toString() ?: getString(R.string.error_bookmarks_text),
bookmarks
)
) {
deleteAllBookmarkedData()
homeViewModel.loadStoredData(null)
}
}
//(home_bookmarked_child_recyclerview?.adapter as? HomeChildItemAdapter?)?.updateList(
// bookmarks
//)
//
// home_bookmarked_child_more_info?.setOnClickListener {
// activity?.loadHomepageList(
// HomePageList(
// getString(R.string.error_bookmarks_text), //home_bookmarked_parent_item_title?.text?.toString() ?: getString(R.string.error_bookmarks_text),
// bookmarks
// )
// ) {
// deleteAllBookmarkedData()
// homeViewModel.loadStoredData(null)
// }
// }
}
observe(homeViewModel.resumeWatching) { resumeWatching ->
home_watch_holder?.isVisible = resumeWatching.isNotEmpty()
(home_watch_child_recyclerview?.adapter as? HomeChildItemAdapter?)?.updateList(
(home_master_recycler?.adapter as? HomeParentItemAdapterPreview?)?.setResumeWatchingData(
resumeWatching
)
//home_watch_holder?.isVisible = resumeWatching.isNotEmpty()
//(home_watch_child_recyclerview?.adapter as? HomeChildItemAdapter?)?.updateList(
// resumeWatching
//)
if (isTrueTvSettings()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ioSafe {
@ -939,21 +810,21 @@ class HomeFragment : Fragment() {
}
}
home_watch_child_more_info?.setOnClickListener {
activity?.loadHomepageList(
HomePageList(
home_watch_parent_item_title?.text?.toString()
?: getString(R.string.continue_watching),
resumeWatching
)
) {
deleteAllResumeStateIds()
homeViewModel.loadResumeWatching()
}
}
//home_watch_child_more_info?.setOnClickListener {
// activity?.loadHomepageList(
// HomePageList(
// home_watch_parent_item_title?.text?.toString()
// ?: getString(R.string.continue_watching),
// resumeWatching
// )
// ) {
// deleteAllResumeStateIds()
// homeViewModel.loadResumeWatching()
// }
//}
}
home_bookmarked_child_recyclerview.adapter = HomeChildItemAdapter(
home_bookmarked_child_recyclerview?.adapter = HomeChildItemAdapter(
ArrayList(),
nextFocusUp = home_bookmarked_child_recyclerview?.nextFocusUpId,
nextFocusDown = home_bookmarked_child_recyclerview?.nextFocusDownId
@ -995,26 +866,15 @@ class HomeFragment : Fragment() {
reloadStored()
}
if (isTv) {
when (actionId) {
0 -> {
play()
}
1 -> {
info()
}
2 -> {
remove()
}
when (actionId) {
0 -> {
play()
}
} else {
when (actionId) {
0 -> {
info()
}
1 -> {
remove()
}
1 -> {
info()
}
2 -> {
remove()
}
}
}
@ -1022,8 +882,8 @@ class HomeFragment : Fragment() {
homeHandleSearch(callback)
}
}
home_watch_child_recyclerview.setLinearListLayout()
home_bookmarked_child_recyclerview.setLinearListLayout()
home_watch_child_recyclerview?.setLinearListLayout()
home_bookmarked_child_recyclerview?.setLinearListLayout()
home_watch_child_recyclerview?.adapter = HomeChildItemAdapter(
ArrayList(),
@ -1100,11 +960,11 @@ class HomeFragment : Fragment() {
}
//context?.fixPaddingStatusbarView(home_statusbar)
context?.fixPaddingStatusbar(home_padding)
//context?.fixPaddingStatusbar(home_padding)
context?.fixPaddingStatusbar(home_loading_statusbar)
home_master_recycler.adapter =
ParentItemAdapter(mutableListOf(), { callback ->
home_master_recycler?.adapter =
HomeParentItemAdapterPreview(mutableListOf(), { callback ->
homeHandleSearch(callback)
}, { item ->
activity?.loadHomepageList(item, expandCallback = {
@ -1112,53 +972,68 @@ class HomeFragment : Fragment() {
})
}, { name ->
homeViewModel.expand(name)
}, { load ->
activity?.loadResult(load.response.url, load.response.apiName, load.action)
}, {
homeViewModel.loadMoreHomeScrollResponses()
}, {
apiChangeClickListener.onClick(it)
}, reloadStored = {
reloadStored()
}, loadStoredData = {
homeViewModel.loadStoredData(it)
}, { (isQuickSearch, text) ->
if (!isQuickSearch) {
QuickSearchFragment.pushSearch(
activity,
text,
currentApiName?.let { arrayOf(it) })
}
})
home_master_recycler.setLinearListLayout()
home_master_recycler?.setMaxViewPoolSize(0, Int.MAX_VALUE)
home_master_recycler.layoutManager = object : LinearLayoutManager(context) {
override fun supportsPredictiveItemAnimations(): Boolean {
return false
}
} // GridLayoutManager(context, 1).also { it.supportsPredictiveItemAnimations() }
//home_master_recycler.setLinearListLayout()
//home_master_recycler?.setMaxViewPoolSize(0, 4)
//home_master_recycler.layoutManager = object : LinearLayoutManager(context) {
// override fun supportsPredictiveItemAnimations(): Boolean {
// return false
// }
//} // GridLayoutManager(context, 1).also { it.supportsPredictiveItemAnimations() }
reloadStored()
loadHomePage(false)
home_loaded.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { v, _, scrollY, _, oldScrollY ->
val dy = scrollY - oldScrollY
if (dy > 0) { //check for scroll down
home_api_fab?.shrink() // hide
home_random?.shrink()
} else if (dy < -5) {
if (!isTvSettings()) {
home_api_fab?.extend() // show
home_random?.extend()
}
/*
home_loaded?.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { v, _, scrollY, _, oldScrollY ->
val dy = scrollY - oldScrollY
if (dy > 0) { //check for scroll down
home_api_fab?.shrink() // hide
home_random?.shrink()
} else if (dy < -5) {
if (!isTvSettings()) {
home_api_fab?.extend() // show
home_random?.extend()
}
})
}
})
*/
// nice profile pic on homepage
home_profile_picture_holder?.isVisible = false
//home_profile_picture_holder?.isVisible = false
// just in case
if (isTvSettings()) {
home_api_fab?.isVisible = false
home_change_api?.isVisible = true
if (isTrueTvSettings()) {
home_change_api_loading?.isVisible = true
home_change_api_loading?.isFocusable = true
home_change_api_loading?.isFocusableInTouchMode = true
home_change_api?.isFocusable = true
home_change_api?.isFocusableInTouchMode = true
}
// home_bookmark_select?.isFocusable = true
// home_bookmark_select?.isFocusableInTouchMode = true
} else {
home_api_fab?.isVisible = true
home_change_api?.isVisible = false
home_change_api_loading?.isVisible = false
}
for (syncApi in OAuth2Apis) {
/*for (syncApi in OAuth2Apis) {
val login = syncApi.loginInfo()
val pic = login?.profilePicture
if (home_profile_picture?.setImage(
@ -1169,6 +1044,6 @@ class HomeFragment : Fragment() {
home_profile_picture_holder?.isVisible = true
break
}
}
}*/
}
}

View File

@ -4,34 +4,70 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListUpdateCallback
import androidx.recyclerview.widget.RecyclerView
import androidx.transition.ChangeBounds
import androidx.transition.TransitionManager
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipDrawable
import com.lagradost.cloudstream3.APIHolder.getId
import com.lagradost.cloudstream3.AcraApplication.Companion.getActivity
import com.lagradost.cloudstream3.HomePageList
import com.lagradost.cloudstream3.LoadResponse
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.ui.result.LinearListLayout
import com.lagradost.cloudstream3.ui.result.ResultViewModel2
import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST
import com.lagradost.cloudstream3.ui.result.setLinearListLayout
import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_LOAD
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
import com.lagradost.cloudstream3.ui.search.SearchFragment.Companion.filterSearchResponse
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
import com.lagradost.cloudstream3.utils.AppUtils.isRecyclerScrollable
import com.lagradost.cloudstream3.utils.AppUtils.loadResult
import com.lagradost.cloudstream3.utils.DataStoreHelper
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbarView
import kotlinx.android.synthetic.main.activity_main_tv.*
import kotlinx.android.synthetic.main.activity_main_tv.view.*
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.android.synthetic.main.fragment_home.view.*
import kotlinx.android.synthetic.main.fragment_home_head_tv.*
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.*
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_preview
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_preview_viewpager
import kotlinx.android.synthetic.main.homepage_parent.view.*
class LoadClickCallback(
val action: Int = 0,
val view: View,
val position: Int,
val response: LoadResponse
)
class ParentItemAdapter(
open class ParentItemAdapter(
private var items: MutableList<HomeViewModel.ExpandableHomepageList>,
private val clickCallback: (SearchClickCallback) -> Unit,
private val moreInfoClickCallback: (HomeViewModel.ExpandableHomepageList) -> Unit,
private val expandCallback: ((String) -> Unit)? = null,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, i: Int): ParentViewHolder {
//println("onCreateViewHolder $i")
val layout =
if (isTvSettings()) R.layout.homepage_parent_tv else R.layout.homepage_parent
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return ParentViewHolder(
LayoutInflater.from(parent.context).inflate(layout, parent, false),
LayoutInflater.from(parent.context).inflate(
if (isTvSettings()) R.layout.homepage_parent_tv else R.layout.homepage_parent,
parent,
false
),
clickCallback,
moreInfoClickCallback,
expandCallback
@ -39,8 +75,6 @@ class ParentItemAdapter(
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
//println("onBindViewHolder $position")
when (holder) {
is ParentViewHolder -> {
holder.bind(items[position])
@ -84,7 +118,10 @@ class ParentItemAdapter(
val mAdapter = this
diffResult.dispatchUpdatesTo(object : ListUpdateCallback {
override fun onInserted(position: Int, count: Int) {
mAdapter.notifyItemRangeInserted(position, count)
mAdapter.notifyItemRangeChanged(
position,
count
)//notifyItemRangeInserted(position, count)
}
override fun onRemoved(position: Int, count: Int) {
@ -95,23 +132,32 @@ class ParentItemAdapter(
mAdapter.notifyItemMoved(fromPosition, toPosition)
}
override fun onChanged(position: Int, count: Int, payload: Any?) {
override fun onChanged(_position: Int, count: Int, payload: Any?) {
val delta = if (this@ParentItemAdapter is HomeParentItemAdapterPreview) {
headItems
} else {
0
}
val position = _position + delta
// I know kinda messy, what this does is using the update or bind instead of onCreateViewHolder -> bind
recyclerView?.apply {
// this loops every viewHolder in the recycle view and checks the position to see if it is within the update range
val missingUpdates = (position until (position + count)).toMutableSet()
for (i in 0 until itemCount) {
val viewHolder = getChildViewHolder(getChildAt(i))
val absolutePosition = viewHolder.absoluteAdapterPosition
val child = getChildAt(i) ?: continue
val viewHolder = getChildViewHolder(child) ?: continue
if (viewHolder !is ParentViewHolder) continue
val absolutePosition = viewHolder.bindingAdapterPosition
if (absolutePosition >= position && absolutePosition < position + count) {
val expand = items.getOrNull(absolutePosition) ?: continue
if (viewHolder is ParentViewHolder) {
missingUpdates -= absolutePosition
if (viewHolder.title.text == expand.list.name) {
viewHolder.update(expand)
} else {
viewHolder.bind(expand)
}
val expand = items.getOrNull(absolutePosition - delta) ?: continue
missingUpdates -= absolutePosition
//println("Updating ${viewHolder.title.text} ($absolutePosition $position) -> ${expand.list.name}")
if (viewHolder.title.text == expand.list.name) {
viewHolder.update(expand)
} else {
viewHolder.bind(expand)
}
}
}
@ -120,7 +166,8 @@ class ParentItemAdapter(
for (i in missingUpdates) {
mAdapter.notifyItemChanged(i, payload)
}
} ?: run { // in case we don't have a nice
} ?: run {
// in case we don't have a nice
mAdapter.notifyItemRangeChanged(position, count, payload)
}
}

View File

@ -0,0 +1,581 @@
package com.lagradost.cloudstream3.ui.home
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.appcompat.widget.SearchView
import androidx.core.content.ContextCompat
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipDrawable
import com.lagradost.cloudstream3.APIHolder.getId
import com.lagradost.cloudstream3.AcraApplication
import com.lagradost.cloudstream3.AcraApplication.Companion.getActivity
import com.lagradost.cloudstream3.LoadResponse
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment
import com.lagradost.cloudstream3.ui.result.ResultViewModel2
import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST
import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_LOAD
import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_SHOW_METADATA
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
import com.lagradost.cloudstream3.ui.search.SearchHelper
import com.lagradost.cloudstream3.ui.settings.SettingsFragment
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult
import com.lagradost.cloudstream3.utils.DataStoreHelper
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showOptionSelectStringRes
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.utils.UIHelper.setImage
import kotlinx.android.synthetic.main.activity_main_tv.view.*
import kotlinx.android.synthetic.main.fragment_home_head.view.*
import kotlinx.android.synthetic.main.fragment_home_head.view.home_bookmarked_child_recyclerview
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.*
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_bookmarked_holder
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_plan_to_watch_btt
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_preview
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_preview_viewpager
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_type_completed_btt
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_type_dropped_btt
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_type_on_hold_btt
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_type_watching_btt
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_watch_child_recyclerview
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_watch_holder
import kotlinx.android.synthetic.main.fragment_setup_media.*
import java.util.ArrayList
class HomeParentItemAdapterPreview(
items: MutableList<HomeViewModel.ExpandableHomepageList>,
val clickCallback: (SearchClickCallback) -> Unit,
moreInfoClickCallback: (HomeViewModel.ExpandableHomepageList) -> Unit,
expandCallback: ((String) -> Unit)? = null,
private val loadCallback: (LoadClickCallback) -> Unit,
private val loadMoreCallback: (() -> Unit),
private val changeHomePageCallback: ((View) -> Unit),
private val reloadStored: (() -> Unit),
private val loadStoredData: ((Set<WatchType>) -> Unit),
private val searchQueryCallback: ((Pair<Boolean, String>) -> Unit)
) : ParentItemAdapter(items, clickCallback, moreInfoClickCallback, expandCallback) {
private var previewData: Resource<Pair<Boolean, List<LoadResponse>>> = Resource.Loading()
private var resumeWatchingData: List<SearchResponse> = listOf()
private var bookmarkData: Pair<Boolean, List<SearchResponse>> =
false to listOf()
val headItems = 1
private var availableWatchStatusTypes: Pair<Set<WatchType>, Set<WatchType>> =
setOf<WatchType>() to setOf()
fun setAvailableWatchStatusTypes(data: Pair<Set<WatchType>, Set<WatchType>>) {
availableWatchStatusTypes = data
holder?.setAvailableWatchStatusTypes(data)
}
companion object {
private const val VIEW_TYPE_HEADER = 4815
private const val VIEW_TYPE_ITEM = 1623
}
fun setResumeWatchingData(resumeWatching: List<SearchResponse>) {
resumeWatchingData = resumeWatching
holder?.updateResume(resumeWatchingData)
}
fun setPreviewData(preview: Resource<Pair<Boolean, List<LoadResponse>>>) {
previewData = preview
holder?.updatePreview(preview)
//notifyItemChanged(0)
}
fun setBookmarkData(data: Pair<Boolean, List<SearchResponse>>) {
bookmarkData = data
holder?.updateBookmarks(data)
}
override fun getItemViewType(position: Int) = when (position) {
0 -> VIEW_TYPE_HEADER
else -> VIEW_TYPE_ITEM
}
var holder: HeaderViewHolder? = null
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is HeaderViewHolder -> {
holder.updatePreview(previewData)
holder.updateResume(resumeWatchingData)
holder.updateBookmarks(bookmarkData)
holder.setAvailableWatchStatusTypes(availableWatchStatusTypes)
}
else -> super.onBindViewHolder(holder, position - 1)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
VIEW_TYPE_HEADER -> HeaderViewHolder(
LayoutInflater.from(parent.context).inflate(
if (isTvSettings()) R.layout.fragment_home_head_tv else R.layout.fragment_home_head,
parent,
false
),
loadCallback,
loadMoreCallback,
changeHomePageCallback,
clickCallback,
reloadStored,
loadStoredData,
searchQueryCallback
).also {
this.holder = it
}
VIEW_TYPE_ITEM -> super.onCreateViewHolder(parent, viewType)
else -> error("Unhandled viewType=$viewType")
}
}
override fun getItemCount(): Int {
return super.getItemCount() + headItems
}
override fun getItemId(position: Int): Long {
if (position == 0) return previewData.hashCode().toLong()
return super.getItemId(position - headItems)
}
override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
when (holder) {
is HeaderViewHolder -> {
holder.onViewDetachedFromWindow()
}
else -> super.onViewDetachedFromWindow(holder)
}
}
override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
when (holder) {
is HeaderViewHolder -> {
holder.onViewAttachedToWindow()
}
else -> super.onViewAttachedToWindow(holder)
}
}
class HeaderViewHolder
constructor(
itemView: View,
private val clickCallback: ((LoadClickCallback) -> Unit)?,
private val loadMoreCallback: (() -> Unit),
private val changeHomePageCallback: ((View) -> Unit),
private val searchClickCallback: (SearchClickCallback) -> Unit,
private val reloadStored: () -> Unit,
private val loadStoredData: ((Set<WatchType>) -> Unit),
private val searchQueryCallback: ((Pair<Boolean, String>) -> Unit)
) : RecyclerView.ViewHolder(itemView) {
private var previewAdapter: HomeScrollAdapter? = null
private val previewViewpager: ViewPager2? = itemView.home_preview_viewpager
private val previewHeader: LinearLayout? = itemView.home_preview
private val previewCallback: ViewPager2.OnPageChangeCallback =
object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
// home_search?.isIconified = true
//home_search?.isVisible = true
//home_search?.clearFocus()
previewAdapter?.apply {
if (position >= itemCount - 1 && hasMoreItems) {
hasMoreItems = false // dont make two requests
loadMoreCallback()
//homeViewModel.loadMoreHomeScrollResponses()
}
}
previewAdapter?.getItem(position)
?.apply {
//itemView.home_preview_title_holder?.let { parent ->
// TransitionManager.beginDelayedTransition(
// parent,
// ChangeBounds()
// )
//}
itemView.home_preview_description?.isGone =
this.plot.isNullOrBlank()
itemView.home_preview_description?.text =
this.plot ?: ""
itemView.home_preview_text?.text = this.name
itemView.home_preview_change_api?.text = apiName
itemView.home_preview_change_api?.setOnClickListener { view ->
changeHomePageCallback(view)
}
itemView.home_preview_tags?.apply {
removeAllViews()
tags?.forEach { tag ->
val chip = Chip(context)
val chipDrawable =
ChipDrawable.createFromAttributes(
context,
null,
0,
R.style.ChipFilledSemiTransparent
)
chip.setChipDrawable(chipDrawable)
chip.text = tag
chip.isChecked = false
chip.isCheckable = false
chip.isFocusable = false
chip.isClickable = false
addView(chip)
}
}
itemView.home_preview_tags?.isGone =
tags.isNullOrEmpty()
itemView.home_preview_image?.setImage(
posterUrl,
posterHeaders
)
// itemView.home_preview_title?.text = name
itemView.home_preview_play?.setOnClickListener { view ->
clickCallback?.invoke(
LoadClickCallback(
START_ACTION_RESUME_LATEST,
view,
position,
this
)
)
}
itemView.home_preview_info?.setOnClickListener { view ->
clickCallback?.invoke(
LoadClickCallback(0, view, position, this)
)
}
itemView.home_preview_play_btt?.setOnClickListener { view ->
clickCallback?.invoke(
LoadClickCallback(
START_ACTION_RESUME_LATEST,
view,
position,
this
)
)
}
itemView.home_preview_info_btt?.setOnClickListener { view ->
clickCallback?.invoke(
LoadClickCallback(0, view, position, this)
)
}
itemView.home_preview_hidden_next_focus?.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
previewViewpager?.apply {
setCurrentItem(currentItem + 1, true)
}
itemView.home_preview_info_btt?.requestFocus()
}
}
itemView.home_preview_hidden_prev_focus?.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
previewViewpager?.apply {
if (currentItem <= 0) {
nav_rail_view?.menu?.getItem(0)?.actionView?.requestFocus()
} else {
setCurrentItem(currentItem - 1, true)
itemView.home_preview_play_btt?.requestFocus()
}
}
}
}
// very ugly code, but I dont care
val watchType =
DataStoreHelper.getResultWatchState(this.getId())
itemView.home_preview_bookmark?.setText(watchType.stringRes)
itemView.home_preview_bookmark?.setCompoundDrawablesWithIntrinsicBounds(
null,
ContextCompat.getDrawable(
itemView.home_preview_bookmark.context,
watchType.iconRes
),
null,
null
)
itemView.home_preview_bookmark?.setOnClickListener { fab ->
fab.context.getActivity()?.showBottomDialog(
WatchType.values()
.map { fab.context.getString(it.stringRes) }
.toList(),
DataStoreHelper.getResultWatchState(this.getId()).ordinal,
fab.context.getString(R.string.action_add_to_bookmarks),
showApply = false,
{}) {
val newValue = WatchType.values()[it]
itemView.home_preview_bookmark?.setCompoundDrawablesWithIntrinsicBounds(
null,
ContextCompat.getDrawable(
itemView.home_preview_bookmark.context,
newValue.iconRes
),
null,
null
)
itemView.home_preview_bookmark?.setText(newValue.stringRes)
ResultViewModel2.updateWatchStatus(
this,
newValue
)
reloadStored()
}
}
}
}
}
private var resumeAdapter: HomeChildItemAdapter? = null
private var resumeHolder: View? = itemView.home_watch_holder
private var resumeRecyclerView: RecyclerView? = itemView.home_watch_child_recyclerview
private var bookmarkHolder: View? = itemView.home_bookmarked_holder
private var bookmarkAdapter: HomeChildItemAdapter? = null
private var bookmarkRecyclerView: RecyclerView? =
itemView.home_bookmarked_child_recyclerview
fun onViewDetachedFromWindow() {
previewViewpager?.unregisterOnPageChangeCallback(previewCallback)
}
fun onViewAttachedToWindow() {
previewViewpager?.registerOnPageChangeCallback(previewCallback)
}
private val toggleList = listOf(
Pair(itemView.home_type_watching_btt, WatchType.WATCHING),
Pair(itemView.home_type_completed_btt, WatchType.COMPLETED),
Pair(itemView.home_type_dropped_btt, WatchType.DROPPED),
Pair(itemView.home_type_on_hold_btt, WatchType.ONHOLD),
Pair(itemView.home_plan_to_watch_btt, WatchType.PLANTOWATCH),
)
init {
previewViewpager?.apply {
if (!isTvSettings())
setPageTransformer(HomeScrollTransformer())
else
setPageTransformer(null)
if (adapter == null)
adapter = HomeScrollAdapter(
if (isTvSettings()) R.layout.home_scroll_view_tv else R.layout.home_scroll_view,
if (isTvSettings()) true else null
)
}
previewAdapter = previewViewpager?.adapter as? HomeScrollAdapter?
previewViewpager?.registerOnPageChangeCallback(previewCallback)
if (resumeAdapter == null) {
resumeRecyclerView?.adapter = HomeChildItemAdapter(
ArrayList(),
nextFocusUp = itemView.nextFocusUpId,
nextFocusDown = itemView.nextFocusDownId
) { callback ->
if (callback.action != SEARCH_ACTION_SHOW_METADATA) {
searchClickCallback(callback)
return@HomeChildItemAdapter
}
callback.view.context?.getActivity()?.showOptionSelectStringRes(
callback.view,
callback.card.posterUrl,
listOf(
R.string.action_open_watching,
R.string.action_remove_watching
),
listOf(
R.string.action_open_play,
R.string.action_open_watching,
R.string.action_remove_watching
)
) { (isTv, actionId) ->
when (actionId + if (isTv) 0 else 1) {
// play
0 -> {
searchClickCallback.invoke(
SearchClickCallback(
START_ACTION_RESUME_LATEST,
callback.view,
-1,
callback.card
)
)
reloadStored()
}
//info
1 -> {
searchClickCallback(
SearchClickCallback(
SEARCH_ACTION_LOAD,
callback.view,
-1,
callback.card
)
)
reloadStored()
}
// remove
2 -> {
val card = callback.card
if (card is DataStoreHelper.ResumeWatchingResult) {
DataStoreHelper.removeLastWatched(card.parentId)
reloadStored()
}
}
}
}
}
}
resumeAdapter = resumeRecyclerView?.adapter as? HomeChildItemAdapter
if (bookmarkAdapter == null) {
bookmarkRecyclerView?.adapter = HomeChildItemAdapter(
ArrayList(),
nextFocusUp = itemView.nextFocusUpId,
nextFocusDown = itemView.nextFocusDownId
) { callback ->
if (callback.action != SEARCH_ACTION_SHOW_METADATA) {
searchClickCallback(callback)
return@HomeChildItemAdapter
}
callback.view.context?.getActivity()?.showOptionSelectStringRes(
callback.view,
callback.card.posterUrl,
listOf(
R.string.action_open_watching,
R.string.action_remove_from_bookmarks,
),
listOf(
R.string.action_open_play,
R.string.action_open_watching,
R.string.action_remove_from_bookmarks
)
) { (isTv, actionId) ->
when (actionId + if (isTv) 0 else 1) { // play
0 -> {
searchClickCallback.invoke(
SearchClickCallback(
START_ACTION_RESUME_LATEST,
callback.view,
-1,
callback.card
)
)
reloadStored()
}
1 -> { // info
searchClickCallback(
SearchClickCallback(
SEARCH_ACTION_LOAD,
callback.view,
-1,
callback.card
)
)
reloadStored()
}
2 -> { // remove
DataStoreHelper.setResultWatchState(
callback.card.id,
WatchType.NONE.internalId
)
reloadStored()
}
}
}
}
}
bookmarkAdapter = bookmarkRecyclerView?.adapter as? HomeChildItemAdapter
for ((chip, watch) in toggleList) {
chip?.isChecked = false
chip?.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
loadStoredData(
setOf(watch)
// If we filter all buttons then two can be checked at the same time
// Revert this if you want to go back to multi selection
// toggleList.filter { it.first?.isChecked == true }.map { it.second }.toSet()
)
}
// Else if all are unchecked -> Do not load data
else if (toggleList.all { it.first?.isChecked != true }) {
loadStoredData(emptySet())
}
}
}
itemView.home_search?.context?.fixPaddingStatusbar(itemView.home_search)
itemView.home_search?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
searchQueryCallback.invoke(false to query)
//QuickSearchFragment.pushSearch(activity, query, currentApiName?.let { arrayOf(it) }
return true
}
override fun onQueryTextChange(newText: String): Boolean {
searchQueryCallback.invoke(true to newText)
//searchViewModel.quickSearch(newText)
return true
}
})
}
fun updatePreview(preview: Resource<Pair<Boolean, List<LoadResponse>>>) {
when (preview) {
is Resource.Success -> {
previewHeader?.isVisible = true
if (true != previewAdapter?.setItems(
preview.value.second,
preview.value.first
)
) {
previewViewpager?.setCurrentItem(0, false)
}
}
else -> {
previewHeader?.isVisible = false
previewAdapter?.setItems(listOf(), false)
previewViewpager?.setCurrentItem(0, false)
}
}
}
fun updateResume(resumeWatching: List<SearchResponse>) {
resumeHolder?.isVisible = resumeWatching.isNotEmpty()
resumeAdapter?.updateList(resumeWatching)
}
fun updateBookmarks(data: Pair<Boolean, List<SearchResponse>>) {
bookmarkHolder?.isVisible = true // data.first
bookmarkAdapter?.updateList(data.second)
}
fun setAvailableWatchStatusTypes(availableWatchStatusTypes: Pair<Set<WatchType>, Set<WatchType>>) {
for ((chip, watch) in toggleList) {
chip?.apply {
isVisible = availableWatchStatusTypes.second.contains(watch)
isChecked = availableWatchStatusTypes.first.contains(watch)
}
}
}
}
}

View File

@ -4,16 +4,22 @@ import android.content.res.Configuration
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.core.view.isGone
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.LoadResponse
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.utils.UIHelper.setImage
import kotlinx.android.synthetic.main.fragment_home_head_tv.*
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.*
import kotlinx.android.synthetic.main.home_scroll_view.view.*
class HomeScrollAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
class HomeScrollAdapter(
@LayoutRes val layout: Int = R.layout.home_scroll_view,
private val forceHorizontalPosters: Boolean? = null
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var items: MutableList<LoadResponse> = mutableListOf()
var hasMoreItems: Boolean = false
@ -40,7 +46,8 @@ class HomeScrollAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return CardViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.home_scroll_view, parent, false),
LayoutInflater.from(parent.context).inflate(layout, parent, false),
forceHorizontalPosters
)
}
@ -55,13 +62,15 @@ class HomeScrollAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
class CardViewHolder
constructor(
itemView: View,
private val forceHorizontalPosters: Boolean? = null
) :
RecyclerView.ViewHolder(itemView) {
fun bind(card: LoadResponse) {
card.apply {
val isHorizontal =
itemView.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
(forceHorizontalPosters == true) || ((forceHorizontalPosters != false) && itemView.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE)
val posterUrl = if (isHorizontal) backgroundPosterUrl ?: posterUrl else posterUrl
?: backgroundPosterUrl
itemView.home_scroll_preview_tags?.text = tags?.joinToString("") ?: ""

View File

@ -128,6 +128,7 @@ class HomeViewModel : ViewModel() {
currentWatchTypes.remove(WatchType.NONE)
if (currentWatchTypes.size <= 0) {
_availableWatchStatusTypes.postValue(setOf<WatchType>() to setOf())
_bookmarks.postValue(Pair(false, ArrayList()))
return@launchSafe
}

View File

@ -921,8 +921,6 @@ open class ResultFragment : ResultTrailerPlayer() {
}
result_tag?.removeAllViews()
d.comingSoon.let { soon ->
result_coming_soon?.isVisible = soon
result_data_holder?.isGone = soon
@ -931,6 +929,7 @@ open class ResultFragment : ResultTrailerPlayer() {
val tags = d.tags
result_tag_holder?.isVisible = tags.isNotEmpty()
result_tag?.apply {
removeAllViews()
tags.forEach { tag ->
val chip = Chip(context)
val chipDrawable = ChipDrawable.createFromAttributes(

View File

@ -20,17 +20,23 @@ const val SEARCH_ACTION_SHOW_METADATA = 1
const val SEARCH_ACTION_PLAY_FILE = 2
const val SEARCH_ACTION_FOCUSED = 4
class SearchClickCallback(val action: Int, val view: View, val position : Int, val card: SearchResponse)
class SearchClickCallback(
val action: Int,
val view: View,
val position: Int,
val card: SearchResponse
)
class SearchAdapter(
private val cardList: MutableList<SearchResponse>,
private val resView: AutofitRecyclerView,
private val clickCallback: (SearchClickCallback) -> Unit,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var hasNext : Boolean = false
var hasNext: Boolean = false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layout = if(parent.context.IsBottomLayout()) R.layout.search_result_grid_expanded else R.layout.search_result_grid
val layout =
if (parent.context.IsBottomLayout()) R.layout.search_result_grid_expanded else R.layout.search_result_grid
return CardViewHolder(
LayoutInflater.from(parent.context).inflate(layout, parent, false),
clickCallback,
@ -71,7 +77,8 @@ class SearchAdapter(
val cardView: ImageView = itemView.imageView
private val compactView = false//itemView.context.getGridIsCompact()
private val coverHeight: Int = if (compactView) 80.toPx else (resView.itemWidth / 0.68).roundToInt()
private val coverHeight: Int =
if (compactView) 80.toPx else (resView.itemWidth / 0.68).roundToInt()
fun bind(card: SearchResponse, position: Int) {
if (!compactView) {
@ -88,7 +95,10 @@ class SearchAdapter(
}
}
class SearchResponseDiffCallback(private val oldList: List<SearchResponse>, private val newList: List<SearchResponse>) :
class SearchResponseDiffCallback(
private val oldList: List<SearchResponse>,
private val newList: List<SearchResponse>
) :
DiffUtil.Callback() {
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) =
oldList[oldItemPosition].name == newList[newItemPosition].name

View File

@ -44,6 +44,7 @@ import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.loadHomepageLis
import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.updateChips
import com.lagradost.cloudstream3.ui.home.ParentItemAdapter
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
import com.lagradost.cloudstream3.utils.Coroutines.main
import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.setKey
@ -93,7 +94,11 @@ class SearchFragment : Fragment() {
activity?.window?.setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
)
return inflater.inflate(R.layout.fragment_search, container, false)
return inflater.inflate(
if (isTvSettings()) R.layout.fragment_search_tv else R.layout.fragment_search,
container,
false
)
}
private fun fixGrid() {

View File

@ -99,7 +99,8 @@ object SingleSelectionHelper {
val textView = dialog.text1//.findViewById<TextView>(R.id.text1)!!
val applyButton = dialog.apply_btt//.findViewById<TextView>(R.id.apply_btt)
val cancelButton = dialog.cancel_btt//findViewById<TextView>(R.id.cancel_btt)
val applyHolder = dialog.apply_btt_holder//.findViewById<LinearLayout>(R.id.apply_btt_holder)
val applyHolder =
dialog.apply_btt_holder//.findViewById<LinearLayout>(R.id.apply_btt_holder)
applyHolder?.isVisible = realShowApply
if (!realShowApply) {
@ -249,6 +250,17 @@ object SingleSelectionHelper {
)
}
fun showBottomDialog(
items: List<String>,
selectedIndex: Int,
name: String,
showApply: Boolean,
dismissCallback: () -> Unit,
callback: (Int) -> Unit,
) {
}
/** Only for a low amount of items */
fun Activity?.showBottomDialog(
items: List<String>,

View File

@ -1,5 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="?attr/white" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M15.41,16.59L10.83,12l4.58,-4.59L14,6l-6,6 6,6 1.41,-1.41z"/>
<path android:fillColor="@android:color/white" android:pathData="M13.3,17.3 L8.7,12.7Q8.55,12.55 8.488,12.375Q8.425,12.2 8.425,12Q8.425,11.8 8.488,11.625Q8.55,11.45 8.7,11.3L13.3,6.7Q13.575,6.425 14,6.425Q14.425,6.425 14.7,6.7Q14.975,6.975 14.975,7.4Q14.975,7.825 14.7,8.1L10.8,12L14.7,15.9Q14.975,16.175 14.975,16.6Q14.975,17.025 14.7,17.3Q14.425,17.575 14,17.575Q13.575,17.575 13.3,17.3Z"/>
</vector>

View File

@ -1,5 +1,11 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="?attr/white" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M8.59,16.59L13.17,12 8.59,7.41 10,6l6,6 -6,6 -1.41,-1.41z"/>
<vector android:autoMirrored="true"
android:height="24dp"
android:tint="?attr/white"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M8.7,17.3Q8.425,17.025 8.425,16.6Q8.425,16.175 8.7,15.9L12.6,12L8.7,8.1Q8.425,7.825 8.425,7.4Q8.425,6.975 8.7,6.7Q8.975,6.425 9.4,6.425Q9.825,6.425 10.1,6.7L14.7,11.3Q14.85,11.45 14.913,11.625Q14.975,11.8 14.975,12Q14.975,12.2 14.913,12.375Q14.85,12.55 14.7,12.7L10.1,17.3Q9.825,17.575 9.4,17.575Q8.975,17.575 8.7,17.3Z" />
</vector>

View File

@ -14,10 +14,11 @@
<com.google.android.material.navigationrail.NavigationRailView
android:id="@+id/nav_rail_view"
android:layout_width="62dp"
android:layout_width="@dimen/navbar_width"
android:layout_height="match_parent"
android:background="?attr/primaryGrayBackground"
app:itemIconTint="@color/item_select_color"
android:descendantFocusability="afterDescendants"
app:itemTextColor="@color/item_select_color"
app:labelVisibilityMode="unlabeled"

View File

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

View File

@ -153,435 +153,14 @@
android:textColor="?attr/textColor" />
</LinearLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/home_loaded"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/home_master_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBlackBackground"
android:visibility="gone"
tools:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
android:id="@+id/home_statusbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/primaryGrayBackground" />
<FrameLayout
android:id="@+id/home_settings_bar"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="?attr/primaryGrayBackground"
android:visibility="gone">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingStart="10dp"
android:paddingTop="10dp"
android:paddingEnd="10dp"
android:paddingBottom="10dp">
<androidx.cardview.widget.CardView
android:id="@+id/home_profile_picture_holder"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="10dp"
app:cardCornerRadius="100dp">
<ImageView
android:id="@+id/home_profile_picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
tools:ignore="ContentDescription" />
</androidx.cardview.widget.CardView>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:background="@drawable/search_background"
android:visibility="visible">
<androidx.appcompat.widget.SearchView
android:id="@+id/home_search2"
android:layout_width="match_parent"
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="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
<TextView
android:id="@+id/home_provider_name"
android:layout_width="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
android:id="@+id/home_provider_meta_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_vertical"
android:textColor="?attr/grayTextColor"
android:textSize="14sp"
tools:text="Hello World" />
</LinearLayout>
</LinearLayout>
<!--
<ImageView
android:nextFocusDown="@id/home_main_poster_recyclerview"
android:nextFocusUp="@id/nav_rail_view"
android:nextFocusLeft="@id/nav_rail_view"
android:id="@+id/home_change_api"
android:layout_margin="10dp"
android:layout_gravity="center|end"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_baseline_keyboard_arrow_down_24"
android:layout_width="30dp"
android:layout_height="30dp"
android:contentDescription="@string/home_change_provider_img_des">
<requestFocus />
</ImageView>-->
</FrameLayout>
<!--https://www.digitalocean.com/community/tutorials/android-viewpager-example-tutorial-->
<FrameLayout
android:id="@+id/home_preview"
android:layout_width="match_parent"
android:layout_height="500dp"
android:visibility="gone"
tools:visibility="visible">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/home_preview_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
</androidx.viewpager2.widget.ViewPager2>
<ImageView
android:id="@+id/home_preview_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.8"
android:scaleType="centerCrop"
android:visibility="gone"
tools:src="@drawable/example_poster" />
<LinearLayout
android:id="@+id/home_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.SearchView
android:id="@+id/home_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:editTextColor="@color/white"
android:gravity="start"
android:iconifiedByDefault="true"
android:textColor="@color/white"
android:textColorHint="@color/white"
app:iconifiedByDefault="true"
app:queryBackground="@color/transparent"
app:queryHint="@string/search"
app:closeIcon="@drawable/ic_baseline_close_24"
app:searchIcon="@drawable/search_icon"
tools:ignore="RtlSymmetry" />
</LinearLayout>
<!--
<TextView
android:visibility="gone"
android:id="@+id/test_search"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:layout_gravity="start"
android:gravity="center"
android:textSize="20dp"
android:layout_margin="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/search"
android:textColor="@color/white"
app:drawableLeftCompat="@drawable/search_icon"
app:tint="@color/white" />
-->
<LinearLayout
android:id="@+id/home_preview_title_holder"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_gravity="bottom"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal"
android:padding="20dp">
<TextView
android:id="@+id/home_preview_bookmark"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:gravity="center"
android:text="@string/none"
android:textColor="?attr/white"
app:drawableTint="?attr/white"
app:drawableTopCompat="@drawable/ic_baseline_add_24"
app:tint="?attr/white" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_preview_play"
style="@style/WhiteButton"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:text="@string/home_play"
app:icon="@drawable/ic_baseline_play_arrow_24" />
<TextView
android:id="@+id/home_preview_info"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:gravity="center"
android:text="@string/home_info"
android:textColor="?attr/white"
app:drawableTint="?attr/white"
app:drawableTopCompat="@drawable/ic_outline_info_24"
app:tint="?attr/white" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
<View
android:id="@+id/home_fix_padding"
android:layout_width="match_parent"
android:layout_height="0dp"></View>
<!--
All padding in home_watch_holder is determined in runtime
This is because the home poster can be invisible which forces
us to take the status bar space into account
-->
<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
android:id="@+id/home_watch_parent_item_title"
style="@style/WatchHeaderText"
android:layout_gravity="center_vertical"
android:text="@string/continue_watching" />
<ImageView
android:layout_width="30dp"
android:layout_height="match_parent"
android:layout_gravity="end|center_vertical"
android:layout_marginEnd="5dp"
android:contentDescription="@string/home_more_info"
android:src="@drawable/ic_baseline_arrow_forward_24"
app:tint="?attr/textColor" />
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/home_watch_child_recyclerview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
android:orientation="horizontal"
android:paddingHorizontal="5dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/home_result_grid" />
</LinearLayout>
<LinearLayout
android:id="@+id/home_bookmarked_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_bookmarked_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:nextFocusUp="@id/home_watch_child_recyclerview"
android:nextFocusForward="@id/home_bookmarked_child_recyclerview"
android:paddingStart="12dp"
android:paddingTop="5dp"
android:paddingEnd="12dp"
android:paddingBottom="5dp">
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="50dp"
android:fadingEdge="horizontal"
android:requiresFadingEdge="horizontal">
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:singleSelection="true">
<com.google.android.material.chip.Chip
android:id="@+id/home_type_watching_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/nav_rail_view"
android:nextFocusRight="@id/home_plan_to_watch_btt"
android:text="@string/type_watching" />
<com.google.android.material.chip.Chip
android:id="@+id/home_plan_to_watch_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_type_watching_btt"
android:nextFocusRight="@id/home_type_on_hold_btt"
android:text="@string/type_plan_to_watch" />
<com.google.android.material.chip.Chip
android:id="@+id/home_type_on_hold_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_plan_to_watch_btt"
android:nextFocusRight="@id/home_type_dropped_btt"
android:text="@string/type_on_hold" />
<com.google.android.material.chip.Chip
android:id="@+id/home_type_dropped_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_type_on_hold_btt"
android:nextFocusRight="@id/home_type_completed_btt"
android:text="@string/type_dropped" />
<com.google.android.material.chip.Chip
android:id="@+id/home_type_completed_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_type_dropped_btt"
android:text="@string/type_completed" />
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
<ImageView
android:layout_width="30dp"
android:layout_height="match_parent"
android:layout_gravity="end|center_vertical"
android:layout_marginEnd="5dp"
android:contentDescription="@string/home_more_info"
android:src="@drawable/ic_baseline_arrow_forward_24"
app:tint="?attr/textColor" />
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/home_bookmarked_child_recyclerview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
android:orientation="horizontal"
android:paddingHorizontal="5dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/home_result_grid" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/home_master_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="afterDescendants"
android:nextFocusLeft="@id/nav_rail_view"
tools:listitem="@layout/homepage_parent" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
android:layout_height="wrap_content"
android:descendantFocusability="afterDescendants"
android:nextFocusLeft="@id/nav_rail_view"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/homepage_parent" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/home_api_fab"

View File

@ -0,0 +1,259 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:orientation="vertical"
android:id="@+id/home_preview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/primaryBlackBackground"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="500dp">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/home_preview_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
</androidx.viewpager2.widget.ViewPager2>
<ImageView
android:id="@+id/home_preview_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.8"
android:scaleType="centerCrop"
android:visibility="gone"
tools:src="@drawable/example_poster" />
<LinearLayout
android:id="@+id/home_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.SearchView
android:id="@+id/home_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:editTextColor="@color/white"
android:gravity="start"
android:iconifiedByDefault="true"
android:textColor="@color/white"
android:textColorHint="@color/white"
app:iconifiedByDefault="true"
app:queryBackground="@color/transparent"
app:queryHint="@string/search_hint"
app:closeIcon="@drawable/ic_baseline_close_24"
app:searchIcon="@drawable/search_icon"
tools:ignore="RtlSymmetry" />
</LinearLayout>
<!--
<TextView
android:visibility="gone"
android:id="@+id/test_search"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:layout_gravity="start"
android:gravity="center"
android:textSize="20dp"
android:layout_margin="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/search"
android:textColor="@color/white"
app:drawableLeftCompat="@drawable/search_icon"
app:tint="@color/white" />
-->
<LinearLayout
android:id="@+id/home_preview_title_holder"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_gravity="bottom"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal"
android:padding="20dp">
<TextView
android:id="@+id/home_preview_bookmark"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:gravity="center"
android:text="@string/none"
android:textColor="?attr/white"
app:drawableTint="?attr/white"
app:drawableTopCompat="@drawable/ic_baseline_add_24"
app:tint="?attr/white" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_preview_play"
style="@style/WhiteButton"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:text="@string/home_play"
app:icon="@drawable/ic_baseline_play_arrow_24" />
<TextView
android:id="@+id/home_preview_info"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:gravity="center"
android:text="@string/home_info"
android:textColor="?attr/white"
app:drawableTint="?attr/white"
app:drawableTopCompat="@drawable/ic_outline_info_24"
app:tint="?attr/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">
<TextView
android:id="@+id/home_watch_parent_item_title"
style="@style/WatchHeaderText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:padding="12dp"
android:text="@string/continue_watching" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/home_watch_child_recyclerview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
android:orientation="horizontal"
android:paddingEnd="5dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/home_result_grid" />
</LinearLayout>
<LinearLayout
android:id="@+id/home_bookmarked_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fadingEdge="horizontal"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:nextFocusLeft="@id/nav_rail_view"
android:nextFocusUp="@id/home_watch_child_recyclerview"
android:nextFocusForward="@id/home_bookmarked_child_recyclerview"
android:paddingStart="12dp"
android:paddingTop="5dp"
android:paddingEnd="12dp"
android:paddingBottom="5dp"
android:requiresFadingEdge="horizontal">
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.chip.Chip
android:id="@+id/home_type_watching_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/nav_rail_view"
android:nextFocusRight="@id/home_plan_to_watch_btt"
android:text="@string/type_watching" />
<com.google.android.material.chip.Chip
android:id="@+id/home_plan_to_watch_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_type_watching_btt"
android:nextFocusRight="@id/home_type_on_hold_btt"
android:text="@string/type_plan_to_watch" />
<com.google.android.material.chip.Chip
android:id="@+id/home_type_on_hold_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_plan_to_watch_btt"
android:nextFocusRight="@id/home_type_dropped_btt"
android:text="@string/type_on_hold" />
<com.google.android.material.chip.Chip
android:id="@+id/home_type_dropped_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_type_on_hold_btt"
android:nextFocusRight="@id/home_type_completed_btt"
android:text="@string/type_dropped" />
<com.google.android.material.chip.Chip
android:id="@+id/home_type_completed_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_type_dropped_btt"
android:text="@string/type_completed" />
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/home_bookmarked_child_recyclerview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
android:orientation="horizontal"
android:paddingEnd="5dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/home_result_grid" />
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,248 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:orientation="vertical"
android:id="@+id/home_preview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/primaryBlackBackground"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/home_preview_viewpager"
android:layout_width="match_parent"
android:layout_height="400dp"
android:orientation="horizontal">
</androidx.viewpager2.widget.ViewPager2>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp">
<com.google.android.material.button.MaterialButton
android:id="@+id/home_preview_change_api"
style="@style/BlackButton"
android:layout_width="wrap_content"
android:layout_gravity="top|start"
android:layout_marginStart="@dimen/navbar_width"
android:backgroundTint="@color/semiWhite"
android:minWidth="150dp" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:layout_marginStart="@dimen/navbar_width"
android:gravity="bottom"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/home_preview_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textSize="25sp"
android:textStyle="bold"
tools:text="The Perfect Run" />
<TextView
android:id="@+id/home_preview_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="5"
android:paddingBottom="5dp"
android:textSize="15sp"
tools:text="very nice tv series" />
<com.google.android.material.chip.ChipGroup
android:id="@+id/home_preview_tags"
style="@style/ChipParent"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp">
<View
android:id="@+id/home_preview_hidden_prev_focus"
android:layout_width="1dp"
android:layout_height="1dp"
android:focusable="true" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_preview_play_btt"
style="@style/WhiteButton"
android:layout_width="wrap_content"
android:layout_margin="0dp"
android:minWidth="150dp"
android:nextFocusLeft="@id/home_preview_hidden_prev_focus"
android:nextFocusRight="@id/home_preview_info_btt"
android:nextFocusUp="@id/home_preview_change_api"
android:nextFocusDown="@id/home_watch_parent_item_title"
android:text="@string/home_play"
app:icon="@drawable/ic_baseline_play_arrow_24" />
<com.google.android.material.button.MaterialButton
android:id="@+id/home_preview_info_btt"
style="@style/BlackButton"
android:layout_width="wrap_content"
android:minWidth="150dp"
android:nextFocusLeft="@id/home_preview_play_btt"
android:nextFocusRight="@id/home_preview_hidden_next_focus"
android:nextFocusUp="@id/home_preview_change_api"
android:nextFocusDown="@id/home_watch_parent_item_title"
android:text="@string/home_info"
app:icon="@drawable/ic_outline_info_24" />
<View
android:id="@+id/home_preview_hidden_next_focus"
android:layout_width="1dp"
android:layout_height="1dp"
android:focusable="true" />
</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">
<TextView
android:id="@+id/home_watch_parent_item_title"
style="@style/WatchHeaderText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/navbar_width"
android:layout_marginEnd="0dp"
android:padding="12dp"
android:text="@string/continue_watching" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/home_watch_child_recyclerview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
android:orientation="horizontal"
android:paddingStart="@dimen/navbar_width"
android:paddingEnd="5dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/home_result_grid" />
</LinearLayout>
<LinearLayout
android:id="@+id/home_bookmarked_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fadingEdge="horizontal"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:nextFocusLeft="@id/nav_rail_view"
android:nextFocusUp="@id/home_watch_child_recyclerview"
android:nextFocusForward="@id/home_bookmarked_child_recyclerview"
android:paddingStart="12dp"
android:paddingTop="5dp"
android:paddingEnd="12dp"
android:paddingBottom="5dp"
android:requiresFadingEdge="horizontal">
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/navbar_width"
android:orientation="horizontal">
<com.google.android.material.chip.Chip
android:id="@+id/home_type_watching_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/nav_rail_view"
android:nextFocusRight="@id/home_plan_to_watch_btt"
android:text="@string/type_watching" />
<com.google.android.material.chip.Chip
android:id="@+id/home_plan_to_watch_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_type_watching_btt"
android:nextFocusRight="@id/home_type_on_hold_btt"
android:text="@string/type_plan_to_watch" />
<com.google.android.material.chip.Chip
android:id="@+id/home_type_on_hold_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_plan_to_watch_btt"
android:nextFocusRight="@id/home_type_dropped_btt"
android:text="@string/type_on_hold" />
<com.google.android.material.chip.Chip
android:id="@+id/home_type_dropped_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_type_on_hold_btt"
android:nextFocusRight="@id/home_type_completed_btt"
android:text="@string/type_dropped" />
<com.google.android.material.chip.Chip
android:id="@+id/home_type_completed_btt"
style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_type_dropped_btt"
android:text="@string/type_completed" />
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/home_bookmarked_child_recyclerview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
android:orientation="horizontal"
android:paddingStart="@dimen/navbar_width"
android:paddingEnd="5dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/home_result_grid" />
</LinearLayout>
</LinearLayout>

View File

@ -1,87 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/home_root"
android:layout_width="match_parent"
android:id="@+id/home_root"
tools:context=".ui.home.HomeFragment">
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment">
<FrameLayout
android:visibility="gone"
tools:visibility="gone"
android:id="@+id/home_loading"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@+id/home_loading"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/navbar_width"
android:visibility="gone"
tools:visibility="gone">
<ProgressBar
android:layout_gravity="center"
android:visibility="gone"
tools:visibility="gone"
android:layout_width="50dp"
android:layout_height="50dp" />
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:visibility="gone"
tools:visibility="gone" />
<com.facebook.shimmer.ShimmerFrameLayout
android:id="@+id/home_loading_shimmer"
app:shimmer_base_alpha="0.2"
app:shimmer_highlight_alpha="0.3"
app:shimmer_duration="@integer/loading_time"
app:shimmer_auto_start="true"
android:paddingTop="40dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginTop="15dp"
android:orientation="vertical">
android:id="@+id/home_loading_shimmer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginTop="15dp"
android:orientation="vertical"
android:paddingTop="40dp"
app:shimmer_auto_start="true"
app:shimmer_base_alpha="0.2"
app:shimmer_duration="@integer/loading_time"
app:shimmer_highlight_alpha="0.3">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.cardview.widget.CardView
android:layout_margin="@dimen/loading_margin"
android:layout_gravity="center"
app:cardCornerRadius="@dimen/loading_radius"
android:background="@color/grayShimmer"
android:translationX="-164dp"
android:layout_width="125dp"
android:layout_height="200dp" />
android:layout_width="125dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_margin="@dimen/loading_margin"
android:background="@color/grayShimmer"
android:translationX="-164dp"
app:cardCornerRadius="@dimen/loading_radius" />
<androidx.cardview.widget.CardView
android:layout_margin="@dimen/loading_margin"
android:layout_gravity="center"
app:cardCornerRadius="@dimen/loading_radius"
android:background="@color/grayShimmer"
android:layout_width="148dp"
android:layout_height="234dp" />
android:layout_width="148dp"
android:layout_height="234dp"
android:layout_gravity="center"
android:layout_margin="@dimen/loading_margin"
android:background="@color/grayShimmer"
app:cardCornerRadius="@dimen/loading_radius" />
<androidx.cardview.widget.CardView
android:layout_margin="@dimen/loading_margin"
android:layout_gravity="center"
app:cardCornerRadius="@dimen/loading_radius"
android:background="@color/grayShimmer"
android:translationX="164dp"
android:layout_width="125dp"
android:layout_height="200dp" />
android:layout_width="125dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_margin="@dimen/loading_margin"
android:background="@color/grayShimmer"
android:translationX="164dp"
app:cardCornerRadius="@dimen/loading_radius" />
</FrameLayout>
<include layout="@layout/loading_line_short_center" />
<LinearLayout
android:orientation="vertical"
android:layout_marginTop="@dimen/result_padding"
android:layout_marginStart="@dimen/result_padding"
android:layout_marginEnd="@dimen/result_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/result_padding"
android:layout_marginTop="@dimen/result_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_marginEnd="@dimen/result_padding"
android:orientation="vertical">
<include layout="@layout/loading_list" />
@ -93,355 +94,82 @@
</com.facebook.shimmer.ShimmerFrameLayout>
<FrameLayout
android:id="@+id/home_loading_statusbar"
android:layout_width="match_parent"
android:layout_height="70dp">
android:id="@+id/home_loading_statusbar"
android:layout_width="match_parent"
android:layout_height="70dp">
<ImageView
android:id="@+id/home_change_api_loading"
android:layout_margin="10dp"
android:layout_gravity="center_vertical|end"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:id="@+id/home_change_api_loading"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical|end"
android:src="@drawable/ic_baseline_keyboard_arrow_down_24"
android:layout_width="30dp"
android:layout_height="30dp"
android:contentDescription="@string/home_change_provider_img_des" />
android:layout_margin="10dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/home_change_provider_img_des"
android:src="@drawable/ic_baseline_keyboard_arrow_down_24" />
</FrameLayout>
</FrameLayout>
<LinearLayout
android:visibility="gone"
tools:visibility="gone"
android:id="@+id/home_loading_error"
android:orientation="vertical"
android:id="@+id/home_loading_error"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="@dimen/navbar_width"
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_width="match_parent"
android:layout_height="wrap_content">
android:layout_margin="5dp"
android:minWidth="200dp"
android:text="@string/reload_error"
app:icon="@drawable/ic_baseline_autorenew_24" />
<com.google.android.material.button.MaterialButton
android:layout_gravity="center"
style="@style/WhiteButton"
android:id="@+id/home_reload_connection_open_in_browser"
style="@style/BlackButton"
android:layout_margin="5dp"
android:layout_width="wrap_content"
app:icon="@drawable/ic_baseline_autorenew_24"
android:text="@string/reload_error"
android:id="@+id/home_reload_connectionerror"
android:layout_width="wrap_content"
android:minWidth="200dp" />
<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" />
android:layout_gravity="center"
android:layout_margin="5dp"
android:minWidth="200dp"
android:text="@string/result_open_in_browser"
app:icon="@drawable/ic_baseline_public_24" />
<TextView
android:layout_margin="5dp"
android:gravity="center"
android:layout_gravity="center"
android:id="@+id/result_error_text"
android:textColor="?attr/textColor"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:id="@+id/result_error_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:gravity="center"
android:textColor="?attr/textColor" />
</LinearLayout>
<androidx.core.widget.NestedScrollView
android:background="?attr/primaryBlackBackground"
tools:visibility="visible"
android:visibility="gone"
android:id="@+id/home_loaded"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:background="?attr/primaryGrayBackground"
android:id="@+id/home_statusbar"
android:layout_height="wrap_content"
android:layout_width="match_parent" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:scaleType="centerCrop"
tools:src="@drawable/example_poster"
android:id="@+id/home_blur_poster"
android:layout_width="match_parent"
android:layout_height="200dp" />
<ImageView
android:id="@+id/shadow_overlay"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@drawable/background_shadow" />
<LinearLayout
android:layout_marginTop="100dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="100dp">
<!--
<androidx.cardview.widget.CardView
android:id="@+id/home_profile_picture_holder"
android:layout_marginEnd="20dp"
app:cardCornerRadius="100dp"
android:layout_gravity="center_vertical"
android:layout_width="35dp"
android:layout_height="35dp">
<ImageView
android:id="@+id/home_profile_picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="ContentDescription" />
</androidx.cardview.widget.CardView>-->
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:nextFocusDown="@id/home_main_poster_recyclerview"
android:nextFocusUp="@id/nav_rail_view"
android:nextFocusLeft="@id/nav_rail_view"
android:layout_gravity="center_vertical"
android:id="@+id/home_change_api"
android:layout_margin="10dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:foreground="@drawable/outline_drawable"
android:src="@drawable/ic_baseline_filter_list_24"
android:layout_width="30dp"
android:layout_height="30dp"
android:contentDescription="@string/home_change_provider_img_des">
<requestFocus />
</ImageView>
<TextView
android:maxLines="1"
android:ellipsize="end"
android:gravity="center_vertical"
android:layout_gravity="center_vertical"
android:textStyle="bold"
android:textSize="25sp"
tools:text="The Perfect Run"
android:id="@+id/home_focus_text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_marginStart="12dp"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:gravity="center_vertical"
android:id="@+id/home_provider_name"
android:textColor="?attr/grayTextColor"
android:textSize="20sp"
android:paddingEnd="10dp"
tools:text="Hello World"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:gravity="center_vertical"
android:id="@+id/home_provider_meta_info"
android:textColor="?attr/grayTextColor"
android:textSize="20sp"
tools:text="Hello World"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:paddingHorizontal="5dp"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
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" />
</LinearLayout>
</FrameLayout>
<LinearLayout
android:id="@+id/home_watch_holder"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/home_watch_parent_item_title"
android:padding="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/WatchHeaderText"
android:layout_marginEnd="0dp"
android:text="@string/continue_watching">
</TextView>
<androidx.recyclerview.widget.RecyclerView
android:paddingHorizontal="5dp"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:id="@+id/home_watch_child_recyclerview"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:listitem="@layout/home_result_grid" />
</LinearLayout>
<LinearLayout
android:id="@+id/home_bookmarked_holder"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<HorizontalScrollView
android:nextFocusLeft="@id/nav_rail_view"
android:nextFocusUp="@id/home_watch_child_recyclerview"
android:nextFocusForward="@id/home_bookmarked_child_recyclerview"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fadingEdge="horizontal"
android:requiresFadingEdge="horizontal">
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.chip.Chip
android:id="@+id/home_type_watching_btt"
style="@style/ChipFilled"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:nextFocusLeft="@id/nav_rail_view"
android:nextFocusRight="@id/home_plan_to_watch_btt"
android:text="@string/type_watching" />
<com.google.android.material.chip.Chip
android:id="@+id/home_plan_to_watch_btt"
style="@style/ChipFilled"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:nextFocusLeft="@id/home_type_watching_btt"
android:nextFocusRight="@id/home_type_on_hold_btt"
android:text="@string/type_plan_to_watch" />
<com.google.android.material.chip.Chip
android:id="@+id/home_type_on_hold_btt"
style="@style/ChipFilled"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:nextFocusLeft="@id/home_plan_to_watch_btt"
android:nextFocusRight="@id/home_type_dropped_btt"
android:text="@string/type_on_hold" />
<com.google.android.material.chip.Chip
android:id="@+id/home_type_dropped_btt"
style="@style/ChipFilled"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:nextFocusLeft="@id/home_type_on_hold_btt"
android:nextFocusRight="@id/home_type_completed_btt"
android:text="@string/type_dropped" />
<com.google.android.material.chip.Chip
android:id="@+id/home_type_completed_btt"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
style="@style/ChipFilled"
android:nextFocusLeft="@id/home_type_dropped_btt"
android:text="@string/type_completed" />
</com.google.android.material.chip.ChipGroup> </HorizontalScrollView>
<androidx.recyclerview.widget.RecyclerView
android:paddingHorizontal="5dp"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:id="@+id/home_bookmarked_child_recyclerview"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:listitem="@layout/home_result_grid" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:nextFocusLeft="@id/nav_rail_view"
android:descendantFocusability="afterDescendants"
android:id="@+id/home_master_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/homepage_parent_tv" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/home_master_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="afterDescendants"
android:nextFocusLeft="@id/nav_rail_view"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/homepage_parent_tv" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:visibility="gone"
tools:visibility="visible"
android:id="@+id/home_api_fab"
app:icon="@drawable/ic_baseline_filter_list_24"
style="@style/ExtendedFloatingActionButton"
tools:ignore="ContentDescription" />
android:id="@+id/home_api_fab"
style="@style/ExtendedFloatingActionButton"
android:visibility="gone"
app:icon="@drawable/ic_baseline_filter_list_24"
tools:ignore="ContentDescription"
tools:visibility="visible" />
</FrameLayout>

View File

@ -516,6 +516,7 @@
android:visibility="gone" />
<com.google.android.material.chip.ChipGroup
style="@style/ChipParent"
android:id="@+id/result_tag"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

View File

@ -385,6 +385,7 @@
<com.google.android.material.chip.ChipGroup
style="@style/ChipParent"
android:id="@+id/result_tag"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

View File

@ -10,79 +10,86 @@
android:orientation="vertical"
tools:context=".ui.search.SearchFragment">
<FrameLayout
<LinearLayout
android:paddingBottom="10dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_margin="10dp"
android:background="@drawable/search_background"
android:visibility="visible">
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="30dp">
android:layout_height="40dp"
android:layout_margin="10dp"
android:background="@drawable/search_background"
android:visibility="visible">
<androidx.appcompat.widget.SearchView
android:id="@+id/main_search"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="30dp">
android:iconifiedByDefault="false"
android:imeOptions="actionSearch"
<androidx.appcompat.widget.SearchView
android:id="@+id/main_search"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:inputType="text"
android:nextFocusLeft="@id/nav_rail_view"
android:iconifiedByDefault="false"
android:imeOptions="actionSearch"
android:nextFocusRight="@id/search_filter"
android:inputType="text"
android:nextFocusLeft="@id/nav_rail_view"
android:nextFocusRight="@id/search_filter"
android:nextFocusUp="@id/nav_rail_view"
android:nextFocusDown="@id/search_autofit_results"
android:paddingStart="-10dp"
app:iconifiedByDefault="false"
app:queryBackground="@color/transparent"
app:queryHint="@string/search_hint"
app:searchIcon="@drawable/search_icon"
tools:ignore="RtlSymmetry">
<requestFocus />
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/search_loading_bar"
style="@style/Widget.AppCompat.ProgressBar"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:layout_marginStart="-35dp"
android:foregroundTint="@color/white"
android:progressTint="@color/white">
</androidx.core.widget.ContentLoadingProgressBar>
<!--app:queryHint="@string/search_hint"
android:background="@color/grayBackground" @color/itemBackground
app:searchHintIcon="@drawable/search_white"
-->
</androidx.appcompat.widget.SearchView>
</FrameLayout>
<ImageView
android:id="@+id/search_filter"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_gravity="end|center_vertical"
android:layout_margin="10dp"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/change_providers_img_des"
android:nextFocusLeft="@id/main_search"
android:nextFocusRight="@id/main_search"
android:nextFocusUp="@id/nav_rail_view"
android:nextFocusDown="@id/search_autofit_results"
android:paddingStart="-10dp"
app:iconifiedByDefault="false"
app:queryBackground="@color/transparent"
app:queryHint="@string/search_hint"
app:searchIcon="@drawable/search_icon"
tools:ignore="RtlSymmetry">
<requestFocus />
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/search_loading_bar"
style="@style/Widget.AppCompat.ProgressBar"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:layout_marginStart="-35dp"
android:foregroundTint="@color/white"
android:progressTint="@color/white">
</androidx.core.widget.ContentLoadingProgressBar>
<!--app:queryHint="@string/search_hint"
android:background="@color/grayBackground" @color/itemBackground
app:searchHintIcon="@drawable/search_white"
-->
</androidx.appcompat.widget.SearchView>
android:src="@drawable/ic_baseline_tune_24"
app:tint="?attr/textColor" />
</FrameLayout>
<ImageView
android:id="@+id/search_filter"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_gravity="end|center_vertical"
android:layout_margin="10dp"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/change_providers_img_des"
android:nextFocusLeft="@id/main_search"
android:nextFocusRight="@id/main_search"
android:nextFocusUp="@id/nav_rail_view"
android:nextFocusDown="@id/search_autofit_results"
android:src="@drawable/ic_baseline_tune_24"
app:tint="?attr/textColor" />
</FrameLayout>
<include layout="@layout/tvtypes_chips_scroll" />
<include layout="@layout/tvtypes_chips_scroll" />
</LinearLayout>
<com.lagradost.cloudstream3.ui.AutofitRecyclerView
@ -112,34 +119,35 @@
android:nextFocusLeft="@id/nav_rail_view"
android:visibility="gone"
tools:listitem="@layout/homepage_parent" />
<FrameLayout
android:id="@+id/search_history_holder"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/search_history_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/search_history_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBlackBackground"
android:descendantFocusability="afterDescendants"
android:nextFocusLeft="@id/nav_rail_view"
android:visibility="visible"
android:paddingBottom="50dp"
tools:listitem="@layout/search_history_item" />
android:background="?attr/primaryBlackBackground"
android:descendantFocusability="afterDescendants"
android:nextFocusLeft="@id/nav_rail_view"
android:visibility="visible"
android:paddingBottom="50dp"
tools:listitem="@layout/search_history_item" />
<com.google.android.material.button.MaterialButton
android:id="@+id/search_clear_call_history"
style="@style/BlackButton"
android:layout_gravity="bottom"
android:padding="0dp"
app:cornerRadius="0dp"
android:layout_margin="0dp"
android:text="@string/clear_history"
app:icon="@drawable/delete_all"
android:layout_width="match_parent"
android:layout_height="50dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/search_clear_call_history"
style="@style/BlackButton"
android:layout_gravity="bottom"
android:padding="0dp"
app:cornerRadius="0dp"
android:layout_margin="0dp"
android:text="@string/clear_history"
app:icon="@drawable/delete_all"
android:layout_width="match_parent"
android:layout_height="50dp" />
</FrameLayout>
</LinearLayout>

View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/searchRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/navbar_height"
android:background="?attr/primaryGrayBackground"
android:orientation="vertical"
tools:context=".ui.search.SearchFragment">
<LinearLayout
android:layout_marginStart="@dimen/navbar_width"
android:paddingBottom="10dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_margin="10dp"
android:background="@drawable/search_background"
android:visibility="visible">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="30dp">
<androidx.appcompat.widget.SearchView
android:id="@+id/main_search"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:iconifiedByDefault="false"
android:imeOptions="actionSearch"
android:inputType="text"
android:nextFocusLeft="@id/nav_rail_view"
android:nextFocusRight="@id/search_filter"
android:nextFocusUp="@id/nav_rail_view"
android:nextFocusDown="@id/search_autofit_results"
android:paddingStart="-10dp"
app:iconifiedByDefault="false"
app:queryBackground="@color/transparent"
app:queryHint="@string/search_hint"
app:searchIcon="@drawable/search_icon"
tools:ignore="RtlSymmetry">
<requestFocus />
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/search_loading_bar"
style="@style/Widget.AppCompat.ProgressBar"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:layout_marginStart="-35dp"
android:foregroundTint="@color/white"
android:progressTint="@color/white">
</androidx.core.widget.ContentLoadingProgressBar>
<!--app:queryHint="@string/search_hint"
android:background="@color/grayBackground" @color/itemBackground
app:searchHintIcon="@drawable/search_white"
-->
</androidx.appcompat.widget.SearchView>
</FrameLayout>
<ImageView
android:id="@+id/search_filter"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_gravity="end|center_vertical"
android:layout_margin="10dp"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/change_providers_img_des"
android:nextFocusLeft="@id/main_search"
android:nextFocusRight="@id/main_search"
android:nextFocusUp="@id/nav_rail_view"
android:nextFocusDown="@id/search_autofit_results"
android:src="@drawable/ic_baseline_tune_24"
app:tint="?attr/textColor" />
</FrameLayout>
<include layout="@layout/tvtypes_chips_scroll" />
</LinearLayout>
<com.lagradost.cloudstream3.ui.AutofitRecyclerView
android:id="@+id/search_autofit_results"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBlackBackground"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
android:nextFocusLeft="@id/nav_rail_view"
android:orientation="vertical"
android:paddingStart="8dp"
android:paddingTop="5dp"
android:paddingEnd="8dp"
android:visibility="gone"
app:spanCount="3"
tools:listitem="@layout/search_result_grid" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/search_master_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBlackBackground"
android:descendantFocusability="afterDescendants"
android:nextFocusLeft="@id/nav_rail_view"
android:visibility="gone"
tools:listitem="@layout/homepage_parent" />
<FrameLayout
android:id="@+id/search_history_holder"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:paddingStart="@dimen/navbar_width"
android:id="@+id/search_history_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBlackBackground"
android:descendantFocusability="afterDescendants"
android:nextFocusLeft="@id/nav_rail_view"
android:visibility="visible"
android:paddingBottom="50dp"
tools:listitem="@layout/search_history_item" />
<com.google.android.material.button.MaterialButton
android:id="@+id/search_clear_call_history"
style="@style/BlackButton"
android:layout_gravity="bottom"
android:padding="0dp"
app:cornerRadius="0dp"
android:layout_margin="0dp"
android:text="@string/clear_history"
app:icon="@drawable/delete_all"
android:layout_width="match_parent"
android:layout_height="50dp" />
</FrameLayout>
</LinearLayout>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="?attr/primaryGrayBackground"
android:layout_height="match_parent">
<ImageView
android:id="@+id/home_scroll_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
tools:src="@drawable/example_poster" />
<View
android:id="@+id/title_shadow"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_gravity="bottom"
android:background="@drawable/background_shadow" />
</FrameLayout>

View File

@ -1,32 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/home_parent_item_title"
android:padding="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/WatchHeaderText"
android:layout_marginEnd="0dp"
tools:text="Trending">
</TextView>
android:layout_marginStart="@dimen/navbar_width"
android:id="@+id/home_parent_item_title"
android:padding="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/WatchHeaderText"
android:layout_marginEnd="0dp"
tools:text="Trending" />
<androidx.recyclerview.widget.RecyclerView
android:nextFocusUp="@id/home_child_more_info"
android:paddingHorizontal="5dp"
android:clipToPadding="false"
android:nextFocusUp="@id/home_child_more_info"
android:descendantFocusability="afterDescendants"
android:paddingEnd="5dp"
android:paddingStart="@dimen/navbar_width"
android:clipToPadding="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:id="@+id/home_child_recyclerview"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="@layout/home_result_grid" />
android:descendantFocusability="afterDescendants"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:id="@+id/home_child_recyclerview"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="@layout/home_result_grid" />
</LinearLayout>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.chip.ChipGroup android:layout_width="match_parent"
style="@style/ChipParent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:paddingStart="8dp"

View File

@ -13,6 +13,7 @@
<color name="boxItemBackground">#161616</color> <!-- 17171B 1B1B20-->
<color name="textColor">#e9eaee</color> <!--FFF-->
<color name="semiWhite">#1AFFFFFF</color> <!--FFF-->
<color name="grayTextColor">#9ba0a4</color> <!-- 5e5f62-->
<color name="grayShimmer">#DCDCDC</color> <!-- 5e5f62-->

View File

@ -16,4 +16,5 @@
<integer name="loading_time">2000</integer>
<dimen name="storage_radius">3dp</dimen>
<dimen name="navbar_width">62dp</dimen>
</resources>

View File

@ -88,6 +88,16 @@
<item name="fontFamily">@font/google_sans</item>
<item name="chipIconTint">@color/chip_color_text</item>
<item name="android:fontFamily">@font/google_sans</item>
<item name="chipMinTouchTargetSize">0dp</item>
</style>
<style name="ChipFilledSemiTransparent" parent="@style/ChipFilled">
<item name="chipBackgroundColor">@color/transparent</item>
<item name="chipSurfaceColor">@color/semiWhite</item>
<item name="backgroundColor">@color/transparent</item>
</style>
<style name="ChipParent">
<item name="chipSpacingVertical">5dp</item>
<item name="chipSpacingHorizontal">5dp</item>
</style>
<style name="AmoledMode">