diff --git a/app/build.gradle b/app/build.gradle
index 814b84aa..affea5d0 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -34,8 +34,8 @@ android {
applicationId "net.pokeranalytics.android"
minSdkVersion 23
targetSdkVersion 29
- versionCode 105
- versionName "5.0.7"
+ versionCode 108
+ versionName "5.0.8"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -112,9 +112,7 @@ dependencies {
implementation 'com.google.android.libraries.places:places:2.3.0'
// Billing / Subscriptions
- // WARNING FOR 2.0: https://developer.android.com/google/play/billing/billing_library_releases_notes
- // Purchases MUST BE ACKNOWLEDGED
- implementation 'com.android.billingclient:billing:1.2.2'
+ implementation 'com.android.billingclient:billing:3.0.0'
// Firebase
implementation 'com.google.firebase:firebase-core:17.5.0'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8ffe53ad..7951a288 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,7 +5,6 @@
-
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt
index 09cfd829..111cee96 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt
@@ -47,7 +47,6 @@ import java.util.*
class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepresentableDataSource {
-
companion object {
/**
@@ -143,7 +142,7 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
if (!AppGuard.isProUser) {
BillingActivity.newInstanceForResult(this, false)
} else {
- this.openPlaystoreAccount()
+ this.openPlayStoreAccount()
}
}
SettingRow.RATE_APP -> showReviewManager()
@@ -175,8 +174,8 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
private fun showReviewManager() {
val manager = ReviewManagerFactory.create(requireContext())
- val request = manager.requestReviewFlow()
- request.addOnCompleteListener { request ->
+ val task = manager.requestReviewFlow()
+ task.addOnCompleteListener { request ->
if (request.isSuccessful) {
// We got the ReviewInfo object
val reviewInfo = request.result
@@ -243,7 +242,7 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
/**
* Open Google Play account
*/
- private fun openPlaystoreAccount() {
+ private fun openPlayStoreAccount() {
val packageName = "net.pokeranalytics.android"
val sku = IAPProducts.PRO.identifier
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt
index 60ed311d..dc4913ee 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt
@@ -7,7 +7,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import io.realm.Realm
-import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
@@ -59,7 +58,7 @@ class StatisticsFragment : FilterableFragment(), RealmAsyncListener {
initUI()
this.currentFilterable = FilterableType.SESSION
applyFilter()
- listenAsynchronously(this, ComputableResult::class.java)
+ listenRealmChanges(this, ComputableResult::class.java)
}
private fun initUI() {
@@ -117,13 +116,14 @@ class StatisticsFragment : FilterableFragment(), RealmAsyncListener {
// Business
override fun asyncListenedEntityChange(realm: Realm) {
+ launchStatComputation()
- val report = createSessionGroupsAndStartCompute(realm)
- tableReportFragment.report = report
-
- GlobalScope.launch(Dispatchers.Main) {
- tableReportFragment.showResults()
- }
+// val report = createSessionGroupsAndStartCompute(realm)
+// tableReportFragment.report = report
+//
+// GlobalScope.launch(Dispatchers.Main) {
+// tableReportFragment.showResults()
+// }
}
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt
index 2c413b07..503464c1 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt
@@ -21,10 +21,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import androidx.viewpager.widget.ViewPager
-import com.android.billingclient.api.BillingClient
-import com.android.billingclient.api.Purchase
-import com.android.billingclient.api.SkuDetails
-import com.android.billingclient.api.SkuDetailsResponseListener
+import com.android.billingclient.api.*
import com.crashlytics.android.Crashlytics
import kotlinx.android.synthetic.main.fragment_subscription.*
import net.pokeranalytics.android.R
@@ -128,7 +125,7 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
// Pager
// The pager adapter, which provides the pages to the view pager widget.
- this.pagerAdapter = ScreenSlidePagerAdapter(requireFragmentManager())
+ this.pagerAdapter = ScreenSlidePagerAdapter(parentFragmentManager)
this.pager.adapter = pagerAdapter
this.pager.addOnPageChangeListener(this)
@@ -196,10 +193,10 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
}
// SkuDetailsResponseListener
- override fun onSkuDetailsResponse(responseCode: Int, skuDetailsList: MutableList?) {
- if (responseCode == BillingClient.BillingResponse.OK && skuDetailsList != null) {
+ override fun onSkuDetailsResponse(result: BillingResult, skuDetailsList: MutableList?) {
+ if (result.responseCode == BillingClient.BillingResponseCode.OK) {
this.hideLoader()
- selectedProduct = skuDetailsList.first { it.sku == IAPProducts.PRO.identifier }
+ selectedProduct = skuDetailsList?.firstOrNull { it.sku == IAPProducts.PRO.identifier }
updateUI()
}
}
@@ -223,6 +220,8 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
val formattedFreeTrial =
"$freeTrialDays " + requireContext().getString(R.string.days) + " " + requireContext().getString(R.string.free_trial)
this.freetrial.text = formattedFreeTrial
+ } ?: run {
+ Toast.makeText(requireContext(), R.string.contact_support, Toast.LENGTH_LONG).show()
}
}
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/RealmFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/RealmFragment.kt
index 69b06f25..c24bd928 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/RealmFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/RealmFragment.kt
@@ -1,7 +1,6 @@
package net.pokeranalytics.android.ui.fragment.components
import android.os.Bundle
-import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -9,9 +8,6 @@ import io.realm.Realm
import io.realm.RealmModel
import io.realm.RealmResults
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.async
-import kotlinx.coroutines.launch
import timber.log.Timber
import kotlin.coroutines.CoroutineContext
@@ -29,17 +25,12 @@ open class RealmFragment : BaseFragment() {
*/
private lateinit var realm: Realm
- /***
- * A background realm instance
- */
- private var asyncRealm: Realm? = null
-
/***
* A listener to async updates
*/
- private var asyncListener: RealmAsyncListener? = null
+ private var changeListener: RealmAsyncListener? = null
- private var asyncResults: RealmResults? = null
+ private var realmResults: RealmResults? = null
/**
* A List of observed RealmResults
@@ -62,24 +53,14 @@ open class RealmFragment : BaseFragment() {
return super.onCreateView(inflater, container, savedInstanceState)
}
- fun listenAsynchronously(listener: RealmAsyncListener, clazz: Class) {
+ fun listenRealmChanges(listener: RealmAsyncListener, clazz: Class) {
- this.asyncListener = listener
+ this.changeListener = listener
- GlobalScope.launch(coroutineContext) {
- val async = GlobalScope.async {
- Looper.prepare() // a looper is required on the thread to listen to change
- Looper.loop()
- val realm = Realm.getDefaultInstance()
-
- asyncResults = realm.where(clazz).findAll()
- asyncResults?.addChangeListener { t, _ ->
- Timber.d("Realm changes: ${asyncResults?.size}, ${this@RealmFragment}")
- asyncListener?.asyncListenedEntityChange(t.realm)
- }
- asyncRealm = realm
- }
- async.await()
+ this.realmResults = this.realm.where(clazz).findAllAsync()
+ this.realmResults?.addChangeListener { t, _ ->
+ Timber.d("Realm changes: ${realmResults?.size}, $this")
+ this.changeListener?.asyncListenedEntityChange(t.realm)
}
}
@@ -92,8 +73,7 @@ open class RealmFragment : BaseFragment() {
}
this.realm.close()
- this.asyncResults?.removeAllChangeListeners()
- this.asyncRealm?.close()
+ this.realmResults?.removeAllChangeListeners()
}
/**
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarDetailsFragment.kt
index 37387757..a918a6e3 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarDetailsFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarDetailsFragment.kt
@@ -7,7 +7,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
-import androidx.lifecycle.ViewModelProviders
+import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.github.mikephil.charting.data.BarDataSet
import com.github.mikephil.charting.data.LineDataSet
@@ -40,7 +40,7 @@ import kotlin.collections.ArrayList
class CalendarDetailsFragment : BaseFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate {
private val model: CalendarDetailsViewModel by lazy {
- ViewModelProviders.of(requireActivity()).get(CalendarDetailsViewModel::class.java)
+ ViewModelProvider(requireActivity()).get(CalendarDetailsViewModel::class.java)
}
companion object {
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt
index 6bd0eaa9..cf10446c 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt
@@ -83,7 +83,7 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
super.onViewCreated(view, savedInstanceState)
initData()
initUI()
- listenAsynchronously(this, ComputableResult::class.java)
+ listenRealmChanges(this, ComputableResult::class.java)
}
override fun adapterRows(): List? {
@@ -417,12 +417,15 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
}
override fun asyncListenedEntityChange(realm: Realm) {
- Timber.d("asyncListenedEntityChange")
- launchStatComputation(realm)
- activity?.runOnUiThread {
- displayData()
- }
+ launchAsyncStatComputation()
+
+// Timber.d("asyncListenedEntityChange")
+// launchStatComputation(realm)
+//
+// activity?.runOnUiThread {
+// displayData()
+// }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/data/DataManagerFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/data/DataManagerFragment.kt
index a6b34ad4..85928927 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/modules/data/DataManagerFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/data/DataManagerFragment.kt
@@ -8,7 +8,7 @@ import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AlertDialog
-import androidx.lifecycle.ViewModelProviders
+import androidx.lifecycle.ViewModelProvider
import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.ConfigurationException
import net.pokeranalytics.android.model.interfaces.Savable
@@ -20,7 +20,7 @@ import net.pokeranalytics.android.ui.viewmodel.DataManagerViewModel
open class DataManagerFragment : RealmFragment() {
protected val model: DataManagerViewModel by lazy {
- ViewModelProviders.of(this).get(DataManagerViewModel::class.java)
+ ViewModelProvider(this).get(DataManagerViewModel::class.java)
}
// lateinit var item: Deletable
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/datalist/DataListActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/datalist/DataListActivity.kt
index d2229f82..8db4b214 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/modules/datalist/DataListActivity.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/datalist/DataListActivity.kt
@@ -4,7 +4,7 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
-import androidx.lifecycle.ViewModelProviders
+import androidx.lifecycle.ViewModelProvider
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.ui.activity.components.BaseActivity
@@ -14,7 +14,7 @@ import net.pokeranalytics.android.ui.modules.filter.FilterActivityRequestCode
class DataListActivity : BaseActivity() {
val model: DataListViewModel by lazy {
- ViewModelProviders.of(this).get(DataListViewModel::class.java)
+ ViewModelProvider(this).get(DataListViewModel::class.java)
}
enum class IntentKey(val keyName: String) {
@@ -37,15 +37,15 @@ class DataListActivity : BaseActivity() {
)
}
- fun newSelectInstance(fragment: Fragment, dataType: Int, showAddButton: Boolean = true) {
- val context = fragment.requireContext()
- fragment.startActivityForResult(
- getIntent(
- context,
- dataType,
- showAddButton
- ), FilterActivityRequestCode.SELECT_FILTER.ordinal)
- }
+// fun newSelectInstance(fragment: Fragment, dataType: Int, showAddButton: Boolean = true) {
+// val context = fragment.requireContext()
+// fragment.startActivityForResult(
+// getIntent(
+// context,
+// dataType,
+// showAddButton
+// ), FilterActivityRequestCode.SELECT_FILTER.ordinal)
+// }
fun newInstance(fragment: Fragment, dataType: LiveData, selection: Boolean, itemIds: Array? = null, showAddButton: Boolean = true) {
val context = fragment.requireContext()
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/datalist/DataListFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/datalist/DataListFragment.kt
index 6d36e830..1973cdd6 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/modules/datalist/DataListFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/datalist/DataListFragment.kt
@@ -6,7 +6,7 @@ import android.os.Bundle
import android.view.*
import androidx.appcompat.widget.SearchView
import androidx.core.view.isVisible
-import androidx.lifecycle.ViewModelProviders
+import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.Realm
@@ -18,14 +18,14 @@ import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.interfaces.Deletable
import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.model.realm.Filter
-import net.pokeranalytics.android.ui.modules.data.EditableDataActivity
-import net.pokeranalytics.android.ui.modules.filter.FiltersActivity
import net.pokeranalytics.android.ui.activity.components.RequestCode
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.extensions.removeMargins
import net.pokeranalytics.android.ui.fragment.components.DeletableItemFragment
import net.pokeranalytics.android.ui.helpers.SwipeToDeleteCallback
+import net.pokeranalytics.android.ui.modules.data.EditableDataActivity
+import net.pokeranalytics.android.ui.modules.filter.FiltersActivity
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.util.extensions.find
import net.pokeranalytics.android.util.extensions.sorted
@@ -34,7 +34,7 @@ import net.pokeranalytics.android.util.extensions.sorted
open class DataListFragment : DeletableItemFragment(), RowRepresentableDelegate {
val model: DataListViewModel by lazy {
- ViewModelProviders.of(requireActivity()).get(DataListViewModel::class.java)
+ ViewModelProvider(requireActivity()).get(DataListViewModel::class.java)
}
companion object {
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterDetailsFragment.kt
index f8795bce..5e5794a7 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterDetailsFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterDetailsFragment.kt
@@ -5,7 +5,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.lifecycle.ViewModelProviders
+import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.fragment_filter_details.*
import kotlinx.android.synthetic.main.fragment_filter_details.view.*
@@ -28,7 +28,7 @@ import kotlin.collections.ArrayList
open class FilterDetailsFragment : RealmFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate {
val model: FilterViewModel by lazy {
- ViewModelProviders.of(requireActivity()).get(FilterViewModel::class.java)
+ ViewModelProvider(requireActivity()).get(FilterViewModel::class.java)
}
private lateinit var rowRepresentableAdapter: RowRepresentableAdapter
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersActivity.kt
index 28ec56ce..8bb9d5a8 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersActivity.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersActivity.kt
@@ -4,7 +4,7 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
-import androidx.lifecycle.ViewModelProviders
+import androidx.lifecycle.ViewModelProvider
import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.activity.components.BaseActivity
import net.pokeranalytics.android.ui.fragment.components.BaseFragment
@@ -12,7 +12,7 @@ import net.pokeranalytics.android.ui.fragment.components.BaseFragment
class FiltersActivity : BaseActivity() {
val model: FilterViewModel by lazy {
- ViewModelProviders.of(this).get(FilterViewModel::class.java)
+ ViewModelProvider(this).get(FilterViewModel::class.java)
}
enum class IntentKey(val keyName: String) {
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersFragment.kt
index 9177d529..88b5894a 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersFragment.kt
@@ -5,7 +5,7 @@ import android.content.Intent
import android.os.Bundle
import android.view.*
import androidx.core.view.isVisible
-import androidx.lifecycle.ViewModelProviders
+import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.chip.Chip
import kotlinx.android.synthetic.main.fragment_editable_data.appBar
@@ -29,7 +29,7 @@ import timber.log.Timber
open class FiltersFragment : RealmFragment(), RowRepresentableDelegate {
val model: FilterViewModel by lazy {
- ViewModelProviders.of(requireActivity()).get(FilterViewModel::class.java)
+ ViewModelProvider(requireActivity()).get(FilterViewModel::class.java)
}
companion object {
@@ -94,8 +94,6 @@ open class FiltersFragment : RealmFragment(), RowRepresentableDelegate {
override fun onBackPressed() {
if (this.model.isUpdating) {
cancelUpdates()
- } else {
-// activity?.finish()
}
}
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersListActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersListActivity.kt
index 3ac7d569..22efb843 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersListActivity.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersListActivity.kt
@@ -4,7 +4,7 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
-import androidx.lifecycle.ViewModelProviders
+import androidx.lifecycle.ViewModelProvider
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.ui.activity.components.BaseActivity
@@ -13,7 +13,7 @@ import net.pokeranalytics.android.ui.modules.datalist.DataListViewModel
class FiltersListActivity : BaseActivity() {
val model: DataListViewModel by lazy {
- ViewModelProviders.of(this).get(DataListViewModel::class.java)
+ ViewModelProvider(this).get(DataListViewModel::class.java)
}
enum class IntentKey(val keyName: String) {
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/editor/EditorFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/editor/EditorFragment.kt
index 51c18ae8..a0e7310d 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/editor/EditorFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/editor/EditorFragment.kt
@@ -10,7 +10,7 @@ import android.view.*
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.Observer
-import androidx.lifecycle.ViewModelProviders
+import androidx.lifecycle.ViewModelProvider
import kotlinx.android.synthetic.main.fragment_hand_history.*
import kotlinx.android.synthetic.main.fragment_settings.recyclerView
import net.pokeranalytics.android.R
@@ -27,7 +27,6 @@ import net.pokeranalytics.android.ui.extensions.px
import net.pokeranalytics.android.ui.extensions.showAlertDialog
import net.pokeranalytics.android.ui.fragment.components.BaseFragment
import net.pokeranalytics.android.ui.fragment.components.RealmFragment
-import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType
import net.pokeranalytics.android.ui.modules.datalist.DataListActivity
import net.pokeranalytics.android.ui.modules.handhistory.HandHistoryActivity
@@ -87,7 +86,7 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
super.onCreate(savedInstanceState)
this.model = activity?.run {
- ViewModelProviders.of(this)[EditorViewModel::class.java]
+ ViewModelProvider(this)[EditorViewModel::class.java]
} ?: throw Exception("Invalid Activity")
}
@@ -153,7 +152,7 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
val observer = Observer> {
this.editorAdapter.notifyDataSetChanged()
}
- this.model.rowsLiveData.observe(this, observer)
+ this.model.rowsLiveData.observe(viewLifecycleOwner, observer)
// At first, the selection is defined before the holder is bound,
// so we retrieve the editText inputConnection once the recycler view has been rendered
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerFragment.kt
index d2e0a644..a58975dc 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerFragment.kt
@@ -6,7 +6,7 @@ import android.os.Looper
import android.view.*
import android.widget.PopupWindow
import android.widget.Switch
-import androidx.lifecycle.ViewModelProviders
+import androidx.lifecycle.ViewModelProvider
import io.realm.Sort
import kotlinx.android.synthetic.main.fragment_replayer.*
import net.pokeranalytics.android.R
@@ -42,7 +42,7 @@ class ReplayerFragment : RealmFragment() {
super.onCreate(savedInstanceState)
this.model = activity?.run {
- ViewModelProviders.of(this)[ReplayerModel::class.java]
+ ViewModelProvider(this)[ReplayerModel::class.java]
} ?: throw Exception("Invalid Activity")
}
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionActivity.kt
index cd4b4cea..6f37ee95 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionActivity.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionActivity.kt
@@ -5,7 +5,7 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
-import androidx.lifecycle.ViewModelProviders
+import androidx.lifecycle.ViewModelProvider
import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.activity.components.BaseActivity
@@ -14,7 +14,7 @@ class SessionActivity: BaseActivity() {
private lateinit var sessionFragment: SessionFragment
val model: SessionViewModel by lazy {
- ViewModelProviders.of(this).get(SessionViewModel::class.java)
+ ViewModelProvider(this).get(SessionViewModel::class.java)
}
enum class IntentKey(val keyName : String) {
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt
index b680cc8a..20f0d407 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt
@@ -7,11 +7,10 @@ import android.view.animation.OvershootInterpolator
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
-import androidx.lifecycle.ViewModelProviders
+import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.DiffUtil
import com.crashlytics.android.Crashlytics
import kotlinx.android.synthetic.main.fragment_session.*
-import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
@@ -45,8 +44,6 @@ import net.pokeranalytics.android.util.extensions.formattedHourlyDuration
import net.pokeranalytics.android.util.extensions.getNextMinuteInMilliseconds
import timber.log.Timber
import java.util.*
-import kotlin.coroutines.CoroutineContext
-
class SessionFragment : RealmFragment(), RowRepresentableDelegate {
@@ -93,7 +90,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate {
super.onCreate(savedInstanceState)
this.viewModel = activity?.run {
- ViewModelProviders.of(this).get(SessionViewModel::class.java)
+ ViewModelProvider(this).get(SessionViewModel::class.java)
} ?: throw Exception("Invalid Activity")
}
diff --git a/app/src/main/java/net/pokeranalytics/android/util/billing/AppGuard.kt b/app/src/main/java/net/pokeranalytics/android/util/billing/AppGuard.kt
index 0412b4ac..fdff8f86 100644
--- a/app/src/main/java/net/pokeranalytics/android/util/billing/AppGuard.kt
+++ b/app/src/main/java/net/pokeranalytics/android/util/billing/AppGuard.kt
@@ -5,6 +5,7 @@ import android.content.Context
import android.os.Handler
import android.os.Looper
import com.android.billingclient.api.*
+import com.android.billingclient.api.BillingClient.BillingResponseCode
import net.pokeranalytics.android.BuildConfig
import net.pokeranalytics.android.R
import timber.log.Timber
@@ -99,7 +100,7 @@ object AppGuard : PurchasesUpdatedListener {
*/
fun load(context: Context) {
- billingClient = BillingClient.newBuilder(context).setListener(this).build()
+ billingClient = BillingClient.newBuilder(context).setListener(this).enablePendingPurchases().build()
this.startConnection(Runnable {
this.updatePurchases()
@@ -110,10 +111,9 @@ object AppGuard : PurchasesUpdatedListener {
private fun startConnection(executeOnSuccess: Runnable) {
billingClient.startConnection(object : BillingClientStateListener {
- override fun onBillingSetupFinished(@BillingClient.BillingResponse billingResponseCode: Int) {
-
- this@AppGuard.billingResponseCode = billingResponseCode
- if (billingResponseCode == BillingClient.BillingResponse.OK) {
+ override fun onBillingSetupFinished(result: BillingResult) {
+ this@AppGuard.billingResponseCode = result.responseCode
+ if (billingResponseCode == BillingResponseCode.OK) {
// The BillingClient is ready. You can query purchases here.
billingClientAvailable = true
executeOnSuccess.run()
@@ -125,6 +125,22 @@ object AppGuard : PurchasesUpdatedListener {
}
})
+// billingClient.startConnection(object : BillingClientStateListener {
+// override fun onBillingSetupFinished(@BillingClient.BillingResponse billingResponseCode: Int) {
+//
+// this@AppGuard.billingResponseCode = billingResponseCode
+// if (billingResponseCode == BillingClient.BillingResponse.OK) {
+// // The BillingClient is ready. You can query purchases here.
+// billingClientAvailable = true
+// executeOnSuccess.run()
+// }
+// }
+//
+// override fun onBillingServiceDisconnected() {
+// billingClientAvailable = false
+// }
+// })
+
}
private fun executeServiceRequest(runnable: Runnable) {
@@ -150,8 +166,8 @@ object AppGuard : PurchasesUpdatedListener {
this.resetPurchases()
// Automatically checks for purchases (when switching devices for example)
val purchasesResult = billingClient.queryPurchases(BillingClient.SkuType.SUBS)
- if (purchasesResult != null && purchasesResult.purchasesList != null) {
- purchasesResult.purchasesList.forEach {
+ if (purchasesResult != null) {
+ purchasesResult.purchasesList?.forEach {
this.handlePurchase(it)
}
}
@@ -206,23 +222,40 @@ object AppGuard : PurchasesUpdatedListener {
// PurchasesUpdatedListener
- /**
- * Purchase callback
- */
- override fun onPurchasesUpdated(responseCode: Int, purchases: MutableList?) {
+ override fun onPurchasesUpdated(result: BillingResult, purchases: MutableList?) {
- if (responseCode == BillingClient.BillingResponse.OK && purchases != null) {
+ if (result.responseCode == BillingResponseCode.OK && purchases != null) {
for (purchase in purchases) {
handlePurchase(purchase)
}
- } else if (responseCode == BillingClient.BillingResponse.USER_CANCELED) {
+ } else if (result.responseCode == BillingResponseCode.USER_CANCELED) {
+ Timber.d("purchase cancel message: ${result.debugMessage}")
// Handle an error caused by a user cancelling the purchase flow.
} else {
+ Timber.d("purchase error message: ${result.debugMessage}")
// Handle any other error codes.
}
+
}
+// /**
+// * Purchase callback
+// */
+// override fun onPurchasesUpdated(responseCode: Int, purchases: MutableList?) {
+//
+// if (responseCode == BillingClient.BillingResponse.OK && purchases != null) {
+// for (purchase in purchases) {
+// handlePurchase(purchase)
+// }
+// } else if (responseCode == BillingClient.BillingResponse.USER_CANCELED) {
+// // Handle an error caused by a user cancelling the purchase flow.
+// } else {
+// // Handle any other error codes.
+// }
+//
+// }
+
/**
* Method called when a [purchase] has been made
*/
@@ -232,18 +265,28 @@ object AppGuard : PurchasesUpdatedListener {
when (purchase.sku) {
IAPProducts.PRO.identifier -> {
-
val date = Date(purchase.purchaseTime)
Timber.d("*** Auto renewing = ${purchase.isAutoRenewing}")
Timber.d("*** purchaseTime = $date")
- this._isProUser = true
- this.purchaseDelegate?.let {
- Handler(Looper.getMainLooper()).post {
- it.purchaseDidSucceed(purchase)
+ if (purchase.purchaseState == Purchase.PurchaseState.PURCHASED) {
+
+ if (!purchase.isAcknowledged) {
+ val params = AcknowledgePurchaseParams.newBuilder().setPurchaseToken(purchase.purchaseToken).build()
+ this.billingClient.acknowledgePurchase(params) { result ->
+ Timber.d("Acknowledge result: ${result.responseCode}")
+ }
+ }
+
+ this._isProUser = true
+ this.purchaseDelegate?.let {
+ Handler(Looper.getMainLooper()).post {
+ it.purchaseDidSucceed(purchase)
+ }
+ this.purchaseDelegate = null
}
- this.purchaseDelegate = null
}
+
}
else -> {
}
diff --git a/app/src/main/java/net/pokeranalytics/android/util/billing/Security.kt b/app/src/main/java/net/pokeranalytics/android/util/billing/Security.kt
index 07676606..a8bb60ad 100644
--- a/app/src/main/java/net/pokeranalytics/android/util/billing/Security.kt
+++ b/app/src/main/java/net/pokeranalytics/android/util/billing/Security.kt
@@ -17,10 +17,9 @@ package net.pokeranalytics.android.util.billing
*/
-
import android.text.TextUtils
import android.util.Base64
-import com.android.billingclient.util.BillingHelper
+import timber.log.Timber
import java.io.IOException
import java.security.*
import java.security.spec.InvalidKeySpecException
@@ -32,10 +31,8 @@ import java.security.spec.X509EncodedKeySpec
*/
object Security {
- private val TAG = "IABUtil/Security"
-
- private val KEY_FACTORY_ALGORITHM = "RSA"
- private val SIGNATURE_ALGORITHM = "SHA1withRSA"
+ private const val KEY_FACTORY_ALGORITHM = "RSA"
+ private const val SIGNATURE_ALGORITHM = "SHA1withRSA"
/**
* Verifies that the data was signed with the given signature, and returns the verified
@@ -54,7 +51,7 @@ object Security {
if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey)
|| TextUtils.isEmpty(signature)
) {
- BillingHelper.logWarn(TAG, "Purchase verification failed: missing data.")
+ Timber.w("Purchase verification failed: missing data.")
return false
}
@@ -70,7 +67,7 @@ object Security {
* is invalid
*/
@Throws(IOException::class)
- fun generatePublicKey(encodedPublicKey: String): PublicKey {
+ private fun generatePublicKey(encodedPublicKey: String): PublicKey {
try {
val decodedKey = Base64.decode(encodedPublicKey, Base64.DEFAULT)
val keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM)
@@ -80,7 +77,7 @@ object Security {
throw RuntimeException(e)
} catch (e: InvalidKeySpecException) {
val msg = "Invalid key specification: $e"
- BillingHelper.logWarn(TAG, msg)
+ Timber.w(msg)
throw IOException(msg)
}
@@ -95,12 +92,12 @@ object Security {
* @param signature server signature
* @return true if the data and signature match
*/
- fun verify(publicKey: PublicKey, signedData: String, signature: String): Boolean {
+ private fun verify(publicKey: PublicKey, signedData: String, signature: String): Boolean {
val signatureBytes: ByteArray
try {
signatureBytes = Base64.decode(signature, Base64.DEFAULT)
} catch (e: IllegalArgumentException) {
- BillingHelper.logWarn(TAG, "Base64 decoding failed.")
+ Timber.w("Base64 decoding failed.")
return false
}
@@ -109,7 +106,7 @@ object Security {
signatureAlgorithm.initVerify(publicKey)
signatureAlgorithm.update(signedData.toByteArray())
if (!signatureAlgorithm.verify(signatureBytes)) {
- BillingHelper.logWarn(TAG, "Signature verification failed.")
+ Timber.w("Signature verification failed.")
return false
}
return true
@@ -117,9 +114,9 @@ object Security {
// "RSA" is guaranteed to be available.
throw RuntimeException(e)
} catch (e: InvalidKeyException) {
- BillingHelper.logWarn(TAG, "Invalid key specification.")
+ Timber.w("Invalid key specification.")
} catch (e: SignatureException) {
- BillingHelper.logWarn(TAG, "Signature exception.")
+ Timber.w("Signature exception.")
}
return false
diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt
index f924f944..86dcaba6 100644
--- a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt
+++ b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt
@@ -191,7 +191,7 @@ open class CSVImporter(istream: InputStream) {
fun save(realm: Realm) {
this.parser.close()
-// realm.refresh()
+ realm.refresh()
this.currentDescriptor?.save(realm)
this.usedDescriptors.forEach { descriptor ->
@@ -201,7 +201,7 @@ open class CSVImporter(istream: InputStream) {
fun cancel(realm: Realm) {
this.parser.close()
-// realm.refresh()
+ realm.refresh()
this.currentDescriptor?.cancel(realm)
this.usedDescriptors.forEach { descriptor ->
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 16bf01b6..185c7a4b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -806,5 +806,6 @@
We\'ll send you a notification when your file is available. Expect approximately one minute!
Show villain cards
Please save before sharing
+ It looks like there is an issue here. Please contact the support to get help.