Reworked the ErrorPanel
* All element on the error panel are now hidden by default (expect for the ``errorTextView``) as they are only optional shown * Added a method to ensure the above * This deduplicates a lot of code * Fixed format of some LoC * Added new method: ``showAndSetErrorButtonAction`` * Fixed ``showTextError`` * Named buttons more logically: ``errorButtonAction`` -> ``errorActionButton``
This commit is contained in:
parent
d9086300f3
commit
d931d058d9
|
@ -6,6 +6,8 @@ import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.annotation.Nullable
|
||||||
|
import androidx.annotation.StringRes
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import com.jakewharton.rxbinding4.view.clicks
|
import com.jakewharton.rxbinding4.view.clicks
|
||||||
|
@ -37,22 +39,39 @@ class ErrorPanelHelper(
|
||||||
onRetry: Runnable
|
onRetry: Runnable
|
||||||
) {
|
) {
|
||||||
private val context: Context = rootView.context!!
|
private val context: Context = rootView.context!!
|
||||||
|
|
||||||
private val errorPanelRoot: View = rootView.findViewById(R.id.error_panel)
|
private val errorPanelRoot: View = rootView.findViewById(R.id.error_panel)
|
||||||
private val errorTextView: TextView = errorPanelRoot.findViewById(R.id.error_message_view)
|
|
||||||
private val errorServiceInfoTextView: TextView = errorPanelRoot.findViewById(R.id.error_message_service_info_view)
|
// the only element that is visible by default
|
||||||
private val errorServiceExplenationTextView: TextView = errorPanelRoot.findViewById(R.id.error_message_service_explenation_view)
|
private val errorTextView: TextView =
|
||||||
private val errorButtonAction: Button = errorPanelRoot.findViewById(R.id.error_button_action)
|
errorPanelRoot.findViewById(R.id.error_message_view)
|
||||||
private val errorButtonRetry: Button = errorPanelRoot.findViewById(R.id.error_button_retry)
|
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)
|
||||||
|
|
||||||
private var errorDisposable: Disposable? = null
|
private var errorDisposable: Disposable? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
errorDisposable = errorButtonRetry.clicks()
|
errorDisposable = errorRetryButton.clicks()
|
||||||
.debounce(300, TimeUnit.MILLISECONDS)
|
.debounce(300, TimeUnit.MILLISECONDS)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe { onRetry.run() }
|
.subscribe { onRetry.run() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ensureDefaultVisibility() {
|
||||||
|
errorTextView.isVisible = true
|
||||||
|
|
||||||
|
errorServiceInfoTextView.isVisible = false
|
||||||
|
errorServiceExplanationTextView.isVisible = false
|
||||||
|
errorActionButton.isVisible = false
|
||||||
|
errorRetryButton.isVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
fun showError(errorInfo: ErrorInfo) {
|
fun showError(errorInfo: ErrorInfo) {
|
||||||
|
|
||||||
if (errorInfo.throwable != null && errorInfo.throwable!!.isInterruptedCaused) {
|
if (errorInfo.throwable != null && errorInfo.throwable!!.isInterruptedCaused) {
|
||||||
|
@ -62,10 +81,14 @@ class ErrorPanelHelper(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
errorButtonAction.isVisible = true
|
ensureDefaultVisibility()
|
||||||
|
|
||||||
if (errorInfo.throwable is ReCaptchaException) {
|
if (errorInfo.throwable is ReCaptchaException) {
|
||||||
errorButtonAction.setText(R.string.recaptcha_solve)
|
errorTextView.setText(R.string.recaptcha_request_toast)
|
||||||
errorButtonAction.setOnClickListener {
|
|
||||||
|
showAndSetErrorButtonAction(
|
||||||
|
R.string.recaptcha_solve
|
||||||
|
) {
|
||||||
// Starting ReCaptcha Challenge Activity
|
// Starting ReCaptcha Challenge Activity
|
||||||
val intent = Intent(context, ReCaptchaActivity::class.java)
|
val intent = Intent(context, ReCaptchaActivity::class.java)
|
||||||
intent.putExtra(
|
intent.putExtra(
|
||||||
|
@ -73,45 +96,31 @@ class ErrorPanelHelper(
|
||||||
(errorInfo.throwable as ReCaptchaException).url
|
(errorInfo.throwable as ReCaptchaException).url
|
||||||
)
|
)
|
||||||
fragment.startActivityForResult(intent, ReCaptchaActivity.RECAPTCHA_REQUEST)
|
fragment.startActivityForResult(intent, ReCaptchaActivity.RECAPTCHA_REQUEST)
|
||||||
errorButtonAction.setOnClickListener(null)
|
errorActionButton.setOnClickListener(null)
|
||||||
}
|
}
|
||||||
errorTextView.setText(R.string.recaptcha_request_toast)
|
|
||||||
// additional info is only provided by AccountTerminatedException
|
errorRetryButton.isVisible = true
|
||||||
errorServiceInfoTextView.isVisible = false
|
|
||||||
errorServiceExplenationTextView.isVisible = false
|
|
||||||
errorButtonRetry.isVisible = true
|
|
||||||
} else if (errorInfo.throwable is AccountTerminatedException) {
|
} else if (errorInfo.throwable is AccountTerminatedException) {
|
||||||
errorButtonRetry.isVisible = false
|
|
||||||
errorButtonAction.isVisible = false
|
|
||||||
errorTextView.setText(R.string.account_terminated)
|
errorTextView.setText(R.string.account_terminated)
|
||||||
|
|
||||||
if (!isNullOrEmpty((errorInfo.throwable as AccountTerminatedException).message)) {
|
if (!isNullOrEmpty((errorInfo.throwable as AccountTerminatedException).message)) {
|
||||||
errorServiceInfoTextView.setText(
|
errorServiceInfoTextView.text = context.resources.getString(
|
||||||
context.resources.getString(
|
|
||||||
R.string.service_provides_reason,
|
R.string.service_provides_reason,
|
||||||
NewPipe.getNameOfService(ServiceHelper.getSelectedServiceId(context))
|
NewPipe.getNameOfService(ServiceHelper.getSelectedServiceId(context))
|
||||||
)
|
)
|
||||||
)
|
|
||||||
errorServiceExplenationTextView.setText(
|
|
||||||
(errorInfo.throwable as AccountTerminatedException).message
|
|
||||||
)
|
|
||||||
errorServiceInfoTextView.isVisible = true
|
errorServiceInfoTextView.isVisible = true
|
||||||
errorServiceExplenationTextView.isVisible = true
|
|
||||||
} else {
|
errorServiceExplanationTextView.text =
|
||||||
errorServiceInfoTextView.isVisible = false
|
(errorInfo.throwable as AccountTerminatedException).message
|
||||||
errorServiceExplenationTextView.isVisible = false
|
errorServiceExplanationTextView.isVisible = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
errorButtonAction.setText(R.string.error_snackbar_action)
|
showAndSetErrorButtonAction(
|
||||||
errorButtonAction.setOnClickListener {
|
R.string.error_snackbar_action
|
||||||
|
) {
|
||||||
ErrorActivity.reportError(context, errorInfo)
|
ErrorActivity.reportError(context, errorInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// additional info is only provided by AccountTerminatedException
|
|
||||||
errorServiceInfoTextView.isVisible = false
|
|
||||||
errorServiceExplenationTextView.isVisible = false
|
|
||||||
|
|
||||||
// hide retry button by default, then show only if not unavailable/unsupported content
|
|
||||||
errorButtonRetry.isVisible = false
|
|
||||||
errorTextView.setText(
|
errorTextView.setText(
|
||||||
when (errorInfo.throwable) {
|
when (errorInfo.throwable) {
|
||||||
is AgeRestrictedContentException -> R.string.restricted_video_no_stream
|
is AgeRestrictedContentException -> R.string.restricted_video_no_stream
|
||||||
|
@ -124,7 +133,7 @@ class ErrorPanelHelper(
|
||||||
is ContentNotSupportedException -> R.string.content_not_supported
|
is ContentNotSupportedException -> R.string.content_not_supported
|
||||||
else -> {
|
else -> {
|
||||||
// show retry button only for content which is not unavailable or unsupported
|
// show retry button only for content which is not unavailable or unsupported
|
||||||
errorButtonRetry.isVisible = true
|
errorRetryButton.isVisible = true
|
||||||
if (errorInfo.throwable != null && errorInfo.throwable!!.isNetworkRelated) {
|
if (errorInfo.throwable != null && errorInfo.throwable!!.isNetworkRelated) {
|
||||||
R.string.network_error
|
R.string.network_error
|
||||||
} else {
|
} else {
|
||||||
|
@ -134,17 +143,36 @@ class ErrorPanelHelper(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
errorPanelRoot.animate(true, 300)
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showTextError(errorString: String) {
|
fun showTextError(errorString: String) {
|
||||||
errorButtonAction.isVisible = false
|
ensureDefaultVisibility()
|
||||||
errorButtonRetry.isVisible = false
|
|
||||||
errorTextView.text = errorString
|
errorTextView.text = errorString
|
||||||
|
|
||||||
|
setRootVisible()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setRootVisible() {
|
||||||
|
errorPanelRoot.animate(true, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hide() {
|
fun hide() {
|
||||||
errorButtonAction.setOnClickListener(null)
|
errorActionButton.setOnClickListener(null)
|
||||||
errorPanelRoot.animate(false, 150)
|
errorPanelRoot.animate(false, 150)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,8 +181,8 @@ class ErrorPanelHelper(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dispose() {
|
fun dispose() {
|
||||||
errorButtonAction.setOnClickListener(null)
|
errorActionButton.setOnClickListener(null)
|
||||||
errorButtonRetry.setOnClickListener(null)
|
errorRetryButton.setOnClickListener(null)
|
||||||
errorDisposable?.dispose()
|
errorDisposable?.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,14 +21,16 @@
|
||||||
android:id="@+id/error_message_service_info_view"
|
android:id="@+id/error_message_service_info_view"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
|
||||||
android:layout_marginTop="6dp"
|
android:layout_marginTop="6dp"
|
||||||
|
android:gravity="center"
|
||||||
android:text="@string/general_error"
|
android:text="@string/general_error"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
tools:text="YouTube provides this reason:" />
|
android:visibility="gone"
|
||||||
|
tools:text="YouTube provides this reason:"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/error_message_service_explenation_view"
|
android:id="@+id/error_message_service_explanation_view"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
@ -36,11 +38,13 @@
|
||||||
android:text="@string/general_error"
|
android:text="@string/general_error"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="italic"
|
android:textStyle="italic"
|
||||||
tools:text="This account has been terminated because we received multiple third-party claims of copyright infringement regarding material that the user posted." />
|
android:visibility="gone"
|
||||||
|
tools:text="This account has been terminated because we received multiple third-party claims of copyright infringement regarding material that the user posted."
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/error_button_action"
|
android:id="@+id/error_action_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
@ -49,10 +53,12 @@
|
||||||
android:textAllCaps="true"
|
android:textAllCaps="true"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:theme="@style/ServiceColoredButton" />
|
android:theme="@style/ServiceColoredButton"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/error_button_retry"
|
android:id="@+id/error_retry_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
|
@ -62,6 +68,8 @@
|
||||||
android:textAllCaps="true"
|
android:textAllCaps="true"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:theme="@style/ServiceColoredButton" />
|
android:theme="@style/ServiceColoredButton"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
Loading…
Reference in New Issue