Purchase handler fixes

This commit is contained in:
Phillip Thelen 2024-06-04 11:23:14 +02:00
parent 71d2efb52c
commit 18996b269d
8 changed files with 323 additions and 246 deletions

View file

@ -1,257 +1,288 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:scrollbarSize="3dp"
android:scrollbarThumbVertical="@color/scrollbarThumb"
android:scrollbars="vertical">
<LinearLayout
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:layout_height="match_parent"
android:scrollbarSize="3dp"
android:scrollbarThumbVertical="@color/scrollbarThumb"
android:scrollbars="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.compose.ui.platform.ComposeView
android:id="@+id/promo_compose_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
android:id="@+id/promo_compose_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
<RelativeLayout
android:id="@+id/promo_banner"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@drawable/g1g1_box"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="@dimen/spacing_large"
android:clipChildren="true"
android:clipToPadding="true"
android:focusable="true"
android:clickable="true"
android:visibility="gone"
tools:visibility="visible">
android:id="@+id/promo_banner"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@drawable/g1g1_box"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="@dimen/spacing_large"
android:clipChildren="true"
android:clipToPadding="true"
android:focusable="true"
android:clickable="true"
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:id="@+id/promo_banner_left_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="false"
android:importantForAccessibility="no"/>
android:id="@+id/promo_banner_left_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="false"
android:importantForAccessibility="no" />
<ImageView
android:id="@+id/promo_banner_right_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:importantForAccessibility="no"/>
android:id="@+id/promo_banner_right_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:importantForAccessibility="no" />
<LinearLayout
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/promo_banner_title_image"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"/>
<TextView
android:id="@+id/promo_banner_title_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:textSize="16sp"
android:textStyle="bold"
android:layout_marginStart="84dp"
android:layout_marginEnd="84dp"
android:gravity="center"
android:textColor="@color/white"
android:layout_marginBottom="6dp"/>
android:orientation="vertical">
<ImageView
android:id="@+id/promo_banner_title_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp" />
<TextView
android:id="@+id/promo_banner_duration_view"
android:id="@+id/promo_banner_title_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:textSize="16sp"
android:textStyle="bold"
android:layout_marginStart="84dp"
android:layout_marginEnd="84dp"
android:gravity="center"
android:textColor="@color/white"
android:layout_marginBottom="6dp" />
<TextView
android:id="@+id/promo_banner_duration_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Overline" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Overline"/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="60dp"
android:layout_marginEnd="60dp"
android:gravity="center_horizontal"
android:textColor="@color/white"
android:textSize="16sp"
android:fontFamily="@string/font_family_medium"
android:layout_marginBottom="12dp"
android:layout_centerInParent="true"/>
android:layout_marginStart="60dp"
android:layout_marginEnd="60dp"
android:gravity="center_horizontal"
android:textColor="@color/white"
android:textSize="16sp"
android:fontFamily="@string/font_family_medium"
android:layout_marginBottom="12dp"
android:layout_centerInParent="true" />
</RelativeLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/gem_footer"
android:layout_gravity="bottom"
android:scaleType="fitXY"
tools:ignore="ContentDescription" />
<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="20dp">
android:layout_height="wrap_content">
<ImageView
android:id="@+id/header_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/gem_purchase_header"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="20dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/gem_purchase_subtitle"
android:gravity="center"
android:textStyle="normal|bold"
android:textColor="?colorPrimaryText"
android:textSize="16sp"
android:lineSpacingExtra="4dp"
android:layout_marginTop="23dp"
android:layout_marginBottom="12dp"
android:layout_marginStart="@dimen/spacing_xlarge"
android:layout_marginEnd="@dimen/spacing_xlarge" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/gem_footer"
android:layout_gravity="bottom"
android:scaleType="fitXY"
tools:ignore="ContentDescription" />
<com.habitrpg.android.habitica.ui.views.DayNightTextView
android:text="@string/gem_purchase_listitem1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/GemPurchaseListItem"
/>
<com.habitrpg.android.habitica.ui.views.DayNightTextView
android:text="@string/gem_purchase_listitem2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/GemPurchaseListItem"
/>
<com.habitrpg.android.habitica.ui.views.DayNightTextView
android:text="@string/gem_purchase_listitem3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/GemPurchaseListItem"
/>
<com.habitrpg.android.habitica.ui.views.DayNightTextView
android:text="@string/gem_purchase_listitem4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/GemPurchaseListItem"
/>
<com.habitrpg.android.habitica.ui.views.DayNightTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/no_billing_gems"
android:paddingTop="50dp"
android:paddingBottom="10dp"
android:visibility="gone" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/visit_habitica_website"
android:layout_marginBottom="50dp"
style="@style/HabiticaButton.Purple"
android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="@dimen/spacing_large">
<LinearLayout
<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="16dp">
<com.habitrpg.android.habitica.ui.GemPurchaseOptionsView
android:id="@+id/gems_4_view"
android:layout_width="0dp"
android:paddingHorizontal="20dp">
<ImageView
android:id="@+id/header_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
app:gemAmount="4"
app:gemDrawable="@drawable/gems_4"
android:layout_marginEnd="@dimen/spacing_large"
/>
<com.habitrpg.android.habitica.ui.GemPurchaseOptionsView
android:id="@+id/gems_21_view"
android:layout_width="0dp"
android:src="@drawable/gem_purchase_header"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="20dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
app:gemAmount="21"
app:gemDrawable="@drawable/gems_21" />
</LinearLayout>
android:text="@string/gem_purchase_subtitle"
android:gravity="center"
android:textStyle="normal|bold"
android:textColor="?colorPrimaryText"
android:textSize="16sp"
android:lineSpacingExtra="4dp"
android:layout_marginTop="23dp"
android:layout_marginBottom="12dp"
android:layout_marginStart="@dimen/spacing_xlarge"
android:layout_marginEnd="@dimen/spacing_xlarge" />
<com.habitrpg.android.habitica.ui.views.DayNightTextView
android:text="@string/gem_purchase_listitem1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/GemPurchaseListItem" />
<com.habitrpg.android.habitica.ui.views.DayNightTextView
android:text="@string/gem_purchase_listitem2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/GemPurchaseListItem" />
<com.habitrpg.android.habitica.ui.views.DayNightTextView
android:text="@string/gem_purchase_listitem3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/GemPurchaseListItem" />
<com.habitrpg.android.habitica.ui.views.DayNightTextView
android:text="@string/gem_purchase_listitem4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/GemPurchaseListItem" />
<com.habitrpg.android.habitica.ui.views.DayNightTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/no_billing_gems"
android:paddingTop="50dp"
android:paddingBottom="10dp"
android:visibility="gone" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/visit_habitica_website"
android:layout_marginBottom="50dp"
style="@style/HabiticaButton.Purple"
android:visibility="gone" />
<androidx.compose.ui.platform.ComposeView
android:id="@+id/loading_indicator"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_gravity="center"
android:layout_marginVertical="60dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:dividerPadding="16dp"
android:showDividers="middle"
android:divider="@android:color/white">
<com.habitrpg.android.habitica.ui.GemPurchaseOptionsView
android:id="@+id/gems_42_view"
android:layout_width="0dp"
android:id="@+id/gem_purchase_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
app:gemAmount="42"
app:gemDrawable="@drawable/gems_42"
android:layout_marginEnd="@dimen/spacing_large" />
<com.habitrpg.android.habitica.ui.GemPurchaseOptionsView
android:id="@+id/gems_84_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:gemAmount="84"
app:gemDrawable="@drawable/gems_84" />
android:orientation="vertical"
android:visibility="gone"
android:layout_marginTop="@dimen/spacing_large">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="16dp">
<com.habitrpg.android.habitica.ui.GemPurchaseOptionsView
android:id="@+id/gems_4_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:gemAmount="4"
app:gemDrawable="@drawable/gems_4"
android:layout_marginEnd="@dimen/spacing_large" />
<com.habitrpg.android.habitica.ui.GemPurchaseOptionsView
android:id="@+id/gems_21_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:gemAmount="21"
app:gemDrawable="@drawable/gems_21" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:dividerPadding="16dp"
android:showDividers="middle"
android:divider="@android:color/white">
<com.habitrpg.android.habitica.ui.GemPurchaseOptionsView
android:id="@+id/gems_42_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:gemAmount="42"
app:gemDrawable="@drawable/gems_42"
android:layout_marginEnd="@dimen/spacing_large" />
<com.habitrpg.android.habitica.ui.GemPurchaseOptionsView
android:id="@+id/gems_84_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:gemAmount="84"
app:gemDrawable="@drawable/gems_84" />
</LinearLayout>
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/gift_sub_gift"
android:layout_marginTop="30dp"
android:layout_marginBottom="6dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/text_quad"
android:text="@string/gems_gift_description"
android:gravity="center_horizontal"
android:layout_marginStart="@dimen/spacing_xlarge"
android:layout_marginEnd="@dimen/spacing_xlarge" />
<Button
android:id="@+id/gift_gems_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/gift_gems"
android:background="@color/transparent"
android:textColor="?colorPrimaryText"
android:textAllCaps="false" />
<TextView
android:id="@+id/supportTextView"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingStart="41dp"
android:paddingEnd="41dp"
android:paddingBottom="30dp"
android:paddingTop="70dp"
android:text="@string/gem_purchase_title"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:lineSpacingExtra="3dp"
android:textColor="@color/white"
style="@style/Caption2"
android:drawablePadding="@dimen/spacing_medium" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/gift_sub_gift"
android:layout_marginTop="30dp"
android:layout_marginBottom="6dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/text_quad"
android:text="@string/gems_gift_description"
android:gravity="center_horizontal"
android:layout_marginStart="@dimen/spacing_xlarge"
android:layout_marginEnd="@dimen/spacing_xlarge"/>
<Button
android:id="@+id/gift_gems_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/gift_gems"
android:background="@color/transparent"
android:textColor="?colorPrimaryText"
android:textAllCaps="false"/>
<TextView android:id="@+id/supportTextView"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingStart="41dp"
android:paddingEnd="41dp"
android:paddingBottom="30dp"
android:paddingTop="70dp"
android:text="@string/gem_purchase_title"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:lineSpacingExtra="3dp"
android:textColor="@color/white"
style="@style/Caption2"
android:drawablePadding="@dimen/spacing_medium"/>
</LinearLayout>
</FrameLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View file

@ -1529,6 +1529,8 @@
<string name="customization_shop">Customization Shop</string>
<string name="equipment">Equipment</string>
<string name="customizing_your_avatar">customizing your avatar</string>
<string name="error">Error</string>
<string name="error_loading_gems">There was an error loading gems</string>
<plurals name="you_x_others">
<item quantity="zero">You</item>

View file

@ -3,6 +3,7 @@ package com.habitrpg.android.habitica.helpers
import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import androidx.core.content.edit
import androidx.lifecycle.asFlow
import com.android.billingclient.api.AcknowledgePurchaseParams
@ -22,6 +23,7 @@ import com.android.billingclient.api.acknowledgePurchase
import com.android.billingclient.api.consumePurchase
import com.android.billingclient.api.queryProductDetails
import com.android.billingclient.api.queryPurchasesAsync
import com.google.api.Billing
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.R
@ -56,7 +58,7 @@ class PurchaseHandler(
private val apiClient: ApiClient,
private val userViewModel: MainUserViewModel,
) : PurchasesUpdatedListener, PurchasesResponseListener {
private val billingClient =
private var billingClient =
BillingClient.newBuilder(context).setListener(this).enablePendingPurchases().build()
override fun onPurchasesUpdated(
@ -160,6 +162,7 @@ class PurchaseHandler(
return
}
billingClientState = BillingClientState.CONNECTING
billingClient = BillingClient.newBuilder(context).setListener(this).enablePendingPurchases().build()
billingClient.startConnection(
object : BillingClientStateListener {
override fun onBillingSetupFinished(billingResult: BillingResult) {
@ -172,34 +175,42 @@ class PurchaseHandler(
}
BillingClient.BillingResponseCode.SERVICE_DISCONNECTED -> {
retryListening()
CoroutineScope(Dispatchers.IO).launchCatching {
retryListening()
}
}
BillingClient.BillingResponseCode.SERVICE_TIMEOUT -> {
retryListening()
CoroutineScope(Dispatchers.IO).launchCatching {
retryListening()
}
}
BillingClient.BillingResponseCode.BILLING_UNAVAILABLE -> {
billingClientState = BillingClientState.UNAVAILABLE
}
else -> {
billingClientState = BillingClientState.UNAVAILABLE
billingClientState = BillingClientState.DISCONNECTED
}
}
}
override fun onBillingServiceDisconnected() {
billingClientState = BillingClientState.DISCONNECTED
retryListening()
CoroutineScope(Dispatchers.IO).launchCatching {
retryListening()
}
}
},
)
}
private fun retryListening() {
private suspend fun retryListening() {
listeningRetryCount += 1
CoroutineScope(Dispatchers.IO).launchCatching {
// try again after 30 seconds
delay(30.seconds)
startListening()
}
// try again after 30 seconds
delay(20.seconds)
startListening()
}
fun stopListening() {
@ -260,8 +271,9 @@ class PurchaseHandler(
type: String,
skus: List<String>,
): List<ProductDetails>? {
retryUntil {
if (billingClientState == BillingClientState.DISCONNECTED) {
retryUntil(8, initialDelay = 500, maxDelay = 2000) {
if (billingClient.connectionState == BillingClient.ConnectionState.DISCONNECTED ||
billingClient.connectionState == BillingClient.ConnectionState.CLOSED) {
startListening()
}
billingClientState.canMaybePurchase && billingClient.isReady
@ -276,6 +288,15 @@ class PurchaseHandler(
withContext(Dispatchers.IO) {
billingClient.queryProductDetails(params)
}
if (skuDetailsResult.billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
Log.e("PurchaseHandler", "Failed to load inventory: ${skuDetailsResult.billingResult.debugMessage}")
FirebaseCrashlytics.getInstance().recordException(
Throwable(
"Failed to load inventory: ${skuDetailsResult.billingResult.debugMessage}",
),
)
return null
}
return skuDetailsResult.productDetailsList
}

View file

@ -18,6 +18,7 @@ import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.databinding.FragmentGemPurchaseBinding
import com.habitrpg.android.habitica.extensions.addCancelButton
import com.habitrpg.android.habitica.extensions.addCloseButton
import com.habitrpg.android.habitica.helpers.Analytics
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.PurchaseHandler
@ -34,6 +35,7 @@ import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
import com.habitrpg.common.habitica.helpers.ExceptionHandler
import com.habitrpg.common.habitica.helpers.launchCatching
import com.habitrpg.common.habitica.theme.HabiticaTheme
import com.habitrpg.common.habitica.views.HabiticaCircularProgressView
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -132,12 +134,31 @@ class GemsPurchaseFragment : BaseFragment<FragmentGemPurchaseBinding>() {
}
private fun loadInventory() {
if (binding?.gems4View?.sku == null) {
binding?.loadingIndicator?.setContent {
HabiticaCircularProgressView()
}
binding?.loadingIndicator?.isVisible = true
binding?.gemPurchaseOptions?.isVisible = false
}
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
val skus = purchaseHandler.getAllGemSKUs()
withContext(Dispatchers.Main) {
if (skus.isEmpty()) {
binding?.loadingIndicator?.isVisible = false
binding?.gemPurchaseOptions?.isVisible = false
val dialog = HabiticaAlertDialog(requireActivity())
dialog.setTitle(getString(R.string.error))
dialog.setMessage(getString(R.string.error_loading_gems))
dialog.addCloseButton()
dialog.show()
return@withContext
}
for (sku in skus) {
updateButtonLabel(sku)
}
binding?.loadingIndicator?.isVisible = false
binding?.gemPurchaseOptions?.isVisible = true
}
}
}

View file

@ -91,10 +91,10 @@ class InsufficientGemsDialog(val parentActivity: Activity, var gemPrice: Int) :
purchaseTextView.text = "4"
PurchaseTypes.PURCHASE_4_GEMS
}
CoroutineScope(Dispatchers.IO).launch {
CoroutineScope(Dispatchers.IO).launchCatching {
val sku =
purchaseHandler.getInAppPurchaseSKU(gemSku)
?: return@launch
?: return@launchCatching
withContext(Dispatchers.Main) {
purchaseButton?.text = sku.oneTimePurchaseOfferDetails?.formattedPrice
contentView.findViewById<ProgressBar>(R.id.loading_indicator).isVisible = false

View file

@ -23,13 +23,10 @@ import com.habitrpg.android.habitica.extensions.addCancelButton
import com.habitrpg.android.habitica.extensions.addCloseButton
import com.habitrpg.android.habitica.extensions.getShortRemainingString
import com.habitrpg.android.habitica.helpers.Analytics
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.EventCategory
import com.habitrpg.android.habitica.helpers.HapticFeedbackManager
import com.habitrpg.android.habitica.helpers.HitType
import com.habitrpg.android.habitica.helpers.PurchaseHandler
import com.habitrpg.android.habitica.helpers.SoundManager
import com.habitrpg.android.habitica.interactors.InsufficientGemsUseCase
import com.habitrpg.android.habitica.models.shops.Shop
import com.habitrpg.android.habitica.models.shops.ShopItem
import com.habitrpg.android.habitica.models.user.OwnedItem
@ -42,7 +39,6 @@ import com.habitrpg.android.habitica.ui.views.CurrencyViews
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
import com.habitrpg.android.habitica.ui.views.SnackbarActivity
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import com.habitrpg.android.habitica.ui.views.getTranslatedClassName
import com.habitrpg.android.habitica.ui.views.getTranslatedClassNamePlural
import com.habitrpg.android.habitica.ui.views.insufficientCurrency.InsufficientGemsDialog
import com.habitrpg.android.habitica.ui.views.insufficientCurrency.InsufficientGoldDialog

View file

@ -49,6 +49,12 @@ android {
buildTypes {
release {
}
create("debugIAP") {
initWith(buildTypes["debug"])
isMinifyEnabled = false
isJniDebuggable = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {

View file

@ -1,2 +1,2 @@
NAME=4.3.7
CODE=7831
CODE=7841