refactor: Simplify use of BackgroundMessageView (#539)

Previous code expected callers to typically provide the drawable and the
error message string resource, resulting in duplicate code at many
callsites.

Replace with three canned messages for empty containers, generic errors,
and network errors respectively. The images for these are fixed, the
caller may choose a different string resource for the error if there is
a more specific option.

Update and simplify the call sites.
This commit is contained in:
Nik Clayton 2024-03-16 22:12:54 +01:00 committed by GitHub
parent e41722e16f
commit 9e0a1f4015
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 86 additions and 83 deletions

View File

@ -42,6 +42,7 @@ import app.pachli.core.designsystem.R as DR
import app.pachli.core.navigation.AttachmentViewData import app.pachli.core.navigation.AttachmentViewData
import app.pachli.core.navigation.ViewMediaActivityIntent import app.pachli.core.navigation.ViewMediaActivityIntent
import app.pachli.core.network.model.Attachment import app.pachli.core.network.model.Attachment
import app.pachli.core.ui.BackgroundMessage
import app.pachli.databinding.FragmentTimelineBinding import app.pachli.databinding.FragmentTimelineBinding
import com.google.android.material.color.MaterialColors import com.google.android.material.color.MaterialColors
import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.IconicsDrawable
@ -113,7 +114,7 @@ class AccountMediaFragment :
is LoadState.NotLoading -> { is LoadState.NotLoading -> {
if (loadState.append is LoadState.NotLoading && loadState.source.refresh is LoadState.NotLoading) { if (loadState.append is LoadState.NotLoading && loadState.source.refresh is LoadState.NotLoading) {
binding.statusView.show() binding.statusView.show()
binding.statusView.setup(app.pachli.core.ui.R.drawable.elephant_friend_empty, app.pachli.core.ui.R.string.message_empty, null) binding.statusView.setup(BackgroundMessage.Empty())
} }
} }
is LoadState.Error -> { is LoadState.Error -> {

View File

@ -54,6 +54,7 @@ import app.pachli.core.network.model.TimelineAccount
import app.pachli.core.network.retrofit.MastodonApi import app.pachli.core.network.retrofit.MastodonApi
import app.pachli.core.preferences.PrefKeys import app.pachli.core.preferences.PrefKeys
import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.core.preferences.SharedPreferencesRepository
import app.pachli.core.ui.BackgroundMessage
import app.pachli.databinding.FragmentAccountListBinding import app.pachli.databinding.FragmentAccountListBinding
import app.pachli.interfaces.AccountActionListener import app.pachli.interfaces.AccountActionListener
import app.pachli.interfaces.AppBarLayoutHost import app.pachli.interfaces.AppBarLayoutHost
@ -376,11 +377,7 @@ class AccountListFragment :
if (adapter.itemCount == 0) { if (adapter.itemCount == 0) {
binding.messageView.show() binding.messageView.show()
binding.messageView.setup( binding.messageView.setup(BackgroundMessage.Empty())
app.pachli.core.ui.R.drawable.elephant_friend_empty,
app.pachli.core.ui.R.string.message_empty,
null,
)
} else { } else {
binding.messageView.hide() binding.messageView.hide()
} }

View File

@ -35,6 +35,7 @@ import app.pachli.core.common.extensions.viewBinding
import app.pachli.core.common.util.unsafeLazy import app.pachli.core.common.util.unsafeLazy
import app.pachli.core.navigation.StatusListActivityIntent import app.pachli.core.navigation.StatusListActivityIntent
import app.pachli.core.preferences.PrefKeys import app.pachli.core.preferences.PrefKeys
import app.pachli.core.ui.BackgroundMessage
import app.pachli.databinding.ActivityAnnouncementsBinding import app.pachli.databinding.ActivityAnnouncementsBinding
import app.pachli.util.Error import app.pachli.util.Error
import app.pachli.util.Loading import app.pachli.util.Loading
@ -109,7 +110,7 @@ class AnnouncementsActivity :
binding.progressBar.hide() binding.progressBar.hide()
binding.swipeRefreshLayout.isRefreshing = false binding.swipeRefreshLayout.isRefreshing = false
if (it.data.isNullOrEmpty()) { if (it.data.isNullOrEmpty()) {
binding.errorMessageView.setup(app.pachli.core.ui.R.drawable.elephant_friend_empty, R.string.no_announcements) binding.errorMessageView.setup(BackgroundMessage.Empty(R.string.no_announcements))
binding.errorMessageView.show() binding.errorMessageView.show()
} else { } else {
binding.errorMessageView.hide() binding.errorMessageView.hide()
@ -122,7 +123,7 @@ class AnnouncementsActivity :
is Error -> { is Error -> {
binding.progressBar.hide() binding.progressBar.hide()
binding.swipeRefreshLayout.isRefreshing = false binding.swipeRefreshLayout.isRefreshing = false
binding.errorMessageView.setup(app.pachli.core.ui.R.drawable.errorphant_error, app.pachli.core.ui.R.string.error_generic) { binding.errorMessageView.setup(BackgroundMessage.GenericError()) {
refreshAnnouncements() refreshAnnouncements()
} }
binding.errorMessageView.show() binding.errorMessageView.show()

View File

@ -49,6 +49,7 @@ import app.pachli.core.network.model.Poll
import app.pachli.core.network.model.Status import app.pachli.core.network.model.Status
import app.pachli.core.preferences.PrefKeys import app.pachli.core.preferences.PrefKeys
import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.core.preferences.SharedPreferencesRepository
import app.pachli.core.ui.BackgroundMessage
import app.pachli.databinding.FragmentTimelineBinding import app.pachli.databinding.FragmentTimelineBinding
import app.pachli.fragment.SFragment import app.pachli.fragment.SFragment
import app.pachli.interfaces.ActionButtonActivity import app.pachli.interfaces.ActionButtonActivity
@ -126,11 +127,7 @@ class ConversationsFragment :
binding.swipeRefreshLayout.isRefreshing = false binding.swipeRefreshLayout.isRefreshing = false
if (loadState.append is LoadState.NotLoading && loadState.source.refresh is LoadState.NotLoading) { if (loadState.append is LoadState.NotLoading && loadState.source.refresh is LoadState.NotLoading) {
binding.statusView.show() binding.statusView.show()
binding.statusView.setup( binding.statusView.setup(BackgroundMessage.Empty())
app.pachli.core.ui.R.drawable.elephant_friend_empty,
app.pachli.core.ui.R.string.message_empty,
null,
)
} }
} }

View File

@ -30,6 +30,7 @@ import app.pachli.core.database.model.DraftEntity
import app.pachli.core.navigation.ComposeActivityIntent import app.pachli.core.navigation.ComposeActivityIntent
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
import app.pachli.core.network.parseAsMastodonHtml import app.pachli.core.network.parseAsMastodonHtml
import app.pachli.core.ui.BackgroundMessage
import app.pachli.databinding.ActivityDraftsBinding import app.pachli.databinding.ActivityDraftsBinding
import app.pachli.db.DraftsAlert import app.pachli.db.DraftsAlert
import at.connyduck.calladapter.networkresult.fold import at.connyduck.calladapter.networkresult.fold
@ -67,7 +68,7 @@ class DraftsActivity : BaseActivity(), DraftActionListener {
setDisplayShowHomeEnabled(true) setDisplayShowHomeEnabled(true)
} }
binding.draftsErrorMessageView.setup(app.pachli.core.ui.R.drawable.elephant_friend_empty, R.string.no_drafts) binding.draftsErrorMessageView.setup(BackgroundMessage.Empty(R.string.no_drafts))
val adapter = DraftsAdapter(this) val adapter = DraftsAdapter(this)

View File

@ -13,6 +13,7 @@ import app.pachli.core.common.extensions.visible
import app.pachli.core.designsystem.R as DR import app.pachli.core.designsystem.R as DR
import app.pachli.core.navigation.EditFilterActivityIntent import app.pachli.core.navigation.EditFilterActivityIntent
import app.pachli.core.network.model.Filter import app.pachli.core.network.model.Filter
import app.pachli.core.ui.BackgroundMessage
import app.pachli.databinding.ActivityFiltersBinding import app.pachli.databinding.ActivityFiltersBinding
import com.google.android.material.color.MaterialColors import com.google.android.material.color.MaterialColors
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@ -62,13 +63,13 @@ class FiltersActivity : BaseActivity(), FiltersListener {
when (state.loadingState) { when (state.loadingState) {
FiltersViewModel.LoadingState.INITIAL, FiltersViewModel.LoadingState.LOADING -> binding.messageView.hide() FiltersViewModel.LoadingState.INITIAL, FiltersViewModel.LoadingState.LOADING -> binding.messageView.hide()
FiltersViewModel.LoadingState.ERROR_NETWORK -> { FiltersViewModel.LoadingState.ERROR_NETWORK -> {
binding.messageView.setup(app.pachli.core.ui.R.drawable.errorphant_offline, app.pachli.core.ui.R.string.error_network) { binding.messageView.setup(BackgroundMessage.Network()) {
loadFilters() loadFilters()
} }
binding.messageView.show() binding.messageView.show()
} }
FiltersViewModel.LoadingState.ERROR_OTHER -> { FiltersViewModel.LoadingState.ERROR_OTHER -> {
binding.messageView.setup(app.pachli.core.ui.R.drawable.errorphant_error, app.pachli.core.ui.R.string.error_generic) { binding.messageView.setup(BackgroundMessage.GenericError()) {
loadFilters() loadFilters()
} }
binding.messageView.show() binding.messageView.show()
@ -76,11 +77,7 @@ class FiltersActivity : BaseActivity(), FiltersListener {
FiltersViewModel.LoadingState.LOADED -> { FiltersViewModel.LoadingState.LOADED -> {
binding.filtersList.adapter = FiltersAdapter(this@FiltersActivity, state.filters) binding.filtersList.adapter = FiltersAdapter(this@FiltersActivity, state.filters)
if (state.filters.isEmpty()) { if (state.filters.isEmpty()) {
binding.messageView.setup( binding.messageView.setup(BackgroundMessage.Empty())
app.pachli.core.ui.R.drawable.elephant_friend_empty,
app.pachli.core.ui.R.string.message_empty,
null,
)
binding.messageView.show() binding.messageView.show()
} else { } else {
binding.messageView.hide() binding.messageView.hide()

View File

@ -14,6 +14,7 @@ import app.pachli.core.common.extensions.show
import app.pachli.core.common.extensions.viewBinding import app.pachli.core.common.extensions.viewBinding
import app.pachli.core.network.model.HttpHeaderLink import app.pachli.core.network.model.HttpHeaderLink
import app.pachli.core.network.retrofit.MastodonApi import app.pachli.core.network.retrofit.MastodonApi
import app.pachli.core.ui.BackgroundMessage
import app.pachli.databinding.FragmentInstanceListBinding import app.pachli.databinding.FragmentInstanceListBinding
import app.pachli.view.EndlessOnScrollListener import app.pachli.view.EndlessOnScrollListener
import at.connyduck.calladapter.networkresult.fold import at.connyduck.calladapter.networkresult.fold
@ -123,11 +124,7 @@ class InstanceListFragment :
if (adapter.itemCount == 0) { if (adapter.itemCount == 0) {
binding.messageView.show() binding.messageView.show()
binding.messageView.setup( binding.messageView.setup(BackgroundMessage.Empty())
app.pachli.core.ui.R.drawable.elephant_friend_empty,
app.pachli.core.ui.R.string.message_empty,
null,
)
} else { } else {
binding.messageView.hide() binding.messageView.hide()
} }

View File

@ -56,6 +56,7 @@ import app.pachli.core.network.model.Filter
import app.pachli.core.network.model.Notification import app.pachli.core.network.model.Notification
import app.pachli.core.network.model.Poll import app.pachli.core.network.model.Poll
import app.pachli.core.network.model.Status import app.pachli.core.network.model.Status
import app.pachli.core.ui.BackgroundMessage
import app.pachli.databinding.FragmentTimelineNotificationsBinding import app.pachli.databinding.FragmentTimelineNotificationsBinding
import app.pachli.fragment.SFragment import app.pachli.fragment.SFragment
import app.pachli.interfaces.AccountActionListener import app.pachli.interfaces.AccountActionListener
@ -420,10 +421,7 @@ class NotificationsFragment :
binding.statusView.hide() binding.statusView.hide()
if (loadState.refresh is LoadState.NotLoading) { if (loadState.refresh is LoadState.NotLoading) {
if (adapter.itemCount == 0) { if (adapter.itemCount == 0) {
binding.statusView.setup( binding.statusView.setup(BackgroundMessage.Empty())
app.pachli.core.ui.R.drawable.elephant_friend_empty,
app.pachli.core.ui.R.string.message_empty,
)
binding.recyclerView.hide() binding.recyclerView.hide()
binding.statusView.show() binding.statusView.show()
} else { } else {

View File

@ -36,6 +36,7 @@ import app.pachli.core.common.extensions.viewBinding
import app.pachli.core.navigation.ComposeActivityIntent import app.pachli.core.navigation.ComposeActivityIntent
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
import app.pachli.core.network.model.ScheduledStatus import app.pachli.core.network.model.ScheduledStatus
import app.pachli.core.ui.BackgroundMessage
import app.pachli.databinding.ActivityScheduledStatusBinding import app.pachli.databinding.ActivityScheduledStatusBinding
import com.google.android.material.color.MaterialColors import com.google.android.material.color.MaterialColors
import com.google.android.material.divider.MaterialDividerItemDecoration import com.google.android.material.divider.MaterialDividerItemDecoration
@ -107,7 +108,7 @@ class ScheduledStatusActivity :
if (loadState.refresh is LoadState.NotLoading) { if (loadState.refresh is LoadState.NotLoading) {
binding.progressBar.hide() binding.progressBar.hide()
if (adapter.itemCount == 0) { if (adapter.itemCount == 0) {
binding.errorMessageView.setup(app.pachli.core.ui.R.drawable.elephant_friend_empty, R.string.no_scheduled_posts) binding.errorMessageView.setup(BackgroundMessage.Empty(R.string.no_scheduled_posts))
binding.errorMessageView.show() binding.errorMessageView.show()
} else { } else {
binding.errorMessageView.hide() binding.errorMessageView.hide()

View File

@ -60,7 +60,7 @@ import app.pachli.core.navigation.AttachmentViewData
import app.pachli.core.network.model.Poll import app.pachli.core.network.model.Poll
import app.pachli.core.network.model.Status import app.pachli.core.network.model.Status
import app.pachli.core.network.model.TimelineKind import app.pachli.core.network.model.TimelineKind
import app.pachli.core.ui.extensions.getDrawableRes import app.pachli.core.ui.BackgroundMessage
import app.pachli.core.ui.extensions.getErrorString import app.pachli.core.ui.extensions.getErrorString
import app.pachli.databinding.FragmentTimelineBinding import app.pachli.databinding.FragmentTimelineBinding
import app.pachli.fragment.SFragment import app.pachli.fragment.SFragment
@ -441,8 +441,7 @@ class TimelineFragment :
.setAction(app.pachli.core.ui.R.string.action_retry) { adapter.retry() } .setAction(app.pachli.core.ui.R.string.action_retry) { adapter.retry() }
snackbar!!.show() snackbar!!.show()
} else { } else {
val drawableRes = error.getDrawableRes() binding.statusView.setup(error) {
binding.statusView.setup(drawableRes, message) {
snackbar?.dismiss() snackbar?.dismiss()
adapter.retry() adapter.retry()
} }
@ -453,10 +452,7 @@ class TimelineFragment :
PresentationState.PRESENTED -> { PresentationState.PRESENTED -> {
if (adapter.itemCount == 0) { if (adapter.itemCount == 0) {
binding.statusView.setup( binding.statusView.setup(BackgroundMessage.Empty())
app.pachli.core.ui.R.drawable.elephant_friend_empty,
app.pachli.core.ui.R.string.message_empty,
)
if (timelineKind == TimelineKind.Home) { if (timelineKind == TimelineKind.Home) {
binding.statusView.showHelp(R.string.help_empty_home) binding.statusView.showHelp(R.string.help_empty_home)
} }

View File

@ -43,6 +43,7 @@ import app.pachli.core.common.extensions.hide
import app.pachli.core.common.extensions.show import app.pachli.core.common.extensions.show
import app.pachli.core.common.extensions.viewBinding import app.pachli.core.common.extensions.viewBinding
import app.pachli.core.designsystem.R as DR import app.pachli.core.designsystem.R as DR
import app.pachli.core.ui.BackgroundMessage
import app.pachli.databinding.FragmentTrendingLinksBinding import app.pachli.databinding.FragmentTrendingLinksBinding
import app.pachli.interfaces.ActionButtonActivity import app.pachli.interfaces.ActionButtonActivity
import app.pachli.interfaces.AppBarLayoutHost import app.pachli.interfaces.AppBarLayoutHost
@ -110,11 +111,7 @@ class TrendingLinksFragment :
binding.progressBar.hide() binding.progressBar.hide()
binding.swipeRefreshLayout.isRefreshing = false binding.swipeRefreshLayout.isRefreshing = false
if (it.data.isEmpty()) { if (it.data.isEmpty()) {
binding.messageView.setup( binding.messageView.setup(BackgroundMessage.Empty())
app.pachli.core.ui.R.drawable.elephant_friend_empty,
app.pachli.core.ui.R.string.message_empty,
null,
)
binding.messageView.show() binding.messageView.show()
} else { } else {
binding.messageView.hide() binding.messageView.hide()

View File

@ -44,6 +44,7 @@ import app.pachli.core.common.extensions.show
import app.pachli.core.common.extensions.viewBinding import app.pachli.core.common.extensions.viewBinding
import app.pachli.core.designsystem.R as DR import app.pachli.core.designsystem.R as DR
import app.pachli.core.navigation.StatusListActivityIntent import app.pachli.core.navigation.StatusListActivityIntent
import app.pachli.core.ui.BackgroundMessage
import app.pachli.databinding.FragmentTrendingTagsBinding import app.pachli.databinding.FragmentTrendingTagsBinding
import app.pachli.interfaces.ActionButtonActivity import app.pachli.interfaces.ActionButtonActivity
import app.pachli.interfaces.AppBarLayoutHost import app.pachli.interfaces.AppBarLayoutHost
@ -199,11 +200,7 @@ class TrendingTagsFragment :
if (viewData.isEmpty()) { if (viewData.isEmpty()) {
binding.recyclerView.hide() binding.recyclerView.hide()
binding.messageView.show() binding.messageView.show()
binding.messageView.setup( binding.messageView.setup(BackgroundMessage.Empty())
app.pachli.core.ui.R.drawable.elephant_friend_empty,
app.pachli.core.ui.R.string.message_empty,
null,
)
} else { } else {
binding.recyclerView.show() binding.recyclerView.show()
binding.messageView.hide() binding.messageView.hide()
@ -233,10 +230,7 @@ class TrendingTagsFragment :
binding.progressBar.hide() binding.progressBar.hide()
binding.swipeRefreshLayout.isRefreshing = false binding.swipeRefreshLayout.isRefreshing = false
binding.messageView.setup( binding.messageView.setup(BackgroundMessage.Network()) { refreshContent() }
app.pachli.core.ui.R.drawable.errorphant_offline,
app.pachli.core.ui.R.string.error_network,
) { refreshContent() }
} }
private fun otherError() { private fun otherError() {
@ -245,10 +239,7 @@ class TrendingTagsFragment :
binding.progressBar.hide() binding.progressBar.hide()
binding.swipeRefreshLayout.isRefreshing = false binding.swipeRefreshLayout.isRefreshing = false
binding.messageView.setup( binding.messageView.setup(BackgroundMessage.GenericError()) { refreshContent() }
app.pachli.core.ui.R.drawable.errorphant_error,
app.pachli.core.ui.R.string.error_generic,
) { refreshContent() }
} }
private fun actionButtonPresent(): Boolean { private fun actionButtonPresent(): Boolean {

View File

@ -42,6 +42,7 @@ import app.pachli.core.navigation.AccountActivityIntent
import app.pachli.core.navigation.StatusListActivityIntent import app.pachli.core.navigation.StatusListActivityIntent
import app.pachli.core.preferences.PrefKeys import app.pachli.core.preferences.PrefKeys
import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.core.preferences.SharedPreferencesRepository
import app.pachli.core.ui.BackgroundMessage
import app.pachli.databinding.FragmentViewEditsBinding import app.pachli.databinding.FragmentViewEditsBinding
import app.pachli.interfaces.LinkListener import app.pachli.interfaces.LinkListener
import com.google.android.material.color.MaterialColors import com.google.android.material.color.MaterialColors
@ -112,10 +113,7 @@ class ViewEditsFragment :
when (uiState.throwable) { when (uiState.throwable) {
is ViewEditsViewModel.MissingEditsException -> { is ViewEditsViewModel.MissingEditsException -> {
binding.statusView.setup( binding.statusView.setup(BackgroundMessage.Empty(R.string.error_missing_edits))
app.pachli.core.ui.R.drawable.elephant_friend_empty,
R.string.error_missing_edits,
)
} }
else -> { else -> {
binding.statusView.setup(uiState.throwable) { binding.statusView.setup(uiState.throwable) {

View File

@ -40,6 +40,41 @@ import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import java.util.regex.Pattern import java.util.regex.Pattern
/** Kinds of message that can be shown */
sealed interface BackgroundMessage {
@get:DrawableRes val drawableRes: Int
@get:StringRes val stringRes: Int
/**
* Generic "Nothing here" message and image, for use when a collection has
* no items.
*
* @param stringRes Alternative string resource to use as the message
*/
data class Empty(override val stringRes: Int = R.string.message_empty) : BackgroundMessage {
override val drawableRes: Int = R.drawable.elephant_friend_empty
}
/**
* Generic "An error occurred" message and image
*
* @param stringRes Alternative string resource to use as the message
*/
data class GenericError(override val stringRes: Int = R.string.error_generic) : BackgroundMessage {
override val drawableRes: Int = R.drawable.errorphant_error
}
/**
* Generic "A network error occurred" message and image
*
* @param stringRes Alternative string resource to use as the message
*/
data class Network(override val stringRes: Int = R.string.error_network) : BackgroundMessage {
override val drawableRes: Int = R.drawable.errorphant_offline
}
}
/** /**
* This view is used for screens with content which may be empty or might have failed to download. * This view is used for screens with content which may be empty or might have failed to download.
*/ */
@ -56,7 +91,7 @@ class BackgroundMessageView @JvmOverloads constructor(
orientation = VERTICAL orientation = VERTICAL
if (isInEditMode) { if (isInEditMode) {
setup(app.pachli.core.ui.R.drawable.errorphant_offline, app.pachli.core.ui.R.string.error_network) {} setup(BackgroundMessage.Network())
} }
} }
@ -64,7 +99,11 @@ class BackgroundMessageView @JvmOverloads constructor(
setup(throwable.getDrawableRes(), throwable.getErrorString(context), listener) setup(throwable.getDrawableRes(), throwable.getErrorString(context), listener)
} }
fun setup( fun setup(message: BackgroundMessage, listener: ((v: View) -> Unit)? = null) {
setup(message.drawableRes, message.stringRes, listener)
}
private fun setup(
@DrawableRes imageRes: Int, @DrawableRes imageRes: Int,
@StringRes messageRes: Int, @StringRes messageRes: Int,
clickListener: ((v: View) -> Unit)? = null, clickListener: ((v: View) -> Unit)? = null,
@ -74,7 +113,7 @@ class BackgroundMessageView @JvmOverloads constructor(
* Setup image, message and button. * Setup image, message and button.
* If [clickListener] is `null` then the button will be hidden. * If [clickListener] is `null` then the button will be hidden.
*/ */
fun setup( private fun setup(
@DrawableRes imageRes: Int, @DrawableRes imageRes: Int,
message: String, message: String,
clickListener: ((v: View) -> Unit)? = null, clickListener: ((v: View) -> Unit)? = null,

View File

@ -25,20 +25,20 @@ import retrofit2.HttpException
/** @return A drawable resource to accompany the error message for this throwable */ /** @return A drawable resource to accompany the error message for this throwable */
fun Throwable.getDrawableRes(): Int = when (this) { fun Throwable.getDrawableRes(): Int = when (this) {
is IOException -> app.pachli.core.ui.R.drawable.errorphant_offline is IOException -> R.drawable.errorphant_offline
is HttpException -> { is HttpException -> {
if (this.code() == 404) { if (this.code() == 404) {
app.pachli.core.ui.R.drawable.elephant_friend_empty R.drawable.elephant_friend_empty
} else { } else {
app.pachli.core.ui.R.drawable.errorphant_offline R.drawable.errorphant_offline
} }
} }
else -> app.pachli.core.ui.R.drawable.errorphant_error else -> R.drawable.errorphant_error
} }
/** @return A string error message for this throwable */ /** @return A string error message for this throwable */
fun Throwable.getErrorString(context: Context): String = getServerErrorMessage() ?: when (this) { fun Throwable.getErrorString(context: Context): String = getServerErrorMessage() ?: when (this) {
is IOException -> context.getString(app.pachli.core.ui.R.string.error_network_fmt, this.message) is IOException -> context.getString(R.string.error_network_fmt, this.message)
is HttpException -> if (this.code() == 404) context.getString(R.string.error_404_not_found_fmt, this.message) else context.getString(R.string.error_generic_fmt, this.message) is HttpException -> if (this.code() == 404) context.getString(R.string.error_404_not_found_fmt, this.message) else context.getString(R.string.error_generic_fmt, this.message)
else -> context.getString(R.string.error_generic_fmt, this.message) else -> context.getString(R.string.error_generic_fmt, this.message)
} }

View File

@ -202,7 +202,7 @@ class AccountsInListFragment : DialogFragment() {
private fun handleError(error: Throwable) { private fun handleError(error: Throwable) {
binding.messageView.show() binding.messageView.show()
binding.messageView.setup(error) { _: View -> binding.messageView.setup(error) {
binding.messageView.hide() binding.messageView.hide()
viewModel.refresh() viewModel.refresh()
} }

View File

@ -49,6 +49,7 @@ import app.pachli.core.network.model.MastoList
import app.pachli.core.network.model.UserListRepliesPolicy import app.pachli.core.network.model.UserListRepliesPolicy
import app.pachli.core.network.retrofit.apiresult.ApiError import app.pachli.core.network.retrofit.apiresult.ApiError
import app.pachli.core.network.retrofit.apiresult.NetworkError import app.pachli.core.network.retrofit.apiresult.NetworkError
import app.pachli.core.ui.BackgroundMessage
import app.pachli.core.ui.extensions.await import app.pachli.core.ui.extensions.await
import app.pachli.feature.lists.databinding.ActivityListsBinding import app.pachli.feature.lists.databinding.ActivityListsBinding
import app.pachli.feature.lists.databinding.DialogListBinding import app.pachli.feature.lists.databinding.DialogListBinding
@ -205,13 +206,9 @@ class ListsActivity : BaseActivity(), MenuProvider {
binding.swipeRefreshLayout.isRefreshing = false binding.swipeRefreshLayout.isRefreshing = false
if (it is NetworkError) { if (it is NetworkError) {
binding.messageView.setup(app.pachli.core.ui.R.drawable.errorphant_offline, app.pachli.core.ui.R.string.error_network) { binding.messageView.setup(BackgroundMessage.Network()) { viewModel.refresh() }
viewModel.refresh()
}
} else { } else {
binding.messageView.setup(app.pachli.core.ui.R.drawable.errorphant_error, app.pachli.core.ui.R.string.error_generic) { binding.messageView.setup(BackgroundMessage.GenericError()) { viewModel.refresh() }
viewModel.refresh()
}
} }
} }
@ -222,11 +219,7 @@ class ListsActivity : BaseActivity(), MenuProvider {
binding.swipeRefreshLayout.isRefreshing = false binding.swipeRefreshLayout.isRefreshing = false
if (lists.lists.isEmpty()) { if (lists.lists.isEmpty()) {
binding.messageView.show() binding.messageView.show()
binding.messageView.setup( binding.messageView.setup(BackgroundMessage.Empty())
app.pachli.core.ui.R.drawable.elephant_friend_empty,
app.pachli.core.ui.R.string.message_empty,
null,
)
} else { } else {
binding.messageView.hide() binding.messageView.hide()
} }

View File

@ -33,6 +33,7 @@ import app.pachli.core.common.extensions.show
import app.pachli.core.common.extensions.viewBinding import app.pachli.core.common.extensions.viewBinding
import app.pachli.core.common.extensions.visible import app.pachli.core.common.extensions.visible
import app.pachli.core.designsystem.R as DR import app.pachli.core.designsystem.R as DR
import app.pachli.core.ui.BackgroundMessage
import app.pachli.core.ui.BindingHolder import app.pachli.core.ui.BindingHolder
import app.pachli.feature.lists.ListsForAccountViewModel.Error import app.pachli.feature.lists.ListsForAccountViewModel.Error
import app.pachli.feature.lists.ListsForAccountViewModel.FlowError import app.pachli.feature.lists.ListsForAccountViewModel.FlowError
@ -140,9 +141,7 @@ class ListsForAccountFragment : DialogFragment() {
binding.progressBar.hide() binding.progressBar.hide()
if (it.listsWithMembership.isEmpty()) { if (it.listsWithMembership.isEmpty()) {
binding.messageView.show() binding.messageView.show()
binding.messageView.setup(app.pachli.core.ui.R.drawable.elephant_friend_empty, R.string.no_lists) { binding.messageView.setup(BackgroundMessage.Empty(R.string.no_lists)) { load() }
load()
}
} else { } else {
binding.listsView.show() binding.listsView.show()
adapter.submitList(it.listsWithMembership.values.toList()) adapter.submitList(it.listsWithMembership.values.toList())