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:
litetex 2021-08-28 17:05:12 +02:00
parent d9086300f3
commit d931d058d9
2 changed files with 88 additions and 52 deletions

View File

@ -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()
} }

View File

@ -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>