From 55a9da2be3becf1249453389d9080d0cddd96c52 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Fri, 5 Jan 2024 16:05:40 +0100 Subject: [PATCH] final fixes --- .../res/layout/activity_gift_subscription.xml | 1 + Habitica/res/layout/widget_avatar_stats.xml | 4 +- Habitica/res/values/strings.xml | 4 +- .../data/implementation/UserRepositoryImpl.kt | 2 +- .../android/habitica/models/tasks/Task.kt | 2 +- .../ui/activities/GiftGemsActivity.kt | 41 ++++++++++++++++--- .../ui/activities/GiftSubscriptionActivity.kt | 39 ++++++++++++++---- .../equipment/EquipmentDetailFragment.kt | 12 +++--- .../stable/PetDetailRecyclerFragment.kt | 12 +++--- .../preferences/PreferencesFragment.kt | 3 ++ .../ui/views/stable/PetBottomSheet.kt | 1 + fastlane/changelog.txt | 14 +++---- version.properties | 2 +- 13 files changed, 100 insertions(+), 37 deletions(-) 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