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