forked from recloudstream/cloudstream
fixed homepage
This commit is contained in:
parent
1c494f0ce2
commit
f268418190
7 changed files with 316 additions and 227 deletions
|
@ -1,40 +1,39 @@
|
|||
package com.lagradost.cloudstream3.plugins
|
||||
|
||||
import android.app.*
|
||||
import dalvik.system.PathClassLoader
|
||||
import com.google.gson.Gson
|
||||
import android.content.Context
|
||||
import android.content.res.AssetManager
|
||||
import android.content.res.Resources
|
||||
import android.os.Environment
|
||||
import android.widget.Toast
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.google.gson.Gson
|
||||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.APIHolder.removePluginMapping
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||
import com.lagradost.cloudstream3.plugins.RepositoryManager.ONLINE_PLUGINS_FOLDER
|
||||
import com.lagradost.cloudstream3.plugins.RepositoryManager.downloadPluginToFile
|
||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||
import com.lagradost.cloudstream3.plugins.RepositoryManager.getRepoPlugins
|
||||
import com.lagradost.cloudstream3.ui.settings.extensions.REPOSITORIES_KEY
|
||||
import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData
|
||||
import com.lagradost.cloudstream3.utils.VideoDownloadManager.sanitizeFilename
|
||||
import com.lagradost.cloudstream3.APIHolder.removePluginMapping
|
||||
import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent
|
||||
import com.lagradost.cloudstream3.mvvm.debugPrint
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||
import com.lagradost.cloudstream3.plugins.RepositoryManager.ONLINE_PLUGINS_FOLDER
|
||||
import com.lagradost.cloudstream3.plugins.RepositoryManager.PREBUILT_REPOSITORIES
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||
import com.lagradost.cloudstream3.plugins.RepositoryManager.downloadPluginToFile
|
||||
import com.lagradost.cloudstream3.plugins.RepositoryManager.getRepoPlugins
|
||||
import com.lagradost.cloudstream3.ui.settings.extensions.REPOSITORIES_KEY
|
||||
import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
|
||||
import com.lagradost.cloudstream3.utils.VideoDownloadManager.sanitizeFilename
|
||||
import com.lagradost.cloudstream3.utils.extractorApis
|
||||
import dalvik.system.PathClassLoader
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import java.io.File
|
||||
|
@ -217,7 +216,7 @@ object PluginManager {
|
|||
* 3. If outdated download and load the plugin
|
||||
* 4. Else load the plugin normally
|
||||
**/
|
||||
fun updateAllOnlinePluginsAndLoadThem(activity: Activity) = ioSafe {
|
||||
fun updateAllOnlinePluginsAndLoadThem(activity: Activity) {
|
||||
// Load all plugins as fast as possible!
|
||||
loadAllOnlinePlugins(activity)
|
||||
|
||||
|
@ -227,7 +226,7 @@ object PluginManager {
|
|||
val urls = (getKey<Array<RepositoryData>>(REPOSITORIES_KEY)
|
||||
?: emptyArray()) + PREBUILT_REPOSITORIES
|
||||
|
||||
val onlinePlugins = urls.toList().amap {
|
||||
val onlinePlugins = urls.toList().apmap {
|
||||
getRepoPlugins(it.url)?.toList() ?: emptyList()
|
||||
}.flatten().distinctBy { it.second.url }
|
||||
|
||||
|
@ -248,7 +247,7 @@ object PluginManager {
|
|||
|
||||
val updatedPlugins = mutableListOf<String>()
|
||||
|
||||
outdatedPlugins.amap { pluginData ->
|
||||
outdatedPlugins.apmap { pluginData ->
|
||||
if (pluginData.isDisabled) {
|
||||
//updatedPlugins.add(activity.getString(R.string.single_plugin_disabled, pluginData.onlineData.second.name))
|
||||
unloadPlugin(pluginData.savedData.filePath)
|
||||
|
@ -279,9 +278,9 @@ object PluginManager {
|
|||
/**
|
||||
* Use updateAllOnlinePluginsAndLoadThem
|
||||
* */
|
||||
fun loadAllOnlinePlugins(activity: Activity) = ioSafe {
|
||||
fun loadAllOnlinePlugins(activity: Activity) {
|
||||
// Load all plugins as fast as possible!
|
||||
(getPluginsOnline()).toList().amap { pluginData ->
|
||||
(getPluginsOnline()).toList().apmap { pluginData ->
|
||||
loadPlugin(
|
||||
activity,
|
||||
File(pluginData.filePath),
|
||||
|
@ -290,7 +289,7 @@ object PluginManager {
|
|||
}
|
||||
}
|
||||
|
||||
fun loadAllLocalPlugins(activity: Activity) = ioSafe {
|
||||
fun loadAllLocalPlugins(activity: Activity) {
|
||||
val dir = File(LOCAL_PLUGINS_PATH)
|
||||
removeKey(PLUGINS_KEY_LOCAL)
|
||||
|
||||
|
@ -298,7 +297,7 @@ object PluginManager {
|
|||
val res = dir.mkdirs()
|
||||
if (!res) {
|
||||
Log.w(TAG, "Failed to create local directories")
|
||||
return@ioSafe
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.lagradost.cloudstream3.ui.home
|
||||
|
||||
import android.animation.LayoutTransition
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
|
@ -26,13 +25,13 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.transition.ChangeBounds
|
||||
import androidx.transition.TransitionManager
|
||||
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
|
||||
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.ChipGroup
|
||||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.APIHolder.allProviders
|
||||
import com.lagradost.cloudstream3.APIHolder.apis
|
||||
import com.lagradost.cloudstream3.APIHolder.filterProviderByPreferredMedia
|
||||
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
|
||||
|
@ -554,7 +553,9 @@ class HomeFragment : Fragment() {
|
|||
is Resource.Success -> {
|
||||
home_preview?.isVisible = true
|
||||
(home_preview_viewpager?.adapter as? HomeScrollAdapter)?.apply {
|
||||
setItems(preview.value)
|
||||
if (!setItems(preview.value.second, preview.value.first)) {
|
||||
home_preview_viewpager?.setCurrentItem(0, false)
|
||||
}
|
||||
// home_preview_viewpager?.setCurrentItem(1000, false)
|
||||
}
|
||||
|
||||
|
@ -563,6 +564,10 @@ class HomeFragment : Fragment() {
|
|||
//}
|
||||
}
|
||||
else -> {
|
||||
(home_preview_viewpager?.adapter as? HomeScrollAdapter)?.setItems(
|
||||
listOf(),
|
||||
false
|
||||
)
|
||||
home_preview?.isVisible = false
|
||||
context?.fixPaddingStatusbar(home_watch_holder)
|
||||
}
|
||||
|
@ -577,59 +582,75 @@ class HomeFragment : Fragment() {
|
|||
}
|
||||
|
||||
home_preview_viewpager?.apply {
|
||||
setPageTransformer(false, HomeScrollTransformer())
|
||||
adapter = HomeScrollAdapter { load ->
|
||||
load.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(load.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(load.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(load, newValue)
|
||||
reloadStored()
|
||||
setPageTransformer(HomeScrollTransformer())
|
||||
val callback: OnPageChangeCallback = object : OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
(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()
|
||||
}
|
||||
|
||||
observe(homeViewModel.apiName) { apiName ->
|
||||
|
|
|
@ -1,60 +1,89 @@
|
|||
package com.lagradost.cloudstream3.ui.home
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import androidx.viewpager.widget.PagerAdapter
|
||||
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.home_scroll_view.view.*
|
||||
|
||||
|
||||
class HomeScrollAdapter(private val onPrimaryCallback: (LoadResponse) -> Unit) : PagerAdapter() {
|
||||
private var items: List<LoadResponse> = listOf()
|
||||
class HomeScrollAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
private var items: MutableList<LoadResponse> = mutableListOf()
|
||||
var hasMoreItems: Boolean = false
|
||||
|
||||
fun setItems(newItems: List<LoadResponse>) {
|
||||
items = newItems
|
||||
|
||||
notifyDataSetChanged()
|
||||
fun getItem(position: Int) : LoadResponse? {
|
||||
return items.getOrNull(position)
|
||||
}
|
||||
|
||||
override fun getCount(): Int {
|
||||
return Int.MAX_VALUE//items.size
|
||||
fun setItems(newItems: List<LoadResponse>, hasNext: Boolean): Boolean {
|
||||
val isSame = newItems.firstOrNull()?.url == items.firstOrNull()?.url
|
||||
hasMoreItems = hasNext
|
||||
|
||||
val diffResult = DiffUtil.calculateDiff(
|
||||
HomeScrollDiffCallback(this.items, newItems)
|
||||
)
|
||||
|
||||
items.clear()
|
||||
items.addAll(newItems)
|
||||
|
||||
|
||||
diffResult.dispatchUpdatesTo(this)
|
||||
|
||||
return isSame
|
||||
}
|
||||
|
||||
override fun getItemPosition(`object`: Any): Int {
|
||||
return POSITION_NONE//super.getItemPosition(`object`)
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
return CardViewHolder(
|
||||
LayoutInflater.from(parent.context).inflate(R.layout.home_scroll_view, parent, false),
|
||||
)
|
||||
}
|
||||
|
||||
private fun getItemAtPosition(idx: Int): LoadResponse {
|
||||
return items[idx % items.size]
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
when (holder) {
|
||||
is CardViewHolder -> {
|
||||
holder.bind(items[position])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun setPrimaryItem(container: ViewGroup, position: Int, `object`: Any) {
|
||||
super.setPrimaryItem(container, position, `object`)
|
||||
onPrimaryCallback.invoke(getItemAtPosition(position))
|
||||
class CardViewHolder
|
||||
constructor(
|
||||
itemView: View,
|
||||
) :
|
||||
RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
fun bind(card: LoadResponse) {
|
||||
card.apply {
|
||||
itemView.home_scroll_preview_tags?.text = tags?.joinToString(" • ") ?: ""
|
||||
itemView.home_scroll_preview_tags?.isGone = tags.isNullOrEmpty()
|
||||
itemView.home_scroll_preview?.setImage(posterUrl, posterHeaders)
|
||||
itemView.home_scroll_preview_title?.text = name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun instantiateItem(container: ViewGroup, position: Int): Any {
|
||||
val image = ImageView(container.context)
|
||||
val item = getItemAtPosition(position)
|
||||
image.scaleType = ImageView.ScaleType.CENTER_CROP
|
||||
image.setImage(item.posterUrl ?: item.backgroundPosterUrl, item.posterHeaders)
|
||||
class HomeScrollDiffCallback(
|
||||
private val oldList: List<LoadResponse>,
|
||||
private val newList: List<LoadResponse>
|
||||
) :
|
||||
DiffUtil.Callback() {
|
||||
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) =
|
||||
oldList[oldItemPosition].url == newList[newItemPosition].url
|
||||
|
||||
// val itemView: View = mLayoutInflater.inflate(R.layout.pager_item, container, false)
|
||||
override fun getOldListSize() = oldList.size
|
||||
|
||||
// val imageView: ImageView = itemView.findViewById<View>(R.id.imageView) as ImageView
|
||||
// imageView.setImageResource(mResources.get(position))
|
||||
override fun getNewListSize() = newList.size
|
||||
|
||||
container.addView(image)
|
||||
|
||||
return image
|
||||
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) =
|
||||
oldList[oldItemPosition] == newList[newItemPosition]
|
||||
}
|
||||
|
||||
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
|
||||
container.removeView(`object` as View)
|
||||
}
|
||||
|
||||
override fun isViewFromObject(view: View, `object`: Any): Boolean {
|
||||
return view === `object`
|
||||
override fun getItemCount(): Int {
|
||||
return items.size
|
||||
}
|
||||
}
|
|
@ -1,13 +1,23 @@
|
|||
package com.lagradost.cloudstream3.ui.home
|
||||
|
||||
import android.view.View
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
|
||||
class HomeScrollTransformer : ViewPager.PageTransformer {
|
||||
class HomeScrollTransformer : ViewPager2.PageTransformer {
|
||||
override fun transformPage(page: View, position: Float) {
|
||||
//page.translationX = -position * page.width / 2.0f
|
||||
|
||||
//val params = RecyclerView.LayoutParams(
|
||||
// RecyclerView.LayoutParams.MATCH_PARENT,
|
||||
// 0
|
||||
//)
|
||||
//page.layoutParams = params
|
||||
//progressBar?.layoutParams = params
|
||||
|
||||
val padding = (-position * page.width / 2).toInt()
|
||||
page.setPadding(
|
||||
maxOf(0, (-position * page.width / 2).toInt()), 0,
|
||||
maxOf(0, (position * page.width / 2).toInt()), 0
|
||||
padding, 0,
|
||||
-padding, 0
|
||||
)
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData
|
|||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.APIHolder.apis
|
||||
import com.lagradost.cloudstream3.APIHolder.filterHomePageListByFilmQuality
|
||||
import com.lagradost.cloudstream3.APIHolder.filterProviderByPreferredMedia
|
||||
|
@ -12,17 +13,12 @@ import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
|
|||
import com.lagradost.cloudstream3.AcraApplication.Companion.context
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||
import com.lagradost.cloudstream3.HomePageList
|
||||
import com.lagradost.cloudstream3.LoadResponse
|
||||
import com.lagradost.cloudstream3.MainAPI
|
||||
import com.lagradost.cloudstream3.SearchResponse
|
||||
import com.lagradost.cloudstream3.mvvm.*
|
||||
import com.lagradost.cloudstream3.ui.APIRepository
|
||||
import com.lagradost.cloudstream3.ui.APIRepository.Companion.noneApi
|
||||
import com.lagradost.cloudstream3.ui.APIRepository.Companion.randomApi
|
||||
import com.lagradost.cloudstream3.ui.WatchType
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.ioWork
|
||||
import com.lagradost.cloudstream3.utils.DOWNLOAD_HEADER_CACHE
|
||||
import com.lagradost.cloudstream3.utils.DataStoreHelper
|
||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllResumeStateIds
|
||||
|
@ -35,7 +31,6 @@ import com.lagradost.cloudstream3.utils.USER_SELECTED_HOMEPAGE_API
|
|||
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.*
|
||||
import kotlin.collections.set
|
||||
|
@ -49,6 +44,8 @@ class HomeViewModel : ViewModel() {
|
|||
private val _randomItems = MutableLiveData<List<SearchResponse>?>(null)
|
||||
val randomItems: LiveData<List<SearchResponse>?> = _randomItems
|
||||
|
||||
private var currentShuffledList: List<SearchResponse> = listOf()
|
||||
|
||||
private fun autoloadRepo(): APIRepository {
|
||||
return APIRepository(apis.first { it.hasMainPage })
|
||||
}
|
||||
|
@ -61,9 +58,12 @@ class HomeViewModel : ViewModel() {
|
|||
val bookmarks: LiveData<Pair<Boolean, List<SearchResponse>>> = _bookmarks
|
||||
|
||||
private val _resumeWatching = MutableLiveData<List<SearchResponse>>()
|
||||
private val _preview = MutableLiveData<Resource<List<LoadResponse>>>()
|
||||
private val _preview = MutableLiveData<Resource<Pair<Boolean, List<LoadResponse>>>>()
|
||||
private val previewResponses = mutableListOf<LoadResponse>()
|
||||
private val previewResponsesAdded = mutableSetOf<String>()
|
||||
|
||||
val resumeWatching: LiveData<List<SearchResponse>> = _resumeWatching
|
||||
val preview: LiveData<Resource<List<LoadResponse>>> = _preview
|
||||
val preview: LiveData<Resource<Pair<Boolean, List<LoadResponse>>>> = _preview
|
||||
|
||||
fun loadResumeWatching() = viewModelScope.launchSafe {
|
||||
val resumeWatching = withContext(Dispatchers.IO) {
|
||||
|
@ -212,6 +212,40 @@ class HomeViewModel : ViewModel() {
|
|||
expandAndReturn(name)
|
||||
}
|
||||
|
||||
// returns the amount of items added and modifies current
|
||||
private suspend fun updatePreviewResponses(
|
||||
current: MutableList<LoadResponse>,
|
||||
alreadyAdded: MutableSet<String>,
|
||||
shuffledList: List<SearchResponse>,
|
||||
size: Int
|
||||
): Int {
|
||||
var count = 0
|
||||
|
||||
val addItems = arrayListOf<SearchResponse>()
|
||||
for (searchResponse in shuffledList) {
|
||||
if (!alreadyAdded.contains(searchResponse.url)) {
|
||||
addItems.add(searchResponse)
|
||||
previewResponsesAdded.add(searchResponse.url)
|
||||
if (++count >= size) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val add = addItems.amap { searchResponse ->
|
||||
repo?.load(searchResponse.url)
|
||||
}.mapNotNull { if (it != null && it is Resource.Success) it.value else null }
|
||||
current.addAll(add)
|
||||
return add.size
|
||||
}
|
||||
|
||||
private var addJob: Job? = null
|
||||
fun loadMoreHomeScrollResponses() {
|
||||
addJob = ioSafe {
|
||||
updatePreviewResponses(previewResponses, previewResponsesAdded, currentShuffledList, 1)
|
||||
_preview.postValue(Resource.Success((previewResponsesAdded.size < currentShuffledList.size) to previewResponses))
|
||||
}
|
||||
}
|
||||
|
||||
private fun load(api: MainAPI?) = ioSafe {
|
||||
repo = if (api != null) {
|
||||
|
@ -226,6 +260,7 @@ class HomeViewModel : ViewModel() {
|
|||
if (repo?.hasMainPage == true) {
|
||||
_page.postValue(Resource.Loading())
|
||||
_preview.postValue(Resource.Loading())
|
||||
addJob?.cancel()
|
||||
|
||||
when (val data = repo?.getMainPage(1, null)) {
|
||||
is Resource.Success -> {
|
||||
|
@ -241,64 +276,10 @@ class HomeViewModel : ViewModel() {
|
|||
}
|
||||
|
||||
val items = data.value.mapNotNull { it?.items }.flatten()
|
||||
val responses = ioWork {
|
||||
items.flatMap { it.list }.shuffled().take(6).map { searchResponse ->
|
||||
async { repo?.load(searchResponse.url) }
|
||||
}.map { it.await() }.mapNotNull { if (it != null && it is Resource.Success) it.value else null } }
|
||||
//.amap { searchResponse ->
|
||||
// repo?.load(searchResponse.url)
|
||||
///}
|
||||
|
||||
//.map { searchResponse ->
|
||||
// async { repo?.load(searchResponse.url) }
|
||||
// }.map { it.await() }
|
||||
|
||||
|
||||
if (responses.isEmpty()) {
|
||||
_preview.postValue(
|
||||
Resource.Failure(
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
"No homepage responses"
|
||||
)
|
||||
)
|
||||
} else {
|
||||
_preview.postValue(Resource.Success(responses))
|
||||
}
|
||||
|
||||
/*
|
||||
items.randomOrNull()?.list?.randomOrNull()?.url?.let { url ->
|
||||
// backup request in case first fails
|
||||
var first = repo?.load(url)
|
||||
if(first == null ||first is Resource.Failure) {
|
||||
first = repo?.load(items.random().list.random().url)
|
||||
}
|
||||
first?.let {
|
||||
_preview.postValue(it)
|
||||
} ?: run {
|
||||
_preview.postValue(
|
||||
Resource.Failure(
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
"No repo found, this should never happen"
|
||||
)
|
||||
)
|
||||
}
|
||||
} ?: run {
|
||||
_preview.postValue(
|
||||
Resource.Failure(
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
"No homepage items"
|
||||
)
|
||||
)
|
||||
}*/
|
||||
|
||||
_page.postValue(Resource.Success(expandable))
|
||||
|
||||
previewResponses.clear()
|
||||
previewResponsesAdded.clear()
|
||||
|
||||
//val home = data.value
|
||||
if (items.isNotEmpty()) {
|
||||
|
@ -313,9 +294,30 @@ class HomeViewModel : ViewModel() {
|
|||
context?.filterSearchResultByFilmQuality(currentList.shuffled())
|
||||
?: currentList.shuffled()
|
||||
|
||||
updatePreviewResponses(
|
||||
previewResponses,
|
||||
previewResponsesAdded,
|
||||
randomItems,
|
||||
3
|
||||
)
|
||||
|
||||
_randomItems.postValue(randomItems)
|
||||
currentShuffledList = randomItems
|
||||
}
|
||||
}
|
||||
if (previewResponses.isEmpty()) {
|
||||
_preview.postValue(
|
||||
Resource.Failure(
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
"No homepage responses"
|
||||
)
|
||||
)
|
||||
} else {
|
||||
_preview.postValue(Resource.Success((previewResponsesAdded.size < currentShuffledList.size) to previewResponses))
|
||||
}
|
||||
_page.postValue(Resource.Success(expandable))
|
||||
} catch (e: Exception) {
|
||||
_randomItems.postValue(emptyList())
|
||||
logError(e)
|
||||
|
|
|
@ -287,39 +287,23 @@
|
|||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/home_preview_viewpager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
</androidx.viewpager.widget.ViewPager>
|
||||
</androidx.viewpager2.widget.ViewPager2>
|
||||
|
||||
<ImageView
|
||||
android:visibility="gone"
|
||||
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" />
|
||||
|
||||
<View
|
||||
android:id="@+id/title_shadow_top"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="150dp"
|
||||
android:layout_gravity="top"
|
||||
android:alpha="1"
|
||||
android:background="@drawable/background_shadow"
|
||||
android:rotation="180"
|
||||
android:visibility="visible" />
|
||||
|
||||
<View
|
||||
android:id="@+id/title_shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="300dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@drawable/background_shadow" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/home_padding"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -363,44 +347,14 @@
|
|||
-->
|
||||
|
||||
<LinearLayout
|
||||
|
||||
android:id="@+id/home_preview_title_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="100dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/home_preview_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="10dp"
|
||||
android:paddingHorizontal="30dp"
|
||||
android:textColor="?attr/white"
|
||||
android:textSize="17sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="The Perfect Run" />
|
||||
<!--<TextView
|
||||
android:paddingStart="30dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:id="@+id/home_season_tags"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp"
|
||||
tools:text="5 seasons 50 episodes" />-->
|
||||
<TextView
|
||||
android:id="@+id/home_preview_tags"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:paddingStart="30dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:textColor="?attr/white"
|
||||
android:textSize="14sp"
|
||||
tools:text="Hello • World • Tags" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
74
app/src/main/res/layout/home_scroll_view.xml
Normal file
74
app/src/main/res/layout/home_scroll_view.xml
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?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_top"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="150dp"
|
||||
android:layout_gravity="top"
|
||||
android:alpha="1"
|
||||
android:background="@drawable/background_shadow"
|
||||
android:rotation="180"
|
||||
android:visibility="visible" />
|
||||
|
||||
<View
|
||||
android:id="@+id/title_shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="300dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@drawable/background_shadow" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
android:layout_marginBottom="100dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/home_scroll_preview_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="30dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:textColor="?attr/white"
|
||||
android:textSize="17sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="The Perfect Run" />
|
||||
<!--<TextView
|
||||
android:paddingStart="30dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:id="@+id/home_season_tags"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp"
|
||||
tools:text="5 seasons 50 episodes" />-->
|
||||
<TextView
|
||||
android:id="@+id/home_scroll_preview_tags"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center"
|
||||
android:paddingStart="30dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:textColor="?attr/white"
|
||||
android:textSize="14sp"
|
||||
tools:text="Hello • World • Tags" />
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
Loading…
Reference in a new issue