From 2e654c9c636132a7c2dcc00a02bda28d56738f6d Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 31 Jan 2022 13:54:01 +0100 Subject: [PATCH 01/18] Design fixes --- Habitica/res/layout/fragment_gem_purchase.xml | 3 +- Habitica/res/layout/purchase_gem_view.xml | 42 +++++++++++++------ Habitica/res/values/strings.xml | 2 +- .../habitica/ui/GemPurchaseOptionsView.kt | 2 +- .../social/InboxMessageListFragment.kt | 2 +- .../habitica/ui/views/shops/PurchaseDialog.kt | 4 +- .../views/yesterdailies/YesterdailyDialog.kt | 7 +++- 7 files changed, 44 insertions(+), 18 deletions(-) diff --git a/Habitica/res/layout/fragment_gem_purchase.xml b/Habitica/res/layout/fragment_gem_purchase.xml index 1e910c52e..1333f53b4 100644 --- a/Habitica/res/layout/fragment_gem_purchase.xml +++ b/Habitica/res/layout/fragment_gem_purchase.xml @@ -233,11 +233,12 @@ android:layout_width="wrap_content" android:paddingStart="41dp" android:paddingEnd="41dp" - android:paddingBottom="20dp" + android:paddingBottom="30dp" android:paddingTop="70dp" android:text="@string/gem_purchase_title" android:layout_gravity="center_horizontal" android:gravity="center" + android:lineSpacingExtra="3dp" android:textColor="@color/white" style="@style/Caption2" android:drawablePadding="@dimen/spacing_medium"/> diff --git a/Habitica/res/layout/purchase_gem_view.xml b/Habitica/res/layout/purchase_gem_view.xml index 454c3e295..b83800c33 100644 --- a/Habitica/res/layout/purchase_gem_view.xml +++ b/Habitica/res/layout/purchase_gem_view.xml @@ -17,19 +17,37 @@ android:contentDescription="@string/gems" android:layout_marginTop="20dp"/> - + android:orientation="horizontal"> + + + Google play services could not be found. Purchase Buying gems supports the developers and helps keep Habitica running - Gems allow you to buy fun extras for your account: + Gems allow you to buy fun extras for your account Cool costumes for your avatar Awesome backgrounds Quests that reward you with pet eggs diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.kt index 89dd9db5a..6f3e7a308 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.kt @@ -20,7 +20,7 @@ class GemPurchaseOptionsView(context: Context, attrs: AttributeSet) : FrameLayou 0, 0 ) - binding.gemAmount.text = "${a.getText(R.styleable.GemPurchaseOptionsView_gemAmount)} GEMS" + binding.gemAmount.text = a.getText(R.styleable.GemPurchaseOptionsView_gemAmount) val iconRes = a.getDrawable(R.styleable.GemPurchaseOptionsView_gemDrawable) if (iconRes != null) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt index 5abbb4fa1..a29284665 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt @@ -215,8 +215,8 @@ class InboxMessageListFragment : BaseMainFragment RxErrorHandler.reportError(error) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt index 95dd40dbf..19674690a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt @@ -11,6 +11,7 @@ import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.toDrawable import androidx.core.os.bundleOf import com.google.firebase.analytics.FirebaseAnalytics +import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.InventoryRepository @@ -319,6 +320,7 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop } private fun buyItem(quantity: Int) { + val application = ownerActivity?.application as? HabiticaBaseApplication FirebaseAnalytics.getInstance(context).logEvent( "item_purchased", bundleOf( @@ -373,7 +375,7 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop "hourglasses" -> ContextCompat.getColor(context, R.color.text_brand) else -> 0 } - (ownerActivity as? SnackbarActivity)?.showSnackbar( + ((application?.currentActivity?.get() ?: getActivity() ?: ownerActivity) as? SnackbarActivity)?.showSnackbar( content = text, rightIcon = priceLabel.compoundDrawables[0], rightTextColor = rightTextColor, diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt index 2ec30a1ce..4deb34968 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt @@ -158,7 +158,12 @@ class YesterdailyDialog private constructor(context: Context, private val userRe private fun configureTaskView(taskView: View, task: Task) { val completed = !task.isDisplayedActive - val checkmark = taskView.findViewById(R.id.checkmark) + val checkmark = taskView.findViewById(R.id.checkmark) + if (task.completed) { + checkmark?.drawable?.setTint(ContextCompat.getColor(context, R.color.gray_400)) + } else { + checkmark?.drawable?.setTint(ContextCompat.getColor(context, task.darkestTaskColor)) + } val checkboxHolder = taskView.findViewById(R.id.checkBoxHolder) val checkboxBackground = taskView.findViewById(R.id.checkbox_background) checkmark?.visibility = if (completed) View.VISIBLE else View.GONE From 46caca91e23ad4d0e7090fb58dc75cbd7b520316 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 31 Jan 2022 15:58:15 +0100 Subject: [PATCH 02/18] Start using a central userViewModel --- .../habitica/components/UserComponent.java | 3 + .../android/habitica/modules/UserModule.java | 8 +++ .../habitica/ui/activities/MainActivity.kt | 4 +- .../inventory/MountDetailRecyclerAdapter.kt | 13 ++-- .../inventory/PetDetailRecyclerAdapter.kt | 13 ++-- .../inventory/StableRecyclerAdapter.kt | 20 +++--- .../ui/fragments/AchievementsFragment.kt | 4 ++ .../habitica/ui/fragments/BaseMainFragment.kt | 11 ---- .../AvatarCustomizationFragment.kt | 20 +++--- .../customization/AvatarEquipmentFragment.kt | 7 ++- .../equipment/EquipmentDetailFragment.kt | 2 +- .../equipment/EquipmentOverviewFragment.kt | 6 +- .../inventory/items/ItemRecyclerFragment.kt | 8 ++- .../inventory/items/ItemsFragment.kt | 1 - .../fragments/inventory/shops/ShopFragment.kt | 28 ++++----- .../stable/MountDetailRecyclerFragment.kt | 9 ++- .../stable/PetDetailRecyclerFragment.kt | 9 ++- .../inventory/stable/StableFragment.kt | 3 +- .../stable/StableRecyclerFragment.kt | 11 +++- .../ui/fragments/skills/SkillsFragment.kt | 31 +++++----- .../social/InboxMessageListFragment.kt | 4 +- .../fragments/social/InboxOverviewFragment.kt | 2 +- .../fragments/social/QuestDetailFragment.kt | 6 +- .../challenges/ChallengeDetailFragment.kt | 6 +- .../social/party/NoPartyFragmentFragment.kt | 21 ++++--- .../fragments/social/party/PartyFragment.kt | 16 ++--- .../ui/fragments/support/BugFixFragment.kt | 6 +- .../ui/viewHolders/MountViewHolder.kt | 10 +-- .../habitica/ui/viewHolders/PetViewHolder.kt | 10 +-- .../habitica/ui/viewmodels/BaseViewModel.kt | 18 +----- .../ui/viewmodels/MainUserViewModel.kt | 62 +++++++++++++++++++ .../equipment/EquipmentOverviewViewModel.kt | 4 ++ 32 files changed, 228 insertions(+), 148 deletions(-) create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/MainUserViewModel.kt diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java b/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java index bf889d2f4..128148286 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java @@ -103,6 +103,7 @@ import com.habitrpg.android.habitica.ui.viewmodels.AuthenticationViewModel; import com.habitrpg.android.habitica.ui.viewmodels.GroupViewModel; import com.habitrpg.android.habitica.ui.viewmodels.InboxViewModel; import com.habitrpg.android.habitica.ui.viewmodels.MainActivityViewModel; +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel; import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel; import com.habitrpg.android.habitica.ui.viewmodels.inventory.equipment.EquipmentOverviewViewModel; import com.habitrpg.android.habitica.ui.views.insufficientCurrency.InsufficientGemsDialog; @@ -352,4 +353,6 @@ public interface UserComponent { void inject(@NotNull MainActivityViewModel mainActivityViewModel); void inject(@NotNull GuidelinesActivity guidelinesActivity); + + void inject(@NotNull MainUserViewModel mainUserViewModel); } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserModule.java b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserModule.java index e6ac9f658..e6e231245 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserModule.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserModule.java @@ -4,8 +4,10 @@ import android.content.Context; import android.content.SharedPreferences; import com.habitrpg.android.habitica.data.TaskRepository; +import com.habitrpg.android.habitica.data.UserRepository; import com.habitrpg.android.habitica.helpers.TaskAlarmManager; import com.habitrpg.android.habitica.helpers.UserScope; +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel; import javax.inject.Named; @@ -28,4 +30,10 @@ public class UserModule { public String providesUserID(SharedPreferences sharedPreferences) { return sharedPreferences.getString("UserID", ""); } + + @Provides + @UserScope + MainUserViewModel providesUserViewModel(UserRepository userRepository) { + return new MainUserViewModel(userRepository); + } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt index 23f799a37..7e02ed842 100755 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt @@ -273,7 +273,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack navigationController.addOnDestinationChangedListener { _, destination, arguments -> updateToolbarTitle(destination, arguments) } if (launchScreen == "/party") { - if (viewModel.isUserInParty) { + if (viewModel.userViewModel.isUserInParty) { MainNavigationController.navigate(R.id.partyFragment) } } @@ -430,7 +430,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack } private fun displayDeathDialogIfNeeded() { - if (!viewModel.isUserFainted) { + if (!viewModel.userViewModel.isUserFainted) { return } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt index 462627480..69e9bcbda 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt @@ -15,7 +15,11 @@ class MountDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Ada private var ownedMounts: Map? = null private val equipEvents = PublishSubject.create() - private var user: User? = null + var currentMount: String? = null + set(value) { + field = value + notifyDataSetChanged() + } private var itemList: List = ArrayList() @@ -37,7 +41,7 @@ class MountDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Ada override fun onBindViewHolder(holder: androidx.recyclerview.widget.RecyclerView.ViewHolder, position: Int) { when (val obj = this.itemList[position]) { is StableSection -> (holder as? SectionViewHolder)?.bind(obj) - is Mount -> (holder as? MountViewHolder)?.bind(obj, ownedMounts?.get(obj.key ?: "")?.owned == true, user) + is Mount -> (holder as? MountViewHolder)?.bind(obj, ownedMounts?.get(obj.key ?: "")?.owned == true, currentMount) } } @@ -49,9 +53,4 @@ class MountDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Ada this.ownedMounts = ownedMounts notifyDataSetChanged() } - - fun setUser(user: User) { - this.user = user - notifyDataSetChanged() - } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt index ffc74fe7d..cfb6b1279 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt @@ -17,7 +17,11 @@ class PetDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapt private var ownedPets: Map? = null private var ownedMounts: Map? = null private var ownedItems: Map? = null - private var user: User? = null + var currentPet: String? = null + set(value) { + field = value + notifyDataSetChanged() + } private val equipEvents = PublishSubject.create() private val feedEvents = PublishSubject.create>() private var ownsSaddles: Boolean = false @@ -29,11 +33,6 @@ class PetDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapt this.notifyDataSetChanged() } - fun setUser(user: User) { - this.user = user - notifyDataSetChanged() - } - fun getEquipFlowable(): Flowable { return equipEvents.toFlowable(BackpressureStrategy.DROP) } @@ -81,7 +80,7 @@ class PetDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapt ownedItems?.get(obj.animal + "-eggs") != null, ownedItems?.get(obj.color + "-hatchingPotions") != null, ownedMounts?.containsKey(obj.key) == true, - user + currentPet ) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt index 90b2da691..ea2d6fb92 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt @@ -31,7 +31,16 @@ class StableRecyclerAdapter : RecyclerView.Adapter() { var animalIngredientsRetriever: ((Animal, ((Pair) -> Unit)) -> Unit)? = null private val feedEvents = PublishSubject.create>() var itemType: String? = null - private var user: User? = null + var currentPet: String? = null + set(value) { + field = value + notifyDataSetChanged() + } + var currentMount: String? = null + set(value) { + field = value + notifyDataSetChanged() + } private val equipEvents = PublishSubject.create() private var existingMounts: List? = null private var ownedMounts: Map? = null @@ -43,11 +52,6 @@ class StableRecyclerAdapter : RecyclerView.Adapter() { return equipEvents.toFlowable(BackpressureStrategy.DROP) } - fun setUser(user: User) { - this.user = user - notifyDataSetChanged() - } - private fun canRaiseToMount(pet: Pet): Boolean { if (pet.type == "special") return false for (mount in existingMounts ?: emptyList()) { @@ -122,10 +126,10 @@ class StableRecyclerAdapter : RecyclerView.Adapter() { hasUnlockedEgg = ownedItems?.get(item.animal + "-eggs") != null, hasUnlockedPotion = ownedItems?.get(item.color + "-hatchingPotions") != null, hasMount = ownedMounts?.containsKey(item.key) == true, - user = user + currentPet = currentPet ) } else if (item is Mount) { - (holder as? MountViewHolder)?.bind(item, item.numberOwned > 0, user) + (holder as? MountViewHolder)?.bind(item, item.numberOwned > 0, currentMount) } return } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AchievementsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AchievementsFragment.kt index 640535294..b77c3c20f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AchievementsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AchievementsFragment.kt @@ -14,6 +14,7 @@ import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBind import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.ui.adapter.AchievementsAdapter import com.habitrpg.android.habitica.ui.helpers.ToolbarColorHelper +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import io.reactivex.rxjava3.kotlin.Flowables import io.reactivex.rxjava3.kotlin.combineLatest import javax.inject.Inject @@ -22,6 +23,8 @@ class AchievementsFragment : BaseMainFragment 0) { entries.add(Pair("Challenges won", challengeAchievementCount)) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt index 9fe7288b5..0d1289d7b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt @@ -39,23 +39,12 @@ abstract class BaseMainFragment : BaseFragment() { var usesTabLayout: Boolean = false var hidesToolbar: Boolean = false var usesBottomNavigation = false - open var user: User? = null - - override fun onAttach(context: Context) { - super.onAttach(context) - - if (activity is MainActivity) { - user = activity?.viewModel?.user?.value - } - } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - compositeSubscription.add(userRepository.getUser().subscribe({ user = it }, RxErrorHandler.handleEmptyError())) - if (this.usesBottomNavigation) { bottomNavigation?.visibility = View.VISIBLE } else { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarCustomizationFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarCustomizationFragment.kt index e89ab1837..4a94dad1e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarCustomizationFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarCustomizationFragment.kt @@ -18,6 +18,7 @@ import com.habitrpg.android.habitica.ui.adapter.CustomizationRecyclerViewAdapter import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment import com.habitrpg.android.habitica.ui.helpers.MarginDecoration import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import javax.inject.Inject class AvatarCustomizationFragment : @@ -34,6 +35,8 @@ class AvatarCustomizationFragment : lateinit var customizationRepository: CustomizationRepository @Inject lateinit var inventoryRepository: InventoryRepository + @Inject + lateinit var userViewModel: MainUserViewModel var type: String? = null var category: String? = null @@ -52,7 +55,7 @@ class AvatarCustomizationFragment : adapter.getSelectCustomizationEvents() .flatMap { customization -> if (customization.type == "background") { - userRepository.unlockPath(user, customization) + userRepository.unlockPath(userViewModel.user.value, customization) .flatMap { userRepository.retrieveUser(false, true, true) } } else { userRepository.useCustomization(customization.type ?: "", customization.category, customization.identifier ?: "") @@ -63,7 +66,7 @@ class AvatarCustomizationFragment : compositeSubscription.add( adapter.getUnlockCustomizationEvents() .flatMap { customization -> - userRepository.unlockPath(user, customization) + userRepository.unlockPath(userViewModel.user.value, customization) } .flatMap { userRepository.retrieveUser(withTasks = false, forced = true) } .flatMap { inventoryRepository.retrieveInAppRewards() } @@ -112,11 +115,7 @@ class AvatarCustomizationFragment : binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator() this.loadCustomizations() - compositeSubscription.add( - userRepository.getUser().subscribeWithErrorHandler { - updateUser(it) - } - ) + userViewModel.user.observe(viewLifecycleOwner) { updateUser(it) } } override fun onDestroy() { @@ -153,7 +152,8 @@ class AvatarCustomizationFragment : layoutManager.spanCount = spanCount } - fun updateUser(user: User) { + fun updateUser(user: User?) { + if (user == null) return this.updateActiveCustomization(user) if (adapter.customizationList.size != 0) { val ownedCustomizations = ArrayList() @@ -162,8 +162,8 @@ class AvatarCustomizationFragment : } else { this.loadCustomizations() } - this.adapter.userSize = this.user?.preferences?.size - this.adapter.hairColor = this.user?.preferences?.hair?.color + this.adapter.userSize = user.preferences?.size + this.adapter.hairColor = user.preferences?.hair?.color this.adapter.gemBalance = user.gemCount adapter.notifyDataSetChanged() } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarEquipmentFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarEquipmentFragment.kt index 7808822ea..2f5e9d9b6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarEquipmentFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarEquipmentFragment.kt @@ -18,6 +18,7 @@ import com.habitrpg.android.habitica.ui.adapter.CustomizationEquipmentRecyclerVi import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment import com.habitrpg.android.habitica.ui.helpers.MarginDecoration import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import io.reactivex.rxjava3.core.Flowable import javax.inject.Inject @@ -27,6 +28,8 @@ class AvatarEquipmentFragment : @Inject lateinit var inventoryRepository: InventoryRepository + @Inject + lateinit var userViewModel: MainUserViewModel override var binding: FragmentRefreshRecyclerviewBinding? = null @@ -51,7 +54,7 @@ class AvatarEquipmentFragment : adapter.getSelectCustomizationEvents() .flatMap { equipment -> val key = (if (equipment.key?.isNotBlank() != true) activeEquipment else equipment.key) ?: "" - inventoryRepository.equip(user, if (user?.preferences?.costume == true) "costume" else "equipped", key) + inventoryRepository.equip(userViewModel.user.value, if (userViewModel.user.value?.preferences?.costume == true) "costume" else "equipped", key) } .subscribe({ }, RxErrorHandler.handleEmptyError()) ) @@ -143,7 +146,7 @@ class AvatarEquipmentFragment : if (this.type == null || user.preferences == null) { return } - val outfit = if (user.preferences?.costume == true) this.user?.items?.gear?.costume else this.user?.items?.gear?.equipped + val outfit = if (user.preferences?.costume == true) user.items?.gear?.costume else user.items?.gear?.equipped val activeEquipment = when (this.type) { "headAccessory" -> outfit?.headAccessory "back" -> outfit?.back 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 665316463..f7c278f11 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 @@ -44,7 +44,7 @@ class EquipmentDetailFragment : savedInstanceState: Bundle? ): View? { compositeSubscription.add( - this.adapter.equipEvents.flatMapMaybe { key -> inventoryRepository.equipGear(user, key, isCostume ?: false).firstElement() } + this.adapter.equipEvents.flatMapMaybe { key -> inventoryRepository.equipGear(null, key, isCostume ?: false).firstElement() } .subscribe({ }, RxErrorHandler.handleEmptyError()) ) return super.onCreateView(inflater, container, savedInstanceState) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentOverviewFragment.kt index 2d0fb80de..a18122de8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentOverviewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentOverviewFragment.kt @@ -45,10 +45,10 @@ class EquipmentOverviewFragment : BaseMainFragment(), SwipeRefreshL lateinit var userRepository: UserRepository @Inject internal lateinit var hatchPetUseCase: HatchPetUseCase + @Inject + lateinit var userViewModel: MainUserViewModel var adapter: ItemRecyclerAdapter? = null var itemType: String? = null var itemTypeText: String? = null - var user: User? = null internal var layoutManager: androidx.recyclerview.widget.LinearLayoutManager? = null override var binding: FragmentItemsBinding? = null @@ -111,7 +113,7 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL ) compositeSubscription.add( adapter.getOpenMysteryItemFlowable() - .flatMap { inventoryRepository.openMysteryItem(user) } + .flatMap { inventoryRepository.openMysteryItem(userViewModel.user.value) } .doOnNext { val activity = activity as? MainActivity if (activity != null) { @@ -122,7 +124,7 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL dialog.binding.titleView.text = it.text dialog.binding.descriptionView.text = it.notes dialog.addButton(R.string.equip, true) { _, _ -> - inventoryRepository.equip(user, "equipped", it.key ?: "").subscribe({}, RxErrorHandler.handleEmptyError()) + inventoryRepository.equip(userViewModel.user.value, "equipped", it.key ?: "").subscribe({}, RxErrorHandler.handleEmptyError()) } dialog.addCloseButton() dialog.enqueue() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt index df4293962..374f1efa3 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt @@ -68,7 +68,6 @@ class ItemsFragment : BaseMainFragment() { 4 -> "special" else -> "" } - fragment.user = this@ItemsFragment.user fragment.itemTypeText = if (position == 4 && isAdded) getString(R.string.special_items) else getPageTitle(position) 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 f007fb066..9d8333152 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 @@ -24,6 +24,7 @@ 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.android.habitica.ui.helpers.SafeDefaultItemAnimator +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.CurrencyViews import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import javax.inject.Inject @@ -44,6 +45,8 @@ open class ShopFragment : BaseMainFragment() lateinit var socialRepository: SocialRepository @Inject lateinit var configManager: AppConfigManager + @Inject + lateinit var userViewModel: MainUserViewModel private var layoutManager: GridLayoutManager? = null @@ -106,7 +109,7 @@ open class ShopFragment : BaseMainFragment() this.shopIdentifier = savedInstanceState.getString(SHOP_IDENTIFIER_KEY, "") } - adapter?.selectedGearCategory = user?.stats?.habitClass ?: "" + adapter?.selectedGearCategory = userViewModel.user.value?.stats?.habitClass ?: "" if (shop != null) { adapter?.setShop(shop) @@ -122,15 +125,10 @@ open class ShopFragment : BaseMainFragment() } } - compositeSubscription.add( - userRepository.getUser().subscribe( - { - adapter?.user = user - updateCurrencyView(it) - }, - RxErrorHandler.handleEmptyError() - ) - ) + userViewModel.user.observe(viewLifecycleOwner) { + adapter?.user = it + updateCurrencyView(it) + } compositeSubscription.add( socialRepository.getGroup(Group.TAVERN_ID) @@ -183,7 +181,7 @@ open class ShopFragment : BaseMainFragment() this.inventoryRepository.retrieveShopInventory(shopUrl) .map { shop1 -> if (shop1.identifier == Shop.MARKET) { - val user = user + val user = userViewModel.user.value val specialCategory = ShopCategory() specialCategory.text = getString(R.string.special) if (user?.isValid == true && user.purchased?.plan?.isActive == true) { @@ -315,9 +313,9 @@ open class ShopFragment : BaseMainFragment() private const val SHOP_IDENTIFIER_KEY = "SHOP_IDENTIFIER_KEY" } - private fun updateCurrencyView(user: User) { - currencyView.gold = user.stats?.gp ?: 0.0 - currencyView.gems = user.gemCount.toDouble() - currencyView.hourglasses = user.hourglassCount.toDouble() + private fun updateCurrencyView(user: User?) { + currencyView.gold = user?.stats?.gp ?: 0.0 + currencyView.gems = user?.gemCount?.toDouble() ?: 0.0 + currencyView.hourglasses = user?.hourglassCount?.toDouble() ?: 0.0 } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt index e476df24b..5c385c316 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt @@ -18,6 +18,7 @@ import com.habitrpg.android.habitica.ui.adapter.inventory.MountDetailRecyclerAda import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment import com.habitrpg.android.habitica.ui.helpers.MarginDecoration import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import javax.inject.Inject class MountDetailRecyclerFragment : @@ -26,6 +27,8 @@ class MountDetailRecyclerFragment : @Inject internal lateinit var inventoryRepository: InventoryRepository + @Inject + lateinit var userViewModel: MainUserViewModel var adapter: MountDetailRecyclerAdapter? = null var animalType: String? = null @@ -86,14 +89,15 @@ class MountDetailRecyclerFragment : binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator() this.loadItems() - adapter?.getEquipFlowable()?.flatMap { key -> inventoryRepository.equip(user, "mount", key) } + adapter?.getEquipFlowable()?.flatMap { key -> inventoryRepository.equip(null, "mount", key) } ?.subscribe( { - user?.let { updatedUser -> adapter?.setUser(updatedUser) } + adapter?.currentMount = it.currentMount }, RxErrorHandler.handleEmptyError() )?.let { compositeSubscription.add(it) } } + userViewModel.user.observe(viewLifecycleOwner) { adapter?.currentMount = it?.currentMount } if (savedInstanceState != null) { this.animalType = savedInstanceState.getString(ANIMAL_TYPE_KEY, "") @@ -134,7 +138,6 @@ class MountDetailRecyclerFragment : return@map mountMap }.doOnNext { adapter?.setOwnedMounts(it) - user?.let { updatedUser -> adapter?.setUser(updatedUser) } }, { unsortedAnimals, ownedAnimals -> val items = mutableListOf() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt index a0d655fa4..3bbe400c7 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt @@ -22,6 +22,7 @@ import com.habitrpg.android.habitica.ui.adapter.inventory.PetDetailRecyclerAdapt import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment import com.habitrpg.android.habitica.ui.fragments.inventory.items.ItemDialogFragment import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import io.reactivex.rxjava3.core.Maybe import io.reactivex.rxjava3.kotlin.Flowables import javax.inject.Inject @@ -34,6 +35,8 @@ class PetDetailRecyclerFragment : lateinit var inventoryRepository: InventoryRepository @Inject lateinit var feedPetUseCase: FeedPetUseCase + @Inject + lateinit var userViewModel: MainUserViewModel var adapter: PetDetailRecyclerAdapter = PetDetailRecyclerAdapter() private var animalType: String? = null @@ -109,14 +112,15 @@ class PetDetailRecyclerFragment : compositeSubscription.add( adapter.getEquipFlowable() - .flatMap { key -> inventoryRepository.equip(user, "pet", key) } + .flatMap { key -> inventoryRepository.equip(null, "pet", key) } .subscribe( { - user?.let { updatedUser -> adapter.setUser(updatedUser) } + adapter.currentPet = it.currentPet }, RxErrorHandler.handleEmptyError() ) ) + userViewModel.user.observe(viewLifecycleOwner) { adapter.currentPet = it?.currentPet } compositeSubscription.add(adapter.feedFlowable.subscribe({ showFeedingDialog(it.first, it.second) }, RxErrorHandler.handleEmptyError())) view.post { setGridSpanCount(view.width) } @@ -168,7 +172,6 @@ class PetDetailRecyclerFragment : return@map petMap }.doOnNext { adapter.setOwnedPets(it) - user?.let { updatedUser -> adapter.setUser(updatedUser) } } ).map { val items = mutableListOf() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.kt index 32e34d316..ee8fff172 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.kt @@ -56,8 +56,7 @@ class StableFragment : BaseMainFragment() { fragment.itemType = "mounts" } } - fragment.user = this@StableFragment.user - fragment.itemTypeText = getPageTitle(position).toString() + fragment.itemTypeText = getPageTitle(position) return fragment } 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 bd88b672f..84a2a1f79 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 @@ -23,6 +23,7 @@ import com.habitrpg.android.habitica.ui.fragments.BaseFragment import com.habitrpg.android.habitica.ui.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 import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Maybe import io.reactivex.rxjava3.kotlin.combineLatest @@ -39,11 +40,12 @@ class StableRecyclerFragment : lateinit var userRepository: UserRepository @Inject lateinit var configManager: AppConfigManager + @Inject + lateinit var userViewModel: MainUserViewModel var adapter: StableRecyclerAdapter? = null var itemType: String? = null var itemTypeText: String? = null - var user: User? = null internal var layoutManager: androidx.recyclerview.widget.GridLayoutManager? = null override var binding: FragmentRefreshRecyclerviewBinding? = null @@ -96,7 +98,6 @@ class StableRecyclerFragment : adapter = binding?.recyclerView?.adapter as? StableRecyclerAdapter if (adapter == null) { adapter = StableRecyclerAdapter() - user?.let { adapter?.setUser(it) } adapter?.animalIngredientsRetriever = { animal, callback -> Maybe.zip( inventoryRepository.getItems(Egg::class.java, arrayOf(animal.animal)).firstElement(), @@ -119,11 +120,15 @@ class StableRecyclerFragment : adapter?.let { compositeSubscription.add( it.getEquipFlowable() - .flatMap { key -> inventoryRepository.equip(user, if (itemType == "pets") "pet" else "mount", key) } + .flatMap { key -> inventoryRepository.equip(null, if (itemType == "pets") "pet" else "mount", key) } .subscribe({ }, RxErrorHandler.handleEmptyError()) ) } } + userViewModel.user.observe(viewLifecycleOwner) { + adapter?.currentPet = it?.currentPet + adapter?.currentMount = it?.currentMount + } this.loadItems() view.post { setGridSpanCount(view.width) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt index 1451d75c2..25503e89e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt @@ -23,12 +23,14 @@ import com.habitrpg.android.habitica.ui.activities.SkillTasksActivity import com.habitrpg.android.habitica.ui.adapter.SkillsRecyclerViewAdapter import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.Companion.showSnackbar import io.reactivex.rxjava3.core.Flowable import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import javax.inject.Inject class SkillsFragment : BaseMainFragment() { internal var adapter: SkillsRecyclerViewAdapter? = null @@ -36,20 +38,16 @@ class SkillsFragment : BaseMainFragment() { override var binding: FragmentSkillsBinding? = null + @Inject + lateinit var userViewModel: MainUserViewModel + override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSkillsBinding { return FragmentSkillsBinding.inflate(inflater, container, false) } - override var user: User? = null - set(value) { - field = value - checkUserLoadSkills() - } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { adapter = SkillsRecyclerViewAdapter() adapter?.useSkillEvents?.subscribeWithErrorHandler { onSkillSelected(it) }?.let { compositeSubscription.add(it) } - checkUserLoadSkills() this.tutorialStepIdentifier = "skills" this.tutorialText = getString(R.string.tutorial_skills) @@ -63,19 +61,22 @@ class SkillsFragment : BaseMainFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + userViewModel.user.observe(viewLifecycleOwner) { user -> + user?.let { checkUserLoadSkills(it) } + } + binding?.recyclerView?.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(activity) binding?.recyclerView?.adapter = adapter binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator() } - private fun checkUserLoadSkills() { - if (user == null || adapter == null) { + private fun checkUserLoadSkills(user: User) { + if (adapter == null) { return } - adapter?.mana = this.user?.stats?.mp ?: 0.0 - adapter?.level = this.user?.stats?.lvl ?: 0 - adapter?.specialItems = this.user?.items?.special - user?.let { user -> + adapter?.mana = user.stats?.mp ?: 0.0 + adapter?.level = user.stats?.lvl ?: 0 + adapter?.specialItems = user.items?.special Flowable.combineLatest( userRepository.getSkills(user), userRepository.getSpecialItems(user), @@ -89,9 +90,7 @@ class SkillsFragment : BaseMainFragment() { } return@combineLatest allEntries } - ) - .subscribe({ skills -> adapter?.setSkillList(skills) }, RxErrorHandler.handleEmptyError()) - } + ).subscribe({ skills -> adapter?.setSkillList(skills) }, RxErrorHandler.handleEmptyError()) } private fun onSkillSelected(skill: Skill) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt index a29284665..00aa3a21c 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt @@ -88,7 +88,7 @@ class InboxMessageListFragment : BaseMainFragment setReceivingUser(member.username, member.id) activity?.title = member.displayName - chatAdapter = InboxAdapter(user, member) + chatAdapter = InboxAdapter(viewModel.user.value, member) viewModel.messages.observe(this.viewLifecycleOwner) { markMessagesAsRead(it) chatAdapter?.submitList(it) @@ -170,7 +170,7 @@ class InboxMessageListFragment : BaseMainFragment) { - socialRepository.markSomePrivateMessagesAsRead(user, messages) + socialRepository.markSomePrivateMessagesAsRead(viewModel.user.value, messages) } private fun startAutoRefreshing() { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxOverviewFragment.kt index d42ca5996..ec808c326 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxOverviewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxOverviewFragment.kt @@ -41,7 +41,7 @@ class InboxOverviewFragment : BaseMainFragment(), androidx override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { this.hidesToolbar = true - compositeSubscription.add(this.socialRepository.markPrivateMessagesRead(user).subscribe({ }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(this.socialRepository.markPrivateMessagesRead(null).subscribe({ }, RxErrorHandler.handleEmptyError())) return super.onCreateView(inflater, container, savedInstanceState) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt index 1768723bf..226e6a294 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt @@ -26,6 +26,7 @@ import com.habitrpg.android.habitica.modules.AppModule import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils import com.habitrpg.android.habitica.ui.helpers.MarkdownParser +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import javax.inject.Inject import javax.inject.Named @@ -38,6 +39,8 @@ class QuestDetailFragment : BaseMainFragment() { lateinit var inventoryRepository: InventoryRepository @field:[Inject Named(AppModule.NAMED_USER_ID)] lateinit var userId: String + @Inject + lateinit var userViewModel: MainUserViewModel override var binding: FragmentQuestDetailBinding? = null @@ -101,7 +104,7 @@ class QuestDetailFragment : BaseMainFragment() { compositeSubscription.add( socialRepository.getMember(quest?.leader).subscribe( { member -> - if (context != null && binding?.questLeaderView != null && member != null) { + if (context != null && binding?.questLeaderView != null) { binding?.questLeaderView?.text = context?.getString(R.string.quest_leader_header, member.displayName) } }, @@ -109,6 +112,7 @@ class QuestDetailFragment : BaseMainFragment() { ) ) + val user = userViewModel.user.value if (binding?.questResponseWrapper != null) { if (userId != party?.quest?.leader && user?.party?.quest?.key == group.quest?.key && user?.party?.quest?.RSVPNeeded == false) { binding?.questLeaveButton?.visibility = View.VISIBLE diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt index 7e61daf32..943295fc7 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt @@ -29,6 +29,7 @@ import com.habitrpg.android.habitica.ui.viewHolders.tasks.DailyViewHolder import com.habitrpg.android.habitica.ui.viewHolders.tasks.HabitViewHolder import com.habitrpg.android.habitica.ui.viewHolders.tasks.RewardViewHolder import com.habitrpg.android.habitica.ui.viewHolders.tasks.TodoViewHolder +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import retrofit2.HttpException @@ -41,6 +42,9 @@ class ChallengeDetailFragment : BaseMainFragment lateinit var challengeRepository: ChallengeRepository @Inject lateinit var socialRepository: SocialRepository + @Inject + lateinit var userViewModel: MainUserViewModel + override var binding: FragmentChallengeDetailBinding? = null @@ -236,7 +240,7 @@ class ChallengeDetailFragment : BaseMainFragment binding?.creatorAvatarview?.setAvatar(creator) binding?.creatorLabel?.tier = creator.contributor?.level ?: 0 binding?.creatorLabel?.username = creator.displayName - isCreator = creator.id == user?.id + isCreator = creator.id == userViewModel.userID this.activity?.invalidateOptionsMenu() } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt index a92ee5ee9..8ca468010 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt @@ -30,6 +30,7 @@ import com.habitrpg.android.habitica.ui.activities.GroupFormActivity import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils import com.habitrpg.android.habitica.ui.helpers.setMarkdown +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar import javax.inject.Inject import kotlin.math.roundToInt @@ -40,6 +41,8 @@ class NoPartyFragmentFragment : BaseMainFragment() { lateinit var socialRepository: SocialRepository @Inject lateinit var configManager: AppConfigManager + @Inject + lateinit var userViewModel: MainUserViewModel override var binding: FragmentNoPartyBinding? = null @@ -65,7 +68,7 @@ class NoPartyFragmentFragment : BaseMainFragment() { parentFragmentManager.popBackStack() MainNavigationController.navigate( R.id.partyFragment, - bundleOf(Pair("partyID", user?.party?.id)) + bundleOf(Pair("partyID", userViewModel.partyID)) ) }, RxErrorHandler.handleEmptyError() @@ -92,7 +95,7 @@ class NoPartyFragmentFragment : BaseMainFragment() { binding?.usernameTextview?.setOnClickListener { val clipboard = context?.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager - val clip = ClipData.newPlainText(context?.getString(R.string.username), user?.username) + val clip = ClipData.newPlainText(context?.getString(R.string.username), userViewModel.username) clipboard?.setPrimaryClip(clip) val activity = activity if (activity != null) { @@ -103,7 +106,7 @@ class NoPartyFragmentFragment : BaseMainFragment() { binding?.createPartyButton?.setOnClickListener { val bundle = Bundle() bundle.putString("groupType", "party") - bundle.putString("leader", user?.id) + bundle.putString("leader", userViewModel.userID) val intent = Intent(activity, GroupFormActivity::class.java) intent.putExtras(bundle) intent.flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT @@ -132,14 +135,15 @@ class NoPartyFragmentFragment : BaseMainFragment() { } } - if ((user?.invitations?.parties?.count() ?: 0) > 0) { + val partyInvitations = userViewModel.partyInvitations + if (partyInvitations.size > 0) { binding?.invitationWrapper?.visibility = View.VISIBLE - user?.invitations?.parties?.let { binding?.invitationsView?.setInvitations(it) } + binding?.invitationsView?.setInvitations(partyInvitations) } else { binding?.invitationWrapper?.visibility = View.GONE } - binding?.usernameTextview?.text = user?.formattedUsername + binding?.usernameTextview?.text = userViewModel.formattedUsername } private val groupFormResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { @@ -164,7 +168,7 @@ class NoPartyFragmentFragment : BaseMainFragment() { } MainNavigationController.navigate( R.id.partyFragment, - bundleOf(Pair("partyID", user?.party?.id)) + bundleOf(Pair("partyID", userViewModel.partyID)) ) }, RxErrorHandler.handleEmptyError() @@ -196,12 +200,11 @@ class NoPartyFragmentFragment : BaseMainFragment() { companion object { - fun newInstance(user: User?): NoPartyFragmentFragment { + fun newInstance(): NoPartyFragmentFragment { val args = Bundle() val fragment = NoPartyFragmentFragment() fragment.arguments = args - fragment.user = user return fragment } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.kt index 62eea83b3..9aa943813 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.kt @@ -96,15 +96,11 @@ class PartyFragment : BaseMainFragment() { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { val group = viewModel.getGroupData().value - if (group != null && this.user != null) { - if (group.leaderID == this.user?.id) { - inflater.inflate(R.menu.menu_party_admin, menu) - if (group.memberCount > 1) { - menu.findItem(R.id.menu_guild_leave).isVisible = false - } - } else { - inflater.inflate(R.menu.menu_party, menu) - } + if (viewModel.isLeader) { + inflater.inflate(R.menu.menu_party_admin, menu) + menu.findItem(R.id.menu_guild_leave).isVisible = group?.memberCount != 1 + } else { + inflater.inflate(R.menu.menu_party, menu) } } @@ -159,7 +155,7 @@ class PartyFragment : BaseMainFragment() { private val sendInvitesResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { if (it.resultCode == Activity.RESULT_OK) { val inviteData = HashMap() - inviteData["inviter"] = user?.profile?.name ?: "" + inviteData["inviter"] = viewModel.user.value?.profile?.name ?: "" val emails = it.data?.getStringArrayExtra(GroupInviteActivity.EMAILS_KEY) if (emails != null && emails.isNotEmpty()) { val invites = ArrayList>() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt index 3c63575f8..53e4b2036 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt @@ -20,6 +20,7 @@ import com.habitrpg.android.habitica.helpers.DeviceName import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.modules.AppModule import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.schedulers.Schedulers import javax.inject.Inject @@ -42,6 +43,8 @@ class BugFixFragment : BaseMainFragment() { @Inject lateinit var appConfigManager: AppConfigManager + @Inject + lateinit var userViewModel: MainUserViewModel override fun injectFragment(component: UserComponent) { component.inject(this) @@ -124,8 +127,7 @@ class BugFixFragment : BaseMainFragment() { } bodyOfEmail += newLine + Uri.encode("User ID: $userId") - val user = this.user - if (user != null) { + userViewModel.user.value?.let { user -> bodyOfEmail += newLine + Uri.encode("Level: " + (user.stats?.lvl ?: 0)) + newLine + Uri.encode( "Class: " + (if (user.preferences?.disableClasses == true) "Disabled" else (user.stats?.habitClass diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt index 27aab30e1..8a4e33a69 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt @@ -19,7 +19,7 @@ class MountViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject private var binding: MountOverviewItemBinding = MountOverviewItemBinding.bind(itemView) private var owned: Boolean = false var animal: Mount? = null - private var user: User? = null + private var currentMount: String? = null var resources: Resources = itemView.resources @@ -27,10 +27,10 @@ class MountViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject itemView.setOnClickListener(this) } - fun bind(item: Mount, owned: Boolean, user: User?) { + fun bind(item: Mount, owned: Boolean, currentMount: String?) { animal = item this.owned = owned - this.user = user + this.currentMount = currentMount binding.titleTextView.visibility = View.GONE binding.ownedTextView.visibility = View.GONE val imageName = "stable_Mount_Icon_" + item.animal + "-" + item.color @@ -39,7 +39,7 @@ class MountViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject binding.imageView.alpha = 0.2f } binding.imageView.background = null - binding.activeIndicator.visibility = if (user?.currentMount.equals(animal?.key)) View.VISIBLE else View.GONE + binding.activeIndicator.visibility = if (currentMount.equals(animal?.key)) View.VISIBLE else View.GONE DataBindingUtils.loadImage(itemView.context, imageName) { val drawable = if (owned) it else BitmapDrawable(itemView.context.resources, it.toBitmap().extractAlpha()) binding.imageView.background = drawable @@ -53,7 +53,7 @@ class MountViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject val menu = BottomSheetMenu(itemView.context) menu.setTitle(animal?.text) - val hasCurrentMount = user?.currentMount.equals(animal?.key) + val hasCurrentMount = currentMount.equals(animal?.key) val labelId = if (hasCurrentMount) R.string.unequip else R.string.equip menu.addMenuItem(BottomSheetMenuItem(resources.getString(labelId))) menu.setSelectionRunnable { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt index ff7f5f0dc..f4bb3c0c2 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt @@ -24,7 +24,7 @@ class PetViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject 0 @@ -61,7 +61,7 @@ class PetViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject by lazy { - loadUserFromLocal() - MutableLiveData() - } val user: LiveData by lazy { - _user + userViewModel.user } init { @@ -47,11 +40,6 @@ abstract class BaseViewModel(initializeComponent: Boolean = true) : ViewModel() internal val disposable = CompositeDisposable() - internal fun loadUserFromLocal() { - disposable.add(userRepository.getUser().observeOn(AndroidSchedulers.mainThread()) - .subscribe({ _user.value = it }, RxErrorHandler.handleEmptyError())) - } - fun updateUser(path: String, value: Any) { disposable.add(userRepository.updateUser(path, value) .subscribe({ }, RxErrorHandler.handleEmptyError())) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/MainUserViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/MainUserViewModel.kt new file mode 100644 index 000000000..d921c4694 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/MainUserViewModel.kt @@ -0,0 +1,62 @@ +package com.habitrpg.android.habitica.ui.viewmodels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.habitrpg.android.habitica.HabiticaBaseApplication +import com.habitrpg.android.habitica.components.UserComponent +import com.habitrpg.android.habitica.data.UserRepository +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.invitations.GenericInvitation +import com.habitrpg.android.habitica.models.invitations.PartyInvite +import com.habitrpg.android.habitica.models.user.User +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.disposables.CompositeDisposable +import javax.inject.Inject + +class MainUserViewModel(val userRepository: UserRepository) { + + val formattedUsername: CharSequence? + get() = user.value?.formattedUsername + val partyInvitations: List + get() = user.value?.invitations?.parties ?: emptyList() + val userID: String? + get() = user.value?.id + val username: CharSequence + get() = user.value?.username ?: "" + val partyID: String? + get() = user.value?.party?.id + val isUserFainted: Boolean + get() = (user.value?.stats?.hp ?: 1.0) == 0.0 + val isUserInParty: Boolean + get() = user.value?.hasParty == true + + private val _user: MutableLiveData by lazy { + loadUserFromLocal() + MutableLiveData() + } + val user: LiveData by lazy { + _user + } + + init { + HabiticaBaseApplication.userComponent?.inject(this) + } + + fun onCleared() { + userRepository.close() + disposable.clear() + } + + internal val disposable = CompositeDisposable() + + internal fun loadUserFromLocal() { + disposable.add(userRepository.getUser().observeOn(AndroidSchedulers.mainThread()) + .subscribe({ _user.value = it }, RxErrorHandler.handleEmptyError())) + } + + fun updateUser(path: String, value: Any) { + disposable.add(userRepository.updateUser(path, value) + .subscribe({ }, RxErrorHandler.handleEmptyError())) + } +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/inventory/equipment/EquipmentOverviewViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/inventory/equipment/EquipmentOverviewViewModel.kt index ebc740ec1..1d2f454e3 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/inventory/equipment/EquipmentOverviewViewModel.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/inventory/equipment/EquipmentOverviewViewModel.kt @@ -9,6 +9,10 @@ import com.habitrpg.android.habitica.ui.viewmodels.BaseViewModel import javax.inject.Inject class EquipmentOverviewViewModel(savedStateHandle: SavedStateHandle): BaseViewModel() { + val usesAutoEquip: Boolean + get() = user.value?.preferences?.autoEquip == true + val usesCostume: Boolean + get() = user.value?.preferences?.costume == true @Inject lateinit var inventoryRepository: InventoryRepository From dde0aa72b4f43793b031e71a02e15c5194cc8712 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Tue, 1 Feb 2022 10:17:14 +0100 Subject: [PATCH 03/18] update dependencies --- Habitica/build.gradle | 22 +++++++++---------- Habitica/res/navigation/navigation.xml | 2 +- .../habitica/helpers/TaskAlarmManager.kt | 1 + .../android/habitica/modules/AppModule.kt | 2 +- .../android/habitica/prefs/TimePreference.kt | 4 ++-- .../preferences/AccountPreferenceFragment.kt | 8 +++---- .../DayStartPreferenceDialogFragment.kt | 2 +- .../EmailNotificationsPreferencesFragment.kt | 4 ++-- .../preferences/PreferencesFragment.kt | 18 +++++++-------- .../PushNotificationsPreferencesFragment.kt | 4 ++-- .../TimePreferenceDialogFragment.kt | 2 +- .../habitica/ui/views/ExtraLabelPreference.kt | 6 ++--- .../habitica/widget/AddTaskWidgetProvider.kt | 4 ++-- 13 files changed, 39 insertions(+), 40 deletions(-) diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 9b19c603b..c1631b15f 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -51,10 +51,10 @@ dependencies { compileOnly 'javax.annotation:javax.annotation-api:1.3.2' compileOnly 'com.github.pengrad:jdk9-deps:1.0' //App Compatibility and Material Design - implementation 'androidx.appcompat:appcompat:1.4.0' - implementation 'com.google.android.material:material:1.4.0' + implementation 'androidx.appcompat:appcompat:1.4.1' + implementation 'com.google.android.material:material:1.5.0' implementation 'androidx.recyclerview:recyclerview:1.2.1' - implementation "androidx.preference:preference-ktx:1.1.1" + implementation "androidx.preference:preference-ktx:1.2.0" // Markdown @@ -121,10 +121,10 @@ dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0" implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.0" implementation "androidx.lifecycle:lifecycle-common-java8:2.4.0" - implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' - implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' + implementation 'androidx.navigation:navigation-fragment-ktx:2.4.0' + implementation 'androidx.navigation:navigation-ui-ktx:2.4.0' implementation 'com.plattysoft.leonids:LeonidsLib:1.3.2' - implementation "androidx.fragment:fragment-ktx:1.4.0" + implementation "androidx.fragment:fragment-ktx:1.4.1" implementation "androidx.paging:paging-runtime-ktx:3.1.0" implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0' @@ -142,7 +142,7 @@ dependencies { android { compileSdkVersion 32 - buildToolsVersion '30.0.2' + buildToolsVersion '30.0.3' testOptions { unitTests { includeAndroidResources = true @@ -157,7 +157,7 @@ android { buildConfigField "String", "TESTING_LEVEL", "\"production\"" resConfigs "en", "bg", "de", "en-rGB", "es", "fr", "hr-rHR", "in", "it", "iw", "ja", "ko", "lt", "nl", "pl", "pt-rBR", "pt-rPT", "ru", "tr", "zh", "zh-rTW" - versionCode 3218 + versionCode 3221 versionName "3.5" targetSdkVersion 32 @@ -382,8 +382,8 @@ def mainSrc = "${project.projectDir}/src/main/java" task jacocoTestReport(type: JacocoReport, dependsOn: 'testProdDebugUnitTest') { group = "Reporting" reports { - html.enabled = true - xml.enabled = true + html.required.set(true) + xml.required.set(true) //html.destination = "${buildDir}/reports/jacoco" } @@ -404,7 +404,6 @@ task jacocoTestReport(type: JacocoReport, dependsOn: 'testProdDebugUnitTest') { task ktlint(type: JavaExec, group: "verification") { description = "Check Kotlin code style." classpath = configurations.ktlint - main = "com.pinterest.ktlint.Main" args "--disabled_rules=no-wildcard-imports", "--reporter=plain?group_by_file", "src/**/*.kt" // to generate report in checkstyle format prepend following args: // "--reporter=plain", "--reporter=checkstyle,output=${buildDir}/ktlint.xml" @@ -417,6 +416,5 @@ check.dependsOn ktlint task ktlintFormat(type: JavaExec, group: "formatting") { description = "Fix Kotlin code style deviations." classpath = configurations.ktlint - main = "com.pinterest.ktlint.Main" args "--disabled_rules=no-wildcard-imports", "-F", "src/**/*.kt" } diff --git a/Habitica/res/navigation/navigation.xml b/Habitica/res/navigation/navigation.xml index 25342e65e..95648dfb3 100644 --- a/Habitica/res/navigation/navigation.xml +++ b/Habitica/res/navigation/navigation.xml @@ -464,7 +464,7 @@ - + showLoginNameDialog() "confirm_username" -> showConfirmUsernameDialog() "email" -> { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/DayStartPreferenceDialogFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/DayStartPreferenceDialogFragment.kt index ddfecaa8c..b7f33cdff 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/DayStartPreferenceDialogFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/DayStartPreferenceDialogFragment.kt @@ -33,7 +33,7 @@ class DayStartPreferenceDialogFragment : PreferenceDialogFragmentCompat() { return lastHour.toString() + ":00" } - override fun onCreateDialogView(context: Context?): View { + override fun onCreateDialogView(context: Context): View { val wrapper = LinearLayout(context) wrapper.orientation = LinearLayout.VERTICAL picker = TimePicker(context) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/EmailNotificationsPreferencesFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/EmailNotificationsPreferencesFragment.kt index 7d81ddb33..0e1910c6c 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/EmailNotificationsPreferencesFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/EmailNotificationsPreferencesFragment.kt @@ -19,12 +19,12 @@ class EmailNotificationsPreferencesFragment : BasePreferencesFragment(), SharedP override fun onResume() { super.onResume() - preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this) + preferenceScreen.sharedPreferences?.registerOnSharedPreferenceChangeListener(this) } override fun onPause() { super.onPause() - preferenceScreen.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) + preferenceScreen.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this) } override fun setupPreferences() { /* no-on */ } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt index 1c289f462..6702d0374 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt @@ -62,16 +62,16 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare override fun setupPreferences() { timePreference = findPreference("reminder_time") as? TimePreference - val useReminder = preferenceManager.sharedPreferences.getBoolean("use_reminder", false) - timePreference?.isEnabled = useReminder + val useReminder = preferenceManager.sharedPreferences?.getBoolean("use_reminder", false) + timePreference?.isEnabled = useReminder ?: false pushNotificationsPreference = findPreference("pushNotifications") as? PreferenceScreen - val usePushNotifications = preferenceManager.sharedPreferences.getBoolean("usePushNotifications", true) - pushNotificationsPreference?.isEnabled = usePushNotifications + val usePushNotifications = preferenceManager.sharedPreferences?.getBoolean("usePushNotifications", true) + pushNotificationsPreference?.isEnabled = usePushNotifications ?: false emailNotificationsPreference = findPreference("emailNotifications") as? PreferenceScreen - val useEmailNotifications = preferenceManager.sharedPreferences.getBoolean("useEmailNotifications", true) - emailNotificationsPreference?.isEnabled = useEmailNotifications + val useEmailNotifications = preferenceManager.sharedPreferences?.getBoolean("useEmailNotifications", true) + emailNotificationsPreference?.isEnabled = useEmailNotifications ?: false classSelectionPreference = findPreference("choose_class") @@ -80,7 +80,7 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare serverUrlPreference = findPreference("server_url") as? ListPreference serverUrlPreference?.isVisible = false - serverUrlPreference?.summary = preferenceManager.sharedPreferences.getString("server_url", "") + serverUrlPreference?.summary = preferenceManager.sharedPreferences?.getString("server_url", "") val themePreference = findPreference("theme_name") as? ListPreference themePreference?.summary = themePreference?.entry ?: "Default" @@ -101,11 +101,11 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare override fun onResume() { super.onResume() - preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this) + preferenceManager.sharedPreferences?.registerOnSharedPreferenceChangeListener(this) } override fun onPause() { - preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) + preferenceManager.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this) super.onPause() } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PushNotificationsPreferencesFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PushNotificationsPreferencesFragment.kt index 4de688c49..97a6eb276 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PushNotificationsPreferencesFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PushNotificationsPreferencesFragment.kt @@ -19,12 +19,12 @@ class PushNotificationsPreferencesFragment : BasePreferencesFragment(), SharedPr override fun onResume() { super.onResume() - preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this) + preferenceScreen.sharedPreferences?.registerOnSharedPreferenceChangeListener(this) } override fun onPause() { super.onPause() - preferenceScreen.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) + preferenceScreen.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this) } override fun setupPreferences() { /* no-on */ } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/TimePreferenceDialogFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/TimePreferenceDialogFragment.kt index b9dc928a5..d7c97b50d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/TimePreferenceDialogFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/TimePreferenceDialogFragment.kt @@ -34,7 +34,7 @@ class TimePreferenceDialogFragment : PreferenceDialogFragmentCompat() { return lastHour.toString() + ":" + String.format(Locale.UK, "%02d", lastMinute) } - override fun onCreateDialogView(context: Context?): View { + override fun onCreateDialogView(context: Context): View { picker = TimePicker(context) picker.setIs24HourView(android.text.format.DateFormat.is24HourFormat(context)) return picker diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ExtraLabelPreference.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ExtraLabelPreference.kt index 54ba9940e..4a5a5cdc7 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ExtraLabelPreference.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ExtraLabelPreference.kt @@ -8,7 +8,7 @@ import androidx.preference.PreferenceViewHolder import com.habitrpg.android.habitica.R class ExtraLabelPreference( - context: Context?, + context: Context, attrs: AttributeSet? ) : Preference(context, attrs) { var extraText: String? = null @@ -18,9 +18,9 @@ class ExtraLabelPreference( layoutResource = R.layout.preference_button } - override fun onBindViewHolder(holder: PreferenceViewHolder?) { + override fun onBindViewHolder(holder: PreferenceViewHolder) { super.onBindViewHolder(holder) - val textView = holder?.itemView?.findViewById(R.id.extra_label) + val textView = holder.itemView.findViewById(R.id.extra_label) textView?.text = extraText extraTextColor?.let { textView?.setTextColor(it) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AddTaskWidgetProvider.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AddTaskWidgetProvider.kt index 9bff91d95..923b83bad 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AddTaskWidgetProvider.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AddTaskWidgetProvider.kt @@ -61,7 +61,7 @@ class AddTaskWidgetProvider : BaseWidgetProvider() { } private fun getSelectedTaskType(widgetId: Int): TaskType { - val preferences = PreferenceManager.getDefaultSharedPreferences(this.context) - return TaskType.from(preferences.getString("add_task_widget_$widgetId", TaskType.HABIT.value)) ?: TaskType.HABIT + val preferences = context?.let { PreferenceManager.getDefaultSharedPreferences(it) } + return TaskType.from(preferences?.getString("add_task_widget_$widgetId", TaskType.HABIT.value)) ?: TaskType.HABIT } } From 354a73f6f18ecb49cff28bfe6bf2f9ef4076d55f Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Tue, 1 Feb 2022 11:33:45 +0100 Subject: [PATCH 04/18] Remove unused call --- .../habitrpg/android/habitica/data/SocialRepository.kt | 1 - .../habitica/data/implementation/SocialRepositoryImpl.kt | 4 ---- .../android/habitica/data/local/SocialLocalRepository.kt | 1 - .../local/implementation/RealmSocialLocalRepository.kt | 8 -------- 4 files changed, 14 deletions(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/SocialRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/SocialRepository.kt index 721e7ace7..af3994412 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/SocialRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/SocialRepository.kt @@ -84,6 +84,5 @@ interface SocialRepository : BaseRepository { fun getGroupMembership(id: String): Flowable fun getGroupMemberships(): Flowable> - fun getChatmessage(messageID: String): Flowable fun blockMember(userID: String): Flowable> } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt index acfbb2bde..d306620b3 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt @@ -37,10 +37,6 @@ class SocialRepositoryImpl(localRepository: SocialLocalRepository, apiClient: Ap } } - override fun getChatmessage(messageID: String): Flowable { - return localRepository.getChatMessage(messageID) - } - override fun blockMember(userID: String): Flowable> { return apiClient.blockMember(userID) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/SocialLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/SocialLocalRepository.kt index aebf06a4b..2dd96f015 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/SocialLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/SocialLocalRepository.kt @@ -47,5 +47,4 @@ interface SocialLocalRepository : BaseLocalRepository { fun saveGroupMemberships(userID: String?, memberships: List) fun saveInboxMessages(userID: String, recipientID: String, messages: List, page: Int) fun saveInboxConversations(userID: String, conversations: List) - fun getChatMessage(messageID: String): Flowable } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt index 07329b047..2bac1fc16 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt @@ -12,14 +12,6 @@ import io.realm.Sort import java.util.* class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), SocialLocalRepository { - override fun getChatMessage(messageID: String): Flowable = RxJavaBridge.toV3Flowable( - realm.where(ChatMessage::class.java) - .equalTo("id", messageID) - .findAll() - .asFlowable() - .filter { it.isLoaded && it.isNotEmpty() } - .map { it.first() } - ) override fun getGroupMembership(userId: String, id: String): Flowable = RxJavaBridge.toV3Flowable( realm.where(GroupMembership::class.java) From 703f51d28ddceb462bd6ec3fe77c9775ff4d9e87 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Tue, 1 Feb 2022 12:14:13 +0100 Subject: [PATCH 05/18] Fix crashes --- .../habitica/data/implementation/SocialRepositoryImpl.kt | 4 +++- .../habitrpg/android/habitica/ui/viewmodels/GroupViewModel.kt | 3 ++- .../habitica/ui/views/dialogs/PetSuggestHatchDialog.kt | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt index d306620b3..954164dd4 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt @@ -88,7 +88,9 @@ class SocialRepositoryImpl(localRepository: SocialLocalRepository, apiClient: Ap return Flowable.empty() } val liked = chatMessage.userLikesMessage(userID) - localRepository.likeMessage(chatMessage, userID, !liked) + if (chatMessage.isManaged) { + localRepository.likeMessage(chatMessage, userID, !liked) + } return apiClient.likeMessage(chatMessage.groupId ?: "", chatMessage.id) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/GroupViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/GroupViewModel.kt index ceee471c5..81f5a3c27 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/GroupViewModel.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/GroupViewModel.kt @@ -249,7 +249,8 @@ open class GroupViewModel(initializeComponent: Boolean) : BaseViewModel(initiali } fun likeMessage(message: ChatMessage) { - val index = _chatMessages.value?.indexOf(message) ?: return + val index = _chatMessages.value?.indexOf(message) + if (index == null || index < 0) return disposable.add(socialRepository.likeMessage(message).subscribe( { val list = _chatMessages.value?.toMutableList() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt index 1358370e3..408825289 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt @@ -6,6 +6,7 @@ import android.view.LayoutInflater import android.view.View import android.widget.LinearLayout import androidx.core.graphics.drawable.toBitmap +import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.databinding.DialogPetSuggestHatchBinding import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler @@ -36,6 +37,7 @@ class PetSuggestHatchDialog(context: Context) : HabiticaAlertDialog(context) { val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as? LayoutInflater inflater?.let { binding = DialogPetSuggestHatchBinding.inflate(it) } setAdditionalContentView(binding.root) + HabiticaBaseApplication.userComponent?.inject(this) } fun configure(pet: Animal, egg: Egg?, potion: HatchingPotion?, eggCount: Int, potionCount: Int, hasUnlockedEgg: Boolean, hasUnlockedPotion: Boolean, hasMount: Boolean) { From 05227415e4f2f93a99c52151a36d632e3872b1aa Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Tue, 1 Feb 2022 16:43:00 +0100 Subject: [PATCH 06/18] update present icon --- Habitica/build.gradle | 2 +- Habitica/res/drawable-hdpi/gift_sub_gift.png | Bin 893 -> 1413 bytes Habitica/res/drawable-mdpi/gift_sub_gift.png | Bin 694 -> 968 bytes Habitica/res/drawable-xhdpi/gift_sub_gift.png | Bin 958 -> 1619 bytes .../res/drawable-xxhdpi/gift_sub_gift.png | Bin 1396 -> 2383 bytes 5 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Habitica/build.gradle b/Habitica/build.gradle index c1631b15f..38e49f375 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -157,7 +157,7 @@ android { buildConfigField "String", "TESTING_LEVEL", "\"production\"" resConfigs "en", "bg", "de", "en-rGB", "es", "fr", "hr-rHR", "in", "it", "iw", "ja", "ko", "lt", "nl", "pl", "pt-rBR", "pt-rPT", "ru", "tr", "zh", "zh-rTW" - versionCode 3221 + versionCode 3223 versionName "3.5" targetSdkVersion 32 diff --git a/Habitica/res/drawable-hdpi/gift_sub_gift.png b/Habitica/res/drawable-hdpi/gift_sub_gift.png index 30842a74b8575cf6fd04c989878100e7b869ac30..278e05552afe64f61af6c00e601780d2fc883c2b 100644 GIT binary patch delta 1395 zcmV-(1&sRr289cdBYyw{XF*Lt006O%3;baP0000uWmrjOO-%qQ0000800D<-00aO4 z0096102%-Q00002paK8{000010000apaTE|000010000d00000PG-9n000E|Nkl7%Q6n-l2t;4cG*XF2fOqyZtEaQ>C9g-+ZUePmkd*AX6_ zoQy5F_Dc-lIRM_Q!U-W?1JO@R^!Hz@(0eaC&wZ0{+}uSDFy!e1dKUDqcym*oj zoTql%JN4au?z$f!%iC+AkPVAybTqwZ=%Rg|&haIGiuS89V*J^z>%&E?PODzVnkYG=64TRmYR_r+dayZv-J9ocgwx zbLRr4JQ_5B|9S*y6nyZ^ToI9&`LIX`;K4QUR{28)WE(9cNR0s*PaH zcKG|a@_&S?CqPV~*G~&ZZX7S&KKY+><3Ba0Z>8hZv;6V1MIC@qJ=U4{6YOcPIAcHI?DWkWmbv^OGWR%Qb}#$(pOnxi(*r}Ng+>-;&)E1YjNz8A(J+M$I$Xe_ zZWoZ2wiZa<(N=}F3I!;cW?3(G5htX8He0HID+&zuRyf(Q^HO)WB~)^kb+&|GM+aZl zGJnLC>0U4b!`!MQmrb!Aqzkc&)(Qq|sel|F^MVnEGN4N%BNmDD93qswiu&axO4rqb zv1EWujW>+>bc(VZJZ)f)%v^5Lpg%o0IH3Y$%2eg9@$pv6gyUFK$2gEaTxB3G(VBqv zF8sQzG%JtkLc`jP%wv&!MnOB39vHY9gnuK)`#zrw8t`-&3S}XPG94mwhwQku*_Es! z<+!`70xEef;yYtM=ewfP=n_0vmCC_iI9=8a;tJa{<vNC`pt7k_IZGYOIgDOD+hrqucAfVw=wh>TJ+Em>JLn<3V@&-detf;yThHO+eg5-u{ zsN&O6bh0|D^V3l@8QA~$|DqQb{ol7tBLjA+zHb>VX`0GZML_xDUlF_yspBbp^ZF?prVvyb0mC>C! zmr)(Q?(+L8{y$#@tIh6UmH8P2AVO5;YWRO~toF#aVk7_npMPi4WETlTIwTD7Fq0<0 zOBnJrWSJ}{=LhVY(P@OJEd&z45u!HV3RYW&{A{;>)sT!ln@WK)6cWH8p^4j4AJxR~ z&1e9W$->I8uqUQMk>X@zKC&?!_5>%wfgvAD8Ai$ZfDpBH5LN(tT9)l7lDaYyhWU++ zM=)eD=R;r&w0{^G7L8>LM<$Q>5uVH)5i%?ipD(Gl&|ThvYRirKqqE$JvRJ-<^Epz6 z+}S{9?%<+?UFuXTGV^UriF06I76hv-rF_qaYHc9dO*;NQUN!31vXTjsEc!X7C-x9f!v2lg#Z2(GuKdUQP{-`WN-xLiHjep$d3uc8vwbl+|g_2wZlJG-W zkoy)wq}y+S!K=nDMkvAV<`q)pXNxN{P2NX4%Wrptny9Z~NskE?3e#A@?=T{cP*pjQ zFq8-x;<|*U|EhP@qn{3LiSZ;jJlweQ1;&L+?jzUy%rM{iNpwpwp5UWPhVgtyh4E(l zpN)^({eNlz2-$2kNLhQxpLMF|Lv`NgL$w}ImjN4HpyQt=(D4t`vrfO5?{=0MuXIf{ zoWjk8LIxld>3lUv*mjVYVMjf@4BqMjVrIO5LT%!<0ih_CTS2PP$;*_YDqcqI&jDg) zeAXy(DGcjM-IiuW|IU3s|C-LTVg1E1*f_@&kfTtMz(psr&WUfL@t9 z1u>$@K`%!_j8H(RQ^LXR9TWEhAvEf31{wA&mf0sSu}qqr561rH7Q~EpgdHo?J;k_1 z=wJeCKG2E1%4W{022=jZ5ybq?IY&QOp@2|8C?FIN3J7&b*t4Tu!fqgh|9a>^x{Y9& xQF(^t#j2{${4aIfM-*<1ICx-4H$O%l1OV2De<6l2<3<1g002ovPDHLkV1k3Oq67c{ diff --git a/Habitica/res/drawable-mdpi/gift_sub_gift.png b/Habitica/res/drawable-mdpi/gift_sub_gift.png index fd10d6689eae4f600fcd55b6076d41cd3a39111c..d133275949c54b37b67d370e4d5aa49b928a2026 100644 GIT binary patch delta 947 zcmV;k15Et31;_`GBYyw{XF*Lt006O%3;baP0000uWmrjOO-%qQ0000800D<-00aO4 z0096102%-Q00002paK8{000010000OpaTE|000010000Q00000yFCQ=0009!NklT1Z-?rl;n3wi>hY-o-2Td(kL#$4)q`SMe z;D~!dKq@q7ihn31y*RjkS9^(G3hUG9dd3U4q|fq+Hbm%r*xY(b>4|#zc{ur7aAgp( z5g|^eZuDGGVz@S^)76yucgh7<7y)>EX0 zhO*0jnNa8efS4zUCk5%bU_gWr`v@UW zm#XVZ4L+YHn;Lb-e$>-KLBRoqI06Rw!8tuE5L;x&fgW{C6%U}{M(+yXY(Q3JYwP$6 z0kiVFlZojGsB5T=Oup-alg%n;CY8PnIl&L^?rdJW{Tw3KTQu0V{V^DD01;nCQ6!^+ zE7@~AnSVd1Ov%*u6_Iu@N`lKvA(LK9B*-BZTw(BN)9p=)QHxq&ykCb~@>Q^b*V?CAqPDzn?w6W_~X`$CR{kW0A z$jYGF(6n{l+>q7OyYGW@GgqQ37W5VsEB-cbj(_G#I+_rFAtaY9E78qQEhv#+-tUJ$ z#hCgI(6Dx^k~sBFaG(o|%QN~u7!|L+ShU)*a*Z=)DckVVulmgBlZ?y97?b6*xwSL( zjR}1XgA5G~XF8M|ToK9aUE0|vxL6Z{im6v0gOS5ES`{9$bLA7T*KRQ^;uAB?!Orf3 z`hU9?OtLg3tSVn7h(N^*iQ8aR2MK1(32u>D!GOh_Vpzn-ZIgyVlpt=+qH1!=EsVz@ zRx?|hDr@UBHIo#moi7Im+ZNH5P5B}JPf+#@ik1KV7Dd<8XL&N&HTC5$h30}Urkly= z9qSA)x!D`yi#RyK)s&!Mme zS+{*vB}Huj%7-2`&kt6azXcyP0guXzho~$ma$?jblfZ^#k$=ADnS>8`NbG(#N#+ZR zS=nwDkRwE8{v4_?H5JRV2;U(jl!JZtIg2D~am67TbErft2{C;L*V@zk0a*mLN>(l$ ziHj>ny%Wfenm@5qQ!Eoi0zlbZ22Wude-+6dvr~0kG>V5m0(9nNiA-gF!}8q!J5+6f z+!H6D&ecorYkyz5@Fw>dCF(JDTRIAi<^oW!*eS68Y>HxSMNs$ZC7v2*Pw^rpvM8bh zzi1H}Yc+N;Zz%9}y!aS)L8+Z+JAY^}+jnYHYt-lK!=KQhqPL zo0>+iz<(7-Qg@wX4f=OD41F?p%QCF~{;QJPv3VEY_r^nx$pdK^U&}4ajMknDyg2YDIT*kJ-vLNAE+QVK>X85d002ovPDHLk FV1g^YFxUV9 diff --git a/Habitica/res/drawable-xhdpi/gift_sub_gift.png b/Habitica/res/drawable-xhdpi/gift_sub_gift.png index cb0b08379a7de16f56f20d4be913269318c12ca2..f13dbf10545efb469f22b4976cd4b482b7b601d3 100644 GIT binary patch delta 1603 zcmV-J2E6&c2h$9YBYyw{XF*Lt006O%3;baP0000uWmrjOO-%qQ0000800D<-00aO4 z0096102%-Q00002paK8{000010000mpaTE|000010000q000004S(qN000HXNklPjW zWIJB@nrjyymwzPI0vtm0sYc`y2fR=8k6si{{1gh^cA7I|0i1JO&>G&xINwVXRJs^; zfQY+$H#ePi!eo=zU%tEu6lpIdXA6*DTRftSzzGFc&K<`)y~ePOC=|aoxJ{1$E(2DJ`PZ9r?<+;Pk(!$5;wLjs2eou1S3;(BD`xn z!K=2k=Cr))dv)4C(5>@m&odiNjfu`KYd!PPh>|+Y zfj1do8YzOz_7k&C6KG>HHnf{_n5FT?k&^?M)l7Dxx^km%fQ>jYfW z0tKN@0eL;$#W&JDzmXQ|GXv8cqOjvasP2F!F?k9eYdc2)t%1;K?2AFb1#AZCXJ0(;I%JbIvB}fdO~N_S!@&VXsi7OQbDG3@~>VA1imY8i!Xbi8NINVGV3Vd|NghI zfQMZnPbAhe;TXymH)gf13eL-l>4|-s72^abw2)I~@+F`274V3H@SZVSDSst3PXQ@= z8y!sg7Ah>jSk8w* z>ksvs^Qk4lAv)k`?6^jpJ%1IH#pc(k)-SR|Zv>JR&TnSi9F_<8h*e)`A!|nR%@-<= z?~Ggh6)IrONWS?(1@fJ7tG_}8tQpBSU#LL7Gj8=)sDL#i`Q|5m1u~uo;!>ZNeh!^b zA`?RjB=4JF_(n_2FQt?8nq5ld^bDU7gE&%@5pRYdk?Qx+Lw$yEE<6Ht0dmB=fWcz( ze;`OvdZeii#nJgHFaAo{I0>q z&0&x#cD`|ijlbdO%*>7Sid$rG3YM0Pk{?9_|BcHk%LdH@u5k(bW4WeKS&a~Jg_B>o z81bVE3%4^#{vWl(2_P6ZL3o_%L01UEE_g&*G=x>)`&W2`gjnRQB_-SA6)g#u)W#%% z2}{0cj2vL&zkg9=DCjh}Q&vSCnX0O-iILHP5`Q#8Z*H>t|(FDG*=aersGkYk0CUb3~=(t zEXC-o<1!EyMp!(I<7+C>lI;NrJVXR2Z?|$~r42Ytgo>;x)&iM60D_r_S7n2Pzmz&a zl9xRI?|+ZC)vv}5{v(=zq>NnkfVvuFl0`~+katEPu!U;C(+F*VN9heLGp{EAUr*4n z)s+zgj;Sc6U3vHMfxxz^^5mvYv8=Fhd3que({sW%aBVd*%Rr|*s4+wFa#h)D5Ai;w z#ziN4KR)$ZpM3mXzOiHP@uE?4+z22ndfsI?MpOsTDuT3R|~(2h3M zGPVRo?YoJsrD#KK2|B2#F)#Cd|KtB~?m73K?|k2VxDWSNJFJzkptK+W01!r_EF6v* zbqp*&=(tke*ts1O&<|;Y1ORB6LfjjC$Gw3s4o$GJ0jM2oegF^E9{@a7Jjake1^{rP z^u&J?R4MO&8vCzl+>jl09BW5gAe~}();$7)AWR99Xu{exhU5%Q_zmb}kOypRc>e8x zVaQht$WLxyF6w!;045hx1$i5g^sIUs^~d+UiF~(m=j`f>{u8EXp_D6Z-gHZF7vWb6 zF*k@&O6eO5;~?%N%Q$4nz;*IbOKmhETGM%=B?lfc6g}ABN58ZS*9!#L19{2GzCO2O zI3I{R7UsHD8&7j<&I7BHbJS$D%~hMV&`VG3n(;SdS%2NqG7+kp(Yw^3hJ3RQLFtvf z5>e5#JkpbSkNU{zv$V3Jv=v>SUJ^_3$*OQUDPtu@PZLhOP!tjQ5GbqQbeE;IxnWdj zQ*VbmRgRH2rk$$fK*Yq`p=VzT@SNqBQh2@dKrgsNAp{>5NsvaIlbQvpeaKXdY6vHc z$oV)t?5=feinDcH;(L)YXcI47`9rVy)@n;*r_fPTrplc3`tqJi(H{y(8!EM4y3ho0 z#l(3&ytysWOc{gmVs+B#Qnn=UXFG%D)9FjHgaJ3unrjL$zO=iu3_)%S)bQ@P z5F|uR%PKx2cr{}RP+r1ODGrc=;(|kmeohFCi5JR=sJ2_uxC0t4UFn%K?94_EuRll7 zDN8{_-EQX$6L)cYsH>@Qv19)Fa~xON`X8vlml3WYNwPi+8qy{!?Rt;zf&FCSkKtk4mc4g8 z`!6SLidrUP{wm)|GpeYFCm9JLLCYUVeAMrAit?rxc%~?|0cS4hkrIWykhUh69$V7TSl9Ra?i#eC zs#!RBjMQJ2ctox3Nf4RLnM7G6rBdRe^h+RDuYB(-+-fx^5v{r0{q4kb^{mk-)Unf&!zr-kd=<%spMMFzc2XB&9s2Jtv61 zIldyS_Reo4OWP>35OItx-eu}8g3%r_^D0~uvOf!sj;XrKBcz8lf)M#;3fk*THfz+U z751NDQ4VsLK3v>^Z_{1hEd92=xH?A03aPzjxeDvA1ZvK=%viC?(JPFK3?*5y$a=~( zo?G(oBeC5!x@3iUj-YFHVFLhHehFg53tm2(M93>Ah^npRCCj)<1+> zUdXAFLnDg8+u7$AH=e{V$98q(+Kx%OE3$%Belxo2?tVt|irXD@)~}4F=euGkF)U*V zSD1*zvO*h@)SfTMUSpHf1UwMy`6rxDWz>@{35WeWKvdKiy15e#=&oV-0MyLR%6Up*d~# z7J3?S{LPtkvLid+e)@hbigRuJ&~^SXV0?n9E8PD!vjNomcK(iL={moNIJGZzD|4}J z-s1wj`$3z+`3N2BDZ5$yKqb4X{W7<0WM0j%u6R-4MOlYU{O!Cj<199jotNUzq`$tq zK+%z?H?Bcv+62DZBjsS!u4UmPuVxIpUc%IBwGDK6K=^o9!^>EeW|4xH1}6)WR+L7s z$X#C{%SK4#{F3{%{C*fMNaA;YpU2YqfOOS~9r3-T&5zc9%qnKo;zBll9K8S{i{sSz z#em_^`Br&~0Z_!MRLarEm{jEy(NuV{rPfU8**mFj3XOO{27Qh7u)bWx%m zH*WK)|7q_-*Y7H6eBlV+-K2b3{M^eR6nGNto+#SKhYs8emRopFC`}1lE_bNO6TgzCliGr{f-I{C(5+ECZ!@RPQ zWLXhj7|th4HuW9gq@>jUX~W2{xirm=nte7x3AQ~u-<{-?xIkX9&H&9 eBk}$3Wb?IMRlj`owH$0v7$ZWV-JRtVj~v8L7(1j)I3_z3 z+Wwz3zwDl#ozpaJ2&apqxR`jD@j2ChII5y%A2$!qclm-oCw~uCJAFa;r));w>vHkI zw_UtY;;!o0$xe`x4tYgyXPPlX$)z0l>ZkQq^J6?NKC| z90VUu5f^whZKUN1I0N8V)K4~$09dOg&@q$`9^D@tR5fXwDlY3c45mM&sp<$z%^2Y< zBnGgKG{^0qG&~U;1XGL_vW6VM@^;hu>`AC!yk#tea)0Kz{K64rII0&dV7;*rn(?ag zHKvm=${$UB3kswj9z;hA!fsY@yphOJ2xlP`6wFpT9m4JK)x(49=z!pZw(^&K;hf&o zv?FTBF^VXdDpE7efB;n#d`{_oYsn8&#J~e7($n~(mk-Rf9f$|>%?|$=VRXq@Me{O;%}HP9Q5z`VBBl||hhYYMwN)_)dtbNP$GR zC&KlcHR#uc+NU=mE1Hbdg;^DRl}41fT52xV=D{HVzBq zu9EjeePoFpKsn7#mVpX7T5SZ9^xiL2d2o{*KzVH~7J*PY+iU~!hLzl2fkvP+SL4ng zZGWJw#sqk0Bhr1jkp~b{$A!Rl+*uT9nmlfG@`EW;~BU#sXaPz^3 zESx11XIRx_SkT$lYjgI7Ra#ZEnA7A-9Df5f2A7BScl*ITsDaNONTjjT>P&$$>!UO( zrqOtsLG;+?;*^Sz^^{LNH>;xIjM9qvr<`25>Eu%?pjmQnFN5P>=KIboJoLO4_%+vm zTetQ4uWR6S1iAF_5Ipm2fX^9V!@0)=XJ3$26*1O88pp-S6_7>>Zw|mQAAd)jn|~+Q z66czSLy*=w{>eZLhygJm2E>4lANmrc5d$bqZ6VGJOV$#{0HU;xe>4ySVn7Ut0WqKx zhQBQ1a{SO2wbCKav?Q9sOTV6#^>N)wTr$6sR%d)8t-<9{amHF)9;uzN=Ap^mt8uyd zw&1+e$G*~$XiggTvTo+!FdHX~cz?Z^)~ho9(a(v`gKl_l61?2=8I|07ao|Ez2nNJ} z7!U(uK>tFZGe&)!f99x4V00Sab)AZCcdjJ3c07*qoM6N<$g49l#6#xJL From e08b3a9d5bec5e38a5be94abe7b666dc9a6c9900 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Tue, 1 Feb 2022 17:03:29 +0100 Subject: [PATCH 07/18] fix icon --- .../habitica/ui/views/yesterdailies/YesterdailyDialog.kt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt index 4deb34968..2f075e230 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt @@ -159,11 +159,7 @@ class YesterdailyDialog private constructor(context: Context, private val userRe private fun configureTaskView(taskView: View, task: Task) { val completed = !task.isDisplayedActive val checkmark = taskView.findViewById(R.id.checkmark) - if (task.completed) { - checkmark?.drawable?.setTint(ContextCompat.getColor(context, R.color.gray_400)) - } else { - checkmark?.drawable?.setTint(ContextCompat.getColor(context, task.darkestTaskColor)) - } + checkmark?.drawable?.setTint(ContextCompat.getColor(context, R.color.gray_400)) val checkboxHolder = taskView.findViewById(R.id.checkBoxHolder) val checkboxBackground = taskView.findViewById(R.id.checkbox_background) checkmark?.visibility = if (completed) View.VISIBLE else View.GONE From 2ed5a7d1244079696ee93a663745bf712b0029c2 Mon Sep 17 00:00:00 2001 From: Hafizzle <34069775+Hafizzle@users.noreply.github.com> Date: Tue, 1 Feb 2022 15:25:32 -0500 Subject: [PATCH 08/18] Fixed chat scroll (#1703) Data observer added to Chat Adapter --- .../ui/fragments/social/InboxMessageListFragment.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt index 5abbb4fa1..eb2708ff5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt @@ -7,6 +7,7 @@ import android.os.Bundle import android.view.* import androidx.appcompat.app.AlertDialog import androidx.fragment.app.viewModels +import androidx.recyclerview.widget.RecyclerView import com.habitrpg.android.habitica.MainNavDirections import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent @@ -89,6 +90,13 @@ class InboxMessageListFragment : BaseMainFragment From 9088d1d566264d66f7c6ae7661b8cb0633ef2bc9 Mon Sep 17 00:00:00 2001 From: Hafizzle <34069775+Hafizzle@users.noreply.github.com> Date: Mon, 7 Feb 2022 15:13:08 -0500 Subject: [PATCH 09/18] Discard Modal for user editing a Task and presses back (#1704) * Check created task being edited isBeingEdited added to check for views being edited check for edited views onBackPressed Add res Strings for discard dialog * Compare by task Check if user is editing by comparing dummy task created during init to any changes * Discard dialog events added fire events to check if user accepted discard on back pressed, or if cancel was pressed and task was saved. Code cleanup * Dialog dismiss listener added Set isDiscardCancelled true to Dialog onDismiss * Format code / cleanup --- Habitica/res/values/strings.xml | 3 + .../android/habitica/models/tasks/Task.kt | 41 +++++++ .../ui/activities/TaskFormActivity.kt | 112 +++++++++++++----- 3 files changed, 126 insertions(+), 30 deletions(-) diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index 2db385876..a9fb5ff8e 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -142,6 +142,7 @@ Rewards Yes No + Discard Quest Body Hair @@ -523,6 +524,7 @@ Your device does not have any of the supported payment methods. Please use the habitica website if you want to purchase gems. Your device does not have any of the supported payment methods. Please use the habitica website if you want to purchase a subscription. Save + Unsaved Changes Location Gem prize Tasks @@ -547,6 +549,7 @@ Start My Day Are you sure you want to leave this party? Do you want to keep participating in the Challenge when leaving the Party? + Are you sure you want to discard changes to this task You will not be able to rejoin this party unless invited. Pending Accepted diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt index 7a1b66989..ebcfa2949 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt @@ -256,6 +256,47 @@ open class Task : RealmObject, BaseMainObject, Parcelable { } } + fun isBeingEdited(task: Task): Boolean { + + when { + text != task.text -> return true + notes != task.notes -> return true + reminders != task.reminders -> return true + checklist != task.checklist -> return true + priority != task.priority -> return true + attribute != task.attribute && attribute != null -> return true + tags != task.tags -> return true + } + if (type == TaskType.HABIT) { + return when { + up != task.up -> true + down != task.down -> true + frequency != task.frequency -> true + counterUp != task.counterUp -> true + counterDown != task.counterDown -> true + else -> false + } + } else if (type == TaskType.DAILY) { + return when { + startDate != task.startDate -> true + everyX != task.everyX -> true + frequency != task.frequency -> true + repeat != task.repeat -> true + streak != task.streak -> true + else -> false + } + + } else if (type == TaskType.TODO) { + return dueDate != task.dueDate + + } else if (type == TaskType.REWARD) { + return value != task.value + + } else { + return false + } + } + override fun hashCode(): Int { return id?.hashCode() ?: 0 } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt index edd88c8e3..d8c1b69b2 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt @@ -1,6 +1,7 @@ package com.habitrpg.android.habitica.ui.activities import android.app.Activity +import android.content.DialogInterface import android.content.Intent import android.content.SharedPreferences import android.content.res.ColorStateList @@ -13,6 +14,7 @@ import android.widget.CheckBox import android.widget.TextView import androidx.appcompat.widget.AppCompatCheckBox import androidx.core.content.ContextCompat +import androidx.core.os.bundleOf import androidx.core.view.children import androidx.core.view.forEachIndexed import androidx.core.widget.NestedScrollView @@ -21,7 +23,6 @@ import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.ChallengeRepository import com.habitrpg.android.habitica.data.TagRepository import com.habitrpg.android.habitica.data.TaskRepository -import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.databinding.ActivityTaskFormBinding import com.habitrpg.android.habitica.extensions.OnChangeTextWatcher import com.habitrpg.android.habitica.extensions.addCancelButton @@ -64,6 +65,7 @@ class TaskFormActivity : BaseActivity() { private var isChallengeTask = false private var usesTaskAttributeStats = false private var task: Task? = null + private var initialTaskInstance: Task? = null private var taskType: TaskType = TaskType.HABIT private var tags = listOf() private var preselectedTags: ArrayList? = null @@ -74,6 +76,7 @@ class TaskFormActivity : BaseActivity() { setSelectedAttribute(value) } + private var isDiscardCancelled: Boolean = false private var canSave: Boolean = false private var tintColor: Int = 0 @@ -198,6 +201,7 @@ class TaskFormActivity : BaseActivity() { { if (!it.isValid) return@subscribe task = it + initialTaskInstance = it // tintColor = ContextCompat.getColor(this, it.mediumTaskColor) fillForm(it) it.challengeID?.let { challengeID -> @@ -224,17 +228,21 @@ class TaskFormActivity : BaseActivity() { task = bundle.getParcelable(PARCELABLE_TASK) task?.let { fillForm(it) } } - else -> title = getString( - R.string.create_task, - getString( - when (taskType) { - TaskType.DAILY -> R.string.daily - TaskType.TODO -> R.string.todo - TaskType.REWARD -> R.string.reward - else -> R.string.habit - } + else -> { + title = getString( + R.string.create_task, + getString( + when (taskType) { + TaskType.DAILY -> R.string.daily + TaskType.TODO -> R.string.todo + TaskType.REWARD -> R.string.reward + else -> R.string.habit + } + ) ) - ) + initialTaskInstance = configureTask(Task()) + } + } configureForm() } @@ -252,6 +260,29 @@ class TaskFormActivity : BaseActivity() { } } + override fun onBackPressed() { + val currentTaskInstance = configureTask(Task()) + if (initialTaskInstance?.isBeingEdited(currentTaskInstance) == true) { + val alert = HabiticaAlertDialog(this) + alert.setTitle(R.string.unsaved_changes) + alert.setMessage(R.string.discard_changes_to_task_message) + alert.addButton(R.string.discard, true, true) { _, _ -> + analyticsManager.logEvent("discard_task", bundleOf(Pair("is_creating", isCreating))) + super.onBackPressed() + } + alert.addButton(R.string.cancel, false) { _, _ -> + isDiscardCancelled = true + alert.dismiss() + } + alert.setOnDismissListener(DialogInterface.OnDismissListener { + isDiscardCancelled = true + }) + alert.show() + } else { + super.onBackPressed() + } + } + override fun onCreateOptionsMenu(menu: Menu): Boolean { if (isCreating) { menuInflater.inflate(R.menu.menu_task_create, menu) @@ -437,19 +468,10 @@ class TaskFormActivity : BaseActivity() { } } - private fun saveTask() { - if (isSaving) { - return - } - isSaving = true - var thisTask = task - if (thisTask == null) { - thisTask = Task() - thisTask.type = taskType - thisTask.dateCreated = Date() - } else { - if (!thisTask.isValid) return - } + private fun configureTask(thisTask: Task): Task { + thisTask.type = taskType + thisTask.dateCreated = Date() + thisTask.text = binding.textEditText.text.toString() thisTask.notes = binding.notesEditText.text.toString() thisTask.priority = binding.taskDifficultyButtons.selectedDifficulty @@ -460,8 +482,10 @@ class TaskFormActivity : BaseActivity() { thisTask.up = binding.habitScoringButtons.isPositive thisTask.down = binding.habitScoringButtons.isNegative thisTask.frequency = binding.habitResetStreakButtons.selectedResetOption.value - if (binding.habitAdjustPositiveStreakView.text?.isNotEmpty() == true) thisTask.counterUp = binding.habitAdjustPositiveStreakView.text.toString().toIntCatchOverflow() - if (binding.habitAdjustNegativeStreakView.text?.isNotEmpty() == true) thisTask.counterDown = binding.habitAdjustNegativeStreakView.text.toString().toIntCatchOverflow() + if (binding.habitAdjustPositiveStreakView.text?.isNotEmpty() == true) thisTask.counterUp = + binding.habitAdjustPositiveStreakView.text.toString().toIntCatchOverflow() + if (binding.habitAdjustNegativeStreakView.text?.isNotEmpty() == true) thisTask.counterDown = + binding.habitAdjustNegativeStreakView.text.toString().toIntCatchOverflow() } else if (taskType == TaskType.DAILY) { thisTask.startDate = binding.taskSchedulingControls.startDate thisTask.everyX = binding.taskSchedulingControls.everyX @@ -469,15 +493,13 @@ class TaskFormActivity : BaseActivity() { thisTask.repeat = binding.taskSchedulingControls.weeklyRepeat thisTask.setDaysOfMonth(binding.taskSchedulingControls.daysOfMonth) thisTask.setWeeksOfMonth(binding.taskSchedulingControls.weeksOfMonth) - if (binding.habitAdjustPositiveStreakView.text?.isNotEmpty() == true) thisTask.streak = binding.habitAdjustPositiveStreakView.text.toString().toIntCatchOverflow() + if (binding.habitAdjustPositiveStreakView.text?.isNotEmpty() == true) thisTask.streak = + binding.habitAdjustPositiveStreakView.text.toString().toIntCatchOverflow() } else if (taskType == TaskType.TODO) { thisTask.dueDate = binding.taskSchedulingControls.dueDate } else if (taskType == TaskType.REWARD) { thisTask.value = binding.rewardValue.value } - - val resultIntent = Intent() - resultIntent.putExtra(TASK_TYPE_KEY, taskType) if (!isChallengeTask) { if (taskType == TaskType.DAILY || taskType == TaskType.TODO) { thisTask.checklist = RealmList() @@ -492,10 +514,40 @@ class TaskFormActivity : BaseActivity() { thisTask.tags?.add(tags[index]) } } + } + return thisTask + } + + private fun saveTask() { + if (isSaving) { + return + } + isSaving = true + var thisTask = task + if (thisTask == null) { + thisTask = Task() + thisTask.type = taskType + thisTask.dateCreated = Date() + } else { + if (!thisTask.isValid) return + } + + thisTask = configureTask(thisTask) + + val resultIntent = Intent() + resultIntent.putExtra(TASK_TYPE_KEY, taskType) + if (!isChallengeTask) { if (isCreating) { + if (isDiscardCancelled){ + analyticsManager.logEvent("back_to_task", bundleOf(Pair("is_creating", isCreating))) + } taskRepository.createTaskInBackground(thisTask) + } else { + if (isDiscardCancelled){ + analyticsManager.logEvent("back_to_task", bundleOf(Pair("is_creating", isCreating))) + } taskRepository.updateTaskInBackground(thisTask) } From 741b59b46b65a29125dcc6934bc47164fac62779 Mon Sep 17 00:00:00 2001 From: Hafiz Date: Sat, 12 Feb 2022 03:33:32 -0500 Subject: [PATCH 10/18] Transformation items added to Item special tab --- .../android/habitica/data/UserRepository.kt | 1 + .../data/implementation/UserRepositoryImpl.kt | 3 +++ .../data/local/UserLocalRepository.kt | 1 + .../RealmUserLocalRepository.kt | 11 ++++++++ .../adapter/inventory/ItemRecyclerAdapter.kt | 26 ++++++++++++++++--- .../inventory/items/ItemRecyclerFragment.kt | 12 +++++++-- 6 files changed, 48 insertions(+), 6 deletions(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt index 298c576e2..df8f051de 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt @@ -35,6 +35,7 @@ interface UserRepository : BaseRepository { fun sleep(user: User): Flowable fun getSkills(user: User): Flowable> + fun getTransformationItems(): Flowable> fun getSpecialItems(user: User): Flowable> diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt index 19156f165..0642b1a59 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt @@ -124,6 +124,9 @@ class UserRepositoryImpl(localRepository: UserLocalRepository, apiClient: ApiCli override fun getSpecialItems(user: User): Flowable> = localRepository.getSpecialItems(user) + override fun getTransformationItems(): Flowable> = + localRepository.getTransformationItems() + override fun useSkill(key: String, target: String?, taskId: String): Flowable { return zipWithLiveUser(apiClient.useSkill(key, target ?: "", taskId)) { response, user -> response.hpDiff = response.user?.stats?.hp ?: 0 - (user.stats?.hp ?: 0.0) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/UserLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/UserLocalRepository.kt index 9842db322..3570a1c1d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/UserLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/UserLocalRepository.kt @@ -26,6 +26,7 @@ interface UserLocalRepository : BaseLocalRepository { fun getSkills(user: User): Flowable> fun getSpecialItems(user: User): Flowable> + fun getTransformationItems(): Flowable> fun getAchievements(): Flowable> fun getQuestAchievements(userID: String): Flowable> fun getUserQuestStatus(userID: String): Flowable diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt index 455c2b00d..e1cbc4077 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt @@ -171,4 +171,15 @@ class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), .filter { it.isLoaded } ) } + + override fun getTransformationItems(): Flowable> { + val habitClass = "special" + return RxJavaBridge.toV3Flowable( + realm.where(Skill::class.java) + .equalTo("habitClass", habitClass) + .findAll() + .asFlowable() + .filter { it.isLoaded } + ) + } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt index 9d5188afc..6a15c43d1 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt @@ -9,6 +9,7 @@ import androidx.recyclerview.widget.RecyclerView import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.databinding.ItemItemBinding import com.habitrpg.android.habitica.extensions.layoutInflater +import com.habitrpg.android.habitica.models.Skill import com.habitrpg.android.habitica.models.inventory.* import com.habitrpg.android.habitica.models.user.OwnedItem import com.habitrpg.android.habitica.models.user.OwnedPet @@ -110,10 +111,14 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter "Egg" @@ -203,4 +208,17 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter, ownedItems: MutableList){ + val transformationItems: MutableList = mutableListOf() + for (item in skillItems){ + val ownedTransformationItem = OwnedItem() + ownedTransformationItem.key = item.key + ownedTransformationItem.itemType = item.habitClass + ownedTransformationItem.numberOwned = 5 //Test + transformationItems.add(ownedTransformationItem) + } + data = ownedItems + transformationItems + notifyDataSetChanged() + } } 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 52e1a3262..f7f083dcb 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 @@ -16,8 +16,8 @@ import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.interactors.HatchPetUseCase -import com.habitrpg.android.habitica.interactors.NotifyUserUseCase import com.habitrpg.android.habitica.models.inventory.* +import com.habitrpg.android.habitica.models.user.OwnedItem import com.habitrpg.android.habitica.models.user.OwnedPet import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.ui.activities.BaseActivity @@ -43,6 +43,7 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL var adapter: ItemRecyclerAdapter? = null var itemType: String? = null + var transformationItems: MutableList = mutableListOf() var itemTypeText: String? = null var user: User? = null internal var layoutManager: androidx.recyclerview.widget.LinearLayoutManager? = null @@ -208,9 +209,16 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL .map { it.distinctBy { it.key } } .doOnNext { items -> adapter?.data = items + if (itemType == "special") { + transformationItems = items.toMutableList() + userRepository.getTransformationItems() + .subscribe { skillItems -> adapter?.setSpecialItems(skillItems, transformationItems) } + } } .map { items -> items.mapNotNull { it.key } } - .flatMap { inventoryRepository.getItems(itemClass, it.toTypedArray()) } + .flatMap { + inventoryRepository.getItems(itemClass, it.toTypedArray()) + } .map { val itemMap = mutableMapOf() for (item in it) { From dfbcdc712565b8a625cb1d83f9b362f0b96e7544 Mon Sep 17 00:00:00 2001 From: Hafiz Date: Mon, 14 Feb 2022 05:51:43 -0500 Subject: [PATCH 11/18] Ability to use special items from Items added --- Habitica/res/values/strings.xml | 1 + .../implementation/ContentRepositoryImpl.kt | 1 - .../RealmContentLocalRepository.kt | 1 + .../habitica/models/inventory/SpecialItem.kt | 1 + .../habitica/models/user/SpecialItems.kt | 15 ++ .../adapter/inventory/ItemRecyclerAdapter.kt | 29 +++- .../inventory/items/ItemRecyclerFragment.kt | 154 +++++++++++++++--- .../habitica/utils/ContentDeserializer.kt | 23 ++- 8 files changed, 181 insertions(+), 44 deletions(-) diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index 1047ee33d..807820cdb 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -466,6 +466,7 @@ Each month, subscribers will receive a mystery item. This is usually released about one week before the end of the month. Open> Open + Use Item on party member> You earned a %1$s as a reward for your devotion to improving your life. Next prize in %1$d Check-Ins pending approval diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt index fd4c8cb9e..2868d580b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt @@ -24,7 +24,6 @@ class ContentRepositoryImpl(localRepository: T, apiC return if (forced || now - this.lastContentSync > 300000) { lastContentSync = now apiClient.content.doOnNext { - it.special = RealmList() it.special.add(mysteryItem) localRepository.saveContent(it) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmContentLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmContentLocalRepository.kt index da558dc96..042f35b2f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmContentLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmContentLocalRepository.kt @@ -28,6 +28,7 @@ open class RealmContentLocalRepository(realm: Realm) : RealmBaseLocalRepository( realm1.insertOrUpdate(contentResult.mounts) realm1.insertOrUpdate(contentResult.spells) + realm1.insertOrUpdate(contentResult.special) realm1.insertOrUpdate(contentResult.appearances) realm1.insertOrUpdate(contentResult.backgrounds) realm1.insertOrUpdate(contentResult.faq) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/SpecialItem.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/SpecialItem.kt index 061955b30..521388af6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/SpecialItem.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/SpecialItem.kt @@ -15,6 +15,7 @@ open class SpecialItem : RealmObject(), Item { internal var notes: String = "" override var value: Int = 0 override var event: ItemEvent? = null + var target: String? = null var isMysteryItem: Boolean = false companion object { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt index 681e158eb..b83d50627 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt @@ -17,4 +17,19 @@ open class SpecialItems : RealmObject(), BaseObject { get() { return seafoam > 0 || shinySeed > 0 || snowball > 0 || spookySparkles > 0 } + + fun getSpecialItemCount(key: String): Int{ + var inventoryPresent: OwnedItem = ownedItems?.filter { it.key == "inventory_present" }?.single() ?: OwnedItem() + + var count = 0 + when(key){ + "seafoam" -> count = seafoam + "shinySeed" -> count = shinySeed + "snowball" -> count = snowball + "spookySparkles" -> count = spookySparkles + "inventory_present" -> count = inventoryPresent.numberOwned + } + return count + + } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt index 6a15c43d1..167d20edd 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt @@ -13,6 +13,7 @@ import com.habitrpg.android.habitica.models.Skill import com.habitrpg.android.habitica.models.inventory.* import com.habitrpg.android.habitica.models.user.OwnedItem import com.habitrpg.android.habitica.models.user.OwnedPet +import com.habitrpg.android.habitica.models.user.SpecialItems import com.habitrpg.android.habitica.ui.adapter.BaseRecyclerViewAdapter import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu @@ -38,6 +39,11 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter() private val questInvitationEvents = PublishSubject.create() @@ -45,6 +51,8 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter() private val hatchPetSubject = PublishSubject.create>() private val feedPetSubject = PublishSubject.create() + private val useSpecialSubject = PublishSubject.create() + fun getSellItemFlowable(): Flowable { return sellItemEvents.toFlowable(BackpressureStrategy.DROP) @@ -60,6 +68,7 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter = startHatchingSubject.toFlowable(BackpressureStrategy.DROP) val hatchPetEvents: Flowable> = hatchPetSubject.toFlowable(BackpressureStrategy.DROP) val feedPetEvents: Flowable = feedPetSubject.toFlowable(BackpressureStrategy.DROP) + val useSpecialEvents: Flowable = useSpecialSubject.toFlowable(BackpressureStrategy.DROP) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { return ItemViewHolder(ItemItemBinding.inflate(context.layoutInflater, parent, false)) @@ -111,14 +120,15 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter "Egg" @@ -161,7 +171,10 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter 0) { menu.addMenuItem(BottomSheetMenuItem(resources.getString(R.string.open))) + } else if (ownedItem?.numberOwned ?: 0 > 0){ + menu.addMenuItem(BottomSheetMenuItem(resources.getString(R.string.use_item))) } + } menu.setSelectionRunnable { index -> item?.let { selectedItem -> @@ -181,7 +194,7 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter openMysteryItemEvents.onNext(selectedItem) + is SpecialItem -> useSpecialSubject.onNext(selectedItem) } } } @@ -209,16 +222,16 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter, ownedItems: MutableList){ + fun setSpecialItems(skillItems: List){ val transformationItems: MutableList = mutableListOf() for (item in skillItems){ val ownedTransformationItem = OwnedItem() ownedTransformationItem.key = item.key - ownedTransformationItem.itemType = item.habitClass - ownedTransformationItem.numberOwned = 5 //Test + ownedTransformationItem.itemType = "special" + ownedTransformationItem.numberOwned = specialItems?.getSpecialItemCount(item.key) ?: 0 transformationItems.add(ownedTransformationItem) } - data = ownedItems + transformationItems + data = transformationItems notifyDataSetChanged() } } 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 f7f083dcb..64509ed91 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 @@ -1,9 +1,15 @@ package com.habitrpg.android.habitica.ui.fragments.inventory.items +import android.app.Activity +import android.content.Intent +import android.graphics.drawable.BitmapDrawable import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.activity.result.contract.ActivityResultContracts +import androidx.core.content.ContextCompat +import androidx.lifecycle.lifecycleScope import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent @@ -16,18 +22,28 @@ import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.interactors.HatchPetUseCase +import com.habitrpg.android.habitica.models.Skill import com.habitrpg.android.habitica.models.inventory.* +import com.habitrpg.android.habitica.models.responses.SkillResponse import com.habitrpg.android.habitica.models.user.OwnedItem import com.habitrpg.android.habitica.models.user.OwnedPet import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.ui.activities.BaseActivity import com.habitrpg.android.habitica.ui.activities.MainActivity +import com.habitrpg.android.habitica.ui.activities.SkillMemberActivity +import com.habitrpg.android.habitica.ui.activities.SkillTasksActivity 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.android.habitica.ui.helpers.SafeDefaultItemAnimator import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper +import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar import com.habitrpg.android.habitica.ui.views.dialogs.OpenedMysteryitemDialog +import io.reactivex.rxjava3.core.Flowable +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import java.util.ArrayList import javax.inject.Inject class ItemRecyclerFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener { @@ -46,6 +62,7 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL var transformationItems: MutableList = mutableListOf() var itemTypeText: String? = null var user: User? = null + private var selectedSpecialItem: SpecialItem? = null internal var layoutManager: androidx.recyclerview.widget.LinearLayoutManager? = null override var binding: FragmentItemsBinding? = null @@ -91,7 +108,8 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL adapter = ItemRecyclerAdapter(context) } binding?.recyclerView?.adapter = adapter - + adapter?.specialItems = this.user?.items?.special + adapter?.useSpecialEvents?.subscribeWithErrorHandler { onSpecialItemSelected(it) }?.let { compositeSubscription.add(it) } adapter?.let { adapter -> compositeSubscription.add( adapter.getSellItemFlowable() @@ -204,35 +222,72 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL else -> Egg::class.java } itemType?.let { type -> - compositeSubscription.add( - inventoryRepository.getOwnedItems(type) - .map { it.distinctBy { it.key } } - .doOnNext { items -> - adapter?.data = items - if (itemType == "special") { - transformationItems = items.toMutableList() - userRepository.getTransformationItems() - .subscribe { skillItems -> adapter?.setSpecialItems(skillItems, transformationItems) } + if (type != "special"){ + compositeSubscription.add( + inventoryRepository.getOwnedItems(type) + .map { it.distinctBy { it.key } } + .doOnNext { items -> + adapter?.data = items +// if (itemType == "special") { +// transformationItems = items.toMutableList() +// userRepository.getTransformationItems() //Get from RealmInventoryLocalRepository +// .subscribe { skillItems -> adapter?.setSpecialItems(skillItems, transformationItems) } +// } } - } - .map { items -> items.mapNotNull { it.key } } - .flatMap { - inventoryRepository.getItems(itemClass, it.toTypedArray()) - } - .map { - val itemMap = mutableMapOf() - for (item in it) { - itemMap[item.key] = item + .map { items -> items.mapNotNull { it.key } } + .flatMap { + inventoryRepository.getItems(itemClass, it.toTypedArray()) } - itemMap + .map { + val itemMap = mutableMapOf() + for (item in it) { + itemMap[item.key] = item + } + itemMap + } + .subscribe( + { items -> + adapter?.items = items + }, + RxErrorHandler.handleEmptyError() + ) + ) + } else { + val specialItems = user?.items?.special + val ownedItems = ArrayList() + if (specialItems != null) { + ownedItems.add("inventory_present") + if (specialItems.snowball > 0) { + ownedItems.add("snowball") } - .subscribe( - { items -> - adapter?.items = items - }, - RxErrorHandler.handleEmptyError() - ) - ) + if (specialItems.shinySeed > 0) { + ownedItems.add("shinySeed") + } + if (specialItems.seafoam > 0) { + ownedItems.add("seafoam") + } + if (specialItems.spookySparkles > 0) { + ownedItems.add("spookySparkles") + } + } + if (ownedItems.size == 0) { + ownedItems.add("") + } + compositeSubscription.add( + inventoryRepository.getItems(SpecialItem::class.java, ownedItems.toTypedArray()) + .map { it.distinctBy { it.key } } + .doOnNext { items -> + adapter?.setSpecialItems(items) + val itemMap = mutableMapOf() + for (item in items) { + itemMap[item.key] = item + } + adapter?.items = itemMap + } + .subscribe() + ) + } + } compositeSubscription.add(inventoryRepository.getPets().subscribe({ adapter?.setExistingPets(it) }, RxErrorHandler.handleEmptyError())) @@ -251,6 +306,51 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL MainNavigationController.navigate(R.id.marketFragment) } + private fun onSpecialItemSelected(specialItem: SpecialItem) { + selectedSpecialItem = specialItem + val intent = Intent(activity, SkillMemberActivity::class.java) + memberSelectionResult.launch(intent) + + } + + private val memberSelectionResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == Activity.RESULT_OK) { + useSpecialItem(selectedSpecialItem, it.data?.getStringExtra("member_id")) + } + } + + private fun useSpecialItem(specialItem: SpecialItem?, memberID: String? = null) { + if (specialItem == null || memberID == null) { + return + } + + val observable: Flowable = userRepository.useSkill(specialItem.key, specialItem.target, memberID) + + compositeSubscription.add( + observable.subscribe( + { skillResponse -> this.displaySkillResult(specialItem) }, + RxErrorHandler.handleEmptyError() + ) + ) + } + + private fun displaySkillResult(specialItem: SpecialItem?) { + if (!isAdded) return + + val activity = activity as? MainActivity + activity?.let { + HabiticaSnackbar.showSnackbar( + it.snackbarContainer, + context?.getString(R.string.used_skill_without_mana, specialItem?.text), + HabiticaSnackbar.SnackbarDisplayType.BLUE + ) + } + + compositeSubscription.add( + userRepository.retrieveUser(false).subscribe({ }, RxErrorHandler.handleEmptyError()) + ) + } + companion object { private const val ITEM_TYPE_KEY = "CLASS_TYPE_KEY" diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt index 815dc0ed2..b7176b24f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt @@ -11,14 +11,7 @@ import com.habitrpg.android.habitica.models.ContentGear import com.habitrpg.android.habitica.models.ContentResult import com.habitrpg.android.habitica.models.FAQArticle import com.habitrpg.android.habitica.models.Skill -import com.habitrpg.android.habitica.models.inventory.Customization -import com.habitrpg.android.habitica.models.inventory.Egg -import com.habitrpg.android.habitica.models.inventory.Equipment -import com.habitrpg.android.habitica.models.inventory.Food -import com.habitrpg.android.habitica.models.inventory.HatchingPotion -import com.habitrpg.android.habitica.models.inventory.Mount -import com.habitrpg.android.habitica.models.inventory.Pet -import com.habitrpg.android.habitica.models.inventory.QuestContent +import com.habitrpg.android.habitica.models.inventory.* import io.realm.RealmList import java.lang.reflect.Type @@ -101,6 +94,20 @@ class ContentDeserializer : JsonDeserializer { result.spells.add(skill) } } + + if (obj.has("special")) {//ToDo add special + for ((classname, value) in obj.getAsJsonObject("special").entrySet()) { + val skillItem = value.asJsonObject + val special = SpecialItem() + special.key = skillItem.get("key").asString + special.text = skillItem.get("text").asString + special.notes = skillItem.get("notes").asString + special.target = skillItem.get("target").asString + special.value = skillItem.get("value").asInt + result.special.add(special) + } + } + result.appearances = context.deserialize(obj.get("appearances"), object : TypeToken>() {}.type) result.backgrounds = context.deserialize(obj.get("backgrounds"), object : TypeToken>() {}.type) val noBackground = Customization() From d2774fa53c6f412fefb67705f9e609ff5e1491eb Mon Sep 17 00:00:00 2001 From: Hafiz Date: Mon, 14 Feb 2022 06:41:52 -0500 Subject: [PATCH 12/18] Clean up logic --- .../habitica/models/user/SpecialItems.kt | 23 +++++++ .../adapter/inventory/ItemRecyclerAdapter.kt | 7 +- .../inventory/items/ItemRecyclerFragment.kt | 65 +++++++------------ 3 files changed, 53 insertions(+), 42 deletions(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt index b83d50627..f48108bf8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt @@ -4,6 +4,7 @@ import com.habitrpg.android.habitica.models.BaseObject import io.realm.RealmList import io.realm.RealmObject import io.realm.annotations.RealmClass +import java.util.ArrayList @RealmClass(embedded = true) open class SpecialItems : RealmObject(), BaseObject { @@ -30,6 +31,28 @@ open class SpecialItems : RealmObject(), BaseObject { "inventory_present" -> count = inventoryPresent.numberOwned } return count + } + fun getOwnedItemsToTypedArray(): Array { + val ownedSpecialItems = ArrayList() + ownedSpecialItems.add("inventory_present") + if (snowball > 0) { + ownedSpecialItems.add("snowball") + } + if (shinySeed > 0) { + ownedSpecialItems.add("shinySeed") + } + if (seafoam > 0) { + ownedSpecialItems.add("seafoam") + } + if (spookySparkles > 0) { + ownedSpecialItems.add("spookySparkles") + } + + if (ownedSpecialItems.size == 0) { + ownedSpecialItems.add("") + } + + return ownedSpecialItems.toTypedArray() } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt index 167d20edd..a52edfd82 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt @@ -194,7 +194,12 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter useSpecialSubject.onNext(selectedItem) + is SpecialItem -> + if (item?.key != "inventory_present") { + useSpecialSubject.onNext(selectedItem) + } else { + openMysteryItemEvents.onNext(selectedItem) + } } } } 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 64509ed91..b661f3559 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 @@ -2,14 +2,11 @@ package com.habitrpg.android.habitica.ui.fragments.inventory.items import android.app.Activity import android.content.Intent -import android.graphics.drawable.BitmapDrawable import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.activity.result.contract.ActivityResultContracts -import androidx.core.content.ContextCompat -import androidx.lifecycle.lifecycleScope import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent @@ -22,7 +19,6 @@ import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.interactors.HatchPetUseCase -import com.habitrpg.android.habitica.models.Skill import com.habitrpg.android.habitica.models.inventory.* import com.habitrpg.android.habitica.models.responses.SkillResponse import com.habitrpg.android.habitica.models.user.OwnedItem @@ -31,18 +27,14 @@ import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.ui.activities.BaseActivity import com.habitrpg.android.habitica.ui.activities.MainActivity import com.habitrpg.android.habitica.ui.activities.SkillMemberActivity -import com.habitrpg.android.habitica.ui.activities.SkillTasksActivity 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.android.habitica.ui.helpers.SafeDefaultItemAnimator import com.habitrpg.android.habitica.ui.helpers.loadImage -import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar import com.habitrpg.android.habitica.ui.views.dialogs.OpenedMysteryitemDialog import io.reactivex.rxjava3.core.Flowable -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch import java.util.ArrayList import javax.inject.Inject @@ -228,11 +220,6 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL .map { it.distinctBy { it.key } } .doOnNext { items -> adapter?.data = items -// if (itemType == "special") { -// transformationItems = items.toMutableList() -// userRepository.getTransformationItems() //Get from RealmInventoryLocalRepository -// .subscribe { skillItems -> adapter?.setSpecialItems(skillItems, transformationItems) } -// } } .map { items -> items.mapNotNull { it.key } } .flatMap { @@ -253,28 +240,8 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL ) ) } else { - val specialItems = user?.items?.special - val ownedItems = ArrayList() - if (specialItems != null) { - ownedItems.add("inventory_present") - if (specialItems.snowball > 0) { - ownedItems.add("snowball") - } - if (specialItems.shinySeed > 0) { - ownedItems.add("shinySeed") - } - if (specialItems.seafoam > 0) { - ownedItems.add("seafoam") - } - if (specialItems.spookySparkles > 0) { - ownedItems.add("spookySparkles") - } - } - if (ownedItems.size == 0) { - ownedItems.add("") - } compositeSubscription.add( - inventoryRepository.getItems(SpecialItem::class.java, ownedItems.toTypedArray()) + inventoryRepository.getItems(SpecialItem::class.java, user?.items?.special?.getOwnedItemsToTypedArray() ?: arrayOf()) .map { it.distinctBy { it.key } } .doOnNext { items -> adapter?.setSpecialItems(items) @@ -307,13 +274,13 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL } private fun onSpecialItemSelected(specialItem: SpecialItem) { - selectedSpecialItem = specialItem + selectedSpecialItem = specialItem val intent = Intent(activity, SkillMemberActivity::class.java) memberSelectionResult.launch(intent) - } - private val memberSelectionResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + private val memberSelectionResult = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { if (it.resultCode == Activity.RESULT_OK) { useSpecialItem(selectedSpecialItem, it.data?.getStringExtra("member_id")) } @@ -324,17 +291,18 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL return } - val observable: Flowable = userRepository.useSkill(specialItem.key, specialItem.target, memberID) + val observable: Flowable = + userRepository.useSkill(specialItem.key, specialItem.target, memberID) compositeSubscription.add( observable.subscribe( - { skillResponse -> this.displaySkillResult(specialItem) }, + { skillResponse -> this.displaySpecialItemResult(specialItem) }, RxErrorHandler.handleEmptyError() ) ) } - private fun displaySkillResult(specialItem: SpecialItem?) { + private fun displaySpecialItemResult(specialItem: SpecialItem?) { if (!isAdded) return val activity = activity as? MainActivity @@ -347,7 +315,22 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL } compositeSubscription.add( - userRepository.retrieveUser(false).subscribe({ }, RxErrorHandler.handleEmptyError()) + userRepository.retrieveUser(false) + .flatMap { + adapter?.specialItems = it.items?.special + inventoryRepository.getItems(SpecialItem::class.java, user?.items?.special?.getOwnedItemsToTypedArray() ?: arrayOf()) + .map { it.distinctBy { it.key } } + .doOnNext { items -> + adapter?.setSpecialItems(items) + val itemMap = mutableMapOf() + for (item in items) { + itemMap[item.key] = item + } + adapter?.items = itemMap + } + + } + .subscribe({}, RxErrorHandler.handleEmptyError()) ) } From 3d85075a26b975bb666e4e4f73c09caf866ae346 Mon Sep 17 00:00:00 2001 From: Hafiz Date: Mon, 14 Feb 2022 06:44:45 -0500 Subject: [PATCH 13/18] Remove previously created unused methods Remove previously created unused methods Cleanup --- .../habitrpg/android/habitica/data/UserRepository.kt | 1 - .../data/implementation/UserRepositoryImpl.kt | 3 --- .../habitica/data/local/UserLocalRepository.kt | 1 - .../local/implementation/RealmUserLocalRepository.kt | 11 ----------- .../fragments/inventory/items/ItemRecyclerFragment.kt | 1 - .../android/habitica/utils/ContentDeserializer.kt | 2 +- 6 files changed, 1 insertion(+), 18 deletions(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt index df8f051de..298c576e2 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt @@ -35,7 +35,6 @@ interface UserRepository : BaseRepository { fun sleep(user: User): Flowable fun getSkills(user: User): Flowable> - fun getTransformationItems(): Flowable> fun getSpecialItems(user: User): Flowable> diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt index 0642b1a59..19156f165 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt @@ -124,9 +124,6 @@ class UserRepositoryImpl(localRepository: UserLocalRepository, apiClient: ApiCli override fun getSpecialItems(user: User): Flowable> = localRepository.getSpecialItems(user) - override fun getTransformationItems(): Flowable> = - localRepository.getTransformationItems() - override fun useSkill(key: String, target: String?, taskId: String): Flowable { return zipWithLiveUser(apiClient.useSkill(key, target ?: "", taskId)) { response, user -> response.hpDiff = response.user?.stats?.hp ?: 0 - (user.stats?.hp ?: 0.0) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/UserLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/UserLocalRepository.kt index 3570a1c1d..9842db322 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/UserLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/UserLocalRepository.kt @@ -26,7 +26,6 @@ interface UserLocalRepository : BaseLocalRepository { fun getSkills(user: User): Flowable> fun getSpecialItems(user: User): Flowable> - fun getTransformationItems(): Flowable> fun getAchievements(): Flowable> fun getQuestAchievements(userID: String): Flowable> fun getUserQuestStatus(userID: String): Flowable diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt index e1cbc4077..455c2b00d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt @@ -171,15 +171,4 @@ class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), .filter { it.isLoaded } ) } - - override fun getTransformationItems(): Flowable> { - val habitClass = "special" - return RxJavaBridge.toV3Flowable( - realm.where(Skill::class.java) - .equalTo("habitClass", habitClass) - .findAll() - .asFlowable() - .filter { it.isLoaded } - ) - } } 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 b661f3559..dae650d99 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 @@ -35,7 +35,6 @@ import com.habitrpg.android.habitica.ui.helpers.loadImage import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar import com.habitrpg.android.habitica.ui.views.dialogs.OpenedMysteryitemDialog import io.reactivex.rxjava3.core.Flowable -import java.util.ArrayList import javax.inject.Inject class ItemRecyclerFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt index b7176b24f..a598b7bc5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt @@ -95,7 +95,7 @@ class ContentDeserializer : JsonDeserializer { } } - if (obj.has("special")) {//ToDo add special + if (obj.has("special")) { for ((classname, value) in obj.getAsJsonObject("special").entrySet()) { val skillItem = value.asJsonObject val special = SpecialItem() From 1a5800c0efaecb566695d6bc38033f2aed9011dc Mon Sep 17 00:00:00 2001 From: Hafizzle <34069775+Hafizzle@users.noreply.github.com> Date: Mon, 14 Feb 2022 09:41:42 -0500 Subject: [PATCH 14/18] Added question mark to Discard string (#1707) --- Habitica/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index a9fb5ff8e..8a528d59b 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -549,7 +549,7 @@ Start My Day Are you sure you want to leave this party? Do you want to keep participating in the Challenge when leaving the Party? - Are you sure you want to discard changes to this task + Are you sure you want to discard changes to this task? You will not be able to rejoin this party unless invited. Pending Accepted From 699462110ef364d0cb4b3b54350a120a18d1f7a0 Mon Sep 17 00:00:00 2001 From: Hafiz Date: Mon, 14 Feb 2022 15:32:31 -0500 Subject: [PATCH 15/18] Recreate implementation of special items to match other items Recreate current implementation of special items to match other items (Eggs, hatching potions, etc). Update Special items in Item tab to reflect changes --- .../implementation/ContentRepositoryImpl.kt | 1 - .../RealmInventoryLocalRepository.kt | 4 +- .../RealmUserLocalRepository.kt | 8 +- .../android/habitica/models/user/Items.kt | 7 +- .../habitica/models/user/SpecialItems.kt | 58 ------------- .../ui/adapter/SkillsRecyclerViewAdapter.kt | 13 +-- .../adapter/inventory/ItemRecyclerAdapter.kt | 20 ----- .../ui/fragments/NavigationDrawerFragment.kt | 2 +- .../inventory/items/ItemRecyclerFragment.kt | 81 ++++++------------- .../ui/fragments/skills/SkillsFragment.kt | 1 - .../utils/OwnedItemListDeserializer.kt | 10 ++- .../habitica/utils/UserDeserializer.kt | 3 +- .../habitica/models/user/SpecialItemsTest.kt | 37 --------- 13 files changed, 51 insertions(+), 194 deletions(-) delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt delete mode 100644 Habitica/src/test/java/com/habitrpg/android/habitica/models/user/SpecialItemsTest.kt diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt index 2868d580b..94c363df5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt @@ -9,7 +9,6 @@ import com.habitrpg.android.habitica.models.ContentResult import com.habitrpg.android.habitica.models.WorldState import com.habitrpg.android.habitica.models.inventory.SpecialItem import io.reactivex.rxjava3.core.Flowable -import io.realm.RealmList import java.util.* class ContentRepositoryImpl(localRepository: T, apiClient: ApiClient, context: Context) : BaseRepositoryImpl(localRepository, apiClient), ContentRepository { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmInventoryLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmInventoryLocalRepository.kt index 9375752f6..cd739e699 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmInventoryLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmInventoryLocalRepository.kt @@ -96,7 +96,7 @@ class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository( "hatchingPotions" -> it.items?.hatchingPotions "food" -> it.items?.food "quests" -> it.items?.quests - "special" -> it.items?.special?.ownedItems + "special" -> it.items?.special else -> emptyList() } ?: emptyList() if (includeZero) { @@ -286,7 +286,7 @@ class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository( return } val liveUser = getLiveObject(user) - val ownedItems = liveUser?.items?.special?.ownedItems + val ownedItems = liveUser?.items?.special val item = ownedItems?.firstOrNull() { it.key == "inventory_present" } executeTransaction { if (item != null && item.isValid) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt index 455c2b00d..37c32a391 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt @@ -147,16 +147,16 @@ class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), val specialItems = user.items?.special val ownedItems = ArrayList() if (specialItems != null) { - if (specialItems.snowball > 0) { + if (specialItems.firstOrNull() { it.key == "snowball" }?.numberOwned ?: 0 > 0) { ownedItems.add("snowball") } - if (specialItems.shinySeed > 0) { + if (specialItems.firstOrNull() { it.key == "shinySeed" }?.numberOwned ?: 0 > 0) { ownedItems.add("shinySeed") } - if (specialItems.seafoam > 0) { + if (specialItems.firstOrNull() { it.key == "seafoam" }?.numberOwned ?: 0 > 0) { ownedItems.add("seafoam") } - if (specialItems.spookySparkles > 0) { + if (specialItems.firstOrNull() { it.key == "spookySparkles" }?.numberOwned ?: 0 > 0) { ownedItems.add("spookySparkles") } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt index 049378511..f1e5b1010 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt @@ -13,6 +13,7 @@ open class Items : RealmObject, BaseObject { eggs?.forEach { it.itemType = "eggs" } food?.forEach { it.itemType = "food" } quests?.forEach { it.itemType = "quests" } + special?.forEach { it.itemType = "special" } } var eggs: RealmList? = null @@ -35,6 +36,11 @@ open class Items : RealmObject, BaseObject { field = value field?.forEach { it.itemType = "quests" } } + var special: RealmList? = null + set(value) { + field = value + field?.forEach { it.itemType = "special" } + } var pets: RealmList? = null var mounts: RealmList? = null var currentMount: String? = null @@ -44,7 +50,6 @@ open class Items : RealmObject, BaseObject { // private QuestContent quest; var gear: Gear? = null - var special: SpecialItems? = null constructor(currentMount: String, currentPet: String, lastDropCount: Int, lastDropDate: Date) { this.currentMount = currentMount diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt deleted file mode 100644 index f48108bf8..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt +++ /dev/null @@ -1,58 +0,0 @@ -package com.habitrpg.android.habitica.models.user - -import com.habitrpg.android.habitica.models.BaseObject -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.annotations.RealmClass -import java.util.ArrayList - -@RealmClass(embedded = true) -open class SpecialItems : RealmObject(), BaseObject { - var ownedItems: RealmList? = null - var seafoam: Int = 0 - var shinySeed: Int = 0 - var snowball: Int = 0 - var spookySparkles: Int = 0 - - val hasSpecialItems: Boolean - get() { - return seafoam > 0 || shinySeed > 0 || snowball > 0 || spookySparkles > 0 - } - - fun getSpecialItemCount(key: String): Int{ - var inventoryPresent: OwnedItem = ownedItems?.filter { it.key == "inventory_present" }?.single() ?: OwnedItem() - - var count = 0 - when(key){ - "seafoam" -> count = seafoam - "shinySeed" -> count = shinySeed - "snowball" -> count = snowball - "spookySparkles" -> count = spookySparkles - "inventory_present" -> count = inventoryPresent.numberOwned - } - return count - } - - fun getOwnedItemsToTypedArray(): Array { - val ownedSpecialItems = ArrayList() - ownedSpecialItems.add("inventory_present") - if (snowball > 0) { - ownedSpecialItems.add("snowball") - } - if (shinySeed > 0) { - ownedSpecialItems.add("shinySeed") - } - if (seafoam > 0) { - ownedSpecialItems.add("seafoam") - } - if (spookySparkles > 0) { - ownedSpecialItems.add("spookySparkles") - } - - if (ownedSpecialItems.size == 0) { - ownedSpecialItems.add("") - } - - return ownedSpecialItems.toTypedArray() - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt index 423793985..0736bdb57 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt @@ -12,12 +12,13 @@ import com.habitrpg.android.habitica.databinding.SkillListItemBinding import com.habitrpg.android.habitica.extensions.inflate import com.habitrpg.android.habitica.extensions.isUsingNightModeResources import com.habitrpg.android.habitica.models.Skill -import com.habitrpg.android.habitica.models.user.SpecialItems +import com.habitrpg.android.habitica.models.user.OwnedItem import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper import io.reactivex.rxjava3.core.BackpressureStrategy import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.subjects.PublishSubject +import io.realm.RealmList class SkillsRecyclerViewAdapter : RecyclerView.Adapter() { @@ -34,7 +35,7 @@ class SkillsRecyclerViewAdapter : RecyclerView.Adapter?? = null set(value) { field = value notifyDataSetChanged() @@ -135,10 +136,10 @@ class SkillsRecyclerViewAdapter : RecyclerView.Adapter specialItems?.snowball - "shinySeed" -> specialItems?.shinySeed - "seafoam" -> specialItems?.seafoam - "spookySparkles" -> specialItems?.spookySparkles + "snowball" -> specialItems?.firstOrNull() { it.key == "snowball" }?.numberOwned + "shinySeed" -> specialItems?.firstOrNull() { it.key == "shinySeed" }?.numberOwned + "seafoam" -> specialItems?.firstOrNull() { it.key == "seafoam" }?.numberOwned + "spookySparkles" -> specialItems?.firstOrNull() { it.key == "spookySparkles" }?.numberOwned else -> 0 } ?: 0 } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt index a52edfd82..915b16fe6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt @@ -9,11 +9,9 @@ import androidx.recyclerview.widget.RecyclerView import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.databinding.ItemItemBinding import com.habitrpg.android.habitica.extensions.layoutInflater -import com.habitrpg.android.habitica.models.Skill import com.habitrpg.android.habitica.models.inventory.* import com.habitrpg.android.habitica.models.user.OwnedItem import com.habitrpg.android.habitica.models.user.OwnedPet -import com.habitrpg.android.habitica.models.user.SpecialItems import com.habitrpg.android.habitica.ui.adapter.BaseRecyclerViewAdapter import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu @@ -39,11 +37,6 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter() private val questInvitationEvents = PublishSubject.create() @@ -226,17 +219,4 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter){ - val transformationItems: MutableList = mutableListOf() - for (item in skillItems){ - val ownedTransformationItem = OwnedItem() - ownedTransformationItem.key = item.key - ownedTransformationItem.itemType = "special" - ownedTransformationItem.numberOwned = specialItems?.getSpecialItemCount(item.key) ?: 0 - transformationItems.add(ownedTransformationItem) - } - data = transformationItems - notifyDataSetChanged() - } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt index 90164183a..697d5c9c9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt @@ -342,7 +342,7 @@ class NavigationDrawerFragment : DialogFragment() { val specialItems = user.items?.special var hasSpecialItems = false if (specialItems != null) { - hasSpecialItems = specialItems.hasSpecialItems + hasSpecialItems = true } val item = getItemWithIdentifier(SIDEBAR_SKILLS) if (item != null) { 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 dae650d99..ef2a1eb45 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 @@ -99,7 +99,6 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL adapter = ItemRecyclerAdapter(context) } binding?.recyclerView?.adapter = adapter - adapter?.specialItems = this.user?.items?.special adapter?.useSpecialEvents?.subscribeWithErrorHandler { onSpecialItemSelected(it) }?.let { compositeSubscription.add(it) } adapter?.let { adapter -> compositeSubscription.add( @@ -213,46 +212,30 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL else -> Egg::class.java } itemType?.let { type -> - if (type != "special"){ - compositeSubscription.add( - inventoryRepository.getOwnedItems(type) - .map { it.distinctBy { it.key } } - .doOnNext { items -> - adapter?.data = items + compositeSubscription.add( + inventoryRepository.getOwnedItems(type) + .map { it.distinctBy { it.key } } + .doOnNext { items -> + adapter?.data = items + } + .map { items -> items.mapNotNull { it.key } } + .flatMap { + inventoryRepository.getItems(itemClass, it.toTypedArray()) + } + .map { + val itemMap = mutableMapOf() + for (item in it) { + itemMap[item.key] = item } - .map { items -> items.mapNotNull { it.key } } - .flatMap { - inventoryRepository.getItems(itemClass, it.toTypedArray()) - } - .map { - val itemMap = mutableMapOf() - for (item in it) { - itemMap[item.key] = item - } - itemMap - } - .subscribe( - { items -> - adapter?.items = items - }, - RxErrorHandler.handleEmptyError() - ) - ) - } else { - compositeSubscription.add( - inventoryRepository.getItems(SpecialItem::class.java, user?.items?.special?.getOwnedItemsToTypedArray() ?: arrayOf()) - .map { it.distinctBy { it.key } } - .doOnNext { items -> - adapter?.setSpecialItems(items) - val itemMap = mutableMapOf() - for (item in items) { - itemMap[item.key] = item - } - adapter?.items = itemMap - } - .subscribe() - ) - } + itemMap + } + .subscribe( + { items -> + adapter?.items = items + }, + RxErrorHandler.handleEmptyError() + ) + ) } @@ -313,24 +296,8 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL ) } - compositeSubscription.add( - userRepository.retrieveUser(false) - .flatMap { - adapter?.specialItems = it.items?.special - inventoryRepository.getItems(SpecialItem::class.java, user?.items?.special?.getOwnedItemsToTypedArray() ?: arrayOf()) - .map { it.distinctBy { it.key } } - .doOnNext { items -> - adapter?.setSpecialItems(items) - val itemMap = mutableMapOf() - for (item in items) { - itemMap[item.key] = item - } - adapter?.items = itemMap - } + loadItems() - } - .subscribe({}, RxErrorHandler.handleEmptyError()) - ) } companion object { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt index 1451d75c2..8f4a0d541 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt @@ -62,7 +62,6 @@ class SkillsFragment : BaseMainFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - binding?.recyclerView?.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(activity) binding?.recyclerView?.adapter = adapter binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/OwnedItemListDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/OwnedItemListDeserializer.kt index 814063d64..0e8de546d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/OwnedItemListDeserializer.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/OwnedItemListDeserializer.kt @@ -13,10 +13,12 @@ class OwnedItemListDeserializer : JsonDeserializer> { val entrySet = json?.asJsonObject?.entrySet() if (entrySet != null) { for (entry in entrySet) { - val item = OwnedItem() - item.key = entry.key - item.numberOwned = entry.value.asInt - ownedItems.add(item) + if (entry.value.isJsonPrimitive){ + val item = OwnedItem() + item.key = entry.key + item.numberOwned = entry.value.asInt + ownedItems.add(item) + } } } return ownedItems diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt index 186339f11..a7eee286a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt @@ -99,8 +99,7 @@ class UserDeserializer : JsonDeserializer { item.key = "inventory_present" item.userID = user.id item.numberOwned = user.purchased?.plan?.mysteryItemCount ?: 0 - user.items?.special?.ownedItems = RealmList() - user.items?.special?.ownedItems?.add(item) + user.items?.special?.add(item) user.items?.setItemTypes() } if (obj.has("auth")) { diff --git a/Habitica/src/test/java/com/habitrpg/android/habitica/models/user/SpecialItemsTest.kt b/Habitica/src/test/java/com/habitrpg/android/habitica/models/user/SpecialItemsTest.kt deleted file mode 100644 index b459b4afd..000000000 --- a/Habitica/src/test/java/com/habitrpg/android/habitica/models/user/SpecialItemsTest.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.habitrpg.android.habitica.models.user - -import io.kotest.common.ExperimentalKotest -import io.kotest.core.spec.style.WordSpec -import io.kotest.datatest.withData -import io.kotest.matchers.shouldBe - -@ExperimentalKotest -class SpecialItemsTest : WordSpec({ - data class SpecialItemsData(val snowBalls: Int, val seafoam: Int, val shinyseed: Int, val spookySparkles: Int) - lateinit var items: SpecialItems - beforeEach { - items = SpecialItems() - } - "hasSpecialItems" should { - "false if none are owned" { - items.hasSpecialItems shouldBe false - } - "true if any are owned" { - items.snowball = 4 - items.hasSpecialItems shouldBe true - } - withData( - SpecialItemsData(1, 0, 0, 0), - SpecialItemsData(0, 1, 0, 0), - SpecialItemsData(0, 0, 1, 0), - SpecialItemsData(0, 0, 0, 1), - SpecialItemsData(1, 3, 4, 8) - ) { (snowballs, seafoam, shinyseeds, spookySparkles) -> - items.snowball = snowballs - items.seafoam = seafoam - items.shinySeed = shinyseeds - items.spookySparkles = spookySparkles - items.hasSpecialItems shouldBe true - } - } -}) From c32fb7914dbc42b9089c4a76b4c65e56f9f733c2 Mon Sep 17 00:00:00 2001 From: Hafiz Date: Wed, 16 Feb 2022 12:13:30 -0500 Subject: [PATCH 16/18] Optimization --- .../implementation/RealmUserLocalRepository.kt | 18 +++--------------- .../android/habitica/models/user/Items.kt | 11 +++++++++++ .../ui/adapter/SkillsRecyclerViewAdapter.kt | 8 +------- .../ui/fragments/NavigationDrawerFragment.kt | 8 +++----- .../habitica/utils/ContentDeserializer.kt | 11 ++--------- 5 files changed, 20 insertions(+), 36 deletions(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt index 37c32a391..ad7040b3a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt @@ -146,22 +146,10 @@ class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), override fun getSpecialItems(user: User): Flowable> { val specialItems = user.items?.special val ownedItems = ArrayList() - if (specialItems != null) { - if (specialItems.firstOrNull() { it.key == "snowball" }?.numberOwned ?: 0 > 0) { - ownedItems.add("snowball") + for (key in listOf("snowball", "shinySeed", "seafoam", "spookySparkles")) { + if (specialItems?.firstOrNull() { it.key == key }?.numberOwned ?: 0 > 0) { + ownedItems.add(key) } - if (specialItems.firstOrNull() { it.key == "shinySeed" }?.numberOwned ?: 0 > 0) { - ownedItems.add("shinySeed") - } - if (specialItems.firstOrNull() { it.key == "seafoam" }?.numberOwned ?: 0 > 0) { - ownedItems.add("seafoam") - } - if (specialItems.firstOrNull() { it.key == "spookySparkles" }?.numberOwned ?: 0 > 0) { - ownedItems.add("spookySparkles") - } - } - if (ownedItems.size == 0) { - ownedItems.add("") } return RxJavaBridge.toV3Flowable( realm.where(Skill::class.java) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt index f1e5b1010..d4d52ad47 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt @@ -41,6 +41,7 @@ open class Items : RealmObject, BaseObject { field = value field?.forEach { it.itemType = "special" } } + var pets: RealmList? = null var mounts: RealmList? = null var currentMount: String? = null @@ -59,4 +60,14 @@ open class Items : RealmObject, BaseObject { } constructor() + + val hasTransformationItems: Boolean + get() { + return special?.any { transformationItem -> + transformationItem.key == ("seafoam") && transformationItem.numberOwned > 0|| + transformationItem.key == ("shinySeed") && transformationItem.numberOwned > 0|| + transformationItem.key == ("snowball") && transformationItem.numberOwned > 0|| + transformationItem.key == ("spookySparkles") && transformationItem.numberOwned > 0 + } ?: false + } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt index 0736bdb57..6b64fa8b0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt @@ -135,13 +135,7 @@ class SkillsRecyclerViewAdapter : RecyclerView.Adapter specialItems?.firstOrNull() { it.key == "snowball" }?.numberOwned - "shinySeed" -> specialItems?.firstOrNull() { it.key == "shinySeed" }?.numberOwned - "seafoam" -> specialItems?.firstOrNull() { it.key == "seafoam" }?.numberOwned - "spookySparkles" -> specialItems?.firstOrNull() { it.key == "spookySparkles" }?.numberOwned - else -> 0 - } ?: 0 + return specialItems?.firstOrNull() { it.key == key }?.numberOwned ?: 0 } } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt index 697d5c9c9..0eb00cb47 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt @@ -28,7 +28,6 @@ import com.habitrpg.android.habitica.extensions.* import com.habitrpg.android.habitica.helpers.AppConfigManager import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.helpers.RxErrorHandler -import com.habitrpg.android.habitica.models.WorldState import com.habitrpg.android.habitica.models.WorldStateEvent import com.habitrpg.android.habitica.models.inventory.Item import com.habitrpg.android.habitica.models.inventory.Quest @@ -41,7 +40,6 @@ import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.ui.activities.MainActivity import com.habitrpg.android.habitica.ui.activities.NotificationsActivity import com.habitrpg.android.habitica.ui.adapter.NavigationDrawerAdapter -import com.habitrpg.android.habitica.ui.fragments.social.TavernDetailFragment import com.habitrpg.android.habitica.ui.menu.HabiticaDrawerItem import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar @@ -339,10 +337,10 @@ class NavigationDrawerFragment : DialogFragment() { tavernItem?.subtitle = null } - val specialItems = user.items?.special + val userItems = user.items var hasSpecialItems = false - if (specialItems != null) { - hasSpecialItems = true + if (userItems != null) { + hasSpecialItems = userItems.hasTransformationItems } val item = getItemWithIdentifier(SIDEBAR_SKILLS) if (item != null) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt index a598b7bc5..b413e31dd 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt @@ -96,15 +96,8 @@ class ContentDeserializer : JsonDeserializer { } if (obj.has("special")) { - for ((classname, value) in obj.getAsJsonObject("special").entrySet()) { - val skillItem = value.asJsonObject - val special = SpecialItem() - special.key = skillItem.get("key").asString - special.text = skillItem.get("text").asString - special.notes = skillItem.get("notes").asString - special.target = skillItem.get("target").asString - special.value = skillItem.get("value").asInt - result.special.add(special) + for (entry in obj.get("special").asJsonObject.entrySet()) { + result.special.add(context.deserialize(entry.value, SpecialItem::class.java)) } } From 7d086e79e4cc537fa4e1d4ed7b0e855d6de477dc Mon Sep 17 00:00:00 2001 From: Hafiz Date: Tue, 1 Mar 2022 08:11:19 -0500 Subject: [PATCH 17/18] setAlarmClock use replace setAndAllowWhileIdle Replace setAndAllowWhileIdle with setAlarmClock due to both setAndAllowWhileIdle and setExactAndAllowWhileIdle have triggering alarm & notification restrictions - setAlarmClock is exact and does not limit alarm count. --- Habitica/AndroidManifest.xml | 1 + .../com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Habitica/AndroidManifest.xml b/Habitica/AndroidManifest.xml index 128c8bab5..d453c944a 100644 --- a/Habitica/AndroidManifest.xml +++ b/Habitica/AndroidManifest.xml @@ -7,6 +7,7 @@ + diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt index ce2a67a2a..bee1b69f6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt @@ -1,6 +1,7 @@ package com.habitrpg.android.habitica.helpers import android.app.AlarmManager +import android.app.AlarmManager.AlarmClockInfo import android.app.PendingIntent import android.content.Context import android.content.Intent @@ -174,7 +175,7 @@ class TaskAlarmManager(private var context: Context, private var taskRepository: if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { alarmManager?.setWindow(AlarmManager.RTC_WAKEUP, time, 60000, pendingIntent) } else { - alarmManager?.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pendingIntent) + alarmManager?.setAlarmClock(AlarmClockInfo(time, pendingIntent), pendingIntent) } } } From 0542a8d3bfa3753b463f0f3dcf346818fbe15a72 Mon Sep 17 00:00:00 2001 From: Hafiz Date: Mon, 14 Mar 2022 04:07:21 -0400 Subject: [PATCH 18/18] Hide gold from other user profiles --- .../habitrpg/android/habitica/ui/AvatarWithBarsViewModel.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.kt index ccb64cf42..e51369eb5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.kt @@ -73,9 +73,9 @@ class AvatarWithBarsViewModel(private val context: Context, private val binding: if (!stats.isBuffed) { binding.buffImageView.visibility = View.GONE } - - binding.currencyView.gold = stats.gp ?: 0.0 + if (user is User) { + binding.currencyView.gold = stats.gp ?: 0.0 binding.currencyView.hourglasses = user.hourglassCount.toDouble() binding.currencyView.gems = user.gemCount.toDouble() }