AquaStream/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt

899 lines
37 KiB
Kotlin
Raw Normal View History

2021-04-30 17:20:15 +00:00
package com.lagradost.cloudstream3.ui.home
2021-07-29 13:39:57 +00:00
import android.annotation.SuppressLint
2021-08-12 00:04:58 +00:00
import android.app.Activity
2021-12-26 00:05:10 +00:00
import android.content.Context
2021-07-29 15:16:08 +00:00
import android.content.Intent
2021-07-29 01:46:10 +00:00
import android.content.res.Configuration
2021-07-29 15:16:08 +00:00
import android.net.Uri
2021-04-30 17:20:15 +00:00
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
2021-12-26 00:05:10 +00:00
import android.widget.*
2022-04-25 18:00:25 +00:00
import androidx.appcompat.widget.SearchView
import androidx.core.view.isVisible
2021-12-26 00:05:10 +00:00
import androidx.core.widget.NestedScrollView
2021-04-30 17:20:15 +00:00
import androidx.fragment.app.Fragment
2021-11-05 21:39:56 +00:00
import androidx.fragment.app.activityViewModels
import androidx.preference.PreferenceManager
2021-07-29 00:19:42 +00:00
import androidx.recyclerview.widget.GridLayoutManager
2021-10-22 13:23:48 +00:00
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearSnapHelper
2021-07-29 00:19:42 +00:00
import androidx.recyclerview.widget.RecyclerView
2021-07-29 01:46:10 +00:00
import com.google.android.material.bottomsheet.BottomSheetDialog
2021-12-26 00:05:10 +00:00
import com.google.android.material.button.MaterialButton
2021-07-30 23:41:54 +00:00
import com.lagradost.cloudstream3.*
2021-07-29 15:16:08 +00:00
import com.lagradost.cloudstream3.APIHolder.apis
import com.lagradost.cloudstream3.APIHolder.filterProviderByPreferredMedia
2021-10-22 13:23:48 +00:00
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
2022-04-06 15:16:08 +00:00
import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
2021-07-29 00:19:42 +00:00
import com.lagradost.cloudstream3.mvvm.Resource
2021-10-10 22:25:49 +00:00
import com.lagradost.cloudstream3.mvvm.logError
2021-07-29 00:19:42 +00:00
import com.lagradost.cloudstream3.mvvm.observe
2021-11-12 16:55:54 +00:00
import com.lagradost.cloudstream3.syncproviders.OAuth2API
2021-09-05 11:56:25 +00:00
import com.lagradost.cloudstream3.ui.APIRepository.Companion.noneApi
import com.lagradost.cloudstream3.ui.APIRepository.Companion.randomApi
2021-07-29 01:46:10 +00:00
import com.lagradost.cloudstream3.ui.AutofitRecyclerView
2021-07-30 23:41:54 +00:00
import com.lagradost.cloudstream3.ui.WatchType
2022-04-25 18:00:25 +00:00
import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment
2021-07-29 15:16:08 +00:00
import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST
2021-08-25 15:28:25 +00:00
import com.lagradost.cloudstream3.ui.search.*
2021-09-12 14:10:22 +00:00
import com.lagradost.cloudstream3.ui.search.SearchFragment.Companion.filterSearchResponse
2021-07-30 23:41:54 +00:00
import com.lagradost.cloudstream3.ui.search.SearchHelper.handleSearchClickCallback
2022-02-18 19:29:48 +00:00
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
2021-11-28 12:18:01 +00:00
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult
2021-07-29 00:19:42 +00:00
import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.setKey
2021-08-25 15:28:25 +00:00
import com.lagradost.cloudstream3.utils.DataStoreHelper
import com.lagradost.cloudstream3.utils.DataStoreHelper.removeLastWatched
2021-07-30 23:41:54 +00:00
import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultWatchState
2021-07-29 01:46:10 +00:00
import com.lagradost.cloudstream3.utils.Event
2021-07-29 00:19:42 +00:00
import com.lagradost.cloudstream3.utils.HOMEPAGE_API
2022-02-03 21:23:00 +00:00
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showOptionSelectStringRes
2022-04-06 15:16:08 +00:00
import com.lagradost.cloudstream3.utils.SubtitleHelper.getFlagFromIso
2021-12-12 02:33:17 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
2021-08-19 20:05:18 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
2021-10-22 13:23:48 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbarView
2021-12-13 18:41:33 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.getSpanCount
2021-08-19 20:05:18 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes
2021-11-07 22:10:19 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.setImage
2022-01-24 20:39:22 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.setImageBlur
2021-10-22 13:23:48 +00:00
import com.lagradost.cloudstream3.widget.CenterZoomLayoutManager
2021-07-29 00:19:42 +00:00
import kotlinx.android.synthetic.main.fragment_home.*
2022-01-24 20:39:22 +00:00
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_main_poster_recyclerview
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_statusbar
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_tv.*
2021-12-09 21:20:27 +00:00
import java.util.*
2021-04-30 17:20:15 +00:00
2021-12-09 21:20:27 +00:00
const val HOME_BOOKMARK_VALUE_LIST = "home_bookmarked_last_list"
2021-12-26 00:05:10 +00:00
const val HOME_PREF_HOMEPAGE = "home_pref_homepage"
2021-07-30 23:41:54 +00:00
2021-04-30 17:20:15 +00:00
class HomeFragment : Fragment() {
2021-08-12 00:04:58 +00:00
companion object {
val configEvent = Event<Int>()
var currentSpan = 1
val listHomepageItems = mutableListOf<SearchResponse>()
2021-08-12 00:04:58 +00:00
private val errorProfilePics = listOf(
R.drawable.monke_benene,
R.drawable.monke_burrito,
R.drawable.monke_coco,
R.drawable.monke_cookie,
R.drawable.monke_flusdered,
R.drawable.monke_funny,
R.drawable.monke_like,
R.drawable.monke_party,
R.drawable.monke_sob,
R.drawable.monke_drink,
)
val errorProfilePic = errorProfilePics.random()
2021-08-12 00:04:58 +00:00
fun Activity.loadHomepageList(item: HomePageList) {
val context = this
val bottomSheetDialogBuilder = BottomSheetDialog(context)
bottomSheetDialogBuilder.setContentView(R.layout.home_episodes_expanded)
val title = bottomSheetDialogBuilder.findViewById<TextView>(R.id.home_expanded_text)!!
title.text = item.name
2022-01-24 20:39:22 +00:00
val recycle =
bottomSheetDialogBuilder.findViewById<AutofitRecyclerView>(R.id.home_expanded_recycler)!!
val titleHolder =
bottomSheetDialogBuilder.findViewById<FrameLayout>(R.id.home_expanded_drag_down)!!
2021-08-12 00:04:58 +00:00
titleHolder.setOnClickListener {
2021-12-12 02:33:17 +00:00
bottomSheetDialogBuilder.dismissSafe(this)
2021-08-12 00:04:58 +00:00
}
// Span settings
recycle.spanCount = currentSpan
2022-02-05 01:05:13 +00:00
recycle.adapter = SearchAdapter(item.list.toMutableList(), recycle) { callback ->
2021-08-12 00:04:58 +00:00
handleSearchClickCallback(this, callback)
2021-08-25 15:28:25 +00:00
if (callback.action == SEARCH_ACTION_LOAD || callback.action == SEARCH_ACTION_PLAY_FILE) {
2021-12-12 02:33:17 +00:00
bottomSheetDialogBuilder.dismissSafe(this)
2021-08-12 00:04:58 +00:00
}
}
val spanListener = { span: Int ->
recycle.spanCount = span
2022-02-13 00:53:40 +00:00
//(recycle.adapter as SearchAdapter).notifyDataSetChanged()
2021-08-12 00:04:58 +00:00
}
configEvent += spanListener
bottomSheetDialogBuilder.setOnDismissListener {
configEvent -= spanListener
}
2022-02-13 00:53:40 +00:00
//(recycle.adapter as SearchAdapter).notifyDataSetChanged()
2021-08-12 00:04:58 +00:00
bottomSheetDialogBuilder.show()
}
2021-12-26 00:05:10 +00:00
fun getPairList(
anime: MaterialButton?,
cartoons: MaterialButton?,
tvs: MaterialButton?,
docs: MaterialButton?,
2022-03-21 11:07:36 +00:00
movies: MaterialButton?,
asian: MaterialButton?,
): List<Pair<MaterialButton?, List<TvType>>> {
return listOf(
2022-01-31 20:47:59 +00:00
Pair(anime, listOf(TvType.Anime, TvType.OVA, TvType.AnimeMovie)),
Pair(cartoons, listOf(TvType.Cartoon)),
Pair(tvs, listOf(TvType.TvSeries)),
Pair(docs, listOf(TvType.Documentary)),
2022-03-21 11:07:36 +00:00
Pair(movies, listOf(TvType.Movie, TvType.Torrent)),
Pair(asian, listOf(TvType.AsianDrama)),
)
}
2021-12-26 00:05:10 +00:00
fun Context.selectHomepage(selectedApiName: String?, callback: (String) -> Unit) {
val validAPIs = filterProviderByPreferredMedia().toMutableList()
validAPIs.add(0, randomApi)
validAPIs.add(0, noneApi)
//val builder: AlertDialog.Builder = AlertDialog.Builder(this)
//builder.setView(R.layout.home_select_mainpage)
val builder =
BottomSheetDialog(this)
builder.setContentView(R.layout.home_select_mainpage)
builder.show()
builder.let { dialog ->
2022-04-06 15:16:08 +00:00
val isMultiLang = getApiProviderLangSettings().size > 1
2021-12-26 00:05:10 +00:00
//dialog.window?.setGravity(Gravity.BOTTOM)
var currentApiName = selectedApiName
var currentValidApis: MutableList<MainAPI> = mutableListOf()
val preSelectedTypes = this.getKey<List<String>>(HOME_PREF_HOMEPAGE)
2022-01-24 20:39:22 +00:00
?.mapNotNull { listName -> TvType.values().firstOrNull { it.name == listName } }
?.toMutableList()
2021-12-26 00:05:10 +00:00
?: mutableListOf(TvType.Movie, TvType.TvSeries)
val anime = dialog.findViewById<MaterialButton>(R.id.home_select_anime)
val cartoons = dialog.findViewById<MaterialButton>(R.id.home_select_cartoons)
val tvs = dialog.findViewById<MaterialButton>(R.id.home_select_tv_series)
val docs = dialog.findViewById<MaterialButton>(R.id.home_select_documentaries)
val movies = dialog.findViewById<MaterialButton>(R.id.home_select_movies)
2022-03-21 11:07:36 +00:00
val asian = dialog.findViewById<MaterialButton>(R.id.home_select_asian)
2021-12-26 00:05:10 +00:00
val cancelBtt = dialog.findViewById<MaterialButton>(R.id.cancel_btt)
val applyBtt = dialog.findViewById<MaterialButton>(R.id.apply_btt)
2022-03-21 11:07:36 +00:00
val pairList = getPairList(anime, cartoons, tvs, docs, movies, asian)
2021-12-26 00:05:10 +00:00
cancelBtt?.setOnClickListener {
dialog.dismissSafe()
}
applyBtt?.setOnClickListener {
if (currentApiName != selectedApiName) {
currentApiName?.let(callback)
}
dialog.dismissSafe()
}
val listView = dialog.findViewById<ListView>(R.id.listview1)
val arrayAdapter = ArrayAdapter<String>(this, R.layout.sort_bottom_single_choice)
listView?.adapter = arrayAdapter
listView?.choiceMode = AbsListView.CHOICE_MODE_SINGLE
listView?.setOnItemClickListener { _, _, i, _ ->
2022-06-02 22:51:41 +00:00
if (currentValidApis.isNotEmpty()) {
2021-12-26 00:05:10 +00:00
currentApiName = currentValidApis[i].name
//to switch to apply simply remove this
currentApiName?.let(callback)
dialog.dismissSafe()
}
}
fun updateList() {
this.setKey(HOME_PREF_HOMEPAGE, preSelectedTypes)
arrayAdapter.clear()
currentValidApis = validAPIs.filter { api ->
api.hasMainPage && api.supportedTypes.any {
preSelectedTypes.contains(it)
}
2022-04-06 15:16:08 +00:00
}.sortedBy { it.name.lowercase() }.toMutableList()
2021-12-26 00:05:10 +00:00
currentValidApis.addAll(0, validAPIs.subList(0, 2))
2022-04-25 18:00:25 +00:00
val names =
currentValidApis.map { if (isMultiLang) "${getFlagFromIso(it.lang)?.plus(" ") ?: ""}${it.name}" else it.name }
2022-04-08 22:13:09 +00:00
val index = currentValidApis.map { it.name }.indexOf(currentApiName)
2021-12-26 00:05:10 +00:00
listView?.setItemChecked(index, true)
arrayAdapter.addAll(names)
arrayAdapter.notifyDataSetChanged()
}
for ((button, validTypes) in pairList) {
2022-01-24 20:39:22 +00:00
val isValid =
validAPIs.any { api -> validTypes.any { api.supportedTypes.contains(it) } }
2021-12-26 00:05:10 +00:00
button?.isVisible = isValid
if (isValid) {
fun buttonContains(): Boolean {
return preSelectedTypes.any { validTypes.contains(it) }
}
button?.isSelected = buttonContains()
button?.setOnClickListener {
preSelectedTypes.clear()
preSelectedTypes.addAll(validTypes)
for ((otherButton, _) in pairList) {
otherButton?.isSelected = false
}
button.isSelected = true
updateList()
}
button?.setOnLongClickListener {
if (!buttonContains()) {
button.isSelected = true
preSelectedTypes.addAll(validTypes)
} else {
button.isSelected = false
preSelectedTypes.removeAll(validTypes)
}
updateList()
return@setOnLongClickListener true
}
}
}
updateList()
}
}
2021-08-12 00:04:58 +00:00
}
2021-11-05 21:39:56 +00:00
private val homeViewModel: HomeViewModel by activityViewModels()
2021-04-30 17:20:15 +00:00
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
2021-11-05 21:39:56 +00:00
//homeViewModel =
// ViewModelProvider(this).get(HomeViewModel::class.java)
2022-01-24 20:39:22 +00:00
val layout =
if (context?.isTvSettings() == true) R.layout.fragment_home_tv else R.layout.fragment_home
return inflater.inflate(layout, container, false)
2021-07-29 00:19:42 +00:00
}
2021-07-29 13:39:57 +00:00
private var currentHomePage: HomePageResponse? = null
private fun toggleMainVisibility(visible: Boolean) {
2022-01-24 20:39:22 +00:00
home_main_holder?.isVisible = visible
home_main_poster_recyclerview?.isVisible = visible
2021-07-29 13:39:57 +00:00
}
2021-07-29 01:46:10 +00:00
private fun fixGrid() {
2021-12-13 18:41:33 +00:00
activity?.getSpanCount()?.let {
currentSpan = it
2021-07-29 01:46:10 +00:00
}
configEvent.invoke(currentSpan)
}
2021-07-29 15:16:08 +00:00
private val apiChangeClickListener = View.OnClickListener { view ->
2021-12-26 00:05:10 +00:00
view.context.selectHomepage(currentApiName) { api ->
homeViewModel.loadAndCancel(api)
}
/*val validAPIs = view.context?.filterProviderByPreferredMedia()?.toMutableList() ?: mutableListOf()
2021-09-05 11:56:25 +00:00
validAPIs.add(0, randomApi)
validAPIs.add(0, noneApi)
2021-07-29 15:16:08 +00:00
view.popupMenuNoIconsAndNoStringRes(validAPIs.mapIndexed { index, api -> Pair(index, api.name) }) {
homeViewModel.loadAndCancel(validAPIs[itemId].name)
2021-12-26 00:05:10 +00:00
}*/
2021-07-29 15:16:08 +00:00
}
2021-07-29 01:46:10 +00:00
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
fixGrid()
}
2021-07-30 23:41:54 +00:00
override fun onResume() {
super.onResume()
2021-09-25 13:00:59 +00:00
reloadStored()
2021-07-30 23:41:54 +00:00
}
2021-09-25 13:00:59 +00:00
/*
2021-07-30 23:41:54 +00:00
override fun onStop() {
backEvent -= ::handleBack
super.onStop()
2021-09-25 13:00:59 +00:00
}*/
2021-07-30 23:41:54 +00:00
private fun reloadStored() {
homeViewModel.loadResumeWatching()
val list = EnumSet.noneOf(WatchType::class.java)
getKey<IntArray>(HOME_BOOKMARK_VALUE_LIST)?.map { WatchType.fromInternalId(it) }?.let {
list.addAll(it)
2021-07-30 23:41:54 +00:00
}
homeViewModel.loadStoredData(list)
2021-07-30 23:41:54 +00:00
}
2021-09-25 13:00:59 +00:00
/*private fun handleBack(poppedFragment: Boolean) {
2021-07-30 23:41:54 +00:00
if (poppedFragment) {
reloadStored()
}
2021-09-25 13:00:59 +00:00
}*/
2021-07-30 23:41:54 +00:00
private fun focusCallback(card: SearchResponse) {
2022-01-24 20:39:22 +00:00
home_focus_text?.text = card.name
home_blur_poster?.setImageBlur(card.posterUrl, 50)
2022-01-24 20:39:22 +00:00
}
private fun homeHandleSearch(callback: SearchClickCallback) {
if (callback.action == SEARCH_ACTION_FOCUSED) {
2022-01-24 20:39:22 +00:00
focusCallback(callback.card)
} else {
handleSearchClickCallback(activity, callback)
}
}
private var currentApiName: String? = null
private var toggleRandomButton = false
2021-12-26 00:05:10 +00:00
2021-10-22 13:23:48 +00:00
@SuppressLint("SetTextI18n")
2021-07-29 00:19:42 +00:00
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
2021-07-29 01:46:10 +00:00
fixGrid()
2021-07-29 00:19:42 +00:00
2022-01-14 18:14:24 +00:00
home_change_api?.setOnClickListener(apiChangeClickListener)
home_change_api_loading?.setOnClickListener(apiChangeClickListener)
home_api_fab?.setOnClickListener(apiChangeClickListener)
home_random?.setOnClickListener {
if (listHomepageItems.isNotEmpty()) {
activity.loadSearchResult(listHomepageItems.random())
}
}
//Disable Random button, if its toggled off on settings
context?.let {
val settingsManager = PreferenceManager.getDefaultSharedPreferences(it)
2022-04-25 18:00:25 +00:00
toggleRandomButton =
settingsManager.getBoolean(getString(R.string.random_button_key), false)
home_random?.isVisible = toggleRandomButton
if (!toggleRandomButton) {
home_random?.visibility = View.GONE
}
}
2021-07-29 15:16:08 +00:00
2021-10-22 13:23:48 +00:00
observe(homeViewModel.apiName) { apiName ->
2021-12-26 00:05:10 +00:00
currentApiName = apiName
setKey(HOMEPAGE_API, apiName)
2022-04-25 18:00:25 +00:00
home_api_fab?.text = apiName
2021-10-22 13:23:48 +00:00
home_provider_name?.text = apiName
2022-04-30 20:31:32 +00:00
try {
home_search?.queryHint = getString(R.string.search_hint_site).format(apiName)
} catch (e: Exception) {
logError(e)
}
2021-10-22 13:23:48 +00:00
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)),
2021-10-22 13:23:48 +00:00
Pair(R.string.cartoons, listOf(TvType.Cartoon)),
2022-01-31 20:47:59 +00:00
Pair(R.string.anime, listOf(TvType.Anime, TvType.OVA, TvType.AnimeMovie)),
2021-10-22 13:23:48 +00:00
Pair(R.string.torrent, listOf(TvType.Torrent)),
2022-03-21 11:07:36 +00:00
Pair(R.string.asian_drama, listOf(TvType.AsianDrama)),
2021-10-22 13:23:48 +00:00
).filter { item -> currentApi.supportedTypes.any { type -> item.second.contains(type) } }
2022-01-24 20:39:22 +00:00
home_provider_meta_info?.text =
typeChoices.joinToString(separator = ", ") { getString(it.first) }
2021-10-22 13:23:48 +00:00
home_provider_meta_info?.isVisible = true
}
2021-07-29 00:19:42 +00:00
}
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
2022-01-24 20:39:22 +00:00
home_main_poster_recyclerview?.adapter =
2021-11-28 12:18:01 +00:00
HomeChildItemAdapter(
2022-02-13 00:53:40 +00:00
items.toMutableList(),
2021-11-28 12:18:01 +00:00
R.layout.home_result_big_grid,
nextFocusUp = home_main_poster_recyclerview.nextFocusUpId,
nextFocusDown = home_main_poster_recyclerview.nextFocusDownId
) { callback ->
2022-01-24 20:39:22 +00:00
homeHandleSearch(callback)
}
2022-01-24 20:39:22 +00:00
if (context?.isTvSettings() == false) {
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)
}
}
}
}
}
2022-01-24 20:39:22 +00:00
} else {
items.firstOrNull()?.let {
focusCallback(it)
}
}
toggleMainVisibility(true)
}
}
2022-04-25 18:00:25 +00:00
home_search?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
2022-04-30 01:13:50 +00:00
QuickSearchFragment.pushSearch(activity, query, currentApiName?.let { arrayOf(it) })
2022-04-25 18:00:25 +00:00
return true
}
override fun onQueryTextChange(newText: String): Boolean {
//searchViewModel.quickSearch(newText)
return true
}
})
2021-07-29 15:16:08 +00:00
observe(homeViewModel.page) { data ->
when (data) {
2021-07-29 00:19:42 +00:00
is Resource.Success -> {
2021-12-10 23:57:11 +00:00
home_loading_shimmer?.stopShimmer()
2021-07-29 15:16:08 +00:00
val d = data.value
listHomepageItems.clear()
2021-09-12 14:10:22 +00:00
2021-07-29 13:39:57 +00:00
currentHomePage = d
2022-02-13 00:53:40 +00:00
(home_master_recycler?.adapter as? ParentItemAdapter?)?.updateList(
2021-12-11 00:26:54 +00:00
d?.items?.mapNotNull {
2021-10-10 22:25:49 +00:00
try {
listHomepageItems.addAll(it.list.filterSearchResponse())
2021-10-10 22:25:49 +00:00
HomePageList(it.name, it.list.filterSearchResponse())
2021-10-22 13:23:48 +00:00
} catch (e: Exception) {
2021-10-10 22:25:49 +00:00
logError(e)
null
}
2022-01-30 22:02:57 +00:00
} ?: listOf())
2021-07-29 15:16:08 +00:00
2021-12-10 23:57:11 +00:00
home_loading?.isVisible = false
home_loading_error?.isVisible = false
home_loaded?.isVisible = true
if (toggleRandomButton) {
home_random?.isVisible = listHomepageItems.isNotEmpty()
}
2021-07-29 00:19:42 +00:00
}
is Resource.Failure -> {
2021-12-10 23:57:11 +00:00
home_loading_shimmer?.stopShimmer()
2021-07-29 15:16:08 +00:00
result_error_text.text = data.errorString
home_reload_connectionerror.setOnClickListener(apiChangeClickListener)
home_reload_connection_open_in_browser.setOnClickListener { view ->
val validAPIs = apis//.filter { api -> api.hasMainPage }
view.popupMenuNoIconsAndNoStringRes(validAPIs.mapIndexed { index, api ->
Pair(
index,
api.name
)
}) {
2022-01-30 22:02:57 +00:00
try {
val i = Intent(Intent.ACTION_VIEW)
i.data = Uri.parse(validAPIs[itemId].mainUrl)
startActivity(i)
} catch (e: Exception) {
logError(e)
}
2021-07-29 15:16:08 +00:00
}
}
2021-07-29 00:19:42 +00:00
2021-12-10 23:57:11 +00:00
home_loading?.isVisible = false
home_loading_error?.isVisible = true
home_loaded?.isVisible = false
2021-07-29 00:19:42 +00:00
}
is Resource.Loading -> {
2022-02-13 00:53:40 +00:00
(home_master_recycler?.adapter as? ParentItemAdapter?)?.updateList(listOf())
2021-12-10 23:57:11 +00:00
home_loading_shimmer?.startShimmer()
home_loading?.isVisible = true
home_loading_error?.isVisible = false
home_loaded?.isVisible = false
2021-07-29 00:19:42 +00:00
}
}
}
2022-01-24 20:39:22 +00:00
val adapter: RecyclerView.Adapter<RecyclerView.ViewHolder> =
2022-01-30 22:02:57 +00:00
ParentItemAdapter(mutableListOf(), { callback ->
2022-01-24 20:39:22 +00:00
homeHandleSearch(callback)
}, { item ->
activity?.loadHomepageList(item)
})
2021-07-29 00:54:27 +00:00
2021-12-09 21:20:27 +00:00
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),
)
for (item in toggleList) {
val watch = item.second
2021-12-26 00:05:10 +00:00
item.first?.setOnClickListener {
homeViewModel.loadStoredData(EnumSet.of(watch))
}
item.first?.setOnLongClickListener { itemView ->
2021-12-09 21:20:27 +00:00
val list = EnumSet.noneOf(WatchType::class.java)
2022-01-24 20:39:22 +00:00
itemView.context.getKey<IntArray>(HOME_BOOKMARK_VALUE_LIST)
?.map { WatchType.fromInternalId(it) }?.let {
list.addAll(it)
}
2021-12-09 21:20:27 +00:00
if (list.contains(watch)) {
list.remove(watch)
} else {
list.add(watch)
}
homeViewModel.loadStoredData(list)
2021-12-10 19:48:21 +00:00
return@setOnLongClickListener true
}
2021-12-09 21:20:27 +00:00
}
2021-07-30 23:41:54 +00:00
observe(homeViewModel.availableWatchStatusTypes) { availableWatchStatusTypes ->
2021-12-09 21:20:27 +00:00
context?.setKey(
HOME_BOOKMARK_VALUE_LIST,
availableWatchStatusTypes.first.map { it.internalId }.toIntArray()
)
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 {
2021-07-30 23:41:54 +00:00
it.popupMenuNoIcons(availableWatchStatusTypes.second.map { type ->
Pair(
type.internalId,
type.stringRes
)
}) {
homeViewModel.loadStoredData(it.context, WatchType.fromInternalId(this.itemId))
}
}
2021-12-09 21:20:27 +00:00
home_bookmarked_parent_item_title?.text = getString(availableWatchStatusTypes.first.stringRes)*/
2021-07-30 23:41:54 +00:00
}
2022-02-13 00:53:40 +00:00
observe(homeViewModel.bookmarks) { (isVis, bookmarks) ->
home_bookmarked_holder.isVisible = isVis
2021-12-09 21:20:27 +00:00
2022-02-13 00:53:40 +00:00
(home_bookmarked_child_recyclerview?.adapter as? HomeChildItemAdapter?)?.updateList(
2022-01-24 20:39:22 +00:00
bookmarks
2022-02-13 00:53:40 +00:00
)
2021-07-30 23:41:54 +00:00
2021-12-09 21:20:27 +00:00
home_bookmarked_child_more_info?.setOnClickListener {
2021-08-12 00:04:58 +00:00
activity?.loadHomepageList(
2021-07-30 23:41:54 +00:00
HomePageList(
2021-12-09 21:20:27 +00:00
getString(R.string.error_bookmarks_text), //home_bookmarked_parent_item_title?.text?.toString() ?: getString(R.string.error_bookmarks_text),
2021-07-30 23:41:54 +00:00
bookmarks
)
)
}
}
2021-08-25 15:28:25 +00:00
observe(homeViewModel.resumeWatching) { resumeWatching ->
home_watch_holder?.isVisible = resumeWatching.isNotEmpty()
2022-02-13 00:53:40 +00:00
(home_watch_child_recyclerview?.adapter as? HomeChildItemAdapter?)?.updateList(
2022-01-24 20:39:22 +00:00
resumeWatching
2022-02-13 00:53:40 +00:00
)
//if (context?.isTvSettings() == true) {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// context?.addProgramsToContinueWatching(resumeWatching.mapNotNull { it as? DataStoreHelper.ResumeWatchingResult })
// }
//}
2021-08-25 15:28:25 +00:00
home_watch_child_more_info?.setOnClickListener {
2021-08-25 15:28:25 +00:00
activity?.loadHomepageList(
HomePageList(
2022-01-24 20:39:22 +00:00
home_watch_parent_item_title?.text?.toString()
?: getString(R.string.continue_watching),
2021-08-25 15:28:25 +00:00
resumeWatching
)
)
}
}
2021-11-28 12:18:01 +00:00
home_bookmarked_child_recyclerview.adapter = HomeChildItemAdapter(
ArrayList(),
nextFocusUp = home_bookmarked_child_recyclerview?.nextFocusUpId,
nextFocusDown = home_bookmarked_child_recyclerview?.nextFocusDownId
) { callback ->
2021-07-30 23:41:54 +00:00
if (callback.action == SEARCH_ACTION_SHOW_METADATA) {
2022-02-03 21:23:00 +00:00
activity?.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) ->
fun play() {
activity.loadSearchResult(callback.card, START_ACTION_RESUME_LATEST)
reloadStored()
}
fun remove() {
setResultWatchState(callback.card.id, WatchType.NONE.internalId)
reloadStored()
}
fun info() {
handleSearchClickCallback(
activity,
SearchClickCallback(
SEARCH_ACTION_LOAD,
callback.view,
-1,
callback.card
2022-01-24 20:39:22 +00:00
)
)
2022-02-03 21:23:00 +00:00
reloadStored()
}
if (isTv) {
when (actionId) {
0 -> {
play()
}
1 -> {
info()
}
2 -> {
remove()
}
}
} else {
when (actionId) {
0 -> {
info()
}
1 -> {
remove()
}
2021-07-30 23:41:54 +00:00
}
}
}
} else {
2022-01-24 20:39:22 +00:00
homeHandleSearch(callback)
2021-07-30 23:41:54 +00:00
}
}
2022-01-24 20:39:22 +00:00
home_watch_child_recyclerview?.adapter = HomeChildItemAdapter(
2021-11-28 12:18:01 +00:00
ArrayList(),
nextFocusUp = home_watch_child_recyclerview?.nextFocusUpId,
nextFocusDown = home_watch_child_recyclerview?.nextFocusDownId
) { callback ->
2021-08-25 15:28:25 +00:00
if (callback.action == SEARCH_ACTION_SHOW_METADATA) {
2022-02-03 21:23:00 +00:00
activity?.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) ->
fun play() {
activity.loadSearchResult(callback.card, START_ACTION_RESUME_LATEST)
reloadStored()
}
fun remove() {
val card = callback.card
if (card is DataStoreHelper.ResumeWatchingResult) {
removeLastWatched(card.parentId)
2021-08-25 15:28:25 +00:00
reloadStored()
}
2022-02-03 21:23:00 +00:00
}
fun info() {
handleSearchClickCallback(
activity,
SearchClickCallback(
SEARCH_ACTION_LOAD,
callback.view,
-1,
callback.card
)
)
reloadStored()
}
if (isTv) {
when (actionId) {
0 -> {
play()
}
1 -> {
info()
}
2 -> {
remove()
}
}
} else {
when (actionId) {
0 -> {
info()
}
1 -> {
remove()
2021-08-25 15:28:25 +00:00
}
}
}
2022-02-03 21:23:00 +00:00
2021-08-25 15:28:25 +00:00
}
} else {
2022-01-24 20:39:22 +00:00
homeHandleSearch(callback)
2021-08-25 15:28:25 +00:00
}
}
2021-10-22 13:23:48 +00:00
context?.fixPaddingStatusbarView(home_statusbar)
context?.fixPaddingStatusbar(home_loading_statusbar)
2021-07-29 00:19:42 +00:00
2022-01-24 20:39:22 +00:00
2021-07-29 00:19:42 +00:00
home_master_recycler.adapter = adapter
home_master_recycler.layoutManager = GridLayoutManager(context, 1)
2022-01-24 20:39:22 +00:00
if (context?.isTvSettings() == false) {
LinearSnapHelper().attachToRecyclerView(home_main_poster_recyclerview) // snap
val centerLayoutManager =
CenterZoomLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
centerLayoutManager.setOnSizeListener { index ->
(home_main_poster_recyclerview?.adapter as HomeChildItemAdapter?)?.cardList?.get(
index
)?.let { random ->
home_main_play?.setOnClickListener {
activity.loadSearchResult(random, START_ACTION_RESUME_LATEST)
}
home_main_info?.setOnClickListener {
activity.loadSearchResult(random)
}
2021-10-22 13:23:48 +00:00
2022-01-24 20:39:22 +00:00
home_main_text?.text =
random.name + if (random is AnimeSearchResponse && !random.dubStatus.isNullOrEmpty()) {
2022-04-13 17:29:30 +00:00
random.dubStatus?.joinToString(
2022-01-24 20:39:22 +00:00
prefix = "",
separator = " | "
) { it.name }
} else ""
}
2021-10-22 13:23:48 +00:00
}
2022-01-24 20:39:22 +00:00
home_main_poster_recyclerview?.layoutManager = centerLayoutManager // scale
2021-10-22 13:23:48 +00:00
}
2021-07-30 23:41:54 +00:00
reloadStored()
2021-09-20 21:11:36 +00:00
val apiName = context?.getKey<String>(HOMEPAGE_API)
2021-10-22 13:23:48 +00:00
if (homeViewModel.apiName.value != apiName || apiName == null) {
//println("Caught home: " + homeViewModel.apiName.value + " at " + apiName)
homeViewModel.loadAndCancel(apiName)
2021-09-20 21:11:36 +00:00
}
2021-11-07 22:10:19 +00:00
2021-12-26 00:05:10 +00:00
home_loaded.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { view, _, scrollY, _, oldScrollY ->
val dy = scrollY - oldScrollY
if (dy > 0) { //check for scroll down
home_api_fab?.shrink() // hide
home_random?.shrink()
2021-12-26 00:05:10 +00:00
} else if (dy < -5) {
if (view?.context?.isTvSettings() == false) {
home_api_fab?.extend() // show
home_random?.extend()
2021-12-26 00:05:10 +00:00
}
}
})
2021-11-07 22:10:19 +00:00
// nice profile pic on homepage
home_profile_picture_holder?.isVisible = false
context?.let { ctx ->
2021-11-28 12:18:01 +00:00
// just in case
if (ctx.isTvSettings()) {
2021-12-26 00:05:10 +00:00
home_api_fab?.isVisible = false
home_change_api?.isVisible = true
2022-03-21 11:07:36 +00:00
if (ctx.isTrueTvSettings()) {
2022-02-18 19:29:48 +00:00
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
}
2021-12-09 21:20:27 +00:00
// home_bookmark_select?.isFocusable = true
// home_bookmark_select?.isFocusableInTouchMode = true
2021-12-26 00:05:10 +00:00
} else {
home_api_fab?.isVisible = true
home_change_api?.isVisible = false
home_change_api_loading?.isVisible = false
2021-11-28 12:18:01 +00:00
}
2021-11-12 16:55:54 +00:00
for (syncApi in OAuth2API.OAuth2Apis) {
val login = syncApi.loginInfo()
2021-11-07 22:10:19 +00:00
val pic = login?.profilePicture
2022-04-30 20:31:32 +00:00
if (home_profile_picture?.setImage(
pic,
errorImageDrawable = errorProfilePic
) == true
) {
2022-04-03 11:51:35 +00:00
home_profile_picture_holder?.isVisible = true
2021-11-07 22:10:19 +00:00
break
}
}
}
2021-04-30 17:20:15 +00:00
}
}