diff --git a/Habitica/res/layout/activity_gift_subscription.xml b/Habitica/res/layout/activity_gift_subscription.xml
index 917be5105..c3b4972b1 100644
--- a/Habitica/res/layout/activity_gift_subscription.xml
+++ b/Habitica/res/layout/activity_gift_subscription.xml
@@ -37,6 +37,7 @@
app:showPet="false"
app:showMount="false"
app:showSleeping="false"
+ android:clipChildren="false"
android:layout_gravity="center_horizontal"/>
SUBSCRIBER BENEFIT
You don\'t have any Saddles
Saddles instantly raise a Pet to a Mount. You can purchase one from the Market.
- Error Loading Member
- There was an error when loading this members data. Please try again later.
+ Unable to find player
+ There was an error when loading this player's data. Please make sure you typed their @username correctly.
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 0287aabad..0d439bc0b 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
@@ -197,7 +197,7 @@ class UserRepositoryImpl(
override suspend fun getNewsNotification(): Notification {
val baileyNews = apiClient.getNews()
- val baileyAnnouncement = (baileyNews?.first() as Map<*, *>)["title"] as String
+ val baileyAnnouncement = (baileyNews?.first() as? Map<*, *>)?.get("title") as? String
val notification = Notification()
notification.id = "custom-new-stuff-notification"
notification.type = Notification.Type.NEW_STUFF.type
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 2c61252e1..a230bd5e9 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
@@ -397,7 +397,7 @@ open class Task : RealmObject, BaseMainObject, Parcelable, BaseTask {
}
// Calculate weeks since start and adjust for the correct interval
val weeksSinceStart = ChronoUnit.WEEKS.between(startDate.toLocalDate(), nextDueDate.toLocalDate())
- if (weeksSinceStart % everyX != 0L) {
+ if (everyX > 0 && weeksSinceStart % everyX != 0L) {
val weeksToNextValidInterval = everyX - (weeksSinceStart % everyX)
nextDueDate = nextDueDate.plusWeeks(weeksToNextValidInterval)
// Find the exact next due day within the valid interval
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftGemsActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftGemsActivity.kt
index 7c4e28a04..fe3f66b7e 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftGemsActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftGemsActivity.kt
@@ -10,16 +10,19 @@ import com.google.android.material.tabs.TabLayoutMediator
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.ActivityGiftGemsBinding
+import com.habitrpg.android.habitica.extensions.addCloseButton
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.PurchaseHandler
import com.habitrpg.android.habitica.models.members.Member
import com.habitrpg.android.habitica.ui.fragments.purchases.GiftBalanceGemsFragment
import com.habitrpg.android.habitica.ui.fragments.purchases.GiftPurchaseGemsFragment
import com.habitrpg.android.habitica.ui.views.CurrencyView
+import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import com.habitrpg.common.habitica.helpers.ExceptionHandler
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch
+import java.lang.reflect.InvocationTargetException
import javax.inject.Inject
@AndroidEntryPoint
@@ -69,15 +72,35 @@ class GiftGemsActivity : PurchaseActivity() {
giftedUserID = intent.getStringExtra("userID")
giftedUsername = intent.getStringExtra("username")
- if (giftedUserID == null && giftedUsername == null) {
- giftedUserID = navArgs().value.userID
- giftedUsername = navArgs().value.username
+ if (giftedUserID.isNullOrBlank()) {
+ try {
+ giftedUserID = navArgs().value.userID
+ } catch (_: InvocationTargetException) {
+ // user ID wasn't passed as nav arg
+ }
+ }
+ if (giftedUsername.isNullOrBlank()) {
+ try {
+ giftedUsername = navArgs().value.username
+ } catch (_: InvocationTargetException) {
+ // username wasn't passed as nav arg
+ }
+ }
+
+ if (giftedUsername.isNullOrBlank() && giftedUserID.isNullOrBlank()) {
+ showMemberLoadingErrorDialog()
}
setViewPagerAdapter()
- lifecycleScope.launch(ExceptionHandler.coroutine()) {
- val member = socialRepository.retrieveMember(giftedUsername ?: giftedUserID) ?: return@launch
+ lifecycleScope.launch(ExceptionHandler.coroutine {
+ showMemberLoadingErrorDialog()
+ }) {
+ val member = socialRepository.retrieveMember(giftedUsername ?: giftedUserID)
+ if (member == null) {
+ showMemberLoadingErrorDialog()
+ return@launch
+ }
giftedMember = member
giftedUserID = member.id
giftedUsername = member.username
@@ -89,6 +112,14 @@ class GiftGemsActivity : PurchaseActivity() {
}
}
+ private fun showMemberLoadingErrorDialog() {
+ val dialog = HabiticaAlertDialog(this)
+ dialog.setTitle(R.string.error_loading_member)
+ dialog.setMessage(R.string.error_loading_member_body)
+ dialog.addCloseButton(isPrimary = true) { _, _ -> finish() }
+ dialog.show()
+ }
+
private fun setViewPagerAdapter() {
val statePagerAdapter = object : FragmentStateAdapter(supportFragmentManager, lifecycle) {
override fun createFragment(position: Int): Fragment {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt
index a0ca9f17e..5b40f4f5a 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt
@@ -21,6 +21,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
+import java.lang.reflect.InvocationTargetException
import javax.inject.Inject
@AndroidEntryPoint
@@ -65,23 +66,37 @@ class GiftSubscriptionActivity : PurchaseActivity() {
giftedUserID = intent.getStringExtra("userID")
giftedUsername = intent.getStringExtra("username")
if (giftedUserID.isNullOrBlank()) {
- giftedUserID = navArgs().value.userID
+ try {
+ giftedUserID = navArgs().value.userID
+ } catch (_: InvocationTargetException) {
+ // user ID wasn't passed as nav arg
+ }
}
if (giftedUsername.isNullOrBlank()) {
- giftedUsername = navArgs().value.username
+ try {
+ giftedUsername = navArgs().value.username
+ } catch (_: InvocationTargetException) {
+ // username wasn't passed as nav arg
+ }
+ }
+
+ if (giftedUsername.isNullOrBlank() && giftedUserID.isNullOrBlank()) {
+ showMemberLoadingErrorDialog()
+ }
+
+ if (giftedUsername?.isNotBlank() == true) {
+ binding.usernameTextView.text = "@${giftedUsername}"
}
binding.subscriptionButton.setOnClickListener {
selectedSubscriptionSku?.let { sku -> purchaseSubscription(sku) }
}
- lifecycleScope.launch(ExceptionHandler.coroutine()) {
+ lifecycleScope.launch(ExceptionHandler.coroutine {
+ showMemberLoadingErrorDialog()
+ }) {
val member = socialRepository.retrieveMember(giftedUsername ?: giftedUserID)
if (member == null) {
- val dialog = HabiticaAlertDialog(this@GiftSubscriptionActivity)
- dialog.setTitle(R.string.error_loading_member)
- dialog.setMessage(R.string.error_loading_member_body)
- dialog.addCloseButton { _, _ -> finish() }
- dialog.show()
+ showMemberLoadingErrorDialog()
return@launch
}
binding.avatarView.setAvatar(member)
@@ -99,6 +114,14 @@ class GiftSubscriptionActivity : PurchaseActivity() {
}
}
+ private fun showMemberLoadingErrorDialog() {
+ val dialog = HabiticaAlertDialog(this@GiftSubscriptionActivity)
+ dialog.setTitle(R.string.error_loading_member)
+ dialog.setMessage(R.string.error_loading_member_body)
+ dialog.addCloseButton(isPrimary = true) { _, _ -> finish() }
+ dialog.show()
+ }
+
override fun onStart() {
super.onStart()
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
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 bb1769770..be8479d64 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
@@ -59,11 +59,13 @@ class EquipmentDetailFragment :
lifecycleScope.launchCatching {
inventoryRepository.equipGear(it, isCostume ?: false)
- userViewModel.user.observeOnce(viewLifecycleOwner) { user ->
- val parentActivity = mainActivity
- val totalCheckIns = user?.loginIncentives
- if (totalCheckIns != null && parentActivity != null) {
- reviewManager.requestReview(parentActivity, totalCheckIns)
+ if (this@EquipmentDetailFragment.isAdded) {
+ userViewModel.user.observeOnce(viewLifecycleOwner) { user ->
+ val parentActivity = mainActivity
+ val totalCheckIns = user?.loginIncentives
+ if (totalCheckIns != null && parentActivity != null) {
+ reviewManager.requestReview(parentActivity, totalCheckIns)
+ }
}
}
}
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 6fc3766f9..225a219ab 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
@@ -133,11 +133,13 @@ class PetDetailRecyclerFragment :
val items = inventoryRepository.equip("pet", it)
adapter.currentPet = items?.currentPet
- userViewModel.user.observeOnce(viewLifecycleOwner) { user ->
- val parentActivity = mainActivity
- val totalCheckIns = user?.loginIncentives
- if (totalCheckIns != null && parentActivity != null) {
- reviewManager.requestReview(parentActivity, totalCheckIns)
+ if (isAdded) {
+ userViewModel.user.observeOnce(viewLifecycleOwner) { user ->
+ val parentActivity = mainActivity
+ val totalCheckIns = user?.loginIncentives
+ if (totalCheckIns != null && parentActivity != null) {
+ reviewManager.requestReview(parentActivity, totalCheckIns)
+ }
}
}
}
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 b2b416947..e689ef5ab 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
@@ -169,6 +169,9 @@ class PreferencesFragment :
isPrimary = true,
isDestructive = true
) { _, _ ->
+ lifecycleScope.launch {
+ userRepository.changeClass()
+ }
classSelectionResult.launch(
intent
)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/PetBottomSheet.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/PetBottomSheet.kt
index d4dadf8af..39194a336 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/PetBottomSheet.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/PetBottomSheet.kt
@@ -266,6 +266,7 @@ fun PetBottomSheet(
MainNavigationController.navigate(R.id.marketFragment)
}
dialog.addCloseButton()
+ dialog.show()
}
onDismiss()
}, modifier = Modifier
diff --git a/fastlane/changelog.txt b/fastlane/changelog.txt
index bfed07418..9f5f9f0bc 100644
--- a/fastlane/changelog.txt
+++ b/fastlane/changelog.txt
@@ -1,10 +1,8 @@
-New in 4.3:
-
+New in 4.3.2:
+- Reminders should show more reliably now
+- Remaining Armoire equipment no longer counts unreleased items
+- Better error handling when gifting
+- Avatar widget now displays correctly
- Pets just got cuter! Tap a Pet or Mount to see them in an environment that changes each month.
-- Pets bounce when fed
-- New Subscriber benefit: Buy one Armoire, get another free!
-- New Subscriber benefit: Get a second chance at life once a day when you run out of HP!
-- Tap your avatar to share your latest looks at any time
+- New Subscriber benefits: Buy one Armoire, get another free! Also, get a second chance at life once a day when you run out of HP!
- See answers to common Quest mechanic questions under your active Quest
-- Updated Quest interface
-- The Quest shop now shows a check by completed Quests
\ No newline at end of file
diff --git a/version.properties b/version.properties
index 6abfdaa21..a74c8a8dd 100644
--- a/version.properties
+++ b/version.properties
@@ -1,2 +1,2 @@
NAME=4.3.2
-CODE=6801
\ No newline at end of file
+CODE=6811
\ No newline at end of file