diff --git a/Habitica/res/layout/fragment_gift_gem_balance.xml b/Habitica/res/layout/fragment_gift_gem_balance.xml index 614f6c32b..a1f4f3532 100644 --- a/Habitica/res/layout/fragment_gift_gem_balance.xml +++ b/Habitica/res/layout/fragment_gift_gem_balance.xml @@ -75,5 +75,10 @@ style="@style/HabiticaButton.Purple" android:layout_marginTop="@dimen/spacing_medium" android:text="@string/send_gift" /> + \ No newline at end of file diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index c4ac3fda7..5d3ffe647 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -747,7 +747,7 @@ Your gift was sent! You sent %1$s a %2$s-month Habitica subscription and the same subscription was applied to your account for our Gift One Get One promotion! You sent @%1$s a %2$s-month Habitica subscription. - You sent @%s %s gems. + You sent @%1$s %2$s gems. You are now subscribed for 1 month You are now subscribed for %s months You gained %s gems. diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt index 0e507d1fc..75933a88e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt @@ -89,11 +89,10 @@ class SocialRepositoryImpl( return null } val liked = chatMessage.userLikesMessage(userID) - if (chatMessage.isManaged) { - localRepository.likeMessage(chatMessage, userID, !liked) - } + localRepository.likeMessage(chatMessage, userID, !liked) val message = apiClient.likeMessage(chatMessage.groupId ?: "", chatMessage.id) message?.groupId = chatMessage.groupId + message?.let { localRepository.save(it) } return null } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt index 1222416d5..7c8b3b0e3 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt @@ -211,7 +211,9 @@ class PurchaseHandler( } val flowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList(listOf(skuDetails).map { - BillingFlowParams.ProductDetailsParams.newBuilder().setProductDetails(skuDetails) + BillingFlowParams.ProductDetailsParams.newBuilder() + .setProductDetails(skuDetails) + .setOfferToken(skuDetails.subscriptionOfferDetails?.first()?.offerToken ?: "") .build() }) .build() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/PushNotificationManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/PushNotificationManager.kt index fb14775c2..79adfd5c4 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/PushNotificationManager.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/PushNotificationManager.kt @@ -11,6 +11,7 @@ import com.habitrpg.android.habitica.helpers.AmplitudeManager import com.habitrpg.android.habitica.helpers.launchCatching import com.habitrpg.android.habitica.models.user.User import kotlinx.coroutines.MainScope +import java.io.IOException class PushNotificationManager( var apiClient: ApiClient, @@ -52,8 +53,12 @@ class PushNotificationManager( addRefreshToken() } else { FirebaseMessaging.getInstance().token.addOnCompleteListener { - refreshedToken = it.result - addRefreshToken() + try { + refreshedToken = it.result + addRefreshToken() + } catch (_: IOException) { + // This can happen during google test runs + } } } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt index acc6756d5..d67256641 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt @@ -126,7 +126,6 @@ class LoginActivity : BaseActivity() { } override fun getLayoutResId(): Int { - window.requestFeature(Window.FEATURE_ACTION_BAR) return R.layout.activity_login } @@ -136,6 +135,7 @@ class LoginActivity : BaseActivity() { } override fun onCreate(savedInstanceState: Bundle?) { + window.requestFeature(Window.FEATURE_ACTION_BAR) super.onCreate(savedInstanceState) viewModel = AuthenticationViewModel() supportActionBar?.hide() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationEquipmentRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationEquipmentRecyclerViewAdapter.kt index 39bdd2d16..c111d3dfd 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationEquipmentRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationEquipmentRecyclerViewAdapter.kt @@ -111,7 +111,7 @@ class CustomizationEquipmentRecyclerViewAdapter : androidx.recyclerview.widget.R imageView.loadImage("shop_" + this.equipment?.key) val priceLabel = dialogContent.findViewById(R.id.priceLabel) - priceLabel.text = if (equipment?.gearSet == "animal") { + priceLabel?.text = if (equipment?.gearSet == "animal") { 2.0 } else { equipment?.value ?: 0 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 924ca94f3..4215b112d 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 @@ -335,7 +335,7 @@ class AvatarCustomizationFragment : button.setOnCheckedChangeListener { _, isChecked -> val newFilter = filter.copy() newFilter.months = mutableListOf() - newFilter.months.addAll(filter.months) + newFilter.months.addAll(currentFilter.value.months) if (!isChecked && newFilter.months.contains(identifier)) { button.typeface = Typeface.create("sans-serif", Typeface.NORMAL) newFilter.months.remove(identifier) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftBalanceGemsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftBalanceGemsFragment.kt index 4dde1b73f..ac78413e9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftBalanceGemsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftBalanceGemsFragment.kt @@ -5,28 +5,41 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope +import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.databinding.FragmentGiftGemBalanceBinding +import com.habitrpg.android.habitica.extensions.addCloseButton import com.habitrpg.android.habitica.helpers.launchCatching import com.habitrpg.android.habitica.models.members.Member import com.habitrpg.android.habitica.ui.fragments.BaseFragment +import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import javax.inject.Inject class GiftBalanceGemsFragment : BaseFragment() { @Inject lateinit var socialRepository: SocialRepository + @Inject lateinit var userRepository: UserRepository override var binding: FragmentGiftGemBalanceBinding? = null private var isGifting = false + set(value) { + field = value + binding?.giftButton?.isVisible = !isGifting + binding?.progressBar?.isVisible = isGifting + } - override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGiftGemBalanceBinding { + override fun createBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): FragmentGiftGemBalanceBinding { return FragmentGiftGemBalanceBinding.inflate(inflater, container, false) } @@ -61,15 +74,29 @@ class GiftBalanceGemsFragment : BaseFragment() { if (isGifting) return isGifting = true try { - val amount = binding?.giftEditText?.text.toString().toInt() + val amount = binding?.giftEditText?.text.toString().strip().toInt() giftedMember?.id?.let { - lifecycleScope.launchCatching({ + activity?.lifecycleScope?.launchCatching({ isGifting = false }) { socialRepository.transferGems(it, amount) userRepository.retrieveUser(false) + val dialog = context?.let { it1 -> HabiticaAlertDialog(it1) } + dialog?.setTitle(R.string.gift_confirmation_title) + dialog?.setMessage( + getString( + R.string.gift_confirmation_text_gems_new, + giftedMember?.username, + amount.toString() + ) + ) + dialog?.addCloseButton { _, _ -> + activity?.finish() + } + dialog?.show() } } - } catch (ignored: NumberFormatException) {} + } catch (ignored: NumberFormatException) { + } } } diff --git a/common/src/main/java/com/habitrpg/common/habitica/helpers/MarkdownParser.kt b/common/src/main/java/com/habitrpg/common/habitica/helpers/MarkdownParser.kt index 1b28948cb..adeb49fc2 100644 --- a/common/src/main/java/com/habitrpg/common/habitica/helpers/MarkdownParser.kt +++ b/common/src/main/java/com/habitrpg/common/habitica/helpers/MarkdownParser.kt @@ -91,8 +91,12 @@ object MarkdownParser { return SpannableString("") } val hashCode = input.hashCode() - if (cache.containsKey(hashCode)) { - return cache[hashCode] ?: SpannableString(input) + try { + if (cache.containsKey(hashCode)) { + return cache[hashCode] ?: SpannableString(input) + } + } catch (_: NullPointerException) { + // Sometimes happens } val text = EmojiParser.parseEmojis(input) ?: input // Adding this space here bc for some reason some markdown is not rendered correctly when the whole string is supposed to be formatted diff --git a/fastlane/changelog.txt b/fastlane/changelog.txt index 13189c062..fd05a0cc1 100644 --- a/fastlane/changelog.txt +++ b/fastlane/changelog.txt @@ -1,9 +1,12 @@ New in 4.1: --You can view, complete, assign, and add tasks to your Group Plan’s shared task board! +-You can view, complete, assign, and add tasks to your Group Plan's shared task board! -Tap your name on a task screen to switch to different task boards --Subscription details will show extra months and when you’ll get your next Hourglass --More intuitive system notification settings --Audio will be controlled by media volume now -Task details are now tinted based on task health +-New Avatar Customization interface +-Audio will be controlled by media volume now -Fixed a bug that caused tasks to shuffle around -Monthly Dailies should recur more consistently now +-More intuitive system notification settings +-Improved link support +-More special event support + diff --git a/version.properties b/version.properties index 19dae3716..8c685bc20 100644 --- a/version.properties +++ b/version.properties @@ -1,2 +1,2 @@ NAME=4.1 -CODE=4981 \ No newline at end of file +CODE=4991 \ No newline at end of file