@ -1,23 +1,31 @@
package net.pokeranalytics.android.ui.fragment
package net.pokeranalytics.android.ui.fragment
import android.os.Build
import android.os.Bundle
import android.os.Bundle
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.TypefaceSpan
import android.view.LayoutInflater
import android.view.LayoutInflater
import android.view.View
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup
import android.widget.Toast
import android.widget.Toast
import androidx.core.content.res.ResourcesCompat
import com.android.billingclient.api.BillingClient
import com.android.billingclient.api.BillingClient
import com.android.billingclient.api.Purchase
import com.android.billingclient.api.SkuDetails
import com.android.billingclient.api.SkuDetails
import com.android.billingclient.api.SkuDetailsResponseListener
import com.android.billingclient.api.SkuDetailsResponseListener
import kotlinx.android.synthetic.main.fragment_subscription.*
import kotlinx.android.synthetic.main.fragment_subscription.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.billing.AppGuard
import net.pokeranalytics.android.util.billing.AppGuard
import net.pokeranalytics.android.util.billing.IAPProducts
import net.pokeranalytics.android.util.billing.IAPProducts
import net.pokeranalytics.android.util.billing.PurchaseDelegate
import net.pokeranalytics.android.util.billing.PurchaseDelegate
class SubscriptionFragment : PokerAnalyticsFragment ( ) , SkuDetailsResponseListener , PurchaseDelegate {
class SubscriptionFragment : PokerAnalyticsFragment ( ) , SkuDetailsResponseListener , PurchaseDelegate {
var selectedProduct : SkuDetails ? = null
private var selectedProduct : SkuDetails ? = null
override fun onCreate ( savedInstanceState : Bundle ? ) {
override fun onCreate ( savedInstanceState : Bundle ? ) {
super . onCreate ( savedInstanceState )
super . onCreate ( savedInstanceState )
@ -25,7 +33,6 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene
if ( ! AppGuard . requestProducts ( this ) ) {
if ( ! AppGuard . requestProducts ( this ) ) {
Toast . makeText ( requireContext ( ) , R . string . billingclient _unavailable , Toast . LENGTH _LONG ) . show ( )
Toast . makeText ( requireContext ( ) , R . string . billingclient _unavailable , Toast . LENGTH _LONG ) . show ( )
}
}
}
}
override fun onCreateView ( inflater : LayoutInflater , container : ViewGroup ? , savedInstanceState : Bundle ? ) : View ? {
override fun onCreateView ( inflater : LayoutInflater , container : ViewGroup ? , savedInstanceState : Bundle ? ) : View ? {
@ -36,21 +43,34 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene
super . onViewCreated ( view , savedInstanceState )
super . onViewCreated ( view , savedInstanceState )
initUI ( )
initUI ( )
}
}
// SkuDetailsResponseListener
private fun initUI ( ) {
override fun onSkuDetailsResponse ( responseCode : Int , skuDetailsList : MutableList < SkuDetails > ? ) {
if ( responseCode == BillingClient . BillingResponse . OK && skuDetailsList != null ) {
val upgradeString = requireContext ( ) . getString ( R . string . pro _upgrade )
selectedProduct = skuDetailsList . first { it . sku == IAPProducts . PRO . identifier }
updatePurchaseButtonState ( )
if ( Build . VERSION . SDK _INT >= Build . VERSION _CODES . P ) {
}
val ssb = SpannableStringBuilder ( upgradeString )
val indexOfLastSpace = upgradeString . lastIndexOf ( " " )
val end = upgradeString . chars ( ) . count ( ) . toInt ( )
val lightTypeFace = ResourcesCompat . getFont ( requireContext ( ) , R . font . roboto _light )
val boldTypeFace = ResourcesCompat . getFont ( requireContext ( ) , R . font . roboto _bold )
if ( lightTypeFace != null && boldTypeFace != null ) {
ssb . setSpan ( TypefaceSpan ( lightTypeFace ) , 0 , indexOfLastSpace , Spanned . SPAN _EXCLUSIVE _INCLUSIVE )
ssb . setSpan ( TypefaceSpan ( boldTypeFace ) , indexOfLastSpace , end , Spanned . SPAN _EXCLUSIVE _INCLUSIVE )
}
}
private fun initUI ( ) {
this . title . text = ssb
} else {
this . title . text = upgradeString
}
this . purchase . isEnabled = false
this . purchase . setOnClickListener {
this . purchase . setOnClickListener {
this . selectedProduct ?. let {
this . selectedProduct ?. let {
@ -59,16 +79,37 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene
throw IllegalStateException ( " Attempt to initiate purchase while no product has been chosen " )
throw IllegalStateException ( " Attempt to initiate purchase while no product has been chosen " )
}
}
}
}
}
// SkuDetailsResponseListener
override fun onSkuDetailsResponse ( responseCode : Int , skuDetailsList : MutableList < SkuDetails > ? ) {
if ( responseCode == BillingClient . BillingResponse . OK && skuDetailsList != null ) {
selectedProduct = skuDetailsList . first { it . sku == IAPProducts . PRO . identifier }
updateUI ( )
}
}
private fun updateUI ( ) {
this . selectedProduct ?. let {
this . purchase . isEnabled = true
val perYearString = requireContext ( ) . getString ( R . string . year _subscription )
val formattedPrice = it . price + " / " + perYearString
this . price . text = formattedPrice
}
}
private fun updatePurchaseButtonState ( ) {
this . purchase . isEnabled = ( this . selectedProduct != null )
}
}
// PurchaseDelegate
// PurchaseDelegate
override fun purchaseDidSucceed ( ) {
override fun purchaseDidSucceed ( purchase : Purchase ) {
// record purchase in preferences for troubleshooting / verification
val purchaseInfos = listOf ( purchase . sku , purchase . orderId , purchase . purchaseToken )
Preferences . setString ( Preferences . Keys . LATEST _PURCHASE , purchaseInfos . joinToString ( " / " ) , requireContext ( ) )
this . activity ?. finish ( )
this . activity ?. finish ( )
}
}