Show empty catalogue error view with actions

This commit is contained in:
arkon 2020-03-09 18:45:38 -04:00
parent ed277357cf
commit bb43e2aa03
4 changed files with 104 additions and 38 deletions

View File

@ -41,8 +41,10 @@ import eu.kanade.tachiyomi.util.view.inflate
import eu.kanade.tachiyomi.util.view.snack import eu.kanade.tachiyomi.util.view.snack
import eu.kanade.tachiyomi.util.view.visible import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.widget.AutofitRecyclerView import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import eu.kanade.tachiyomi.widget.EmptyView
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlinx.android.synthetic.main.catalogue_controller.catalogue_view import kotlinx.android.synthetic.main.catalogue_controller.catalogue_view
import kotlinx.android.synthetic.main.catalogue_controller.empty_view
import kotlinx.android.synthetic.main.catalogue_controller.progress import kotlinx.android.synthetic.main.catalogue_controller.progress
import kotlinx.android.synthetic.main.main_activity.drawer import kotlinx.android.synthetic.main.main_activity.drawer
import rx.Observable import rx.Observable
@ -352,17 +354,33 @@ open class BrowseCatalogueController(bundle: Bundle) :
snack?.dismiss() snack?.dismiss()
if (catalogue_view != null) { if (catalogue_view != null) {
snack = catalogue_view.snack(getErrorMessage(error), Snackbar.LENGTH_INDEFINITE) { val message = getErrorMessage(error)
setAction(R.string.action_retry) { val retryAction = View.OnClickListener {
empty_view.hide()
// If not the first page, show bottom progress bar. // If not the first page, show bottom progress bar.
if (adapter.mainItemCount > 0) { if (adapter.mainItemCount > 0 && progressItem != null) {
val item = progressItem ?: return@setAction adapter.addScrollableFooterWithDelay(progressItem!!, 0, true)
adapter.addScrollableFooterWithDelay(item, 0, true)
} else { } else {
showProgressBar() showProgressBar()
} }
presenter.requestNext() presenter.requestNext()
} }
val openInWebViewAction = View.OnClickListener {
openInWebView()
}
if (adapter.isEmpty) {
empty_view.show(message, listOf(
EmptyView.Action(R.string.action_retry, retryAction),
EmptyView.Action(R.string.action_open_in_web_view, openInWebViewAction)
))
} else {
empty_view.hide()
snack = catalogue_view.snack(message, Snackbar.LENGTH_INDEFINITE) {
setAction(R.string.action_retry, retryAction)
}
} }
} }
} }

View File

@ -2,12 +2,16 @@ package eu.kanade.tachiyomi.widget
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import android.widget.RelativeLayout import android.widget.RelativeLayout
import androidx.annotation.StringRes import androidx.annotation.StringRes
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.visible import eu.kanade.tachiyomi.util.view.visible
import kotlin.random.Random import kotlin.random.Random
import kotlinx.android.synthetic.main.common_view_empty.view.actions_container
import kotlinx.android.synthetic.main.common_view_empty.view.text_face import kotlinx.android.synthetic.main.common_view_empty.view.text_face
import kotlinx.android.synthetic.main.common_view_empty.view.text_label import kotlinx.android.synthetic.main.common_view_empty.view.text_label
@ -29,9 +33,30 @@ class EmptyView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
* Show the information view * Show the information view
* @param textResource text of information view * @param textResource text of information view
*/ */
fun show(@StringRes textResource: Int) { fun show(@StringRes textResource: Int, actions: List<Action>? = null) {
show(context.getString(textResource), actions)
}
fun show(message: String, actions: List<Action>? = null) {
text_face.text = getRandomErrorFace() text_face.text = getRandomErrorFace()
text_label.text = context.getString(textResource) text_label.text = message
actions_container.removeAllViews()
if (!actions.isNullOrEmpty()) {
actions.forEach {
val button = Button(context).apply {
layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
setText(it.resId)
setOnClickListener(it.listener)
}
actions_container.addView(button)
}
}
this.visible() this.visible()
} }
@ -49,4 +74,9 @@ class EmptyView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
return ERROR_FACES[Random.nextInt(ERROR_FACES.size)] return ERROR_FACES[Random.nextInt(ERROR_FACES.size)]
} }
} }
data class Action(
@StringRes val resId: Int,
val listener: View.OnClickListener
)
} }

View File

@ -4,11 +4,15 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout <LinearLayout
android:id="@+id/catalogue_view" android:id="@+id/catalogue_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical" android:orientation="vertical"
tools:context="eu.kanade.tachiyomi.ui.catalogue.browse.BrowseCatalogueController"> tools:context="eu.kanade.tachiyomi.ui.catalogue.browse.BrowseCatalogueController">
@ -17,9 +21,18 @@
style="?android:attr/progressBarStyleLarge" style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="center_vertical|center_horizontal" android:layout_gravity="center"
android:visibility="gone" /> android:visibility="gone" />
</LinearLayout> </LinearLayout>
<eu.kanade.tachiyomi.widget.EmptyView
android:id="@+id/empty_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:visibility="gone" />
</FrameLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_gravity="center"> android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="16dp">
<TextView <TextView
android:id="@+id/text_face" android:id="@+id/text_face"
style="@style/TextAppearance.Medium.Body2.Hint" style="@style/TextAppearance.Medium.Body2.Hint"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_margin="16dp"
android:gravity="center" android:gravity="center"
android:textSize="48sp" android:textSize="48sp"
tools:text="-_-" /> tools:text="-_-" />
@ -21,10 +21,15 @@
style="@style/TextAppearance.Medium.Body2.Hint" style="@style/TextAppearance.Medium.Body2.Hint"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/text_face"
android:layout_centerHorizontal="true"
android:layout_margin="16dp" android:layout_margin="16dp"
android:gravity="center" android:gravity="center"
tools:text="Label" /> tools:text="Label" />
</RelativeLayout> <LinearLayout
android:id="@+id/actions_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" />
</LinearLayout>