mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
removed synthetic by removing ResultFragment
This commit is contained in:
parent
4fcf396591
commit
ed0d374721
7 changed files with 459 additions and 355 deletions
|
@ -7,7 +7,6 @@ plugins {
|
|||
id("com.android.application")
|
||||
id("kotlin-android")
|
||||
id("kotlin-kapt")
|
||||
id("kotlin-android-extensions")
|
||||
id("org.jetbrains.dokka")
|
||||
}
|
||||
|
||||
|
|
|
@ -1,94 +1,18 @@
|
|||
package com.lagradost.cloudstream3.ui.result
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.Intent.*
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.chip.ChipDrawable
|
||||
import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings
|
||||
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
|
||||
import com.lagradost.cloudstream3.APIHolder.updateHasTrailers
|
||||
import com.lagradost.cloudstream3.DubStatus
|
||||
import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.SearchResponse
|
||||
import com.lagradost.cloudstream3.TvType
|
||||
import com.lagradost.cloudstream3.mvvm.*
|
||||
import com.lagradost.cloudstream3.syncproviders.providers.Kitsu
|
||||
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_ACTION_DOWNLOAD
|
||||
import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup.handleDownloadClick
|
||||
import com.lagradost.cloudstream3.ui.player.FullScreenPlayer
|
||||
import com.lagradost.cloudstream3.ui.result.EpisodeAdapter.Companion.getPlayerAction
|
||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||
import com.lagradost.cloudstream3.utils.*
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.getNameFull
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.html
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.openBrowser
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||
import com.lagradost.cloudstream3.utils.DataStoreHelper
|
||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.getVideoWatchState
|
||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
|
||||
import kotlinx.android.synthetic.main.fragment_result.download_button
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_cast_items
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_cast_text
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_coming_soon
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_data_holder
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_description
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_dub_select
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_episode_loading
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_episode_select
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_episodes
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_error_text
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_finish_loading
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_info
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_loading
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_loading_error
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_meta_duration
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_meta_rating
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_meta_site
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_meta_type
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_meta_year
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_next_airing
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_next_airing_time
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_no_episodes
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_play_movie
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_poster
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_poster_background
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_poster_holder
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_reload_connection_open_in_browser
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_reload_connectionerror
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_resume_parent
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_resume_progress_holder
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_resume_series_button
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_resume_series_progress
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_resume_series_progress_text
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_resume_series_title
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_season_button
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_tag
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_tag_holder
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_title
|
||||
import kotlinx.android.synthetic.main.fragment_result.result_vpn
|
||||
import kotlinx.android.synthetic.main.fragment_result_tv.result_resume_series_button_play
|
||||
import kotlinx.android.synthetic.main.fragment_result_tv.temporary_no_focus
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import com.lagradost.cloudstream3.utils.Event
|
||||
|
||||
const val START_ACTION_RESUME_LATEST = 1
|
||||
const val START_ACTION_LOAD_EP = 2
|
||||
|
@ -188,118 +112,113 @@ fun ResultEpisode.getWatchProgress(): Float {
|
|||
return (getDisplayPosition() / 1000).toFloat() / (duration / 1000).toFloat()
|
||||
}
|
||||
|
||||
open class ResultFragment : FullScreenPlayer() {
|
||||
companion object {
|
||||
const val URL_BUNDLE = "url"
|
||||
const val API_NAME_BUNDLE = "apiName"
|
||||
const val SEASON_BUNDLE = "season"
|
||||
const val EPISODE_BUNDLE = "episode"
|
||||
const val START_ACTION_BUNDLE = "startAction"
|
||||
const val START_VALUE_BUNDLE = "startValue"
|
||||
const val RESTART_BUNDLE = "restart"
|
||||
object ResultFragment {
|
||||
private const val URL_BUNDLE = "url"
|
||||
private const val API_NAME_BUNDLE = "apiName"
|
||||
private const val SEASON_BUNDLE = "season"
|
||||
private const val EPISODE_BUNDLE = "episode"
|
||||
private const val START_ACTION_BUNDLE = "startAction"
|
||||
private const val START_VALUE_BUNDLE = "startValue"
|
||||
private const val RESTART_BUNDLE = "restart"
|
||||
|
||||
fun newInstance(
|
||||
card: SearchResponse, startAction: Int = 0, startValue: Int? = null
|
||||
): Bundle {
|
||||
return Bundle().apply {
|
||||
putString(URL_BUNDLE, card.url)
|
||||
putString(API_NAME_BUNDLE, card.apiName)
|
||||
if (card is DataStoreHelper.ResumeWatchingResult) {
|
||||
if (card.season != null)
|
||||
putInt(SEASON_BUNDLE, card.season)
|
||||
if (card.episode != null)
|
||||
putInt(EPISODE_BUNDLE, card.episode)
|
||||
}
|
||||
putInt(START_ACTION_BUNDLE, startAction)
|
||||
if (startValue != null)
|
||||
putInt(START_VALUE_BUNDLE, startValue)
|
||||
|
||||
|
||||
putBoolean(RESTART_BUNDLE, true)
|
||||
fun newInstance(
|
||||
card: SearchResponse, startAction: Int = 0, startValue: Int? = null
|
||||
): Bundle {
|
||||
return Bundle().apply {
|
||||
putString(URL_BUNDLE, card.url)
|
||||
putString(API_NAME_BUNDLE, card.apiName)
|
||||
if (card is DataStoreHelper.ResumeWatchingResult) {
|
||||
if (card.season != null)
|
||||
putInt(SEASON_BUNDLE, card.season)
|
||||
if (card.episode != null)
|
||||
putInt(EPISODE_BUNDLE, card.episode)
|
||||
}
|
||||
}
|
||||
|
||||
fun newInstance(
|
||||
url: String,
|
||||
apiName: String,
|
||||
startAction: Int = 0,
|
||||
startValue: Int = 0
|
||||
): Bundle {
|
||||
return Bundle().apply {
|
||||
putString(URL_BUNDLE, url)
|
||||
putString(API_NAME_BUNDLE, apiName)
|
||||
putInt(START_ACTION_BUNDLE, startAction)
|
||||
putInt(START_ACTION_BUNDLE, startAction)
|
||||
if (startValue != null)
|
||||
putInt(START_VALUE_BUNDLE, startValue)
|
||||
putBoolean(RESTART_BUNDLE, true)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateUI() {
|
||||
updateUIListener?.invoke()
|
||||
}
|
||||
|
||||
private var updateUIListener: (() -> Unit)? = null
|
||||
putBoolean(RESTART_BUNDLE, true)
|
||||
}
|
||||
}
|
||||
|
||||
open fun setTrailers(trailers: List<ExtractorLink>?) {}
|
||||
fun newInstance(
|
||||
url: String,
|
||||
apiName: String,
|
||||
startAction: Int = 0,
|
||||
startValue: Int = 0
|
||||
): Bundle {
|
||||
return Bundle().apply {
|
||||
putString(URL_BUNDLE, url)
|
||||
putString(API_NAME_BUNDLE, apiName)
|
||||
putInt(START_ACTION_BUNDLE, startAction)
|
||||
putInt(START_VALUE_BUNDLE, startValue)
|
||||
putBoolean(RESTART_BUNDLE, true)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateUI(id: Int? = null) {
|
||||
// updateUIListener?.invoke()
|
||||
updateUIEvent.invoke(id)
|
||||
}
|
||||
val updateUIEvent = Event<Int?>()
|
||||
|
||||
//private var updateUIListener: (() -> Unit)? = null
|
||||
|
||||
|
||||
protected lateinit var viewModel: ResultViewModel2 //by activityViewModels()
|
||||
protected lateinit var syncModel: SyncViewModel
|
||||
//protected open val resultLayout = R.layout.fragment_result_swipe
|
||||
|
||||
override var layout = R.layout.fragment_result_swipe
|
||||
/* override var layout = R.layout.fragment_result_swipe
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?,
|
||||
): View? {
|
||||
viewModel =
|
||||
ViewModelProvider(this)[ResultViewModel2::class.java]
|
||||
syncModel =
|
||||
ViewModelProvider(this)[SyncViewModel::class.java]
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?,
|
||||
): View? {
|
||||
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
//return inflater.inflate(resultLayout, container, false)
|
||||
}
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
//return inflater.inflate(resultLayout, container, false)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
updateUIListener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
override fun onDestroyView() {
|
||||
updateUIListener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
afterPluginsLoadedEvent += ::reloadViewModel
|
||||
super.onResume()
|
||||
activity?.let {
|
||||
it.window?.navigationBarColor =
|
||||
it.colorFromAttribute(R.attr.primaryBlackBackground)
|
||||
}
|
||||
}
|
||||
override fun onResume() {
|
||||
afterPluginsLoadedEvent += ::reloadViewModel
|
||||
super.onResume()
|
||||
activity?.let {
|
||||
it.window?.navigationBarColor =
|
||||
it.colorFromAttribute(R.attr.primaryBlackBackground)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
afterPluginsLoadedEvent -= ::reloadViewModel
|
||||
super.onDestroy()
|
||||
}
|
||||
override fun onDestroy() {
|
||||
afterPluginsLoadedEvent -= ::reloadViewModel
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
|
||||
private fun updateUI() {
|
||||
syncModel.updateUserData()
|
||||
viewModel.reloadEpisodes()
|
||||
}
|
||||
private fun updateUI() {
|
||||
syncModel.updateUserData()
|
||||
viewModel.reloadEpisodes()
|
||||
}*/
|
||||
|
||||
data class StoredData(
|
||||
val url: String?,
|
||||
val url: String,
|
||||
val apiName: String,
|
||||
val showFillers: Boolean,
|
||||
val dubStatus: DubStatus,
|
||||
val start: AutoResume?,
|
||||
val playerAction: Int
|
||||
val playerAction: Int,
|
||||
val restart : Boolean,
|
||||
)
|
||||
|
||||
fun getStoredData(context: Context): StoredData? {
|
||||
fun Fragment.getStoredData(): StoredData? {
|
||||
val context = this.context ?: this.activity ?: return null
|
||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val url = arguments?.getString(URL_BUNDLE)
|
||||
val url = arguments?.getString(URL_BUNDLE) ?: return null
|
||||
val apiName = arguments?.getString(API_NAME_BUNDLE) ?: return null
|
||||
val showFillers =
|
||||
settingsManager.getBoolean(context.getString(R.string.show_fillers_key), false)
|
||||
|
@ -310,6 +229,11 @@ open class ResultFragment : FullScreenPlayer() {
|
|||
|
||||
val playerAction = getPlayerAction(context)
|
||||
|
||||
val restart = arguments?.getBoolean(RESTART_BUNDLE) ?: false
|
||||
if (restart) {
|
||||
arguments?.putBoolean(RESTART_BUNDLE, false)
|
||||
}
|
||||
|
||||
val start = startAction?.let { action ->
|
||||
val startValue = arguments?.getInt(START_VALUE_BUNDLE)
|
||||
val resumeEpisode = arguments?.getInt(EPISODE_BUNDLE)
|
||||
|
@ -324,10 +248,10 @@ open class ResultFragment : FullScreenPlayer() {
|
|||
season = resumeSeason
|
||||
)
|
||||
}
|
||||
return StoredData(url, apiName, showFillers, dubStatus, start, playerAction)
|
||||
return StoredData(url, apiName, showFillers, dubStatus, start, playerAction, restart)
|
||||
}
|
||||
|
||||
private fun reloadViewModel(forceReload: Boolean) {
|
||||
/*private fun reloadViewModel(forceReload: Boolean) {
|
||||
if (!viewModel.hasLoaded() || forceReload) {
|
||||
val storedData = getStoredData(activity ?: context ?: return) ?: return
|
||||
|
||||
|
@ -346,26 +270,6 @@ open class ResultFragment : FullScreenPlayer() {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
result_cast_items?.layoutManager = object : LinearListLayout(view.context) {
|
||||
override fun onRequestChildFocus(
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State,
|
||||
child: View,
|
||||
focused: View?
|
||||
): Boolean {
|
||||
// Make the cast always focus the first visible item when focused
|
||||
// from somewhere else. Otherwise it jumps to the last item.
|
||||
return if (parent.focusedChild == null) {
|
||||
scrollToPosition(this.findFirstCompletelyVisibleItemPosition())
|
||||
true
|
||||
} else {
|
||||
super.onRequestChildFocus(parent, state, child, focused)
|
||||
}
|
||||
}
|
||||
}.apply {
|
||||
this.orientation = RecyclerView.HORIZONTAL
|
||||
}
|
||||
result_cast_items?.adapter = ActorAdaptor()
|
||||
|
||||
updateUIListener = ::updateUI
|
||||
|
||||
|
@ -401,97 +305,7 @@ open class ResultFragment : FullScreenPlayer() {
|
|||
result_season_button?.isFocusableInTouchMode = isTv
|
||||
result_episode_select?.isFocusableInTouchMode = isTv
|
||||
result_dub_select?.isFocusableInTouchMode = isTv
|
||||
|
||||
|
||||
observeNullable(viewModel.resumeWatching) { resume ->
|
||||
if (resume == null) {
|
||||
result_resume_parent?.isVisible = false
|
||||
return@observeNullable
|
||||
}
|
||||
result_resume_parent?.isVisible = true
|
||||
resume.progress?.let { progress ->
|
||||
result_resume_series_title?.apply {
|
||||
isVisible = !resume.isMovie
|
||||
text =
|
||||
if (resume.isMovie) null else activity?.getNameFull(
|
||||
resume.result.name,
|
||||
resume.result.episode,
|
||||
resume.result.season
|
||||
)
|
||||
}
|
||||
result_resume_series_progress_text?.setText(progress.progressLeft)
|
||||
result_resume_series_progress?.apply {
|
||||
isVisible = true
|
||||
this.max = progress.maxProgress
|
||||
this.progress = progress.progress
|
||||
}
|
||||
result_resume_progress_holder?.isVisible = true
|
||||
} ?: run {
|
||||
result_resume_progress_holder?.isVisible = false
|
||||
result_resume_series_progress?.isVisible = false
|
||||
result_resume_series_title?.isVisible = false
|
||||
result_resume_series_progress_text?.isVisible = false
|
||||
}
|
||||
|
||||
result_resume_series_button?.isVisible = !resume.isMovie
|
||||
result_resume_series_button_play?.isVisible = !resume.isMovie
|
||||
|
||||
val click = View.OnClickListener {
|
||||
viewModel.handleAction(
|
||||
activity,
|
||||
EpisodeClickEvent(
|
||||
storedData?.playerAction ?: ACTION_PLAY_EPISODE_IN_PLAYER,
|
||||
resume.result
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
result_resume_series_button?.setOnClickListener(click)
|
||||
result_resume_series_button_play?.setOnClickListener(click)
|
||||
}
|
||||
|
||||
context?.let { ctx ->
|
||||
|
||||
//result_bookmark_button?.isVisible = ctx.isTvSettings()
|
||||
|
||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(ctx)
|
||||
|
||||
|
||||
Kitsu.isEnabled =
|
||||
settingsManager.getBoolean(ctx.getString(R.string.show_kitsu_posters_key), true)
|
||||
|
||||
if (storedData?.url != null) {
|
||||
result_reload_connectionerror.setOnClickListener {
|
||||
viewModel.load(
|
||||
activity,
|
||||
storedData.url,
|
||||
storedData.apiName,
|
||||
storedData.showFillers,
|
||||
storedData.dubStatus,
|
||||
storedData.start
|
||||
)
|
||||
}
|
||||
|
||||
result_reload_connection_open_in_browser?.setOnClickListener {
|
||||
val i = Intent(ACTION_VIEW)
|
||||
i.data = Uri.parse(storedData.url)
|
||||
try {
|
||||
startActivity(i)
|
||||
} catch (e: Exception) {
|
||||
logError(e)
|
||||
}
|
||||
}
|
||||
|
||||
// bloats the navigation on tv
|
||||
if (!isTrueTvSettings()) {
|
||||
result_meta_site?.setOnClickListener {
|
||||
it.context?.openBrowser(storedData.url)
|
||||
}
|
||||
result_meta_site?.isFocusable = true
|
||||
} else {
|
||||
result_meta_site?.isFocusable = false
|
||||
}
|
||||
|
||||
if (restart || !viewModel.hasLoaded()) {
|
||||
//viewModel.clear()
|
||||
viewModel.load(
|
||||
|
@ -504,6 +318,5 @@ open class ResultFragment : FullScreenPlayer() {
|
|||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.app.Dialog
|
|||
import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Rect
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
|
@ -23,6 +22,8 @@ import androidx.core.view.isGone
|
|||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.discord.panels.OverlappingPanelsLayout
|
||||
import com.discord.panels.PanelsChildGestureRegionObserver
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory
|
||||
|
@ -34,6 +35,7 @@ import com.lagradost.cloudstream3.APIHolder.updateHasTrailers
|
|||
import com.lagradost.cloudstream3.CommonActivity
|
||||
import com.lagradost.cloudstream3.DubStatus
|
||||
import com.lagradost.cloudstream3.LoadResponse
|
||||
import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.SearchResponse
|
||||
import com.lagradost.cloudstream3.databinding.FragmentResultBinding
|
||||
|
@ -50,11 +52,16 @@ import com.lagradost.cloudstream3.ui.WatchType
|
|||
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_ACTION_DOWNLOAD
|
||||
import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup
|
||||
import com.lagradost.cloudstream3.ui.player.CSPlayerEvent
|
||||
import com.lagradost.cloudstream3.ui.player.FullScreenPlayer
|
||||
import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment
|
||||
import com.lagradost.cloudstream3.ui.result.ResultFragment.getStoredData
|
||||
import com.lagradost.cloudstream3.ui.result.ResultFragment.updateUIEvent
|
||||
import com.lagradost.cloudstream3.ui.search.SearchAdapter
|
||||
import com.lagradost.cloudstream3.ui.search.SearchHelper
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.getNameFull
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.html
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.openBrowser
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
|
||||
|
@ -63,6 +70,7 @@ import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog
|
|||
import com.lagradost.cloudstream3.utils.UIHelper
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.popCurrentPage
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.populateChips
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes
|
||||
|
@ -70,17 +78,29 @@ import com.lagradost.cloudstream3.utils.UIHelper.setImage
|
|||
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
|
||||
|
||||
|
||||
open class ResultFragmentPhone : ResultFragment(),
|
||||
open class ResultFragmentPhone : FullScreenPlayer(),
|
||||
PanelsChildGestureRegionObserver.GestureRegionsListener {
|
||||
protected lateinit var viewModel: ResultViewModel2
|
||||
protected lateinit var syncModel: SyncViewModel
|
||||
|
||||
protected var binding: FragmentResultSwipeBinding? = null
|
||||
protected var resultBinding: FragmentResultBinding? = null
|
||||
protected var recommendationBinding: ResultRecommendationsBinding? = null
|
||||
protected var syncBinding: ResultSyncBinding? = null
|
||||
|
||||
override var layout = R.layout.fragment_result_swipe
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
viewModel =
|
||||
ViewModelProvider(this)[ResultViewModel2::class.java]
|
||||
syncModel =
|
||||
ViewModelProvider(this)[SyncViewModel::class.java]
|
||||
updateUIEvent += ::updateUI
|
||||
|
||||
val root = super.onCreateView(inflater, container, savedInstanceState) ?: return null
|
||||
FragmentResultSwipeBinding.bind(root).let { bind ->
|
||||
resultBinding =
|
||||
|
@ -180,7 +200,7 @@ open class ResultFragmentPhone : ResultFragment(),
|
|||
|
||||
}
|
||||
|
||||
override fun setTrailers(trailers: List<ExtractorLink>?) {
|
||||
private fun setTrailers(trailers: List<ExtractorLink>?) {
|
||||
context?.updateHasTrailers()
|
||||
if (!LoadResponse.isTrailersEnabled) return
|
||||
currentTrailers = trailers?.sortedBy { -it.quality } ?: emptyList()
|
||||
|
@ -196,6 +216,7 @@ open class ResultFragmentPhone : ResultFragment(),
|
|||
}
|
||||
obs.removeGestureRegionsUpdateListener(this)
|
||||
}
|
||||
updateUIEvent -= ::updateUI
|
||||
binding = null
|
||||
resultBinding = null
|
||||
syncBinding = null
|
||||
|
@ -218,48 +239,128 @@ open class ResultFragmentPhone : ResultFragment(),
|
|||
|
||||
var selectSeason: String? = null
|
||||
|
||||
private fun setUrl(url : String?) {
|
||||
if(url == null) {
|
||||
private fun setUrl(url: String?) {
|
||||
if (url == null) {
|
||||
binding?.resultOpenInBrowser?.isVisible = false
|
||||
return
|
||||
}
|
||||
|
||||
val valid = url.startsWith("http")
|
||||
|
||||
binding?.resultOpenInBrowser?.apply {
|
||||
isVisible = url.startsWith("http")
|
||||
isVisible = valid
|
||||
setOnClickListener {
|
||||
val i = Intent(Intent.ACTION_VIEW)
|
||||
i.data = Uri.parse(url)
|
||||
try {
|
||||
startActivity(i)
|
||||
} catch (e: Exception) {
|
||||
logError(e)
|
||||
}
|
||||
context?.openBrowser(url)
|
||||
}
|
||||
}
|
||||
|
||||
resultBinding?.resultReloadConnectionOpenInBrowser?.setOnClickListener {
|
||||
view?.context?.openBrowser(url)
|
||||
}
|
||||
|
||||
resultBinding?.resultMetaSite?.setOnClickListener {
|
||||
view?.context?.openBrowser(url)
|
||||
}
|
||||
}
|
||||
|
||||
private fun reloadViewModel(forceReload: Boolean) {
|
||||
if (!viewModel.hasLoaded() || forceReload) {
|
||||
val storedData = getStoredData() ?: return
|
||||
viewModel.load(
|
||||
activity,
|
||||
storedData.url,
|
||||
storedData.apiName,
|
||||
storedData.showFillers,
|
||||
storedData.dubStatus,
|
||||
storedData.start
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
afterPluginsLoadedEvent += ::reloadViewModel
|
||||
activity?.let {
|
||||
it.window?.navigationBarColor =
|
||||
it.colorFromAttribute(R.attr.primaryBlackBackground)
|
||||
}
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
afterPluginsLoadedEvent -= ::reloadViewModel
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
private fun updateUI(id : Int?) {
|
||||
syncModel.updateUserData()
|
||||
viewModel.reloadEpisodes()
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
val apiName = arguments?.getString(API_NAME_BUNDLE) ?: return
|
||||
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// ===== setup =====
|
||||
UIHelper.fixPaddingStatusbar(binding?.resultTopBar)
|
||||
val storedData = (activity ?: context)?.let {
|
||||
getStoredData(it)
|
||||
}
|
||||
val storedData = getStoredData() ?: return
|
||||
activity?.window?.decorView?.clearFocus()
|
||||
activity?.loadCache()
|
||||
context?.updateHasTrailers()
|
||||
hideKeyboard()
|
||||
if (storedData.restart || !viewModel.hasLoaded())
|
||||
viewModel.load(
|
||||
activity,
|
||||
storedData.url,
|
||||
storedData.apiName,
|
||||
storedData.showFillers,
|
||||
storedData.dubStatus,
|
||||
storedData.start
|
||||
)
|
||||
|
||||
setUrl(storedData?.url)
|
||||
syncModel.addFromUrl(storedData?.url)
|
||||
|
||||
val api = APIHolder.getApiFromNameNull(apiName)
|
||||
setUrl(storedData.url)
|
||||
syncModel.addFromUrl(storedData.url)
|
||||
val api = APIHolder.getApiFromNameNull(storedData.apiName)
|
||||
PanelsChildGestureRegionObserver.Provider.get().addGestureRegionsUpdateListener(this)
|
||||
// ===== ===== =====
|
||||
|
||||
resultBinding?.apply {
|
||||
resultReloadConnectionerror.setOnClickListener {
|
||||
viewModel.load(
|
||||
activity,
|
||||
storedData.url,
|
||||
storedData.apiName,
|
||||
storedData.showFillers,
|
||||
storedData.dubStatus,
|
||||
storedData.start
|
||||
)
|
||||
}
|
||||
|
||||
resultCastItems.layoutManager = object : LinearListLayout(view.context) {
|
||||
override fun onRequestChildFocus(
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State,
|
||||
child: View,
|
||||
focused: View?
|
||||
): Boolean {
|
||||
// Make the cast always focus the first visible item when focused
|
||||
// from somewhere else. Otherwise it jumps to the last item.
|
||||
return if (parent.focusedChild == null) {
|
||||
scrollToPosition(this.findFirstCompletelyVisibleItemPosition())
|
||||
true
|
||||
} else {
|
||||
super.onRequestChildFocus(parent, state, child, focused)
|
||||
}
|
||||
}
|
||||
}.apply {
|
||||
this.orientation = RecyclerView.HORIZONTAL
|
||||
}
|
||||
resultCastItems.adapter = ActorAdaptor()
|
||||
|
||||
resultEpisodes.adapter =
|
||||
EpisodeAdapter(
|
||||
api?.hasDownloadSupport == true,
|
||||
{ episodeClick ->
|
||||
viewModel.handleAction(activity, episodeClick)
|
||||
viewModel.handleAction(episodeClick)
|
||||
},
|
||||
{ downloadClickEvent ->
|
||||
DownloadButtonSetup.handleDownloadClick(downloadClickEvent)
|
||||
|
@ -291,6 +392,8 @@ open class ResultFragmentPhone : ResultFragment(),
|
|||
resultBack.setOnClickListener {
|
||||
activity?.popCurrentPage()
|
||||
}
|
||||
|
||||
|
||||
resultMiniSync.adapter = ImageAdapter(
|
||||
nextFocusDown = R.id.result_sync_set_score,
|
||||
clickCallback = { action ->
|
||||
|
@ -368,7 +471,6 @@ open class ResultFragmentPhone : ResultFragment(),
|
|||
}
|
||||
}
|
||||
|
||||
PanelsChildGestureRegionObserver.Provider.get().addGestureRegionsUpdateListener(this)
|
||||
|
||||
/*
|
||||
result_bookmark_button?.setOnClickListener {
|
||||
|
@ -381,6 +483,50 @@ open class ResultFragmentPhone : ResultFragment(),
|
|||
}
|
||||
}*/
|
||||
|
||||
observeNullable(viewModel.resumeWatching) { resume ->
|
||||
resultBinding?.apply {
|
||||
if (resume == null) {
|
||||
resultResumeParent.isVisible = false
|
||||
return@observeNullable
|
||||
}
|
||||
resultResumeParent.isVisible = true
|
||||
resume.progress?.let { progress ->
|
||||
resultResumeSeriesTitle.apply {
|
||||
isVisible = !resume.isMovie
|
||||
text =
|
||||
if (resume.isMovie) null else context?.getNameFull(
|
||||
resume.result.name,
|
||||
resume.result.episode,
|
||||
resume.result.season
|
||||
)
|
||||
}
|
||||
|
||||
resultResumeSeriesProgressText.setText(progress.progressLeft)
|
||||
resultResumeSeriesProgress.apply {
|
||||
isVisible = true
|
||||
this.max = progress.maxProgress
|
||||
this.progress = progress.progress
|
||||
}
|
||||
resultResumeProgressHolder.isVisible = true
|
||||
} ?: run {
|
||||
resultResumeProgressHolder.isVisible = false
|
||||
resultResumeSeriesProgress.isVisible = false
|
||||
resultResumeSeriesTitle.isVisible = false
|
||||
resultResumeSeriesProgressText.isVisible = false
|
||||
}
|
||||
|
||||
resultResumeSeriesButton.isVisible = !resume.isMovie
|
||||
resultResumeSeriesButton.setOnClickListener {
|
||||
viewModel.handleAction(
|
||||
EpisodeClickEvent(
|
||||
storedData.playerAction, //?: ACTION_PLAY_EPISODE_IN_PLAYER,
|
||||
resume.result
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
observeNullable(viewModel.subscribeStatus) { isSubscribed ->
|
||||
binding?.resultSubscribe?.isVisible = isSubscribed != null
|
||||
if (isSubscribed == null) return@observeNullable
|
||||
|
@ -403,7 +549,7 @@ open class ResultFragmentPhone : ResultFragment(),
|
|||
// no failure?
|
||||
resultEpisodeLoading.isVisible = episodes is Resource.Loading
|
||||
resultEpisodes.isVisible = episodes is Resource.Success
|
||||
if(episodes is Resource.Success) {
|
||||
if (episodes is Resource.Success) {
|
||||
(resultEpisodes.adapter as? EpisodeAdapter)?.updateList(episodes.value)
|
||||
}
|
||||
}
|
||||
|
@ -419,13 +565,11 @@ open class ResultFragmentPhone : ResultFragment(),
|
|||
resultPlayMovie.setText(text)
|
||||
resultPlayMovie.setOnClickListener {
|
||||
viewModel.handleAction(
|
||||
activity,
|
||||
EpisodeClickEvent(ACTION_CLICK_DEFAULT, ep)
|
||||
)
|
||||
}
|
||||
resultPlayMovie.setOnLongClickListener {
|
||||
viewModel.handleAction(
|
||||
activity,
|
||||
EpisodeClickEvent(ACTION_SHOW_OPTIONS, ep)
|
||||
)
|
||||
return@setOnLongClickListener true
|
||||
|
@ -446,7 +590,6 @@ open class ResultFragmentPhone : ResultFragment(),
|
|||
when (click.action) {
|
||||
DOWNLOAD_ACTION_DOWNLOAD -> {
|
||||
viewModel.handleAction(
|
||||
activity,
|
||||
EpisodeClickEvent(ACTION_DOWNLOAD_EPISODE, ep)
|
||||
)
|
||||
}
|
||||
|
@ -529,7 +672,7 @@ open class ResultFragmentPhone : ResultFragment(),
|
|||
}
|
||||
|
||||
(data as? Resource.Failure)?.let { data ->
|
||||
resultErrorText.text = (storedData?.url?.plus("\n") ?: "") + data.errorString
|
||||
resultErrorText.text = storedData.url.plus("\n") + data.errorString
|
||||
}
|
||||
|
||||
binding?.resultBookmarkFab?.isVisible = data is Resource.Success
|
||||
|
|
|
@ -9,11 +9,14 @@ import android.view.ViewGroup
|
|||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.lagradost.cloudstream3.APIHolder.updateHasTrailers
|
||||
import com.lagradost.cloudstream3.DubStatus
|
||||
import com.lagradost.cloudstream3.LoadResponse
|
||||
import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.SearchResponse
|
||||
import com.lagradost.cloudstream3.databinding.FragmentResultTvBinding
|
||||
|
@ -24,27 +27,32 @@ import com.lagradost.cloudstream3.ui.WatchType
|
|||
import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup
|
||||
import com.lagradost.cloudstream3.ui.player.ExtractorLinkGenerator
|
||||
import com.lagradost.cloudstream3.ui.player.GeneratorPlayer
|
||||
import com.lagradost.cloudstream3.ui.result.ResultFragment.getStoredData
|
||||
import com.lagradost.cloudstream3.ui.result.ResultFragment.updateUIEvent
|
||||
import com.lagradost.cloudstream3.ui.search.SearchAdapter
|
||||
import com.lagradost.cloudstream3.ui.search.SearchHelper
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.getNameFull
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.html
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
|
||||
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialogInstant
|
||||
import com.lagradost.cloudstream3.utils.UIHelper
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.navigate
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.popCurrentPage
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.setImage
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
class ResultFragmentTv : ResultFragment() {
|
||||
override var layout = R.layout.fragment_result_tv
|
||||
|
||||
class ResultFragmentTv : Fragment() {
|
||||
protected lateinit var viewModel: ResultViewModel2
|
||||
private var binding: FragmentResultTvBinding? = null
|
||||
|
||||
override fun onDestroyView() {
|
||||
binding = null
|
||||
updateUIEvent -= ::updateUI
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
|
@ -52,11 +60,18 @@ class ResultFragmentTv : ResultFragment() {
|
|||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val root = super.onCreateView(inflater, container, savedInstanceState) ?: return null
|
||||
binding = FragmentResultTvBinding.bind(root)
|
||||
): View {
|
||||
viewModel =
|
||||
ViewModelProvider(this)[ResultViewModel2::class.java]
|
||||
updateUIEvent += ::updateUI
|
||||
|
||||
return root
|
||||
val localBinding = FragmentResultTvBinding.inflate(inflater, container, false)
|
||||
binding = localBinding
|
||||
return localBinding.root
|
||||
}
|
||||
|
||||
private fun updateUI(id : Int?) {
|
||||
viewModel.reloadEpisodes()
|
||||
}
|
||||
|
||||
private var currentRecommendations: List<SearchResponse> = emptyList()
|
||||
|
@ -102,25 +117,6 @@ class ResultFragmentTv : ResultFragment() {
|
|||
return focus == binding?.resultRoot
|
||||
}
|
||||
|
||||
override fun setTrailers(trailers: List<ExtractorLink>?) {
|
||||
context?.updateHasTrailers()
|
||||
if (!LoadResponse.isTrailersEnabled) return
|
||||
binding?.resultPlayTrailer?.apply {
|
||||
isGone = trailers.isNullOrEmpty()
|
||||
setOnClickListener {
|
||||
if (trailers.isNullOrEmpty()) return@setOnClickListener
|
||||
activity.navigate(
|
||||
R.id.global_to_navigation_player, GeneratorPlayer.newInstance(
|
||||
ExtractorLinkGenerator(
|
||||
trailers,
|
||||
emptyList()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setRecommendations(rec: List<SearchResponse>?, validApiName: String?) {
|
||||
currentRecommendations = rec ?: emptyList()
|
||||
val isInvalid = rec.isNullOrEmpty()
|
||||
|
@ -145,15 +141,78 @@ class ResultFragmentTv : ResultFragment() {
|
|||
var loadingDialog: Dialog? = null
|
||||
var popupDialog: Dialog? = null
|
||||
|
||||
private fun reloadViewModel(forceReload : Boolean) {
|
||||
if (!viewModel.hasLoaded() || forceReload) {
|
||||
val storedData = getStoredData() ?: return
|
||||
viewModel.load(
|
||||
activity,
|
||||
storedData.url,
|
||||
storedData.apiName,
|
||||
storedData.showFillers,
|
||||
storedData.dubStatus,
|
||||
storedData.start
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
activity?.let {
|
||||
it.window?.navigationBarColor =
|
||||
it.colorFromAttribute(R.attr.primaryBlackBackground)
|
||||
}
|
||||
afterPluginsLoadedEvent += ::reloadViewModel
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
afterPluginsLoadedEvent -= ::reloadViewModel
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// ===== setup =====
|
||||
val storedData = getStoredData() ?: return
|
||||
activity?.window?.decorView?.clearFocus()
|
||||
activity?.loadCache()
|
||||
hideKeyboard()
|
||||
if (storedData.restart || !viewModel.hasLoaded())
|
||||
viewModel.load(
|
||||
activity,
|
||||
storedData.url,
|
||||
storedData.apiName,
|
||||
storedData.showFillers,
|
||||
storedData.dubStatus,
|
||||
storedData.start
|
||||
)
|
||||
// ===== ===== =====
|
||||
|
||||
binding?.apply {
|
||||
resultEpisodes.layoutManager =
|
||||
LinearListLayout(resultEpisodes.context).apply {
|
||||
setHorizontal()
|
||||
}
|
||||
|
||||
resultReloadConnectionerror.setOnClickListener {
|
||||
viewModel.load(
|
||||
activity,
|
||||
storedData.url,
|
||||
storedData.apiName,
|
||||
storedData.showFillers,
|
||||
storedData.dubStatus,
|
||||
storedData.start
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
resultMetaSite.isFocusable = false
|
||||
|
||||
//resultReloadConnectionOpenInBrowser.setOnClickListener {view ->
|
||||
// view.context?.openBrowser(storedData?.url ?: return@setOnClickListener, fallbackWebview = true)
|
||||
//}
|
||||
|
||||
resultSeasonSelection.setAdapter()
|
||||
resultRangeSelection.setAdapter()
|
||||
resultDubSelection.setAdapter()
|
||||
|
@ -180,12 +239,97 @@ class ResultFragmentTv : ResultFragment() {
|
|||
EpisodeAdapter(
|
||||
false,
|
||||
{ episodeClick ->
|
||||
viewModel.handleAction(activity, episodeClick)
|
||||
viewModel.handleAction(episodeClick)
|
||||
},
|
||||
{ downloadClickEvent ->
|
||||
DownloadButtonSetup.handleDownloadClick(downloadClickEvent)
|
||||
}
|
||||
)
|
||||
|
||||
resultCastItems.layoutManager = object : LinearListLayout(view.context) {
|
||||
override fun onRequestChildFocus(
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State,
|
||||
child: View,
|
||||
focused: View?
|
||||
): Boolean {
|
||||
// Make the cast always focus the first visible item when focused
|
||||
// from somewhere else. Otherwise it jumps to the last item.
|
||||
return if (parent.focusedChild == null) {
|
||||
scrollToPosition(this.findFirstCompletelyVisibleItemPosition())
|
||||
true
|
||||
} else {
|
||||
super.onRequestChildFocus(parent, state, child, focused)
|
||||
}
|
||||
}
|
||||
}.apply {
|
||||
this.orientation = RecyclerView.HORIZONTAL
|
||||
}
|
||||
resultCastItems.adapter = ActorAdaptor()
|
||||
}
|
||||
|
||||
observeNullable(viewModel.resumeWatching) { resume ->
|
||||
binding?.apply {
|
||||
if (resume == null) {
|
||||
resultResumeParent.isVisible = false
|
||||
return@observeNullable
|
||||
}
|
||||
resultResumeParent.isVisible = true
|
||||
resume.progress?.let { progress ->
|
||||
resultResumeSeriesTitle.apply {
|
||||
isVisible = !resume.isMovie
|
||||
text =
|
||||
if (resume.isMovie) null else context?.getNameFull(
|
||||
resume.result.name,
|
||||
resume.result.episode,
|
||||
resume.result.season
|
||||
)
|
||||
}
|
||||
|
||||
resultResumeSeriesProgressText.setText(progress.progressLeft)
|
||||
resultResumeSeriesProgress.apply {
|
||||
isVisible = true
|
||||
this.max = progress.maxProgress
|
||||
this.progress = progress.progress
|
||||
}
|
||||
resultResumeProgressHolder.isVisible = true
|
||||
} ?: run {
|
||||
resultResumeProgressHolder.isVisible = false
|
||||
resultResumeSeriesProgress.isVisible = false
|
||||
resultResumeSeriesTitle.isVisible = false
|
||||
resultResumeSeriesProgressText.isVisible = false
|
||||
}
|
||||
|
||||
resultResumeSeriesButton.isVisible = !resume.isMovie
|
||||
resultResumeSeriesButton.setOnClickListener {
|
||||
viewModel.handleAction(
|
||||
EpisodeClickEvent(
|
||||
storedData.playerAction, //?: ACTION_PLAY_EPISODE_IN_PLAYER,
|
||||
resume.result
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
observe(viewModel.trailers) { trailersLinks ->
|
||||
context?.updateHasTrailers()
|
||||
if (!LoadResponse.isTrailersEnabled) return@observe
|
||||
val trailers = trailersLinks.flatMap { it.mirros }
|
||||
binding?.resultPlayTrailer?.apply {
|
||||
isGone = trailers.isEmpty()
|
||||
setOnClickListener {
|
||||
if (trailers.isEmpty()) return@setOnClickListener
|
||||
activity.navigate(
|
||||
R.id.global_to_navigation_player, GeneratorPlayer.newInstance(
|
||||
ExtractorLinkGenerator(
|
||||
trailers,
|
||||
emptyList()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
observe(viewModel.watchStatus) { watchType ->
|
||||
|
@ -211,13 +355,11 @@ class ResultFragmentTv : ResultFragment() {
|
|||
resultPlayMovie.setText(text)
|
||||
resultPlayMovie.setOnClickListener {
|
||||
viewModel.handleAction(
|
||||
activity,
|
||||
EpisodeClickEvent(ACTION_CLICK_DEFAULT, ep)
|
||||
)
|
||||
}
|
||||
resultPlayMovie.setOnLongClickListener {
|
||||
viewModel.handleAction(
|
||||
activity,
|
||||
EpisodeClickEvent(ACTION_SHOW_OPTIONS, ep)
|
||||
)
|
||||
return@setOnLongClickListener true
|
||||
|
@ -397,8 +539,7 @@ class ResultFragmentTv : ResultFragment() {
|
|||
|
||||
is Resource.Failure -> {
|
||||
resultErrorText.text =
|
||||
(this@ResultFragmentTv.context?.let { getStoredData(it) }?.url?.plus("\n")
|
||||
?: "") + data.errorString
|
||||
storedData.url.plus("\n") + data.errorString
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,7 +548,7 @@ class ResultFragmentTv : ResultFragment() {
|
|||
resultLoading.isVisible = data is Resource.Loading
|
||||
|
||||
resultLoadingError.isVisible = data is Resource.Failure
|
||||
resultReloadConnectionOpenInBrowser.isVisible = data is Resource.Failure
|
||||
//resultReloadConnectionOpenInBrowser.isVisible = data is Resource.Failure
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import com.lagradost.cloudstream3.APIHolder.getId
|
|||
import com.lagradost.cloudstream3.APIHolder.unixTime
|
||||
import com.lagradost.cloudstream3.APIHolder.unixTimeMS
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||
import com.lagradost.cloudstream3.CommonActivity.activity
|
||||
import com.lagradost.cloudstream3.CommonActivity.getCastSession
|
||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
|
||||
|
@ -1144,9 +1145,9 @@ class ResultViewModel2 : ViewModel() {
|
|||
}
|
||||
|
||||
|
||||
fun handleAction(activity: Activity?, click: EpisodeClickEvent) =
|
||||
fun handleAction(click: EpisodeClickEvent) =
|
||||
viewModelScope.launchSafe {
|
||||
handleEpisodeClickEvent(activity, click)
|
||||
handleEpisodeClickEvent(click)
|
||||
}
|
||||
|
||||
data class ExternalApp(
|
||||
|
@ -1176,7 +1177,7 @@ class ResultViewModel2 : ViewModel() {
|
|||
_episodeSynopsis.postValue(null)
|
||||
}
|
||||
|
||||
private suspend fun handleEpisodeClickEvent(activity: Activity?, click: EpisodeClickEvent) {
|
||||
private suspend fun handleEpisodeClickEvent(click: EpisodeClickEvent) {
|
||||
when (click.action) {
|
||||
ACTION_SHOW_OPTIONS -> {
|
||||
val options = mutableListOf<Pair<UiText, Int>>()
|
||||
|
@ -1234,7 +1235,6 @@ class ResultViewModel2 : ViewModel() {
|
|||
options
|
||||
) { result ->
|
||||
handleEpisodeClickEvent(
|
||||
activity,
|
||||
click.copy(action = result ?: return@postPopup)
|
||||
)
|
||||
}
|
||||
|
@ -1244,13 +1244,11 @@ class ResultViewModel2 : ViewModel() {
|
|||
activity?.let { ctx ->
|
||||
if (ctx.isConnectedToChromecast()) {
|
||||
handleEpisodeClickEvent(
|
||||
activity,
|
||||
click.copy(action = ACTION_CHROME_CAST_EPISODE)
|
||||
)
|
||||
} else {
|
||||
val action = getPlayerAction(ctx)
|
||||
handleEpisodeClickEvent(
|
||||
activity,
|
||||
click.copy(action = action)
|
||||
)
|
||||
}
|
||||
|
@ -2210,7 +2208,6 @@ class ResultViewModel2 : ViewModel() {
|
|||
for (ep in currentRange) {
|
||||
if (ep.getWatchProgress() > 0.9) continue
|
||||
handleAction(
|
||||
activity,
|
||||
EpisodeClickEvent(
|
||||
getPlayerAction(activity),
|
||||
ep
|
||||
|
@ -2231,7 +2228,6 @@ class ResultViewModel2 : ViewModel() {
|
|||
}
|
||||
?: return@launchSafe
|
||||
handleAction(
|
||||
activity,
|
||||
EpisodeClickEvent(
|
||||
getPlayerAction(activity),
|
||||
episode
|
||||
|
|
|
@ -33,6 +33,7 @@ import androidx.core.widget.ContentLoadingProgressBar
|
|||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
@ -54,6 +55,7 @@ import com.lagradost.cloudstream3.mvvm.logError
|
|||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||
import com.lagradost.cloudstream3.plugins.RepositoryManager
|
||||
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringResumeWatching
|
||||
import com.lagradost.cloudstream3.syncproviders.providers.Kitsu
|
||||
import com.lagradost.cloudstream3.ui.WebviewFragment
|
||||
import com.lagradost.cloudstream3.ui.result.ResultFragment
|
||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
||||
|
@ -597,6 +599,14 @@ object AppUtils {
|
|||
startAction: Int = 0,
|
||||
startValue: Int = 0
|
||||
) {
|
||||
try {
|
||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
Kitsu.isEnabled =
|
||||
settingsManager.getBoolean(this.getString(R.string.show_kitsu_posters_key), true)
|
||||
}catch (t : Throwable) {
|
||||
logError(t)
|
||||
}
|
||||
|
||||
this.runOnUiThread {
|
||||
// viewModelStore.clear()
|
||||
this.navigate(
|
||||
|
|
|
@ -88,6 +88,7 @@
|
|||
android:text="@string/reload_error"
|
||||
app:icon="@drawable/ic_baseline_autorenew_24" />
|
||||
|
||||
<!--
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/result_reload_connection_open_in_browser"
|
||||
style="@style/BlackButton"
|
||||
|
@ -99,6 +100,7 @@
|
|||
android:minWidth="200dp"
|
||||
android:text="@string/result_open_in_browser"
|
||||
app:icon="@drawable/ic_baseline_public_24" />
|
||||
-->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/result_error_text"
|
||||
|
@ -439,7 +441,7 @@
|
|||
android:minWidth="250dp"
|
||||
android:nextFocusRight="@id/result_play_trailer"
|
||||
android:nextFocusUp="@id/result_cast_items"
|
||||
android:nextFocusDown="@id/result_resume_series_button_play"
|
||||
android:nextFocusDown="@id/result_resume_series_button"
|
||||
android:text="@string/play_movie_button"
|
||||
android:visibility="visible"
|
||||
app:icon="@drawable/ic_baseline_play_arrow_24">
|
||||
|
@ -457,7 +459,7 @@
|
|||
android:minWidth="250dp"
|
||||
android:nextFocusRight="@id/download_button"
|
||||
android:nextFocusUp="@id/result_cast_items"
|
||||
android:nextFocusDown="@id/result_resume_series_button_play"
|
||||
android:nextFocusDown="@id/result_resume_series_button"
|
||||
android:text="@string/play_trailer_button"
|
||||
android:visibility="gone"
|
||||
app:icon="@drawable/ic_baseline_play_arrow_24">
|
||||
|
@ -486,7 +488,7 @@
|
|||
android:minWidth="250dp"
|
||||
android:nextFocusLeft="@id/download_button"
|
||||
android:nextFocusRight="@id/result_bookmark_button"
|
||||
android:nextFocusDown="@id/result_resume_series_button_play"
|
||||
android:nextFocusDown="@id/result_resume_series_button"
|
||||
android:text="@string/type_none"
|
||||
android:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
@ -521,7 +523,7 @@
|
|||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/result_resume_series_button_play"
|
||||
android:id="@+id/result_resume_series_button"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
|
||||
|
@ -600,7 +602,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:nextFocusUp="@id/result_resume_series_button_play"
|
||||
android:nextFocusUp="@id/result_resume_series_button"
|
||||
android:nextFocusDown="@id/result_range_selection"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="10dp"
|
||||
|
|
Loading…
Reference in a new issue