Fixes issue where GoPro button appears even if the user is subscribed

kmm
Laurent 5 years ago
parent 6c2367aa7f
commit eeaba2876a
  1. 22
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt
  2. 17
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt
  3. 33
      app/src/main/java/net/pokeranalytics/android/ui/modules/feed/FeedFragment.kt
  4. 48
      app/src/main/java/net/pokeranalytics/android/util/billing/AppGuard.kt

@ -12,6 +12,7 @@ import android.view.ViewGroup
import android.widget.Toast
import androidx.core.content.FileProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.android.billingclient.api.Purchase
import com.google.android.play.core.review.ReviewManagerFactory
import io.realm.Realm
import kotlinx.android.synthetic.main.fragment_settings.*
@ -37,6 +38,7 @@ import net.pokeranalytics.android.ui.view.rowrepresentable.SettingRow
import net.pokeranalytics.android.util.*
import net.pokeranalytics.android.util.billing.AppGuard
import net.pokeranalytics.android.util.billing.IAPProducts
import net.pokeranalytics.android.util.billing.PurchaseListener
import net.pokeranalytics.android.util.csv.ProductCSVDescriptors
import net.pokeranalytics.android.util.extensions.dateTimeFileFormatted
import timber.log.Timber
@ -45,7 +47,7 @@ import java.io.IOException
import java.util.*
class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepresentableDataSource {
class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepresentableDataSource, PurchaseListener {
companion object {
@ -69,6 +71,16 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
private lateinit var settingsAdapterRow: RowRepresentableAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppGuard.registerListener(this)
}
override fun onDestroy() {
super.onDestroy()
AppGuard.unregisterListener(this)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_settings, container, false)
@ -299,4 +311,12 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
}
override fun purchaseDidSucceed(purchase: Purchase) {
this.settingsAdapterRow.refreshRow(SettingRow.SUBSCRIPTION)
}
override fun noPurchaseRetrieved() {
}
}

@ -32,12 +32,12 @@ import net.pokeranalytics.android.ui.fragment.components.ScreenSlidePageFragment
import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.billing.AppGuard
import net.pokeranalytics.android.util.billing.IAPProducts
import net.pokeranalytics.android.util.billing.PurchaseDelegate
import net.pokeranalytics.android.util.billing.PurchaseListener
import java.lang.ref.WeakReference
import java.time.Period
import java.time.format.DateTimeParseException
class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, PurchaseDelegate, ViewPager.OnPageChangeListener {
class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, PurchaseListener, ViewPager.OnPageChangeListener {
companion object {
val parallax: Float = 64f.px
@ -67,6 +67,8 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
return
}
AppGuard.registerListener(this)
this.showLoader(R.string.loading_please_wait)
if (!AppGuard.requestProducts(this)) {
this.hideLoader()
@ -86,6 +88,11 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
initUI()
}
override fun onDestroy() {
super.onDestroy()
AppGuard.unregisterListener(this)
}
private fun initData() {
this.showSessionMessage = arguments?.getBoolean(BundleKey.SHOW_MESSAGE.value) ?: false
}
@ -133,7 +140,7 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
this.purchase.setOnClickListener {
this.selectedProduct?.let {
AppGuard.initiatePurchase(this.requireActivity(), it, this)
AppGuard.initiatePurchase(this.requireActivity(), it)
} ?: run {
throw PAIllegalStateException("Attempt to initiate purchase while no product has been chosen")
}
@ -236,6 +243,10 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
this.activity?.finish()
}
override fun noPurchaseRetrieved() {
}
// OnPageChangeListener
override fun onPageScrollStateChanged(state: Int) {}

@ -8,6 +8,7 @@ import android.widget.Toast
import androidx.core.app.ActivityOptionsCompat
import androidx.core.view.isVisible
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import com.android.billingclient.api.Purchase
import com.google.android.material.tabs.TabLayout
import io.realm.RealmModel
import io.realm.RealmResults
@ -37,11 +38,12 @@ import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager
import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.billing.AppGuard
import net.pokeranalytics.android.util.billing.PurchaseListener
import net.pokeranalytics.android.util.extensions.count
import timber.log.Timber
import java.util.*
class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
class FeedFragment : FilterableFragment(), RowRepresentableDelegate, PurchaseListener {
private enum class Tab {
SESSIONS,
@ -104,6 +106,11 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppGuard.registerListener(this)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -205,6 +212,11 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
}
override fun onDestroy() {
AppGuard.unregisterListener(this)
super.onDestroy()
}
override fun onDestroyView() {
super.onDestroyView()
realmTransactions.removeAllChangeListeners()
@ -313,7 +325,6 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
this.showSubscriptionButton()
}
}
this.showSubscriptionButton()
}
@ -419,11 +430,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
/**
* Create a new cash game
*/
private fun createNewSession(
isTournament: Boolean,
sessionId: String? = null,
duplicate: Boolean = false
) {
private fun createNewSession(isTournament: Boolean, sessionId: String? = null, duplicate: Boolean = false) {
val sessionCount = getRealm().count(Session::class.java)
if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG
@ -473,10 +480,6 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
*/
private fun createNewHandHistory() {
// val intent = Intent(requireContext(), TestActivity::class.java)
// startActivity(intent)
// return
AppGuard.endOfUse?.let { endDate ->
if (Date().after(endDate)) {
this.showEndOfUseMessage()
@ -577,4 +580,12 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
this.sessionAdapter.notifyDataSetChanged() // refreshes session durations
}
override fun purchaseDidSucceed(purchase: Purchase) {
this.showSubscriptionButton()
}
override fun noPurchaseRetrieved() {
this.showSubscriptionButton()
}
}

@ -18,8 +18,9 @@ enum class IAPProducts(var identifier: String) {
PRO("unlimited")
}
interface PurchaseDelegate {
interface PurchaseListener {
fun purchaseDidSucceed(purchase: Purchase)
fun noPurchaseRetrieved()
}
/**
@ -61,6 +62,8 @@ object AppGuard : PurchasesUpdatedListener {
*/
val isProUser: Boolean
get() {
return this._isProUser
if (this.endOfUse != null) return true
@ -93,7 +96,7 @@ object AppGuard : PurchasesUpdatedListener {
/**
* A delegate to notify when the purchase has succeeded
*/
private var purchaseDelegate: PurchaseDelegate? = null
private var purchaseListeners: MutableList<PurchaseListener> = mutableListOf()
/**
* Initialization of AppGuard
@ -206,9 +209,7 @@ object AppGuard : PurchasesUpdatedListener {
/**
* Initiates purchase with the product [skuDetails]
*/
fun initiatePurchase(activity: Activity, skuDetails: SkuDetails, delegate: PurchaseDelegate) {
this.purchaseDelegate = delegate
fun initiatePurchase(activity: Activity, skuDetails: SkuDetails) {
val flowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
@ -225,9 +226,13 @@ object AppGuard : PurchasesUpdatedListener {
override fun onPurchasesUpdated(result: BillingResult, purchases: MutableList<Purchase>?) {
if (result.responseCode == BillingResponseCode.OK && purchases != null) {
for (purchase in purchases) {
handlePurchase(purchase)
if (result.responseCode == BillingResponseCode.OK) {
if (purchases != null && purchases.isNotEmpty()) {
for (purchase in purchases) {
handlePurchase(purchase)
}
} else {
sendNoPurchaseRetrievedEvent()
}
} else if (result.responseCode == BillingResponseCode.USER_CANCELED) {
Timber.d("purchase cancel message: ${result.debugMessage}")
@ -240,6 +245,12 @@ object AppGuard : PurchasesUpdatedListener {
}
private fun sendNoPurchaseRetrievedEvent() {
this.purchaseListeners.forEach { listener ->
listener.noPurchaseRetrieved()
}
}
// /**
// * Purchase callback
// */
@ -280,12 +291,13 @@ object AppGuard : PurchasesUpdatedListener {
}
this._isProUser = true
this.purchaseDelegate?.let {
this.purchaseListeners.forEach { listener ->
Handler(Looper.getMainLooper()).post {
it.purchaseDidSucceed(purchase)
listener.purchaseDidSucceed(purchase)
}
this.purchaseDelegate = null
}
}
}
@ -318,4 +330,18 @@ object AppGuard : PurchasesUpdatedListener {
return context.getString(resId)
}
/***
* Removes a listener
*/
fun registerListener(listener: PurchaseListener) {
this.purchaseListeners.add(listener)
}
/***
* Removes a listener
*/
fun unregisterListener(listener: PurchaseListener) {
this.purchaseListeners.remove(listener)
}
}
Loading…
Cancel
Save