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