From 9e3ba67f1313617e824b1b592997b2f3df2dd589 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 4 Oct 2021 14:28:32 +0200 Subject: [PATCH] move more code to user viewmodel --- Habitica/build.gradle | 4 +- Habitica/res/values/strings.xml | 1 + .../habitica/components/UserComponent.java | 3 + .../ui/fragments/NavigationDrawerFragment.kt | 4 +- .../equipment/EquipmentDetailFragment.kt | 1 - .../equipment/EquipmentOverviewFragment.kt | 87 ++++++++----------- .../ui/fragments/social/ChatFragment.kt | 2 +- .../social/guilds/GuildDetailFragment.kt | 2 +- .../social/party/PartyDetailFragment.kt | 4 +- .../habitica/ui/viewmodels/BaseViewModel.kt | 14 +-- .../habitica/ui/viewmodels/PartyViewModel.kt | 4 +- .../equipment/EquipmentOverviewViewModel.kt | 25 ++++++ 12 files changed, 84 insertions(+), 67 deletions(-) create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/inventory/equipment/EquipmentOverviewViewModel.kt diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 40a08c857..c924bba11 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -116,10 +116,12 @@ dependencies { implementation 'com.nex3z:flow-layout:1.2.2' implementation 'androidx.core:core-ktx:1.6.0' - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1" + implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1" implementation "androidx.lifecycle:lifecycle-common-java8:2.3.1" implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' + implementation "androidx.fragment:fragment-ktx:1.3.6" implementation "androidx.paging:paging-runtime-ktx:3.0.1" implementation 'com.plattysoft.leonids:LeonidsLib:1.3.2' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2' diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index 64a224eea..7c6a4859d 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -1183,4 +1183,5 @@ Terms of Service %.01f dmg pending %s remaining + Sale ends in %s 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 f62177ff5..c24273044 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.fragments.tasks.TeamBoardFragment; import com.habitrpg.android.habitica.ui.viewmodels.GroupViewModel; import com.habitrpg.android.habitica.ui.viewmodels.InboxViewModel; 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; import com.habitrpg.android.habitica.ui.views.shops.PurchaseDialog; import com.habitrpg.android.habitica.ui.views.social.ChatBarView; @@ -346,4 +347,6 @@ public interface UserComponent { void inject(@NotNull PromoWebFragment promoWebFragment); void inject(@NotNull ItemDialogFragment itemDialogFragment); + + void inject(@NotNull EquipmentOverviewViewModel equipmentOverviewViewModel); } 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 485918e97..07fe20db1 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 @@ -16,6 +16,7 @@ import androidx.core.os.bundleOf import androidx.core.view.GravityCompat import androidx.fragment.app.DialogFragment import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.SimpleItemAnimator import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.data.ContentRepository @@ -181,6 +182,7 @@ class NavigationDrawerFragment : DialogFragment() { binding?.recyclerView?.adapter = adapter binding?.recyclerView?.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(context) + (binding?.recyclerView?.itemAnimator as? SimpleItemAnimator)?.supportsChangeAnimations = false initializeMenuItems() subscriptions?.add( @@ -675,7 +677,7 @@ class NavigationDrawerFragment : DialogFragment() { val diff = activePromo.endDate.time - Date().time if (diff < (Duration.hours(1).inWholeMilliseconds)) Duration.seconds(1) else Duration.minutes(1) }) { - promotedItem.subtitle = context?.getString(R.string.x_remaining, activePromo.endDate.getShortRemainingString()) + promotedItem.subtitle = context?.getString(R.string.sale_ends_in, activePromo.endDate.getShortRemainingString()) updateItem(promotedItem) } } ?: run { 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 1ee163b59..665316463 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 @@ -33,7 +33,6 @@ class EquipmentDetailFragment : } var type: String? = null - var typeText: String? = null var equippedGear: String? = null var isCostume: Boolean? = null 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 45101cbb1..6a015a12f 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 @@ -4,38 +4,25 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.fragment.app.viewModels import com.habitrpg.android.habitica.components.UserComponent -import com.habitrpg.android.habitica.data.InventoryRepository import com.habitrpg.android.habitica.databinding.FragmentEquipmentOverviewBinding import com.habitrpg.android.habitica.helpers.MainNavigationController -import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.user.Gear -import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.models.user.Outfit import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment -import javax.inject.Inject +import com.habitrpg.android.habitica.ui.viewmodels.inventory.equipment.EquipmentOverviewViewModel class EquipmentOverviewFragment : BaseMainFragment() { + private val viewModel: EquipmentOverviewViewModel by viewModels() + override var binding: FragmentEquipmentOverviewBinding? = null override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentEquipmentOverviewBinding { return FragmentEquipmentOverviewBinding.inflate(inflater, container, false) } - @Inject - lateinit var inventoryRepository: InventoryRepository - - override var user: User? - get() = super.user - set(value) { - super.user = value - if (this::inventoryRepository.isInitialized) { - value?.items?.gear?.let { - updateGearData(it) - } - } - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -46,22 +33,30 @@ class EquipmentOverviewFragment : BaseMainFragment + if (isChecked == viewModel.user.value?.preferences?.autoEquip) return@setOnCheckedChangeListener + viewModel.updateUser("preferences.autoEquip", isChecked) } + binding?.costumeSwitch?.setOnCheckedChangeListener { _, isChecked -> + if (isChecked == viewModel.user.value?.preferences?.costume) return@setOnCheckedChangeListener + viewModel.updateUser("preferences.costume", isChecked) } - binding?.autoEquipSwitch?.setOnCheckedChangeListener { _, isChecked -> userRepository.updateUser("preferences.autoEquip", isChecked).subscribe({ }, RxErrorHandler.handleEmptyError()) } - binding?.costumeSwitch?.setOnCheckedChangeListener { _, isChecked -> userRepository.updateUser("preferences.costume", isChecked).subscribe({ }, RxErrorHandler.handleEmptyError()) } + viewModel.user.observe(viewLifecycleOwner) { + it?.items?.gear?.let { + updateGearData(it) + } + binding?.autoEquipSwitch?.isChecked = user?.preferences?.autoEquip ?: false + binding?.costumeSwitch?.isChecked = user?.preferences?.costume ?: false - user?.items?.gear?.let { - updateGearData(it) + if (user?.preferences?.costume == true) { + binding?.costumeView?.alpha = 1.0f + binding?.costumeView?.isEnabled = true + } else { + binding?.costumeView?.alpha = 0.6f + binding?.costumeView?.isEnabled = false + } } } - override fun onDestroy() { - inventoryRepository.close() - super.onDestroy() - } - override fun injectFragment(component: UserComponent) { component.inject(this) } @@ -71,31 +66,17 @@ class EquipmentOverviewFragment : BaseMainFragment() { viewModel?.updateUser("flags.communityGuidelinesAccepted", true) } - viewModel?.getUserData()?.observe( + viewModel?.user?.observe( viewLifecycleOwner, { chatAdapter?.user = it diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildDetailFragment.kt index 5d2de4c30..1a80da036 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildDetailFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildDetailFragment.kt @@ -111,7 +111,7 @@ class GuildDetailFragment : BaseFragment() { private val sendInvitesResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { if (it.resultCode == Activity.RESULT_OK) { val inviteData = HashMap() - inviteData["inviter"] = viewModel?.getUserData()?.value?.profile?.name ?: "" + inviteData["inviter"] = viewModel?.user?.value?.profile?.name ?: "" if (it.data?.getBooleanExtra(GroupInviteActivity.IS_EMAIL_KEY, false) == true) { val emails = it.data?.getStringArrayExtra(GroupInviteActivity.EMAILS_KEY) val invites = ArrayList>() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt index 8dfdb6ec6..1ca9c25bf 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt @@ -114,7 +114,7 @@ class PartyDetailFragment : BaseFragment() { } viewModel?.getGroupData()?.observe(viewLifecycleOwner, { updateParty(it) }) - viewModel?.getUserData()?.observe(viewLifecycleOwner, { updateUser(it) }) + viewModel?.user?.observe(viewLifecycleOwner, { updateUser(it) }) viewModel?.getMembersData()?.observe(viewLifecycleOwner, { updateMembersList(it) }) } @@ -269,7 +269,7 @@ class PartyDetailFragment : BaseFragment() { } ) ?: return@forEachIndexed val viewHolder = GroupMemberViewHolder(memberView) - viewHolder.bind(member, leaderID ?: "", viewModel?.getUserData()?.value?.id) + viewHolder.bind(member, leaderID ?: "", viewModel?.user?.value?.id) viewHolder.onClickEvent = { FullProfileActivity.open(member.id ?: "") } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/BaseViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/BaseViewModel.kt index 32417f81d..23551b00d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/BaseViewModel.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/BaseViewModel.kt @@ -7,6 +7,7 @@ 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.inventory.Equipment import com.habitrpg.android.habitica.models.user.User import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.disposables.CompositeDisposable @@ -17,10 +18,13 @@ abstract class BaseViewModel(initializeComponent: Boolean = true) : ViewModel() @Inject lateinit var userRepository: UserRepository - private val user: MutableLiveData by lazy { + private val _user: MutableLiveData by lazy { loadUserFromLocal() MutableLiveData() } + val user: LiveData by lazy { + _user + } init { if (initializeComponent) { @@ -38,13 +42,13 @@ abstract class BaseViewModel(initializeComponent: Boolean = true) : ViewModel() internal val disposable = CompositeDisposable() - fun getUserData(): LiveData = user - private fun loadUserFromLocal() { - disposable.add(userRepository.getUser().observeOn(AndroidSchedulers.mainThread()).subscribe({ user.value = it }, RxErrorHandler.handleEmptyError())) + 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())) + disposable.add(userRepository.updateUser(path, value) + .subscribe({ }, RxErrorHandler.handleEmptyError())) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/PartyViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/PartyViewModel.kt index effce0176..03d59dc03 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/PartyViewModel.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/PartyViewModel.kt @@ -20,7 +20,7 @@ class PartyViewModel(initializeComponent: Boolean) : GroupViewModel(initializeCo internal val isUserOnQuest: Boolean get() = !( - getGroupData().value?.quest?.members?.none { it.key == getUserData().value?.id } + getGroupData().value?.quest?.members?.none { it.key == user.value?.id } ?: true ) @@ -88,7 +88,7 @@ class PartyViewModel(initializeComponent: Boolean) : GroupViewModel(initializeCo } fun showParticipantButtons(): Boolean { - val user = getUserData().value + val user = user.value return !(user?.party == null || user.party?.quest == null) && !isQuestActive && user.party?.quest?.RSVPNeeded == true } 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 new file mode 100644 index 000000000..ebc740ec1 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/inventory/equipment/EquipmentOverviewViewModel.kt @@ -0,0 +1,25 @@ +package com.habitrpg.android.habitica.ui.viewmodels.inventory.equipment + +import androidx.lifecycle.SavedStateHandle +import com.habitrpg.android.habitica.components.UserComponent +import com.habitrpg.android.habitica.data.InventoryRepository +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.inventory.Equipment +import com.habitrpg.android.habitica.ui.viewmodels.BaseViewModel +import javax.inject.Inject + +class EquipmentOverviewViewModel(savedStateHandle: SavedStateHandle): BaseViewModel() { + + @Inject + lateinit var inventoryRepository: InventoryRepository + + override fun inject(component: UserComponent) { + component.inject(this) + } + + fun getGear(key: String, onSuccess: (Equipment) -> Unit) { + disposable.add(inventoryRepository.getEquipment(key).subscribe( { + onSuccess(it) + }, RxErrorHandler.handleEmptyError())) + } +}