|
|
|
|
@ -35,7 +35,7 @@ import java.lang.ref.WeakReference |
|
|
|
|
import java.time.Period |
|
|
|
|
import java.time.format.DateTimeParseException |
|
|
|
|
|
|
|
|
|
class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, PurchaseListener, ViewPager.OnPageChangeListener { |
|
|
|
|
class SubscriptionFragment : BaseFragment(), ProductDetailsResponseListener, PurchaseListener, ViewPager.OnPageChangeListener { |
|
|
|
|
|
|
|
|
|
companion object { |
|
|
|
|
val parallax: Float = 64f.px |
|
|
|
|
@ -50,7 +50,9 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private var pagerAdapter: ScreenSlidePagerAdapter? = null |
|
|
|
|
private var selectedProduct: SkuDetails? = null |
|
|
|
|
private var selectedProduct: ProductDetails? = null |
|
|
|
|
private var selectedOfferDetails: ProductDetails.SubscriptionOfferDetails? = null |
|
|
|
|
|
|
|
|
|
private var showSessionMessage = false |
|
|
|
|
|
|
|
|
|
private var _binding: FragmentSubscriptionBinding? = null |
|
|
|
|
@ -164,8 +166,14 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas |
|
|
|
|
return@setOnClickListener |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.selectedProduct?.let { |
|
|
|
|
AppGuard.initiatePurchase(this.requireActivity(), it) |
|
|
|
|
this.selectedProduct?.let { productDetails -> |
|
|
|
|
|
|
|
|
|
this.selectedOfferDetails?.let { offerDetails -> |
|
|
|
|
AppGuard.initiatePurchase(this.requireActivity(), productDetails, offerDetails.offerToken) |
|
|
|
|
|
|
|
|
|
}?: run { |
|
|
|
|
Toast.makeText(requireContext(), R.string.product_unavailable, Toast.LENGTH_LONG).show() |
|
|
|
|
} |
|
|
|
|
} ?: run { |
|
|
|
|
Toast.makeText(requireContext(), R.string.product_unavailable, Toast.LENGTH_LONG).show() |
|
|
|
|
} |
|
|
|
|
@ -225,32 +233,71 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// SkuDetailsResponseListener |
|
|
|
|
override fun onSkuDetailsResponse(result: BillingResult, skuDetailsList: MutableList<SkuDetails>?) { |
|
|
|
|
// override fun onSkuDetailsResponse(result: BillingResult, skuDetailsList: MutableList<SkuDetails>?) { |
|
|
|
|
// if (result.responseCode == BillingClient.BillingResponseCode.OK) { |
|
|
|
|
// this.hideLoader() |
|
|
|
|
// selectedProduct = skuDetailsList?.firstOrNull { it.sku == IAPProducts.PRO.identifier } |
|
|
|
|
// updateUI() |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
// ProductDetailsResponseListener |
|
|
|
|
override fun onProductDetailsResponse(result: BillingResult, productList: MutableList<ProductDetails>) { |
|
|
|
|
if (result.responseCode == BillingClient.BillingResponseCode.OK) { |
|
|
|
|
this.hideLoader() |
|
|
|
|
selectedProduct = skuDetailsList?.firstOrNull { it.sku == IAPProducts.PRO.identifier } |
|
|
|
|
selectedProduct = productList.firstOrNull { it.productId == IAPProducts.PRO.identifier } |
|
|
|
|
|
|
|
|
|
this.selectedOfferDetails = selectedProduct?.subscriptionOfferDetails?.firstOrNull() |
|
|
|
|
|
|
|
|
|
Timber.d("OFFERS = ${this.selectedProduct?.subscriptionOfferDetails?.size ?: 0}") |
|
|
|
|
|
|
|
|
|
updateUI() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun updateUI() { |
|
|
|
|
this.selectedProduct?.let { |
|
|
|
|
val perYearString = requireContext().getString(R.string.year_subscription) |
|
|
|
|
val formattedPrice = it.price + " / " + perYearString |
|
|
|
|
binding.price.text = formattedPrice |
|
|
|
|
|
|
|
|
|
var freeTrialDays = 30 // initial, should be more, no less |
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { |
|
|
|
|
try { |
|
|
|
|
val p = Period.parse(it.freeTrialPeriod) |
|
|
|
|
freeTrialDays = p.days |
|
|
|
|
} catch (e: DateTimeParseException) { |
|
|
|
|
CrashLogging.log("Error parsing period with value: ${it.freeTrialPeriod}") |
|
|
|
|
this.selectedProduct?.let { productDetails -> |
|
|
|
|
|
|
|
|
|
var price: String? = null |
|
|
|
|
var freeTrialPeriod: String? = null |
|
|
|
|
|
|
|
|
|
productDetails.subscriptionOfferDetails?.firstOrNull()?.let { details -> |
|
|
|
|
details.pricingPhases.pricingPhaseList.forEach { pricingPhase -> |
|
|
|
|
|
|
|
|
|
when (pricingPhase.priceAmountMicros) { |
|
|
|
|
0L -> { |
|
|
|
|
freeTrialPeriod = pricingPhase.billingPeriod |
|
|
|
|
} |
|
|
|
|
else -> { |
|
|
|
|
price = pricingPhase.formattedPrice |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
price?.let { |
|
|
|
|
val perYearString = requireContext().getString(R.string.year_subscription) |
|
|
|
|
val formattedPrice = "$it / $perYearString" |
|
|
|
|
binding.price.text = formattedPrice |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
freeTrialPeriod?.let { |
|
|
|
|
var freeTrialDays = 30 // initial, should be more, no less |
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { |
|
|
|
|
try { |
|
|
|
|
val p = Period.parse(it) |
|
|
|
|
freeTrialDays = p.days |
|
|
|
|
} catch (e: DateTimeParseException) { |
|
|
|
|
CrashLogging.log("Error parsing period with value: $it") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
val formattedFreeTrial = |
|
|
|
|
"$freeTrialDays " + requireContext().getString(R.string.days) + " " + requireContext().getString(R.string.free_trial) |
|
|
|
|
binding.freetrial.text = formattedFreeTrial |
|
|
|
|
} |
|
|
|
|
val formattedFreeTrial = |
|
|
|
|
"$freeTrialDays " + requireContext().getString(R.string.days) + " " + requireContext().getString(R.string.free_trial) |
|
|
|
|
binding.freetrial.text = formattedFreeTrial |
|
|
|
|
|
|
|
|
|
} ?: run { |
|
|
|
|
Toast.makeText(requireContext(), R.string.contact_support, Toast.LENGTH_LONG).show() |
|
|
|
|
} |
|
|
|
|
@ -261,7 +308,7 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas |
|
|
|
|
override fun purchaseDidSucceed(purchase: Purchase) { |
|
|
|
|
|
|
|
|
|
// record purchase in preferences for troubleshooting / verification |
|
|
|
|
val purchaseInfos = listOf(purchase.sku, purchase.orderId, purchase.purchaseToken) |
|
|
|
|
val purchaseInfos = listOf(purchase.products.joinToString(" - "), purchase.orderId, purchase.purchaseToken) |
|
|
|
|
Preferences.setString(Preferences.Keys.LATEST_PURCHASE, purchaseInfos.joinToString("/"), requireContext()) |
|
|
|
|
|
|
|
|
|
this.activity?.finish() |
|
|
|
|
@ -286,8 +333,7 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas |
|
|
|
|
|
|
|
|
|
private fun updatePagerIndicators(position: Int) { |
|
|
|
|
binding.pageIndicator.children.forEachIndexed { index, view -> |
|
|
|
|
val drawable = view.background |
|
|
|
|
when (drawable) { |
|
|
|
|
when (val drawable = view.background) { |
|
|
|
|
is GradientDrawable -> { |
|
|
|
|
val color = if (position == index) R.color.white else R.color.quantum_grey |
|
|
|
|
drawable.setColor(requireContext().getColor(color)) |
|
|
|
|
|