This commit is contained in:
Phillip Thelen 2023-01-04 19:44:44 +01:00
parent 827a38faa1
commit 6ff7040647
10 changed files with 90 additions and 47 deletions

View file

@ -162,6 +162,8 @@ class PurchaseHandler(
}
}
suspend fun getGryphatriceSKU() = getSKU(BillingClient.ProductType.INAPP, PurchaseTypes.JubilentGrphatrice)
suspend fun getAllGemSKUs() =
getSKUs(BillingClient.ProductType.INAPP, PurchaseTypes.allGemTypes)
@ -357,7 +359,9 @@ class PurchaseHandler(
suspend fun checkForSubscription(): Purchase? {
val result = withContext(Dispatchers.IO) {
val params = QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.SUBS).build()
val params =
QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.SUBS)
.build()
billingClient.queryPurchasesAsync(params)
}
val fallback: Purchase? = null

View file

@ -3,7 +3,7 @@ package com.habitrpg.android.habitica.ui
import android.content.Context
import android.util.AttributeSet
import android.widget.FrameLayout
import com.android.billingclient.api.SkuDetails
import com.android.billingclient.api.ProductDetails
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.PurchaseGemViewBinding
import com.habitrpg.common.habitica.extensions.layoutInflater
@ -11,7 +11,7 @@ import com.habitrpg.common.habitica.extensions.layoutInflater
class GemPurchaseOptionsView(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs) {
var binding: PurchaseGemViewBinding = PurchaseGemViewBinding.inflate(context.layoutInflater, this, true)
var sku: SkuDetails? = null
var sku: ProductDetails? = null
init {
val a = context.theme.obtainStyledAttributes(

View file

@ -23,6 +23,7 @@ import androidx.compose.material.ProvideTextStyle
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
@ -45,10 +46,15 @@ import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.lifecycleScope
import coil.compose.AsyncImage
import com.android.billingclient.api.ProductDetails
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.data.InventoryRepository
import com.habitrpg.android.habitica.helpers.MainNavigationController
import com.habitrpg.android.habitica.helpers.PurchaseHandler
import com.habitrpg.android.habitica.helpers.launchCatching
import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.theme.HabiticaTheme
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
@ -59,6 +65,13 @@ import javax.inject.Inject
class BirthdayActivity : BaseActivity() {
@Inject
lateinit var userViewModel: MainUserViewModel
@Inject
lateinit var purchaseHandler: PurchaseHandler
@Inject
lateinit var inventoryRepository: InventoryRepository
private val price = mutableStateOf("")
private var gryphatriceProductDetails: ProductDetails? = null
override fun getLayoutResId(): Int? = null
@ -67,7 +80,19 @@ class BirthdayActivity : BaseActivity() {
setContent {
HabiticaTheme {
val user = userViewModel.user.observeAsState()
BirthdayActivityView(user.value)
BirthdayActivityView(user.value, price.value, {
gryphatriceProductDetails?.let {
purchaseHandler.purchase(this, it)
}
}, {
lifecycleScope.launchCatching {
inventoryRepository.purchaseItem("", "Jubilent-Gryphatrice", 1)
}
}, {
lifecycleScope.launchCatching {
inventoryRepository.equip("pets", "Jubilent-Gryphatrice")
}
})
}
}
}
@ -109,7 +134,7 @@ fun BirthdayTitle(text: String) {
}
@Composable
fun BirthdayActivityView(user: User?) {
fun BirthdayActivityView(user: User?, price: String, onPurchaseClick: () -> Unit, onGemPurchaseClick: () -> Unit, onEquipClick: () -> Unit) {
val activity = LocalContext.current as? Activity
val textColor = Color.White
val specialTextColor = colorResource(R.color.yellow_50)
@ -227,7 +252,7 @@ fun BirthdayActivityView(user: User?) {
Text(buildAnnotatedString {
append("Buy for ")
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
append("")
append(price)
}
append(" or ")
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
@ -237,7 +262,9 @@ fun BirthdayActivityView(user: User?) {
HabiticaButton(
Color.White,
colorResource(R.color.brand_200),
{},
{
onPurchaseClick()
},
modifier = Modifier.padding(top = 20.dp)
) {
Text(stringResource(R.string.buy_for_x, ""))
@ -245,7 +272,9 @@ fun BirthdayActivityView(user: User?) {
HabiticaButton(
Color.White,
colorResource(R.color.brand_200),
{},
{
onGemPurchaseClick()
},
modifier = Modifier.padding(top = 20.dp)
) {
Row(verticalAlignment = Alignment.CenterVertically) {
@ -266,7 +295,9 @@ fun BirthdayActivityView(user: User?) {
HabiticaButton(
Color.White,
colorResource(R.color.brand_200),
{},
{
onEquipClick()
},
modifier = Modifier.padding(top = 20.dp)
) {
Text(stringResource(R.string.visit_the_market))
@ -361,5 +392,7 @@ fun HabiticaButton(
@Preview(device = Devices.PIXEL_4)
@Composable
private fun Preview() {
BirthdayActivityView(null)
BirthdayActivityView(null, "", {
}, {}, {})
}

View file

@ -5,7 +5,7 @@ import android.os.Bundle
import android.view.View
import androidx.lifecycle.lifecycleScope
import androidx.navigation.navArgs
import com.android.billingclient.api.SkuDetails
import com.android.billingclient.api.ProductDetails
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.data.SocialRepository
@ -35,8 +35,8 @@ class GiftSubscriptionActivity : PurchaseActivity() {
private var giftedUsername: String? = null
private var giftedUserID: String? = null
private var selectedSubscriptionSku: SkuDetails? = null
private var skus: List<SkuDetails> = emptyList()
private var selectedSubscriptionSku: ProductDetails? = null
private var skus: List<ProductDetails> = emptyList()
override fun getLayoutResId(): Int {
return R.layout.activity_gift_subscription
@ -97,20 +97,20 @@ class GiftSubscriptionActivity : PurchaseActivity() {
for (sku in skus) {
updateButtonLabel(sku)
}
skus.minByOrNull { it.priceAmountMicros }?.let { selectSubscription(it) }
skus.minByOrNull { it.oneTimePurchaseOfferDetails?.priceAmountMicros ?: 0 }?.let { selectSubscription(it) }
}
}
}
private fun updateButtonLabel(sku: SkuDetails) {
private fun updateButtonLabel(sku: ProductDetails) {
val matchingView = buttonForSku(sku)
if (matchingView != null) {
matchingView.setPriceText(sku.price)
matchingView.sku = sku.sku
matchingView.setPriceText(sku.oneTimePurchaseOfferDetails?.formattedPrice ?: "")
matchingView.sku = sku.productId
matchingView.setOnPurchaseClickListener { selectSubscription(sku) }
}
}
private fun selectSubscription(sku: SkuDetails) {
private fun selectSubscription(sku: ProductDetails) {
for (thisSku in skus) {
buttonForSku(thisSku)?.setIsSelected(false)
}
@ -120,8 +120,8 @@ class GiftSubscriptionActivity : PurchaseActivity() {
binding.subscriptionButton.isEnabled = true
}
private fun buttonForSku(sku: SkuDetails?): SubscriptionOptionView? {
return buttonForSku(sku?.sku)
private fun buttonForSku(sku: ProductDetails?): SubscriptionOptionView? {
return buttonForSku(sku?.productId)
}
private fun buttonForSku(sku: String?): SubscriptionOptionView? {
@ -134,12 +134,12 @@ class GiftSubscriptionActivity : PurchaseActivity() {
}
}
private fun purchaseSubscription(sku: SkuDetails) {
private fun purchaseSubscription(sku: ProductDetails) {
giftedUserID?.let { id ->
if (id.isEmpty()) {
return
}
PurchaseHandler.addGift(sku.sku, id, giftedUsername ?: id)
PurchaseHandler.addGift(sku.productId, id, giftedUsername ?: id)
purchaseHandler.purchase(this, sku)
}
}

View file

@ -213,13 +213,14 @@ class ItemDialogFragment : BaseDialogFragment<FragmentItemsDialogBinding>() {
}
}
adapter?.onHatchPet = { pet, egg -> hatchPet(pet, egg) }
adapter?.onFeedPet = { food -> feedPet(food) }
}
}
private fun feedPet(food: Food) {
val pet = feedingPet ?: return
val activity = activity ?: return
lifecycleScope.launchCatching {
activity.lifecycleScope.launchCatching {
feedPetUseCase.callInteractor(
FeedPetUseCase.RequestValues(
pet, food,

View file

@ -7,7 +7,8 @@ import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.fragment.app.Fragment
import com.android.billingclient.api.SkuDetails
import androidx.lifecycle.lifecycleScope
import com.android.billingclient.api.ProductDetails
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.data.UserRepository
@ -18,6 +19,7 @@ import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.ExceptionHandler
import com.habitrpg.android.habitica.helpers.PurchaseHandler
import com.habitrpg.android.habitica.helpers.PurchaseTypes
import com.habitrpg.android.habitica.helpers.launchCatching
import com.habitrpg.android.habitica.models.promotions.PromoType
import com.habitrpg.android.habitica.ui.GemPurchaseOptionsView
import com.habitrpg.android.habitica.ui.activities.GiftGemsActivity
@ -95,7 +97,9 @@ class GemsPurchaseFragment : BaseFragment<FragmentGemPurchaseBinding>() {
override fun onResume() {
super.onResume()
purchaseHandler.queryPurchases()
lifecycleScope.launchCatching {
purchaseHandler.queryPurchases()
}
loadInventory()
}
@ -110,8 +114,8 @@ class GemsPurchaseFragment : BaseFragment<FragmentGemPurchaseBinding>() {
}
}
private fun updateButtonLabel(sku: SkuDetails) {
val matchingView: GemPurchaseOptionsView? = when (sku.sku) {
private fun updateButtonLabel(sku: ProductDetails) {
val matchingView: GemPurchaseOptionsView? = when (sku.productId) {
PurchaseTypes.Purchase4Gems -> binding?.gems4View
PurchaseTypes.Purchase21Gems -> binding?.gems21View
PurchaseTypes.Purchase42Gems -> binding?.gems42View
@ -119,7 +123,7 @@ class GemsPurchaseFragment : BaseFragment<FragmentGemPurchaseBinding>() {
else -> return
}
if (matchingView != null) {
matchingView.setPurchaseButtonText(sku.price)
matchingView.setPurchaseButtonText(sku.oneTimePurchaseOfferDetails?.formattedPrice ?: "")
matchingView.sku = sku
}
}

View file

@ -5,7 +5,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.android.billingclient.api.SkuDetails
import com.android.billingclient.api.ProductDetails
import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.FragmentGiftGemPurchaseBinding
@ -59,7 +59,7 @@ class GiftPurchaseGemsFragment : BaseFragment<FragmentGiftGemPurchaseBinding>()
val skus = purchaseHandler?.getAllGemSKUs()
withContext(Dispatchers.Main) {
for (sku in skus ?: emptyList()) {
updateButtonLabel(sku, sku.price)
updateButtonLabel(sku, sku.oneTimePurchaseOfferDetails?.formattedPrice ?: "")
}
}
}
@ -69,8 +69,8 @@ class GiftPurchaseGemsFragment : BaseFragment<FragmentGiftGemPurchaseBinding>()
this.purchaseHandler = handler
}
private fun updateButtonLabel(sku: SkuDetails, price: String) {
val matchingView: GemPurchaseOptionsView? = when (sku.sku) {
private fun updateButtonLabel(sku: ProductDetails, price: String) {
val matchingView: GemPurchaseOptionsView? = when (sku.productId) {
PurchaseTypes.Purchase4Gems -> binding?.gems4View
PurchaseTypes.Purchase21Gems -> binding?.gems21View
PurchaseTypes.Purchase42Gems -> binding?.gems42View
@ -86,7 +86,7 @@ class GiftPurchaseGemsFragment : BaseFragment<FragmentGiftGemPurchaseBinding>()
}
}
private fun purchaseGems(sku: SkuDetails) {
private fun purchaseGems(sku: ProductDetails) {
giftedMember?.id?.let {
activity?.let { it1 -> purchaseHandler?.purchase(it1, sku, it, giftedMember?.username) }
}

View file

@ -9,7 +9,7 @@ import android.view.ViewGroup
import android.widget.EditText
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.android.billingclient.api.SkuDetails
import com.android.billingclient.api.ProductDetails
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.data.InventoryRepository
@ -54,8 +54,8 @@ class SubscriptionFragment : BaseFragment<FragmentSubscriptionBinding>() {
@Inject
lateinit var purchaseHandler: PurchaseHandler
private var selectedSubscriptionSku: SkuDetails? = null
private var skus: List<SkuDetails> = emptyList()
private var selectedSubscriptionSku: ProductDetails? = null
private var skus: List<ProductDetails> = emptyList()
private var user: User? = null
private var hasLoadedSubscriptionOptions: Boolean = false
@ -108,7 +108,9 @@ class SubscriptionFragment : BaseFragment<FragmentSubscriptionBinding>() {
override fun onResume() {
super.onResume()
purchaseHandler.queryPurchases()
lifecycleScope.launchCatching {
purchaseHandler.queryPurchases()
}
refresh()
loadInventory()
}
@ -131,27 +133,27 @@ class SubscriptionFragment : BaseFragment<FragmentSubscriptionBinding>() {
skus = subscriptions
withContext(Dispatchers.Main) {
for (sku in subscriptions) {
updateButtonLabel(sku, sku.price)
updateButtonLabel(sku, sku.subscriptionOfferDetails?.firstOrNull()?.pricingPhases?.pricingPhaseList?.firstOrNull()?.formattedPrice ?: "")
}
subscriptions.minByOrNull { it.priceAmountMicros }?.let { selectSubscription(it) }
subscriptions.minByOrNull { it.subscriptionOfferDetails?.firstOrNull()?.pricingPhases?.pricingPhaseList?.firstOrNull()?.priceAmountMicros ?: 0 }?.let { selectSubscription(it) }
hasLoadedSubscriptionOptions = true
updateSubscriptionInfo()
}
}
}
private fun updateButtonLabel(sku: SkuDetails, price: String) {
private fun updateButtonLabel(sku: ProductDetails, price: String) {
val matchingView = buttonForSku(sku)
if (matchingView != null) {
matchingView.setPriceText(price)
matchingView.sku = sku.sku
matchingView.sku = sku.productId
matchingView.setOnPurchaseClickListener {
selectSubscription(sku)
}
}
}
private fun selectSubscription(sku: SkuDetails) {
private fun selectSubscription(sku: ProductDetails) {
if (this.selectedSubscriptionSku != null) {
val oldButton = buttonForSku(this.selectedSubscriptionSku)
oldButton?.setIsSelected(false)
@ -164,8 +166,8 @@ class SubscriptionFragment : BaseFragment<FragmentSubscriptionBinding>() {
}
}
private fun buttonForSku(sku: SkuDetails?): SubscriptionOptionView? {
return buttonForSku(sku?.sku)
private fun buttonForSku(sku: ProductDetails?): SubscriptionOptionView? {
return buttonForSku(sku?.productId)
}
private fun buttonForSku(sku: String?): SubscriptionOptionView? {

View file

@ -12,7 +12,6 @@ import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.extensions.addCloseButton
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.ExceptionHandler
import com.habitrpg.android.habitica.helpers.MainNavigationController
import com.habitrpg.android.habitica.helpers.PurchaseHandler
import com.habitrpg.android.habitica.helpers.PurchaseTypes
@ -67,7 +66,7 @@ class InsufficientGemsDialog(context: Context, var gemPrice: Int) : Insufficient
val sku = purchaseHandler.getInAppPurchaseSKU(gemSku)
?: return@launch
withContext(Dispatchers.Main) {
purchaseButton?.text = sku.price
purchaseButton?.text = sku.oneTimePurchaseOfferDetails?.formattedPrice
contentView.findViewById<ProgressBar>(R.id.loading_indicator).isVisible = false
purchaseButton.isVisible = true

View file

@ -1,2 +1,2 @@
NAME=4.1
CODE=4951
CODE=4961