From 0d0c4e403845fa3f2ebfcc1aba0bd01169a7b846 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 27 Jun 2022 15:23:00 +0200 Subject: [PATCH] Various minor improvements --- .../baseline_error_outline_black_36dp.png | Bin 746 -> 0 bytes .../baseline_error_outline_black_36dp.png | Bin 499 -> 0 bytes .../baseline_error_outline_black_36dp.png | Bin 954 -> 0 bytes .../baseline_error_outline_black_36dp.png | Bin 1790 -> 0 bytes .../baseline_error_outline_black_36dp.png | Bin 2631 -> 0 bytes Habitica/res/values/dimens.xml | 3 +- Habitica/res/values/strings.xml | 3 - .../ui/activities/FullProfileActivity.kt | 2 +- .../equipment/EquipmentDetailFragment.kt | 2 +- .../inventory/items/ItemDialogFragment.kt | 2 +- .../inventory/items/ItemRecyclerFragment.kt | 2 +- .../fragments/inventory/shops/ShopFragment.kt | 2 +- .../stable/StableRecyclerFragment.kt | 2 +- .../challenges/ChallengeListFragment.kt | 2 +- .../social/guilds/GuildListFragment.kt | 2 +- .../tasks/TaskRecyclerViewFragment.kt | 2 +- .../ui/helpers/RecyclerViewEmptySupport.kt | 133 +++--------------- .../extensions/ViewGroup-Extensions.kt | 0 .../helpers/RecyclerViewEmptySupport.kt | 118 ++++++++++++++++ .../res/drawable-anydpi/failed_loading.xml | 16 +++ .../main/res/drawable-hdpi/failed_loading.png | Bin 0 -> 577 bytes .../main/res/drawable-mdpi/failed_loading.png | Bin 0 -> 424 bytes .../res/drawable-xhdpi/failed_loading.png | Bin 0 -> 904 bytes .../res/drawable-xxhdpi/failed_loading.png | Bin 0 -> 1312 bytes .../src/main}/res/layout/empty_item.xml | 3 +- .../src/main}/res/layout/failed_item.xml | 9 +- .../src/main}/res/layout/loading_item.xml | 0 common/src/main/res/values/dimens.xml | 3 + common/src/main/res/values/strings.xml | 5 + .../data/repositories/TaskLocalRepository.kt | 24 +++- .../data/repositories/TaskRepository.kt | 1 + .../wearos/habitica/models/user/MenuItem.kt | 1 + .../habitica/ui/activities/MainActivity.kt | 26 ++-- .../ui/activities/TaskListActivity.kt | 17 ++- .../habitica/ui/viewHolders/HubViewHolder.kt | 2 + .../habitica/ui/viewmodels/MainViewModel.kt | 2 +- .../ui/viewmodels/TaskListViewModel.kt | 5 + .../wearos/habitica/ui/views/AddTaskButton.kt | 32 +++-- .../habitica/ui/views/HabiticaRecyclerView.kt | 72 +++++++++- wearos/src/main/res/layout/activity_rya.xml | 6 +- .../src/main/res/layout/activity_tasklist.xml | 2 +- wearos/src/main/res/layout/row_hub.xml | 3 +- wearos/src/main/res/values/strings.xml | 1 + 43 files changed, 340 insertions(+), 165 deletions(-) delete mode 100644 Habitica/res/drawable-hdpi/baseline_error_outline_black_36dp.png delete mode 100644 Habitica/res/drawable-mdpi/baseline_error_outline_black_36dp.png delete mode 100644 Habitica/res/drawable-xhdpi/baseline_error_outline_black_36dp.png delete mode 100644 Habitica/res/drawable-xxhdpi/baseline_error_outline_black_36dp.png delete mode 100644 Habitica/res/drawable-xxxhdpi/baseline_error_outline_black_36dp.png rename {Habitica/src/main/java/com/habitrpg/android => common/src/main/java/com/habitrpg/common}/habitica/extensions/ViewGroup-Extensions.kt (100%) create mode 100644 common/src/main/java/com/habitrpg/common/habitica/helpers/RecyclerViewEmptySupport.kt create mode 100644 common/src/main/res/drawable-anydpi/failed_loading.xml create mode 100644 common/src/main/res/drawable-hdpi/failed_loading.png create mode 100644 common/src/main/res/drawable-mdpi/failed_loading.png create mode 100644 common/src/main/res/drawable-xhdpi/failed_loading.png create mode 100644 common/src/main/res/drawable-xxhdpi/failed_loading.png rename {Habitica => common/src/main}/res/layout/empty_item.xml (95%) rename {Habitica => common/src/main}/res/layout/failed_item.xml (76%) rename {Habitica => common/src/main}/res/layout/loading_item.xml (100%) diff --git a/Habitica/res/drawable-hdpi/baseline_error_outline_black_36dp.png b/Habitica/res/drawable-hdpi/baseline_error_outline_black_36dp.png deleted file mode 100644 index ec4860d026be38f31181fb3ea2a482f16834ed85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 746 zcmVG0rXAX3E}1^c2RK*nOy{);>^D7? z52&`DnD**FankfzK8RTBriWVGqQP`Pi$sC=n>PN34Yq0jSf5NMv}DeizR3^X>9OgQ z^418p^r3I+uhUo4*{(xvnA8vXLD4fUuH;l;4FxJp*c_B8+fr{dTyu;iz736);mIGs^KHe)Y`);r%?~II%sjvGzixFO^-zGq{n1tmv84Wpd6YZy z9XW9-CCK}utrTKO{Sosh%}%V@Td{WXm|NYa1o`+TC6C(azBa|_zV-vUHpCLgHu(V! zHA||R%qpp%W)WO-jm<8Co87iRlN(J~lMkqgqk(1*bD+uNw~i(cOrhB$ZfNqQL`Rda zkvf>%(3R`N19aQH`0LV)k zSs62%s(Tq8FjjY}br}Pc=TL?RAh|Qunrcxs--tH9(dSR#U3DNoC?m;SNH^%CYD+ca z*oD9bTYTIY=aQL}zcQCnuR<#L;OoX>rIOf?dWkK-iPS5W3%h$*6BgD(Cr?AM9iLcAH*W2*>ffI!YrPpb=dB9e@jY2Kuoje zp6XluuN&BmDO=2GN==BE?v~(255nWX3{Snj5UB|PvCW4ugAAlKT=n`wJm{`@n@ prI-&zm!dwUT_|G_e>O}gf=~SVAB2U+kQ4v_002ovPDHLkV1jk2=;Z(a diff --git a/Habitica/res/drawable-xhdpi/baseline_error_outline_black_36dp.png b/Habitica/res/drawable-xhdpi/baseline_error_outline_black_36dp.png deleted file mode 100644 index 356880514a609db407c37d792989adeb8cacbcde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 954 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 diff --git a/Habitica/res/values/dimens.xml b/Habitica/res/values/dimens.xml index 9b3247235..ad847cc41 100644 --- a/Habitica/res/values/dimens.xml +++ b/Habitica/res/values/dimens.xml @@ -4,8 +4,7 @@ 16dp 8dp - 18.0sp - 14.0sp + 12dp 6dp 6dp diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index aec444b80..8314dbe93 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -270,7 +270,6 @@ • Bosses won’t do damage for your missed Dailies\n • Your boss damage or collection quest items will stay pending until check-out You don\'t have any %s - Lvl %d Lvl %1$d %2$s Level %1$d %2$s Warrior @@ -1138,9 +1137,7 @@ You must purchase the previous items in this sequence to unlock You caused damage to the boss Style - Failed to load Daily Checkbox - Retry Nothing here yet You don\'t have any equipment of this type yet. You can purchase equipment from the market using the gold you earned. Todo Checkbox diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt index 3bdd27755..a715cabf1 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt @@ -31,7 +31,7 @@ import com.habitrpg.android.habitica.models.user.Outfit import com.habitrpg.android.habitica.models.user.Stats import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel import com.habitrpg.android.habitica.ui.adapter.social.AchievementProfileAdapter -import com.habitrpg.android.habitica.ui.helpers.RecyclerViewState +import com.habitrpg.common.habitica.helpers.RecyclerViewState import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.SnackbarDisplayType import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentDetailFragment.kt index 597073473..68275bca6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentDetailFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentDetailFragment.kt @@ -15,7 +15,7 @@ import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.ui.adapter.inventory.EquipmentRecyclerViewAdapter import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment -import com.habitrpg.android.habitica.ui.helpers.EmptyItem +import com.habitrpg.common.habitica.helpers.EmptyItem import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator import javax.inject.Inject diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt index 24bfc8ab3..985f5f2bc 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt @@ -31,7 +31,7 @@ import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.ui.activities.MainActivity import com.habitrpg.android.habitica.ui.adapter.inventory.ItemRecyclerAdapter import com.habitrpg.android.habitica.ui.fragments.BaseDialogFragment -import com.habitrpg.android.habitica.ui.helpers.EmptyItem +import com.habitrpg.common.habitica.helpers.EmptyItem import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt index 5e7186238..47c5353d1 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt @@ -37,7 +37,7 @@ import com.habitrpg.android.habitica.ui.activities.MainActivity import com.habitrpg.android.habitica.ui.activities.SkillMemberActivity import com.habitrpg.android.habitica.ui.adapter.inventory.ItemRecyclerAdapter import com.habitrpg.android.habitica.ui.fragments.BaseFragment -import com.habitrpg.android.habitica.ui.helpers.EmptyItem +import com.habitrpg.common.habitica.helpers.EmptyItem import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt index e1d66a087..1741c70dd 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt @@ -21,7 +21,7 @@ import com.habitrpg.android.habitica.models.social.Group import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.ui.adapter.inventory.ShopRecyclerAdapter import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment -import com.habitrpg.android.habitica.ui.helpers.RecyclerViewState +import com.habitrpg.common.habitica.helpers.RecyclerViewState import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.CurrencyViews diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt index c3a1a63d8..5433ec79a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt @@ -19,7 +19,7 @@ import com.habitrpg.android.habitica.models.inventory.Egg import com.habitrpg.android.habitica.models.inventory.HatchingPotion import com.habitrpg.android.habitica.ui.adapter.inventory.StableRecyclerAdapter import com.habitrpg.android.habitica.ui.fragments.BaseFragment -import com.habitrpg.android.habitica.ui.helpers.EmptyItem +import com.habitrpg.common.habitica.helpers.EmptyItem import com.habitrpg.android.habitica.ui.helpers.MarginDecoration import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt index caa1844ca..a85a6e613 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt @@ -18,7 +18,7 @@ import com.habitrpg.android.habitica.models.social.Group import com.habitrpg.android.habitica.modules.AppModule import com.habitrpg.android.habitica.ui.adapter.social.ChallengesListViewAdapter import com.habitrpg.android.habitica.ui.fragments.BaseFragment -import com.habitrpg.android.habitica.ui.helpers.EmptyItem +import com.habitrpg.common.habitica.helpers.EmptyItem import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.kotlin.Flowables diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildListFragment.kt index 774ece179..7b090ab0a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildListFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildListFragment.kt @@ -13,7 +13,7 @@ import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBind import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.ui.adapter.social.GuildListAdapter import com.habitrpg.android.habitica.ui.fragments.BaseFragment -import com.habitrpg.android.habitica.ui.helpers.EmptyItem +import com.habitrpg.common.habitica.helpers.EmptyItem import com.habitrpg.android.habitica.ui.helpers.KeyboardUtil import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator import javax.inject.Inject diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt index 4626b579b..80033e1a9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt @@ -38,7 +38,7 @@ import com.habitrpg.android.habitica.ui.adapter.tasks.RewardsRecyclerViewAdapter import com.habitrpg.android.habitica.ui.adapter.tasks.TaskRecyclerViewAdapter import com.habitrpg.android.habitica.ui.adapter.tasks.TodosRecyclerViewAdapter import com.habitrpg.android.habitica.ui.fragments.BaseFragment -import com.habitrpg.android.habitica.ui.helpers.EmptyItem +import com.habitrpg.common.habitica.helpers.EmptyItem import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator import com.habitrpg.android.habitica.ui.viewHolders.tasks.BaseTaskViewHolder import com.habitrpg.android.habitica.ui.viewmodels.TasksViewModel diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/RecyclerViewEmptySupport.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/RecyclerViewEmptySupport.kt index e2ad593c6..9d95f282b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/RecyclerViewEmptySupport.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/RecyclerViewEmptySupport.kt @@ -2,34 +2,18 @@ package com.habitrpg.android.habitica.ui.helpers import android.content.Context import android.util.AttributeSet -import android.view.View -import android.view.ViewGroup -import android.view.animation.AlphaAnimation -import android.widget.ProgressBar -import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView -import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.databinding.EmptyItemBinding -import com.habitrpg.android.habitica.databinding.FailedItemBinding -import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.common.habitica.helpers.EmptyItem +import com.habitrpg.common.habitica.helpers.RecyclerViewState +import com.habitrpg.common.habitica.helpers.RecyclerViewStateAdapter -data class EmptyItem( - var title: String, - var text: String? = null, - var iconResource: Int? = null, - var buttonLabel: String? = null, - var onButtonTap: (() -> Unit)? = null -) +class RecyclerViewEmptySupport @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null +) : RecyclerView(context, attrs) { + var onRefresh: (() -> Unit)? + get() = emptyAdapter.onRefresh + set(value) { emptyAdapter.onRefresh = value } -enum class RecyclerViewState { - LOADING, - EMPTY, - DISPLAYING_DATA, - FAILED -} - -class RecyclerViewEmptySupport : RecyclerView { - var onRefresh: (() -> Unit)? = null var state: RecyclerViewState = RecyclerViewState.LOADING set(value) { field = value @@ -37,7 +21,7 @@ class RecyclerViewEmptySupport : RecyclerView { RecyclerViewState.DISPLAYING_DATA -> updateAdapter(actualAdapter) else -> { updateAdapter(emptyAdapter) - emptyAdapter.notifyDataSetChanged() + emptyAdapter.state = value } } } @@ -48,53 +32,16 @@ class RecyclerViewEmptySupport : RecyclerView { } } - var emptyItem: EmptyItem? = null + var emptyItem: EmptyItem? + get() = emptyAdapter.emptyItem set(value) { - field = value - emptyAdapter.notifyDataSetChanged() + emptyAdapter.emptyItem = value } private var actualAdapter: Adapter<*>? = null - private val emptyAdapter: Adapter = object : Adapter() { - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - return when (viewType) { - 0 -> { - val view = parent.inflate(R.layout.loading_item) - val animation1 = AlphaAnimation(0.0f, 1.0f) - animation1.duration = 300 - animation1.startOffset = 500 - animation1.fillAfter = true - view.findViewById(R.id.loading_indicator).startAnimation(animation1) - object : ViewHolder(view) {} - } - 1 -> FailedViewHolder(parent.inflate(R.layout.failed_item)) - else -> EmptyViewHolder(parent.inflate(R.layout.empty_item)) - } - } + private val emptyAdapter = RecyclerViewStateAdapter() - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - if (holder is EmptyViewHolder) { - holder.bind(emptyItem) - } else if (holder is FailedViewHolder) { - holder.bind(onRefresh) - } - (holder as? EmptyViewHolder)?.bind(emptyItem) - } - - override fun getItemCount(): Int { - return 1 - } - - override fun getItemViewType(position: Int): Int { - return when (state) { - RecyclerViewState.LOADING -> 0 - RecyclerViewState.FAILED -> 1 - else -> 2 - } - } - } - - private val observer = object : RecyclerView.AdapterDataObserver() { + private val observer = object : AdapterDataObserver() { override fun onChanged() { updateState() } @@ -108,22 +55,16 @@ class RecyclerViewEmptySupport : RecyclerView { } } - constructor(context: Context) : super(context) - - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) - - constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) - internal fun updateState(isInitial: Boolean = false) { - if (actualAdapter != null && !isInitial) { + state = if (actualAdapter != null && !isInitial) { val emptyViewVisible = actualAdapter?.itemCount == 0 if (emptyViewVisible) { - state = RecyclerViewState.EMPTY + RecyclerViewState.EMPTY } else { - state = RecyclerViewState.DISPLAYING_DATA + RecyclerViewState.DISPLAYING_DATA } } else { - state = RecyclerViewState.LOADING + RecyclerViewState.LOADING } } @@ -135,38 +76,4 @@ class RecyclerViewEmptySupport : RecyclerView { actualAdapter = adapter updateState(true) } -} - -class FailedViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - private val binding = FailedItemBinding.bind(itemView) - - fun bind(onRefresh: (() -> Unit)?) { - if (onRefresh != null) { - binding.refreshButton.visibility = View.VISIBLE - binding.refreshButton.setOnClickListener { onRefresh() } - } else { - binding.refreshButton.visibility = View.GONE - } - } -} - -class EmptyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - - private val binding = EmptyItemBinding.bind(itemView) - - fun bind(emptyItem: EmptyItem?) { - binding.emptyIconView.setColorFilter(ContextCompat.getColor(itemView.context, R.color.text_dimmed), android.graphics.PorterDuff.Mode.MULTIPLY) - emptyItem?.iconResource?.let { binding.emptyIconView.setImageResource(it) } - binding.emptyViewTitle.text = emptyItem?.title - binding.emptyViewDescription.text = emptyItem?.text - - val buttonLabel = emptyItem?.buttonLabel - if (buttonLabel != null) { - binding.button.visibility = View.VISIBLE - binding.button.text = buttonLabel - binding.button.setOnClickListener { emptyItem.onButtonTap?.invoke() } - } else { - binding.button.visibility = View.GONE - } - } -} +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ViewGroup-Extensions.kt b/common/src/main/java/com/habitrpg/common/habitica/extensions/ViewGroup-Extensions.kt similarity index 100% rename from Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ViewGroup-Extensions.kt rename to common/src/main/java/com/habitrpg/common/habitica/extensions/ViewGroup-Extensions.kt diff --git a/common/src/main/java/com/habitrpg/common/habitica/helpers/RecyclerViewEmptySupport.kt b/common/src/main/java/com/habitrpg/common/habitica/helpers/RecyclerViewEmptySupport.kt new file mode 100644 index 000000000..e88db2736 --- /dev/null +++ b/common/src/main/java/com/habitrpg/common/habitica/helpers/RecyclerViewEmptySupport.kt @@ -0,0 +1,118 @@ +package com.habitrpg.common.habitica.helpers + +import android.view.View +import android.view.ViewGroup +import android.view.animation.AlphaAnimation +import android.widget.ProgressBar +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.common.habitica.R +import com.habitrpg.common.habitica.databinding.EmptyItemBinding +import com.habitrpg.common.habitica.databinding.FailedItemBinding + +data class EmptyItem( + var title: String, + var text: String? = null, + var iconResource: Int? = null, + var buttonLabel: String? = null, + var onButtonTap: (() -> Unit)? = null +) + +enum class RecyclerViewState { + LOADING, + EMPTY, + DISPLAYING_DATA, + FAILED +} + +class FailedViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + private val binding = FailedItemBinding.bind(itemView) + + fun bind(onRefresh: (() -> Unit)?) { + if (onRefresh != null) { + binding.refreshButton.visibility = View.VISIBLE + binding.refreshButton.setOnClickListener { onRefresh() } + } else { + binding.refreshButton.visibility = View.GONE + } + } +} + +class EmptyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + + private val binding = EmptyItemBinding.bind(itemView) + + fun bind(emptyItem: EmptyItem?) { + binding.emptyIconView.setColorFilter( + ContextCompat.getColor( + itemView.context, + R.color.text_dimmed + ), android.graphics.PorterDuff.Mode.MULTIPLY) + emptyItem?.iconResource?.let { binding.emptyIconView.setImageResource(it) } + binding.emptyViewTitle.text = emptyItem?.title + binding.emptyViewDescription.text = emptyItem?.text + + val buttonLabel = emptyItem?.buttonLabel + if (buttonLabel != null) { + binding.button.visibility = View.VISIBLE + binding.button.text = buttonLabel + binding.button.setOnClickListener { emptyItem.onButtonTap?.invoke() } + } else { + binding.button.visibility = View.GONE + } + } +} + +class RecyclerViewStateAdapter(val showLoadingAsEmpty: Boolean = false) : RecyclerView.Adapter() { + var onRefresh: (() -> Unit)? = null + var emptyItem: EmptyItem? = null + set(value) { + field = value + notifyItemChanged(0) + } + + var state: RecyclerViewState = RecyclerViewState.LOADING + set(value) { + field = value + notifyItemChanged(0) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + return when (viewType) { + 0 -> { + val view = parent.inflate(R.layout.loading_item) + val animation1 = AlphaAnimation(0.0f, 1.0f) + animation1.duration = 300 + animation1.startOffset = 500 + animation1.fillAfter = true + view.findViewById(R.id.loading_indicator).startAnimation(animation1) + object : RecyclerView.ViewHolder(view) {} + } + 1 -> FailedViewHolder(parent.inflate(R.layout.failed_item)) + else -> EmptyViewHolder(parent.inflate(R.layout.empty_item)) + } + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + if (holder is EmptyViewHolder) { + holder.bind(emptyItem) + } else if (holder is FailedViewHolder) { + holder.bind(onRefresh) + } + (holder as? EmptyViewHolder)?.bind(emptyItem) + } + + override fun getItemCount(): Int { + return 1 + } + + override fun getItemViewType(position: Int): Int { + return when { + state == RecyclerViewState.LOADING && !showLoadingAsEmpty -> 0 + state == RecyclerViewState.FAILED -> 1 + else -> 2 + } + } +} + diff --git a/common/src/main/res/drawable-anydpi/failed_loading.xml b/common/src/main/res/drawable-anydpi/failed_loading.xml new file mode 100644 index 000000000..a2abd198b --- /dev/null +++ b/common/src/main/res/drawable-anydpi/failed_loading.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/common/src/main/res/drawable-hdpi/failed_loading.png b/common/src/main/res/drawable-hdpi/failed_loading.png new file mode 100644 index 0000000000000000000000000000000000000000..92a4bc43bd500f85765e844c5e92bbb7f14997e6 GIT binary patch literal 577 zcmV-H0>1r;P))@TRlPO2YK?(8So@h8{z-Mu@ArKcCk7{YGX z2oc!_9s@rDZ-I}%ZzW#i8rBfA=lsnO#3wDb6t5+6Cf4gl5Ib}lVM61;`b`J|Z;o(G zjOZSCRpNC#LXWRpXB9H#Q9%`(c z62CJij%x)p9NinoB@nx3zNDioIY3J_;~E!^dqRWx4mLBhpt_FOQB{pe(*1Ggbq~;{ zTIuLyKJ?;%Dq*0<5I}k0R9dtx%wWI}kM6oG;A3tVD$#2Qpj>e8&9iFnEEqIoYl}Ti z*AJ@*gNE#MNbtc)YZx&Epk|V9E;M2TLuo^zH*?Dxv4Npv%lu12qa(YhDbW93Du8b2 zIkKTmJqpth8T{Cf0JW(0^J8xhr(c3w+jZFh6+J7PZbs}cjCnee?j!K;zFc*2qQ&x0 z%LoI8xH}UEaF?pu-(v{cRLkaxZ6R1ax>_{V2@CHO_?ZpvfSQ43T%&xLiX9zTHNFyp z#*3qCN5zo*gJRdSIdU|Y_39oJ0X5}yYB6>!iD^D!JR=~qv-w$w-BZl?{~!>rz3#>= z@0m5o-11zvS_qBik!KvH1CriUYkVJi?&8% P00000NkvXXu0mjf;j;l@ literal 0 HcmV?d00001 diff --git a/common/src/main/res/drawable-mdpi/failed_loading.png b/common/src/main/res/drawable-mdpi/failed_loading.png new file mode 100644 index 0000000000000000000000000000000000000000..1e3f3a3ec8eb73b207268f3c27ecf54706dba11a GIT binary patch literal 424 zcmV;Z0ayNsP) zvsr+MG|G47m-3>#8~Mh@T$BBt!UBJWfX|4wE|Cgb@g`8gJ~^F~ zZ&~MH&NR_ypLIRR9z<8=Hfu^iYd-GZW&u6Fh2X`iOTZ^2A=bDjI_N_7*~-zy*W_$OXg&sDPvZsem+K72pDt0;mGg(*;ieE%Lbh03@ZE?99&C z!eMWZ1P-L^r>7NQW-o!ez@LF1f#<-#j(o=0KJa_sv)8#RFcA17@KczbOXlwEp2b+a z+K0ee7%F9L@y@*Xe5)cQA(=O@7VE&h&$}2w^qb``l|O-}M1J<;VJHQTaKgKr3nb zJY_{NL5MWu_OIUd&`jDsU&G4Jk+8U7Yasyhu0#RIA@V{z4eqZm*l@Sm+;eEDgjQ|s3mblU7eS|%P8KjL^oj}qrW?y`Urq*O0<%JI zNdam@$Btxi`S`(0S0WFX6`I8b06YoJ=b`G3ULXgU6`D&6I10^*0o8qqmk+?K&|F%8 zy3l(D)YD+U&t?E&p}DjG&MB{XVxac|?kDF0vtE{=6{*8y3(z)Kme* z{lCG61@xBte_6oUPt3)J1@!l;sdcpwLE{y}j;}s07v86_UrpQ=Ti8ao0G@=;Ya3nt zAlm|X51`@;K4Oj|t3Lj8^vDLuzhPi7IBj%?c^(}t6tCrGTiWo6J zymUN9MBu>+HueKV+!s0UEv183b(Bk5(-rWX4GK){Kxl5}}=Ca4`XIudT$p}}GckJF51<5R9 e#LzZZG5rsq`mrU5j!U}$0000gFKP)_l|FYpN>C*{4HK*TlQH=dq)o!)P>`%|K8oDPE$NNaLR()YR4br1;R21WSN92{?@zHV@0uAmp$ z-u!U9l6n_~6Y!u2J2XB>-OT~NGVu;cF{S)=e0O|wyn`Qw8hMRv*p_{yol;WkGAkau z@Iet_@e96AP2S6}Z?HjI(!Rw3Gkh1pIk-_ATYPRIj5dR9>CfVgv{eN(tT@Y&Q=|E? zrjOuD`p>a$l4wwIGDg;m=82J@&){3?8DpI!!PgvVTqBEU9j7w@U)ZI#G0vO%@ONcU z3`=sAnCGk_s0C$(e88O19s-v}CE4cSw)fOjs$cdk0?G>CK_(}H+JZ)@Tk=u%%>re0 z=b)1lL5)GH)Gt|nEGaN}6v>I8R@gPEY^uTURAuLsT&=1VWW(RRY(Ev$tk{>lll`^; zpXovAn6m0pj)f9Lz}^B3$juB2QaYu4mwo2K@L4rM1Y=PAl=*}`dZzCgMnFM|A6x81 zFb2g>%1_y64cNzt{g%Q)VBrK2un)PrWyJmXsx(Ylee@9MlOSspz3$uLd8||QWG(xfB_H|e^_AGI4s=Qo!Ppd^k(+6T{OZ+OWX}ZUd=Iga zHPo6-F9LaytrKLOIah3yTi(B=(b_=A1QCo;@f&$#39PV`=I6<#ol0yO5BmJb_Rbr7^4z* zbJ#y{&(4KEpE=SnpRTIIOlsHpvJ+wc)_Sxn3%|U*e?RKaHbVv|mQGBJ` zesLH&<(7N0$)*u~5@d~@-B-^9@~atHeH3Bg1i`L7LBP4<}!!)J>GS%2g= ze*T32fXW(0;|3-G3nqx#6(1=X`}hY`1Vt$wC95s_hQDeFqGrXuWZBKf@BD}}w<%o5 zB>Rm5_8H}9l0=O`tJE*K-?Jy=pOYL#lBg|cl)5FSZD9(HA7qlKsZ_u0TMYOer?sk) zoZr<7_gqj*&?I$AGPZepJCxO<$nJlRO$~}JjZ99Rn+p3Fl9C&-d3R+37;Nw@^^8$J zPD}+2Do%2I!UBn+kKjxC&#`WDB4}7~X7LHNhH?Vh47R1e967DpBqsvCCY2O!$@srD zE~U*O4R8k51c?6b^1Cc!^q Wv{^17$9+Hm0000 @@ -37,7 +37,6 @@ android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" - style="@style/HabiticaButton.Primary" android:visibility="gone" tools:visibility="visible" android:layout_marginTop="@dimen/spacing_large"/> diff --git a/Habitica/res/layout/failed_item.xml b/common/src/main/res/layout/failed_item.xml similarity index 76% rename from Habitica/res/layout/failed_item.xml rename to common/src/main/res/layout/failed_item.xml index 9944a2a90..d43be218c 100644 --- a/Habitica/res/layout/failed_item.xml +++ b/common/src/main/res/layout/failed_item.xml @@ -2,24 +2,23 @@ - + android:src="@drawable/failed_loading" + app:tint="@color/text_quad"/>