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()))
+ }
+}