2020-12-11 14:55:47 +01:00
|
|
|
package org.schabi.newpipe.error
|
|
|
|
|
|
|
|
import android.content.Context
|
|
|
|
import android.content.Intent
|
|
|
|
import android.util.Log
|
|
|
|
import android.view.View
|
|
|
|
import android.widget.Button
|
|
|
|
import android.widget.TextView
|
2021-08-28 17:05:12 +02:00
|
|
|
import androidx.annotation.Nullable
|
|
|
|
import androidx.annotation.StringRes
|
2020-12-11 14:55:47 +01:00
|
|
|
import androidx.core.view.isVisible
|
|
|
|
import androidx.fragment.app.Fragment
|
|
|
|
import com.jakewharton.rxbinding4.view.clicks
|
|
|
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
|
|
import io.reactivex.rxjava3.disposables.Disposable
|
|
|
|
import org.schabi.newpipe.MainActivity
|
|
|
|
import org.schabi.newpipe.R
|
2021-03-31 22:46:52 +02:00
|
|
|
import org.schabi.newpipe.extractor.exceptions.AccountTerminatedException
|
2020-12-11 14:55:47 +01:00
|
|
|
import org.schabi.newpipe.extractor.exceptions.AgeRestrictedContentException
|
|
|
|
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException
|
|
|
|
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException
|
|
|
|
import org.schabi.newpipe.extractor.exceptions.GeographicRestrictionException
|
|
|
|
import org.schabi.newpipe.extractor.exceptions.PaidContentException
|
|
|
|
import org.schabi.newpipe.extractor.exceptions.PrivateContentException
|
|
|
|
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException
|
|
|
|
import org.schabi.newpipe.extractor.exceptions.SoundCloudGoPlusContentException
|
|
|
|
import org.schabi.newpipe.extractor.exceptions.YoutubeMusicPremiumContentException
|
2021-03-31 22:46:52 +02:00
|
|
|
import org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty
|
2020-12-11 14:55:47 +01:00
|
|
|
import org.schabi.newpipe.ktx.animate
|
|
|
|
import org.schabi.newpipe.ktx.isInterruptedCaused
|
|
|
|
import org.schabi.newpipe.ktx.isNetworkRelated
|
2021-03-31 22:46:52 +02:00
|
|
|
import org.schabi.newpipe.util.ServiceHelper
|
2022-10-27 14:38:08 +02:00
|
|
|
import org.schabi.newpipe.util.external_communication.ShareUtils
|
2020-12-11 14:55:47 +01:00
|
|
|
import java.util.concurrent.TimeUnit
|
|
|
|
|
|
|
|
class ErrorPanelHelper(
|
2020-12-11 15:07:18 +01:00
|
|
|
private val fragment: Fragment,
|
|
|
|
rootView: View,
|
|
|
|
onRetry: Runnable
|
2020-12-11 14:55:47 +01:00
|
|
|
) {
|
|
|
|
private val context: Context = rootView.context!!
|
2021-08-28 17:05:12 +02:00
|
|
|
|
2020-12-11 14:55:47 +01:00
|
|
|
private val errorPanelRoot: View = rootView.findViewById(R.id.error_panel)
|
2021-08-28 17:05:12 +02:00
|
|
|
|
|
|
|
// the only element that is visible by default
|
|
|
|
private val errorTextView: TextView =
|
|
|
|
errorPanelRoot.findViewById(R.id.error_message_view)
|
|
|
|
private val errorServiceInfoTextView: TextView =
|
|
|
|
errorPanelRoot.findViewById(R.id.error_message_service_info_view)
|
|
|
|
private val errorServiceExplanationTextView: TextView =
|
|
|
|
errorPanelRoot.findViewById(R.id.error_message_service_explanation_view)
|
|
|
|
private val errorActionButton: Button =
|
|
|
|
errorPanelRoot.findViewById(R.id.error_action_button)
|
|
|
|
private val errorRetryButton: Button =
|
|
|
|
errorPanelRoot.findViewById(R.id.error_retry_button)
|
2022-10-27 14:38:08 +02:00
|
|
|
private val errorOpenInBrowserButton: Button =
|
|
|
|
errorPanelRoot.findViewById(R.id.error_open_in_browser)
|
2020-12-11 14:55:47 +01:00
|
|
|
|
|
|
|
private var errorDisposable: Disposable? = null
|
|
|
|
|
|
|
|
init {
|
2021-08-28 17:05:12 +02:00
|
|
|
errorDisposable = errorRetryButton.clicks()
|
2020-12-11 14:55:47 +01:00
|
|
|
.debounce(300, TimeUnit.MILLISECONDS)
|
|
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
|
|
.subscribe { onRetry.run() }
|
|
|
|
}
|
|
|
|
|
2021-08-28 17:05:12 +02:00
|
|
|
private fun ensureDefaultVisibility() {
|
|
|
|
errorTextView.isVisible = true
|
|
|
|
|
|
|
|
errorServiceInfoTextView.isVisible = false
|
|
|
|
errorServiceExplanationTextView.isVisible = false
|
|
|
|
errorActionButton.isVisible = false
|
|
|
|
errorRetryButton.isVisible = false
|
2022-10-27 14:38:08 +02:00
|
|
|
errorOpenInBrowserButton.isVisible = false
|
2021-08-28 17:05:12 +02:00
|
|
|
}
|
|
|
|
|
2020-12-11 14:55:47 +01:00
|
|
|
fun showError(errorInfo: ErrorInfo) {
|
|
|
|
|
|
|
|
if (errorInfo.throwable != null && errorInfo.throwable!!.isInterruptedCaused) {
|
|
|
|
if (DEBUG) {
|
|
|
|
Log.w(TAG, "onError() isInterruptedCaused! = [$errorInfo.throwable]")
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-08-28 17:05:12 +02:00
|
|
|
ensureDefaultVisibility()
|
|
|
|
|
2020-12-11 14:55:47 +01:00
|
|
|
if (errorInfo.throwable is ReCaptchaException) {
|
2021-08-28 17:05:12 +02:00
|
|
|
errorTextView.setText(R.string.recaptcha_request_toast)
|
|
|
|
|
|
|
|
showAndSetErrorButtonAction(
|
|
|
|
R.string.recaptcha_solve
|
|
|
|
) {
|
2020-12-11 14:55:47 +01:00
|
|
|
// Starting ReCaptcha Challenge Activity
|
|
|
|
val intent = Intent(context, ReCaptchaActivity::class.java)
|
2020-12-11 15:07:18 +01:00
|
|
|
intent.putExtra(
|
|
|
|
ReCaptchaActivity.RECAPTCHA_URL_EXTRA,
|
|
|
|
(errorInfo.throwable as ReCaptchaException).url
|
|
|
|
)
|
2020-12-11 14:55:47 +01:00
|
|
|
fragment.startActivityForResult(intent, ReCaptchaActivity.RECAPTCHA_REQUEST)
|
2021-08-28 17:05:12 +02:00
|
|
|
errorActionButton.setOnClickListener(null)
|
2020-12-11 14:55:47 +01:00
|
|
|
}
|
2021-08-28 17:05:12 +02:00
|
|
|
|
|
|
|
errorRetryButton.isVisible = true
|
2022-10-27 14:38:08 +02:00
|
|
|
showAndSetOpenInBrowserButtonAction(errorInfo)
|
2021-03-31 22:46:52 +02:00
|
|
|
} else if (errorInfo.throwable is AccountTerminatedException) {
|
|
|
|
errorTextView.setText(R.string.account_terminated)
|
2021-08-28 17:05:12 +02:00
|
|
|
|
2021-03-31 22:46:52 +02:00
|
|
|
if (!isNullOrEmpty((errorInfo.throwable as AccountTerminatedException).message)) {
|
2021-08-28 17:05:12 +02:00
|
|
|
errorServiceInfoTextView.text = context.resources.getString(
|
|
|
|
R.string.service_provides_reason,
|
2022-06-21 21:45:10 +02:00
|
|
|
ServiceHelper.getSelectedService(context)?.serviceInfo?.name ?: "<unknown>"
|
2021-03-31 22:46:52 +02:00
|
|
|
)
|
|
|
|
errorServiceInfoTextView.isVisible = true
|
2021-08-28 17:05:12 +02:00
|
|
|
|
|
|
|
errorServiceExplanationTextView.text =
|
|
|
|
(errorInfo.throwable as AccountTerminatedException).message
|
|
|
|
errorServiceExplanationTextView.isVisible = true
|
2021-03-31 22:46:52 +02:00
|
|
|
}
|
2020-12-11 14:55:47 +01:00
|
|
|
} else {
|
2021-08-28 17:05:12 +02:00
|
|
|
showAndSetErrorButtonAction(
|
|
|
|
R.string.error_snackbar_action
|
|
|
|
) {
|
2021-12-01 09:43:24 +01:00
|
|
|
ErrorUtil.openActivity(context, errorInfo)
|
2020-12-11 14:55:47 +01:00
|
|
|
}
|
|
|
|
|
2021-09-05 19:54:03 +02:00
|
|
|
errorTextView.setText(getExceptionDescription(errorInfo.throwable))
|
|
|
|
|
|
|
|
if (errorInfo.throwable !is ContentNotAvailableException &&
|
|
|
|
errorInfo.throwable !is ContentNotSupportedException
|
|
|
|
) {
|
|
|
|
// show retry button only for content which is not unavailable or unsupported
|
|
|
|
errorRetryButton.isVisible = true
|
|
|
|
}
|
2022-10-27 14:38:08 +02:00
|
|
|
showAndSetOpenInBrowserButtonAction(errorInfo)
|
2020-12-11 14:55:47 +01:00
|
|
|
}
|
2021-08-28 17:05:12 +02:00
|
|
|
|
|
|
|
setRootVisible()
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shows the errorButtonAction, sets a text into it and sets the click listener.
|
|
|
|
*/
|
|
|
|
private fun showAndSetErrorButtonAction(
|
|
|
|
@StringRes resid: Int,
|
|
|
|
@Nullable listener: View.OnClickListener
|
|
|
|
) {
|
|
|
|
errorActionButton.isVisible = true
|
|
|
|
errorActionButton.setText(resid)
|
|
|
|
errorActionButton.setOnClickListener(listener)
|
2020-12-11 14:55:47 +01:00
|
|
|
}
|
|
|
|
|
2022-10-27 14:38:08 +02:00
|
|
|
fun showAndSetOpenInBrowserButtonAction(
|
|
|
|
errorInfo: ErrorInfo
|
|
|
|
) {
|
|
|
|
errorOpenInBrowserButton.isVisible = true
|
|
|
|
errorOpenInBrowserButton.setOnClickListener {
|
|
|
|
ShareUtils.openUrlInBrowser(context, errorInfo.request, true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-11 14:55:47 +01:00
|
|
|
fun showTextError(errorString: String) {
|
2021-08-28 17:05:12 +02:00
|
|
|
ensureDefaultVisibility()
|
|
|
|
|
2020-12-11 14:55:47 +01:00
|
|
|
errorTextView.text = errorString
|
2021-08-28 17:05:12 +02:00
|
|
|
|
|
|
|
setRootVisible()
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun setRootVisible() {
|
|
|
|
errorPanelRoot.animate(true, 300)
|
2020-12-11 14:55:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fun hide() {
|
2021-08-28 17:05:12 +02:00
|
|
|
errorActionButton.setOnClickListener(null)
|
2020-12-11 14:55:47 +01:00
|
|
|
errorPanelRoot.animate(false, 150)
|
|
|
|
}
|
|
|
|
|
|
|
|
fun isVisible(): Boolean {
|
|
|
|
return errorPanelRoot.isVisible
|
|
|
|
}
|
|
|
|
|
|
|
|
fun dispose() {
|
2021-08-28 17:05:12 +02:00
|
|
|
errorActionButton.setOnClickListener(null)
|
|
|
|
errorRetryButton.setOnClickListener(null)
|
2020-12-11 14:55:47 +01:00
|
|
|
errorDisposable?.dispose()
|
|
|
|
}
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
val TAG: String = ErrorPanelHelper::class.simpleName!!
|
|
|
|
val DEBUG: Boolean = MainActivity.DEBUG
|
2021-09-05 19:54:03 +02:00
|
|
|
|
|
|
|
@StringRes
|
2021-12-01 09:43:24 +01:00
|
|
|
fun getExceptionDescription(throwable: Throwable?): Int {
|
2021-09-05 19:54:03 +02:00
|
|
|
return when (throwable) {
|
|
|
|
is AgeRestrictedContentException -> R.string.restricted_video_no_stream
|
|
|
|
is GeographicRestrictionException -> R.string.georestricted_content
|
|
|
|
is PaidContentException -> R.string.paid_content
|
|
|
|
is PrivateContentException -> R.string.private_content
|
|
|
|
is SoundCloudGoPlusContentException -> R.string.soundcloud_go_plus_content
|
|
|
|
is YoutubeMusicPremiumContentException -> R.string.youtube_music_premium_content
|
|
|
|
is ContentNotAvailableException -> R.string.content_not_available
|
|
|
|
is ContentNotSupportedException -> R.string.content_not_supported
|
|
|
|
else -> {
|
|
|
|
// show retry button only for content which is not unavailable or unsupported
|
|
|
|
if (throwable != null && throwable.isNetworkRelated) {
|
|
|
|
R.string.network_error
|
|
|
|
} else {
|
|
|
|
R.string.error_snackbar_message
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-12-11 14:55:47 +01:00
|
|
|
}
|
|
|
|
}
|