mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
weakrefrence activity for cleaner code + HomeParentItemAdapterPreview viewmodel + more stuff in viewmodel
This commit is contained in:
parent
afadf121f4
commit
4d6e64adb6
29 changed files with 378 additions and 326 deletions
|
@ -34,9 +34,18 @@ import com.lagradost.cloudstream3.utils.UIHelper.hasPIPPermission
|
|||
import com.lagradost.cloudstream3.utils.UIHelper.shouldShowPIPMode
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.toPx
|
||||
import org.schabi.newpipe.extractor.NewPipe
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
|
||||
object CommonActivity {
|
||||
|
||||
private var _activity: WeakReference<Activity>? = null
|
||||
var activity
|
||||
get() = _activity?.get()
|
||||
private set(value) {
|
||||
_activity = WeakReference(value)
|
||||
}
|
||||
|
||||
@MainThread
|
||||
fun Activity?.getCastSession(): CastSession? {
|
||||
return (this as MainActivity?)?.mSessionManager?.currentCastSession
|
||||
|
@ -56,6 +65,30 @@ object CommonActivity {
|
|||
|
||||
var currentToast: Toast? = null
|
||||
|
||||
fun showToast(@StringRes message: Int, duration: Int? = null) {
|
||||
val act = activity ?: return
|
||||
act.runOnUiThread {
|
||||
showToast(act, act.getString(message), duration)
|
||||
}
|
||||
}
|
||||
|
||||
fun showToast(message: String?, duration: Int? = null) {
|
||||
val act = activity ?: return
|
||||
act.runOnUiThread {
|
||||
showToast(act, message, duration)
|
||||
}
|
||||
}
|
||||
|
||||
fun showToast(message: UiText?, duration: Int? = null) {
|
||||
val act = activity ?: return
|
||||
if (message == null) return
|
||||
act.runOnUiThread {
|
||||
showToast(act, message.asString(act), duration)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@MainThread
|
||||
fun showToast(act: Activity?, text: UiText, duration: Int) {
|
||||
if (act == null) return
|
||||
text.asStringNull(act)?.let {
|
||||
|
@ -140,6 +173,7 @@ object CommonActivity {
|
|||
|
||||
fun init(act: ComponentActivity?) {
|
||||
if (act == null) return
|
||||
activity = act
|
||||
//https://stackoverflow.com/questions/52594181/how-to-know-if-user-has-disabled-picture-in-picture-feature-permission
|
||||
//https://developer.android.com/guide/topics/ui/picture-in-picture
|
||||
canShowPipMode =
|
||||
|
@ -222,6 +256,7 @@ object CommonActivity {
|
|||
"AmoledLight" -> R.style.AmoledModeLight
|
||||
"Monet" -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
|
||||
R.style.MonetMode else R.style.AppTheme
|
||||
|
||||
else -> R.style.AppTheme
|
||||
}
|
||||
|
||||
|
@ -244,8 +279,10 @@ object CommonActivity {
|
|||
"Pink" -> R.style.OverlayPrimaryColorPink
|
||||
"Monet" -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
|
||||
R.style.OverlayPrimaryColorMonet else R.style.OverlayPrimaryColorNormal
|
||||
|
||||
"Monet2" -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
|
||||
R.style.OverlayPrimaryColorMonetTwo else R.style.OverlayPrimaryColorNormal
|
||||
|
||||
else -> R.style.OverlayPrimaryColorNormal
|
||||
}
|
||||
act.theme.applyStyle(currentTheme, true)
|
||||
|
@ -271,12 +308,15 @@ object CommonActivity {
|
|||
FocusDirection.Left -> {
|
||||
view.nextFocusLeftId
|
||||
}
|
||||
|
||||
FocusDirection.Up -> {
|
||||
view.nextFocusUpId
|
||||
}
|
||||
|
||||
FocusDirection.Right -> {
|
||||
view.nextFocusRightId
|
||||
}
|
||||
|
||||
FocusDirection.Down -> {
|
||||
view.nextFocusDownId
|
||||
}
|
||||
|
@ -328,30 +368,39 @@ object CommonActivity {
|
|||
KeyEvent.KEYCODE_FORWARD, KeyEvent.KEYCODE_D, KeyEvent.KEYCODE_MEDIA_SKIP_FORWARD, KeyEvent.KEYCODE_MEDIA_FAST_FORWARD -> {
|
||||
PlayerEventType.SeekForward
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_A, KeyEvent.KEYCODE_MEDIA_SKIP_BACKWARD, KeyEvent.KEYCODE_MEDIA_REWIND -> {
|
||||
PlayerEventType.SeekBack
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_MEDIA_NEXT, KeyEvent.KEYCODE_BUTTON_R1, KeyEvent.KEYCODE_N -> {
|
||||
PlayerEventType.NextEpisode
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_MEDIA_PREVIOUS, KeyEvent.KEYCODE_BUTTON_L1, KeyEvent.KEYCODE_B -> {
|
||||
PlayerEventType.PrevEpisode
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_MEDIA_PAUSE -> {
|
||||
PlayerEventType.Pause
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_MEDIA_PLAY, KeyEvent.KEYCODE_BUTTON_START -> {
|
||||
PlayerEventType.Play
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_L, KeyEvent.KEYCODE_NUMPAD_7, KeyEvent.KEYCODE_7 -> {
|
||||
PlayerEventType.Lock
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_H, KeyEvent.KEYCODE_MENU -> {
|
||||
PlayerEventType.ToggleHide
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_M, KeyEvent.KEYCODE_VOLUME_MUTE -> {
|
||||
PlayerEventType.ToggleMute
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_S, KeyEvent.KEYCODE_NUMPAD_9, KeyEvent.KEYCODE_9 -> {
|
||||
PlayerEventType.ShowMirrors
|
||||
}
|
||||
|
@ -359,21 +408,27 @@ object CommonActivity {
|
|||
KeyEvent.KEYCODE_O, KeyEvent.KEYCODE_NUMPAD_8, KeyEvent.KEYCODE_8 -> {
|
||||
PlayerEventType.SearchSubtitlesOnline
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_E, KeyEvent.KEYCODE_NUMPAD_3, KeyEvent.KEYCODE_3 -> {
|
||||
PlayerEventType.ShowSpeed
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_R, KeyEvent.KEYCODE_NUMPAD_0, KeyEvent.KEYCODE_0 -> {
|
||||
PlayerEventType.Resize
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_C, KeyEvent.KEYCODE_NUMPAD_4, KeyEvent.KEYCODE_4 -> {
|
||||
PlayerEventType.SkipOp
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_V, KeyEvent.KEYCODE_NUMPAD_5, KeyEvent.KEYCODE_5 -> {
|
||||
PlayerEventType.SkipCurrentChapter
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, KeyEvent.KEYCODE_P, KeyEvent.KEYCODE_SPACE, KeyEvent.KEYCODE_NUMPAD_ENTER, KeyEvent.KEYCODE_ENTER -> { // space is not captured due to navigation
|
||||
PlayerEventType.PlayPauseToggle
|
||||
}
|
||||
|
||||
else -> null
|
||||
}?.let { playerEvent ->
|
||||
playerEventListener?.invoke(playerEvent)
|
||||
|
@ -398,16 +453,19 @@ object CommonActivity {
|
|||
act.currentFocus,
|
||||
FocusDirection.Left
|
||||
)
|
||||
|
||||
KeyEvent.KEYCODE_DPAD_RIGHT -> getNextFocus(
|
||||
act,
|
||||
act.currentFocus,
|
||||
FocusDirection.Right
|
||||
)
|
||||
|
||||
KeyEvent.KEYCODE_DPAD_UP -> getNextFocus(
|
||||
act,
|
||||
act.currentFocus,
|
||||
FocusDirection.Up
|
||||
)
|
||||
|
||||
KeyEvent.KEYCODE_DPAD_DOWN -> getNextFocus(
|
||||
act,
|
||||
act.currentFocus,
|
||||
|
|
|
@ -309,7 +309,6 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
this@with.runOnUiThread {
|
||||
try {
|
||||
showToast(
|
||||
this@with,
|
||||
getString(if (isSuccessful) R.string.authenticated_user else R.string.authenticated_user_fail).format(
|
||||
api.name
|
||||
)
|
||||
|
@ -785,7 +784,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
newLocalBinding
|
||||
}
|
||||
} catch (t: Throwable) {
|
||||
showToast(this, txt(R.string.unable_to_inflate, t.message ?: ""), Toast.LENGTH_LONG)
|
||||
showToast(txt(R.string.unable_to_inflate, t.message ?: ""), Toast.LENGTH_LONG)
|
||||
null
|
||||
}
|
||||
|
||||
|
@ -817,7 +816,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
|
||||
if (PluginManager.checkSafeModeFile()) {
|
||||
normalSafeApiCall {
|
||||
showToast(this, R.string.safe_mode_file, Toast.LENGTH_LONG)
|
||||
showToast( R.string.safe_mode_file, Toast.LENGTH_LONG)
|
||||
}
|
||||
} else if (lastError == null) {
|
||||
ioSafe {
|
||||
|
@ -876,7 +875,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
}
|
||||
when (resource) {
|
||||
is Resource.Failure -> {
|
||||
showToast(this, R.string.error)
|
||||
showToast(R.string.error)
|
||||
viewModel.clear()
|
||||
hidePreviewPopupDialog()
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.content.DialogInterface
|
|||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||
import com.lagradost.cloudstream3.CommonActivity.activity
|
||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
|
@ -19,7 +20,7 @@ import com.lagradost.cloudstream3.utils.VideoDownloadHelper
|
|||
import com.lagradost.cloudstream3.utils.VideoDownloadManager
|
||||
|
||||
object DownloadButtonSetup {
|
||||
fun handleDownloadClick(activity: Activity?, click: DownloadClickEvent) {
|
||||
fun handleDownloadClick(click: DownloadClickEvent) {
|
||||
val id = click.data.id
|
||||
if (click.data !is VideoDownloadHelper.DownloadEpisodeCached) return
|
||||
when (click.action) {
|
||||
|
@ -89,9 +90,9 @@ object DownloadButtonSetup {
|
|||
)?.fileLength
|
||||
?: 0
|
||||
if (length > 0) {
|
||||
showToast(act, R.string.delete, Toast.LENGTH_LONG)
|
||||
showToast(R.string.delete, Toast.LENGTH_LONG)
|
||||
} else {
|
||||
showToast(act, R.string.download, Toast.LENGTH_LONG)
|
||||
showToast(R.string.download, Toast.LENGTH_LONG)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ class DownloadChildFragment : Fragment() {
|
|||
DownloadChildAdapter(
|
||||
ArrayList(),
|
||||
) { click ->
|
||||
handleDownloadClick(activity, click)
|
||||
handleDownloadClick(click)
|
||||
}
|
||||
|
||||
downloadDeleteEventListener = { id: Int ->
|
||||
|
|
|
@ -162,7 +162,7 @@ class DownloadFragment : Fragment() {
|
|||
},
|
||||
{ downloadClickEvent ->
|
||||
if (downloadClickEvent.data !is VideoDownloadHelper.DownloadEpisodeCached) return@DownloadHeaderAdapter
|
||||
handleDownloadClick(activity, downloadClickEvent)
|
||||
handleDownloadClick(downloadClickEvent)
|
||||
if (downloadClickEvent.action == DOWNLOAD_ACTION_DELETE_FILE) {
|
||||
context?.let { ctx ->
|
||||
downloadsViewModel.updateList(ctx)
|
||||
|
@ -230,7 +230,7 @@ class DownloadFragment : Fragment() {
|
|||
binding.applyBtt.setOnClickListener {
|
||||
val url = binding.streamUrl.text?.toString()
|
||||
if (url.isNullOrEmpty()) {
|
||||
showToast(activity, R.string.error_invalid_url, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.error_invalid_url, Toast.LENGTH_SHORT)
|
||||
} else {
|
||||
val referer = binding.streamReferer.text?.toString()
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ import com.lagradost.cloudstream3.databinding.TvtypesChipsBinding
|
|||
import com.lagradost.cloudstream3.mvvm.Resource
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
import com.lagradost.cloudstream3.mvvm.observe
|
||||
import com.lagradost.cloudstream3.mvvm.observeNullable
|
||||
import com.lagradost.cloudstream3.ui.APIRepository.Companion.noneApi
|
||||
import com.lagradost.cloudstream3.ui.APIRepository.Companion.randomApi
|
||||
import com.lagradost.cloudstream3.ui.WatchType
|
||||
|
@ -194,7 +195,7 @@ class HomeFragment : Fragment() {
|
|||
|
||||
binding.homeExpandedRecycler.adapter =
|
||||
SearchAdapter(item.list.toMutableList(), binding.homeExpandedRecycler) { callback ->
|
||||
handleSearchClickCallback(this, callback)
|
||||
handleSearchClickCallback(callback)
|
||||
if (callback.action == SEARCH_ACTION_LOAD || callback.action == SEARCH_ACTION_PLAY_FILE) {
|
||||
bottomSheetDialogBuilder.ownHide() // we hide here because we want to resume it later
|
||||
//bottomSheetDialogBuilder.dismissSafe(this)
|
||||
|
@ -440,8 +441,8 @@ class HomeFragment : Fragment() {
|
|||
val root = inflater.inflate(layout, container, false)
|
||||
binding = try {
|
||||
FragmentHomeBinding.bind(root)
|
||||
} catch (t : Throwable) {
|
||||
showToast(activity, txt(R.string.unable_to_inflate, t.message ?: ""), Toast.LENGTH_LONG)
|
||||
} catch (t: Throwable) {
|
||||
showToast(txt(R.string.unable_to_inflate, t.message ?: ""), Toast.LENGTH_LONG)
|
||||
logError(t)
|
||||
null
|
||||
}
|
||||
|
@ -481,59 +482,6 @@ class HomeFragment : Fragment() {
|
|||
fixGrid()
|
||||
}
|
||||
|
||||
fun bookmarksUpdated(_data: Boolean) {
|
||||
reloadStored()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
reloadStored()
|
||||
bookmarksUpdatedEvent += ::bookmarksUpdated
|
||||
afterPluginsLoadedEvent += ::afterPluginsLoaded
|
||||
mainPluginsLoadedEvent += ::afterMainPluginsLoaded
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
bookmarksUpdatedEvent -= ::bookmarksUpdated
|
||||
afterPluginsLoadedEvent -= ::afterPluginsLoaded
|
||||
mainPluginsLoadedEvent -= ::afterMainPluginsLoaded
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
private fun reloadStored() {
|
||||
homeViewModel.loadResumeWatching()
|
||||
val list = EnumSet.noneOf(WatchType::class.java)
|
||||
getKey<IntArray>(HOME_BOOKMARK_VALUE_LIST)?.map { WatchType.fromInternalId(it) }?.let {
|
||||
list.addAll(it)
|
||||
}
|
||||
homeViewModel.loadStoredData(list)
|
||||
}
|
||||
|
||||
private fun afterMainPluginsLoaded(unused: Boolean = false) {
|
||||
loadHomePage(false)
|
||||
}
|
||||
|
||||
private fun afterPluginsLoaded(forceReload: Boolean) {
|
||||
loadHomePage(forceReload)
|
||||
}
|
||||
|
||||
private fun loadHomePage(forceReload: Boolean) {
|
||||
val apiName = context?.getKey<String>(USER_SELECTED_HOMEPAGE_API)
|
||||
|
||||
if (homeViewModel.apiName.value != apiName || apiName == null || forceReload) {
|
||||
//println("Caught home: " + homeViewModel.apiName.value + " at " + apiName)
|
||||
homeViewModel.loadAndCancel(apiName, forceReload)
|
||||
}
|
||||
}
|
||||
|
||||
private fun homeHandleSearch(callback: SearchClickCallback) {
|
||||
if (callback.action == SEARCH_ACTION_FOCUSED) {
|
||||
//focusCallback(callback.card)
|
||||
} else {
|
||||
handleSearchClickCallback(activity, callback)
|
||||
}
|
||||
}
|
||||
|
||||
private var currentApiName: String? = null
|
||||
private var toggleRandomButton = false
|
||||
|
||||
|
@ -546,8 +494,6 @@ class HomeFragment : Fragment() {
|
|||
fixGrid()
|
||||
|
||||
binding?.homeChangeApiLoading?.setOnClickListener(apiChangeClickListener)
|
||||
|
||||
|
||||
binding?.homeChangeApiLoading?.setOnClickListener(apiChangeClickListener)
|
||||
binding?.homeApiFab?.setOnClickListener(apiChangeClickListener)
|
||||
binding?.homeRandom?.setOnClickListener {
|
||||
|
@ -567,18 +513,9 @@ class HomeFragment : Fragment() {
|
|||
binding?.homeRandom?.visibility = View.GONE
|
||||
}
|
||||
|
||||
observe(homeViewModel.preview) { preview ->
|
||||
(binding?.homeMasterRecycler?.adapter as? HomeParentItemAdapterPreview?)?.setPreviewData(
|
||||
preview
|
||||
)
|
||||
}
|
||||
|
||||
observe(homeViewModel.apiName) { apiName ->
|
||||
currentApiName = apiName
|
||||
binding?.homeApiFab?.text = apiName
|
||||
(binding?.homeMasterRecycler?.adapter as? HomeParentItemAdapterPreview?)?.setApiName(
|
||||
apiName
|
||||
)
|
||||
}
|
||||
|
||||
observe(homeViewModel.page) { data ->
|
||||
|
@ -659,73 +596,38 @@ class HomeFragment : Fragment() {
|
|||
}
|
||||
|
||||
|
||||
|
||||
observe(homeViewModel.availableWatchStatusTypes) { availableWatchStatusTypes ->
|
||||
context?.setKey(
|
||||
HOME_BOOKMARK_VALUE_LIST,
|
||||
availableWatchStatusTypes.first.map { it.internalId }.toIntArray()
|
||||
)
|
||||
(binding?.homeMasterRecycler?.adapter as? HomeParentItemAdapterPreview?)?.setAvailableWatchStatusTypes(
|
||||
availableWatchStatusTypes
|
||||
)
|
||||
}
|
||||
|
||||
observe(homeViewModel.bookmarks) { data ->
|
||||
(binding?.homeMasterRecycler?.adapter as? HomeParentItemAdapterPreview?)?.setBookmarkData(
|
||||
data
|
||||
)
|
||||
}
|
||||
|
||||
observe(homeViewModel.resumeWatching) { resumeWatching ->
|
||||
(binding?.homeMasterRecycler?.adapter as? HomeParentItemAdapterPreview?)?.setResumeWatchingData(
|
||||
resumeWatching
|
||||
)
|
||||
if (isTrueTvSettings()) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
ioSafe {
|
||||
activity?.addProgramsToContinueWatching(resumeWatching.mapNotNull { it as? DataStoreHelper.ResumeWatchingResult })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//context?.fixPaddingStatusbarView(home_statusbar)
|
||||
//context?.fixPaddingStatusbar(home_padding)
|
||||
fixPaddingStatusbar(binding?.homeLoadingStatusbar)
|
||||
|
||||
binding?.homeMasterRecycler?.adapter =
|
||||
HomeParentItemAdapterPreview(mutableListOf(), { callback ->
|
||||
homeHandleSearch(callback)
|
||||
}, { item ->
|
||||
bottomSheetDialog = activity?.loadHomepageList(item, expandCallback = {
|
||||
homeViewModel.expandAndReturn(it)
|
||||
}, dismissCallback = {
|
||||
bottomSheetDialog = null
|
||||
})
|
||||
}, { name ->
|
||||
homeViewModel.expand(name)
|
||||
}, { load ->
|
||||
activity?.loadResult(load.response.url, load.response.apiName, load.action)
|
||||
}, {
|
||||
homeViewModel.loadMoreHomeScrollResponses()
|
||||
}, {
|
||||
apiChangeClickListener.onClick(it)
|
||||
}, reloadStored = {
|
||||
reloadStored()
|
||||
}, loadStoredData = {
|
||||
homeViewModel.loadStoredData(it)
|
||||
}, { (isQuickSearch, text) ->
|
||||
if (!isQuickSearch) {
|
||||
QuickSearchFragment.pushSearch(
|
||||
activity,
|
||||
text,
|
||||
currentApiName?.let { arrayOf(it) })
|
||||
}
|
||||
})
|
||||
observeNullable(homeViewModel.popup) { item ->
|
||||
if (item == null) {
|
||||
bottomSheetDialog?.dismissSafe()
|
||||
bottomSheetDialog = null
|
||||
return@observeNullable
|
||||
}
|
||||
|
||||
reloadStored()
|
||||
loadHomePage(false)
|
||||
// don't recreate
|
||||
if (bottomSheetDialog != null) {
|
||||
return@observeNullable
|
||||
}
|
||||
|
||||
bottomSheetDialog = activity?.loadHomepageList(item, expandCallback = {
|
||||
homeViewModel.expandAndReturn(it)
|
||||
}, dismissCallback = {
|
||||
homeViewModel.popup(null)
|
||||
bottomSheetDialog = null
|
||||
})
|
||||
}
|
||||
|
||||
binding?.homeMasterRecycler?.adapter =
|
||||
HomeParentItemAdapterPreview(
|
||||
mutableListOf(),
|
||||
homeViewModel
|
||||
)
|
||||
|
||||
homeViewModel.reloadStored()
|
||||
//loadHomePage(false)
|
||||
binding?.homeMasterRecycler?.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ class LoadClickCallback(
|
|||
|
||||
open class ParentItemAdapter(
|
||||
private var items: MutableList<HomeViewModel.ExpandableHomepageList>,
|
||||
//private val viewModel: HomeViewModel,
|
||||
private val clickCallback: (SearchClickCallback) -> Unit,
|
||||
private val moreInfoClickCallback: (HomeViewModel.ExpandableHomepageList) -> Unit,
|
||||
private val expandCallback: ((String) -> Unit)? = null,
|
||||
|
@ -153,6 +154,7 @@ open class ParentItemAdapter(
|
|||
class ParentViewHolder
|
||||
constructor(
|
||||
val binding: HomepageParentBinding,
|
||||
// val viewModel: HomeViewModel,
|
||||
private val clickCallback: (SearchClickCallback) -> Unit,
|
||||
private val moreInfoClickCallback: (HomeViewModel.ExpandableHomepageList) -> Unit,
|
||||
private val expandCallback: ((String) -> Unit)? = null,
|
||||
|
|
|
@ -8,7 +8,9 @@ import androidx.appcompat.widget.SearchView
|
|||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.findViewTreeLifecycleOwner
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.chip.ChipDrawable
|
||||
|
@ -18,8 +20,13 @@ import com.lagradost.cloudstream3.HomePageList
|
|||
import com.lagradost.cloudstream3.LoadResponse
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.SearchResponse
|
||||
import com.lagradost.cloudstream3.databinding.FragmentHomeHeadBinding
|
||||
import com.lagradost.cloudstream3.databinding.FragmentHomeHeadTvBinding
|
||||
import com.lagradost.cloudstream3.mvvm.Resource
|
||||
import com.lagradost.cloudstream3.mvvm.debugException
|
||||
import com.lagradost.cloudstream3.mvvm.observe
|
||||
import com.lagradost.cloudstream3.ui.WatchType
|
||||
import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.selectHomepage
|
||||
import com.lagradost.cloudstream3.ui.result.ResultViewModel2
|
||||
import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST
|
||||
import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_LOAD
|
||||
|
@ -61,102 +68,51 @@ import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_type_on_ho
|
|||
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_type_watching_btt
|
||||
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_watch_child_recyclerview
|
||||
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_watch_holder
|
||||
import kotlinx.android.synthetic.main.toast.view.*
|
||||
|
||||
class HomeParentItemAdapterPreview(
|
||||
items: MutableList<HomeViewModel.ExpandableHomepageList>,
|
||||
val clickCallback: (SearchClickCallback) -> Unit,
|
||||
private val moreInfoClickCallback: (HomeViewModel.ExpandableHomepageList) -> Unit,
|
||||
expandCallback: ((String) -> Unit)? = null,
|
||||
private val loadCallback: (LoadClickCallback) -> Unit,
|
||||
private val loadMoreCallback: (() -> Unit),
|
||||
private val changeHomePageCallback: ((View) -> Unit),
|
||||
private val reloadStored: (() -> Unit),
|
||||
private val loadStoredData: ((Set<WatchType>) -> Unit),
|
||||
private val searchQueryCallback: ((Pair<Boolean, String>) -> Unit)
|
||||
) : ParentItemAdapter(items, clickCallback, moreInfoClickCallback, expandCallback) {
|
||||
private var previewData: Resource<Pair<Boolean, List<LoadResponse>>> = Resource.Loading()
|
||||
private var resumeWatchingData: List<SearchResponse> = listOf()
|
||||
private var bookmarkData: Pair<Boolean, List<SearchResponse>> =
|
||||
false to listOf()
|
||||
private var apiName: String = "NONE"
|
||||
|
||||
private val viewModel: HomeViewModel,
|
||||
) : ParentItemAdapter(items, clickCallback = {
|
||||
viewModel.click(it)
|
||||
}, moreInfoClickCallback = {
|
||||
viewModel.popup(it)
|
||||
}, expandCallback = {
|
||||
viewModel.expand(it)
|
||||
}) {
|
||||
val headItems = 1
|
||||
|
||||
private var availableWatchStatusTypes: Pair<Set<WatchType>, Set<WatchType>> =
|
||||
setOf<WatchType>() to setOf()
|
||||
|
||||
fun setAvailableWatchStatusTypes(data: Pair<Set<WatchType>, Set<WatchType>>) {
|
||||
availableWatchStatusTypes = data
|
||||
holder?.setAvailableWatchStatusTypes(data)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val VIEW_TYPE_HEADER = 2
|
||||
private const val VIEW_TYPE_ITEM = 1
|
||||
}
|
||||
|
||||
fun setResumeWatchingData(resumeWatching: List<SearchResponse>) {
|
||||
resumeWatchingData = resumeWatching
|
||||
holder?.updateResume(resumeWatchingData)
|
||||
}
|
||||
|
||||
fun setPreviewData(preview: Resource<Pair<Boolean, List<LoadResponse>>>) {
|
||||
previewData = preview
|
||||
holder?.updatePreview(preview)
|
||||
}
|
||||
|
||||
fun setApiName(name: String) {
|
||||
apiName = name
|
||||
holder?.updateApiName(name)
|
||||
}
|
||||
|
||||
fun setBookmarkData(data: Pair<Boolean, List<SearchResponse>>) {
|
||||
bookmarkData = data
|
||||
holder?.updateBookmarks(data)
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int) = when (position) {
|
||||
0 -> VIEW_TYPE_HEADER
|
||||
else -> VIEW_TYPE_ITEM
|
||||
}
|
||||
|
||||
var holder: HeaderViewHolder? = null
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
when (holder) {
|
||||
is HeaderViewHolder -> {
|
||||
holder.updatePreview(previewData)
|
||||
holder.updateResume(resumeWatchingData)
|
||||
holder.updateBookmarks(bookmarkData)
|
||||
holder.setAvailableWatchStatusTypes(availableWatchStatusTypes)
|
||||
holder.updateApiName(apiName)
|
||||
}
|
||||
else -> super.onBindViewHolder(holder, position - 1)
|
||||
is HeaderViewHolder -> {}
|
||||
else -> super.onBindViewHolder(holder, position - headItems)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
println("onCreateViewHolder $viewType")
|
||||
return when (viewType) {
|
||||
VIEW_TYPE_HEADER -> HeaderViewHolder(
|
||||
LayoutInflater.from(parent.context).inflate(
|
||||
if (isTvSettings()) R.layout.fragment_home_head_tv else R.layout.fragment_home_head,
|
||||
VIEW_TYPE_HEADER -> {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
val binding = if (isTvSettings()) FragmentHomeHeadTvBinding.inflate(
|
||||
inflater,
|
||||
parent,
|
||||
false
|
||||
),
|
||||
loadCallback,
|
||||
loadMoreCallback,
|
||||
changeHomePageCallback,
|
||||
clickCallback,
|
||||
reloadStored,
|
||||
loadStoredData,
|
||||
searchQueryCallback,
|
||||
moreInfoClickCallback
|
||||
).also {
|
||||
this.holder = it
|
||||
) else FragmentHomeHeadBinding.inflate(inflater, parent, false)
|
||||
HeaderViewHolder(
|
||||
binding,
|
||||
viewModel,
|
||||
)
|
||||
}
|
||||
|
||||
VIEW_TYPE_ITEM -> super.onCreateViewHolder(parent, viewType)
|
||||
else -> error("Unhandled viewType=$viewType")
|
||||
}
|
||||
|
@ -167,7 +123,7 @@ class HomeParentItemAdapterPreview(
|
|||
}
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
if (position == 0) return previewData.hashCode().toLong()
|
||||
if (position == 0) return 0//previewData.hashCode().toLong()
|
||||
return super.getItemId(position - headItems)
|
||||
}
|
||||
|
||||
|
@ -176,6 +132,7 @@ class HomeParentItemAdapterPreview(
|
|||
is HeaderViewHolder -> {
|
||||
holder.onViewDetachedFromWindow()
|
||||
}
|
||||
|
||||
else -> super.onViewDetachedFromWindow(holder)
|
||||
}
|
||||
}
|
||||
|
@ -185,6 +142,7 @@ class HomeParentItemAdapterPreview(
|
|||
is HeaderViewHolder -> {
|
||||
holder.onViewAttachedToWindow()
|
||||
}
|
||||
|
||||
else -> super.onViewAttachedToWindow(holder)
|
||||
}
|
||||
}
|
||||
|
@ -192,16 +150,9 @@ class HomeParentItemAdapterPreview(
|
|||
|
||||
class HeaderViewHolder
|
||||
constructor(
|
||||
itemView: View,
|
||||
private val clickCallback: ((LoadClickCallback) -> Unit)?,
|
||||
private val loadMoreCallback: (() -> Unit),
|
||||
private val changeHomePageCallback: ((View) -> Unit),
|
||||
private val searchClickCallback: (SearchClickCallback) -> Unit,
|
||||
private val reloadStored: () -> Unit,
|
||||
private val loadStoredData: ((Set<WatchType>) -> Unit),
|
||||
private val searchQueryCallback: ((Pair<Boolean, String>) -> Unit),
|
||||
private val moreInfoClickCallback: (HomeViewModel.ExpandableHomepageList) -> Unit
|
||||
) : RecyclerView.ViewHolder(itemView) {
|
||||
val binding: ViewBinding,
|
||||
val viewModel: HomeViewModel,
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
private var previewAdapter: HomeScrollAdapter? = null
|
||||
private val previewViewpager: ViewPager2? = itemView.home_preview_viewpager
|
||||
private val previewHeader: FrameLayout? = itemView.home_preview
|
||||
|
@ -214,8 +165,8 @@ class HomeParentItemAdapterPreview(
|
|||
|
||||
previewAdapter?.apply {
|
||||
if (position >= itemCount - 1 && hasMoreItems) {
|
||||
hasMoreItems = false // dont make two requests
|
||||
loadMoreCallback()
|
||||
hasMoreItems = false // don't make two requests
|
||||
viewModel.loadMoreHomeScrollResponses()
|
||||
//homeViewModel.loadMoreHomeScrollResponses()
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +212,7 @@ class HomeParentItemAdapterPreview(
|
|||
// itemView.home_preview_title?.text = name
|
||||
|
||||
itemView.home_preview_play?.setOnClickListener { view ->
|
||||
clickCallback?.invoke(
|
||||
viewModel.click(
|
||||
LoadClickCallback(
|
||||
START_ACTION_RESUME_LATEST,
|
||||
view,
|
||||
|
@ -271,13 +222,13 @@ class HomeParentItemAdapterPreview(
|
|||
)
|
||||
}
|
||||
itemView.home_preview_info?.setOnClickListener { view ->
|
||||
clickCallback?.invoke(
|
||||
viewModel.click(
|
||||
LoadClickCallback(0, view, position, this)
|
||||
)
|
||||
}
|
||||
|
||||
itemView.home_preview_play_btt?.setOnClickListener { view ->
|
||||
clickCallback?.invoke(
|
||||
viewModel.click(
|
||||
LoadClickCallback(
|
||||
START_ACTION_RESUME_LATEST,
|
||||
view,
|
||||
|
@ -298,7 +249,7 @@ class HomeParentItemAdapterPreview(
|
|||
|
||||
|
||||
itemView.home_preview_info_btt?.setOnClickListener { view ->
|
||||
clickCallback?.invoke(
|
||||
viewModel.click(
|
||||
LoadClickCallback(0, view, position, this)
|
||||
)
|
||||
}
|
||||
|
@ -362,7 +313,7 @@ class HomeParentItemAdapterPreview(
|
|||
this,
|
||||
newValue
|
||||
)
|
||||
reloadStored()
|
||||
viewModel.reloadStored()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -384,6 +335,24 @@ class HomeParentItemAdapterPreview(
|
|||
|
||||
fun onViewAttachedToWindow() {
|
||||
previewViewpager?.registerOnPageChangeCallback(previewCallback)
|
||||
|
||||
binding.root.findViewTreeLifecycleOwner()?.apply {
|
||||
observe(viewModel.preview) {
|
||||
updatePreview(it)
|
||||
}
|
||||
observe(viewModel.apiName) {
|
||||
updateApiName(it)
|
||||
}
|
||||
observe(viewModel.resumeWatching) {
|
||||
updateResume(it)
|
||||
}
|
||||
observe(viewModel.bookmarks) {
|
||||
updateBookmarks(it)
|
||||
}
|
||||
observe(viewModel.availableWatchStatusTypes) {
|
||||
setAvailableWatchStatusTypes(it)
|
||||
}
|
||||
} ?: debugException { "Expected findViewTreeLifecycleOwner" }
|
||||
}
|
||||
|
||||
private val toggleList = listOf(
|
||||
|
@ -395,11 +364,17 @@ class HomeParentItemAdapterPreview(
|
|||
)
|
||||
|
||||
init {
|
||||
itemView.home_preview_change_api?.setOnClickListener { view ->
|
||||
changeHomePageCallback(view)
|
||||
}
|
||||
itemView.home_preview_change_api2?.setOnClickListener { view ->
|
||||
changeHomePageCallback(view)
|
||||
if (binding is FragmentHomeHeadTvBinding) {
|
||||
binding.homePreviewChangeApi.setOnClickListener { view ->
|
||||
view.context.selectHomepage(viewModel.repo?.name) { api ->
|
||||
viewModel.loadAndCancel(api)
|
||||
}
|
||||
}
|
||||
binding.homePreviewChangeApi2.setOnClickListener { view ->
|
||||
view.context.selectHomepage(viewModel.repo?.name) { api ->
|
||||
viewModel.loadAndCancel(api)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
previewViewpager?.apply {
|
||||
|
@ -421,7 +396,7 @@ class HomeParentItemAdapterPreview(
|
|||
nextFocusDown = itemView.nextFocusDownId
|
||||
) { callback ->
|
||||
if (callback.action != SEARCH_ACTION_SHOW_METADATA) {
|
||||
searchClickCallback(callback)
|
||||
viewModel.click(callback)
|
||||
return@HomeChildItemAdapter
|
||||
}
|
||||
callback.view.context?.getActivity()?.showOptionSelectStringRes(
|
||||
|
@ -440,7 +415,7 @@ class HomeParentItemAdapterPreview(
|
|||
when (actionId + if (isTv) 0 else 1) {
|
||||
// play
|
||||
0 -> {
|
||||
searchClickCallback.invoke(
|
||||
viewModel.click(
|
||||
SearchClickCallback(
|
||||
START_ACTION_RESUME_LATEST,
|
||||
callback.view,
|
||||
|
@ -448,11 +423,11 @@ class HomeParentItemAdapterPreview(
|
|||
callback.card
|
||||
)
|
||||
)
|
||||
reloadStored()
|
||||
viewModel.reloadStored()
|
||||
}
|
||||
//info
|
||||
1 -> {
|
||||
searchClickCallback(
|
||||
viewModel.click(
|
||||
SearchClickCallback(
|
||||
SEARCH_ACTION_LOAD,
|
||||
callback.view,
|
||||
|
@ -461,14 +436,14 @@ class HomeParentItemAdapterPreview(
|
|||
)
|
||||
)
|
||||
|
||||
reloadStored()
|
||||
viewModel.reloadStored()
|
||||
}
|
||||
// remove
|
||||
2 -> {
|
||||
val card = callback.card
|
||||
if (card is DataStoreHelper.ResumeWatchingResult) {
|
||||
DataStoreHelper.removeLastWatched(card.parentId)
|
||||
reloadStored()
|
||||
viewModel.reloadStored()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -483,7 +458,7 @@ class HomeParentItemAdapterPreview(
|
|||
nextFocusDown = itemView.nextFocusDownId
|
||||
) { callback ->
|
||||
if (callback.action != SEARCH_ACTION_SHOW_METADATA) {
|
||||
searchClickCallback(callback)
|
||||
viewModel.click(callback)
|
||||
return@HomeChildItemAdapter
|
||||
}
|
||||
callback.view.context?.getActivity()?.showOptionSelectStringRes(
|
||||
|
@ -501,7 +476,7 @@ class HomeParentItemAdapterPreview(
|
|||
) { (isTv, actionId) ->
|
||||
when (actionId + if (isTv) 0 else 1) { // play
|
||||
0 -> {
|
||||
searchClickCallback.invoke(
|
||||
viewModel.click(
|
||||
SearchClickCallback(
|
||||
START_ACTION_RESUME_LATEST,
|
||||
callback.view,
|
||||
|
@ -509,10 +484,11 @@ class HomeParentItemAdapterPreview(
|
|||
callback.card
|
||||
)
|
||||
)
|
||||
reloadStored()
|
||||
viewModel.reloadStored()
|
||||
}
|
||||
|
||||
1 -> { // info
|
||||
searchClickCallback(
|
||||
viewModel.click(
|
||||
SearchClickCallback(
|
||||
SEARCH_ACTION_LOAD,
|
||||
callback.view,
|
||||
|
@ -521,14 +497,15 @@ class HomeParentItemAdapterPreview(
|
|||
)
|
||||
)
|
||||
|
||||
reloadStored()
|
||||
viewModel.reloadStored()
|
||||
}
|
||||
|
||||
2 -> { // remove
|
||||
DataStoreHelper.setResultWatchState(
|
||||
callback.card.id,
|
||||
WatchType.NONE.internalId
|
||||
)
|
||||
reloadStored()
|
||||
viewModel.reloadStored()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -540,7 +517,7 @@ class HomeParentItemAdapterPreview(
|
|||
chip?.isChecked = false
|
||||
chip?.setOnCheckedChangeListener { _, isChecked ->
|
||||
if (isChecked) {
|
||||
loadStoredData(
|
||||
viewModel.loadStoredData(
|
||||
setOf(watch)
|
||||
// If we filter all buttons then two can be checked at the same time
|
||||
// Revert this if you want to go back to multi selection
|
||||
|
@ -549,7 +526,7 @@ class HomeParentItemAdapterPreview(
|
|||
}
|
||||
// Else if all are unchecked -> Do not load data
|
||||
else if (toggleList.all { it.first?.isChecked != true }) {
|
||||
loadStoredData(emptySet())
|
||||
viewModel.loadStoredData(emptySet())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -558,25 +535,26 @@ class HomeParentItemAdapterPreview(
|
|||
|
||||
itemView.home_search?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String): Boolean {
|
||||
searchQueryCallback.invoke(false to query)
|
||||
viewModel.queryTextSubmit(query)
|
||||
|
||||
//QuickSearchFragment.pushSearch(activity, query, currentApiName?.let { arrayOf(it) }
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String): Boolean {
|
||||
searchQueryCallback.invoke(true to newText)
|
||||
viewModel.queryTextChange(newText)
|
||||
//searchViewModel.quickSearch(newText)
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun updateApiName(name: String) {
|
||||
private fun updateApiName(name: String) {
|
||||
itemView.home_preview_change_api2?.text = name
|
||||
itemView.home_preview_change_api?.text = name
|
||||
}
|
||||
|
||||
fun updatePreview(preview: Resource<Pair<Boolean, List<LoadResponse>>>) {
|
||||
private fun updatePreview(preview: Resource<Pair<Boolean, List<LoadResponse>>>) {
|
||||
itemView.home_preview_change_api2?.isGone = preview is Resource.Success
|
||||
if (preview is Resource.Success) {
|
||||
itemView.home_none_padding?.apply {
|
||||
|
@ -604,6 +582,7 @@ class HomeParentItemAdapterPreview(
|
|||
previewHeader?.isVisible = true
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
previewAdapter?.setItems(listOf(), false)
|
||||
previewViewpager?.setCurrentItem(0, false)
|
||||
|
@ -614,13 +593,13 @@ class HomeParentItemAdapterPreview(
|
|||
//previewViewpager?.postInvalidate()
|
||||
}
|
||||
|
||||
fun updateResume(resumeWatching: List<SearchResponse>) {
|
||||
private fun updateResume(resumeWatching: List<SearchResponse>) {
|
||||
resumeHolder?.isVisible = resumeWatching.isNotEmpty()
|
||||
resumeAdapter?.updateList(resumeWatching)
|
||||
|
||||
if (!isTvSettings()) {
|
||||
itemView.home_watch_parent_item_title?.setOnClickListener {
|
||||
moreInfoClickCallback.invoke(
|
||||
viewModel.popup(
|
||||
HomeViewModel.ExpandableHomepageList(
|
||||
HomePageList(
|
||||
itemView.home_watch_parent_item_title?.text.toString(),
|
||||
|
@ -633,9 +612,10 @@ class HomeParentItemAdapterPreview(
|
|||
}
|
||||
}
|
||||
|
||||
fun updateBookmarks(data: Pair<Boolean, List<SearchResponse>>) {
|
||||
bookmarkHolder?.isVisible = data.first
|
||||
bookmarkAdapter?.updateList(data.second)
|
||||
private fun updateBookmarks(data: Pair<Boolean, List<SearchResponse>>) {
|
||||
val (visible, list) = data
|
||||
bookmarkHolder?.isVisible = visible
|
||||
bookmarkAdapter?.updateList(list)
|
||||
if (!isTvSettings()) {
|
||||
itemView.home_bookmark_parent_item_title?.setOnClickListener {
|
||||
val items = toggleList.mapNotNull { it.first }.filter { it.isChecked }
|
||||
|
@ -643,11 +623,11 @@ class HomeParentItemAdapterPreview(
|
|||
val textSum = items
|
||||
.mapNotNull { it.text }.joinToString()
|
||||
|
||||
moreInfoClickCallback.invoke(
|
||||
viewModel.popup(
|
||||
HomeViewModel.ExpandableHomepageList(
|
||||
HomePageList(
|
||||
textSum,
|
||||
data.second,
|
||||
list,
|
||||
false
|
||||
), 1, false
|
||||
)
|
||||
|
@ -656,11 +636,12 @@ class HomeParentItemAdapterPreview(
|
|||
}
|
||||
}
|
||||
|
||||
fun setAvailableWatchStatusTypes(availableWatchStatusTypes: Pair<Set<WatchType>, Set<WatchType>>) {
|
||||
private fun setAvailableWatchStatusTypes(availableWatchStatusTypes: Pair<Set<WatchType>, Set<WatchType>>) {
|
||||
val (visible, checked) = availableWatchStatusTypes
|
||||
for ((chip, watch) in toggleList) {
|
||||
chip?.apply {
|
||||
isVisible = availableWatchStatusTypes.second.contains(watch)
|
||||
isChecked = availableWatchStatusTypes.first.contains(watch)
|
||||
isVisible = visible.contains(watch)
|
||||
isChecked = checked.contains(watch)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.lagradost.cloudstream3.ui.home
|
||||
|
||||
import android.os.Build
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
@ -13,13 +14,24 @@ import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
|
|||
import com.lagradost.cloudstream3.AcraApplication.Companion.context
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||
import com.lagradost.cloudstream3.CommonActivity.activity
|
||||
import com.lagradost.cloudstream3.mvvm.*
|
||||
import com.lagradost.cloudstream3.ui.APIRepository
|
||||
import com.lagradost.cloudstream3.ui.APIRepository.Companion.noneApi
|
||||
import com.lagradost.cloudstream3.ui.APIRepository.Companion.randomApi
|
||||
import com.lagradost.cloudstream3.ui.WatchType
|
||||
import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.loadHomepageList
|
||||
import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment
|
||||
import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_FOCUSED
|
||||
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
|
||||
import com.lagradost.cloudstream3.ui.search.SearchHelper
|
||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.addProgramsToContinueWatching
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.loadResult
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||
import com.lagradost.cloudstream3.utils.DOWNLOAD_HEADER_CACHE
|
||||
import com.lagradost.cloudstream3.utils.DataStore.getKey
|
||||
import com.lagradost.cloudstream3.utils.DataStore.setKey
|
||||
import com.lagradost.cloudstream3.utils.DataStoreHelper
|
||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllResumeStateIds
|
||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllWatchStateIds
|
||||
|
@ -72,7 +84,7 @@ class HomeViewModel : ViewModel() {
|
|||
}
|
||||
}
|
||||
|
||||
private var repo: APIRepository? = null
|
||||
var repo: APIRepository? = null
|
||||
|
||||
private val _apiName = MutableLiveData<String>()
|
||||
val apiName: LiveData<String> = _apiName
|
||||
|
@ -101,8 +113,14 @@ class HomeViewModel : ViewModel() {
|
|||
val resumeWatching: LiveData<List<SearchResponse>> = _resumeWatching
|
||||
val preview: LiveData<Resource<Pair<Boolean, List<LoadResponse>>>> = _preview
|
||||
|
||||
fun loadResumeWatching() = viewModelScope.launchSafe {
|
||||
private fun loadResumeWatching() = viewModelScope.launchSafe {
|
||||
val resumeWatchingResult = getResumeWatching()
|
||||
if (isTrueTvSettings() && resumeWatchingResult != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
ioSafe {
|
||||
// this WILL crash on non tvs, so keep this inside a try catch
|
||||
activity?.addProgramsToContinueWatching(resumeWatchingResult)
|
||||
}
|
||||
}
|
||||
resumeWatchingResult?.let {
|
||||
_resumeWatching.postValue(it)
|
||||
}
|
||||
|
@ -128,6 +146,10 @@ class HomeViewModel : ViewModel() {
|
|||
currentWatchTypes.remove(WatchType.NONE)
|
||||
|
||||
if (currentWatchTypes.size <= 0) {
|
||||
setKey(
|
||||
HOME_BOOKMARK_VALUE_LIST,
|
||||
intArrayOf()
|
||||
)
|
||||
_availableWatchStatusTypes.postValue(setOf<WatchType>() to setOf())
|
||||
_bookmarks.postValue(Pair(false, ArrayList()))
|
||||
return@launchSafe
|
||||
|
@ -135,7 +157,10 @@ class HomeViewModel : ViewModel() {
|
|||
|
||||
val watchPrefNotNull = preferredWatchStatus ?: EnumSet.of(currentWatchTypes.first())
|
||||
//if (currentWatchTypes.any { watchPrefNotNull.contains(it) }) watchPrefNotNull else listOf(currentWatchTypes.first())
|
||||
|
||||
setKey(
|
||||
HOME_BOOKMARK_VALUE_LIST,
|
||||
watchPrefNotNull.map { it.internalId }.toIntArray()
|
||||
)
|
||||
_availableWatchStatusTypes.postValue(
|
||||
Pair(
|
||||
watchPrefNotNull,
|
||||
|
@ -337,14 +362,80 @@ class HomeViewModel : ViewModel() {
|
|||
logError(e)
|
||||
}
|
||||
}
|
||||
|
||||
is Resource.Failure -> {
|
||||
_page.postValue(data!!)
|
||||
_preview.postValue(data!!)
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
fun click(callback: SearchClickCallback) {
|
||||
if (callback.action == SEARCH_ACTION_FOCUSED) {
|
||||
//focusCallback(callback.card)
|
||||
} else {
|
||||
SearchHelper.handleSearchClickCallback(callback)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private val _popup = MutableLiveData<ExpandableHomepageList?>(null)
|
||||
val popup: LiveData<ExpandableHomepageList?> = _popup
|
||||
|
||||
fun popup(list: ExpandableHomepageList?) {
|
||||
_popup.postValue(list)
|
||||
}
|
||||
|
||||
private fun bookmarksUpdated(unused: Boolean) {
|
||||
reloadStored()
|
||||
}
|
||||
|
||||
private fun afterPluginsLoaded(forceReload: Boolean) {
|
||||
loadAndCancel(getKey(USER_SELECTED_HOMEPAGE_API), forceReload)
|
||||
}
|
||||
|
||||
private fun afterMainPluginsLoaded(unused: Boolean = false) {
|
||||
loadAndCancel(getKey(USER_SELECTED_HOMEPAGE_API), false)
|
||||
}
|
||||
|
||||
init {
|
||||
MainActivity.bookmarksUpdatedEvent += ::bookmarksUpdated
|
||||
MainActivity.afterPluginsLoadedEvent += ::afterPluginsLoaded
|
||||
MainActivity.mainPluginsLoadedEvent += ::afterMainPluginsLoaded
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
MainActivity.bookmarksUpdatedEvent -= ::bookmarksUpdated
|
||||
MainActivity.afterPluginsLoadedEvent -= ::afterPluginsLoaded
|
||||
MainActivity.mainPluginsLoadedEvent -= ::afterMainPluginsLoaded
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
fun queryTextSubmit(query: String) {
|
||||
QuickSearchFragment.pushSearch(
|
||||
query,
|
||||
repo?.name?.let { arrayOf(it) })
|
||||
}
|
||||
|
||||
fun queryTextChange(newText: String) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
fun reloadStored() {
|
||||
loadResumeWatching()
|
||||
val list = EnumSet.noneOf(WatchType::class.java)
|
||||
getKey<IntArray>(HOME_BOOKMARK_VALUE_LIST)?.map { WatchType.fromInternalId(it) }?.let {
|
||||
list.addAll(it)
|
||||
}
|
||||
loadStoredData(list)
|
||||
}
|
||||
|
||||
fun click(load: LoadClickCallback) {
|
||||
loadResult(load.response.url, load.response.apiName, load.action)
|
||||
}
|
||||
|
||||
fun loadAndCancel(preferredApiName: String?, forceReload: Boolean = true) =
|
||||
viewModelScope.launchSafe {
|
||||
// Since plugins are loaded in stages this function can get called multiple times.
|
||||
|
|
|
@ -243,14 +243,12 @@ abstract class AbstractPlayerFragment(
|
|||
fun showToast(message: String, gotoNext: Boolean = false) {
|
||||
if (gotoNext && hasNextMirror()) {
|
||||
showToast(
|
||||
activity,
|
||||
message,
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
nextMirror()
|
||||
} else {
|
||||
showToast(
|
||||
activity,
|
||||
context?.getString(R.string.no_links_found_toast) + "\n" + message,
|
||||
Toast.LENGTH_LONG
|
||||
)
|
||||
|
@ -461,7 +459,7 @@ abstract class AbstractPlayerFragment(
|
|||
player_view?.resizeMode = type
|
||||
|
||||
if (showToast)
|
||||
showToast(activity, resize.nameRes, Toast.LENGTH_SHORT)
|
||||
showToast(resize.nameRes, Toast.LENGTH_SHORT)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
|
|
|
@ -509,7 +509,6 @@ class GeneratorPlayer : FullScreenPlayer() {
|
|||
selectSourceDialog?.dismissSafe()
|
||||
|
||||
showToast(
|
||||
activity,
|
||||
String.format(ctx.getString(R.string.player_loaded_subtitles), subtitleData.name),
|
||||
Toast.LENGTH_LONG
|
||||
)
|
||||
|
@ -889,7 +888,7 @@ class GeneratorPlayer : FullScreenPlayer() {
|
|||
}
|
||||
|
||||
private fun noLinksFound() {
|
||||
showToast(activity, R.string.no_links_found_toast, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.no_links_found_toast, Toast.LENGTH_SHORT)
|
||||
activity?.popCurrentPage()
|
||||
}
|
||||
|
||||
|
@ -1357,7 +1356,7 @@ class GeneratorPlayer : FullScreenPlayer() {
|
|||
}
|
||||
|
||||
is Resource.Failure -> {
|
||||
showToast(activity, it.errorString, Toast.LENGTH_LONG)
|
||||
showToast(it.errorString, Toast.LENGTH_LONG)
|
||||
startPlayer()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
|
|||
import com.lagradost.cloudstream3.APIHolder.filterProviderByPreferredMedia
|
||||
import com.lagradost.cloudstream3.APIHolder.filterSearchResultByFilmQuality
|
||||
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
|
||||
import com.lagradost.cloudstream3.CommonActivity.activity
|
||||
import com.lagradost.cloudstream3.HomePageList
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.databinding.QuickSearchBinding
|
||||
|
@ -45,6 +46,13 @@ class QuickSearchFragment : Fragment() {
|
|||
const val AUTOSEARCH_KEY = "autosearch"
|
||||
const val PROVIDER_KEY = "providers"
|
||||
|
||||
fun pushSearch(
|
||||
autoSearch: String? = null,
|
||||
providers: Array<String>? = null
|
||||
) {
|
||||
pushSearch(activity, autoSearch, providers)
|
||||
}
|
||||
|
||||
fun pushSearch(
|
||||
activity: Activity?,
|
||||
autoSearch: String? = null,
|
||||
|
@ -151,19 +159,20 @@ class QuickSearchFragment : Fragment() {
|
|||
ArrayList(),
|
||||
this,
|
||||
) { callback ->
|
||||
SearchHelper.handleSearchClickCallback(activity, callback)
|
||||
SearchHelper.handleSearchClickCallback(callback)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
binding?.quickSearch?.queryHint = getString(R.string.search_hint_site).format(providers?.first())
|
||||
binding?.quickSearch?.queryHint =
|
||||
getString(R.string.search_hint_site).format(providers?.first())
|
||||
} catch (e: Exception) {
|
||||
logError(e)
|
||||
}
|
||||
} else {
|
||||
binding?.quickSearchMasterRecycler?.adapter =
|
||||
ParentItemAdapter(mutableListOf(), { callback ->
|
||||
SearchHelper.handleSearchClickCallback(activity, callback)
|
||||
SearchHelper.handleSearchClickCallback(callback)
|
||||
//when (callback.action) {
|
||||
//SEARCH_ACTION_LOAD -> {
|
||||
// clickCallback?.invoke(callback)
|
||||
|
@ -235,11 +244,13 @@ class QuickSearchFragment : Fragment() {
|
|||
searchExitIcon?.alpha = 1f
|
||||
binding?.quickSearchLoadingBar?.alpha = 0f
|
||||
}
|
||||
|
||||
is Resource.Failure -> {
|
||||
// Toast.makeText(activity, "Server error", Toast.LENGTH_LONG).show()
|
||||
searchExitIcon?.alpha = 1f
|
||||
binding?.quickSearchLoadingBar?.alpha = 0f
|
||||
}
|
||||
|
||||
is Resource.Loading -> {
|
||||
searchExitIcon?.alpha = 0f
|
||||
binding?.quickSearchLoadingBar?.alpha = 1f
|
||||
|
|
|
@ -388,7 +388,7 @@ open class ResultFragment : ResultTrailerPlayer() {
|
|||
)
|
||||
}
|
||||
|
||||
else -> handleDownloadClick(activity, click)
|
||||
else -> handleDownloadClick(click)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -575,7 +575,7 @@ open class ResultFragment : ResultTrailerPlayer() {
|
|||
viewModel.handleAction(activity, episodeClick)
|
||||
},
|
||||
{ downloadClickEvent ->
|
||||
handleDownloadClick(activity, downloadClickEvent)
|
||||
handleDownloadClick(downloadClickEvent)
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -939,7 +939,7 @@ open class ResultFragment : ResultTrailerPlayer() {
|
|||
|
||||
val name = (viewModel.page.value as? Resource.Success)?.value?.title
|
||||
?: txt(R.string.no_data).asStringNull(context) ?: ""
|
||||
showToast(activity, txt(message, name), Toast.LENGTH_SHORT)
|
||||
showToast(txt(message, name), Toast.LENGTH_SHORT)
|
||||
}
|
||||
|
||||
result_open_in_browser?.isVisible = d.url.startsWith("http")
|
||||
|
|
|
@ -187,7 +187,7 @@ class ResultFragmentPhone : ResultFragment() {
|
|||
ArrayList(),
|
||||
result_recommendations,
|
||||
) { callback ->
|
||||
SearchHelper.handleSearchClickCallback(activity, callback)
|
||||
SearchHelper.handleSearchClickCallback(callback)
|
||||
}
|
||||
PanelsChildGestureRegionObserver.Provider.get().addGestureRegionsUpdateListener(this)
|
||||
|
||||
|
@ -246,7 +246,6 @@ class ResultFragmentPhone : ResultFragment() {
|
|||
if (!chromecastSupport) {
|
||||
media_route_button?.setOnClickListener {
|
||||
CommonActivity.showToast(
|
||||
activity,
|
||||
R.string.no_chromecast_support_toast,
|
||||
Toast.LENGTH_LONG
|
||||
)
|
||||
|
|
|
@ -226,7 +226,7 @@ class ResultFragmentTv : ResultFragment() {
|
|||
ArrayList(),
|
||||
result_recommendations,
|
||||
) { callback ->
|
||||
SearchHelper.handleSearchClickCallback(activity, callback)
|
||||
SearchHelper.handleSearchClickCallback(callback)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -748,7 +748,6 @@ class ResultViewModel2 : ViewModel() {
|
|||
if (currentLinks.isEmpty()) {
|
||||
main {
|
||||
showToast(
|
||||
activity,
|
||||
R.string.no_links_found_toast,
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
|
@ -757,7 +756,6 @@ class ResultViewModel2 : ViewModel() {
|
|||
} else {
|
||||
main {
|
||||
showToast(
|
||||
activity,
|
||||
R.string.download_started,
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
|
@ -1030,9 +1028,9 @@ class ResultViewModel2 : ViewModel() {
|
|||
logError(t)
|
||||
main {
|
||||
if (t is ActivityNotFoundException) {
|
||||
showToast(activity, txt(R.string.app_not_found_error), Toast.LENGTH_LONG)
|
||||
showToast(txt(R.string.app_not_found_error), Toast.LENGTH_LONG)
|
||||
} else {
|
||||
showToast(activity, t.toString(), Toast.LENGTH_LONG)
|
||||
showToast(t.toString(), Toast.LENGTH_LONG)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1285,7 +1283,6 @@ class ResultViewModel2 : ViewModel() {
|
|||
)
|
||||
)
|
||||
showToast(
|
||||
activity,
|
||||
R.string.download_started,
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
|
@ -1293,7 +1290,7 @@ class ResultViewModel2 : ViewModel() {
|
|||
}
|
||||
|
||||
ACTION_SHOW_TOAST -> {
|
||||
showToast(activity, R.string.play_episode_toast, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.play_episode_toast, Toast.LENGTH_SHORT)
|
||||
}
|
||||
|
||||
ACTION_DOWNLOAD_EPISODE -> {
|
||||
|
@ -1334,7 +1331,6 @@ class ResultViewModel2 : ViewModel() {
|
|||
)
|
||||
}
|
||||
showToast(
|
||||
activity,
|
||||
R.string.download_started,
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
|
@ -1389,7 +1385,7 @@ class ResultViewModel2 : ViewModel() {
|
|||
val link = result.links[index]
|
||||
val clip = ClipData.newPlainText(link.name, link.url)
|
||||
serviceClipboard.setPrimaryClip(clip)
|
||||
showToast(act, R.string.copy_link_toast, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.copy_link_toast, Toast.LENGTH_SHORT)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1400,7 +1396,7 @@ class ResultViewModel2 : ViewModel() {
|
|||
ACTION_PLAY_EPISODE_IN_VLC_PLAYER -> {
|
||||
loadLinks(click.data, isVisible = true, isCasting = true) { links ->
|
||||
if (links.links.isEmpty()) {
|
||||
showToast(activity, R.string.no_links_found_toast, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.no_links_found_toast, Toast.LENGTH_SHORT)
|
||||
return@loadLinks
|
||||
}
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ class SearchFragment : Fragment() {
|
|||
ArrayList(),
|
||||
searchAutofitResults,
|
||||
) { callback ->
|
||||
SearchHelper.handleSearchClickCallback(activity, callback)
|
||||
SearchHelper.handleSearchClickCallback(callback)
|
||||
}
|
||||
|
||||
|
||||
|
@ -491,7 +491,7 @@ class SearchFragment : Fragment() {
|
|||
|
||||
val masterAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder> =
|
||||
ParentItemAdapter(mutableListOf(), { callback ->
|
||||
SearchHelper.handleSearchClickCallback(activity, callback)
|
||||
SearchHelper.handleSearchClickCallback(callback)
|
||||
}, { item ->
|
||||
bottomSheetDialog = activity?.loadHomepageList(item, dismissCallback = {
|
||||
bottomSheetDialog = null
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.lagradost.cloudstream3.ui.search
|
|||
|
||||
import android.app.Activity
|
||||
import android.widget.Toast
|
||||
import com.lagradost.cloudstream3.CommonActivity.activity
|
||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||
import com.lagradost.cloudstream3.MainActivity
|
||||
import com.lagradost.cloudstream3.R
|
||||
|
@ -15,21 +16,21 @@ import com.lagradost.cloudstream3.utils.DataStoreHelper
|
|||
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
|
||||
|
||||
object SearchHelper {
|
||||
fun handleSearchClickCallback(activity: Activity?, callback: SearchClickCallback) {
|
||||
fun handleSearchClickCallback(callback: SearchClickCallback) {
|
||||
val card = callback.card
|
||||
when (callback.action) {
|
||||
SEARCH_ACTION_LOAD -> {
|
||||
activity.loadSearchResult(card)
|
||||
loadSearchResult(card)
|
||||
}
|
||||
SEARCH_ACTION_PLAY_FILE -> {
|
||||
if (card is DataStoreHelper.ResumeWatchingResult) {
|
||||
val id = card.id
|
||||
if(id == null) {
|
||||
showToast(activity, R.string.error_invalid_id, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.error_invalid_id, Toast.LENGTH_SHORT)
|
||||
} else {
|
||||
if (card.isFromDownload) {
|
||||
handleDownloadClick(
|
||||
activity, DownloadClickEvent(
|
||||
DownloadClickEvent(
|
||||
DOWNLOAD_ACTION_PLAY_FILE,
|
||||
VideoDownloadHelper.DownloadEpisodeCached(
|
||||
card.name,
|
||||
|
@ -45,12 +46,11 @@ object SearchHelper {
|
|||
)
|
||||
)
|
||||
} else {
|
||||
activity.loadSearchResult(card, START_ACTION_LOAD_EP, id)
|
||||
loadSearchResult(card, START_ACTION_LOAD_EP, id)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handleSearchClickCallback(
|
||||
activity,
|
||||
SearchClickCallback(SEARCH_ACTION_LOAD, callback.view, -1, callback.card)
|
||||
)
|
||||
}
|
||||
|
@ -60,10 +60,10 @@ object SearchHelper {
|
|||
(activity as? MainActivity?)?.apply {
|
||||
loadPopup(callback.card)
|
||||
} ?: kotlin.run {
|
||||
showToast(activity, callback.card.name, Toast.LENGTH_SHORT)
|
||||
showToast(callback.card.name, Toast.LENGTH_SHORT)
|
||||
}
|
||||
} else {
|
||||
showToast(activity, callback.card.name, Toast.LENGTH_SHORT)
|
||||
showToast(callback.card.name, Toast.LENGTH_SHORT)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -216,7 +216,6 @@ class SettingsAccount : PreferenceFragmentCompat() {
|
|||
activity.runOnUiThread {
|
||||
try {
|
||||
showToast(
|
||||
activity,
|
||||
activity.getString(if (isSuccessful) R.string.authenticated_user else R.string.authenticated_user_fail)
|
||||
.format(
|
||||
api.name
|
||||
|
|
|
@ -213,7 +213,7 @@ class SettingsGeneral : PreferenceFragmentCompat() {
|
|||
val lang = binding.siteLangInput.text?.toString()
|
||||
val realLang = if (lang.isNullOrBlank()) provider.lang else lang
|
||||
if (url.isNullOrBlank() || name.isNullOrBlank() || realLang.length != 2) {
|
||||
showToast(activity, R.string.error_invalid_data, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.error_invalid_data, Toast.LENGTH_SHORT)
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ class SettingsUpdates : PreferenceFragmentCompat() {
|
|||
serviceClipboard.setPrimaryClip(clip)
|
||||
dialog.dismissSafe(activity)
|
||||
} catch (e: TransactionTooLargeException) {
|
||||
showToast(activity, R.string.clipboard_too_large)
|
||||
showToast(R.string.clipboard_too_large)
|
||||
}
|
||||
}
|
||||
binding.clearBtt.setOnClickListener {
|
||||
|
@ -158,7 +158,6 @@ class SettingsUpdates : PreferenceFragmentCompat() {
|
|||
if (activity?.runAutoUpdate(false) == false) {
|
||||
activity?.runOnUiThread {
|
||||
showToast(
|
||||
activity,
|
||||
R.string.no_update_found,
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
|
|
|
@ -211,7 +211,7 @@ class ExtensionsFragment : Fragment() {
|
|||
?.let { it1 -> RepositoryManager.parseRepoUrl(it1) }
|
||||
if (url.isNullOrBlank()) {
|
||||
main {
|
||||
showToast(activity, R.string.error_invalid_data, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.error_invalid_data, Toast.LENGTH_SHORT)
|
||||
}
|
||||
} else {
|
||||
val fixedName = if (!name.isNullOrBlank()) name
|
||||
|
|
|
@ -86,7 +86,6 @@ class PluginsViewModel : ViewModel() {
|
|||
}.also { list ->
|
||||
main {
|
||||
showToast(
|
||||
activity,
|
||||
if (list.isEmpty()) {
|
||||
txt(
|
||||
R.string.batch_download_nothing_to_download_format,
|
||||
|
@ -113,7 +112,6 @@ class PluginsViewModel : ViewModel() {
|
|||
}.main { list ->
|
||||
if (list.any { it }) {
|
||||
showToast(
|
||||
activity,
|
||||
txt(
|
||||
R.string.batch_download_finish_format,
|
||||
list.count { it },
|
||||
|
@ -123,7 +121,7 @@ class PluginsViewModel : ViewModel() {
|
|||
)
|
||||
viewModel?.updatePluginListPrivate(activity, repositoryUrl)
|
||||
} else if (list.isNotEmpty()) {
|
||||
showToast(activity, R.string.download_failed, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.download_failed, Toast.LENGTH_SHORT)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -166,9 +164,9 @@ class PluginsViewModel : ViewModel() {
|
|||
|
||||
runOnMainThread {
|
||||
if (success)
|
||||
showToast(activity, message, Toast.LENGTH_SHORT)
|
||||
showToast(message, Toast.LENGTH_SHORT)
|
||||
else
|
||||
showToast(activity, R.string.error, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.error, Toast.LENGTH_SHORT)
|
||||
}
|
||||
|
||||
if (success)
|
||||
|
|
|
@ -194,7 +194,7 @@ class ChromecastSubtitlesFragment : Fragment() {
|
|||
|
||||
this.setOnLongClickListener {
|
||||
it.context.setColor(id, null)
|
||||
showToast(activity, R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||
return@setOnLongClickListener true
|
||||
}
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ class ChromecastSubtitlesFragment : Fragment() {
|
|||
binding?.subsEdgeType?.setOnLongClickListener {
|
||||
state.edgeType = defaultState.edgeType
|
||||
it.context.updateState()
|
||||
showToast(activity, R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||
return@setOnLongClickListener true
|
||||
}
|
||||
|
||||
|
@ -293,7 +293,7 @@ class ChromecastSubtitlesFragment : Fragment() {
|
|||
binding?.subsFontSize?.setOnLongClickListener { _ ->
|
||||
state.fontScale = defaultState.fontScale
|
||||
//textView.context.updateState() // font size not changed
|
||||
showToast(activity, R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||
return@setOnLongClickListener true
|
||||
}
|
||||
|
||||
|
|
|
@ -272,7 +272,7 @@ class SubtitlesFragment : Fragment() {
|
|||
|
||||
this.setOnLongClickListener {
|
||||
it.context.setColor(id, null)
|
||||
showToast(activity, R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||
return@setOnLongClickListener true
|
||||
}
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ class SubtitlesFragment : Fragment() {
|
|||
subsSubtitleElevation.setOnLongClickListener {
|
||||
state.elevation = DEF_SUBS_ELEVATION
|
||||
it.context.updateState()
|
||||
showToast(activity, R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||
return@setOnLongClickListener true
|
||||
}
|
||||
|
||||
|
@ -367,7 +367,7 @@ class SubtitlesFragment : Fragment() {
|
|||
subsEdgeType.setOnLongClickListener {
|
||||
state.edgeType = CaptionStyleCompat.EDGE_TYPE_OUTLINE
|
||||
it.context.updateState()
|
||||
showToast(activity, R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||
showToast(R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||
return@setOnLongClickListener true
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ import com.google.android.gms.common.GoogleApiAvailability
|
|||
import com.google.android.gms.common.wrappers.Wrappers
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.CommonActivity.activity
|
||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||
import com.lagradost.cloudstream3.MainActivity.Companion.afterRepositoryLoadedEvent
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
|
@ -198,7 +199,11 @@ object AppUtils {
|
|||
animation.start()
|
||||
}
|
||||
|
||||
fun Context.createNotificationChannel(channelId: String, channelName: String, description: String) {
|
||||
fun Context.createNotificationChannel(
|
||||
channelId: String,
|
||||
channelName: String,
|
||||
description: String
|
||||
) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val importance = NotificationManager.IMPORTANCE_DEFAULT
|
||||
val channel =
|
||||
|
@ -288,6 +293,7 @@ object AppUtils {
|
|||
|
||||
// https://github.com/googlearchive/leanback-homescreen-channels/blob/master/app/src/main/java/com/google/android/tvhomescreenchannels/SampleTvProvider.java
|
||||
@SuppressLint("RestrictedApi")
|
||||
@Throws
|
||||
@WorkerThread
|
||||
suspend fun Context.addProgramsToContinueWatching(data: List<DataStoreHelper.ResumeWatchingResult>) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
|
||||
|
@ -369,7 +375,6 @@ object AppUtils {
|
|||
)
|
||||
main {
|
||||
showToast(
|
||||
this@loadRepository,
|
||||
getString(R.string.player_loaded_subtitles, repo.name),
|
||||
Toast.LENGTH_LONG
|
||||
)
|
||||
|
@ -577,6 +582,15 @@ object AppUtils {
|
|||
}
|
||||
}
|
||||
|
||||
fun loadResult(
|
||||
url: String,
|
||||
apiName: String,
|
||||
startAction: Int = 0,
|
||||
startValue: Int = 0
|
||||
) {
|
||||
(activity as FragmentActivity?)?.loadResult(url, apiName, startAction, startValue)
|
||||
}
|
||||
|
||||
fun FragmentActivity.loadResult(
|
||||
url: String,
|
||||
apiName: String,
|
||||
|
@ -592,6 +606,14 @@ object AppUtils {
|
|||
}
|
||||
}
|
||||
|
||||
fun loadSearchResult(
|
||||
card: SearchResponse,
|
||||
startAction: Int = 0,
|
||||
startValue: Int? = null,
|
||||
) {
|
||||
activity?.loadSearchResult(card, startAction, startValue)
|
||||
}
|
||||
|
||||
fun Activity?.loadSearchResult(
|
||||
card: SearchResponse,
|
||||
startAction: Int = 0,
|
||||
|
@ -776,12 +798,12 @@ object AppUtils {
|
|||
return networkInfo.any {
|
||||
conManager.getNetworkCapabilities(it)
|
||||
?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true
|
||||
} &&
|
||||
} &&
|
||||
!networkInfo.any {
|
||||
conManager.getNetworkCapabilities(it)
|
||||
?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun Activity?.cacheClass(clazz: String?) {
|
||||
|
|
|
@ -149,7 +149,7 @@ object BackupUtils {
|
|||
fun FragmentActivity.backup() {
|
||||
try {
|
||||
if (!checkWrite()) {
|
||||
showToast(this, getString(R.string.backup_failed), Toast.LENGTH_LONG)
|
||||
showToast(getString(R.string.backup_failed), Toast.LENGTH_LONG)
|
||||
requestRW()
|
||||
return
|
||||
}
|
||||
|
@ -201,7 +201,6 @@ object BackupUtils {
|
|||
printStream.close()
|
||||
|
||||
showToast(
|
||||
this,
|
||||
R.string.backup_success,
|
||||
Toast.LENGTH_LONG
|
||||
)
|
||||
|
@ -209,7 +208,6 @@ object BackupUtils {
|
|||
logError(e)
|
||||
try {
|
||||
showToast(
|
||||
this,
|
||||
getString(R.string.backup_failed_error_format).format(e.toString()),
|
||||
Toast.LENGTH_LONG
|
||||
)
|
||||
|
@ -243,7 +241,6 @@ object BackupUtils {
|
|||
logError(e)
|
||||
main { // smth can fail in .format
|
||||
showToast(
|
||||
activity,
|
||||
getString(R.string.restore_failed_format).format(e.toString())
|
||||
)
|
||||
}
|
||||
|
@ -270,7 +267,7 @@ object BackupUtils {
|
|||
)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
showToast(this, e.message)
|
||||
showToast(e.message)
|
||||
logError(e)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -300,7 +300,7 @@ class InAppUpdater {
|
|||
// Forcefully start any delayed installations
|
||||
if (ApkInstaller.delayedInstaller?.startInstallation() == true) return@setPositiveButton
|
||||
|
||||
showToast(context, R.string.download_started, Toast.LENGTH_LONG)
|
||||
showToast(R.string.download_started, Toast.LENGTH_LONG)
|
||||
|
||||
// Check if the setting hasn't been changed
|
||||
if (settingsManager.getInt(
|
||||
|
@ -335,7 +335,6 @@ class InAppUpdater {
|
|||
if (!downloadUpdate(update.updateURL))
|
||||
runOnUiThread {
|
||||
showToast(
|
||||
context,
|
||||
R.string.download_failed,
|
||||
Toast.LENGTH_LONG
|
||||
)
|
||||
|
|
|
@ -46,6 +46,7 @@ import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
|||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.RequestOptions.bitmapTransform
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.lagradost.cloudstream3.CommonActivity.activity
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
import com.lagradost.cloudstream3.ui.result.UiImage
|
||||
|
@ -554,7 +555,7 @@ object UIHelper {
|
|||
}
|
||||
|
||||
fun Dialog?.dismissSafe() {
|
||||
if (this?.isShowing == true) {
|
||||
if (this?.isShowing == true && activity?.isFinishing != true) {
|
||||
this.dismiss()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue