removed synthetic by removing ResultFragment

This commit is contained in:
LagradOst 2023-07-19 01:51:17 +02:00
parent 4fcf396591
commit ed0d374721
7 changed files with 459 additions and 355 deletions

View file

@ -7,7 +7,6 @@ plugins {
id("com.android.application") id("com.android.application")
id("kotlin-android") id("kotlin-android")
id("kotlin-kapt") id("kotlin-kapt")
id("kotlin-android-extensions")
id("org.jetbrains.dokka") id("org.jetbrains.dokka")
} }

View file

@ -1,94 +1,18 @@
package com.lagradost.cloudstream3.ui.result 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.os.Bundle
import android.view.LayoutInflater import androidx.fragment.app.Fragment
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.preference.PreferenceManager 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.getApiDubstatusSettings
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
import com.lagradost.cloudstream3.APIHolder.updateHasTrailers
import com.lagradost.cloudstream3.DubStatus import com.lagradost.cloudstream3.DubStatus
import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.TvType 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.result.EpisodeAdapter.Companion.getPlayerAction
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings import com.lagradost.cloudstream3.utils.DataStoreHelper
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.getVideoWatchState import com.lagradost.cloudstream3.utils.DataStoreHelper.getVideoWatchState
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute import com.lagradost.cloudstream3.utils.Event
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
const val START_ACTION_RESUME_LATEST = 1 const val START_ACTION_RESUME_LATEST = 1
const val START_ACTION_LOAD_EP = 2 const val START_ACTION_LOAD_EP = 2
@ -188,15 +112,14 @@ fun ResultEpisode.getWatchProgress(): Float {
return (getDisplayPosition() / 1000).toFloat() / (duration / 1000).toFloat() return (getDisplayPosition() / 1000).toFloat() / (duration / 1000).toFloat()
} }
open class ResultFragment : FullScreenPlayer() { object ResultFragment {
companion object { private const val URL_BUNDLE = "url"
const val URL_BUNDLE = "url" private const val API_NAME_BUNDLE = "apiName"
const val API_NAME_BUNDLE = "apiName" private const val SEASON_BUNDLE = "season"
const val SEASON_BUNDLE = "season" private const val EPISODE_BUNDLE = "episode"
const val EPISODE_BUNDLE = "episode" private const val START_ACTION_BUNDLE = "startAction"
const val START_ACTION_BUNDLE = "startAction" private const val START_VALUE_BUNDLE = "startValue"
const val START_VALUE_BUNDLE = "startValue" private const val RESTART_BUNDLE = "restart"
const val RESTART_BUNDLE = "restart"
fun newInstance( fun newInstance(
card: SearchResponse, startAction: Int = 0, startValue: Int? = null card: SearchResponse, startAction: Int = 0, startValue: Int? = null
@ -234,30 +157,24 @@ open class ResultFragment : FullScreenPlayer() {
} }
} }
fun updateUI() { fun updateUI(id: Int? = null) {
updateUIListener?.invoke() // updateUIListener?.invoke()
updateUIEvent.invoke(id)
} }
val updateUIEvent = Event<Int?>()
private var updateUIListener: (() -> Unit)? = null //private var updateUIListener: (() -> Unit)? = null
}
open fun setTrailers(trailers: List<ExtractorLink>?) {}
protected lateinit var viewModel: ResultViewModel2 //by activityViewModels()
protected lateinit var syncModel: SyncViewModel
//protected open val resultLayout = R.layout.fragment_result_swipe //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( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle?, savedInstanceState: Bundle?,
): View? { ): View? {
viewModel =
ViewModelProvider(this)[ResultViewModel2::class.java]
syncModel =
ViewModelProvider(this)[SyncViewModel::class.java]
return super.onCreateView(inflater, container, savedInstanceState) return super.onCreateView(inflater, container, savedInstanceState)
//return inflater.inflate(resultLayout, container, false) //return inflater.inflate(resultLayout, container, false)
@ -286,20 +203,22 @@ open class ResultFragment : FullScreenPlayer() {
private fun updateUI() { private fun updateUI() {
syncModel.updateUserData() syncModel.updateUserData()
viewModel.reloadEpisodes() viewModel.reloadEpisodes()
} }*/
data class StoredData( data class StoredData(
val url: String?, val url: String,
val apiName: String, val apiName: String,
val showFillers: Boolean, val showFillers: Boolean,
val dubStatus: DubStatus, val dubStatus: DubStatus,
val start: AutoResume?, 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 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 apiName = arguments?.getString(API_NAME_BUNDLE) ?: return null
val showFillers = val showFillers =
settingsManager.getBoolean(context.getString(R.string.show_fillers_key), false) settingsManager.getBoolean(context.getString(R.string.show_fillers_key), false)
@ -310,6 +229,11 @@ open class ResultFragment : FullScreenPlayer() {
val playerAction = getPlayerAction(context) val playerAction = getPlayerAction(context)
val restart = arguments?.getBoolean(RESTART_BUNDLE) ?: false
if (restart) {
arguments?.putBoolean(RESTART_BUNDLE, false)
}
val start = startAction?.let { action -> val start = startAction?.let { action ->
val startValue = arguments?.getInt(START_VALUE_BUNDLE) val startValue = arguments?.getInt(START_VALUE_BUNDLE)
val resumeEpisode = arguments?.getInt(EPISODE_BUNDLE) val resumeEpisode = arguments?.getInt(EPISODE_BUNDLE)
@ -324,10 +248,10 @@ open class ResultFragment : FullScreenPlayer() {
season = resumeSeason 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) { if (!viewModel.hasLoaded() || forceReload) {
val storedData = getStoredData(activity ?: context ?: return) ?: return val storedData = getStoredData(activity ?: context ?: return) ?: return
@ -346,26 +270,6 @@ open class ResultFragment : FullScreenPlayer() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) 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 updateUIListener = ::updateUI
@ -401,97 +305,7 @@ open class ResultFragment : FullScreenPlayer() {
result_season_button?.isFocusableInTouchMode = isTv result_season_button?.isFocusableInTouchMode = isTv
result_episode_select?.isFocusableInTouchMode = isTv result_episode_select?.isFocusableInTouchMode = isTv
result_dub_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) { 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()) { if (restart || !viewModel.hasLoaded()) {
//viewModel.clear() //viewModel.clear()
viewModel.load( viewModel.load(
@ -504,6 +318,5 @@ open class ResultFragment : FullScreenPlayer() {
) )
} }
} }
} }*/
}
} }

View file

@ -5,7 +5,6 @@ import android.app.Dialog
import android.content.Intent import android.content.Intent
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.graphics.Rect import android.graphics.Rect
import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
@ -23,6 +22,8 @@ import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.widget.NestedScrollView import androidx.core.widget.NestedScrollView
import androidx.core.widget.doOnTextChanged import androidx.core.widget.doOnTextChanged
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.RecyclerView
import com.discord.panels.OverlappingPanelsLayout import com.discord.panels.OverlappingPanelsLayout
import com.discord.panels.PanelsChildGestureRegionObserver import com.discord.panels.PanelsChildGestureRegionObserver
import com.google.android.gms.cast.framework.CastButtonFactory 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.CommonActivity
import com.lagradost.cloudstream3.DubStatus import com.lagradost.cloudstream3.DubStatus
import com.lagradost.cloudstream3.LoadResponse import com.lagradost.cloudstream3.LoadResponse
import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.databinding.FragmentResultBinding 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.DOWNLOAD_ACTION_DOWNLOAD
import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup
import com.lagradost.cloudstream3.ui.player.CSPlayerEvent 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.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.SearchAdapter
import com.lagradost.cloudstream3.ui.search.SearchHelper 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.html
import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable 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.AppUtils.openBrowser
import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog 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
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe 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.popCurrentPage
import com.lagradost.cloudstream3.utils.UIHelper.populateChips import com.lagradost.cloudstream3.utils.UIHelper.populateChips
import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes
@ -70,17 +78,29 @@ import com.lagradost.cloudstream3.utils.UIHelper.setImage
import com.lagradost.cloudstream3.utils.VideoDownloadHelper import com.lagradost.cloudstream3.utils.VideoDownloadHelper
open class ResultFragmentPhone : ResultFragment(), open class ResultFragmentPhone : FullScreenPlayer(),
PanelsChildGestureRegionObserver.GestureRegionsListener { PanelsChildGestureRegionObserver.GestureRegionsListener {
protected lateinit var viewModel: ResultViewModel2
protected lateinit var syncModel: SyncViewModel
protected var binding: FragmentResultSwipeBinding? = null protected var binding: FragmentResultSwipeBinding? = null
protected var resultBinding: FragmentResultBinding? = null protected var resultBinding: FragmentResultBinding? = null
protected var recommendationBinding: ResultRecommendationsBinding? = null protected var recommendationBinding: ResultRecommendationsBinding? = null
protected var syncBinding: ResultSyncBinding? = null protected var syncBinding: ResultSyncBinding? = null
override var layout = R.layout.fragment_result_swipe
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
viewModel =
ViewModelProvider(this)[ResultViewModel2::class.java]
syncModel =
ViewModelProvider(this)[SyncViewModel::class.java]
updateUIEvent += ::updateUI
val root = super.onCreateView(inflater, container, savedInstanceState) ?: return null val root = super.onCreateView(inflater, container, savedInstanceState) ?: return null
FragmentResultSwipeBinding.bind(root).let { bind -> FragmentResultSwipeBinding.bind(root).let { bind ->
resultBinding = resultBinding =
@ -180,7 +200,7 @@ open class ResultFragmentPhone : ResultFragment(),
} }
override fun setTrailers(trailers: List<ExtractorLink>?) { private fun setTrailers(trailers: List<ExtractorLink>?) {
context?.updateHasTrailers() context?.updateHasTrailers()
if (!LoadResponse.isTrailersEnabled) return if (!LoadResponse.isTrailersEnabled) return
currentTrailers = trailers?.sortedBy { -it.quality } ?: emptyList() currentTrailers = trailers?.sortedBy { -it.quality } ?: emptyList()
@ -196,6 +216,7 @@ open class ResultFragmentPhone : ResultFragment(),
} }
obs.removeGestureRegionsUpdateListener(this) obs.removeGestureRegionsUpdateListener(this)
} }
updateUIEvent -= ::updateUI
binding = null binding = null
resultBinding = null resultBinding = null
syncBinding = null syncBinding = null
@ -218,48 +239,128 @@ open class ResultFragmentPhone : ResultFragment(),
var selectSeason: String? = null var selectSeason: String? = null
private fun setUrl(url : String?) { private fun setUrl(url: String?) {
if(url == null) { if (url == null) {
binding?.resultOpenInBrowser?.isVisible = false binding?.resultOpenInBrowser?.isVisible = false
return return
} }
val valid = url.startsWith("http")
binding?.resultOpenInBrowser?.apply { binding?.resultOpenInBrowser?.apply {
isVisible = url.startsWith("http") isVisible = valid
setOnClickListener { setOnClickListener {
val i = Intent(Intent.ACTION_VIEW) context?.openBrowser(url)
i.data = Uri.parse(url)
try {
startActivity(i)
} catch (e: Exception) {
logError(e)
} }
} }
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") @SuppressLint("SetTextI18n")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val apiName = arguments?.getString(API_NAME_BUNDLE) ?: return
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
// ===== setup =====
UIHelper.fixPaddingStatusbar(binding?.resultTopBar) UIHelper.fixPaddingStatusbar(binding?.resultTopBar)
val storedData = (activity ?: context)?.let { val storedData = getStoredData() ?: return
getStoredData(it) 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) setUrl(storedData.url)
syncModel.addFromUrl(storedData?.url) syncModel.addFromUrl(storedData.url)
val api = APIHolder.getApiFromNameNull(storedData.apiName)
val api = APIHolder.getApiFromNameNull(apiName) PanelsChildGestureRegionObserver.Provider.get().addGestureRegionsUpdateListener(this)
// ===== ===== =====
resultBinding?.apply { 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 = resultEpisodes.adapter =
EpisodeAdapter( EpisodeAdapter(
api?.hasDownloadSupport == true, api?.hasDownloadSupport == true,
{ episodeClick -> { episodeClick ->
viewModel.handleAction(activity, episodeClick) viewModel.handleAction(episodeClick)
}, },
{ downloadClickEvent -> { downloadClickEvent ->
DownloadButtonSetup.handleDownloadClick(downloadClickEvent) DownloadButtonSetup.handleDownloadClick(downloadClickEvent)
@ -291,6 +392,8 @@ open class ResultFragmentPhone : ResultFragment(),
resultBack.setOnClickListener { resultBack.setOnClickListener {
activity?.popCurrentPage() activity?.popCurrentPage()
} }
resultMiniSync.adapter = ImageAdapter( resultMiniSync.adapter = ImageAdapter(
nextFocusDown = R.id.result_sync_set_score, nextFocusDown = R.id.result_sync_set_score,
clickCallback = { action -> clickCallback = { action ->
@ -368,7 +471,6 @@ open class ResultFragmentPhone : ResultFragment(),
} }
} }
PanelsChildGestureRegionObserver.Provider.get().addGestureRegionsUpdateListener(this)
/* /*
result_bookmark_button?.setOnClickListener { 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 -> observeNullable(viewModel.subscribeStatus) { isSubscribed ->
binding?.resultSubscribe?.isVisible = isSubscribed != null binding?.resultSubscribe?.isVisible = isSubscribed != null
if (isSubscribed == null) return@observeNullable if (isSubscribed == null) return@observeNullable
@ -403,7 +549,7 @@ open class ResultFragmentPhone : ResultFragment(),
// no failure? // no failure?
resultEpisodeLoading.isVisible = episodes is Resource.Loading resultEpisodeLoading.isVisible = episodes is Resource.Loading
resultEpisodes.isVisible = episodes is Resource.Success resultEpisodes.isVisible = episodes is Resource.Success
if(episodes is Resource.Success) { if (episodes is Resource.Success) {
(resultEpisodes.adapter as? EpisodeAdapter)?.updateList(episodes.value) (resultEpisodes.adapter as? EpisodeAdapter)?.updateList(episodes.value)
} }
} }
@ -419,13 +565,11 @@ open class ResultFragmentPhone : ResultFragment(),
resultPlayMovie.setText(text) resultPlayMovie.setText(text)
resultPlayMovie.setOnClickListener { resultPlayMovie.setOnClickListener {
viewModel.handleAction( viewModel.handleAction(
activity,
EpisodeClickEvent(ACTION_CLICK_DEFAULT, ep) EpisodeClickEvent(ACTION_CLICK_DEFAULT, ep)
) )
} }
resultPlayMovie.setOnLongClickListener { resultPlayMovie.setOnLongClickListener {
viewModel.handleAction( viewModel.handleAction(
activity,
EpisodeClickEvent(ACTION_SHOW_OPTIONS, ep) EpisodeClickEvent(ACTION_SHOW_OPTIONS, ep)
) )
return@setOnLongClickListener true return@setOnLongClickListener true
@ -446,7 +590,6 @@ open class ResultFragmentPhone : ResultFragment(),
when (click.action) { when (click.action) {
DOWNLOAD_ACTION_DOWNLOAD -> { DOWNLOAD_ACTION_DOWNLOAD -> {
viewModel.handleAction( viewModel.handleAction(
activity,
EpisodeClickEvent(ACTION_DOWNLOAD_EPISODE, ep) EpisodeClickEvent(ACTION_DOWNLOAD_EPISODE, ep)
) )
} }
@ -529,7 +672,7 @@ open class ResultFragmentPhone : ResultFragment(),
} }
(data as? Resource.Failure)?.let { data -> (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 binding?.resultBookmarkFab?.isVisible = data is Resource.Success

View file

@ -9,11 +9,14 @@ import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import com.lagradost.cloudstream3.APIHolder.updateHasTrailers import com.lagradost.cloudstream3.APIHolder.updateHasTrailers
import com.lagradost.cloudstream3.DubStatus import com.lagradost.cloudstream3.DubStatus
import com.lagradost.cloudstream3.LoadResponse import com.lagradost.cloudstream3.LoadResponse
import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.databinding.FragmentResultTvBinding 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.download.DownloadButtonSetup
import com.lagradost.cloudstream3.ui.player.ExtractorLinkGenerator import com.lagradost.cloudstream3.ui.player.ExtractorLinkGenerator
import com.lagradost.cloudstream3.ui.player.GeneratorPlayer 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.SearchAdapter
import com.lagradost.cloudstream3.ui.search.SearchHelper 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.html
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
import com.lagradost.cloudstream3.utils.Coroutines.main 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.showBottomDialog
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialogInstant import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialogInstant
import com.lagradost.cloudstream3.utils.UIHelper 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.dismissSafe
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
import com.lagradost.cloudstream3.utils.UIHelper.navigate import com.lagradost.cloudstream3.utils.UIHelper.navigate
import com.lagradost.cloudstream3.utils.UIHelper.popCurrentPage import com.lagradost.cloudstream3.utils.UIHelper.popCurrentPage
import com.lagradost.cloudstream3.utils.UIHelper.setImage import com.lagradost.cloudstream3.utils.UIHelper.setImage
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
class ResultFragmentTv : ResultFragment() { class ResultFragmentTv : Fragment() {
override var layout = R.layout.fragment_result_tv protected lateinit var viewModel: ResultViewModel2
private var binding: FragmentResultTvBinding? = null private var binding: FragmentResultTvBinding? = null
override fun onDestroyView() { override fun onDestroyView() {
binding = null binding = null
updateUIEvent -= ::updateUI
super.onDestroyView() super.onDestroyView()
} }
@ -52,11 +60,18 @@ class ResultFragmentTv : ResultFragment() {
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View {
val root = super.onCreateView(inflater, container, savedInstanceState) ?: return null viewModel =
binding = FragmentResultTvBinding.bind(root) 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() private var currentRecommendations: List<SearchResponse> = emptyList()
@ -102,25 +117,6 @@ class ResultFragmentTv : ResultFragment() {
return focus == binding?.resultRoot 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?) { private fun setRecommendations(rec: List<SearchResponse>?, validApiName: String?) {
currentRecommendations = rec ?: emptyList() currentRecommendations = rec ?: emptyList()
val isInvalid = rec.isNullOrEmpty() val isInvalid = rec.isNullOrEmpty()
@ -145,15 +141,78 @@ class ResultFragmentTv : ResultFragment() {
var loadingDialog: Dialog? = null var loadingDialog: Dialog? = null
var popupDialog: 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") @SuppressLint("SetTextI18n")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) 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 { binding?.apply {
resultEpisodes.layoutManager = resultEpisodes.layoutManager =
LinearListLayout(resultEpisodes.context).apply { LinearListLayout(resultEpisodes.context).apply {
setHorizontal() 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() resultSeasonSelection.setAdapter()
resultRangeSelection.setAdapter() resultRangeSelection.setAdapter()
resultDubSelection.setAdapter() resultDubSelection.setAdapter()
@ -180,12 +239,97 @@ class ResultFragmentTv : ResultFragment() {
EpisodeAdapter( EpisodeAdapter(
false, false,
{ episodeClick -> { episodeClick ->
viewModel.handleAction(activity, episodeClick) viewModel.handleAction(episodeClick)
}, },
{ downloadClickEvent -> { downloadClickEvent ->
DownloadButtonSetup.handleDownloadClick(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 -> observe(viewModel.watchStatus) { watchType ->
@ -211,13 +355,11 @@ class ResultFragmentTv : ResultFragment() {
resultPlayMovie.setText(text) resultPlayMovie.setText(text)
resultPlayMovie.setOnClickListener { resultPlayMovie.setOnClickListener {
viewModel.handleAction( viewModel.handleAction(
activity,
EpisodeClickEvent(ACTION_CLICK_DEFAULT, ep) EpisodeClickEvent(ACTION_CLICK_DEFAULT, ep)
) )
} }
resultPlayMovie.setOnLongClickListener { resultPlayMovie.setOnLongClickListener {
viewModel.handleAction( viewModel.handleAction(
activity,
EpisodeClickEvent(ACTION_SHOW_OPTIONS, ep) EpisodeClickEvent(ACTION_SHOW_OPTIONS, ep)
) )
return@setOnLongClickListener true return@setOnLongClickListener true
@ -397,8 +539,7 @@ class ResultFragmentTv : ResultFragment() {
is Resource.Failure -> { is Resource.Failure -> {
resultErrorText.text = resultErrorText.text =
(this@ResultFragmentTv.context?.let { getStoredData(it) }?.url?.plus("\n") storedData.url.plus("\n") + data.errorString
?: "") + data.errorString
} }
} }
@ -407,7 +548,7 @@ class ResultFragmentTv : ResultFragment() {
resultLoading.isVisible = data is Resource.Loading resultLoading.isVisible = data is Resource.Loading
resultLoadingError.isVisible = data is Resource.Failure resultLoadingError.isVisible = data is Resource.Failure
resultReloadConnectionOpenInBrowser.isVisible = data is Resource.Failure //resultReloadConnectionOpenInBrowser.isVisible = data is Resource.Failure
} }
} }
} }

View file

@ -19,6 +19,7 @@ import com.lagradost.cloudstream3.APIHolder.getId
import com.lagradost.cloudstream3.APIHolder.unixTime import com.lagradost.cloudstream3.APIHolder.unixTime
import com.lagradost.cloudstream3.APIHolder.unixTimeMS import com.lagradost.cloudstream3.APIHolder.unixTimeMS
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.CommonActivity.activity
import com.lagradost.cloudstream3.CommonActivity.getCastSession import com.lagradost.cloudstream3.CommonActivity.getCastSession
import com.lagradost.cloudstream3.CommonActivity.showToast import com.lagradost.cloudstream3.CommonActivity.showToast
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer 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 { viewModelScope.launchSafe {
handleEpisodeClickEvent(activity, click) handleEpisodeClickEvent(click)
} }
data class ExternalApp( data class ExternalApp(
@ -1176,7 +1177,7 @@ class ResultViewModel2 : ViewModel() {
_episodeSynopsis.postValue(null) _episodeSynopsis.postValue(null)
} }
private suspend fun handleEpisodeClickEvent(activity: Activity?, click: EpisodeClickEvent) { private suspend fun handleEpisodeClickEvent(click: EpisodeClickEvent) {
when (click.action) { when (click.action) {
ACTION_SHOW_OPTIONS -> { ACTION_SHOW_OPTIONS -> {
val options = mutableListOf<Pair<UiText, Int>>() val options = mutableListOf<Pair<UiText, Int>>()
@ -1234,7 +1235,6 @@ class ResultViewModel2 : ViewModel() {
options options
) { result -> ) { result ->
handleEpisodeClickEvent( handleEpisodeClickEvent(
activity,
click.copy(action = result ?: return@postPopup) click.copy(action = result ?: return@postPopup)
) )
} }
@ -1244,13 +1244,11 @@ class ResultViewModel2 : ViewModel() {
activity?.let { ctx -> activity?.let { ctx ->
if (ctx.isConnectedToChromecast()) { if (ctx.isConnectedToChromecast()) {
handleEpisodeClickEvent( handleEpisodeClickEvent(
activity,
click.copy(action = ACTION_CHROME_CAST_EPISODE) click.copy(action = ACTION_CHROME_CAST_EPISODE)
) )
} else { } else {
val action = getPlayerAction(ctx) val action = getPlayerAction(ctx)
handleEpisodeClickEvent( handleEpisodeClickEvent(
activity,
click.copy(action = action) click.copy(action = action)
) )
} }
@ -2210,7 +2208,6 @@ class ResultViewModel2 : ViewModel() {
for (ep in currentRange) { for (ep in currentRange) {
if (ep.getWatchProgress() > 0.9) continue if (ep.getWatchProgress() > 0.9) continue
handleAction( handleAction(
activity,
EpisodeClickEvent( EpisodeClickEvent(
getPlayerAction(activity), getPlayerAction(activity),
ep ep
@ -2231,7 +2228,6 @@ class ResultViewModel2 : ViewModel() {
} }
?: return@launchSafe ?: return@launchSafe
handleAction( handleAction(
activity,
EpisodeClickEvent( EpisodeClickEvent(
getPlayerAction(activity), getPlayerAction(activity),
episode episode

View file

@ -33,6 +33,7 @@ import androidx.core.widget.ContentLoadingProgressBar
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView 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.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.plugins.RepositoryManager import com.lagradost.cloudstream3.plugins.RepositoryManager
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringResumeWatching 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.WebviewFragment
import com.lagradost.cloudstream3.ui.result.ResultFragment import com.lagradost.cloudstream3.ui.result.ResultFragment
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
@ -597,6 +599,14 @@ object AppUtils {
startAction: Int = 0, startAction: Int = 0,
startValue: 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 { this.runOnUiThread {
// viewModelStore.clear() // viewModelStore.clear()
this.navigate( this.navigate(

View file

@ -88,6 +88,7 @@
android:text="@string/reload_error" android:text="@string/reload_error"
app:icon="@drawable/ic_baseline_autorenew_24" /> app:icon="@drawable/ic_baseline_autorenew_24" />
<!--
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/result_reload_connection_open_in_browser" android:id="@+id/result_reload_connection_open_in_browser"
style="@style/BlackButton" style="@style/BlackButton"
@ -99,6 +100,7 @@
android:minWidth="200dp" android:minWidth="200dp"
android:text="@string/result_open_in_browser" android:text="@string/result_open_in_browser"
app:icon="@drawable/ic_baseline_public_24" /> app:icon="@drawable/ic_baseline_public_24" />
-->
<TextView <TextView
android:id="@+id/result_error_text" android:id="@+id/result_error_text"
@ -439,7 +441,7 @@
android:minWidth="250dp" android:minWidth="250dp"
android:nextFocusRight="@id/result_play_trailer" android:nextFocusRight="@id/result_play_trailer"
android:nextFocusUp="@id/result_cast_items" 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:text="@string/play_movie_button"
android:visibility="visible" android:visibility="visible"
app:icon="@drawable/ic_baseline_play_arrow_24"> app:icon="@drawable/ic_baseline_play_arrow_24">
@ -457,7 +459,7 @@
android:minWidth="250dp" android:minWidth="250dp"
android:nextFocusRight="@id/download_button" android:nextFocusRight="@id/download_button"
android:nextFocusUp="@id/result_cast_items" 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:text="@string/play_trailer_button"
android:visibility="gone" android:visibility="gone"
app:icon="@drawable/ic_baseline_play_arrow_24"> app:icon="@drawable/ic_baseline_play_arrow_24">
@ -486,7 +488,7 @@
android:minWidth="250dp" android:minWidth="250dp"
android:nextFocusLeft="@id/download_button" android:nextFocusLeft="@id/download_button"
android:nextFocusRight="@id/result_bookmark_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:text="@string/type_none"
android:visibility="visible" /> android:visibility="visible" />
</LinearLayout> </LinearLayout>
@ -521,7 +523,7 @@
android:orientation="horizontal"> android:orientation="horizontal">
<ImageView <ImageView
android:id="@+id/result_resume_series_button_play" android:id="@+id/result_resume_series_button"
android:layout_width="30dp" android:layout_width="30dp"
android:layout_height="30dp" android:layout_height="30dp"
@ -600,7 +602,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="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:nextFocusDown="@id/result_range_selection"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingBottom="10dp" android:paddingBottom="10dp"