homepage working

This commit is contained in:
LagradOst 2021-07-29 03:46:10 +02:00
parent 684f2ed119
commit 545f1ab793
10 changed files with 200 additions and 105 deletions

View File

@ -1,23 +1,29 @@
package com.lagradost.cloudstream3.ui.home package com.lagradost.cloudstream3.ui.home
import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.UIHelper.getGridIsCompact
import com.lagradost.cloudstream3.UIHelper.loadResult import com.lagradost.cloudstream3.UIHelper.loadResult
import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.observe import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.ui.AutofitRecyclerView
import com.lagradost.cloudstream3.ui.search.SearchAdapter
import com.lagradost.cloudstream3.utils.DataStore.getKey import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.setKey import com.lagradost.cloudstream3.utils.DataStore.setKey
import com.lagradost.cloudstream3.utils.Event
import com.lagradost.cloudstream3.utils.HOMEPAGE_API import com.lagradost.cloudstream3.utils.HOMEPAGE_API
import kotlinx.android.synthetic.main.fragment_child_downloads.*
import kotlinx.android.synthetic.main.fragment_home.* import kotlinx.android.synthetic.main.fragment_home.*
class HomeFragment : Fragment() { class HomeFragment : Fragment() {
@ -34,8 +40,31 @@ class HomeFragment : Fragment() {
return inflater.inflate(R.layout.fragment_home, container, false) return inflater.inflate(R.layout.fragment_home, container, false)
} }
private val configEvent = Event<Int>()
private var currentSpan = 1
private fun fixGrid() {
val compactView = activity?.getGridIsCompact() ?: false
val spanCountLandscape = if (compactView) 2 else 6
val spanCountPortrait = if (compactView) 1 else 3
val orientation = resources.configuration.orientation
currentSpan = if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
spanCountLandscape
} else {
spanCountPortrait
}
configEvent.invoke(currentSpan)
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
fixGrid()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
fixGrid()
observe(homeViewModel.apiName) { observe(homeViewModel.apiName) {
context?.setKey(HOMEPAGE_API, it) context?.setKey(HOMEPAGE_API, it)
@ -45,7 +74,7 @@ class HomeFragment : Fragment() {
when (it) { when (it) {
is Resource.Success -> { is Resource.Success -> {
val d = it.value val d = it.value
(home_master_recycler?.adapter as ParentItemAdapter?)?.itemList = d.items (home_master_recycler?.adapter as ParentItemAdapter?)?.items = d.items
home_master_recycler?.adapter?.notifyDataSetChanged() home_master_recycler?.adapter?.notifyDataSetChanged()
} }
is Resource.Failure -> { is Resource.Failure -> {
@ -59,8 +88,35 @@ class HomeFragment : Fragment() {
val adapter: RecyclerView.Adapter<RecyclerView.ViewHolder> = ParentItemAdapter(listOf(), { card -> val adapter: RecyclerView.Adapter<RecyclerView.ViewHolder> = ParentItemAdapter(listOf(), { card ->
(activity as AppCompatActivity).loadResult(card.url, card.slug, card.apiName) (activity as AppCompatActivity).loadResult(card.url, card.slug, card.apiName)
}, { }, { item ->
val bottomSheetDialogBuilder = BottomSheetDialog(view.context)
bottomSheetDialogBuilder.setContentView(R.layout.home_episodes_expanded)
val title = bottomSheetDialogBuilder.findViewById<TextView>(R.id.home_expanded_text)!!
title.text = item.name
val recycle = bottomSheetDialogBuilder.findViewById<AutofitRecyclerView>(R.id.home_expanded_recycler)!!
// Span settings
recycle.spanCount = currentSpan
recycle.adapter = SearchAdapter(item.list, recycle) { card ->
bottomSheetDialogBuilder.dismiss()
(activity as AppCompatActivity).loadResult(card.url, card.slug, card.apiName)
}
val spanListener = { span: Int ->
recycle.spanCount = span
(recycle.adapter as SearchAdapter).notifyDataSetChanged()
}
configEvent += spanListener
bottomSheetDialogBuilder.setOnDismissListener {
configEvent -= spanListener
}
(recycle.adapter as SearchAdapter).notifyDataSetChanged()
bottomSheetDialogBuilder.show()
}) })
context?.fixPaddingStatusbar(home_root) context?.fixPaddingStatusbar(home_root)

View File

@ -5,18 +5,16 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.HomePageList import com.lagradost.cloudstream3.HomePageList
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.SearchResponse
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.android.synthetic.main.homepage_parent.view.* import kotlinx.android.synthetic.main.homepage_parent.view.*
class ParentItemAdapter( class ParentItemAdapter(
var itemList: List<HomePageList>, var items: List<HomePageList>,
private val clickCallback: (SearchResponse) -> Unit, private val clickCallback: (SearchResponse) -> Unit,
private val moreInfoClickCallback: (List<SearchResponse>) -> Unit, private val moreInfoClickCallback: (HomePageList) -> Unit,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, i: Int): ParentViewHolder { override fun onCreateViewHolder(parent: ViewGroup, i: Int): ParentViewHolder {
val layout = R.layout.homepage_parent val layout = R.layout.homepage_parent
@ -28,20 +26,20 @@ class ParentItemAdapter(
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) { when (holder) {
is ParentViewHolder -> { is ParentViewHolder -> {
holder.bind(itemList[position]) holder.bind(items[position])
} }
} }
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {
return itemList.size return items.size
} }
class ParentViewHolder class ParentViewHolder
constructor( constructor(
itemView: View, itemView: View,
private val clickCallback: (SearchResponse) -> Unit, private val clickCallback: (SearchResponse) -> Unit,
private val moreInfoClickCallback: (List<SearchResponse>) -> Unit private val moreInfoClickCallback: (HomePageList) -> Unit
) : ) :
RecyclerView.ViewHolder(itemView) { RecyclerView.ViewHolder(itemView) {
val title: TextView = itemView.home_parent_item_title val title: TextView = itemView.home_parent_item_title
@ -53,7 +51,7 @@ class ParentItemAdapter(
(recyclerView.adapter as HomeChildItemAdapter).notifyDataSetChanged() (recyclerView.adapter as HomeChildItemAdapter).notifyDataSetChanged()
moreInfo.setOnClickListener { moreInfo.setOnClickListener {
moreInfoClickCallback.invoke(info.list) moreInfoClickCallback.invoke(info)
} }
} }
} }

View File

@ -25,10 +25,10 @@ import kotlinx.android.synthetic.main.search_result_grid.view.*
import kotlin.math.roundToInt import kotlin.math.roundToInt
class SearchAdapter( class SearchAdapter(
var cardList: ArrayList<Any>, var cardList: List<SearchResponse>,
private val resView: AutofitRecyclerView, private val resView: AutofitRecyclerView,
private val clickCallback: (SearchResponse) -> Unit, private val clickCallback: (SearchResponse) -> Unit,
) : ) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() { RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
@ -70,59 +70,58 @@ class SearchAdapter(
private val compactView = itemView.context.getGridIsCompact() private val compactView = 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: Any) { fun bind(card: SearchResponse) {
if (card is SearchResponse) { // GENERIC if (!compactView) {
if (!compactView) { cardView.apply {
cardView.apply { layoutParams = FrameLayout.LayoutParams(
layoutParams = FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT, coverHeight
coverHeight )
)
}
} }
}
textType?.text = when (card.type) { textType?.text = when (card.type) {
TvType.Anime -> "Anime" TvType.Anime -> "Anime"
TvType.Movie -> "Movie" TvType.Movie -> "Movie"
TvType.ONA -> "ONA" TvType.ONA -> "ONA"
TvType.TvSeries -> "TV" TvType.TvSeries -> "TV"
} }
// search_result_lang?.visibility = View.GONE // search_result_lang?.visibility = View.GONE
textIsDub?.visibility = View.GONE textIsDub?.visibility = View.GONE
textIsSub?.visibility = View.GONE textIsSub?.visibility = View.GONE
cardText.text = card.name cardText.text = card.name
//imageTextProvider.text = card.apiName //imageTextProvider.text = card.apiName
if (!card.posterUrl.isNullOrEmpty()) { if (!card.posterUrl.isNullOrEmpty()) {
val glideUrl = val glideUrl =
GlideUrl(card.posterUrl) GlideUrl(card.posterUrl)
Glide.with(cardView.context) Glide.with(cardView.context)
.load(glideUrl) .load(glideUrl)
.into(cardView) .into(cardView)
} }
bg.setOnClickListener { bg.setOnClickListener {
clickCallback.invoke(card) clickCallback.invoke(card)
} }
when (card) { when (card) {
is AnimeSearchResponse -> { is AnimeSearchResponse -> {
if (card.dubStatus?.size == 1) { if (card.dubStatus?.size == 1) {
//search_result_lang?.visibility = View.VISIBLE //search_result_lang?.visibility = View.VISIBLE
if (card.dubStatus.contains(DubStatus.Dubbed)) { if (card.dubStatus.contains(DubStatus.Dubbed)) {
textIsDub?.visibility = View.VISIBLE textIsDub?.visibility = View.VISIBLE
//search_result_lang?.setColorFilter(ContextCompat.getColor(activity, R.color.dubColor)) //search_result_lang?.setColorFilter(ContextCompat.getColor(activity, R.color.dubColor))
} else if (card.dubStatus.contains(DubStatus.Subbed)) { } else if (card.dubStatus.contains(DubStatus.Subbed)) {
//search_result_lang?.setColorFilter(ContextCompat.getColor(activity, R.color.subColor)) //search_result_lang?.setColorFilter(ContextCompat.getColor(activity, R.color.subColor))
textIsSub?.visibility = View.VISIBLE textIsSub?.visibility = View.VISIBLE
}
} }
} }
} }
} }
} }
} }

View File

@ -135,7 +135,7 @@ class SearchFragment : Fragment() {
is Resource.Success -> { is Resource.Success -> {
it.value.let { data -> it.value.let { data ->
if (data != null) { if (data != null) {
(cardSpace?.adapter as SearchAdapter?)?.cardList = ArrayList(data.filterNotNull()) (cardSpace?.adapter as SearchAdapter?)?.cardList = data.filterNotNull()
cardSpace?.adapter?.notifyDataSetChanged() cardSpace?.adapter?.notifyDataSetChanged()
} }
} }

View File

@ -5,14 +5,15 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.lagradost.cloudstream3.APIHolder.allApi import com.lagradost.cloudstream3.APIHolder.allApi
import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.safeApiCall import com.lagradost.cloudstream3.mvvm.safeApiCall
import com.lagradost.cloudstream3.ui.APIRepository import com.lagradost.cloudstream3.ui.APIRepository
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class SearchViewModel : ViewModel() { class SearchViewModel : ViewModel() {
private val _searchResponse: MutableLiveData<Resource<ArrayList<Any>>> = MutableLiveData() private val _searchResponse: MutableLiveData<Resource<ArrayList<SearchResponse>>> = MutableLiveData()
val searchResponse: LiveData<Resource<ArrayList<Any>>> get() = _searchResponse val searchResponse: LiveData<Resource<ArrayList<SearchResponse>>> get() = _searchResponse
var searchCounter = 0 var searchCounter = 0
private val repo = APIRepository(allApi) private val repo = APIRepository(allApi)
@ -31,7 +32,7 @@ class SearchViewModel : ViewModel() {
val data = repo.search(query) val data = repo.search(query)
if(localSearchCounter != searchCounter) return@launch if(localSearchCounter != searchCounter) return@launch
_searchResponse.postValue(data as Resource<ArrayList<Any>>?) _searchResponse.postValue(data)
} }
fun quickSearch(query: String) = viewModelScope.launch { fun quickSearch(query: String) = viewModelScope.launch {
@ -45,6 +46,6 @@ class SearchViewModel : ViewModel() {
val data = repo.quickSearch(query) val data = repo.quickSearch(query)
if(localSearchCounter != searchCounter) return@launch if(localSearchCounter != searchCounter) return@launch
_searchResponse.postValue(data as Resource<ArrayList<Any>>?) _searchResponse.postValue(data)
} }
} }

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
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="M7.41,8.59L12,13.17l4.59,-4.58L18,10l-6,6 -6,-6 1.41,-1.41z"/>
</vector>

View File

@ -1,59 +1,54 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout <FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" 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" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/homeRoot"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden" android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
android:paddingTop="0dp"> android:paddingTop="0dp">
<FrameLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:id="@+id/homeRoot" android:layout_width="match_parent">
> <com.google.android.material.bottomnavigation.BottomNavigationView
<androidx.constraintlayout.widget.ConstraintLayout android:layout_height="match_parent" android:id="@+id/nav_view"
android:layout_width="match_parent"> android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/darkBackground"
app:itemRippleColor="@color/colorRipple"
<com.google.android.material.bottomnavigation.BottomNavigationView app:layout_constraintLeft_toLeftOf="parent"
android:id="@+id/nav_view" app:layout_constraintRight_toRightOf="parent"
android:layout_width="0dp" app:menu="@menu/bottom_nav_menu"
android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent"/>
android:background="@color/darkBackground" <fragment
app:itemRippleColor="@color/colorRipple" android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:layout_constraintLeft_toLeftOf="parent" android:layout_width="match_parent"
app:layout_constraintRight_toRightOf="parent" android:layout_height="0dp"
app:menu="@menu/bottom_nav_menu" app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"/> app:layout_constraintBottom_toTopOf="@+id/nav_view"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation"
app:layout_constraintEnd_toEndOf="parent"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/nav_view"
android:id="@+id/cast_mini_controller_holder"
>
<!--com.google.android.gms.cast.framework.media.widget.MiniControllerFragment-->
<fragment <fragment
android:id="@+id/nav_host_fragment" app:customCastBackgroundColor="?attr/darkBackground"
android:name="androidx.navigation.fragment.NavHostFragment" app:castControlButtons="@array/cast_mini_controller_control_buttons"
android:layout_width="match_parent" android:id="@+id/cast_mini_controller"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@+id/nav_view"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation"
app:layout_constraintEnd_toEndOf="parent"/>
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/nav_view" android:visibility="gone"
android:id="@+id/cast_mini_controller_holder" class="com.lagradost.cloudstream3.ui.MyMiniControllerFragment"
> tools:ignore="FragmentTagUsage">
<!--com.google.android.gms.cast.framework.media.widget.MiniControllerFragment--> </fragment>
<fragment </LinearLayout>
app:customCastBackgroundColor="?attr/darkBackground" </androidx.constraintlayout.widget.ConstraintLayout>
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">
</fragment>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
</FrameLayout> </FrameLayout>

View File

@ -71,6 +71,7 @@
app:spanCount="3" app:spanCount="3"
android:paddingEnd="8dp" android:paddingEnd="8dp"
android:id="@+id/cardSpace" android:id="@+id/cardSpace"
tools:listitem="@layout/search_result_grid"
android:orientation="vertical" android:orientation="vertical"
> >
</com.lagradost.cloudstream3.ui.AutofitRecyclerView> </com.lagradost.cloudstream3.ui.AutofitRecyclerView>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:orientation="vertical"
android:layout_width="match_parent"
android:background="?attr/darkBackground"
android:layout_height="wrap_content">
<FrameLayout
android:padding="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/home_expanded_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/textColor"
android:gravity="center_vertical"
android:textSize="18sp"
android:textStyle="bold"
tools:text="Trending"
/>
<ImageView
android:layout_marginEnd="5dp"
android:layout_gravity="end|center_vertical"
android:src="@drawable/ic_baseline_keyboard_arrow_down_24"
android:layout_width="30dp"
android:layout_height="match_parent"
android:contentDescription="@string/home_expanded_hide">
</ImageView>
</FrameLayout>
<com.lagradost.cloudstream3.ui.AutofitRecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/home_expanded_recycler"
tools:listitem="@layout/search_result_grid"
/>
</LinearLayout>

View File

@ -55,4 +55,5 @@
<string name="acra_report_toast">Sorry, the application crashed. An anonymous bug report will be sent to the developers</string> <string name="acra_report_toast">Sorry, the application crashed. An anonymous bug report will be sent to the developers</string>
<string name="pref_disable_acra">Disable automatic bug reporting</string> <string name="pref_disable_acra">Disable automatic bug reporting</string>
<string name="home_more_info">More info</string> <string name="home_more_info">More info</string>
<string name="home_expanded_hide">Hide</string>
</resources> </resources>